cargo install: Ignore Cargo.lock for non --path installs.

Requires `--locked` to use Cargo.lock for registry and git installs.
This commit is contained in:
Eric Huss 2019-04-07 18:26:08 -07:00
parent 27932ead44
commit 3d89379367
4 changed files with 73 additions and 5 deletions

View file

@ -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<HashMap<PathBuf, Package>>,
// 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`.
///

View file

@ -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);

View file

@ -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)?;

View file

@ -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]