Fix ruff linting for scripts in source/tools/dist/

By default ruff excludes all files in directories named "dist" from
linting (https://docs.astral.sh/ruff/settings/#exclude). This caused the
Python scripts in `source/tools/dist/` to not get linted. This commit
fixes that and adjusts their style to fit our ruff rules.
This commit is contained in:
Dunedan 2025-02-27 08:13:03 +01:00
parent b831b1f559
commit 3c57fdb4a9
No known key found for this signature in database
GPG key ID: 885B16854284E0B2
3 changed files with 195 additions and 110 deletions

View file

@ -1,3 +1,25 @@
# default excludes minus "dist"
exclude = [
".bzr",
".direnv",
".eggs",
".git",
".git-rewrite",
".hg",
".mypy_cache",
".nox",
".pants.d",
".pytype",
".ruff_cache",
".svn",
".tox",
".venv",
"__pypackages__",
"_build",
"buck-out",
"node_modules",
"venv"]
line-length = 99
target-version = "py311"

View file

@ -1,38 +1,41 @@
#!/usr/bin/python3
"""
Builds the OSX bundle from existing elements.
"""Build the OSX bundle from existing elements.
App bundles are intended to be self-contained and portable.
An SDK is required, usually included with Xcode. The SDK ensures
that only those system libraries are used which are available on
the chosen target and compatible systems.
This is Python because plistlib is extremely strict about what it accepts
This is Python because plistlib is extremely strict about what it accepts,
and it's used by dmgbuild, and saving the Plist doesn't really work otherwise.
"""
import argparse
import datetime
import glob
import os
import plistlib
import shutil
import subprocess
import sys
from datetime import datetime
import dmgbuild
parser = argparse.ArgumentParser()
parser.add_argument('bundle_version', help='Bundle version')
parser.add_argument('--architecture', help='aarch64 (arm64) or x86_64 (amd64)',
default='aarch64')
parser.add_argument('--min_osx', help='Minimum supported OSX version',
default='10.12')
parser.add_argument('--bundle_identifier', help='Bundle identifier',
default='com.wildfiregames.play0ad')
parser.add_argument('-s', '--signkey', help='Signature key sha sum')
parser.add_argument('--notarytool_user', help='Apple ID user for notarization')
parser.add_argument('--notarytool_team', help='Team ID for notarization')
parser.add_argument('--notarytool_password', help='App password for notarization')
parser.add_argument('--dev', help='Turn on dev mode, which isn\'t fit for release but faster',
action="store_true")
parser.add_argument("bundle_version", help="Bundle version")
parser.add_argument("--architecture", help="aarch64 (arm64) or x86_64 (amd64)", default="aarch64")
parser.add_argument("--min_osx", help="Minimum supported OSX version", default="10.12")
parser.add_argument(
"--bundle_identifier", help="Bundle identifier", default="com.wildfiregames.play0ad"
)
parser.add_argument("-s", "--signkey", help="Signature key sha sum")
parser.add_argument("--notarytool_user", help="Apple ID user for notarization")
parser.add_argument("--notarytool_team", help="Team ID for notarization")
parser.add_argument("--notarytool_password", help="App password for notarization")
parser.add_argument(
"--dev", help="Turn on dev mode, which isn't fit for release but faster", action="store_true"
)
args = parser.parse_args()
ARCH = args.architecture
@ -77,9 +80,18 @@ shutil.copy("binaries/system/libMoltenVK.dylib", BUNDLE_FRAMEWORKS)
if not args.dev:
print("Signing libs")
subprocess.run(["codesign", "-s", SIGNKEY, "-f", "--timestamp", BUNDLE_FRAMEWORKS + "/libAtlasUI.dylib"], check=True)
subprocess.run(["codesign", "-s", SIGNKEY, "-f", "--timestamp", BUNDLE_FRAMEWORKS + "/libCollada.dylib"], check=True)
subprocess.run(["codesign", "-s", SIGNKEY, "-f", "--timestamp", BUNDLE_FRAMEWORKS + "/libMoltenVK.dylib"], check=True)
subprocess.run(
["codesign", "-s", SIGNKEY, "-f", "--timestamp", BUNDLE_FRAMEWORKS + "/libAtlasUI.dylib"],
check=True,
)
subprocess.run(
["codesign", "-s", SIGNKEY, "-f", "--timestamp", BUNDLE_FRAMEWORKS + "/libCollada.dylib"],
check=True,
)
subprocess.run(
["codesign", "-s", SIGNKEY, "-f", "--timestamp", BUNDLE_FRAMEWORKS + "/libMoltenVK.dylib"],
check=True,
)
if not args.dev:
print("Copying archived game data from archives/")
@ -112,50 +124,72 @@ shutil.copy("libraries/LICENSE.txt", BUNDLE_RESOURCES + "/LIB_LICENSE.txt")
print("Creating Info.plist")
with open(BUNDLE_CONTENTS + "/Info.plist", 'wb') as f:
plistlib.dump({
'CFBundleName': '0 A.D.',
'CFBundleIdentifier': BUNDLE_IDENTIFIER,
'CFBundleVersion': BUNDLE_VERSION,
'CFBundlePackageType': 'APPL',
'CFBundleSignature': 'none',
'CFBundleExecutable': 'pyrogenesis',
'CFBundleShortVersionString': BUNDLE_VERSION,
'CFBundleDevelopmentRegion': 'English',
'CFBundleInfoDictionaryVersion': '6.0',
'CFBundleIconFile': '0ad',
'LSHasLocalizedDisplayName': True,
'LSMinimumSystemVersion': BUNDLE_MIN_OSX_VERSION,
'NSHumanReadableCopyright': f'Copyright © {datetime.datetime.now().year} Wildfire Games',
'UTExportedTypeDeclarations': [{
'UTTypeIdentifier': BUNDLE_IDENTIFIER,
'UTTypeTagSpecification': {
'public.filename-extension': ["pyromod"],
},
'UTTypeConformsTo': ['public.zip-archive'],
'UTTypeDescription': '0 A.D. Zipped Mod',
'UTTypeIconFile': '0ad'
}],
'CFBundleDocumentTypes': [{
'CFBundleTypeExtensions': ['pyromod'],
'CFBundleTypeRole': 'Editor',
'CFBundleTypeIconFile': '0ad',
'LSHandlerRank': 'Owner'
},
with open(BUNDLE_CONTENTS + "/Info.plist", "wb") as f:
plistlib.dump(
{
'CFBundleTypeExtensions': ['zip'],
'CFBundleTypeRole': 'Viewer',
'CFBundleTypeIconFile': '0ad',
'LSHandlerRank': 'Alternate'
}],
}, f)
"CFBundleName": "0 A.D.",
"CFBundleIdentifier": BUNDLE_IDENTIFIER,
"CFBundleVersion": BUNDLE_VERSION,
"CFBundlePackageType": "APPL",
"CFBundleSignature": "none",
"CFBundleExecutable": "pyrogenesis",
"CFBundleShortVersionString": BUNDLE_VERSION,
"CFBundleDevelopmentRegion": "English",
"CFBundleInfoDictionaryVersion": "6.0",
"CFBundleIconFile": "0ad",
"LSHasLocalizedDisplayName": True,
"LSMinimumSystemVersion": BUNDLE_MIN_OSX_VERSION,
"NSHumanReadableCopyright": f"Copyright © {datetime.now(tz=datetime.UTC).year} "
f"Wildfire Games",
"UTExportedTypeDeclarations": [
{
"UTTypeIdentifier": BUNDLE_IDENTIFIER,
"UTTypeTagSpecification": {
"public.filename-extension": ["pyromod"],
},
"UTTypeConformsTo": ["public.zip-archive"],
"UTTypeDescription": "0 A.D. Zipped Mod",
"UTTypeIconFile": "0ad",
}
],
"CFBundleDocumentTypes": [
{
"CFBundleTypeExtensions": ["pyromod"],
"CFBundleTypeRole": "Editor",
"CFBundleTypeIconFile": "0ad",
"LSHandlerRank": "Owner",
},
{
"CFBundleTypeExtensions": ["zip"],
"CFBundleTypeRole": "Viewer",
"CFBundleTypeIconFile": "0ad",
"LSHandlerRank": "Alternate",
},
],
},
f,
)
if args.dev:
print(f"Dev mode bundle complete, located at {BUNDLE_OUTPUT}")
exit(0)
sys.exit(0)
print("Signing bundle")
subprocess.run(["codesign", "-s", SIGNKEY, "-f", "--timestamp", "-o", "runtime", "--entitlements", "source/tools/dist/0ad.entitlements", BUNDLE_OUTPUT], check=True)
subprocess.run(
[
"codesign",
"-s",
SIGNKEY,
"-f",
"--timestamp",
"-o",
"runtime",
"--entitlements",
"source/tools/dist/0ad.entitlements",
BUNDLE_OUTPUT,
],
check=True,
)
print("Creating .dmg")
@ -167,14 +201,42 @@ dmgbuild.build_dmg(
defines={
"app": BUNDLE_OUTPUT,
"background": "build/resources/dmgbackground.png",
"icon": "build/resources/0ad.icns"
})
"icon": "build/resources/0ad.icns",
},
)
print("Signing .dmg")
subprocess.run(["codesign", "-s", SIGNKEY, "-f", "--timestamp", "-i", BUNDLE_IDENTIFIER, BUNDLE_DMG_NAME + ".dmg"], check=True)
subprocess.run(
[
"codesign",
"-s",
SIGNKEY,
"-f",
"--timestamp",
"-i",
BUNDLE_IDENTIFIER,
BUNDLE_DMG_NAME + ".dmg",
],
check=True,
)
print("Notarizing .dmg")
subprocess.run(["xcrun", "notarytool", "submit", BUNDLE_DMG_NAME + ".dmg", "--apple-id", NOTARYTOOL_USER, "--team-id", NOTARYTOOL_TEAM, "--password", NOTARYTOOL_PASSWORD, "--wait"], check=True)
subprocess.run(
[
"xcrun",
"notarytool",
"submit",
BUNDLE_DMG_NAME + ".dmg",
"--apple-id",
NOTARYTOOL_USER,
"--team-id",
NOTARYTOOL_TEAM,
"--password",
NOTARYTOOL_PASSWORD,
"--wait",
],
check=True,
)
print("Stapling notarization ticket")
subprocess.run(["xcrun", "stapler", "staple", BUNDLE_DMG_NAME + ".dmg"], check=True)

View file

@ -1,27 +1,31 @@
"""0 A.D. settings file for dmgbuild.
Use like this:
dmgbuild -s settings.py -D app=/path/to/My.app \
-D background=/path/to/background.png "My Application" MyApp.dmg
"""
# ruff: noqa: A001,F821,INP001
import os.path
#
# 0 A.D. settings file for dmgbuild
#
# Use like this:
# dmgbuild -s settings.py -D app=/path/to/My.app -D background=/path/to/background.png "My Application" MyApp.dmg
application = defines.get('app')
application = defines.get("app")
# .. Basics ....................................................................
# Volume format (see hdiutil create -help)
format = defines.get('format', 'UDBZ')
format = defines.get("format", "UDBZ")
# Volume size
size = defines.get('size', '4G')
size = defines.get("size", "4G")
# Files to include
files = [ application ]
files = [application]
# Symlinks to create
symlinks = { 'Applications': '/Applications' }
symlinks = {"Applications": "/Applications"}
# Volume icon
#
@ -29,18 +33,15 @@ symlinks = { 'Applications': '/Applications' }
# image, *or* you can define badge_icon, in which case the icon file you specify
# will be used to badge the system's Removable Disk icon
#
badge_icon = defines.get('icon')
badge_icon = defines.get("icon")
# Where to put the icons
icon_locations = {
os.path.basename(application): (125, 170),
'Applications': (475, 170)
}
icon_locations = {os.path.basename(application): (125, 170), "Applications": (475, 170)}
# .. Window configuration ......................................................
# Background
background = defines.get('background')
background = defines.get("background")
show_status_bar = False
show_tab_view = False
@ -54,20 +55,20 @@ window_rect = ((0, 0), (600, 393))
# Select the default view; must be one of
#
# 'icon-view'
# 'list-view'
# 'column-view'
# 'coverflow'
# "icon-view"
# "list-view"
# "column-view"
# "coverflow"
#
default_view = 'icon-view'
default_view = "icon-view"
# General view configuration
show_icon_preview = False
# Set these to True to force inclusion of icon/list view settings (otherwise
# we only include settings for the default view)
include_icon_view_settings = 'auto'
include_list_view_settings = 'auto'
include_icon_view_settings = "auto"
include_list_view_settings = "auto"
# .. Icon view configuration ...................................................
@ -75,7 +76,7 @@ arrange_by = None
grid_offset = (0, 0)
grid_spacing = 100
scroll_position = (0, 0)
label_pos = 'bottom' # or 'right'
label_pos = "bottom" # or "right"
text_size = 12
icon_size = 90
@ -97,33 +98,33 @@ icon_size = 90
list_icon_size = 16
list_text_size = 12
list_scroll_position = (0, 0)
list_sort_by = 'name'
list_sort_by = "name"
list_use_relative_dates = True
list_calculate_all_sizes = False,
list_columns = ('name', 'date-modified', 'size', 'kind', 'date-added')
list_calculate_all_sizes = False
list_columns = ("name", "date-modified", "size", "kind", "date-added")
list_column_widths = {
'name': 300,
'date-modified': 181,
'date-created': 181,
'date-added': 181,
'date-last-opened': 181,
'size': 97,
'kind': 115,
'label': 100,
'version': 75,
'comments': 300,
"name": 300,
"date-modified": 181,
"date-created": 181,
"date-added": 181,
"date-last-opened": 181,
"size": 97,
"kind": 115,
"label": 100,
"version": 75,
"comments": 300,
}
list_column_sort_directions = {
'name': 'ascending',
'date-modified': 'descending',
'date-created': 'descending',
'date-added': 'descending',
'date-last-opened': 'descending',
'size': 'descending',
'kind': 'ascending',
'label': 'ascending',
'version': 'ascending',
'comments': 'ascending',
"name": "ascending",
"date-modified": "descending",
"date-created": "descending",
"date-added": "descending",
"date-last-opened": "descending",
"size": "descending",
"kind": "ascending",
"label": "ascending",
"version": "ascending",
"comments": "ascending",
}
# .. License configuration .....................................................