diff --git a/src/cargo/core/workspace.rs b/src/cargo/core/workspace.rs index 45b6a7877..1b0c6bd0d 100644 --- a/src/cargo/core/workspace.rs +++ b/src/cargo/core/workspace.rs @@ -77,6 +77,10 @@ pub struct Workspace<'cfg> { // A cache of loaded packages for particular paths which is disjoint from // `packages` up above, used in the `load` method down below. loaded_packages: RefCell>, + + // If `true`, then the resolver will ignore any existing `Cargo.lock` + // file. This is set for `cargo install` without `--locked`. + ignore_lock: bool, } // Separate structure for tracking loaded packages (to avoid loading anything @@ -148,6 +152,7 @@ impl<'cfg> Workspace<'cfg> { is_ephemeral: false, require_optional_deps: true, loaded_packages: RefCell::new(HashMap::new()), + ignore_lock: false, }; ws.root_manifest = ws.find_root(manifest_path)?; ws.find_members()?; @@ -184,6 +189,7 @@ impl<'cfg> Workspace<'cfg> { is_ephemeral: true, require_optional_deps, loaded_packages: RefCell::new(HashMap::new()), + ignore_lock: false, }; { let key = ws.current_manifest.parent().unwrap(); @@ -320,14 +326,23 @@ impl<'cfg> Workspace<'cfg> { self.require_optional_deps } - pub fn set_require_optional_deps<'a>( - &'a mut self, + pub fn set_require_optional_deps( + &mut self, require_optional_deps: bool, ) -> &mut Workspace<'cfg> { self.require_optional_deps = require_optional_deps; self } + pub fn ignore_lock(&self) -> bool { + self.ignore_lock + } + + pub fn set_ignore_lock(&mut self, ignore_lock: bool) -> &mut Workspace<'cfg> { + self.ignore_lock = ignore_lock; + self + } + /// Finds the root of a workspace for the crate whose manifest is located /// at `manifest_path`. /// diff --git a/src/cargo/ops/cargo_install.rs b/src/cargo/ops/cargo_install.rs index 12ea145a1..08c4693d3 100644 --- a/src/cargo/ops/cargo_install.rs +++ b/src/cargo/ops/cargo_install.rs @@ -215,7 +215,11 @@ fn install_one( }; let ws = match overidden_target_dir { - Some(dir) => Workspace::ephemeral(pkg, config, Some(dir), false)?, + Some(dir) => { + let mut ws = Workspace::ephemeral(pkg, config, Some(dir), false)?; + ws.set_ignore_lock(config.lock_update_allowed()); + ws + } None => { let mut ws = Workspace::new(pkg.manifest_path(), config)?; ws.set_require_optional_deps(false); diff --git a/src/cargo/ops/resolve.rs b/src/cargo/ops/resolve.rs index f14abf182..1532fb31b 100644 --- a/src/cargo/ops/resolve.rs +++ b/src/cargo/ops/resolve.rs @@ -64,7 +64,9 @@ pub fn resolve_ws_with_method<'a>( } let mut add_patches = true; - let resolve = if ws.require_optional_deps() { + let resolve = if ws.ignore_lock() { + None + } else if ws.require_optional_deps() { // First, resolve the root_package's *listed* dependencies, as well as // downloading and updating all remotes and such. let resolve = resolve_with_registry(ws, &mut registry, false)?; diff --git a/tests/testsuite/install.rs b/tests/testsuite/install.rs index 0a0ead7bc..ada9f3f5c 100644 --- a/tests/testsuite/install.rs +++ b/tests/testsuite/install.rs @@ -1190,6 +1190,8 @@ fn custom_target_dir_for_git_source() { #[test] fn install_respects_lock_file() { + // `cargo install` now requires --locked to use a Cargo.lock for non + // --path installs. Package::new("bar", "0.1.0").publish(); Package::new("bar", "0.1.1") .file("src/lib.rs", "not rust") @@ -1219,7 +1221,52 @@ dependencies = [ ) .publish(); - cargo_process("install foo").run(); + cargo_process("install foo") + .with_stderr_contains("[..]not rust[..]") + .with_status(101) + .run(); + cargo_process("install --locked foo").run(); +} + +#[test] +fn install_path_respects_lock_file() { + // For --path installs, always use local Cargo.lock. + Package::new("bar", "0.1.0").publish(); + Package::new("bar", "0.1.1") + .file("src/lib.rs", "not rust") + .publish(); + let p = project() + .file( + "Cargo.toml", + r#" + [package] + name = "foo" + version = "0.1.0" + + [dependencies] + bar = "0.1" + "#, + ) + .file("src/main.rs", "extern crate bar; fn main() {}") + .file( + "Cargo.lock", + r#" +[[package]] +name = "bar" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" + +[[package]] +name = "foo" +version = "0.1.0" +dependencies = [ + "bar 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", +] +"#, + ) + .build(); + + p.cargo("install --path .").run(); } #[test]