Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Teach bazelisk.py about .bazeliskrc #494

Open
wants to merge 2 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -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. (The Python implementation of Bazelisk doesn't check the user home directory yet, only the workspace directory.)

Example file content:

Expand Down
60 changes: 53 additions & 7 deletions bazelisk.py
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,50 @@

BAZEL_UPSTREAM = "bazelbuild"

_dotfiles_dict = None


def get_dotfiles_dict():
"""Loads all supported dotfiles and returns a unified name=value dictionary
for their config settings. The dictionary is only loaded on the first call
to this function; subsequent calls used a cached result, so won't change.
"""
global _dotfiles_dict
if _dotfiles_dict is not None:
return _dotfiles_dict
_dotfiles_dict = dict()
env_files = []
# Here we're only checking the workspace root. Ideally, we would also check
# the user's home directory to match the Go version. When making that edit,
# be sure to obey the correctly prioritization of workspace / home rcfiles.
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:
rcdata = f.read()
except Exception:
continue
for line in rcdata.splitlines():
line = line.split("#", 1)[0].strip()
if not line:
continue
some_name, some_value = line.split("=", 1)
_dotfiles_dict[some_name] = some_value
return _dotfiles_dict


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]
dotfiles = get_dotfiles_dict()
if name in dotfiles:
return dotfiles[name]
return default


def decide_which_bazel_version_to_use():
# Check in this order:
Expand All @@ -79,8 +123,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:
Expand Down Expand Up @@ -229,7 +274,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)

Expand Down Expand Up @@ -280,8 +325,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
Expand Down Expand Up @@ -345,7 +391,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:
Expand All @@ -360,7 +406,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

Expand Down
16 changes: 8 additions & 8 deletions bazelisk_test.sh
Original file line number Diff line number Diff line change
Expand Up @@ -508,6 +508,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
Expand Down Expand Up @@ -545,14 +553,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
Expand Down