From 6b568d49a18708c55b4532857bf5e0686ffb9382 Mon Sep 17 00:00:00 2001 From: Eric Date: Thu, 17 Aug 2023 10:17:01 -0700 Subject: [PATCH] wiring more stuff up to use pcommandbatch --- .efrocachemap | 88 +++++++++---------- .idea/dictionaries/ericf.xml | 1 + .../.idea/dictionaries/ericf.xml | 1 + config/spinoffconfig.py | 1 - src/assets/Makefile | 18 +++- src/tools/pcommandbatch/pcommandbatch.c | 30 +++++-- tools/batools/assetsmakefile.py | 11 +-- tools/batools/pcommands.py | 2 +- tools/efrotools/pcommand.py | 36 ++++++-- tools/efrotools/pcommandbatch.py | 23 +++-- tools/efrotools/pcommands.py | 81 +++++++++++++++-- tools/efrotools/pcommands2.py | 2 + tools/pcommand | 5 ++ 13 files changed, 213 insertions(+), 86 deletions(-) diff --git a/.efrocachemap b/.efrocachemap index f3a60421..4c0a634e 100644 --- a/.efrocachemap +++ b/.efrocachemap @@ -4068,50 +4068,50 @@ "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": "c26b65a24311880c74d69c4983b22ece", - "build/prefab/full/linux_arm64_gui/release/ballisticakit": "b5f0703ed12ca1a25200b5d4114909df", - "build/prefab/full/linux_arm64_server/debug/dist/ballisticakit_headless": "02f6cf0e2fe78cc1ac9c8e3094f60079", - "build/prefab/full/linux_arm64_server/release/dist/ballisticakit_headless": "1468af4af839e714c2d622caee6b9181", - "build/prefab/full/linux_x86_64_gui/debug/ballisticakit": "1464adfba201f6fcf79d54068a915409", - "build/prefab/full/linux_x86_64_gui/release/ballisticakit": "60fdad12226023caa043da4685831c8a", - "build/prefab/full/linux_x86_64_server/debug/dist/ballisticakit_headless": "ac01bff1450ed6b66bb77d8b0af6e84f", - "build/prefab/full/linux_x86_64_server/release/dist/ballisticakit_headless": "58cf449ec84b211b0bb38d1d1358c974", - "build/prefab/full/mac_arm64_gui/debug/ballisticakit": "6da4ad354507711c5857c81e3bed4e33", - "build/prefab/full/mac_arm64_gui/release/ballisticakit": "d642aeeaeffdd5ebe07e968be2311da5", - "build/prefab/full/mac_arm64_server/debug/dist/ballisticakit_headless": "0800f2ca27c13408afbb75b5bdf76bae", - "build/prefab/full/mac_arm64_server/release/dist/ballisticakit_headless": "e008727c4b62b7ef09c775b505cee886", - "build/prefab/full/mac_x86_64_gui/debug/ballisticakit": "ef184ee79f268744612130743cf8369d", - "build/prefab/full/mac_x86_64_gui/release/ballisticakit": "c1ea1a2c7362b2a47b5f55f8ff112c61", - "build/prefab/full/mac_x86_64_server/debug/dist/ballisticakit_headless": "7997bb41bb8db4a2aa1105c498787c41", - "build/prefab/full/mac_x86_64_server/release/dist/ballisticakit_headless": "939d32d2010fbcd76398fb9a08ac9152", - "build/prefab/full/windows_x86_gui/debug/BallisticaKit.exe": "b35c2813cfa23a4d4c58f50b71617f69", - "build/prefab/full/windows_x86_gui/release/BallisticaKit.exe": "48eeea81dc9bba2fe9d8afae1c163b69", - "build/prefab/full/windows_x86_server/debug/dist/BallisticaKitHeadless.exe": "4ae9e07d5d7b61bb5c019badfbef37a5", - "build/prefab/full/windows_x86_server/release/dist/BallisticaKitHeadless.exe": "95bbece528dfa908838caf48a496dca6", - "build/prefab/lib/linux_arm64_gui/debug/libballisticaplus.a": "2c39f4296ba083f11168beaa56256909", - "build/prefab/lib/linux_arm64_gui/release/libballisticaplus.a": "02b17ff1ab03fb4a526ef85186baf9b3", - "build/prefab/lib/linux_arm64_server/debug/libballisticaplus.a": "2c39f4296ba083f11168beaa56256909", - "build/prefab/lib/linux_arm64_server/release/libballisticaplus.a": "02b17ff1ab03fb4a526ef85186baf9b3", - "build/prefab/lib/linux_x86_64_gui/debug/libballisticaplus.a": "9a78f6330fea20ba8343b09a339595f1", - "build/prefab/lib/linux_x86_64_gui/release/libballisticaplus.a": "5a3358818ebea17293a1090d295e1047", - "build/prefab/lib/linux_x86_64_server/debug/libballisticaplus.a": "9a78f6330fea20ba8343b09a339595f1", - "build/prefab/lib/linux_x86_64_server/release/libballisticaplus.a": "5a3358818ebea17293a1090d295e1047", - "build/prefab/lib/mac_arm64_gui/debug/libballisticaplus.a": "6cc12ac10a557a546b6a9c3fd0792af0", - "build/prefab/lib/mac_arm64_gui/release/libballisticaplus.a": "e1fbd7e130511cd8690e0da886910d1a", - "build/prefab/lib/mac_arm64_server/debug/libballisticaplus.a": "6cc12ac10a557a546b6a9c3fd0792af0", - "build/prefab/lib/mac_arm64_server/release/libballisticaplus.a": "e1fbd7e130511cd8690e0da886910d1a", - "build/prefab/lib/mac_x86_64_gui/debug/libballisticaplus.a": "758dea018f7a06c611b9cff20e7d064f", - "build/prefab/lib/mac_x86_64_gui/release/libballisticaplus.a": "9355211cad3fae2a29eb8016f7cc062c", - "build/prefab/lib/mac_x86_64_server/debug/libballisticaplus.a": "6d309fba1c355902662343b627b6aa8c", - "build/prefab/lib/mac_x86_64_server/release/libballisticaplus.a": "9355211cad3fae2a29eb8016f7cc062c", - "build/prefab/lib/windows/Debug_Win32/BallisticaKitGenericPlus.lib": "e3085c83263ccc1c13e1bb344f0a7c8e", - "build/prefab/lib/windows/Debug_Win32/BallisticaKitGenericPlus.pdb": "38a1826608e0829e25ceded2e5a8e50d", - "build/prefab/lib/windows/Debug_Win32/BallisticaKitHeadlessPlus.lib": "9b3612f4c807362baf25daed9bd8ab01", - "build/prefab/lib/windows/Debug_Win32/BallisticaKitHeadlessPlus.pdb": "671c648cb9d8f257033b6c203e33aab8", - "build/prefab/lib/windows/Release_Win32/BallisticaKitGenericPlus.lib": "6b926b48877a0ecef54107be894f5dc2", - "build/prefab/lib/windows/Release_Win32/BallisticaKitGenericPlus.pdb": "15d1aec51cf77095399b46b7a5da5880", - "build/prefab/lib/windows/Release_Win32/BallisticaKitHeadlessPlus.lib": "b5b4cf9234f0f4f8d657f2a98364aba9", - "build/prefab/lib/windows/Release_Win32/BallisticaKitHeadlessPlus.pdb": "8418ee35e7ae3d6564df2c011b8e5838", + "build/prefab/full/linux_arm64_gui/debug/ballisticakit": "1629179fc405896247a0bceeb8f3c446", + "build/prefab/full/linux_arm64_gui/release/ballisticakit": "4f8983cbe31b742d16d675b70a701efd", + "build/prefab/full/linux_arm64_server/debug/dist/ballisticakit_headless": "cb32354e389617f4181feaf1c52f38f4", + "build/prefab/full/linux_arm64_server/release/dist/ballisticakit_headless": "b69793b8a89aee749af98e48e1af635b", + "build/prefab/full/linux_x86_64_gui/debug/ballisticakit": "11901eac902eeb5cf1764013979f1f2c", + "build/prefab/full/linux_x86_64_gui/release/ballisticakit": "fa0c68f8c4a39638f9aeffb2065499b6", + "build/prefab/full/linux_x86_64_server/debug/dist/ballisticakit_headless": "07f5f9251718f8b130567cb4118b6ff9", + "build/prefab/full/linux_x86_64_server/release/dist/ballisticakit_headless": "1788b53fc7216b1f29729fe834f29e33", + "build/prefab/full/mac_arm64_gui/debug/ballisticakit": "3c20375d5a1c39e98800585b00d3f451", + "build/prefab/full/mac_arm64_gui/release/ballisticakit": "3dbc1132cdca65114028a473b2fbc3f2", + "build/prefab/full/mac_arm64_server/debug/dist/ballisticakit_headless": "cb76e40fe65b031c6fc1500f2a8b4475", + "build/prefab/full/mac_arm64_server/release/dist/ballisticakit_headless": "a3819f1db78636a4e10f7355abb9c6d5", + "build/prefab/full/mac_x86_64_gui/debug/ballisticakit": "0f341e3f75e7a10e448a2ee5f545848c", + "build/prefab/full/mac_x86_64_gui/release/ballisticakit": "a134aeb2c8428f7cd8b2afb53ca6606a", + "build/prefab/full/mac_x86_64_server/debug/dist/ballisticakit_headless": "0550721ee0b498144a54fa7c0ceb9666", + "build/prefab/full/mac_x86_64_server/release/dist/ballisticakit_headless": "18cd688e4d9c852d9ee6adaa191a773b", + "build/prefab/full/windows_x86_gui/debug/BallisticaKit.exe": "0b9a6a07dce21e96ac48cf49b5b40342", + "build/prefab/full/windows_x86_gui/release/BallisticaKit.exe": "c45e14c71ce4b650565bfbc418c0f1f3", + "build/prefab/full/windows_x86_server/debug/dist/BallisticaKitHeadless.exe": "1ed75e05401fce08e797a98c12f31c52", + "build/prefab/full/windows_x86_server/release/dist/BallisticaKitHeadless.exe": "c9195366171b0b9d655e0e4a26ee9417", + "build/prefab/lib/linux_arm64_gui/debug/libballisticaplus.a": "85ba4e81a1f7ae2cff4b1355eb49904f", + "build/prefab/lib/linux_arm64_gui/release/libballisticaplus.a": "498921f7eb2afd327d4b900cb70e31f9", + "build/prefab/lib/linux_arm64_server/debug/libballisticaplus.a": "85ba4e81a1f7ae2cff4b1355eb49904f", + "build/prefab/lib/linux_arm64_server/release/libballisticaplus.a": "498921f7eb2afd327d4b900cb70e31f9", + "build/prefab/lib/linux_x86_64_gui/debug/libballisticaplus.a": "ded5f785236bf64e644ee20041ac8342", + "build/prefab/lib/linux_x86_64_gui/release/libballisticaplus.a": "c436a058b7204fa39f22eafc7ca7855f", + "build/prefab/lib/linux_x86_64_server/debug/libballisticaplus.a": "ded5f785236bf64e644ee20041ac8342", + "build/prefab/lib/linux_x86_64_server/release/libballisticaplus.a": "c436a058b7204fa39f22eafc7ca7855f", + "build/prefab/lib/mac_arm64_gui/debug/libballisticaplus.a": "fe0ba4b21528a557c5a434b8f2eeda41", + "build/prefab/lib/mac_arm64_gui/release/libballisticaplus.a": "7950a02c3d9a1088e9acd4c29bd3cb72", + "build/prefab/lib/mac_arm64_server/debug/libballisticaplus.a": "fe0ba4b21528a557c5a434b8f2eeda41", + "build/prefab/lib/mac_arm64_server/release/libballisticaplus.a": "7950a02c3d9a1088e9acd4c29bd3cb72", + "build/prefab/lib/mac_x86_64_gui/debug/libballisticaplus.a": "870d11d339fd1b3acf66cc601ff29c83", + "build/prefab/lib/mac_x86_64_gui/release/libballisticaplus.a": "0ab638b6602610bdaf432e3cc2464080", + "build/prefab/lib/mac_x86_64_server/debug/libballisticaplus.a": "92394eb19387c363471ce134ac9e6a1b", + "build/prefab/lib/mac_x86_64_server/release/libballisticaplus.a": "0ab638b6602610bdaf432e3cc2464080", + "build/prefab/lib/windows/Debug_Win32/BallisticaKitGenericPlus.lib": "50e765d3311e1ebad4c8345367fdc732", + "build/prefab/lib/windows/Debug_Win32/BallisticaKitGenericPlus.pdb": "8f7eaf90f31ba1eae2d826c30f856f0c", + "build/prefab/lib/windows/Debug_Win32/BallisticaKitHeadlessPlus.lib": "b4643b6746e296f7556d60a0bb3ae301", + "build/prefab/lib/windows/Debug_Win32/BallisticaKitHeadlessPlus.pdb": "4891adddcabbbb62b837e3af63a4ee05", + "build/prefab/lib/windows/Release_Win32/BallisticaKitGenericPlus.lib": "988e180dbd2259c975262244ed18f467", + "build/prefab/lib/windows/Release_Win32/BallisticaKitGenericPlus.pdb": "c27456c1f1485e7d8457cda051afd607", + "build/prefab/lib/windows/Release_Win32/BallisticaKitHeadlessPlus.lib": "1156d006f762ca1d8e7266957d5190b0", + "build/prefab/lib/windows/Release_Win32/BallisticaKitHeadlessPlus.pdb": "ae8d248251abed94d56285757c434990", "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": "eeddad968b176000e31c65be6206a2bc", diff --git a/.idea/dictionaries/ericf.xml b/.idea/dictionaries/ericf.xml index fbe3d896..6a80f527 100644 --- a/.idea/dictionaries/ericf.xml +++ b/.idea/dictionaries/ericf.xml @@ -2469,6 +2469,7 @@ representer reprlib repro + reqdata reqs reqtype reqtypes diff --git a/ballisticakit-cmake/.idea/dictionaries/ericf.xml b/ballisticakit-cmake/.idea/dictionaries/ericf.xml index fc4b2764..f61aea1a 100644 --- a/ballisticakit-cmake/.idea/dictionaries/ericf.xml +++ b/ballisticakit-cmake/.idea/dictionaries/ericf.xml @@ -1470,6 +1470,7 @@ rené reprfunc repro + reqdata requireable rerase resends diff --git a/config/spinoffconfig.py b/config/spinoffconfig.py index 275ccdfa..64dac935 100644 --- a/config/spinoffconfig.py +++ b/config/spinoffconfig.py @@ -172,7 +172,6 @@ ctx.filter_file_names = { 'assets_phase_xcode', 'ballistica_maya_tools.mel', 'check_python_syntax', - 'compile_python_file', 'pcommand', 'vmshell', 'cloudshell', diff --git a/src/assets/Makefile b/src/assets/Makefile index caf6ee97..4b1970c0 100644 --- a/src/assets/Makefile +++ b/src/assets/Makefile @@ -150,7 +150,6 @@ ASSET_TARGETS_WIN_X64 += $(EXTRAS_TARGETS_WIN_X64) # Note: Code below needs updating when Python version changes (currently 3.11) define make-opt-pyc-target $1: $$(subst /__pycache__,,$$(subst .cpython-311.opt-1.pyc,.py,$1)) -# @echo Compiling script: $$(subst $(BUILD_DIR)/,,$$^) @$$(PCOMMANDBATCH) compile_python_file $$^ endef @@ -702,7 +701,6 @@ SCRIPT_TARGETS_PYC_PUBLIC = \ # Rule to copy src asset scripts to dst. # (and make non-writable so I'm less likely to accidentally edit them there) $(SCRIPT_TARGETS_PY_PUBLIC) : $(BUILD_DIR)/%.py : %.py -# @echo Copying script: $(subst $(BUILD_DIR)/,,$@) @$(PCOMMANDBATCH) copy_python_file $^ $@ # These are too complex to define in a pattern rule; @@ -781,7 +779,6 @@ SCRIPT_TARGETS_PYC_PUBLIC_TOOLS = \ # Rule to copy src asset scripts to dst. # (and make non-writable so I'm less likely to accidentally edit them there) $(SCRIPT_TARGETS_PY_PUBLIC_TOOLS) : $(BUILD_DIR)/ba_data/python/%.py : $(TOOLS_DIR)/%.py -# @echo Copying script: $(subst $(BUILD_DIR)/,,$@) @$(PCOMMANDBATCH) copy_python_file $^ $@ # These are too complex to define in a pattern rule; @@ -7423,6 +7420,21 @@ ba_data/%.tex2d.png : ../../.efrocachemap ba_data/%_+x.tex2d.png : ../../.efrocachemap @cd ../.. && tools/pcommand efrocache_get src/assets/$@ +ba_data/%_-x.tex2d.png: ../../.efrocachemap + @cd ../.. && tools/pcommand efrocache_get src/assets/$@ + +ba_data/%_+y.tex2d.png: ../../.efrocachemap + @cd ../.. && tools/pcommand efrocache_get src/assets/$@ + +ba_data/%_-y.tex2d.png: ../../.efrocachemap + @cd ../.. && tools/pcommand efrocache_get src/assets/$@ + +ba_data/%_+z.tex2d.png: ../../.efrocachemap + @cd ../.. && tools/pcommand efrocache_get src/assets/$@ + +ba_data/%_-z.tex2d.png: ../../.efrocachemap + @cd ../.. && tools/pcommand efrocache_get src/assets/$@ + $(BUILD_DIR)/ba_data/%_preview.png : ../../.efrocachemap @cd ../.. && tools/pcommand efrocache_get src/assets/$@ diff --git a/src/tools/pcommandbatch/pcommandbatch.c b/src/tools/pcommandbatch/pcommandbatch.c index 07e38b59..57c4de64 100644 --- a/src/tools/pcommandbatch/pcommandbatch.c +++ b/src/tools/pcommandbatch/pcommandbatch.c @@ -24,6 +24,7 @@ struct Context_ { const char* state_dir_path; + const char* project_dir_path; const char* instance_prefix; int instance_num; int pid; @@ -46,9 +47,6 @@ int main(int argc, char** argv) { struct Context_ ctx; memset(&ctx, 0, sizeof(ctx)); - ctx.state_dir_path = NULL; - ctx.instance_prefix = NULL; - ctx.pcommandpath = NULL; ctx.server_idle_seconds = 5; ctx.pid = getpid(); @@ -221,10 +219,11 @@ int establish_connection_(const struct Context_* ctx) { } char buf[512]; snprintf(buf, sizeof(buf), - "%s run_pcommandbatch_server --timeout %d --state-dir %s " - "--instance %s_%d %s", - ctx->pcommandpath, ctx->server_idle_seconds, ctx->state_dir_path, - ctx->instance_prefix, ctx->instance_num, endbuf); + "%s run_pcommandbatch_server --timeout %d --project-dir %s" + " --state-dir %s --instance %s_%d %s", + ctx->pcommandpath, ctx->server_idle_seconds, ctx->project_dir_path, + ctx->state_dir_path, ctx->instance_prefix, ctx->instance_num, + endbuf); system(buf); // Spin and wait up to a few seconds for the file to appear. @@ -327,12 +326,14 @@ int calc_paths_(struct Context_* ctx) { // this is project-root and src/assets if (path_exists_("config/projectconfig.json")) { // Looks like we're in project root. + ctx->project_dir_path = "."; ctx->state_dir_path = ".cache/pcommandbatch"; ctx->instance_prefix = "root"; ctx->pcommandpath = "tools/pcommand"; } else if (path_exists_("ba_data") && path_exists_("../../config/projectconfig.json")) { // Looks like we're in src/assets. + ctx->project_dir_path = "../.."; ctx->state_dir_path = "../../.cache/pcommandbatch"; ctx->instance_prefix = "assets"; ctx->pcommandpath = "../../tools/pcommand"; @@ -362,16 +363,27 @@ int calc_paths_(struct Context_* ctx) { // instance that spins up worker instances as needed. Though such a fancy // setup might be overkill. ctx->instance_num = rand() % 6; + + // I was wondering if using pid would lead to a more even distribution, + // but it didn't make a significant difference in my tests. And I worry + // there would be some odd corner case where pid isn't going up evenly, so + // sticking with rand() for now. ctx->instance_num = ctx->pid % 6; return 0; } int send_command_(struct Context_* ctx, int argc, char** argv) { // Build a json array of our args. + cJSON* req = cJSON_CreateObject(); cJSON* array = cJSON_CreateArray(); for (int i = 0; i < argc; ++i) { cJSON_AddItemToArray(array, cJSON_CreateString(argv[i])); } - char* json_out = cJSON_Print(array); + cJSON_AddItemToObject(req, "a", array); + cJSON_AddItemToObject(req, "t", + isatty(1) ? cJSON_CreateTrue() : cJSON_CreateFalse()); + cJSON_AddItemToObject(req, "t", + isatty(1) ? cJSON_CreateTrue() : cJSON_CreateFalse()); + char* json_out = cJSON_Print(req); // Send our command. int msglen = strlen(json_out); @@ -393,7 +405,7 @@ int send_command_(struct Context_* ctx, int argc, char** argv) { // Clean up our mess after we've sent them on their way. free(json_out); - cJSON_Delete(array); + cJSON_Delete(req); return 0; } diff --git a/tools/batools/assetsmakefile.py b/tools/batools/assetsmakefile.py index fb775d9f..728b21ac 100755 --- a/tools/batools/assetsmakefile.py +++ b/tools/batools/assetsmakefile.py @@ -265,7 +265,7 @@ def _get_py_targets_subset( '# (and make non-writable so I\'m less likely to ' 'accidentally edit them there)\n' f'{efc}$(SCRIPT_TARGETS_PY{suffix}) : {copyrule}\n' - '#\t@echo Copying script: $(subst $(BUILD_DIR)/,,$@)\n' + # '#\t@echo Copying script: $(subst $(BUILD_DIR)/,,$@)\n' '\t@$(PCOMMANDBATCH) copy_python_file $^ $@\n' ) @@ -395,10 +395,11 @@ def _get_extras_targets_win( f'# __EFROCACHE_TARGET__\n' f'$(EXTRAS_TARGETS_WIN_{p_up}) : $(BUILD_DIR)/% :' ' %\n' - '\t@echo Copying file: $(subst $(BUILD_DIR)/,,$@)\n' - '\t@mkdir -p $(dir $@)\n' - '\t@rm -f $@\n' - '\t@cp $^ $@\n' + '\t@$(PCOMMANDBATCH) copy_win_extra_file $^ $@\n' + # '\t@echo Copying file: $(subst $(BUILD_DIR)/,,$@)\n' + # '\t@mkdir -p $(dir $@)\n' + # '\t@rm -f $@\n' + # '\t@cp $^ $@\n' ) return out diff --git a/tools/batools/pcommands.py b/tools/batools/pcommands.py index e68b9540..0b2d8a29 100644 --- a/tools/batools/pcommands.py +++ b/tools/batools/pcommands.py @@ -785,7 +785,7 @@ def stage_build() -> None: try: batools.staging.stage_build( - projroot=str(pcommand.PROJROOT), args=sys.argv[2:] + projroot=str(pcommand.PROJROOT), args=pcommand.get_args() ) except CleanError as exc: exc.pretty_print() diff --git a/tools/efrotools/pcommand.py b/tools/efrotools/pcommand.py index ccd3d9d4..1a255dc7 100644 --- a/tools/efrotools/pcommand.py +++ b/tools/efrotools/pcommand.py @@ -18,6 +18,8 @@ if TYPE_CHECKING: import threading from typing import Any + from efro.terminal import ClrBase + # Absolute path of the project root. PROJROOT = Path(__file__).resolve().parents[2] @@ -76,6 +78,22 @@ def get_args() -> list[str]: return argv[2:] +def clr() -> type[ClrBase]: + """Like efro.terminal.Clr but works correctly under pcommandbatch.""" + import efro.terminal + + # Note: currently just using the 'isatty' value from the client. + # ideally should expand the client-side logic to exactly match what + # efro.terminal.Clr does locally. + if _g_batch_server_mode: + assert _g_thread_local_storage is not None + isatty = _g_thread_local_storage.isatty + assert isinstance(isatty, bool) + return efro.terminal.ClrAlways if isatty else efro.terminal.ClrNever + + return efro.terminal.Clr + + def set_output(output: str, newline: bool = True) -> None: """Set an output string for the current pcommand. @@ -103,12 +121,6 @@ def _run_pcommand(sysargv: list[str]) -> int: assert _g_funcs is not None - # If we're in batch mode, stuff these args into our thread-local - # storage. - if _g_batch_server_mode: - assert _g_thread_local_storage is not None - _g_thread_local_storage.argv = sysargv - retval = 0 show_help = False if len(sysargv) < 2: @@ -192,7 +204,9 @@ def is_batch() -> bool: return _g_batch_server_mode -def run_client_pcommand(args: list[str], log_path: str) -> tuple[int, str]: +def run_client_pcommand( + args: list[str], log_path: str, isatty: bool +) -> tuple[int, str]: """Call a pcommand function when running as a batch server.""" assert _g_batch_server_mode assert _g_thread_local_storage is not None @@ -203,6 +217,11 @@ def run_client_pcommand(args: list[str], log_path: str) -> tuple[int, str]: if hasattr(_g_thread_local_storage, 'output'): delattr(_g_thread_local_storage, 'output') + # Stuff args into our thread-local storage so the user can get at + # them. + _g_thread_local_storage.argv = args + _g_thread_local_storage.isatty = isatty + # Run the command. resultcode: int = _run_pcommand(args) @@ -214,7 +233,8 @@ def run_client_pcommand(args: list[str], log_path: str) -> tuple[int, str]: output += '\n' output += ( f'Error: pcommandbatch command failed: {args}.' - f" See '{log_path}' for more info.\n" + f" For more info, see '{log_path}', or rerun with" + ' env var BA_PCOMMANDBATCH_DISABLE=1 to see all output here.\n' ) assert isinstance(output, str) diff --git a/tools/efrotools/pcommandbatch.py b/tools/efrotools/pcommandbatch.py index 19801104..1093a9dd 100644 --- a/tools/efrotools/pcommandbatch.py +++ b/tools/efrotools/pcommandbatch.py @@ -117,7 +117,7 @@ def build_pcommandbatch(inpaths: list[str], outpath: str) -> None: def run_pcommandbatch_server( - idle_timeout_secs: int, state_dir: str, instance: str + idle_timeout_secs: int, project_dir: str, state_dir: str, instance: str ) -> None: """Run a server for handling batches of pcommands. @@ -135,6 +135,7 @@ def run_pcommandbatch_server( # just keep the existing ones. server = Server( idle_timeout_secs=idle_timeout_secs, + project_dir=project_dir, state_dir=state_dir, instance=instance, daemon=use_daemon, @@ -159,11 +160,13 @@ class Server: def __init__( self, idle_timeout_secs: int, + project_dir: str, state_dir: str, instance: str, daemon: bool, ) -> None: self._daemon = daemon + self._project_dir = project_dir self._state_dir = state_dir self._idle_timeout_secs = idle_timeout_secs self._worker_state_file_path = f'{state_dir}/worker_state_{instance}' @@ -178,11 +181,6 @@ class Server: self._spinup_lock = filelock.FileLock(self._spinup_lock_path) self._server_error: str | None = None - # def __del__(self) -> None: - # if self._spinup_lock.is_locked: - # self._spinup_lock.release() - # pass - def run(self) -> None: """Do the thing.""" @@ -310,9 +308,13 @@ class Server: self._client_count_since_last_check += 1 self._running_client_count += 1 try: - argv: list[str] = json.loads((await reader.read()).decode()) + reqdata: dict = json.loads((await reader.read()).decode()) + assert isinstance(reqdata, dict) + argv: list[str] = reqdata['a'] assert isinstance(argv, list) assert all(isinstance(i, str) for i in argv) + isatty: bool = reqdata['t'] + assert isinstance(isatty, bool) print( f'pcommandbatch server {self._instance} (pid {self._pid})' @@ -332,7 +334,12 @@ class Server: ) = await asyncio.get_running_loop().run_in_executor( None, lambda: run_client_pcommand( - argv, self._worker_log_file_path + argv, + # Show log file path relative to project. + self._worker_log_file_path.removeprefix( + f'{self._project_dir}/' + ), + isatty, ), ) if VERBOSE: diff --git a/tools/efrotools/pcommands.py b/tools/efrotools/pcommands.py index d46f4d30..f7e0d3a6 100644 --- a/tools/efrotools/pcommands.py +++ b/tools/efrotools/pcommands.py @@ -479,6 +479,60 @@ def sync() -> None: run_standard_syncs(pcommand.PROJROOT, mode, sync_items) +def copy_win_extra_file() -> None: + """Copy a windows extra file.""" + _simple_file_copy('Copying file') + + +def compile_language_file() -> None: + """Compile a language file.""" + _simple_file_copy('Compiling language json') + + +def compile_mesh_file() -> None: + """Compile a mesh file.""" + import os + import subprocess + from efro.error import CleanError + + args = pcommand.get_args() + if len(args) != 3: + raise CleanError('Expected 3 args.') + + src, dst, makebob = args + + # Show project-relative paths when possible. + relpath = os.path.abspath(dst).removeprefix(f'{pcommand.PROJROOT}/') + pcommand.set_output(f'Compiling mesh: {relpath}') + + os.makedirs(os.path.dirname(dst), exist_ok=True) + subprocess.run([makebob, src, dst], check=True) + + assert os.path.exists(dst) + + +def compile_collision_mesh_file() -> None: + """Compile a mesh file.""" + import os + import subprocess + from efro.error import CleanError + + args = pcommand.get_args() + if len(args) != 3: + raise CleanError('Expected 3 args.') + + src, dst, makebob = args + + # Show project-relative paths when possible. + relpath = os.path.abspath(dst).removeprefix(f'{pcommand.PROJROOT}/') + pcommand.set_output(f'Compiling collision mesh: {relpath}') + + os.makedirs(os.path.dirname(dst), exist_ok=True) + subprocess.run([makebob, src, dst], check=True) + + assert os.path.exists(dst) + + def compile_python_file() -> None: """Compile pyc files for packaging. @@ -499,9 +553,11 @@ def compile_python_file() -> None: if len(args) != 1: raise CleanError('Expected a single arg.') fname = args[0] - # Print project-relative path when possible. + + # Show project-relative path when possible. relpath = os.path.abspath(fname).removeprefix(f'{pcommand.PROJROOT}/') pcommand.set_output(f'Compiling script: {relpath}') + py_compile.compile( fname, doraise=True, @@ -512,6 +568,10 @@ def compile_python_file() -> None: def copy_python_file() -> None: """Copy Python files for packaging.""" + _simple_file_copy('Copying script', make_unwritable=True) + + +def _simple_file_copy(msg: str, make_unwritable: bool = False) -> None: import os import shutil from efro.error import CleanError @@ -523,21 +583,28 @@ def copy_python_file() -> None: src, dst = args relpath = os.path.abspath(dst).removeprefix(f'{pcommand.PROJROOT}/') - pcommand.set_output(f'Copying script: {relpath}') + pcommand.set_output(f'{msg}: {relpath}') - # Since we're making built files unwritable, we need to blow + # If we're making built files unwritable, we need to blow # away exiting ones to allow this to succeed. - if os.path.exists(dst): - os.unlink(dst) + if make_unwritable: + if os.path.exists(dst): + os.unlink(dst) os.makedirs(os.path.dirname(dst), exist_ok=True) shutil.copyfile(src, dst) + assert os.path.exists(dst) + # Make built files unwritable to save myself from accidentally # doing editing there and then blowing away my work. - os.chmod(dst, 0o444) + if make_unwritable: + os.chmod(dst, 0o444) - assert os.path.exists(dst) + +def compile_font_file() -> None: + """Compile a font file.""" + _simple_file_copy('Compiling font') def pytest() -> None: diff --git a/tools/efrotools/pcommands2.py b/tools/efrotools/pcommands2.py index 67b73b07..486e9a62 100644 --- a/tools/efrotools/pcommands2.py +++ b/tools/efrotools/pcommands2.py @@ -130,6 +130,7 @@ def run_pcommandbatch_server() -> None: args = pcommand.get_args() idle_timeout_secs = int(extract_arg(args, '--timeout', required=True)) + project_dir = extract_arg(args, '--project-dir', required=True) state_dir = extract_arg(args, '--state-dir', required=True) instance = extract_arg(args, '--instance', required=True) @@ -138,6 +139,7 @@ def run_pcommandbatch_server() -> None: pcb.run_pcommandbatch_server( idle_timeout_secs=idle_timeout_secs, + project_dir=project_dir, state_dir=state_dir, instance=instance, ) diff --git a/tools/pcommand b/tools/pcommand index de48733f..f5b19bfe 100755 --- a/tools/pcommand +++ b/tools/pcommand @@ -41,8 +41,13 @@ from efrotools.pcommands import ( spelling_all, pytest, echo, + copy_win_extra_file, compile_python_file, copy_python_file, + compile_language_file, + compile_mesh_file, + compile_collision_mesh_file, + compile_font_file, pyver, try_repeat, xcodebuild,