Skip to content

Commit 52b93ae

Browse files
Optionally write the rendering lockfile when vendored (#3523)
This lockfile is useful for tools like gazelle because it contains all the information about resolved crates. The regular cargo lockfile does not have enough details about each crate to properly identify dependencies.
1 parent 62d7317 commit 52b93ae

File tree

2 files changed

+30
-4
lines changed

2 files changed

+30
-4
lines changed

crate_universe/private/crates_vendor.bzl

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -449,6 +449,12 @@ def _crates_vendor_impl(ctx):
449449
args.extend(["--bazel", _expand_env("BAZEL_REAL", is_windows)])
450450
cargo_bazel_runfiles.append(ctx.executable.bazel)
451451

452+
# Optionally write the rendering lockfile.
453+
if ctx.attr.lockfile:
454+
environ.append(_sys_runfile_env(ctx, "BAZEL_LOCK", ctx.file.lockfile, is_windows))
455+
args.extend(["--lockfile", _expand_env("BAZEL_LOCK", is_windows)])
456+
cargo_bazel_runfiles.extend([ctx.file.lockfile])
457+
452458
# Determine platform specific settings
453459
if is_windows:
454460
extension = ".bat"
@@ -536,6 +542,14 @@ CRATES_VENDOR_ATTRS = {
536542
doc = "DEPRECATED: Moved to `render_config`.",
537543
default = True,
538544
),
545+
"lockfile": attr.label(
546+
doc = (
547+
"The path to a file to write rendering information. It contains the same information as the " +
548+
"lockfile attribute of crates_repository. It is not used by crates_vendor but may be useful " +
549+
"for code generators like gazelle."
550+
),
551+
allow_single_file = True,
552+
),
539553
"manifests": attr.label_list(
540554
doc = "A list of Cargo manifests (`Cargo.toml` files).",
541555
allow_files = ["Cargo.toml"],

crate_universe/src/cli/vendor.rs

Lines changed: 16 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ use clap::Parser;
1313

1414
use crate::config::{Config, VendorMode};
1515
use crate::context::Context;
16+
use crate::lockfile::{lock_context, write_lockfile};
1617
use crate::metadata::CargoUpdateRequest;
1718
use crate::metadata::TreeResolver;
1819
use crate::metadata::{Annotations, Cargo, Generator, MetadataGenerator, VendorGenerator};
@@ -44,6 +45,10 @@ pub struct VendorOptions {
4445
#[clap(long)]
4546
pub splicing_manifest: PathBuf,
4647

48+
/// The path to write a Bazel lockfile
49+
#[clap(long)]
50+
pub lockfile: Option<PathBuf>,
51+
4752
/// The path to a [Cargo.lock](https://doc.rust-lang.org/cargo/guide/cargo-toml-vs-cargo-lock.html) file.
4853
#[clap(long)]
4954
pub cargo_lockfile: Option<PathBuf>,
@@ -205,8 +210,8 @@ pub fn vendor(opt: VendorOptions) -> anyhow::Result<()> {
205210
.unwrap_or_else(|path| panic!("Temporary directory wasn't valid UTF-8: {:?}", path));
206211

207212
// Generate a splicer for creating a Cargo workspace manifest
208-
let splicer =
209-
Splicer::new(temp_dir_path, splicing_manifest).context("Failed to create splicer")?;
213+
let splicer = Splicer::new(temp_dir_path, splicing_manifest.clone())
214+
.context("Failed to create splicer")?;
210215

211216
let cargo = Cargo::new(opt.cargo, opt.rustc.clone());
212217

@@ -261,7 +266,7 @@ pub fn vendor(opt: VendorOptions) -> anyhow::Result<()> {
261266
// Render build files
262267
let outputs = Renderer::new(
263268
Arc::new(config.rendering.clone()),
264-
Arc::new(config.supported_platform_triples),
269+
Arc::new(config.supported_platform_triples.clone()),
265270
)
266271
.render(&context, None)?;
267272

@@ -280,7 +285,7 @@ pub fn vendor(opt: VendorOptions) -> anyhow::Result<()> {
280285
}
281286

282287
if matches!(config.rendering.vendor_mode, Some(VendorMode::Local)) {
283-
VendorGenerator::new(cargo, opt.rustc.clone())
288+
VendorGenerator::new(cargo.clone(), opt.rustc.clone())
284289
.generate(manifest_path.as_path_buf(), &vendor_dir)
285290
.context("Failed to vendor dependencies")?;
286291
}
@@ -311,6 +316,13 @@ pub fn vendor(opt: VendorOptions) -> anyhow::Result<()> {
311316
}
312317
}
313318

319+
// Write the rendering lockfile if requested.
320+
if let Some(lockfile) = opt.lockfile {
321+
let lock_content = lock_context(context, &config, &splicing_manifest, &cargo, &opt.rustc)?;
322+
323+
write_lockfile(lock_content, &lockfile, opt.dry_run)?;
324+
}
325+
314326
Ok(())
315327
}
316328

0 commit comments

Comments
 (0)