From d09f4e1f6750724741d2a137c93434ac06f1b2b3 Mon Sep 17 00:00:00 2001 From: Ifropc Date: Thu, 19 Sep 2024 18:33:44 -0700 Subject: [PATCH] feat: --lockfile-path add install support --- src/bin/cargo/commands/install.rs | 9 +++ src/cargo/core/workspace.rs | 4 ++ src/cargo/ops/cargo_install.rs | 32 +++++++++-- src/cargo/util/context/mod.rs | 4 ++ .../cargo_install/help/stdout.term.svg | 56 ++++++++++--------- tests/testsuite/lockfile_path.rs | 12 +++- 6 files changed, 82 insertions(+), 35 deletions(-) diff --git a/src/bin/cargo/commands/install.rs b/src/bin/cargo/commands/install.rs index 8aaaeb87b0e4..55e18f760c23 100644 --- a/src/bin/cargo/commands/install.rs +++ b/src/bin/cargo/commands/install.rs @@ -97,6 +97,7 @@ pub fn cli() -> Command { .arg_target_triple("Build for the target triple") .arg_target_dir() .arg_timings() + .arg_lockfile_path() .after_help(color_print::cstr!( "Run `cargo help install` for more detailed information.\n" )) @@ -201,6 +202,13 @@ pub fn exec(gctx: &mut GlobalContext, args: &ArgMatches) -> CliResult { compile_opts.build_config.requested_profile = args.get_profile_name("release", ProfileChecking::Custom)?; + let requested_lockfile_path = args.lockfile_path(gctx)?; + + // 14421: lockfile path should imply --locked on running `install` + if requested_lockfile_path.is_some() { + gctx.set_locked(true); + } + if args.flag("list") { ops::install_list(root, gctx)?; } else { @@ -213,6 +221,7 @@ pub fn exec(gctx: &mut GlobalContext, args: &ArgMatches) -> CliResult { &compile_opts, args.flag("force"), args.flag("no-track"), + requested_lockfile_path, )?; } Ok(()) diff --git a/src/cargo/core/workspace.rs b/src/cargo/core/workspace.rs index 28897365b890..9d80d9ce172b 100644 --- a/src/cargo/core/workspace.rs +++ b/src/cargo/core/workspace.rs @@ -662,6 +662,10 @@ impl<'gctx> Workspace<'gctx> { self.requested_lockfile_path = path; } + pub fn get_requested_lockfile_path(&self) -> Option<&PathBuf> { + self.requested_lockfile_path.as_ref() + } + /// Get the lowest-common denominator `package.rust-version` within the workspace, if specified /// anywhere pub fn rust_version(&self) -> Option<&RustVersion> { diff --git a/src/cargo/ops/cargo_install.rs b/src/cargo/ops/cargo_install.rs index 7abc1b393757..70df14b8a0d9 100644 --- a/src/cargo/ops/cargo_install.rs +++ b/src/cargo/ops/cargo_install.rs @@ -46,7 +46,6 @@ struct InstallablePackage<'gctx> { vers: Option, force: bool, no_track: bool, - pkg: Package, ws: Workspace<'gctx>, rustc: Rustc, @@ -68,6 +67,7 @@ impl<'gctx> InstallablePackage<'gctx> { no_track: bool, needs_update_if_source_is_index: bool, current_rust_version: Option<&PartialVersion>, + lockfile_path: Option, ) -> CargoResult> { if let Some(name) = krate { if name == "." { @@ -155,6 +155,7 @@ impl<'gctx> InstallablePackage<'gctx> { &root, &dst, force, + lockfile_path.clone(), ) { let msg = format!( "package `{}` is already installed, use --force to override", @@ -179,8 +180,13 @@ impl<'gctx> InstallablePackage<'gctx> { } }; - let (ws, rustc, target) = - make_ws_rustc_target(gctx, &original_opts, &source_id, pkg.clone())?; + let (ws, rustc, target) = make_ws_rustc_target( + gctx, + &original_opts, + &source_id, + pkg.clone(), + lockfile_path.clone(), + )?; // If we're installing in --locked mode and there's no `Cargo.lock` published // ie. the bin was published before https://github.com/rust-lang/cargo/pull/7026 if gctx.locked() && !ws.root().join("Cargo.lock").exists() { @@ -189,6 +195,13 @@ impl<'gctx> InstallablePackage<'gctx> { pkg.to_string() ))?; } + // When --lockfile-path is set, move lock file to the new location + // (the new location is expected downstream and will be used during compilation) + if gctx.locked() && ws.get_requested_lockfile_path().is_some() { + let requested_lockfile_path = ws.get_requested_lockfile_path().unwrap(); + paths::create_dir_all(ws.lock_root().as_path_unlocked())?; + fs::rename(ws.root().join("Cargo.lock"), requested_lockfile_path)?; + } let pkg = if source_id.is_git() { // Don't use ws.current() in order to keep the package source as a git source so that // install tracking uses the correct source. @@ -246,7 +259,6 @@ impl<'gctx> InstallablePackage<'gctx> { vers: vers.cloned(), force, no_track, - pkg, ws, rustc, @@ -620,6 +632,7 @@ pub fn install( opts: &ops::CompileOptions, force: bool, no_track: bool, + lockfile_path: Option, ) -> CargoResult<()> { let root = resolve_root(root, gctx)?; let dst = root.join("bin").into_path_unlocked(); @@ -651,6 +664,7 @@ pub fn install( no_track, true, current_rust_version.as_ref(), + lockfile_path.clone(), )?; let mut installed_anything = true; if let Some(installable_pkg) = installable_pkg { @@ -682,6 +696,7 @@ pub fn install( no_track, !did_update, current_rust_version.as_ref(), + lockfile_path.clone(), ) { Ok(Some(installable_pkg)) => { did_update = true; @@ -788,6 +803,7 @@ fn installed_exact_package( root: &Filesystem, dst: &Path, force: bool, + lockfile_path: Option, ) -> CargoResult> where T: Source, @@ -803,7 +819,7 @@ where // best-effort check to see if we can avoid hitting the network. if let Ok(pkg) = select_dep_pkg(source, dep, gctx, false, None) { let (_ws, rustc, target) = - make_ws_rustc_target(gctx, opts, &source.source_id(), pkg.clone())?; + make_ws_rustc_target(gctx, opts, &source.source_id(), pkg.clone(), lockfile_path)?; if let Ok(true) = is_installed(&pkg, gctx, opts, &rustc, &target, root, dst, force) { return Ok(Some(pkg)); } @@ -816,6 +832,7 @@ fn make_ws_rustc_target<'gctx>( opts: &ops::CompileOptions, source_id: &SourceId, pkg: Package, + lockfile_path: Option, ) -> CargoResult<(Workspace<'gctx>, Rustc, String)> { let mut ws = if source_id.is_git() || source_id.is_path() { Workspace::new(pkg.manifest_path(), gctx)? @@ -825,6 +842,11 @@ fn make_ws_rustc_target<'gctx>( ws }; ws.set_ignore_lock(gctx.lock_update_allowed()); + ws.set_requested_lockfile_path(lockfile_path); + // if --lockfile-path is set, imply --locked + if ws.get_requested_lockfile_path().is_some() { + ws.set_ignore_lock(false); + } ws.set_require_optional_deps(false); let rustc = gctx.load_global_rustc(Some(&ws))?; diff --git a/src/cargo/util/context/mod.rs b/src/cargo/util/context/mod.rs index 1db5b9a3c987..f243f71bef11 100644 --- a/src/cargo/util/context/mod.rs +++ b/src/cargo/util/context/mod.rs @@ -1142,6 +1142,10 @@ impl GlobalContext { self.locked } + pub fn set_locked(&mut self, locked: bool) { + self.locked = locked; + } + pub fn lock_update_allowed(&self) -> bool { !self.frozen && !self.locked } diff --git a/tests/testsuite/cargo_install/help/stdout.term.svg b/tests/testsuite/cargo_install/help/stdout.term.svg index e021922563f3..bc78e7b0a5e2 100644 --- a/tests/testsuite/cargo_install/help/stdout.term.svg +++ b/tests/testsuite/cargo_install/help/stdout.term.svg @@ -1,4 +1,4 @@ - +