From e30b981a2234083717296e2bb00faad730b6ca42 Mon Sep 17 00:00:00 2001 From: Adam Gemmell Date: Thu, 29 Aug 2024 14:56:49 +0100 Subject: [PATCH] Implement `--locked` for build-std --- src/cargo/core/compiler/standard_lib.rs | 7 +- src/cargo/core/workspace.rs | 15 +++ src/cargo/ops/lockfile.rs | 9 ++ tests/testsuite/mock-std/library/Cargo.lock | 101 ++++++++++++++++++++ 4 files changed, 126 insertions(+), 6 deletions(-) create mode 100644 tests/testsuite/mock-std/library/Cargo.lock diff --git a/src/cargo/core/compiler/standard_lib.rs b/src/cargo/core/compiler/standard_lib.rs index a3b2ff8acd1..b9717752e41 100644 --- a/src/cargo/core/compiler/standard_lib.rs +++ b/src/cargo/core/compiler/standard_lib.rs @@ -75,13 +75,8 @@ pub fn resolve_std<'gctx>( let src_path = detect_sysroot_src_path(target_data)?; let std_ws_manifest_path = src_path.join("Cargo.toml"); let gctx = ws.gctx(); - // TODO: Consider doing something to enforce --locked? Or to prevent the - // lock file from being written, such as setting ephemeral. let mut std_ws = Workspace::new(&std_ws_manifest_path, gctx)?; - // Don't require optional dependencies in this workspace, aka std's own - // `[dev-dependencies]`. No need for us to generate a `Resolve` which has - // those included because we'll never use them anyway. - std_ws.set_require_optional_deps(false); + std_ws.set_is_locked(true); // `sysroot` is not in the default set because it is optional, but it needs // to be part of the resolve in case we do need it or `libtest`. let mut spec_pkgs = Vec::from(crates); diff --git a/src/cargo/core/workspace.rs b/src/cargo/core/workspace.rs index ad4ecc3e25f..3a649d7a9a4 100644 --- a/src/cargo/core/workspace.rs +++ b/src/cargo/core/workspace.rs @@ -103,6 +103,12 @@ pub struct Workspace<'gctx> { /// file. This is set for `cargo install` without `--locked`. ignore_lock: bool, + /// If `true`, then the resolver will not update the `Cargo.lock` file and + /// return an error if the lockfile is missing or out of date, similar + /// to the `GlobalContext::locked()` behaviour. Note that + /// the lockfile is not written if `require_optional_deps` is false. + is_locked: bool, + /// Requested path of the lockfile (i.e. passed as the cli flag) requested_lockfile_path: Option, @@ -240,6 +246,7 @@ impl<'gctx> Workspace<'gctx> { member_ids: HashSet::new(), default_members: Vec::new(), is_ephemeral: false, + is_locked: false, require_optional_deps: true, loaded_packages: RefCell::new(HashMap::new()), ignore_lock: false, @@ -635,6 +642,14 @@ impl<'gctx> Workspace<'gctx> { self } + pub fn is_locked(&self) -> bool { + self.is_locked + } + + pub fn set_is_locked(&mut self, is_locked: bool) { + self.is_locked = is_locked + } + /// Returns the directory where the lockfile is in. pub fn lock_root(&self) -> Filesystem { if let Some(requested) = self.requested_lockfile_path.as_ref() { diff --git a/src/cargo/ops/lockfile.rs b/src/cargo/ops/lockfile.rs index 07985e42a1c..aba62a4039f 100644 --- a/src/cargo/ops/lockfile.rs +++ b/src/cargo/ops/lockfile.rs @@ -66,6 +66,15 @@ pub fn write_pkg_lockfile(ws: &Workspace<'_>, resolve: &mut Resolve) -> CargoRes ); } + if ws.is_locked() { + println!("{out}"); + anyhow::bail!( + "Attempted to write to the standard library's lockfile.\n\ + This most likely means the lockfile has been previously modified by mistake.\ + Try removing and readding the `rust-src` component." + ); + } + // While we're updating the lock file anyway go ahead and update its // encoding to whatever the latest default is. That way we can slowly roll // out lock file updates as they're otherwise already updated, and changes diff --git a/tests/testsuite/mock-std/library/Cargo.lock b/tests/testsuite/mock-std/library/Cargo.lock new file mode 100644 index 00000000000..8ab333ed339 --- /dev/null +++ b/tests/testsuite/mock-std/library/Cargo.lock @@ -0,0 +1,101 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +version = 3 + +[[package]] +name = "alloc" +version = "0.1.0" +dependencies = [ + "registry-dep-using-core", +] + +[[package]] +name = "compiler_builtins" +version = "0.1.0" + +[[package]] +name = "core" +version = "0.1.0" + +[[package]] +name = "panic_unwind" +version = "0.1.0" + +[[package]] +name = "proc_macro" +version = "0.1.0" + +[[package]] +name = "registry-dep-using-alloc" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c1d9a2abefa2f5aaa137653fca3cdff3c47ce9727e47fd7f377dfc898b94b1dc" +dependencies = [ + "rustc-std-workspace-alloc", + "rustc-std-workspace-core", +] + +[[package]] +name = "registry-dep-using-core" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ce6253e8df30c5f598cb8783702f5eaa17c3b9b8bf83cbbe4bb6f502330a9510" +dependencies = [ + "rustc-std-workspace-core", +] + +[[package]] +name = "registry-dep-using-std" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "14d3e364d307e328fac1a519ed7dc9c4a9ab5909df6904bf485f2d9b13dc0880" +dependencies = [ + "rustc-std-workspace-std", +] + +[[package]] +name = "rustc-std-workspace-alloc" +version = "1.9.0" +dependencies = [ + "alloc", +] + +[[package]] +name = "rustc-std-workspace-core" +version = "1.9.0" +dependencies = [ + "core", +] + +[[package]] +name = "rustc-std-workspace-std" +version = "1.9.0" +dependencies = [ + "std", +] + +[[package]] +name = "std" +version = "0.1.0" +dependencies = [ + "registry-dep-using-alloc", +] + +[[package]] +name = "sysroot" +version = "0.1.0" +dependencies = [ + "proc_macro", + "std", + "test", +] + +[[package]] +name = "test" +version = "0.1.0" +dependencies = [ + "compiler_builtins", + "panic_unwind", + "registry-dep-using-std", + "std", +]