From 1ffccfae5b473ae6359195e8edb6fe1d23a5ff87 Mon Sep 17 00:00:00 2001 From: Reid 'arrdem' McKenzie Date: Mon, 12 Feb 2024 18:57:45 -0700 Subject: [PATCH] M0ar --- projects/bazelshim/BUILD.bazel | 1 + projects/bazelshim/src/bazelshim/__main__.py | 66 +++++++------------- 2 files changed, 25 insertions(+), 42 deletions(-) diff --git a/projects/bazelshim/BUILD.bazel b/projects/bazelshim/BUILD.bazel index f5177f6..5013a2e 100644 --- a/projects/bazelshim/BUILD.bazel +++ b/projects/bazelshim/BUILD.bazel @@ -1,3 +1,4 @@ py_project( name = "bazelshim", + main = "src/bazelshim/__main__.py", ) diff --git a/projects/bazelshim/src/bazelshim/__main__.py b/projects/bazelshim/src/bazelshim/__main__.py index 5a0a6fb..62923ca 100755 --- a/projects/bazelshim/src/bazelshim/__main__.py +++ b/projects/bazelshim/src/bazelshim/__main__.py @@ -1,32 +1,5 @@ #!/usr/bin/env python3 -""" -A Bazel wrapper -=============== - -This script exists to allow for the setting of environment viariables and other context flags to -Bazel on behalf of the user. Consequently it has some magical (partial) knowledge of Bazel's CLI -options since it's really a CLI shim. This allows for user(s) to define their own Bazel CLI -middleware machinery while using structured and testable parsing rather than BASH nonsense. - -It's important that this script stands "alone" because it needs to be usable mostly in isolation -with a non-hermetic interpreter before we can do Bazel builds. - -For instance this script could be used as a basis to define custom Bazel tasks such as 'repl' (run -with some magic) or 'watch' as an alias for punting to ibazel/bazel-watcher. - -Such a middleware can also be used to provide configurations which are hard to autodetect from -within Bazel in an appropriately structured way such as - `--action_env=GLIBC_VERSION=$(ldd --version)` -or - `--action_env=PLATFORM_FEATURE_POSTGRESQL=$(which pg_ctl >/dev/null 2>&1 && echo 'true' || echo 'false')` - -I suggest using a `bazel` and maybe `bazelisk` shim script on your $PATH like - exec "${SOURCE}/projects/bazelshim/src/bazelshim/__main__.py" \ - --bazelshim_exclude="$(dirname $(realpath $0))" \ - "$@" -""" - # Since this can't run under Bazel, we have to set up the sys.path ourselves import os import sys @@ -40,6 +13,7 @@ if (p := str(Path(sys.argv[0]).absolute().parent.parent)) not in sys.path: from dataclasses import dataclass from shlex import quote, split as shlex import sys +import tomllib from pathlib import Path from typing import List, Optional from itertools import chain @@ -61,6 +35,7 @@ VERBS = [ "run", "sync", "test", + "watch", ] @@ -169,8 +144,11 @@ class BazelCli: *self.startup_opts, ] if self.command: - acc.append(self.command) - acc.extend(self.command_opts) + if self.command == "watch": + acc.extend(self.command_opts) + else: + acc.append(self.command) + acc.extend(self.command_opts) if self.command == "test": acc.extend(["--test_arg=" + it for it in self.subprocess_opts]) @@ -190,23 +168,27 @@ class BazelCli: def executable(self, exclude: List[Path]): """Try to resolve as via which() an executable to delegate to.""" - for p in chain(which("bazelisk"), which("bazel")): - if p.parent not in exclude: - return str(p) + if self.command == "watch": + for p in chain(which("ibazel")): + if p.parent not in exclude: + return str(p) + + else: + for p in chain(which("bazelisk"), which("bazel")): + if p.parent not in exclude: + return str(p) def render_text(self, next): lines = [] lines.append(" " + next) - for arg in self.startup_opts: - lines.append(" " + arg) - if self.command: - lines.append(" " + self.command) - for arg in self.command_opts: - lines.append(" " + arg) - if self.subprocess_opts: - lines.append(" --") - for arg in self.subprocess_opts: - lines.append(" " + arg) + base_prefix = " " + for arg in self.render_cli()[1:]: + prefix = base_prefix + if arg in VERBS or arg == self.command: + prefix = " " + elif arg == "--": + base_prefix += " " + lines.append(prefix + arg) return "\\\n".join(lines)