diff --git a/src/bin/cargo/cli.rs b/src/bin/cargo/cli.rs index 7061e849cf3..e71fbe084ce 100644 --- a/src/bin/cargo/cli.rs +++ b/src/bin/cargo/cli.rs @@ -34,7 +34,6 @@ Available unstable (nightly-only) flags: -Z no-index-update -- Do not update the registry, avoids a network request for benchmarking -Z unstable-options -- Allow the usage of unstable options such as --registry -Z config-profile -- Read profiles from .cargo/config files - -Z install-upgrade -- `cargo install` will upgrade instead of failing -Z timings -- Display concurrency information -Z doctest-xcompile -- Compile and run doctests for non-host target using runner config diff --git a/src/bin/cargo/commands/install.rs b/src/bin/cargo/commands/install.rs index 0db246e604f..beb3287e4c9 100644 --- a/src/bin/cargo/commands/install.rs +++ b/src/bin/cargo/commands/install.rs @@ -46,10 +46,7 @@ pub fn cli() -> App { )) .arg_jobs() .arg(opt("force", "Force overwriting existing crates or binaries").short("f")) - .arg(opt( - "no-track", - "Do not save tracking information (unstable)", - )) + .arg(opt("no-track", "Do not save tracking information")) .arg_features() .arg_profile("Install artifacts with the specified profile") .arg(opt("debug", "Build in debug mode instead of release mode")) @@ -90,13 +87,9 @@ crate has multiple binaries, the `--bin` argument can selectively install only one of them, and if you'd rather install examples the `--example` argument can be used as well. -By default cargo will refuse to overwrite existing binaries. The `--force` flag -enables overwriting existing binaries. Thus you can reinstall a crate with -`cargo install --force `. - -Omitting the specification entirely will install the crate in the -current directory. This behaviour is deprecated, and it no longer works in the -Rust 2018 edition. Use the more explicit `install --path .` instead. +If the package is already installed, Cargo will reinstall it if the installed +version does not appear to be up-to-date. Installing with `--path` will always +build and install, unless there are conflicting binaries from another package. If the source is crates.io or `--git` then by default the crate will be built in a temporary target directory. To avoid this, the target directory can be @@ -159,13 +152,6 @@ pub fn exec(config: &mut Config, args: &ArgMatches<'_>) -> CliResult { let version = args.value_of("version"); let root = args.value_of("root"); - if args.is_present("no-track") && !config.cli_unstable().install_upgrade { - return Err(failure::format_err!( - "`--no-track` flag is unstable, pass `-Z install-upgrade` to enable it" - ) - .into()); - }; - if args.is_present("list") { ops::install_list(root, config)?; } else { diff --git a/src/cargo/core/features.rs b/src/cargo/core/features.rs index f7a1cfb60a7..71ad75bba97 100644 --- a/src/cargo/core/features.rs +++ b/src/cargo/core/features.rs @@ -334,7 +334,6 @@ pub struct CliUnstable { pub config_profile: bool, pub dual_proc_macros: bool, pub mtime_on_use: bool, - pub install_upgrade: bool, pub named_profiles: bool, pub binary_dep_depinfo: bool, pub build_std: Option>, @@ -400,7 +399,6 @@ impl CliUnstable { "dual-proc-macros" => self.dual_proc_macros = parse_empty(k, v)?, // can also be set in .cargo/config or with and ENV "mtime-on-use" => self.mtime_on_use = parse_empty(k, v)?, - "install-upgrade" => self.install_upgrade = parse_empty(k, v)?, "named-profiles" => self.named_profiles = parse_empty(k, v)?, "binary-dep-depinfo" => self.binary_dep_depinfo = parse_empty(k, v)?, "build-std" => { diff --git a/src/cargo/ops/common_for_install_and_uninstall.rs b/src/cargo/ops/common_for_install_and_uninstall.rs index 9016c9c5268..4708108d80d 100644 --- a/src/cargo/ops/common_for_install_and_uninstall.rs +++ b/src/cargo/ops/common_for_install_and_uninstall.rs @@ -18,33 +18,31 @@ use crate::util::{FileLock, Filesystem}; /// On-disk tracking for which package installed which binary. /// -/// v1 is an older style, v2 is a new (experimental) style that tracks more -/// information. The new style is only enabled with the `-Z install-upgrade` -/// flag (which sets the `unstable_upgrade` flag). v1 is still considered the -/// source of truth. When v2 is used, it will sync with any changes with v1, -/// and will continue to update v1. +/// v1 is an older style, v2 is a new style that tracks more information, and +/// is both backwards and forwards compatible. Cargo keeps both files in sync, +/// updating both v1 and v2 at the same time. Additionally, if it detects +/// changes in v1 that are not in v2 (such as when an older version of Cargo +/// is used), it will automatically propagate those changes to v2. /// /// This maintains a filesystem lock, preventing other instances of Cargo from /// modifying at the same time. Drop the value to unlock. /// -/// If/when v2 is stabilized, it is intended that v1 is retained for a while -/// during a longish transition period, and then v1 can be removed. +/// It is intended that v1 should be retained for a while during a longish +/// transition period, and then v1 can be removed. pub struct InstallTracker { v1: CrateListingV1, v2: CrateListingV2, v1_lock: FileLock, - v2_lock: Option, - unstable_upgrade: bool, + v2_lock: FileLock, } /// Tracking information for the set of installed packages. -/// -/// This v2 format is unstable and requires the `-Z unstable-upgrade` option -/// to enable. #[derive(Default, Deserialize, Serialize)] struct CrateListingV2 { + /// Map of every installed package. installs: BTreeMap, - /// Forwards compatibility. + /// Forwards compatibility. Unknown keys from future versions of Cargo + /// will be stored here and retained when the file is saved. #[serde(flatten)] other: BTreeMap, } @@ -56,7 +54,7 @@ struct CrateListingV2 { /// determine if it needs to be rebuilt/reinstalled. If nothing has changed, /// then Cargo will inform the user that it is "up to date". /// -/// This is only used for the (unstable) v2 format. +/// This is only used for the v2 format. #[derive(Debug, Deserialize, Serialize)] struct InstallInfo { /// Version requested via `--version`. @@ -87,19 +85,15 @@ struct InstallInfo { /// Tracking information for the set of installed packages. #[derive(Default, Deserialize, Serialize)] pub struct CrateListingV1 { + /// Map of installed package id to the set of binary names for that package. v1: BTreeMap>, } impl InstallTracker { /// Create an InstallTracker from information on disk. pub fn load(config: &Config, root: &Filesystem) -> CargoResult { - let unstable_upgrade = config.cli_unstable().install_upgrade; let v1_lock = root.open_rw(Path::new(".crates.toml"), config, "crate metadata")?; - let v2_lock = if unstable_upgrade { - Some(root.open_rw(Path::new(".crates2.json"), config, "crate metadata")?) - } else { - None - }; + let v2_lock = root.open_rw(Path::new(".crates2.json"), config, "crate metadata")?; let v1 = (|| -> CargoResult<_> { let mut contents = String::new(); @@ -119,26 +113,21 @@ impl InstallTracker { })?; let v2 = (|| -> CargoResult<_> { - match &v2_lock { - Some(lock) => { - let mut contents = String::new(); - lock.file().read_to_string(&mut contents)?; - let mut v2 = if contents.is_empty() { - CrateListingV2::default() - } else { - serde_json::from_str(&contents) - .chain_err(|| format_err!("invalid JSON found for metadata"))? - }; - v2.sync_v1(&v1)?; - Ok(v2) - } - None => Ok(CrateListingV2::default()), - } + let mut contents = String::new(); + v2_lock.file().read_to_string(&mut contents)?; + let mut v2 = if contents.is_empty() { + CrateListingV2::default() + } else { + serde_json::from_str(&contents) + .chain_err(|| format_err!("invalid JSON found for metadata"))? + }; + v2.sync_v1(&v1)?; + Ok(v2) })() .chain_err(|| { format_err!( "failed to parse crate metadata at `{}`", - v2_lock.as_ref().unwrap().path().to_string_lossy() + v2_lock.path().to_string_lossy() ) })?; @@ -147,7 +136,6 @@ impl InstallTracker { v2, v1_lock, v2_lock, - unstable_upgrade, }) } @@ -204,7 +192,7 @@ impl InstallTracker { // If both sets are the same length, that means all duplicates come // from packages with the same name. - if self.unstable_upgrade && matching_duplicates.len() == duplicates.len() { + if matching_duplicates.len() == duplicates.len() { // Determine if it is dirty or fresh. let source_id = pkg.package_id().source_id(); if source_id.is_path() { @@ -265,11 +253,8 @@ impl InstallTracker { .filter_map(|name| { if !dst.join(&name).exists() { None - } else if self.unstable_upgrade { - let p = self.v2.package_for_bin(name); - Some((name.clone(), p)) } else { - let p = self.v1.package_for_bin(name); + let p = self.v2.package_for_bin(name); Some((name.clone(), p)) } }) @@ -286,10 +271,8 @@ impl InstallTracker { target: &str, rustc: &str, ) { - if self.unstable_upgrade { - self.v2 - .mark_installed(package, bins, version_req, opts, target, rustc) - } + self.v2 + .mark_installed(package, bins, version_req, opts, target, rustc); self.v1.mark_installed(package, bins); } @@ -302,14 +285,12 @@ impl InstallTracker { ) })?; - if self.unstable_upgrade { - self.v2.save(self.v2_lock.as_ref().unwrap()).chain_err(|| { - format_err!( - "failed to write crate metadata at `{}`", - self.v2_lock.as_ref().unwrap().path().to_string_lossy() - ) - })?; - } + self.v2.save(&self.v2_lock).chain_err(|| { + format_err!( + "failed to write crate metadata at `{}`", + self.v2_lock.path().to_string_lossy() + ) + })?; Ok(()) } @@ -329,20 +310,11 @@ impl InstallTracker { /// Remove a package from the tracker. pub fn remove(&mut self, pkg_id: PackageId, bins: &BTreeSet) { self.v1.remove(pkg_id, bins); - if self.unstable_upgrade { - self.v2.remove(pkg_id, bins); - } + self.v2.remove(pkg_id, bins); } } impl CrateListingV1 { - fn package_for_bin(&self, bin_name: &str) -> Option { - self.v1 - .iter() - .find(|(_, bins)| bins.contains(bin_name)) - .map(|(pkg_id, _)| *pkg_id) - } - fn mark_installed(&mut self, pkg: &Package, bins: &BTreeSet) { // Remove bins from any other packages. for other_bins in self.v1.values_mut() { @@ -600,24 +572,11 @@ where match v.to_semver() { Ok(v) => Some(format!("={}", v)), Err(e) => { - let mut msg = if config.cli_unstable().install_upgrade { - format!( - "the `--vers` provided, `{}`, is \ - not a valid semver version: {}\n", - v, e - ) - } else { - format!( - "the `--vers` provided, `{}`, is \ - not a valid semver version\n\n\ - historically Cargo treated this \ - as a semver version requirement \ - accidentally\nand will continue \ - to do so, but this behavior \ - will be removed eventually", - v - ) - }; + let mut msg = format!( + "the `--vers` provided, `{}`, is \ + not a valid semver version: {}\n", + v, e + ); // If it is not a valid version but it is a valid version // requirement, add a note to the warning @@ -628,12 +587,7 @@ where v )); } - if config.cli_unstable().install_upgrade { - bail!(msg); - } else { - config.shell().warn(&msg)?; - } - Some(v.to_string()) + bail!(msg); } } } diff --git a/src/doc/man/cargo-install.adoc b/src/doc/man/cargo-install.adoc index fef7b250d18..e88909ba11b 100644 --- a/src/doc/man/cargo-install.adoc +++ b/src/doc/man/cargo-install.adoc @@ -37,6 +37,20 @@ crate has multiple binaries, the `--bin` argument can selectively install only one of them, and if you'd rather install examples the `--example` argument can be used as well. +If the package is already installed, Cargo will reinstall it if the installed +version does not appear to be up-to-date. If any of the following values +change, then Cargo will reinstall the package: + +- The package version and source. +- The set of binary names installed. +- The chosen features. +- The release mode (`--debug`). +- The target (`--target`). + +Installing with `--path` will always build and install, unless there are +conflicting binaries from another package. The `--force` flag may be used to +force Cargo to always reinstall the package. + If the source is crates.io or `--git` then by default the crate will be built in a temporary target directory. To avoid this, the target directory can be specified by setting the `CARGO_TARGET_DIR` environment variable to a relative @@ -63,7 +77,13 @@ available. *--vers* _VERSION_:: *--version* _VERSION_:: - Specify a version to install. + Specify a version to install. This may be a + linkcargo:reference/specifying-dependencies.md[version requirement], like + `~1.2`, to have Cargo select the newest version from the given + requirement. If the version does not have a requirement operator (such as + `^` or `~`), then it must be in the form _MAJOR.MINOR.PATCH_, and will + install exactly that version; it is *not* treated as a caret requirement + like Cargo dependencies are. *--git* _URL_:: Git URL to install the specified crate from. @@ -85,9 +105,18 @@ available. *-f*:: *--force*:: - Force overwriting existing crates or binaries. This can be used to - reinstall or upgrade a crate. - + Force overwriting existing crates or binaries. This can be used if a + package has installed a binary with the same name as another package. This + is also useful if something has changed on the system that you want to + rebuild with, such as a newer version of `rustc`. + +*--no-track*:: + By default, Cargo keeps track of the installed packages with a metadata + file stored in the installation root directory. This flag tells Cargo not + to use or create that file. With this flag, Cargo will refuse to overwrite + any existing files unless the `--force` flag is used. This also disables + Cargo's ability to protect against multiple concurrent invocations of + Cargo installing at the same time. *--bin* _NAME_...:: Install only the specified binary. @@ -137,13 +166,17 @@ include::section-exit-status.adoc[] == EXAMPLES -. Install a package from crates.io: +. Install or upgrade a package from crates.io: cargo install ripgrep -. Reinstall or upgrade a package: +. Install or reinstall the package in the current directory: + + cargo install --path . + +. View the list of installed packages: - cargo install ripgrep --force + cargo install --list == SEE ALSO man:cargo[1], man:cargo-uninstall[1], man:cargo-search[1], man:cargo-publish[1] diff --git a/src/doc/man/generated/cargo-install.html b/src/doc/man/generated/cargo-install.html index 5c567e898c6..252639075f2 100644 --- a/src/doc/man/generated/cargo-install.html +++ b/src/doc/man/generated/cargo-install.html @@ -60,6 +60,35 @@

DESCRIPTION

be used as well.

+

If the package is already installed, Cargo will reinstall it if the installed +version does not appear to be up-to-date. If any of the following values +change, then Cargo will reinstall the package:

+
+
+
    +
  • +

    The package version and source.

    +
  • +
  • +

    The set of binary names installed.

    +
  • +
  • +

    The chosen features.

    +
  • +
  • +

    The release mode (--debug).

    +
  • +
  • +

    The target (--target).

    +
  • +
+
+
+

Installing with --path will always build and install, unless there are +conflicting binaries from another package. The --force flag may be used to +force Cargo to always reinstall the package.

+
+

If the source is crates.io or --git then by default the crate will be built in a temporary target directory. To avoid this, the target directory can be specified by setting the CARGO_TARGET_DIR environment variable to a relative @@ -93,7 +122,13 @@

Install Options

--vers VERSION
--version VERSION
-

Specify a version to install.

+

Specify a version to install. This may be a +version requirement, like +~1.2, to have Cargo select the newest version from the given +requirement. If the version does not have a requirement operator (such as +^ or ~), then it must be in the form MAJOR.MINOR.PATCH, and will +install exactly that version; it is not treated as a caret requirement +like Cargo dependencies are.

--git URL
@@ -122,8 +157,19 @@

Install Options

-f
--force
-

Force overwriting existing crates or binaries. This can be used to -reinstall or upgrade a crate.

+

Force overwriting existing crates or binaries. This can be used if a +package has installed a binary with the same name as another package. This +is also useful if something has changed on the system that you want to +rebuild with, such as a newer version of rustc.

+
+
--no-track
+
+

By default, Cargo keeps track of the installed packages with a metadata +file stored in the installation root directory. This flag tells Cargo not +to use or create that file. With this flag, Cargo will refuse to overwrite +any existing files unless the --force flag is used. This also disables +Cargo’s ability to protect against multiple concurrent invocations of +Cargo installing at the same time.

--bin NAME…​
@@ -346,7 +392,7 @@

EXAMPLES

  1. -

    Install a package from crates.io:

    +

    Install or upgrade a package from crates.io:

    cargo install ripgrep
    @@ -354,10 +400,18 @@

    EXAMPLES

  2. -

    Reinstall or upgrade a package:

    +

    Install or reinstall the package in the current directory:

    +
    +
    +
    cargo install --path .
    +
    +
    +
  3. +
  4. +

    View the list of installed packages:

    -
    cargo install ripgrep --force
    +
    cargo install --list
  5. diff --git a/src/doc/src/reference/unstable.md b/src/doc/src/reference/unstable.md index 861a6885e5f..d7f1cd5de18 100644 --- a/src/doc/src/reference/unstable.md +++ b/src/doc/src/reference/unstable.md @@ -280,38 +280,6 @@ extra-info = "qwerty" Metabuild packages should have a public function called `metabuild` that performs the same actions as a regular `build.rs` script would perform. -### install-upgrade -* Tracking Issue: [#6797](https://github.com/rust-lang/cargo/issues/6797) - -The `install-upgrade` feature changes the behavior of `cargo install` so that -it will reinstall a package if it is not "up-to-date". If it is "up-to-date", -it will do nothing and exit with success instead of failing. Example: - -``` -cargo +nightly install foo -Z install-upgrade -``` - -Cargo tracks some information to determine if a package is "up-to-date", -including: - -- The package version and source. -- The set of binary names installed. -- The chosen features. -- The release mode (`--debug`). -- The target (`--target`). - -If any of these values change, then Cargo will reinstall the package. - -Installation will still fail if a different package installs a binary of the -same name. `--force` may be used to unconditionally reinstall the package. - -Installing with `--path` will always build and install, unless there are -conflicting binaries from another package. - -Additionally, a new flag `--no-track` is available to prevent `cargo install` -from writing tracking information in `$CARGO_HOME` about which packages are -installed. - ### public-dependency * Tracking Issue: [#44663](https://github.com/rust-lang/rust/issues/44663) diff --git a/src/etc/man/cargo-install.1 b/src/etc/man/cargo-install.1 index 358d92109b3..2dfdff5f5ec 100644 --- a/src/etc/man/cargo-install.1 +++ b/src/etc/man/cargo-install.1 @@ -2,12 +2,12 @@ .\" Title: cargo-install .\" Author: [see the "AUTHOR(S)" section] .\" Generator: Asciidoctor 2.0.10 -.\" Date: 2019-10-09 +.\" Date: 2019-11-04 .\" Manual: \ \& .\" Source: \ \& .\" Language: English .\" -.TH "CARGO\-INSTALL" "1" "2019-10-09" "\ \&" "\ \&" +.TH "CARGO\-INSTALL" "1" "2019-11-04" "\ \&" "\ \&" .ie \n(.g .ds Aq \(aq .el .ds Aq ' .ss \n[.ss] 0 @@ -116,6 +116,69 @@ crate has multiple binaries, the \fB\-\-bin\fP argument can selectively install one of them, and if you\(cqd rather install examples the \fB\-\-example\fP argument can be used as well. .sp +If the package is already installed, Cargo will reinstall it if the installed +version does not appear to be up\-to\-date. If any of the following values +change, then Cargo will reinstall the package: +.sp +.RS 4 +.ie n \{\ +\h'-04'\(bu\h'+03'\c +.\} +.el \{\ +. sp -1 +. IP \(bu 2.3 +.\} +The package version and source. +.RE +.sp +.RS 4 +.ie n \{\ +\h'-04'\(bu\h'+03'\c +.\} +.el \{\ +. sp -1 +. IP \(bu 2.3 +.\} +The set of binary names installed. +.RE +.sp +.RS 4 +.ie n \{\ +\h'-04'\(bu\h'+03'\c +.\} +.el \{\ +. sp -1 +. IP \(bu 2.3 +.\} +The chosen features. +.RE +.sp +.RS 4 +.ie n \{\ +\h'-04'\(bu\h'+03'\c +.\} +.el \{\ +. sp -1 +. IP \(bu 2.3 +.\} +The release mode (\fB\-\-debug\fP). +.RE +.sp +.RS 4 +.ie n \{\ +\h'-04'\(bu\h'+03'\c +.\} +.el \{\ +. sp -1 +. IP \(bu 2.3 +.\} +The target (\fB\-\-target\fP). +.RE +.sp +Installing with \fB\-\-path\fP will always build and install, unless there are +conflicting binaries from another package. The \fB\-\-force\fP flag may be used to +force Cargo to always reinstall the package. +.sp If the source is crates.io or \fB\-\-git\fP then by default the crate will be built in a temporary target directory. To avoid this, the target directory can be specified by setting the \fBCARGO_TARGET_DIR\fP environment variable to a relative @@ -140,7 +203,14 @@ available. .sp \fB\-\-vers\fP \fIVERSION\fP, \fB\-\-version\fP \fIVERSION\fP .RS 4 -Specify a version to install. +Specify a version to install. This may be a +.URL "https://doc.rust\-lang.org/cargo/reference/specifying\-dependencies.md" "version requirement" "," +like +\fB~1.2\fP, to have Cargo select the newest version from the given +requirement. If the version does not have a requirement operator (such as +\fB^\fP or \fB~\fP), then it must be in the form \fIMAJOR.MINOR.PATCH\fP, and will +install exactly that version; it is \fBnot\fP treated as a caret requirement +like Cargo dependencies are. .RE .sp \fB\-\-git\fP \fIURL\fP @@ -175,8 +245,20 @@ List all installed packages and their versions. .sp \fB\-f\fP, \fB\-\-force\fP .RS 4 -Force overwriting existing crates or binaries. This can be used to -reinstall or upgrade a crate. +Force overwriting existing crates or binaries. This can be used if a +package has installed a binary with the same name as another package. This +is also useful if something has changed on the system that you want to +rebuild with, such as a newer version of \fBrustc\fP. +.RE +.sp +\fB\-\-no\-track\fP +.RS 4 +By default, Cargo keeps track of the installed packages with a metadata +file stored in the installation root directory. This flag tells Cargo not +to use or create that file. With this flag, Cargo will refuse to overwrite +any existing files unless the \fB\-\-force\fP flag is used. This also disables +Cargo\(cqs ability to protect against multiple concurrent invocations of +Cargo installing at the same time. .RE .sp \fB\-\-bin\fP \fINAME\fP... @@ -385,7 +467,7 @@ Cargo failed to complete. . sp -1 . IP " 1." 4.2 .\} -Install a package from crates.io: +Install or upgrade a package from crates.io: .sp .if n .RS 4 .nf @@ -402,14 +484,31 @@ cargo install ripgrep . sp -1 . IP " 2." 4.2 .\} -Reinstall or upgrade a package: +Install or reinstall the package in the current directory: +.sp +.if n .RS 4 +.nf +cargo install \-\-path . +.fi +.if n .RE +.RE +.sp +.RS 4 +.ie n \{\ +\h'-04' 3.\h'+01'\c +.\} +.el \{\ +. sp -1 +. IP " 3." 4.2 +.\} +View the list of installed packages: .sp .if n .RS 4 .nf -cargo install ripgrep \-\-force +cargo install \-\-list .fi .if n .RE .RE .SH "SEE ALSO" .sp -\fBcargo\fP(1), \fBcargo\-uninstall\fP(1), \fBcargo\-search\fP(1), \fBcargo\-publish\fP(1) \ No newline at end of file +\fBcargo\fP(1), \fBcargo\-uninstall\fP(1), \fBcargo\-search\fP(1), \fBcargo\-publish\fP(1) diff --git a/tests/testsuite/concurrent.rs b/tests/testsuite/concurrent.rs index 43b4363c908..878fe5770bf 100644 --- a/tests/testsuite/concurrent.rs +++ b/tests/testsuite/concurrent.rs @@ -99,20 +99,8 @@ fn one_install_should_be_bad() { let b = b.wait_with_output().unwrap(); let a = a.join().unwrap(); - let (bad, good) = if a.status.code() == Some(101) { - (a, b) - } 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(&a); + execs().run_output(&b); assert_has_installed_exe(cargo_home(), "foo"); } diff --git a/tests/testsuite/install.rs b/tests/testsuite/install.rs index 84641fd5db6..fa011f1e18a 100644 --- a/tests/testsuite/install.rs +++ b/tests/testsuite/install.rs @@ -251,12 +251,15 @@ fn install_path() { cargo_process("install --path").arg(p.root()).run(); assert_has_installed_exe(cargo_home(), "foo"); + // path-style installs force a reinstall p.cargo("install --path .") - .with_status(101) .with_stderr( "\ -[ERROR] binary `foo[..]` already exists in destination as part of `foo v0.0.1 [..]` -Add --force to overwrite +[INSTALLING] foo v0.0.1 [..] +[FINISHED] release [..] +[REPLACING] [..]/.cargo/bin/foo[EXE] +[REPLACED] package `foo v0.0.1 [..]` with `foo v0.0.1 [..]` (executable `foo[EXE]`) +[WARNING] be sure to add [..] ", ) .run(); @@ -450,27 +453,6 @@ fn examples() { assert_has_installed_exe(cargo_home(), "foo"); } -#[cargo_test] -fn install_twice() { - let p = project() - .file("src/bin/foo-bin1.rs", "fn main() {}") - .file("src/bin/foo-bin2.rs", "fn main() {}") - .build(); - - cargo_process("install --path").arg(p.root()).run(); - cargo_process("install --path") - .arg(p.root()) - .with_status(101) - .with_stderr( - "\ -[ERROR] 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 -", - ) - .run(); -} - #[cargo_test] fn install_force() { let p = project().file("src/main.rs", "fn main() {}").build(); @@ -1113,22 +1095,6 @@ but cannot be used multiple times .run(); } -#[cargo_test] -fn legacy_version_requirement() { - pkg("foo", "0.1.1"); - - cargo_process("install foo --vers 0.1") - .with_stderr_contains( - "\ -warning: the `--vers` provided, `0.1`, is not a valid semver version - -historically Cargo treated this as a semver version requirement accidentally -and will continue to do so, but this behavior will be removed eventually -", - ) - .run(); -} - #[cargo_test] fn test_install_git_cannot_be_a_base_url() { cargo_process("install --git github.com:rust-lang-nursery/rustfmt.git") diff --git a/tests/testsuite/install_upgrade.rs b/tests/testsuite/install_upgrade.rs index 256bb164de3..f591b80a28b 100644 --- a/tests/testsuite/install_upgrade.rs +++ b/tests/testsuite/install_upgrade.rs @@ -118,8 +118,7 @@ fn validate_trackers(name: &str, version: &str, bins: &[&str]) { fn registry_upgrade() { // Installing and upgrading from a registry. pkg("foo", "1.0.0"); - cargo_process("install foo -Z install-upgrade") - .masquerade_as_nightly_cargo() + cargo_process("install foo") .with_stderr( "\ [UPDATING] `[..]` index @@ -137,8 +136,7 @@ fn registry_upgrade() { installed_process("foo").with_stdout("1.0.0").run(); validate_trackers("foo", "1.0.0", &["foo"]); - cargo_process("install foo -Z install-upgrade") - .masquerade_as_nightly_cargo() + cargo_process("install foo") .with_stderr( "\ [UPDATING] `[..]` index @@ -150,8 +148,7 @@ fn registry_upgrade() { pkg("foo", "1.0.1"); - cargo_process("install foo -Z install-upgrade") - .masquerade_as_nightly_cargo() + cargo_process("install foo") .with_stderr( "\ [UPDATING] `[..]` index @@ -170,22 +167,19 @@ fn registry_upgrade() { installed_process("foo").with_stdout("1.0.1").run(); validate_trackers("foo", "1.0.1", &["foo"]); - cargo_process("install foo --version=1.0.0 -Z install-upgrade") - .masquerade_as_nightly_cargo() + cargo_process("install foo --version=1.0.0") .with_stderr_contains("[COMPILING] foo v1.0.0") .run(); installed_process("foo").with_stdout("1.0.0").run(); validate_trackers("foo", "1.0.0", &["foo"]); - cargo_process("install foo --version=^1.0 -Z install-upgrade") - .masquerade_as_nightly_cargo() + cargo_process("install foo --version=^1.0") .with_stderr_contains("[COMPILING] foo v1.0.1") .run(); installed_process("foo").with_stdout("1.0.1").run(); validate_trackers("foo", "1.0.1", &["foo"]); - cargo_process("install foo --version=^1.0 -Z install-upgrade") - .masquerade_as_nightly_cargo() + cargo_process("install foo --version=^1.0") .with_stderr_contains("[IGNORED] package `foo v1.0.1` is already installed[..]") .run(); } @@ -194,12 +188,8 @@ fn registry_upgrade() { fn uninstall() { // Basic uninstall test. pkg("foo", "1.0.0"); - cargo_process("install foo -Z install-upgrade") - .masquerade_as_nightly_cargo() - .run(); - cargo_process("uninstall foo -Z install-upgrade") - .masquerade_as_nightly_cargo() - .run(); + cargo_process("install foo").run(); + cargo_process("uninstall foo").run(); let data = load_crates2(); assert_eq!(data["installs"].as_object().unwrap().len(), 0); let v1_table = load_crates1(); @@ -209,11 +199,8 @@ fn uninstall() { #[cargo_test] fn upgrade_force() { pkg("foo", "1.0.0"); - cargo_process("install foo -Z install-upgrade") - .masquerade_as_nightly_cargo() - .run(); - cargo_process("install foo -Z install-upgrade --force") - .masquerade_as_nightly_cargo() + cargo_process("install foo").run(); + cargo_process("install foo --force") .with_stderr( "\ [UPDATING] `[..]` index @@ -233,8 +220,7 @@ fn upgrade_force() { fn ambiguous_version_no_longer_allowed() { // Non-semver-requirement is not allowed for `--version`. pkg("foo", "1.0.0"); - cargo_process("install foo --version=1.0 -Z install-upgrade") - .masquerade_as_nightly_cargo() + cargo_process("install foo --version=1.0") .with_stderr( "\ [UPDATING] `[..]` index @@ -251,11 +237,8 @@ if you want to specify semver range, add an explicit qualifier, like ^1.0 fn path_is_always_dirty() { // --path should always reinstall. let p = project().file("src/main.rs", "fn main() {}").build(); - p.cargo("install --path . -Z install-upgrade") - .masquerade_as_nightly_cargo() - .run(); - p.cargo("install --path . -Z install-upgrade") - .masquerade_as_nightly_cargo() + p.cargo("install --path .").run(); + p.cargo("install --path .") .with_stderr_contains("[REPLACING] [..]/foo[EXE]") .run(); } @@ -267,8 +250,7 @@ fn fails_for_conflicts_unknown() { let exe = installed_exe("foo"); exe.parent().unwrap().mkdir_p(); fs::write(exe, "").unwrap(); - cargo_process("install foo -Z install-upgrade") - .masquerade_as_nightly_cargo() + cargo_process("install foo") .with_stderr_contains("[ERROR] binary `foo[EXE]` already exists in destination") .with_status(101) .run(); @@ -281,11 +263,8 @@ fn fails_for_conflicts_known() { Package::new("bar", "1.0.0") .file("src/bin/foo.rs", "fn main() {}") .publish(); - cargo_process("install foo -Z install-upgrade") - .masquerade_as_nightly_cargo() - .run(); - cargo_process("install bar -Z install-upgrade") - .masquerade_as_nightly_cargo() + cargo_process("install foo").run(); + cargo_process("install bar") .with_stderr_contains( "[ERROR] binary `foo[EXE]` already exists in destination as part of `foo v1.0.0`", ) @@ -301,33 +280,23 @@ fn supports_multiple_binary_names() { .file("src/bin/a.rs", r#"fn main() { println!("a"); }"#) .file("examples/ex1.rs", r#"fn main() { println!("ex1"); }"#) .publish(); - cargo_process("install foo -Z install-upgrade --bin foo") - .masquerade_as_nightly_cargo() - .run(); + cargo_process("install foo --bin foo").run(); installed_process("foo").with_stdout("foo").run(); assert!(!installed_exe("a").exists()); assert!(!installed_exe("ex1").exists()); validate_trackers("foo", "1.0.0", &["foo"]); - cargo_process("install foo -Z install-upgrade --bin a") - .masquerade_as_nightly_cargo() - .run(); + cargo_process("install foo --bin a").run(); installed_process("a").with_stdout("a").run(); assert!(!installed_exe("ex1").exists()); validate_trackers("foo", "1.0.0", &["a", "foo"]); - cargo_process("install foo -Z install-upgrade --example ex1") - .masquerade_as_nightly_cargo() - .run(); + cargo_process("install foo --example ex1").run(); installed_process("ex1").with_stdout("ex1").run(); validate_trackers("foo", "1.0.0", &["a", "ex1", "foo"]); - cargo_process("uninstall foo -Z install-upgrade --bin foo") - .masquerade_as_nightly_cargo() - .run(); + cargo_process("uninstall foo --bin foo").run(); assert!(!installed_exe("foo").exists()); assert!(installed_exe("ex1").exists()); validate_trackers("foo", "1.0.0", &["a", "ex1"]); - cargo_process("uninstall foo -Z install-upgrade") - .masquerade_as_nightly_cargo() - .run(); + cargo_process("uninstall foo").run(); assert!(!installed_exe("ex1").exists()); assert!(!installed_exe("a").exists()); } @@ -337,9 +306,8 @@ fn v1_already_installed_fresh() { // Install with v1, then try to install again with v2. pkg("foo", "1.0.0"); cargo_process("install foo").run(); - cargo_process("install foo -Z install-upgrade") + cargo_process("install foo") .with_stderr_contains("[IGNORED] package `foo v1.0.0` is already installed[..]") - .masquerade_as_nightly_cargo() .run(); } @@ -349,10 +317,9 @@ fn v1_already_installed_dirty() { pkg("foo", "1.0.0"); cargo_process("install foo").run(); pkg("foo", "1.0.1"); - cargo_process("install foo -Z install-upgrade") + cargo_process("install foo") .with_stderr_contains("[COMPILING] foo v1.0.1") .with_stderr_contains("[REPLACING] [..]/foo[EXE]") - .masquerade_as_nightly_cargo() .run(); validate_trackers("foo", "1.0.1", &["foo"]); } @@ -385,37 +352,25 @@ fn change_features_rebuilds() { "#, ) .publish(); - cargo_process("install foo -Z install-upgrade") - .masquerade_as_nightly_cargo() - .run(); + cargo_process("install foo").run(); installed_process("foo").with_stdout("f1").run(); - cargo_process("install foo -Z install-upgrade --no-default-features") - .masquerade_as_nightly_cargo() - .run(); + cargo_process("install foo --no-default-features").run(); installed_process("foo").with_stdout("").run(); - cargo_process("install foo -Z install-upgrade --all-features") - .masquerade_as_nightly_cargo() - .run(); + cargo_process("install foo --all-features").run(); installed_process("foo").with_stdout("f1\nf2").run(); - cargo_process("install foo -Z install-upgrade --no-default-features --features=f1") - .masquerade_as_nightly_cargo() - .run(); + cargo_process("install foo --no-default-features --features=f1").run(); installed_process("foo").with_stdout("f1").run(); } #[cargo_test] fn change_profile_rebuilds() { pkg("foo", "1.0.0"); - cargo_process("install foo -Z install-upgrade") - .masquerade_as_nightly_cargo() - .run(); - cargo_process("install foo -Z install-upgrade --debug") - .masquerade_as_nightly_cargo() + cargo_process("install foo").run(); + cargo_process("install foo --debug") .with_stderr_contains("[COMPILING] foo v1.0.0") .with_stderr_contains("[REPLACING] [..]foo[EXE]") .run(); - cargo_process("install foo -Z install-upgrade --debug") - .masquerade_as_nightly_cargo() + cargo_process("install foo --debug") .with_stderr_contains("[IGNORED] package `foo v1.0.0` is already installed[..]") .run(); } @@ -426,13 +381,10 @@ fn change_target_rebuilds() { return; } pkg("foo", "1.0.0"); - cargo_process("install foo -Z install-upgrade") - .masquerade_as_nightly_cargo() - .run(); + cargo_process("install foo").run(); let target = cross_compile::alternate(); - cargo_process("install foo -v -Z install-upgrade --target") + cargo_process("install foo -v --target") .arg(&target) - .masquerade_as_nightly_cargo() .with_stderr_contains("[COMPILING] foo v1.0.0") .with_stderr_contains("[REPLACING] [..]foo[EXE]") .with_stderr_contains(&format!("[..]--target {}[..]", target)) @@ -447,23 +399,19 @@ fn change_bin_sets_rebuilds() { .file("src/bin/x.rs", "fn main() { }") .file("src/bin/y.rs", "fn main() { }") .publish(); - cargo_process("install foo -Z install-upgrade --bin x") - .masquerade_as_nightly_cargo() - .run(); + cargo_process("install foo --bin x").run(); assert!(installed_exe("x").exists()); assert!(!installed_exe("y").exists()); assert!(!installed_exe("foo").exists()); validate_trackers("foo", "1.0.0", &["x"]); - cargo_process("install foo -Z install-upgrade --bin y") - .masquerade_as_nightly_cargo() + cargo_process("install foo --bin y") .with_stderr_contains("[INSTALLED] package `foo v1.0.0` (executable `y[EXE]`)") .run(); assert!(installed_exe("x").exists()); assert!(installed_exe("y").exists()); assert!(!installed_exe("foo").exists()); validate_trackers("foo", "1.0.0", &["x", "y"]); - cargo_process("install foo -Z install-upgrade") - .masquerade_as_nightly_cargo() + cargo_process("install foo") .with_stderr_contains("[INSTALLED] package `foo v1.0.0` (executable `foo[EXE]`)") .with_stderr_contains( "[REPLACED] package `foo v1.0.0` with `foo v1.0.0` (executables `x[EXE]`, `y[EXE]`)", @@ -480,18 +428,14 @@ fn forwards_compatible() { // Unknown fields should be preserved. pkg("foo", "1.0.0"); pkg("bar", "1.0.0"); - cargo_process("install foo -Z install-upgrade") - .masquerade_as_nightly_cargo() - .run(); + cargo_process("install foo").run(); let key = "foo 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)"; let v2 = cargo_home().join(".crates2.json"); let mut data = load_crates2(); data["newfield"] = serde_json::Value::Bool(true); data["installs"][key]["moreinfo"] = serde_json::Value::String("shazam".to_string()); fs::write(&v2, serde_json::to_string(&data).unwrap()).unwrap(); - cargo_process("install bar -Z install-upgrade") - .masquerade_as_nightly_cargo() - .run(); + cargo_process("install bar").run(); let data: serde_json::Value = serde_json::from_str(&fs::read_to_string(&v2).unwrap()).unwrap(); assert_eq!(data["newfield"].as_bool().unwrap(), true); assert_eq!( @@ -510,21 +454,15 @@ fn v2_syncs() { .file("src/bin/x.rs", "fn main() {}") .file("src/bin/y.rs", "fn main() {}") .build(); - cargo_process("install one -Z install-upgrade") - .masquerade_as_nightly_cargo() - .run(); + cargo_process("install one").run(); validate_trackers("one", "1.0.0", &["one"]); - p.cargo("install -Z install-upgrade --path .") - .masquerade_as_nightly_cargo() - .run(); + p.cargo("install --path .").run(); validate_trackers("foo", "1.0.0", &["x", "y"]); // v1 add/remove cargo_process("install two").run(); cargo_process("uninstall one").run(); // This should pick up that `two` was added, `one` was removed. - cargo_process("install three -Z install-upgrade") - .masquerade_as_nightly_cargo() - .run(); + cargo_process("install three").run(); validate_trackers("three", "1.0.0", &["three"]); cargo_process("install --list") .with_stdout( @@ -539,13 +477,10 @@ two v1.0.0: ", ) .run(); - cargo_process("install one -Z install-upgrade") - .masquerade_as_nightly_cargo() - .run(); + cargo_process("install one").run(); installed_process("one").with_stdout("1.0.0").run(); validate_trackers("one", "1.0.0", &["one"]); - cargo_process("install two -Z install-upgrade") - .masquerade_as_nightly_cargo() + cargo_process("install two") .with_stderr_contains("[IGNORED] package `two v1.0.0` is already installed[..]") .run(); // v1 remove @@ -553,13 +488,10 @@ two v1.0.0: pkg("x", "1.0.0"); pkg("y", "1.0.0"); // This should succeed because `x` was removed in V1. - cargo_process("install x -Z install-upgrade") - .masquerade_as_nightly_cargo() - .run(); + cargo_process("install x").run(); validate_trackers("x", "1.0.0", &["x"]); // This should fail because `y` still exists in a different package. - cargo_process("install y -Z install-upgrade") - .masquerade_as_nightly_cargo() + cargo_process("install y") .with_stderr_contains( "[ERROR] binary `y[EXE]` already exists in destination \ as part of `foo v0.0.1 ([..])`", @@ -572,14 +504,12 @@ two v1.0.0: fn upgrade_git() { let git_project = git::new("foo", |project| project.file("src/main.rs", "fn main() {}")); // install - cargo_process("install -Z install-upgrade --git") + cargo_process("install --git") .arg(git_project.url().to_string()) - .masquerade_as_nightly_cargo() .run(); // Check install stays fresh. - cargo_process("install -Z install-upgrade --git") + cargo_process("install --git") .arg(git_project.url().to_string()) - .masquerade_as_nightly_cargo() .with_stderr_contains( "[IGNORED] package `foo v0.0.1 (file://[..]/foo#[..])` is \ already installed,[..]", @@ -591,17 +521,15 @@ fn upgrade_git() { git::add(&repo); git::commit(&repo); // Install should reinstall. - cargo_process("install -Z install-upgrade --git") + cargo_process("install --git") .arg(git_project.url().to_string()) - .masquerade_as_nightly_cargo() .with_stderr_contains("[COMPILING] foo v0.0.1 ([..])") .with_stderr_contains("[REPLACING] [..]/foo[EXE]") .run(); installed_process("foo").with_stdout("onomatopoeia").run(); // Check install stays fresh. - cargo_process("install -Z install-upgrade --git") + cargo_process("install --git") .arg(git_project.url().to_string()) - .masquerade_as_nightly_cargo() .with_stderr_contains( "[IGNORED] package `foo v0.0.1 (file://[..]/foo#[..])` is \ already installed,[..]", @@ -627,21 +555,14 @@ fn switch_sources() { project.file("src/main.rs", r#"fn main() { println!("git"); }"#) }); - cargo_process("install -Z install-upgrade foo") - .masquerade_as_nightly_cargo() - .run(); + cargo_process("install foo").run(); installed_process("foo").with_stdout("1.0.0").run(); - cargo_process("install -Z install-upgrade foo --registry alternative") - .masquerade_as_nightly_cargo() - .run(); + cargo_process("install foo --registry alternative").run(); installed_process("foo").with_stdout("alt").run(); - p.cargo("install -Z install-upgrade --path .") - .masquerade_as_nightly_cargo() - .run(); + p.cargo("install --path .").run(); installed_process("foo").with_stdout("local").run(); - cargo_process("install -Z install-upgrade --git") + cargo_process("install --git") .arg(git_project.url().to_string()) - .masquerade_as_nightly_cargo() .run(); installed_process("foo").with_stdout("git").run(); } @@ -659,8 +580,7 @@ fn multiple_report() { .publish(); } three("1.0.0"); - cargo_process("install -Z install-upgrade one two three") - .masquerade_as_nightly_cargo() + cargo_process("install one two three") .with_stderr( "\ [UPDATING] `[..]` index @@ -695,8 +615,7 @@ fn multiple_report() { pkg("foo", "1.0.1"); pkg("bar", "1.0.1"); three("1.0.1"); - cargo_process("install -Z install-upgrade one two three") - .masquerade_as_nightly_cargo() + cargo_process("install one two three") .with_stderr( "\ [UPDATING] `[..]` index @@ -716,8 +635,7 @@ fn multiple_report() { ", ) .run(); - cargo_process("uninstall -Z install-upgrade three") - .masquerade_as_nightly_cargo() + cargo_process("uninstall three") .with_stderr( "\ [REMOVING] [..]/.cargo/bin/three[EXE] @@ -726,8 +644,7 @@ fn multiple_report() { ", ) .run(); - cargo_process("install -Z install-upgrade three --bin x") - .masquerade_as_nightly_cargo() + cargo_process("install three --bin x") .with_stderr( "\ [UPDATING] `[..]` index @@ -740,8 +657,7 @@ fn multiple_report() { ", ) .run(); - cargo_process("install -Z install-upgrade three") - .masquerade_as_nightly_cargo() + cargo_process("install three") .with_stderr( "\ [UPDATING] `[..]` index @@ -759,27 +675,13 @@ fn multiple_report() { .run(); } -#[cargo_test] -fn no_track_gated() { - cargo_process("install --no-track foo") - .masquerade_as_nightly_cargo() - .with_stderr( - "[ERROR] `--no-track` flag is unstable, pass `-Z install-upgrade` to enable it", - ) - .with_status(101) - .run(); -} - #[cargo_test] fn no_track() { pkg("foo", "1.0.0"); - cargo_process("install --no-track foo -Z install-upgrade") - .masquerade_as_nightly_cargo() - .run(); + cargo_process("install --no-track foo").run(); assert!(!v1_path().exists()); assert!(!v2_path().exists()); - cargo_process("install --no-track foo -Z install-upgrade") - .masquerade_as_nightly_cargo() + cargo_process("install --no-track foo") .with_stderr( "\ [UPDATING] `[..]` index @@ -807,9 +709,7 @@ fn deletes_orphaned() { .file("src/bin/other.rs", "fn main() {}") .file("examples/ex1.rs", "fn main() {}") .build(); - p.cargo("install -Z install-upgrade --path . --bins --examples") - .masquerade_as_nightly_cargo() - .run(); + p.cargo("install --path . --bins --examples").run(); assert!(installed_exe("other").exists()); // Remove a binary, add a new one, and bump the version. @@ -823,8 +723,7 @@ fn deletes_orphaned() { version = "0.2.0" "#, ); - p.cargo("install -Z install-upgrade --path . --bins --examples") - .masquerade_as_nightly_cargo() + p.cargo("install --path . --bins --examples") .with_stderr( "\ [INSTALLING] foo v0.2.0 [..]