Skip to content

Commit 3f2f4ed

Browse files
committed
feat(cargo-update): --precise to allow yanked versions
1 parent 4f1e41e commit 3f2f4ed

File tree

3 files changed

+68
-7
lines changed

3 files changed

+68
-7
lines changed

src/cargo/sources/registry/mod.rs

Lines changed: 28 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -779,22 +779,47 @@ impl<'cfg> Source for RegistrySource<'cfg> {
779779
Poll::Pending
780780
}
781781
} else {
782+
let mut precise_yanked_in_use = false;
782783
ready!(self
783784
.index
784785
.query_inner(dep.package_name(), &req, &mut *self.ops, &mut |s| {
785786
let matched = match kind {
786787
QueryKind::Exact => dep.matches(s.as_summary()),
787788
QueryKind::Fuzzy => true,
788789
};
790+
if !matched {
791+
return;
792+
}
789793
// Next filter out all yanked packages. Some yanked packages may
790794
// leak through if they're in a whitelist (aka if they were
791795
// previously in `Cargo.lock`
792-
if matched
793-
&& (!s.is_yanked() || self.yanked_whitelist.contains(&s.package_id()))
794-
{
796+
if !s.is_yanked() {
797+
callback(s);
798+
} else if self.yanked_whitelist.contains(&s.package_id()) {
795799
callback(s);
800+
} else if req.is_precise() {
801+
precise_yanked_in_use = true;
802+
if self.config.cli_unstable().unstable_options {
803+
callback(s);
804+
}
796805
}
797806
}))?;
807+
if precise_yanked_in_use {
808+
self.config
809+
.cli_unstable()
810+
.fail_if_stable_opt("--precise <yanked-version>", 4225)?;
811+
let name = dep.package_name();
812+
let version = req
813+
.precise_version()
814+
.expect("--precise <yanked-version> in use");
815+
let source = self.source_id();
816+
let mut shell = self.config.shell();
817+
shell.warn(format_args!(
818+
"yanked package `{name}@{version}` is selected by the `--precise` flag from {source}",
819+
))?;
820+
shell.note("it is not recommended to depend on a yanked version")?;
821+
shell.note("if possible, try other SemVer-compatbile versions")?;
822+
}
798823
if called {
799824
return Poll::Ready(Ok(()));
800825
}

src/cargo/util/semver_ext.rs

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -87,6 +87,18 @@ impl OptVersionReq {
8787
};
8888
}
8989

90+
pub fn is_precise(&self) -> bool {
91+
matches!(self, OptVersionReq::Precise(..))
92+
}
93+
94+
/// Gets the version to which this req is precise to, if any.
95+
pub fn precise_version(&self) -> Option<&Version> {
96+
match self {
97+
OptVersionReq::Precise(version, _) => Some(version),
98+
_ => None,
99+
}
100+
}
101+
90102
pub fn is_locked(&self) -> bool {
91103
matches!(self, OptVersionReq::Locked(..))
92104
}

tests/testsuite/update.rs

Lines changed: 28 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1400,10 +1400,34 @@ fn precise_yanked() {
14001400
.with_stderr(
14011401
"\
14021402
[UPDATING] `dummy-registry` index
1403-
[ERROR] no matching package named `bar` found
1404-
location searched: registry `crates-io`
1405-
required by package `foo v0.0.0 ([CWD])`
1403+
[ERROR] failed to get `bar` as a dependency of package `foo v0.0.0 ([CWD])`
1404+
1405+
Caused by:
1406+
failed to query replaced source registry `crates-io`
1407+
1408+
Caused by:
1409+
the `--precise <yanked-version>` flag is unstable[..]
1410+
See [..]
1411+
See [..]
1412+
",
1413+
)
1414+
.run();
1415+
1416+
p.cargo("update --precise 0.1.1 bar")
1417+
.masquerade_as_nightly_cargo(&["--precise <yanked-version>"])
1418+
.arg("-Zunstable-options")
1419+
.with_stderr(
1420+
"\
1421+
[UPDATING] `dummy-registry` index
1422+
[WARNING] yanked package `bar@0.1.1` is selected by the `--precise` flag from registry `dummy-registry`
1423+
[NOTE] it is not recommended to depend on a yanked version
1424+
[NOTE] if possible, try other SemVer-compatbile versions
1425+
[UPDATING] bar v0.1.0 -> v0.1.1
14061426
",
14071427
)
1408-
.run()
1428+
.run();
1429+
1430+
// Use yanked version.
1431+
let lockfile = p.read_lockfile();
1432+
assert!(lockfile.contains("\nname = \"bar\"\nversion = \"0.1.1\""));
14091433
}

0 commit comments

Comments
 (0)