Skip to content

Commit

Permalink
feat(cargo-update): --precise to allow yanked versions
Browse files Browse the repository at this point in the history
  • Loading branch information
weihanglo committed Jan 21, 2024
1 parent 4f1e41e commit 35345f2
Show file tree
Hide file tree
Showing 3 changed files with 67 additions and 7 deletions.
30 changes: 27 additions & 3 deletions src/cargo/sources/registry/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -779,22 +779,46 @@ 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 {
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 mut shell = self.config.shell();
shell.warn(format_args!(
"a yanked package `{name}@{version}` is requested by the `--precise` flag",
))?;
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] a yanked package `bar@0.1.1` is requested by the `--precise` flag
[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
",
)
.run()
.run();

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

0 comments on commit 35345f2

Please sign in to comment.