Skip to content

Commit

Permalink
Teach custom fallback version behavior (#289)
Browse files Browse the repository at this point in the history
This allows for smoother migrations from globally pinned Bazel to
project-local pinned Bazel using Bazelisk.
  • Loading branch information
bb010g authored Jul 5, 2022
1 parent 70694fe commit 37c5a95
Show file tree
Hide file tree
Showing 2 changed files with 38 additions and 5 deletions.
6 changes: 5 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,11 @@ It uses a simple algorithm:
- If the environment variable `USE_BAZEL_VERSION` is set, it will use the version specified in the value.
- Otherwise, if a `.bazeliskrc` file exists in the workspace root and contains the `USE_BAZEL_VERSION` variable, this version will be used.
- Otherwise, if a `.bazelversion` file exists in the current directory or recursively any parent directory, it will read the file and use the version specified in it.
- Otherwise it will use the official latest Bazel release.
- Otherwise, if the environment variable `USE_BAZEL_FALLBACK_VERSION` is set to one of the following formats:
- If set to a value starting with `error:`, it will report an error and version detection will fail.
- If set to a value starting with `warn:`, it will report a warning and use the version specified after the prefix.
- If set to a value starting with `silent:`, it will use the version specified after the prefix.
- Otherwise, it will use the official latest Bazel release.

A version can optionally be prefixed with a fork name.
The fork and version should be separated by slash: `<FORK>/<VERSION>`.
Expand Down
37 changes: 33 additions & 4 deletions core/core.go
Original file line number Diff line number Diff line change
Expand Up @@ -249,19 +249,30 @@ func findWorkspaceRoot(root string) string {
return findWorkspaceRoot(parentDirectory)
}

// TODO(go 1.18): remove backport of strings.Cut
func cutString(s, sep string) (before, after string, found bool) {
if i := strings.Index(s, sep); i >= 0 {
return s[:i], s[i+len(sep):], true
}
return s, "", false
}

func getBazelVersion() (string, error) {
// Check in this order:
// - env var "USE_BAZEL_VERSION" is set to a specific version.
// - workspace_root/.bazeliskrc exists -> read contents, in contents:
// var "USE_BAZEL_VERSION" is set to a specific version.
// - env var "USE_NIGHTLY_BAZEL" or "USE_BAZEL_NIGHTLY" is set -> latest
// nightly. (TODO)
// - env var "USE_CANARY_BAZEL" or "USE_BAZEL_CANARY" is set -> latest
// rc. (TODO)
// - the file workspace_root/tools/bazel exists -> that version. (TODO)
// - workspace_root/.bazeliskrc exists and contains a 'USE_BAZEL_VERSION'
// variable -> read contents, that version.
// - workspace_root/.bazelversion exists -> read contents, that version.
// - workspace_root/WORKSPACE contains a version -> that version. (TODO)
// - fallback: latest release
// - env var "USE_BAZEL_FALLBACK_VERSION" is set to a fallback version format.
// - workspace_root/.bazeliskrc exists -> read contents, in contents:
// var "USE_BAZEL_FALLBACK_VERSION" is set to a fallback version format.
// - fallback version format "silent:latest"
bazelVersion := GetEnvOrConfig("USE_BAZEL_VERSION")
if len(bazelVersion) != 0 {
return bazelVersion, nil
Expand Down Expand Up @@ -295,7 +306,25 @@ func getBazelVersion() (string, error) {
}
}

return "latest", nil
fallbackVersionFormat := GetEnvOrConfig("USE_BAZEL_FALLBACK_VERSION")
fallbackVersionMode, fallbackVersion, hasFallbackVersionMode := cutString(fallbackVersionFormat, ":")
if !hasFallbackVersionMode {
fallbackVersionMode, fallbackVersion, hasFallbackVersionMode = "silent", fallbackVersionMode, true
}
if len(fallbackVersion) == 0 {
fallbackVersion = "latest"
}
if fallbackVersionMode == "error" {
return "", fmt.Errorf("not allowed to use fallback version %q", fallbackVersion)
}
if fallbackVersionMode == "warn" {
log.Printf("Warning: used fallback version %q\n", fallbackVersion)
return fallbackVersion, nil
}
if fallbackVersionMode == "silent" {
return fallbackVersion, nil
}
return "", fmt.Errorf("invalid fallback version format %q (effectively %q)", fallbackVersionFormat, fmt.Sprintf("%s:%s", fallbackVersionMode, fallbackVersion))
}

func parseBazelForkAndVersion(bazelForkAndVersion string) (string, string, error) {
Expand Down

0 comments on commit 37c5a95

Please sign in to comment.