buildbuddy-io / bazel_env.bzl

A virtual environment for Bazel-managed tools and toolchains.
MIT License
19 stars 0 forks source link

Allow users to choose subsets of commands #14

Open kolloch opened 1 month ago

kolloch commented 1 month ago

Some of our commands are cheap to provision (just a simple download), some of them are expensive since they will be built from source with many dependencies.

Always building all tools therefore seems excessive.

Possible solutions:

  1. Allow "lazy" tools that only get provisioned when called first.
  2. Allow easy selection of tools that the user really wants. E.g. have optional commands and have the user execute bazel_env add to actually provision them. Or allow select in the attribute so that some simple lines in the user's .bazelrc suffice.
fmeum commented 1 month ago
  1. I'm still thinking about how lazy tools could be made to work reliably.

  2. selecting tools unfortunately can't be done since we need to create one target per tool for runfiles to work properly and that requires knowing the tools at load rather than analysis time. But you can use an alias as a tool and add a select to it that switches to a stub tool showing an "unavailable unless you flip flag X" error.

kolloch commented 1 month ago
  1. What I did for now, is to define different bazel_env targets with different sets of tools.
  2. I defined some base dictionaries in Starlark that I then join into some larger sets. That way different targets can reuse the same groups of commands.
  3. Then I included the following snippet in the .envrc that allows you to write your env target suffix into .bazelenv:

    .envrc

    watch_file .bazelenv
    if [ -r .bazelenv ]; then
        BAZEL_ENV=$(cat .bazelenv)
        # remove leading whitespace characters
        BAZEL_ENV="${BAZEL_ENV#"${BAZEL_ENV%%[![:space:]]*}"}"
        # remove trailing whitespace characters
        BAZEL_ENV="${BAZEL_ENV%"${BAZEL_ENV##*[![:space:]]}"}"
        echo "Detected bazelenv: $BAZEL_ENV" >&2
    else
        BAZEL_ENV="devenv"
    fi
    
    watch_file bazel-out/bazel_env-opt/bin/env/$BAZEL_ENV/bin
    PATH_add bazel-out/bazel_env-opt/bin/env/$BAZEL_ENV/bin
    if [[ ! -d bazel-out/bazel_env-opt/bin/env/$BAZEL_ENV/bin ]]; then
      log_error "ERROR[bazel_env.bzl]: Run 'bazel run //env:$BAZEL_ENV' to regenerate bazel-out/bazel_env-opt/bin/env/$BAZEL_ENV/bin"
    fi
    
    export BAZEL_BINDIR="$(expand_path bazel-bin)"

It would be nice to standardize on one approach here. E.g. one could make bazel run @bazel_env.bzl read a config file for the target to use and/or some other options. And then also use that in .envrc