From 4ec0d7cab4fe91509fca3c57fcd2859bffa7a154 Mon Sep 17 00:00:00 2001 From: Jeremy Nimmer Date: Thu, 24 Aug 2023 17:57:30 -0700 Subject: [PATCH] Teach bazelisk.py about .bazeliskrc Update README to list new capabilities; the Python implementation comes a bit closer to the Go implementation. --- README.md | 18 +++++++++--------- bazelisk.py | 41 ++++++++++++++++++++++++++++++++++------- bazelisk_test.sh | 16 ++++++++-------- 3 files changed, 51 insertions(+), 24 deletions(-) diff --git a/README.md b/README.md index 35d46226..ee2e0298 100644 --- a/README.md +++ b/README.md @@ -166,7 +166,7 @@ You can control the user agent that Bazelisk sends in all HTTP requests by setti # .bazeliskrc configuration file -The Go version supports a `.bazeliskrc` file in the root directory of a workspace and the user home directory. This file allows users to set environment variables persistently. +A `.bazeliskrc` file in the root directory of a workspace or the user home directory allows users to set environment variables persistently. Example file content: @@ -179,21 +179,21 @@ BAZELISK_GITHUB_TOKEN=abc The following variables can be set: - `BAZELISK_BASE_URL` -- `BAZELISK_CLEAN` -- `BAZELISK_GITHUB_TOKEN` +- `BAZELISK_CLEAN` (Go version only) +- `BAZELISK_GITHUB_TOKEN` (Go version only) - `BAZELISK_HOME` -- `BAZELISK_INCOMPATIBLE_FLAGS` -- `BAZELISK_SHUTDOWN` -- `BAZELISK_SKIP_WRAPPER` -- `BAZELISK_USER_AGENT` -- `BAZELISK_VERIFY_SHA256` +- `BAZELISK_INCOMPATIBLE_FLAGS` (Go version only) +- `BAZELISK_SHUTDOWN` (Go version only) +- `BAZELISK_SKIP_WRAPPER` (Go version only) +- `BAZELISK_USER_AGENT` (Go version only) +- `BAZELISK_VERIFY_SHA256` (Go version only) - `USE_BAZEL_VERSION` Configuration variables are evaluated with precedence order. The preferred values are derived in order from highest to lowest precedence as follows: * Variables defined in the environment * Variables defined in the workspace root `.bazeliskrc` -* Variables defined in the user home `.bazeliskrc` +* Variables defined in the user home `.bazeliskrc` (Go version only) ## Requirements diff --git a/bazelisk.py b/bazelisk.py index 8a967c27..3351837f 100755 --- a/bazelisk.py +++ b/bazelisk.py @@ -68,6 +68,31 @@ BAZEL_UPSTREAM = "bazelbuild" +def get_env_or_config(name, default=None): + """Reads a configuration value from the environment, but falls back to + reading it from .bazeliskrc in the workspace root. + """ + if name in os.environ: + return os.environ[name] + env_files = [] + root = find_workspace_root() + if root: + env_files.append(os.path.join(root, ".bazeliskrc")) + for env_file in env_files: + try: + with open(env_file, "r") as f: + for line in f.readlines(): + line = line.split("#", maxsplit=1)[0].strip() + if not line: + continue + some_name, some_value = line.split("=", maxsplit=1) + if some_name == name: + return some_value + except Exception: + pass + return default + + def decide_which_bazel_version_to_use(): # Check in this order: # - env var "USE_BAZEL_VERSION" is set to a specific version. @@ -79,8 +104,9 @@ def decide_which_bazel_version_to_use(): # - workspace_root/.bazelversion exists -> read contents, that version. # - workspace_root/WORKSPACE contains a version -> that version. (TODO) # - fallback: latest release - if "USE_BAZEL_VERSION" in os.environ: - return os.environ["USE_BAZEL_VERSION"] + use_bazel_version = get_env_or_config("USE_BAZEL_VERSION") + if use_bazel_version is not None: + return use_bazel_version workspace_root = find_workspace_root() if workspace_root: @@ -226,7 +252,7 @@ def determine_bazel_filename(version): filename_suffix = determine_executable_filename_suffix() bazel_flavor = "bazel" - if os.environ.get("BAZELISK_NOJDK", "0") != "0": + if get_env_or_config("BAZELISK_NOJDK", "0") != "0": bazel_flavor = "bazel_nojdk" return "{}-{}-{}-{}{}".format(bazel_flavor, version, operating_system, machine, filename_suffix) @@ -277,8 +303,9 @@ def determine_url(version, is_commit, bazel_filename): # Example: '0.19.1' -> ('0.19.1', None), '0.20.0rc1' -> ('0.20.0', 'rc1') (version, rc) = re.match(r"(\d*\.\d*(?:\.\d*)?)(rc\d+)?", version).groups() - if "BAZELISK_BASE_URL" in os.environ: - return "{}/{}/{}".format(os.environ["BAZELISK_BASE_URL"], version, bazel_filename) + bazelisk_base_url = get_env_or_config("BAZELISK_BASE_URL") + if bazelisk_base_url is not None: + return "{}/{}/{}".format(bazelisk_base_url, version, bazel_filename) else: return "https://releases.bazel.build/{}/{}/{}".format( version, rc if rc else "release", bazel_filename @@ -342,7 +369,7 @@ def download_bazel_into_directory(version, is_commit, directory): def download(url, destination_path): sys.stderr.write("Downloading {}...\n".format(url)) request = Request(url) - if "BAZELISK_BASE_URL" in os.environ: + if get_env_or_config("BAZELISK_BASE_URL") is not None: parts = urlparse(url) creds = None try: @@ -357,7 +384,7 @@ def download(url, destination_path): def get_bazelisk_directory(): - bazelisk_home = os.environ.get("BAZELISK_HOME") + bazelisk_home = get_env_or_config("BAZELISK_HOME") if bazelisk_home is not None: return bazelisk_home diff --git a/bazelisk_test.sh b/bazelisk_test.sh index 95b51d69..c1abf6a0 100755 --- a/bazelisk_test.sh +++ b/bazelisk_test.sh @@ -479,6 +479,14 @@ echo "# test_bazel_version_from_environment" test_bazel_version_from_environment echo +echo "# test_bazel_version_prefer_environment_to_bazeliskrc" +test_bazel_version_prefer_environment_to_bazeliskrc +echo + +echo "# test_bazel_version_from_workspace_bazeliskrc" +test_bazel_version_from_workspace_bazeliskrc +echo + echo "# test_bazel_version_from_file" test_bazel_version_from_file echo @@ -512,14 +520,6 @@ if [[ $BAZELISK_VERSION == "GO" ]]; then test_bazel_version_from_base_url echo - echo "# test_bazel_version_prefer_environment_to_bazeliskrc" - test_bazel_version_prefer_environment_to_bazeliskrc - echo - - echo "# test_bazel_version_from_workspace_bazeliskrc" - test_bazel_version_from_workspace_bazeliskrc - echo - echo "# test_bazel_version_from_user_home_bazeliskrc" test_bazel_version_from_user_home_bazeliskrc echo