diff --git a/src/cargo/ops/cargo_install.rs b/src/cargo/ops/cargo_install.rs index 4e1036abb52..134b9eb6bed 100644 --- a/src/cargo/ops/cargo_install.rs +++ b/src/cargo/ops/cargo_install.rs @@ -419,10 +419,29 @@ fn check_overwrites( failure::bail!("specified package has no binaries") } let duplicates = find_duplicates(dst, pkg, filter, prev); + if force || duplicates.is_empty() { return Ok(duplicates); } - // Format the error message. + + let msg = check_overwrites_format_error_message(&duplicates); + + let is_installed_old = duplicates + .iter() + .filter(|(_, v)| v.is_some()) + .all(|(_, v)| v.unwrap().version() < pkg.version()); + + if is_installed_old { + return Ok(duplicates); + } + + eprintln!("{}", msg); + std::process::exit(0) +} + +fn check_overwrites_format_error_message( + duplicates: &BTreeMap>, +) -> String { let mut msg = String::new(); for (bin, p) in duplicates.iter() { msg.push_str(&format!("binary `{}` already exists in destination", bin)); @@ -433,7 +452,8 @@ fn check_overwrites( } } msg.push_str("Add --force to overwrite"); - Err(failure::format_err!("{}", msg)) + + msg } fn find_duplicates( diff --git a/tests/testsuite/concurrent.rs b/tests/testsuite/concurrent.rs index 90e7847807c..c1d6cd6c6d9 100644 --- a/tests/testsuite/concurrent.rs +++ b/tests/testsuite/concurrent.rs @@ -105,15 +105,8 @@ fn one_install_should_be_bad() { } else { (b, a) }; - execs() - .with_status(101) - .with_stderr_contains( - "[ERROR] binary `foo[..]` already exists in destination as part of `[..]`", - ) - .run_output(&bad); - execs() - .with_stderr_contains("warning: be sure to add `[..]` to your PATH [..]") - .run_output(&good); + execs().run_output(&bad); + execs().run_output(&good); assert_has_installed_exe(cargo_home(), "foo"); } diff --git a/tests/testsuite/install.rs b/tests/testsuite/install.rs index b7955461f68..5bca026abed 100644 --- a/tests/testsuite/install.rs +++ b/tests/testsuite/install.rs @@ -247,11 +247,10 @@ fn install_path() { cargo_process("install --path").arg(p.root()).run(); assert_has_installed_exe(cargo_home(), "foo"); p.cargo("install --path .") - .with_status(101) .with_stderr( "\ [INSTALLING] foo v0.0.1 [..] -[ERROR] binary `foo[..]` already exists in destination as part of `foo v0.0.1 [..]` +binary `foo[..]` already exists in destination as part of `foo v0.0.1 [..]` Add --force to overwrite ", ) @@ -457,11 +456,10 @@ fn install_twice() { cargo_process("install --path").arg(p.root()).run(); cargo_process("install --path") .arg(p.root()) - .with_status(101) .with_stderr( "\ [INSTALLING] foo v0.0.1 [..] -[ERROR] binary `foo-bin1[..]` already exists in destination as part of `foo v0.0.1 ([..])` +binary `foo-bin1[..]` already exists in destination as part of `foo v0.0.1 ([..])` binary `foo-bin2[..]` already exists in destination as part of `foo v0.0.1 ([..])` Add --force to overwrite ", @@ -469,6 +467,41 @@ Add --force to overwrite .run(); } +#[test] +fn install_version_update() { + let p = project() + .at("foo1") + .file("Cargo.toml", &basic_manifest("foo", "0.1.0")) + .file("src/main.rs", "fn main() {}") + .build(); + + cargo_process("install --path").arg(p.root()).run(); + cargo_process("install --list") + .with_stdout( + "\ +foo v0.1.0 ([..]): + foo[..] +", + ) + .run(); + + let p = project() + .at("foo2") + .file("Cargo.toml", &basic_manifest("foo", "0.2.0")) + .file("src/main.rs", "fn main() {}") + .build(); + + cargo_process("install --path").arg(p.root()).run(); + cargo_process("install --list") + .with_stdout( + "\ +foo v0.2.0 ([..]): + foo[..] +", + ) + .run(); +} + #[test] fn install_force() { let p = project().file("src/main.rs", "fn main() {}").build();