Skip to content

Commit f7b2971

Browse files
committed
Stabilize install-upgrade.
1 parent f612284 commit f7b2971

File tree

11 files changed

+323
-379
lines changed

11 files changed

+323
-379
lines changed

src/bin/cargo/cli.rs

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,6 @@ Available unstable (nightly-only) flags:
3434
-Z no-index-update -- Do not update the registry, avoids a network request for benchmarking
3535
-Z unstable-options -- Allow the usage of unstable options such as --registry
3636
-Z config-profile -- Read profiles from .cargo/config files
37-
-Z install-upgrade -- `cargo install` will upgrade instead of failing
3837
-Z timings -- Display concurrency information
3938
-Z doctest-xcompile -- Compile and run doctests for non-host target using runner config
4039

src/bin/cargo/commands/install.rs

Lines changed: 4 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -46,10 +46,7 @@ pub fn cli() -> App {
4646
))
4747
.arg_jobs()
4848
.arg(opt("force", "Force overwriting existing crates or binaries").short("f"))
49-
.arg(opt(
50-
"no-track",
51-
"Do not save tracking information (unstable)",
52-
))
49+
.arg(opt("no-track", "Do not save tracking information"))
5350
.arg_features()
5451
.arg_profile("Install artifacts with the specified profile")
5552
.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
9087
one of them, and if you'd rather install examples the `--example` argument can
9188
be used as well.
9289
93-
By default cargo will refuse to overwrite existing binaries. The `--force` flag
94-
enables overwriting existing binaries. Thus you can reinstall a crate with
95-
`cargo install --force <crate>`.
96-
97-
Omitting the <crate> specification entirely will install the crate in the
98-
current directory. This behaviour is deprecated, and it no longer works in the
99-
Rust 2018 edition. Use the more explicit `install --path .` instead.
90+
If the package is already installed, Cargo will reinstall it if the installed
91+
version does not appear to be up-to-date. Installing with `--path` will always
92+
build and install, unless there are conflicting binaries from another package.
10093
10194
If the source is crates.io or `--git` then by default the crate will be built
10295
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 {
159152
let version = args.value_of("version");
160153
let root = args.value_of("root");
161154

162-
if args.is_present("no-track") && !config.cli_unstable().install_upgrade {
163-
return Err(failure::format_err!(
164-
"`--no-track` flag is unstable, pass `-Z install-upgrade` to enable it"
165-
)
166-
.into());
167-
};
168-
169155
if args.is_present("list") {
170156
ops::install_list(root, config)?;
171157
} else {

src/cargo/core/features.rs

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -334,7 +334,6 @@ pub struct CliUnstable {
334334
pub config_profile: bool,
335335
pub dual_proc_macros: bool,
336336
pub mtime_on_use: bool,
337-
pub install_upgrade: bool,
338337
pub named_profiles: bool,
339338
pub binary_dep_depinfo: bool,
340339
pub build_std: Option<Vec<String>>,
@@ -400,7 +399,6 @@ impl CliUnstable {
400399
"dual-proc-macros" => self.dual_proc_macros = parse_empty(k, v)?,
401400
// can also be set in .cargo/config or with and ENV
402401
"mtime-on-use" => self.mtime_on_use = parse_empty(k, v)?,
403-
"install-upgrade" => self.install_upgrade = parse_empty(k, v)?,
404402
"named-profiles" => self.named_profiles = parse_empty(k, v)?,
405403
"binary-dep-depinfo" => self.binary_dep_depinfo = parse_empty(k, v)?,
406404
"build-std" => {

src/cargo/ops/common_for_install_and_uninstall.rs

Lines changed: 42 additions & 88 deletions
Original file line numberDiff line numberDiff line change
@@ -18,33 +18,31 @@ use crate::util::{FileLock, Filesystem};
1818

1919
/// On-disk tracking for which package installed which binary.
2020
///
21-
/// v1 is an older style, v2 is a new (experimental) style that tracks more
22-
/// information. The new style is only enabled with the `-Z install-upgrade`
23-
/// flag (which sets the `unstable_upgrade` flag). v1 is still considered the
24-
/// source of truth. When v2 is used, it will sync with any changes with v1,
25-
/// and will continue to update v1.
21+
/// v1 is an older style, v2 is a new style that tracks more information, and
22+
/// is both backwards and forwards compatible. Cargo keeps both files in sync,
23+
/// updating both v1 and v2 at the same time. Additionally, if it detects
24+
/// changes in v1 that are not in v2 (such as when an older version of Cargo
25+
/// is used), it will automatically propagate those changes to v2.
2626
///
2727
/// This maintains a filesystem lock, preventing other instances of Cargo from
2828
/// modifying at the same time. Drop the value to unlock.
2929
///
30-
/// If/when v2 is stabilized, it is intended that v1 is retained for a while
31-
/// during a longish transition period, and then v1 can be removed.
30+
/// It is intended that v1 should be retained for a while during a longish
31+
/// transition period, and then v1 can be removed.
3232
pub struct InstallTracker {
3333
v1: CrateListingV1,
3434
v2: CrateListingV2,
3535
v1_lock: FileLock,
36-
v2_lock: Option<FileLock>,
37-
unstable_upgrade: bool,
36+
v2_lock: FileLock,
3837
}
3938

4039
/// Tracking information for the set of installed packages.
41-
///
42-
/// This v2 format is unstable and requires the `-Z unstable-upgrade` option
43-
/// to enable.
4440
#[derive(Default, Deserialize, Serialize)]
4541
struct CrateListingV2 {
42+
/// Map of every installed package.
4643
installs: BTreeMap<PackageId, InstallInfo>,
47-
/// Forwards compatibility.
44+
/// Forwards compatibility. Unknown keys from future versions of Cargo
45+
/// will be stored here and retained when the file is saved.
4846
#[serde(flatten)]
4947
other: BTreeMap<String, serde_json::Value>,
5048
}
@@ -56,7 +54,7 @@ struct CrateListingV2 {
5654
/// determine if it needs to be rebuilt/reinstalled. If nothing has changed,
5755
/// then Cargo will inform the user that it is "up to date".
5856
///
59-
/// This is only used for the (unstable) v2 format.
57+
/// This is only used for the v2 format.
6058
#[derive(Debug, Deserialize, Serialize)]
6159
struct InstallInfo {
6260
/// Version requested via `--version`.
@@ -87,19 +85,15 @@ struct InstallInfo {
8785
/// Tracking information for the set of installed packages.
8886
#[derive(Default, Deserialize, Serialize)]
8987
pub struct CrateListingV1 {
88+
/// Map of installed package id to the set of binary names for that package.
9089
v1: BTreeMap<PackageId, BTreeSet<String>>,
9190
}
9291

9392
impl InstallTracker {
9493
/// Create an InstallTracker from information on disk.
9594
pub fn load(config: &Config, root: &Filesystem) -> CargoResult<InstallTracker> {
96-
let unstable_upgrade = config.cli_unstable().install_upgrade;
9795
let v1_lock = root.open_rw(Path::new(".crates.toml"), config, "crate metadata")?;
98-
let v2_lock = if unstable_upgrade {
99-
Some(root.open_rw(Path::new(".crates2.json"), config, "crate metadata")?)
100-
} else {
101-
None
102-
};
96+
let v2_lock = root.open_rw(Path::new(".crates2.json"), config, "crate metadata")?;
10397

10498
let v1 = (|| -> CargoResult<_> {
10599
let mut contents = String::new();
@@ -119,26 +113,21 @@ impl InstallTracker {
119113
})?;
120114

121115
let v2 = (|| -> CargoResult<_> {
122-
match &v2_lock {
123-
Some(lock) => {
124-
let mut contents = String::new();
125-
lock.file().read_to_string(&mut contents)?;
126-
let mut v2 = if contents.is_empty() {
127-
CrateListingV2::default()
128-
} else {
129-
serde_json::from_str(&contents)
130-
.chain_err(|| format_err!("invalid JSON found for metadata"))?
131-
};
132-
v2.sync_v1(&v1)?;
133-
Ok(v2)
134-
}
135-
None => Ok(CrateListingV2::default()),
136-
}
116+
let mut contents = String::new();
117+
v2_lock.file().read_to_string(&mut contents)?;
118+
let mut v2 = if contents.is_empty() {
119+
CrateListingV2::default()
120+
} else {
121+
serde_json::from_str(&contents)
122+
.chain_err(|| format_err!("invalid JSON found for metadata"))?
123+
};
124+
v2.sync_v1(&v1)?;
125+
Ok(v2)
137126
})()
138127
.chain_err(|| {
139128
format_err!(
140129
"failed to parse crate metadata at `{}`",
141-
v2_lock.as_ref().unwrap().path().to_string_lossy()
130+
v2_lock.path().to_string_lossy()
142131
)
143132
})?;
144133

@@ -147,7 +136,6 @@ impl InstallTracker {
147136
v2,
148137
v1_lock,
149138
v2_lock,
150-
unstable_upgrade,
151139
})
152140
}
153141

@@ -204,7 +192,7 @@ impl InstallTracker {
204192

205193
// If both sets are the same length, that means all duplicates come
206194
// from packages with the same name.
207-
if self.unstable_upgrade && matching_duplicates.len() == duplicates.len() {
195+
if matching_duplicates.len() == duplicates.len() {
208196
// Determine if it is dirty or fresh.
209197
let source_id = pkg.package_id().source_id();
210198
if source_id.is_path() {
@@ -265,11 +253,8 @@ impl InstallTracker {
265253
.filter_map(|name| {
266254
if !dst.join(&name).exists() {
267255
None
268-
} else if self.unstable_upgrade {
269-
let p = self.v2.package_for_bin(name);
270-
Some((name.clone(), p))
271256
} else {
272-
let p = self.v1.package_for_bin(name);
257+
let p = self.v2.package_for_bin(name);
273258
Some((name.clone(), p))
274259
}
275260
})
@@ -286,10 +271,8 @@ impl InstallTracker {
286271
target: &str,
287272
rustc: &str,
288273
) {
289-
if self.unstable_upgrade {
290-
self.v2
291-
.mark_installed(package, bins, version_req, opts, target, rustc)
292-
}
274+
self.v2
275+
.mark_installed(package, bins, version_req, opts, target, rustc);
293276
self.v1.mark_installed(package, bins);
294277
}
295278

@@ -302,14 +285,12 @@ impl InstallTracker {
302285
)
303286
})?;
304287

305-
if self.unstable_upgrade {
306-
self.v2.save(self.v2_lock.as_ref().unwrap()).chain_err(|| {
307-
format_err!(
308-
"failed to write crate metadata at `{}`",
309-
self.v2_lock.as_ref().unwrap().path().to_string_lossy()
310-
)
311-
})?;
312-
}
288+
self.v2.save(&self.v2_lock).chain_err(|| {
289+
format_err!(
290+
"failed to write crate metadata at `{}`",
291+
self.v2_lock.path().to_string_lossy()
292+
)
293+
})?;
313294
Ok(())
314295
}
315296

@@ -329,20 +310,11 @@ impl InstallTracker {
329310
/// Remove a package from the tracker.
330311
pub fn remove(&mut self, pkg_id: PackageId, bins: &BTreeSet<String>) {
331312
self.v1.remove(pkg_id, bins);
332-
if self.unstable_upgrade {
333-
self.v2.remove(pkg_id, bins);
334-
}
313+
self.v2.remove(pkg_id, bins);
335314
}
336315
}
337316

338317
impl CrateListingV1 {
339-
fn package_for_bin(&self, bin_name: &str) -> Option<PackageId> {
340-
self.v1
341-
.iter()
342-
.find(|(_, bins)| bins.contains(bin_name))
343-
.map(|(pkg_id, _)| *pkg_id)
344-
}
345-
346318
fn mark_installed(&mut self, pkg: &Package, bins: &BTreeSet<String>) {
347319
// Remove bins from any other packages.
348320
for other_bins in self.v1.values_mut() {
@@ -600,24 +572,11 @@ where
600572
match v.to_semver() {
601573
Ok(v) => Some(format!("={}", v)),
602574
Err(e) => {
603-
let mut msg = if config.cli_unstable().install_upgrade {
604-
format!(
605-
"the `--vers` provided, `{}`, is \
606-
not a valid semver version: {}\n",
607-
v, e
608-
)
609-
} else {
610-
format!(
611-
"the `--vers` provided, `{}`, is \
612-
not a valid semver version\n\n\
613-
historically Cargo treated this \
614-
as a semver version requirement \
615-
accidentally\nand will continue \
616-
to do so, but this behavior \
617-
will be removed eventually",
618-
v
619-
)
620-
};
575+
let mut msg = format!(
576+
"the `--vers` provided, `{}`, is \
577+
not a valid semver version: {}\n",
578+
v, e
579+
);
621580

622581
// If it is not a valid version but it is a valid version
623582
// requirement, add a note to the warning
@@ -628,12 +587,7 @@ where
628587
v
629588
));
630589
}
631-
if config.cli_unstable().install_upgrade {
632-
bail!(msg);
633-
} else {
634-
config.shell().warn(&msg)?;
635-
}
636-
Some(v.to_string())
590+
bail!(msg);
637591
}
638592
}
639593
}

src/doc/man/cargo-install.adoc

Lines changed: 40 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,20 @@ crate has multiple binaries, the `--bin` argument can selectively install only
3737
one of them, and if you'd rather install examples the `--example` argument can
3838
be used as well.
3939

40+
If the package is already installed, Cargo will reinstall it if the installed
41+
version does not appear to be up-to-date. If any of the following values
42+
change, then Cargo will reinstall the package:
43+
44+
- The package version and source.
45+
- The set of binary names installed.
46+
- The chosen features.
47+
- The release mode (`--debug`).
48+
- The target (`--target`).
49+
50+
Installing with `--path` will always build and install, unless there are
51+
conflicting binaries from another package. The `--force` flag may be used to
52+
force Cargo to always reinstall the package.
53+
4054
If the source is crates.io or `--git` then by default the crate will be built
4155
in a temporary target directory. To avoid this, the target directory can be
4256
specified by setting the `CARGO_TARGET_DIR` environment variable to a relative
@@ -63,7 +77,13 @@ available.
6377

6478
*--vers* _VERSION_::
6579
*--version* _VERSION_::
66-
Specify a version to install.
80+
Specify a version to install. This may be a
81+
linkcargo:reference/specifying-dependencies.md[version requirement], like
82+
`~1.2`, to have Cargo select the newest version from the given
83+
requirement. If the version does not have a requirement operator (such as
84+
`^` or `~`), then it must be in the form _MAJOR.MINOR.PATCH_, and will
85+
install exactly that version; it is *not* treated as a caret requirement
86+
like Cargo dependencies are.
6787

6888
*--git* _URL_::
6989
Git URL to install the specified crate from.
@@ -85,9 +105,18 @@ available.
85105

86106
*-f*::
87107
*--force*::
88-
Force overwriting existing crates or binaries. This can be used to
89-
reinstall or upgrade a crate.
90-
108+
Force overwriting existing crates or binaries. This can be used if a
109+
package has installed a binary with the same name as another package. This
110+
is also useful if something has changed on the system that you want to
111+
rebuild with, such as a newer version of `rustc`.
112+
113+
*--no-track*::
114+
By default, Cargo keeps track of the installed packages with a metadata
115+
file stored in the installation root directory. This flag tells Cargo not
116+
to use or create that file. With this flag, Cargo will refuse to overwrite
117+
any existing files unless the `--force` flag is used. This also disables
118+
Cargo's ability to protect against multiple concurrent invocations of
119+
Cargo installing at the same time.
91120

92121
*--bin* _NAME_...::
93122
Install only the specified binary.
@@ -137,13 +166,17 @@ include::section-exit-status.adoc[]
137166

138167
== EXAMPLES
139168

140-
. Install a package from crates.io:
169+
. Install or upgrade a package from crates.io:
141170

142171
cargo install ripgrep
143172

144-
. Reinstall or upgrade a package:
173+
. Install or reinstall the package in the current directory:
174+
175+
cargo install --path .
176+
177+
. View the list of installed packages:
145178

146-
cargo install ripgrep --force
179+
cargo install --list
147180

148181
== SEE ALSO
149182
man:cargo[1], man:cargo-uninstall[1], man:cargo-search[1], man:cargo-publish[1]

0 commit comments

Comments
 (0)