Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(cargo-update): --precise to allow yanked versions #13333

Merged
merged 7 commits into from
Jan 29, 2024
31 changes: 28 additions & 3 deletions src/cargo/sources/registry/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -779,22 +779,47 @@ impl<'cfg> Source for RegistrySource<'cfg> {
Poll::Pending
}
} else {
let mut precise_yanked_in_use = false;
ready!(self
.index
.query_inner(dep.package_name(), &req, &mut *self.ops, &mut |s| {
let matched = match kind {
QueryKind::Exact => dep.matches(s.as_summary()),
QueryKind::Fuzzy => true,
};
if !matched {
return;
}
// Next filter out all yanked packages. Some yanked packages may
// leak through if they're in a whitelist (aka if they were
// previously in `Cargo.lock`
if matched
&& (!s.is_yanked() || self.yanked_whitelist.contains(&s.package_id()))
{
if !s.is_yanked() {
callback(s);
} else if self.yanked_whitelist.contains(&s.package_id()) {
callback(s);
} else if req.is_precise() {
precise_yanked_in_use = true;
if self.config.cli_unstable().unstable_options {
callback(s);
}
}
}))?;
if precise_yanked_in_use {
weihanglo marked this conversation as resolved.
Show resolved Hide resolved
self.config
.cli_unstable()
.fail_if_stable_opt("--precise <yanked-version>", 4225)?;
let name = dep.package_name();
let version = req
.precise_version()
.expect("--precise <yanked-version> in use");
let source = self.source_id();
let mut shell = self.config.shell();
shell.warn(format_args!(
"yanked package `{name}@{version}` is selected by the `--precise` flag from {source}",
))?;
shell.note("it is not recommended to depend on a yanked version")?;
shell.note("if possible, try other SemVer-compatbile versions")?;
}
if called {
return Poll::Ready(Ok(()));
}
Expand Down
12 changes: 12 additions & 0 deletions src/cargo/util/semver_ext.rs
Original file line number Diff line number Diff line change
Expand Up @@ -87,6 +87,18 @@ impl OptVersionReq {
};
}

pub fn is_precise(&self) -> bool {
matches!(self, OptVersionReq::Precise(..))
}

/// Gets the version to which this req is precise to, if any.
pub fn precise_version(&self) -> Option<&Version> {
match self {
OptVersionReq::Precise(version, _) => Some(version),
_ => None,
}
}

pub fn is_locked(&self) -> bool {
matches!(self, OptVersionReq::Locked(..))
}
Expand Down
32 changes: 28 additions & 4 deletions tests/testsuite/update.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1400,10 +1400,34 @@ fn precise_yanked() {
.with_stderr(
"\
[UPDATING] `dummy-registry` index
[ERROR] no matching package named `bar` found
location searched: registry `crates-io`
required by package `foo v0.0.0 ([CWD])`
[ERROR] failed to get `bar` as a dependency of package `foo v0.0.0 ([CWD])`

Caused by:
failed to query replaced source registry `crates-io`

Caused by:
the `--precise <yanked-version>` flag is unstable[..]
See [..]
See [..]
",
)
.run();

p.cargo("update --precise 0.1.1 bar")
.masquerade_as_nightly_cargo(&["--precise <yanked-version>"])
.arg("-Zunstable-options")
.with_stderr(
"\
[UPDATING] `dummy-registry` index
[WARNING] yanked package `bar@0.1.1` is selected by the `--precise` flag from registry `dummy-registry`
[NOTE] it is not recommended to depend on a yanked version
[NOTE] if possible, try other SemVer-compatbile versions
[UPDATING] bar v0.1.0 -> v0.1.1
weihanglo marked this conversation as resolved.
Show resolved Hide resolved
",
)
.run()
.run();

// Use yanked version.
let lockfile = p.read_lockfile();
assert!(lockfile.contains("\nname = \"bar\"\nversion = \"0.1.1\""));
}