diff --git a/.efrocachemap b/.efrocachemap index 7e406c9c..b3c99a23 100644 --- a/.efrocachemap +++ b/.efrocachemap @@ -4072,26 +4072,26 @@ "build/assets/workspace/ninjafightplug.py": "https://files.ballistica.net/cache/ba1/c5/09/4f10b8a21ba87aa5509cff7a164b", "build/assets/workspace/onslaughtplug.py": "https://files.ballistica.net/cache/ba1/ff/0a/a354984f9c074dab0676ac7e4877", "build/assets/workspace/runaroundplug.py": "https://files.ballistica.net/cache/ba1/2a/1c/9ee5db6d1bceca7fa6638fb8abde", - "build/prefab/full/linux_arm64_gui/debug/ballisticakit": "https://files.ballistica.net/cache/ba1/01/62/032e7f17e55eb4d1a46d00b7f8b3", - "build/prefab/full/linux_arm64_gui/release/ballisticakit": "https://files.ballistica.net/cache/ba1/d9/db/295a7e947eab3626dd09344f8773", - "build/prefab/full/linux_arm64_server/debug/dist/ballisticakit_headless": "https://files.ballistica.net/cache/ba1/4f/23/abf9b8a3d8382e132001a07ce659", - "build/prefab/full/linux_arm64_server/release/dist/ballisticakit_headless": "https://files.ballistica.net/cache/ba1/8b/e6/969ff181328b319b0d0d7ba737b5", - "build/prefab/full/linux_x86_64_gui/debug/ballisticakit": "https://files.ballistica.net/cache/ba1/3f/71/ee0b615ae5737b07b14611fba521", - "build/prefab/full/linux_x86_64_gui/release/ballisticakit": "https://files.ballistica.net/cache/ba1/ed/7b/f6b7d63868eff24231ddb4f08acc", - "build/prefab/full/linux_x86_64_server/debug/dist/ballisticakit_headless": "https://files.ballistica.net/cache/ba1/b0/ed/b7c1d78cf2f4ca9501ae6ada5f2a", - "build/prefab/full/linux_x86_64_server/release/dist/ballisticakit_headless": "https://files.ballistica.net/cache/ba1/18/5b/eaea207321a10f13c932a3fd66d3", - "build/prefab/full/mac_arm64_gui/debug/ballisticakit": "https://files.ballistica.net/cache/ba1/0c/2b/9fab63531b80c48e4751abd97dc2", - "build/prefab/full/mac_arm64_gui/release/ballisticakit": "https://files.ballistica.net/cache/ba1/a8/5c/40fb49f7a0e1a65496766c5767e6", - "build/prefab/full/mac_arm64_server/debug/dist/ballisticakit_headless": "https://files.ballistica.net/cache/ba1/2d/bf/7a2f85c03f3cf34a395b44d973d2", - "build/prefab/full/mac_arm64_server/release/dist/ballisticakit_headless": "https://files.ballistica.net/cache/ba1/6e/79/66ccaa09094203be7f1bd96ba81b", - "build/prefab/full/mac_x86_64_gui/debug/ballisticakit": "https://files.ballistica.net/cache/ba1/e1/85/9687ff7b6ef6816cacf6a73b3175", - "build/prefab/full/mac_x86_64_gui/release/ballisticakit": "https://files.ballistica.net/cache/ba1/84/af/9a03f2688c69a9f704cb8c4c52df", - "build/prefab/full/mac_x86_64_server/debug/dist/ballisticakit_headless": "https://files.ballistica.net/cache/ba1/50/a6/02867f49514bc30eef36324fbf40", - "build/prefab/full/mac_x86_64_server/release/dist/ballisticakit_headless": "https://files.ballistica.net/cache/ba1/b2/0f/acd0b9a413537b781d21e9d3d48f", - "build/prefab/full/windows_x86_gui/debug/BallisticaKit.exe": "https://files.ballistica.net/cache/ba1/4a/fe/2bb19d0c6768998cac5e29aa28f3", - "build/prefab/full/windows_x86_gui/release/BallisticaKit.exe": "https://files.ballistica.net/cache/ba1/3e/03/37e6e3143dabc166e90ef9a1c53c", - "build/prefab/full/windows_x86_server/debug/dist/BallisticaKitHeadless.exe": "https://files.ballistica.net/cache/ba1/63/eb/b5b19380d16d171fdea79d2be504", - "build/prefab/full/windows_x86_server/release/dist/BallisticaKitHeadless.exe": "https://files.ballistica.net/cache/ba1/50/f0/698126e96f79156f18c9cc17736f", + "build/prefab/full/linux_arm64_gui/debug/ballisticakit": "https://files.ballistica.net/cache/ba1/55/6b/e121957fd82e859978fa3f4af422", + "build/prefab/full/linux_arm64_gui/release/ballisticakit": "https://files.ballistica.net/cache/ba1/31/72/7e8a9913cf35dee3c6fe58ca3b68", + "build/prefab/full/linux_arm64_server/debug/dist/ballisticakit_headless": "https://files.ballistica.net/cache/ba1/73/95/f4282112234f1ee6bf85b002f7a1", + "build/prefab/full/linux_arm64_server/release/dist/ballisticakit_headless": "https://files.ballistica.net/cache/ba1/a0/03/493c9adbc287bdf78e7805d4dadb", + "build/prefab/full/linux_x86_64_gui/debug/ballisticakit": "https://files.ballistica.net/cache/ba1/35/80/396064bdf00d3fac806deb8bcb98", + "build/prefab/full/linux_x86_64_gui/release/ballisticakit": "https://files.ballistica.net/cache/ba1/dc/70/7bdbc05f71bd2b4baee0583c5c10", + "build/prefab/full/linux_x86_64_server/debug/dist/ballisticakit_headless": "https://files.ballistica.net/cache/ba1/3c/37/224b7f44e3b8a05246a93372707b", + "build/prefab/full/linux_x86_64_server/release/dist/ballisticakit_headless": "https://files.ballistica.net/cache/ba1/7a/2a/0ba6681061dc5b37ab8b22956866", + "build/prefab/full/mac_arm64_gui/debug/ballisticakit": "https://files.ballistica.net/cache/ba1/0e/00/800c35d813cca3e2e3e63466c27e", + "build/prefab/full/mac_arm64_gui/release/ballisticakit": "https://files.ballistica.net/cache/ba1/75/30/2aa812a882602a68cd8964fb1342", + "build/prefab/full/mac_arm64_server/debug/dist/ballisticakit_headless": "https://files.ballistica.net/cache/ba1/3a/df/1ab366d634b98658c1cc0777deab", + "build/prefab/full/mac_arm64_server/release/dist/ballisticakit_headless": "https://files.ballistica.net/cache/ba1/06/cf/c55480c3becf6a6c2fb25fc4c7dd", + "build/prefab/full/mac_x86_64_gui/debug/ballisticakit": "https://files.ballistica.net/cache/ba1/9a/d7/ac988919c775fe9cbd94e8dcc4b8", + "build/prefab/full/mac_x86_64_gui/release/ballisticakit": "https://files.ballistica.net/cache/ba1/f7/ba/833d780e8a18a259fbe718b6da39", + "build/prefab/full/mac_x86_64_server/debug/dist/ballisticakit_headless": "https://files.ballistica.net/cache/ba1/6d/e2/2a90fc6f49aeb39c2faece177666", + "build/prefab/full/mac_x86_64_server/release/dist/ballisticakit_headless": "https://files.ballistica.net/cache/ba1/92/80/e65efc75286312b059e796dcdc3e", + "build/prefab/full/windows_x86_gui/debug/BallisticaKit.exe": "https://files.ballistica.net/cache/ba1/9a/ac/dbe17c7907ac15a338ef7cae89f8", + "build/prefab/full/windows_x86_gui/release/BallisticaKit.exe": "https://files.ballistica.net/cache/ba1/06/2b/bb13f4dd9ff4671a5142f56d3c6b", + "build/prefab/full/windows_x86_server/debug/dist/BallisticaKitHeadless.exe": "https://files.ballistica.net/cache/ba1/0b/b6/db6ca3469a280a6ba15ae8e554c8", + "build/prefab/full/windows_x86_server/release/dist/BallisticaKitHeadless.exe": "https://files.ballistica.net/cache/ba1/72/3a/5c2a8e5e3b0152de7141397a50cc", "build/prefab/lib/linux_arm64_gui/debug/libballistica_plus.a": "https://files.ballistica.net/cache/ba1/d4/6a/dd303a200b98a56ba3b100277057", "build/prefab/lib/linux_arm64_gui/release/libballistica_plus.a": "https://files.ballistica.net/cache/ba1/fc/2c/2996c558fb408a548fdd37398c9a", "build/prefab/lib/linux_arm64_server/debug/libballistica_plus.a": "https://files.ballistica.net/cache/ba1/ed/28/b7a72be7ae1bd2b58dda4b6902a0", @@ -4108,14 +4108,14 @@ "build/prefab/lib/mac_x86_64_gui/release/libballistica_plus.a": "https://files.ballistica.net/cache/ba1/71/f6/691482915ad58ea1e953cc23d74c", "build/prefab/lib/mac_x86_64_server/debug/libballistica_plus.a": "https://files.ballistica.net/cache/ba1/b8/2b/6ec8c78980a62e3e0ee4b36ece04", "build/prefab/lib/mac_x86_64_server/release/libballistica_plus.a": "https://files.ballistica.net/cache/ba1/4e/56/a95c987b2a371759896b037fea86", - "build/prefab/lib/windows/Debug_Win32/BallisticaKitGenericPlus.lib": "https://files.ballistica.net/cache/ba1/4b/cc/a2ec3215d71090861b22bf616104", - "build/prefab/lib/windows/Debug_Win32/BallisticaKitGenericPlus.pdb": "https://files.ballistica.net/cache/ba1/73/60/e0da28e6c086648d8b85464eca14", - "build/prefab/lib/windows/Debug_Win32/BallisticaKitHeadlessPlus.lib": "https://files.ballistica.net/cache/ba1/7f/db/fa1351270bbc9705cefafd841d55", - "build/prefab/lib/windows/Debug_Win32/BallisticaKitHeadlessPlus.pdb": "https://files.ballistica.net/cache/ba1/12/fb/a1f2e9b6fb7a094f8f7ad9520273", - "build/prefab/lib/windows/Release_Win32/BallisticaKitGenericPlus.lib": "https://files.ballistica.net/cache/ba1/67/ca/f17bd5d265e24efcc2ecf6a7f71a", - "build/prefab/lib/windows/Release_Win32/BallisticaKitGenericPlus.pdb": "https://files.ballistica.net/cache/ba1/a1/50/7e6e23f7b68a9c9abb8e4cee7dd2", - "build/prefab/lib/windows/Release_Win32/BallisticaKitHeadlessPlus.lib": "https://files.ballistica.net/cache/ba1/a8/42/554205c4e22be41bbb2b0fbbe218", - "build/prefab/lib/windows/Release_Win32/BallisticaKitHeadlessPlus.pdb": "https://files.ballistica.net/cache/ba1/bc/9f/9105016fe3cc388b00b6b920a683", + "build/prefab/lib/windows/Debug_Win32/BallisticaKitGenericPlus.lib": "https://files.ballistica.net/cache/ba1/3a/61/2d09cedad6dd6ad3b754cb11dd82", + "build/prefab/lib/windows/Debug_Win32/BallisticaKitGenericPlus.pdb": "https://files.ballistica.net/cache/ba1/a6/70/a1d5515282cd1ecbd9eced7914d2", + "build/prefab/lib/windows/Debug_Win32/BallisticaKitHeadlessPlus.lib": "https://files.ballistica.net/cache/ba1/ce/22/f66d8ff129799e94b46762d756ec", + "build/prefab/lib/windows/Debug_Win32/BallisticaKitHeadlessPlus.pdb": "https://files.ballistica.net/cache/ba1/66/27/69c082147bb67cc08d5b9ac25a7d", + "build/prefab/lib/windows/Release_Win32/BallisticaKitGenericPlus.lib": "https://files.ballistica.net/cache/ba1/e8/19/ad053e8755fbcfaa056d3682ebd7", + "build/prefab/lib/windows/Release_Win32/BallisticaKitGenericPlus.pdb": "https://files.ballistica.net/cache/ba1/1c/5b/677ae1098e3cd199d09fe8a8cd3e", + "build/prefab/lib/windows/Release_Win32/BallisticaKitHeadlessPlus.lib": "https://files.ballistica.net/cache/ba1/a0/00/de0c7e8f73dd1d5f77d8cd8fd4de", + "build/prefab/lib/windows/Release_Win32/BallisticaKitHeadlessPlus.pdb": "https://files.ballistica.net/cache/ba1/1d/46/a0500598a1a66f898fea906420e8", "src/assets/ba_data/python/babase/_mgen/__init__.py": "https://files.ballistica.net/cache/ba1/52/c6/c11130af7b10d6c0321add5518fa", "src/assets/ba_data/python/babase/_mgen/enums.py": "https://files.ballistica.net/cache/ba1/38/c3/1dedd5e74f2508efc5974c8815a1", "src/ballistica/base/mgen/pyembed/binding_base.inc": "https://files.ballistica.net/cache/ba1/d5/4a/0e480a855ce83709bd7f6761107d", diff --git a/CHANGELOG.md b/CHANGELOG.md index 196d71bd..19d18ca6 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,4 +1,4 @@ -### 1.7.20 (build 21032, api 8, 2023-06-01) +### 1.7.20 (build 21034, api 8, 2023-06-01) - This seems like a good time for a `refactoring` release in anticipation of changes coming in 1.8. Basically this means that a lot of things will be diff --git a/Makefile b/Makefile index bcbaee32..a7d2be13 100644 --- a/Makefile +++ b/Makefile @@ -589,7 +589,32 @@ build/prefab/lib/windows/Release_%/BallisticaKitHeadlessPlus.pdb: .efrocachemap ################################################################################ spinoff-test-empty: - tools/pcommand spinoff_test empty + tools/pcommand spinoff_test empty $(SPINOFF_TEST_EXTRA_ARGS) + +# Grab the current parent project and sync it into ourself. +spinoff-update: + @tools/pcommand spinoff_check_submodule_parent + $(MAKE) update + @tools/pcommand echo BLU Pulling current parent project... + git submodule update + @tools/pcommand echo BLU Syncing parent into current project... + tools/spinoff update + @$(MAKE) update-check # Make sure spinoff didn't break anything. + @tools/pcommand echo GRN Spinoff update successful! + +# Upgrade to latest parent project and sync it into ourself. +spinoff-upgrade: + @tools/pcommand spinoff_check_submodule_parent + $(MAKE) update + @tools/pcommand echo BLU Pulling latest parent project... + cd submodules/ballistica && git checkout master && git pull + @tools/pcommand echo BLU Syncing parent into current project... + tools/spinoff update + @$(MAKE) update-check # Make sure spinoff didn't break anything. + @tools/pcommand echo GRN Spinoff upgrade successful! + +# Tell make which of these targets don't represent files. +.PHONY: spinoff-test-empty spinoff-update spinoff-upgrade ################################################################################ diff --git a/src/assets/ba_data/python/baenv.py b/src/assets/ba_data/python/baenv.py index 3f467a07..278773f0 100644 --- a/src/assets/ba_data/python/baenv.py +++ b/src/assets/ba_data/python/baenv.py @@ -30,7 +30,7 @@ if TYPE_CHECKING: # Build number and version of the ballistica binary we expect to be # using. -TARGET_BALLISTICA_BUILD = 21032 +TARGET_BALLISTICA_BUILD = 21034 TARGET_BALLISTICA_VERSION = '1.7.20' _g_env_config: EnvConfig | None = None diff --git a/src/ballistica/shared/ballistica.cc b/src/ballistica/shared/ballistica.cc index a8a65042..cecff518 100644 --- a/src/ballistica/shared/ballistica.cc +++ b/src/ballistica/shared/ballistica.cc @@ -39,7 +39,7 @@ auto main(int argc, char** argv) -> int { namespace ballistica { // These are set automatically via script; don't modify them here. -const int kEngineBuildNumber = 21032; +const int kEngineBuildNumber = 21034; const char* kEngineVersion = "1.7.20"; auto MonolithicMain(const core::CoreConfig& core_config) -> int { diff --git a/tools/batools/pcommand2.py b/tools/batools/pcommand2.py index 4fad15f4..f1775316 100644 --- a/tools/batools/pcommand2.py +++ b/tools/batools/pcommand2.py @@ -12,7 +12,7 @@ from efrotools.pcommand import PROJROOT def gen_monolithic_register_modules() -> None: - """Generate .h file for registering py modules in monolithic builds.""" + """Generate .h file for registering py modules.""" import os import textwrap @@ -309,10 +309,19 @@ def spinoff_test() -> None: import os import subprocess + from efrotools import extract_flag from efro.terminal import Clr from efro.error import CleanError args = sys.argv[2:] + + submodule_parent = extract_flag(args, '--submodule-parent') + + # A spinoff symlink means we're a spun-off project. + if os.path.islink('tools/spinoff'): + raise CleanError( + 'This must be run in a src project; this appears to be a dst.' + ) if len(args) != 1: raise CleanError('Expected 1 arg.') testtype = args[0] @@ -324,23 +333,42 @@ def spinoff_test() -> None: f'...{Clr.RST}', flush=True, ) - subprocess.run(['rm', '-rf', path], check=True) - cmd = [ - './tools/spinoff', - 'create', - 'SpinoffTest', - path, - '--featuresets', - 'none', - ] - # Show the spinoff command we'd use here. - print(Clr.MAG + ' '.join(cmd) + Clr.RST, flush=True) - # Avoid the 'what to do next' help. - subprocess.run( - cmd + ['--noninteractive'], - check=True, - ) - os.makedirs(path, exist_ok=True) + + if os.path.exists(path): + if bool(False): + subprocess.run(['rm', '-rf', path], check=True) + submpath = os.path.join(path, 'submodules/ballistica') + if os.path.exists(submpath): + print( + f'{Clr.BLU}Pulling latest parent submodule' + f' for existing test setup...{Clr.RST}', + flush=True, + ) + subprocess.run( + f'cd "{submpath}" && git checkout master && git pull', + shell=True, + check=True, + ) + + else: + cmd = [ + './tools/spinoff', + 'create', + 'SpinoffTest', + path, + '--featuresets', + 'none', + ] + (['--submodule-parent'] if submodule_parent else []) + + # Show the spinoff command we'd use here. + print(Clr.MAG + ' '.join(cmd) + Clr.RST, flush=True) + + # Avoid the 'what to do next' help. + subprocess.run( + cmd + ['--noninteractive'], + check=True, + ) + print(f'{Clr.MAG}tools/spinoff update{Clr.RST}', flush=True) subprocess.run(['tools/spinoff', 'update'], cwd=path, check=True) # subprocess.run(['make', 'cmake-server-binary'], cwd=path, check=True) @@ -381,3 +409,24 @@ def spinoff_test() -> None: ) else: raise CleanError(f"Invalid test type '{testtype}'.") + + +def spinoff_check_submodule_parent() -> None: + """Make sure this dst proj has a submodule parent.""" + import os + from efro.error import CleanError + + # Make sure we're a spinoff dst project. The spinoff command will be + # a symlink if this is the case. + if not os.path.exists('tools/spinoff'): + raise CleanError( + 'This does not appear to be a spinoff-enabled project.' + ) + if not os.path.islink('tools/spinoff'): + raise CleanError('This project is a spinoff parent; we require a dst.') + + if not os.path.isdir('submodules/ballistica'): + raise CleanError( + 'This project is not using a submodule for its parent.\n' + 'To set one up, run `tools/spinoff add-submodule-parent`' + ) diff --git a/tools/batools/spinoff/_context.py b/tools/batools/spinoff/_context.py index 13bf4dab..c4209d84 100644 --- a/tools/batools/spinoff/_context.py +++ b/tools/batools/spinoff/_context.py @@ -33,8 +33,10 @@ if TYPE_CHECKING: # Tags that default_filter_file() looks for; these can be used to strip # out sections that should never be included in spinoff projects. -STRIP_BEGIN_TAG = '# __SPINOFF_STRIP_BEGIN__' -STRIP_END_TAG = '# __SPINOFF_STRIP_END__' +STRIP_TAG_PAIRS = [ + ('# __SPINOFF_STRIP_BEGIN__', '# __SPINOFF_STRIP_END__'), + ('// __SPINOFF_STRIP_BEGIN__', '// __SPINOFF_STRIP_END__'), +] class SpinoffContext: @@ -703,24 +705,25 @@ class SpinoffContext: """Run default filtering on a file.""" # Strip out any sections frames by our strip-begin/end tags. - if STRIP_BEGIN_TAG in text: + if any(t[0] in text for t in STRIP_TAG_PAIRS): lines = text.splitlines() - while STRIP_BEGIN_TAG in lines: - index = lines.index(STRIP_BEGIN_TAG) - endindex = index - while lines[endindex] != STRIP_END_TAG: - endindex += 1 + for begin_tag, end_tag in STRIP_TAG_PAIRS: + while begin_tag in lines: + index = lines.index(begin_tag) + endindex = index + while lines[endindex] != end_tag: + endindex += 1 - # If the line after us is blank, - # include it too to keep spacing clean. - if ( - len(lines) > (endindex + 1) - and not lines[endindex + 1].strip() - ): - endindex += 1 + # If the line after us is blank, + # include it too to keep spacing clean. + if ( + len(lines) > (endindex + 1) + and not lines[endindex + 1].strip() + ): + endindex += 1 - del lines[index : endindex + 1] + del lines[index : endindex + 1] text = '\n'.join(lines) + '\n' diff --git a/tools/batools/spinoff/_main.py b/tools/batools/spinoff/_main.py index b5601969..d858d940 100644 --- a/tools/batools/spinoff/_main.py +++ b/tools/batools/spinoff/_main.py @@ -8,6 +8,7 @@ import os import sys import subprocess from enum import Enum +from pathlib import Path from typing import assert_never from efro.error import CleanError @@ -31,6 +32,7 @@ class Command(Enum): BACKPORT = 'backport' FEATURESETS = 'featuresets' CREATE = 'create' + ADD_SUBMODULE_PARENT = 'add-submodule-parent' def spinoff_main() -> None: @@ -71,15 +73,6 @@ def _main() -> None: else: src_root = None - # By default we assume our src project is a git submodule at - # submodules/ballistica, but this can be overridden to an arbitrary - # directory via the project localconfig. - # src_proj_val = getlocalconfig(Path(dst_root)).get('spinoff_src') - # if isinstance(src_proj_val, str): - # src_root = src_proj_val - # else: - # src_root = os.path.join(dst_root, 'submodules', 'ballistica') - single_run_mode: SpinoffContext.Mode | None = None if cmd is Command.STATUS: @@ -104,6 +97,11 @@ def _main() -> None: _do_featuresets(dst_root) elif cmd is Command.CREATE: _do_create(src_root, dst_root) + elif cmd is Command.ADD_SUBMODULE_PARENT: + from efrotools import getconfig + + public = getconfig(Path(dst_root))['public'] + _do_add_submodule_parent(dst_root, is_new=False, public=public) else: assert_never(cmd) @@ -130,9 +128,13 @@ def _main() -> None: def _do_create(src_root: str | None, dst_root: str) -> None: + # pylint: disable=too-many-locals from efrotools import extract_arg, extract_flag from efrotools.code import format_python_str + from efrotools import getconfig + # Note: in our case dst_root is actualy what becomes the src project + # should clean up these var names to make that clearer. if src_root is not None: raise CleanError('This only works on src projects.') @@ -149,6 +151,8 @@ def _do_create(src_root: str | None, dst_root: str) -> None: noninteractive = extract_flag(args, '--noninteractive') + submodule_parent = extract_flag(args, '--submodule-parent') + if len(args) != 2: raise CleanError(f'Expected a name and path arg; got {args}.') @@ -170,16 +174,6 @@ def _do_create(src_root: str | None, dst_root: str) -> None: subprocess.run(['mkdir', os.path.join(path, 'tools')], check=True) subprocess.run(['mkdir', os.path.join(path, 'config')], check=True) - subprocess.run( - [ - 'ln', - '-s', - os.path.join(dst_root, 'tools', 'spinoff'), - os.path.join(path, 'tools'), - ], - check=True, - ) - # Read in the dummy module we use as a template. template_path = os.path.join( os.path.dirname(batools.spinoff.__file__), '_config_template.py' @@ -210,6 +204,21 @@ def _do_create(src_root: str | None, dst_root: str) -> None: # on git so its best to always do this. subprocess.run(['git', 'init'], cwd=path, check=True, capture_output=True) + public = getconfig(Path(dst_root))['public'] + + if submodule_parent: + _do_add_submodule_parent(path, is_new=True, public=public) + else: + subprocess.run( + [ + 'ln', + '-s', + os.path.join(dst_root, 'tools', 'spinoff'), + os.path.join(path, 'tools'), + ], + check=True, + ) + # Go with green for interactive use since the command is 'done'. # Otherwise go blue since its probably part of some larger picture. doneclr = Clr.BLU if noninteractive else Clr.GRN @@ -311,36 +320,97 @@ def _print_available_commands() -> None: print( ( 'Available commands:\n' - f' {bgn}status{end} ' + f' {bgn}status{end} ' 'Print list of files update would affect.\n' - f' {bgn}diff{end} ' + f' {bgn}diff{end} ' 'Print diffs for what update would do.\n' - f' {bgn}update{end} ' + f' {bgn}update{end} ' 'Sync all spinoff files from src project.\n' - f' {bgn}check{end} ' + f' {bgn}check{end} ' 'Make sure everything is kosher.\n' - f' {bgn}clean{end} ' + f' {bgn}clean{end} ' 'Remove all spinoff files' - ' (minus a few such as .gitignore).\n' - f' {bgn}cleanlist{end} ' + ' (minus a few exceptions such\n' + ' as .gitignore).\n' + f' {bgn}cleanlist{end} ' 'Shows what clean would do.\n' - f' {bgn}override [file...]{end} ' + f' {bgn}override [file...]{end} ' 'Remove files from spinoff, leaving local copies in place.\n' - f' {bgn}backport [file]{end} ' + f' {bgn}backport [file]{end} ' 'Help get changes to spinoff dst files back to src.\n' - f' {bgn}featuresets{end} ' + f' {bgn}featuresets{end} ' 'List featuresets present in the current project.\n' - f' {bgn}create [name, path]{end} ' + f' {bgn}create [name, path]{end} ' 'Create a new spinoff project based on this src one.\n' - ' Name should be passed in CamelCase form.\n' - ' Use --featuresets a,b to specify included' + ' Name should be passed in CamelCase form.\n' + ' By default, includes all feature-sets from' + ' src.\n' + ' Pass --featuresets a,b to specify included' ' feature-sets.\n' - " Pass 'none' or an empty string for no" + " Use 'none' or an empty string for no" ' featuresets.\n' - ' If unspecified, all src feature-sets will be' - ' included.\n' - ' Pass --noninteractive to suppress help' + ' Pass --noninteractive to suppress help' ' messages.\n' + ' By default, the spinoff project will' + ' directly access this\n' + ' parent project via a local symlink. To' + ' instead set up a\n' + ' git submodule at \'submodules/ballistica\'' + ' in the spinoff\n' + ' project, pass --submodule-parent.\n' + f' {bgn}add-submodule-parent{end} Adds a git submodule parent' + ' to an already existing dst\n' + ' project in the current directory.' + ' The same can be\n' + ' achieved by passing --submodule-parent to' + ' the \'create\'\n' + ' command.' ), file=sys.stderr, ) + + +def _do_add_submodule_parent(dst_root: str, is_new: bool, public: bool) -> None: + if os.path.exists(os.path.join(dst_root, 'submodules/ballistica')): + raise CleanError('This project already has a submodule parent.') + + if not is_new: + if not os.path.islink(os.path.join(dst_root, 'tools/spinoff')): + raise CleanError( + 'Invalid dst project; expected a symlink for tools/spinoff.' + ) + + repo = ( + 'https://github.com/efroemling/ballistica.git' + if public + else 'git@github.com:efroemling/ballistica-internal.git' + ) + + print(f'{Clr.BLU}Setting up parent project submodule...{Clr.RST}') + submodules_root = os.path.join(dst_root, 'submodules') + os.mkdir(submodules_root) + subprocess.run( + [ + 'git', + 'submodule', + 'add', + repo, + 'submodules/ballistica', + ], + cwd=dst_root, + check=True, + ) + subprocess.run( + [ + 'ln', + '-sf', + '../submodules/ballistica/tools/spinoff', + os.path.join(dst_root, 'tools', 'spinoff'), + ], + check=True, + ) + print( + f'{Clr.BLU}Created parent project submodule at' + f' {Clr.RST}{Clr.BLD}submodules/ballistica{Clr.RST}' + f'{Clr.BLU}.{Clr.RST}' + ) diff --git a/tools/pcommand b/tools/pcommand index 2e39eca9..e3720111 100755 --- a/tools/pcommand +++ b/tools/pcommand @@ -123,6 +123,7 @@ from batools.pcommand2 import ( update_cmake_prefab_lib, android_archive_unstripped_libs, spinoff_test, + spinoff_check_submodule_parent, ) # pylint: enable=unused-import