From 4a530aa5d991a2bb1d55ef0ed83e458992188a17 Mon Sep 17 00:00:00 2001 From: Steve Barrau <98589981+stevebarrau@users.noreply.github.com> Date: Mon, 22 Jul 2024 22:43:27 +0200 Subject: [PATCH] feat(crates_repository): customizable repin instructions (#2756) Add customizable instructions to re-pin the repository if required. Many people have wrapper scripts for keeping dependencies up to date, and would like to point users to that instead of the default. This follows the logic of https://github.com/bazelbuild/rules_jvm_external/pull/1000 --------- Co-authored-by: Daniel Wagner-Hall --- crate_universe/private/crates_repository.bzl | 4 +++ crate_universe/private/generate_utils.bzl | 27 +++++++++++++------- docs/crate_universe.md | 3 ++- 3 files changed, 24 insertions(+), 10 deletions(-) diff --git a/crate_universe/private/crates_repository.bzl b/crate_universe/private/crates_repository.bzl index 0a3de518da..7924711372 100644 --- a/crate_universe/private/crates_repository.bzl +++ b/crate_universe/private/crates_repository.bzl @@ -50,6 +50,7 @@ def _crates_repository_impl(repository_ctx): splicing_manifest = splicing_manifest, cargo = cargo_path, rustc = rustc_path, + repin_instructions = repository_ctx.attr.repin_instructions, ) # If re-pinning is enabled, gather additional inputs for the generator @@ -281,6 +282,9 @@ CARGO_BAZEL_REPIN=1 CARGO_BAZEL_REPIN_ONLY=crate_index bazel sync --only=crate_i "generate the value for this field. If unset, the defaults defined there will be used." ), ), + "repin_instructions": attr.string( + doc = "Instructions to re-pin the repository if required. Many people have wrapper scripts for keeping dependencies up to date, and would like to point users to that instead of the default.", + ), "rust_toolchain_cargo_template": attr.string( doc = ( "The template to use for finding the host `cargo` binary. `{version}` (eg. '1.53.0'), " + diff --git a/crate_universe/private/generate_utils.bzl b/crate_universe/private/generate_utils.bzl index a6c88dd81b..94dcdd2360 100644 --- a/crate_universe/private/generate_utils.bzl +++ b/crate_universe/private/generate_utils.bzl @@ -336,7 +336,7 @@ def get_lockfiles(repository_ctx): bazel = repository_ctx.path(repository_ctx.attr.lockfile) if repository_ctx.attr.lockfile else None, ) -def determine_repin(repository_ctx, generator, lockfile_path, config, splicing_manifest, cargo, rustc): +def determine_repin(repository_ctx, generator, lockfile_path, config, splicing_manifest, cargo, rustc, repin_instructions = None): """Use the `cargo-bazel` binary to determine whether or not dpeendencies need to be re-pinned Args: @@ -347,6 +347,7 @@ def determine_repin(repository_ctx, generator, lockfile_path, config, splicing_m lockfile_path (path): The path to a "lock" file for reproducible outputs. cargo (path): The path to a Cargo binary. rustc (path): The path to a Rustc binary. + repin_instructions (optional string): Instructions to re-pin dependencies in your repository. Will be shown when re-pinning is required. Returns: bool: True if dependencies need to be re-pinned @@ -403,14 +404,22 @@ def determine_repin(repository_ctx, generator, lockfile_path, config, splicing_m # flag indicating repinning was requested, an error is raised # since repinning should be an explicit action if result.return_code: - fail(("\n".join([ - result.stderr, - ( - "The current `lockfile` is out of date for '{}'. Please re-run " + - "bazel using `CARGO_BAZEL_REPIN=true` if this is expected " + - "and the lockfile should be updated." - ).format(repository_ctx.name), - ]))) + if repin_instructions: + msg = ("\n".join([ + result.stderr, + "The current `lockfile` is out of date for '{}'.".format(repository_ctx.name), + repin_instructions, + ])) + else: + msg = ("\n".join([ + result.stderr, + ( + "The current `lockfile` is out of date for '{}'. Please re-run " + + "bazel using `CARGO_BAZEL_REPIN=true` if this is expected " + + "and the lockfile should be updated." + ).format(repository_ctx.name), + ])) + fail(msg) return False diff --git a/docs/crate_universe.md b/docs/crate_universe.md index 806ef9041e..11588b4971 100644 --- a/docs/crate_universe.md +++ b/docs/crate_universe.md @@ -752,7 +752,7 @@ str: A json encoded string of the parameters provided crates_repository(name, annotations, cargo_config, cargo_lockfile, generate_binaries, generate_build_scripts, generate_target_compatible_with, generator, generator_sha256s, generator_urls, isolated, lockfile, manifests, packages, quiet, - render_config, repo_mapping, rust_toolchain_cargo_template, + render_config, repin_instructions, repo_mapping, rust_toolchain_cargo_template, rust_toolchain_rustc_template, rust_version, splicing_config, supported_platform_triples) @@ -867,6 +867,7 @@ CARGO_BAZEL_REPIN=1 CARGO_BAZEL_REPIN_ONLY=crate_index bazel sync --only=crate_i | packages | A set of crates (packages) specifications to depend on. See [crate.spec](#crate.spec). | Dictionary: String -> String | optional | `{}` | | quiet | If stdout and stderr should not be printed to the terminal. | Boolean | optional | `True` | | render_config | The configuration flags to use for rendering. Use `//crate_universe:defs.bzl\%render_config` to generate the value for this field. If unset, the defaults defined there will be used. | String | optional | `""` | +| repin_instructions | Instructions to re-pin the repository if required. Many people have wrapper scripts for keeping dependencies up to date, and would like to point users to that instead of the default. | String | optional | `""` | | repo_mapping | In `WORKSPACE` context only: a dictionary from local repository name to global repository name. This allows controls over workspace dependency resolution for dependencies of this repository.

For example, an entry `"@foo": "@bar"` declares that, for any time this repository depends on `@foo` (such as a dependency on `@foo//some:target`, it should actually resolve that dependency within globally-declared `@bar` (`@bar//some:target`).

This attribute is _not_ supported in `MODULE.bazel` context (when invoking a repository rule inside a module extension's implementation function). | Dictionary: String -> String | optional | | | rust_toolchain_cargo_template | The template to use for finding the host `cargo` binary. `{version}` (eg. '1.53.0'), `{triple}` (eg. 'x86_64-unknown-linux-gnu'), `{arch}` (eg. 'aarch64'), `{vendor}` (eg. 'unknown'), `{system}` (eg. 'darwin'), `{cfg}` (eg. 'exec'), `{channel}` (eg. 'stable'), and `{tool}` (eg. 'rustc.exe') will be replaced in the string if present. | String | optional | `"@rust_{system}_{arch}__{triple}__{channel}_tools//:bin/{tool}"` | | rust_toolchain_rustc_template | The template to use for finding the host `rustc` binary. `{version}` (eg. '1.53.0'), `{triple}` (eg. 'x86_64-unknown-linux-gnu'), `{arch}` (eg. 'aarch64'), `{vendor}` (eg. 'unknown'), `{system}` (eg. 'darwin'), `{cfg}` (eg. 'exec'), `{channel}` (eg. 'stable'), and `{tool}` (eg. 'cargo.exe') will be replaced in the string if present. | String | optional | `"@rust_{system}_{arch}__{triple}__{channel}_tools//:bin/{tool}"` |