Bazel: Feature request: self-downloading/installing wrapper script

Created on 8 Jul 2016  路  14Comments  路  Source: bazelbuild/bazel

It would be great if there were a wrapper script (let's call it "bazelw") that downloads a specific version (which could be the latest version) of bazel, and executes the given command with the downloaded copy of bazel. I'm thinking of something similar to the gradle wrapper ("gradlew"):

    https://docs.gradle.org/current/userguide/gradle_wrapper.html

This would make it more palatable to use Bazel in opensource projects, as it would reduce the number of steps required for users to setup their machine. It would also make the build even more reliable by ensuring that a specific version (encoded in the wrapper) is used, rather than whatever version of bazel happens to installed on the user's machine (which may be incompatible with the BUILD/WORKSPACE).

P3 team-Bazel feature request

Most helpful comment

This is _still_ really important, 2 years later. There needs to be a standard way to version bazel itself, like this proposes.

All 14 comments

Is this not more a thing you would like to do with docker?

Docker is ideal for remote builds (like a continuous integration machine), but it is a very heavy-weight solution for ordinary developers. It's also not compatible with all environments (e.g. for developers working on Cloud 9 or other hosted environments that are, themselves, running in Docker and, therefore, incapable of running Docker). So I think there is still a reason to desire something like this.

I swear we had a bug open before to create a gradlew-similar wrapper script for Bazel, but now I can't find it. I think this is a good idea.

The duplicate bug is #373 which is wrongly triaged, let keep this bug which is more complete and close #373

FYI, I've started to sketch out just such a wrapper script:
https://github.com/michaelsafyan/bazel-wrapper

(Feel free to crib from that for going forward).

FYI, there is also dazel: https://github.com/nadirizr/dazel

This is _still_ really important, 2 years later. There needs to be a standard way to version bazel itself, like this proposes.

It won't be sufficient to just download a specific version of Bazel. You will also want to get the rule sets at the versions the Bazel version was tested against. We are thinking about better versioning across core Bazel and the rules, but there may not be anything new for a quarter or so.

@philwo made a wrapper here: https://github.com/philwo/bazelisk

While we wait for an officially support solution, this isn't too difficult to implement on your own:

#!/bin/bash

# This script is a wrapper for Bazel that controls version pinning for the
# Bazel client binary. This allows us to pin the required Bazel version
# for each commit.
#
# It works by downloading the pinned version of the Bazel binary to the
# host (if it isn't already cached) and transparently exec'ing it with
# the provided Bazel args. To the end user it should appear no different
# than calling Bazel directly

BAZEL_VERSION="0.23.2"
BAZEL_FILENAME="bazel-${BAZEL_VERSION}-linux-x86_64"
BAZEL_LOCAL_DIR="${HOME}/.cache/bazel-versions"
BAZEL_LOCAL_LOCK="${BAZEL_LOCAL_DIR}/.lock"
BAZEL_LOCAL_BINARY="${BAZEL_LOCAL_DIR}/${BAZEL_FILENAME}"
BAZEL_BINARY_URL="https://github.com/bazelbuild/bazel/releases/download/${BAZEL_VERSION}/${BAZEL_FILENAME}"

# Check if pinned bazel version is cached
if ! [ -x "${BAZEL_LOCAL_BINARY}" ]; then
  mkdir -p "${BAZEL_LOCAL_DIR}"
  (
    flock 200
    if ! [ -x "${BAZEL_LOCAL_BINARY}" ]; then
      >&2 echo "Downloading Bazel version ${BAZEL_VERSION}"
      curl -s -L "${BAZEL_BINARY_URL}" --output ${BAZEL_LOCAL_BINARY}
      chmod +x "${BAZEL_LOCAL_BINARY}"
    fi
  ) 200>"${BAZEL_LOCAL_LOCK}"
fi

exec "${BAZEL_LOCAL_BINARY}" "$@"

We check this into our git repo with a filename of bazel and have devs/ci add it to their PATH. It makes upgrading bazel versions way less of a headache. If you want to be a good neighbor, replace the URL with a path to your own blob store (ex GCS).

$ bazel version
Downloading Bazel version 0.23.2
Build label: 0.23.2
Build target: bazel-out/k8-opt/bin/src/main/java/com/google/devtools/build/lib/bazel/BazelServer_deploy.jar
Build time: Mon Mar 11 16:47:03 2019 (1552322823)
Build timestamp: 1552322823
Build timestamp as int: 1552322823

@ebracho Bazelisk is the "official" solution - it will move into the bazelbuild org, soon. Any reason you didn't consider using it? (Just want to make sure that it's as usable as possible for all of you. :))

(Co-worker of @ebracho here)

We don't want to rely on github, so we actually reupload bazel binaries into our object store and pull it from there, as our CI system is fairly transient, and we don't want builds to fail just cause of network/github issues. If bazelisk was able to be told a specific url, or ideally even a command to run to pull it, that would probably be a viable solution for us.

@philwo To add to that, until now I didn't realize that Bazelisk had a python version we could check into our own repo (as opposed to provisioning every environment with an external dependency), which was the main deciding factor. I'm glad to hear that Bazelisk is being adopted as the official solution though! Our script is concise but fairly limited (e.g. no macOS/windows support).

bazelisk is now in the bazelbuild GitHub org, and is the official wrapper to version your Bazel binaries.

Was this page helpful?
0 / 5 - 0 ratings