From eb213d6268f6b632ab128c7d5b47dc699749760f Mon Sep 17 00:00:00 2001 From: Eric Date: Wed, 30 Aug 2023 15:26:20 -0700 Subject: [PATCH] functionality for stripping out code in spinoff when a feature-set is not present --- .efrocachemap | 56 +++++++------- CHANGELOG.md | 11 ++- src/assets/ba_data/python/babase/_app.py | 21 ++++-- src/assets/ba_data/python/baenv.py | 2 +- .../ba_data/python/bascenev1lib/mainmenu.py | 9 ++- .../ba_data/python/bauiv1/_subsystem.py | 4 +- .../ba_data/python/bauiv1lib/mainmenu.py | 2 +- .../base/python/class/python_class_env.cc | 1 + .../base/python/methods/python_methods_app.cc | 4 +- .../scene_v1/support/scene_v1_app_mode.cc | 9 +-- src/ballistica/shared/ballistica.cc | 2 +- .../python/methods/python_methods_ui_v1.cc | 28 ++++++- src/ballistica/ui_v1/widget/button_widget.cc | 6 +- tools/batools/spinoff/_context.py | 73 +++++++++++++++---- 14 files changed, 157 insertions(+), 71 deletions(-) diff --git a/.efrocachemap b/.efrocachemap index b5048916..85ec4410 100644 --- a/.efrocachemap +++ b/.efrocachemap @@ -4064,26 +4064,26 @@ "build/assets/windows/Win32/ucrtbased.dll": "2def5335207d41b21b9823f6805997f1", "build/assets/windows/Win32/vc_redist.x86.exe": "b08a55e2e77623fe657bea24f223a3ae", "build/assets/windows/Win32/vcruntime140d.dll": "865b2af4d1e26a1a8073c89acb06e599", - "build/prefab/full/linux_arm64_gui/debug/ballisticakit": "a039bab674a99b559440323b965d2274", - "build/prefab/full/linux_arm64_gui/release/ballisticakit": "fb15d3a3e792163f18af727447564192", - "build/prefab/full/linux_arm64_server/debug/dist/ballisticakit_headless": "246782dc8e1f2114c62980f8addbc4f4", - "build/prefab/full/linux_arm64_server/release/dist/ballisticakit_headless": "8e59c9779e54f22b66ddfe2cd7c21528", - "build/prefab/full/linux_x86_64_gui/debug/ballisticakit": "0c241652d1669e3bbaf8df19c3ae756c", - "build/prefab/full/linux_x86_64_gui/release/ballisticakit": "40ba4e0316c063238ab8e8b94f98351c", - "build/prefab/full/linux_x86_64_server/debug/dist/ballisticakit_headless": "9d80b87c57556a0877f260305f571c78", - "build/prefab/full/linux_x86_64_server/release/dist/ballisticakit_headless": "0e7d5147a5b1b9a7ecb8e6fc4cfc1174", - "build/prefab/full/mac_arm64_gui/debug/ballisticakit": "221c74c7e4cb4d17d8922fdb9bc67246", - "build/prefab/full/mac_arm64_gui/release/ballisticakit": "af9ef217e000fb8e2d7fff8770b7bf44", - "build/prefab/full/mac_arm64_server/debug/dist/ballisticakit_headless": "cb99167ea13b4b452354f54fb8c9279d", - "build/prefab/full/mac_arm64_server/release/dist/ballisticakit_headless": "3f265457324e3a07a676b4db52a5f111", - "build/prefab/full/mac_x86_64_gui/debug/ballisticakit": "9f1982bc3d674e27202521e2fdfe1e26", - "build/prefab/full/mac_x86_64_gui/release/ballisticakit": "c6354818c9abd243e9b9af03f1f075f7", - "build/prefab/full/mac_x86_64_server/debug/dist/ballisticakit_headless": "00b1e678fc49a78ad7dc8758c38d0cb5", - "build/prefab/full/mac_x86_64_server/release/dist/ballisticakit_headless": "c91f0c62c989a33caa7b4b4769754f1a", - "build/prefab/full/windows_x86_gui/debug/BallisticaKit.exe": "9f86ca681c50be1ff449dd28346896c7", - "build/prefab/full/windows_x86_gui/release/BallisticaKit.exe": "1728872a08e4db33e5506839ad8fe227", - "build/prefab/full/windows_x86_server/debug/dist/BallisticaKitHeadless.exe": "99b9add3338ff96d3ffaac7bf490d517", - "build/prefab/full/windows_x86_server/release/dist/BallisticaKitHeadless.exe": "6ff18bb40c63970dbf7d6771b240243c", + "build/prefab/full/linux_arm64_gui/debug/ballisticakit": "d3d9fb45a4c9b2d03c3d8d92b21e391c", + "build/prefab/full/linux_arm64_gui/release/ballisticakit": "4046514b27b8de5eec099669270e760a", + "build/prefab/full/linux_arm64_server/debug/dist/ballisticakit_headless": "1eb01901da8e4e6a9aae10d93e75f669", + "build/prefab/full/linux_arm64_server/release/dist/ballisticakit_headless": "b2bc222a442085ae9e77c4736c1a47c2", + "build/prefab/full/linux_x86_64_gui/debug/ballisticakit": "98cc6c34ae3baf9f03483ecf718f0860", + "build/prefab/full/linux_x86_64_gui/release/ballisticakit": "f55ff138c57aeb6d3b5061b6e5289c89", + "build/prefab/full/linux_x86_64_server/debug/dist/ballisticakit_headless": "47b4af4d42c6ab169bb33d9b1016a321", + "build/prefab/full/linux_x86_64_server/release/dist/ballisticakit_headless": "37b2fd64034132fef6a8f202760fc833", + "build/prefab/full/mac_arm64_gui/debug/ballisticakit": "b4c9e97df51d5cc4f4086c20f75fadea", + "build/prefab/full/mac_arm64_gui/release/ballisticakit": "017b34a328d86dc83a975504c3228a23", + "build/prefab/full/mac_arm64_server/debug/dist/ballisticakit_headless": "f3f4e7aac95d70d36f1458f793df846a", + "build/prefab/full/mac_arm64_server/release/dist/ballisticakit_headless": "5e0c95b6088822a1a8dbb11d889832e3", + "build/prefab/full/mac_x86_64_gui/debug/ballisticakit": "adb8dfd68d6aea6f450b2ad5ccad3d67", + "build/prefab/full/mac_x86_64_gui/release/ballisticakit": "951745d14df5d233952a002468b37efa", + "build/prefab/full/mac_x86_64_server/debug/dist/ballisticakit_headless": "bdd54abe7304f4458867692c28ad1d35", + "build/prefab/full/mac_x86_64_server/release/dist/ballisticakit_headless": "6585700cc49deb2c42c4119042648ebd", + "build/prefab/full/windows_x86_gui/debug/BallisticaKit.exe": "aae37dce0c102274289663de0ac083d5", + "build/prefab/full/windows_x86_gui/release/BallisticaKit.exe": "3c30cbf4fb4bde6ce99f0f287052a4a2", + "build/prefab/full/windows_x86_server/debug/dist/BallisticaKitHeadless.exe": "63bf6d378e6af7f7c02837d201d06a17", + "build/prefab/full/windows_x86_server/release/dist/BallisticaKitHeadless.exe": "85aaa5262f488e0a411d8ca8ec6e8987", "build/prefab/lib/linux_arm64_gui/debug/libballisticaplus.a": "56ebc8c31e020e515395d3a81d2bb766", "build/prefab/lib/linux_arm64_gui/release/libballisticaplus.a": "b9aabf060ca52f9957e5c0c68975dd0d", "build/prefab/lib/linux_arm64_server/debug/libballisticaplus.a": "56ebc8c31e020e515395d3a81d2bb766", @@ -4100,14 +4100,14 @@ "build/prefab/lib/mac_x86_64_gui/release/libballisticaplus.a": "5bfe717b5f30a67822130299b7342bcf", "build/prefab/lib/mac_x86_64_server/debug/libballisticaplus.a": "6c7d4caaad12d39c61b291fe33eef2af", "build/prefab/lib/mac_x86_64_server/release/libballisticaplus.a": "5bfe717b5f30a67822130299b7342bcf", - "build/prefab/lib/windows/Debug_Win32/BallisticaKitGenericPlus.lib": "4bfc1596cb2eea5a3925de63c28be1e1", - "build/prefab/lib/windows/Debug_Win32/BallisticaKitGenericPlus.pdb": "e4b88f921516e864d9b7cb5d346a3c29", - "build/prefab/lib/windows/Debug_Win32/BallisticaKitHeadlessPlus.lib": "b91013c1acf051072c0d9b255ac85d34", - "build/prefab/lib/windows/Debug_Win32/BallisticaKitHeadlessPlus.pdb": "bd0905746e2a31b608409ad289decb06", - "build/prefab/lib/windows/Release_Win32/BallisticaKitGenericPlus.lib": "0ec18bf4b330a9aa06943fcd9fa7ad22", - "build/prefab/lib/windows/Release_Win32/BallisticaKitGenericPlus.pdb": "52c457717ae225929291bfb5c2d73656", - "build/prefab/lib/windows/Release_Win32/BallisticaKitHeadlessPlus.lib": "34d233aa7492cdd7d3c08b5d23875fb0", - "build/prefab/lib/windows/Release_Win32/BallisticaKitHeadlessPlus.pdb": "c597bd1d50530d16a5e920d19f3be226", + "build/prefab/lib/windows/Debug_Win32/BallisticaKitGenericPlus.lib": "facd9669de199a464287b985d9373c0f", + "build/prefab/lib/windows/Debug_Win32/BallisticaKitGenericPlus.pdb": "deff82055a269fa905dd0cd7622adb64", + "build/prefab/lib/windows/Debug_Win32/BallisticaKitHeadlessPlus.lib": "e5ebf7e622ff126bc6b91dd7148fac4f", + "build/prefab/lib/windows/Debug_Win32/BallisticaKitHeadlessPlus.pdb": "ad8c2bae99b72b48a510cdf1ce849358", + "build/prefab/lib/windows/Release_Win32/BallisticaKitGenericPlus.lib": "a5302ab082d0555788b32e7485e07620", + "build/prefab/lib/windows/Release_Win32/BallisticaKitGenericPlus.pdb": "0376b9a3e88c8c7305b33160f11a3de9", + "build/prefab/lib/windows/Release_Win32/BallisticaKitHeadlessPlus.lib": "1260620b96e0615fd993bfa19d5368c8", + "build/prefab/lib/windows/Release_Win32/BallisticaKitHeadlessPlus.pdb": "2ab0357736b91e5be4cd03c153f92c36", "src/assets/ba_data/python/babase/_mgen/__init__.py": "f885fed7f2ed98ff2ba271f9dbe3391c", "src/assets/ba_data/python/babase/_mgen/enums.py": "f8cd3af311ac63147882590123b78318", "src/ballistica/base/mgen/pyembed/binding_base.inc": "ad347097a38e0d7ede9eb6dec6a80ee9", diff --git a/CHANGELOG.md b/CHANGELOG.md index 5f7efab3..d8d10600 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,8 +1,10 @@ -### 1.7.27 (build 21269, api 8, 2023-08-30) +### 1.7.27 (build 21272, api 8, 2023-08-30) - Fixed a rare crash that could occur if the app shuts down while a background thread is making a web request. The app will now try to wait for any such attempts to complete. +- Fixed a bug where PlayerSpaz used `bs.apptime()` where `bs.time()` should have + been used (thanks EraOSBeta!). - Added `babase.app.env` which is a type-friendly object containing various environment/runtime values. Values directly under `app` such as `babase.app.debug_build` will either be consolidated here or moved to classic @@ -20,11 +22,16 @@ deprecation warnings and will disappear sometime soon. This includes `build_number`, `device_name`, `config_file_path`, `version`, `debug_build`, `test_build`, `data_directory`, `python_directory_user`, - `python_directory_app`, `python_directory_app_site`, `api_version`. + `python_directory_app`, `python_directory_app_site`, `api_version`, `on_tv`, + `vr_mode`. - Reverting the Android keyboard changes from 1.7.26, as I've received a few reports of bluetooth game controllers now thinking they are keyboards. I'm thinking I'll have to bite the bullet and implement something that asks the user what the thing is to solve cases like that. +- Added tags allowing easily stripping code out of spinoff projects when a + specific feature-set is not present. For example, for feature-set 'foo', one + can strip lines out by adding `__SPINOFF_REQUIRE_FOO_BEGIN__` and + `__SPINOFF_REQUIRE_FOO_END__` tags. ### 1.7.26 (build 21259, api 8, 2023-08-29) diff --git a/src/assets/ba_data/python/babase/_app.py b/src/assets/ba_data/python/babase/_app.py index e0072b7a..e73e45a3 100644 --- a/src/assets/ba_data/python/babase/_app.py +++ b/src/assets/ba_data/python/babase/_app.py @@ -58,8 +58,6 @@ class App: plugins: PluginSubsystem lang: LanguageSubsystem - env: babase.Env - health_monitor: AppHealthMonitor # How long we allow shutdown tasks to run before killing them. @@ -154,7 +152,6 @@ class App: self.env: babase.Env = _babase.Env() self._subsystems: list[AppSubsystem] = [] - self._native_bootstrapping_completed = False self._init_completed = False self._meta_scan_completed = False @@ -180,8 +177,8 @@ class App: self._env = _babase.env() self.protocol_version: int = self._env['protocol_version'] assert isinstance(self.protocol_version, int) - self.toolbar_test: bool = self._env['toolbar_test'] - assert isinstance(self.toolbar_test, bool) + # self.toolbar_test: bool = self._env['toolbar_test'] + # assert isinstance(self.toolbar_test, bool) self.demo_mode: bool = self._env['demo_mode'] assert isinstance(self.demo_mode, bool) self.arcade_mode: bool = self._env['arcade_mode'] @@ -1000,3 +997,17 @@ class App: stacklevel=2, ) return self.env.vr + + # __SPINOFF_REQUIRE_UI_V1_BEGIN__ + + @property + def toolbar_test(self) -> bool: + """(internal).""" + warnings.warn( + 'app.toolbar_test is deprecated; use app.ui_v1.use_toolbars', + DeprecationWarning, + stacklevel=2, + ) + return self.ui_v1.use_toolbars + + # __SPINOFF_REQUIRE_UI_V1_END__ diff --git a/src/assets/ba_data/python/baenv.py b/src/assets/ba_data/python/baenv.py index 20380121..c59fa57f 100644 --- a/src/assets/ba_data/python/baenv.py +++ b/src/assets/ba_data/python/baenv.py @@ -52,7 +52,7 @@ if TYPE_CHECKING: # Build number and version of the ballistica binary we expect to be # using. -TARGET_BALLISTICA_BUILD = 21269 +TARGET_BALLISTICA_BUILD = 21272 TARGET_BALLISTICA_VERSION = '1.7.27' diff --git a/src/assets/ba_data/python/bascenev1lib/mainmenu.py b/src/assets/ba_data/python/bascenev1lib/mainmenu.py index dce9b4a9..94794cba 100644 --- a/src/assets/ba_data/python/bascenev1lib/mainmenu.py +++ b/src/assets/ba_data/python/bascenev1lib/mainmenu.py @@ -62,7 +62,7 @@ class MainMenuActivity(bs.Activity[bs.Player, bs.Team]): # sees things in their own optimal way. vr_mode = bs.app.env.vr - if not bs.app.toolbar_test: + if not bs.app.ui_v1.use_toolbars: color = (1.0, 1.0, 1.0, 1.0) if vr_mode else (0.5, 0.6, 0.5, 0.6) # FIXME: Need a node attr for vr-specific-scale. @@ -125,7 +125,7 @@ class MainMenuActivity(bs.Activity[bs.Player, bs.Team]): # build number. force_show_build_number = False - if not bs.app.toolbar_test: + if not bs.app.ui_v1.use_toolbars: if env.debug or env.test or force_show_build_number: if env.debug: text = bs.Lstr( @@ -292,7 +292,10 @@ class MainMenuActivity(bs.Activity[bs.Player, bs.Team]): random.seed() - if not (app.demo_mode or app.arcade_mode) and not app.toolbar_test: + if ( + not (app.demo_mode or app.arcade_mode) + and not app.ui_v1.use_toolbars + ): self._news = NewsDisplay(self) # Bring up the last place we were, or start at the main menu otherwise. diff --git a/src/assets/ba_data/python/bauiv1/_subsystem.py b/src/assets/ba_data/python/bauiv1/_subsystem.py index 8349d83a..2d5e8c3f 100644 --- a/src/assets/ba_data/python/bauiv1/_subsystem.py +++ b/src/assets/ba_data/python/bauiv1/_subsystem.py @@ -55,7 +55,9 @@ class UIV1Subsystem(babase.AppSubsystem): self.have_party_queue_window = False self.cleanupchecks: list[UICleanupCheck] = [] self.upkeeptimer: babase.AppTimer | None = None - self.use_toolbars = env.get('toolbar_test', True) + self.use_toolbars = _bauiv1.toolbar_test() + # self.use_toolbars = env.get('toolbar_test', True) + self.title_color = (0.72, 0.7, 0.75) self.heading_color = (0.72, 0.7, 0.75) self.infotextcolor = (0.7, 0.9, 0.7) diff --git a/src/assets/ba_data/python/bauiv1lib/mainmenu.py b/src/assets/ba_data/python/bauiv1lib/mainmenu.py index 78d6b0ea..1ec449f9 100644 --- a/src/assets/ba_data/python/bauiv1lib/mainmenu.py +++ b/src/assets/ba_data/python/bauiv1lib/mainmenu.py @@ -219,7 +219,7 @@ class MainMenuWindow(bui.Window): self._have_store_button = not self._in_game self._have_settings_button = ( - not self._in_game or not app.toolbar_test + not self._in_game or not app.ui_v1.use_toolbars ) and not (self._is_demo or self._is_arcade) self._input_device = input_device = bs.get_ui_input_device() diff --git a/src/ballistica/base/python/class/python_class_env.cc b/src/ballistica/base/python/class/python_class_env.cc index 75a1b0b8..4af103ee 100644 --- a/src/ballistica/base/python/class/python_class_env.cc +++ b/src/ballistica/base/python/class/python_class_env.cc @@ -150,6 +150,7 @@ void PythonClassEnv::SetupType(PyTypeObject* cls) { envs["vr"] = BoolEntry_(g_core->IsVRMode(), "Whether the app is currently running in VR."); + bool first = true; for (auto&& entry : envs) { if (!first) { diff --git a/src/ballistica/base/python/methods/python_methods_app.cc b/src/ballistica/base/python/methods/python_methods_app.cc index e6e42efb..56628c81 100644 --- a/src/ballistica/base/python/methods/python_methods_app.cc +++ b/src/ballistica/base/python/methods/python_methods_app.cc @@ -753,7 +753,7 @@ static auto PyEnv(PyObject* self) -> PyObject* { "ss" // ui_scale "sO" // on_tv "sO" // vr_mode - "sO" // toolbar_test + // "sO" // toolbar_test "sO" // demo_mode "sO" // arcade_mode "sO" // iircade_mode @@ -779,7 +779,7 @@ static auto PyEnv(PyObject* self) -> PyObject* { "ui_scale", ui_scale, "on_tv", g_core->platform->IsRunningOnTV() ? Py_True : Py_False, "vr_mode", g_core->IsVRMode() ? Py_True : Py_False, - "toolbar_test", BA_TOOLBAR_TEST ? Py_True : Py_False, + // "toolbar_test", BA_TOOLBAR_TEST ? Py_True : Py_False, "demo_mode", g_buildconfig.demo_build() ? Py_True : Py_False, "arcade_mode", g_buildconfig.arcade_build() ? Py_True : Py_False, "iircade_mode", g_buildconfig.iircade_build() ? Py_True: Py_False, diff --git a/src/ballistica/scene_v1/support/scene_v1_app_mode.cc b/src/ballistica/scene_v1/support/scene_v1_app_mode.cc index efeaed8f..92b8e5b5 100644 --- a/src/ballistica/scene_v1/support/scene_v1_app_mode.cc +++ b/src/ballistica/scene_v1/support/scene_v1_app_mode.cc @@ -554,13 +554,12 @@ void SceneV1AppMode::UpdateGameRoster() { // ..but only if we have a connected client (otherwise our party is // considered 'empty'). - // UPDATE: starting with our big ui revision we'll always include ourself - // here. bool include_self = (connections()->GetConnectedClientCount() > 0); -#if BA_TOOLBAR_TEST - include_self = true; -#endif // BA_TOOLBAR_TEST + // Previously were gonna enable this with the UI revision. + // #if BA_TOOLBAR_TEST + // include_self = true; + // #endif // BA_TOOLBAR_TEST if (auto* hs = dynamic_cast(GetForegroundSession())) { // Add our host-y self. diff --git a/src/ballistica/shared/ballistica.cc b/src/ballistica/shared/ballistica.cc index 97ec299e..e58f14ab 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 = 21269; +const int kEngineBuildNumber = 21272; const char* kEngineVersion = "1.7.27"; const int kEngineApiVersion = 8; diff --git a/src/ballistica/ui_v1/python/methods/python_methods_ui_v1.cc b/src/ballistica/ui_v1/python/methods/python_methods_ui_v1.cc index e667ffd5..06c1c41f 100644 --- a/src/ballistica/ui_v1/python/methods/python_methods_ui_v1.cc +++ b/src/ballistica/ui_v1/python/methods/python_methods_ui_v1.cc @@ -2821,8 +2821,7 @@ static PyMethodDef PyConsolePrintDef = { // ------------------------ is_party_icon_visible ------------------------------ -static auto PyIsPartyIconVisible(PyObject* self, PyObject* args, - PyObject* keywds) -> PyObject* { +static auto PyIsPartyIconVisible(PyObject* self) -> PyObject* { BA_PYTHON_TRY; bool party_button_active = (g_base->app_mode()->HasConnectionToClients() || g_base->app_mode()->HasConnectionToHost() @@ -2838,13 +2837,35 @@ static auto PyIsPartyIconVisible(PyObject* self, PyObject* args, static PyMethodDef PyIsPartyIconVisibleDef = { "is_party_icon_visible", // name (PyCFunction)PyIsPartyIconVisible, // method - METH_VARARGS | METH_KEYWORDS, // flags + METH_NOARGS, // flags "is_party_icon_visible() -> bool\n" "\n" "(internal)", }; +// ------------------------ is_party_icon_visible ------------------------------ + +static auto PyToolbarTest(PyObject* self) -> PyObject* { + BA_PYTHON_TRY; + if (BA_TOOLBAR_TEST) { + Py_RETURN_TRUE; + } else { + Py_RETURN_FALSE; + } + BA_PYTHON_CATCH; +} + +static PyMethodDef PyToolbarTestDef = { + "toolbar_test", // name + (PyCFunction)PyToolbarTest, // method + METH_NOARGS, // flags + + "toolbar_test() -> bool\n" + "\n" + "(internal)", +}; + // ----------------------------------------------------------------------------- auto PythonMethodsUIV1::GetMethods() -> std::vector { @@ -2880,6 +2901,7 @@ auto PythonMethodsUIV1::GetMethods() -> std::vector { PyGetSoundDef, PyGetTextureDef, PyGetMeshDef, + PyToolbarTestDef, }; } diff --git a/src/ballistica/ui_v1/widget/button_widget.cc b/src/ballistica/ui_v1/widget/button_widget.cc index e0401bb9..df35ab11 100644 --- a/src/ballistica/ui_v1/widget/button_widget.cc +++ b/src/ballistica/ui_v1/widget/button_widget.cc @@ -231,7 +231,7 @@ void ButtonWidget::Draw(base::RenderPass* pass, bool draw_transparent) { float l_border, r_border, b_border, t_border; - bool doDraw = true; + bool do_draw = true; base::MeshAsset* mesh; @@ -255,7 +255,7 @@ void ButtonWidget::Draw(base::RenderPass* pass, bool draw_transparent) { } c.SetMaskTexture(mask_texture_.Get()); } else { - doDraw = false; + do_draw = false; } l_border = r_border = 0.04f * width_; b_border = t_border = 0.04f * height_; @@ -351,7 +351,7 @@ void ButtonWidget::Draw(base::RenderPass* pass, bool draw_transparent) { c.SetTexture(g_base->assets->SysTexture(tex_id)); mesh = g_base->assets->SysMesh(mesh_id); } - if (doDraw) { + if (do_draw) { c.PushTransform(); c.Translate((l - l_border + r + r_border) * 0.5f + extra_offs_x, (b - b_border + t + t_border) * 0.5f + extra_offs_y, 0); diff --git a/tools/batools/spinoff/_context.py b/tools/batools/spinoff/_context.py index 155a9564..1c2b60c2 100644 --- a/tools/batools/spinoff/_context.py +++ b/tools/batools/spinoff/_context.py @@ -33,13 +33,6 @@ if TYPE_CHECKING: from batools.project import ProjectUpdater -# Tags that default_filter_file() looks for; these can be used to strip -# out sections that should never be included in spinoff projects. -STRIP_TAG_PAIRS: list[tuple[str, str]] = [ - ('# __SPINOFF_STRIP_BEGIN__', '# __SPINOFF_STRIP_END__'), - ('// __SPINOFF_STRIP_BEGIN__', '// __SPINOFF_STRIP_END__'), -] - class SpinoffContext: """Guts of the spinoff system.""" @@ -120,6 +113,27 @@ class SpinoffContext: f.name: f for f in FeatureSet.get_all_for_project(self._src_root) } + # Generate our list of tags for selectively stripping out code. + # __SPINOFF_STRIP_BEGIN__ / __SPINOFF_STRIP_END__ will *always* + # strip code in spinoff projects and + # __SPINOFF_REQUIRE_FOO_BEGIN__ / __SPINOFF_REQUIRE_FOO_END__ will + # strip code only when feature-set foo is not present in the + # spinoff project. + + # begin-tag / end-tag / associated-feature-set-name + self._strip_tags: list[tuple[str, str, str | None]] = [ + ('__SPINOFF_STRIP_BEGIN__', '__SPINOFF_STRIP_END__', None) + ] + for fsetname in sorted(self._src_all_feature_sets.keys()): + fnsu = fsetname.upper() + self._strip_tags.append( + ( + f'__SPINOFF_REQUIRE_{fnsu}_BEGIN__', + f'__SPINOFF_REQUIRE_{fnsu}_END__', + fsetname, + ) + ) + self._src_git_files: set[str] | None = None self._dst_git_files: set[str] | None = None self._dst_git_file_dirs: set[str] | None = None @@ -259,7 +273,10 @@ class SpinoffContext: # Based on feature-sets they requested, calc which feature-sets # from src we *exclude*. - self._src_omit_feature_sets = self._calc_src_omit_feature_sets() + ( + self._src_retain_feature_sets, + self._src_omit_feature_sets, + ) = self._calc_src_retain_omit_feature_sets() # Generate a version of src_omit_paths that includes our feature-set # omissions. Basically, omitting a feature set simply omits @@ -289,10 +306,10 @@ class SpinoffContext: self._sanity_test_setup() self._generate_env_hash() - def _calc_src_omit_feature_sets(self) -> set[str]: + def _calc_src_retain_omit_feature_sets(self) -> tuple[set[str], set[str]]: # If they want everything, omit nothing. if self.src_feature_sets is None: - return set() + return set(self._src_all_feature_sets.keys()), set() # Based on the requested set, calc the total sets we'll need. # Also always include 'core' since we'd be totally broken @@ -303,7 +320,8 @@ class SpinoffContext: ) # Now simply return any sets *not* included in our resolved set. - return {s for s in self._src_all_feature_sets.keys() if s not in reqs} + omits = {s for s in self._src_all_feature_sets.keys() if s not in reqs} + return (reqs, omits) def _add_feature_set_omit_paths(self, paths: set[str]) -> None: for fsname in sorted(self._src_omit_feature_sets): @@ -725,14 +743,37 @@ class SpinoffContext: # pylint: disable=too-many-branches # Strip out any sections frames by our strip-begin/end tags. - if any(t[0] in text for t in STRIP_TAG_PAIRS): + + # strip_tag_pairs: list[tuple[str, str]] = [] + # print('HELLO WORLD') + + def _first_index_containing_string( + items: list[str], substring: str + ) -> int | None: + for f_index, f_item in enumerate(items): + if substring in f_item: + return f_index + return None + + # Quick-out if no begin-tags are found in the entire text. + if any(t[0] in text for t in self._strip_tags): lines = text.splitlines() - for begin_tag, end_tag in STRIP_TAG_PAIRS: - while begin_tag in lines: - index = lines.index(begin_tag) + for begin_tag, end_tag, fsetname in self._strip_tags: + # For sections requiring a specific fset, don't touch + # it if we're keeping that set. + if ( + fsetname is not None + and fsetname in self._src_retain_feature_sets + ): + continue + while ( + index := _first_index_containing_string(lines, begin_tag) + ) is not None: + # while begin_tag in lines: + # index = lines.index(begin_tag) endindex = index - while lines[endindex] != end_tag: + while end_tag not in lines[endindex]: endindex += 1 # If the line after us is blank,