mirror of
https://github.com/rust-lang/cargo.git
synced 2025-09-28 11:20:36 +00:00
Auto merge of #13626 - linyihai:pre-update, r=weihanglo
Allow precise update to prerelease. ### What does this PR try to resolve? This is a feature that attempts to support updates to pre-release versions via `cargo update --precise`. when `precise-pre-release` used, the prerelase version will be taking consider as compatible version. That said, we can update to any compatible pre-release version. The logic of checking the compatibility of pre-release versions is currently tentative and does not take many conditions into account, this part of the logic makes more sense when implemented in semver. Use `-Zunstable-options` instead of `-Zprecise-pre-release`. ### How should we test and review this PR? ### Additional information Part of https://github.com/rust-lang/cargo/issues/13290
This commit is contained in:
commit
6774b8503c
@ -402,6 +402,14 @@ impl Dependency {
|
||||
self.matches_id(sum.package_id())
|
||||
}
|
||||
|
||||
pub fn matches_prerelease(&self, sum: &Summary) -> bool {
|
||||
let id = sum.package_id();
|
||||
self.inner.name == id.name()
|
||||
&& (self.inner.only_match_name
|
||||
|| (self.inner.req.matches_prerelease(id.version())
|
||||
&& self.inner.source_id == id.source_id()))
|
||||
}
|
||||
|
||||
/// Returns `true` if the package (`id`) can fulfill this dependency request.
|
||||
pub fn matches_ignoring_source(&self, id: PackageId) -> bool {
|
||||
self.package_name() == id.name() && self.version_req().matches(id.version())
|
||||
|
@ -768,7 +768,6 @@ unstable_cli_options!(
|
||||
next_lockfile_bump: bool,
|
||||
no_index_update: bool = ("Do not update the registry index even if the cache is outdated"),
|
||||
panic_abort_tests: bool = ("Enable support to run tests with -Cpanic=abort"),
|
||||
precise_pre_release: bool = ("Enable pre-release versions to be selected with `update --precise`"),
|
||||
profile_rustflags: bool = ("Enable the `rustflags` option in profiles in .cargo/config.toml file"),
|
||||
public_dependency: bool = ("Respect a dependency's `public` field in Cargo.toml to control public/private dependencies"),
|
||||
publish_timeout: bool = ("Enable the `publish.timeout` key in .cargo/config.toml file"),
|
||||
@ -1158,7 +1157,6 @@ impl CliUnstable {
|
||||
"panic-abort-tests" => self.panic_abort_tests = parse_empty(k, v)?,
|
||||
"public-dependency" => self.public_dependency = parse_empty(k, v)?,
|
||||
"profile-rustflags" => self.profile_rustflags = parse_empty(k, v)?,
|
||||
"precise-pre-release" => self.precise_pre_release = parse_empty(k, v)?,
|
||||
"trim-paths" => self.trim_paths = parse_empty(k, v)?,
|
||||
"publish-timeout" => self.publish_timeout = parse_empty(k, v)?,
|
||||
"rustdoc-map" => self.rustdoc_map = parse_empty(k, v)?,
|
||||
|
@ -208,9 +208,9 @@ use crate::sources::source::QueryKind;
|
||||
use crate::sources::source::Source;
|
||||
use crate::sources::PathSource;
|
||||
use crate::util::cache_lock::CacheLockMode;
|
||||
use crate::util::hex;
|
||||
use crate::util::interning::InternedString;
|
||||
use crate::util::network::PollExt;
|
||||
use crate::util::{hex, VersionExt};
|
||||
use crate::util::{restricted_names, CargoResult, Filesystem, GlobalContext, LimitErrorReader};
|
||||
|
||||
/// The `.cargo-ok` file is used to track if the source is already unpacked.
|
||||
@ -752,7 +752,13 @@ impl<'gctx> Source for RegistrySource<'gctx> {
|
||||
if let Some((_, requested)) = self
|
||||
.source_id
|
||||
.precise_registry_version(dep.package_name().as_str())
|
||||
.filter(|(c, _)| req.matches(c))
|
||||
.filter(|(c, to)| {
|
||||
if to.is_prerelease() && self.gctx.cli_unstable().unstable_options {
|
||||
req.matches_prerelease(c)
|
||||
} else {
|
||||
req.matches(c)
|
||||
}
|
||||
})
|
||||
{
|
||||
req.precise_to(&requested);
|
||||
}
|
||||
@ -790,7 +796,13 @@ impl<'gctx> Source for RegistrySource<'gctx> {
|
||||
.index
|
||||
.query_inner(dep.package_name(), &req, &mut *self.ops, &mut |s| {
|
||||
let matched = match kind {
|
||||
QueryKind::Exact => dep.matches(s.as_summary()),
|
||||
QueryKind::Exact => {
|
||||
if req.is_precise() && self.gctx.cli_unstable().unstable_options {
|
||||
dep.matches_prerelease(s.as_summary())
|
||||
} else {
|
||||
dep.matches(s.as_summary())
|
||||
}
|
||||
}
|
||||
QueryKind::Alternatives => true,
|
||||
QueryKind::Normalized => true,
|
||||
};
|
||||
|
@ -111,6 +111,19 @@ impl OptVersionReq {
|
||||
}
|
||||
}
|
||||
|
||||
/// Since Semver does not support prerelease versions,
|
||||
/// the simplest implementation is taken here without comparing the prerelease section.
|
||||
/// The logic here is temporary, we'll have to consider more boundary conditions later,
|
||||
/// and we're not sure if this part of the functionality should be implemented in semver or cargo.
|
||||
pub fn matches_prerelease(&self, version: &Version) -> bool {
|
||||
if version.is_prerelease() {
|
||||
let mut version = version.clone();
|
||||
version.pre = semver::Prerelease::EMPTY;
|
||||
return self.matches(&version);
|
||||
}
|
||||
self.matches(version)
|
||||
}
|
||||
|
||||
pub fn matches(&self, version: &Version) -> bool {
|
||||
match self {
|
||||
OptVersionReq::Any => true,
|
||||
|
@ -46,6 +46,8 @@ revision (such as a SHA hash or tag).
|
||||
While not recommended, you can specify a yanked version of a package (nightly only).
|
||||
When possible, try other non-yanked SemVer-compatible versions or seek help
|
||||
from the maintainers of the package.
|
||||
|
||||
A compatible `pre-release` version can also be specified even when the version requirement in `Cargo.toml` doesn't contain any pre-release identifer (nightly only).
|
||||
{{/option}}
|
||||
|
||||
{{#option "`-w`" "`--workspace`" }}
|
||||
|
@ -40,6 +40,10 @@ OPTIONS
|
||||
SemVer-compatible versions or seek help from the maintainers of the
|
||||
package.
|
||||
|
||||
A compatible pre-release version can also be specified even when the
|
||||
version requirement in Cargo.toml doesn’t contain any pre-release
|
||||
identifer (nightly only).
|
||||
|
||||
-w, --workspace
|
||||
Attempt to update only packages defined in the workspace. Other
|
||||
packages are updated only if they don’t already exist in the
|
||||
|
@ -42,7 +42,8 @@ the package to. If the package comes from a git repository, this can be a git
|
||||
revision (such as a SHA hash or tag).</p>
|
||||
<p>While not recommended, you can specify a yanked version of a package (nightly only).
|
||||
When possible, try other non-yanked SemVer-compatible versions or seek help
|
||||
from the maintainers of the package.</dd>
|
||||
from the maintainers of the package.</p>
|
||||
<p>A compatible <code>pre-release</code> version can also be specified even when the version requirement in <code>Cargo.toml</code> doesn’t contain any pre-release identifer (nightly only).</dd>
|
||||
|
||||
|
||||
<dt class="option-term" id="option-cargo-update--w"><a class="option-anchor" href="#option-cargo-update--w"></a><code>-w</code></dt>
|
||||
|
@ -347,7 +347,7 @@ Take for example this `Cargo.toml`.
|
||||
my-dependency = "0.1.1"
|
||||
```
|
||||
|
||||
It's possible to update `my-dependancy` to a pre-release with `update -Zprecise-pre-release -p my-dependency --precise 0.1.2-pre.0`.
|
||||
It's possible to update `my-dependancy` to a pre-release with `update -Zunstable-options my-dependency --precise 0.1.2-pre.0`.
|
||||
This is because `0.1.2-pre.0` is considered compatible with `0.1.1`.
|
||||
It would not be possible to upgrade to `0.2.0-pre.0` from `0.1.1` in the same way.
|
||||
|
||||
|
@ -43,6 +43,8 @@ revision (such as a SHA hash or tag).
|
||||
While not recommended, you can specify a yanked version of a package (nightly only).
|
||||
When possible, try other non\-yanked SemVer\-compatible versions or seek help
|
||||
from the maintainers of the package.
|
||||
.sp
|
||||
A compatible \fBpre\-release\fR version can also be specified even when the version requirement in \fBCargo.toml\fR doesn\[cq]t contain any pre\-release identifer (nightly only).
|
||||
.RE
|
||||
.sp
|
||||
\fB\-w\fR,
|
||||
|
@ -1,4 +1,4 @@
|
||||
<svg width="1230px" height="740px" xmlns="http://www.w3.org/2000/svg">
|
||||
<svg width="1230px" height="722px" xmlns="http://www.w3.org/2000/svg">
|
||||
<style>
|
||||
.fg { fill: #AAAAAA }
|
||||
.bg { background: #000000 }
|
||||
@ -69,35 +69,33 @@
|
||||
</tspan>
|
||||
<tspan x="10px" y="460px"><tspan> </tspan><tspan class="fg-cyan bold">-Z panic-abort-tests </tspan><tspan> Enable support to run tests with -Cpanic=abort</tspan>
|
||||
</tspan>
|
||||
<tspan x="10px" y="478px"><tspan> </tspan><tspan class="fg-cyan bold">-Z precise-pre-release </tspan><tspan> Enable pre-release versions to be selected with `update --precise`</tspan>
|
||||
<tspan x="10px" y="478px"><tspan> </tspan><tspan class="fg-cyan bold">-Z profile-rustflags </tspan><tspan> Enable the `rustflags` option in profiles in .cargo/config.toml file</tspan>
|
||||
</tspan>
|
||||
<tspan x="10px" y="496px"><tspan> </tspan><tspan class="fg-cyan bold">-Z profile-rustflags </tspan><tspan> Enable the `rustflags` option in profiles in .cargo/config.toml file</tspan>
|
||||
<tspan x="10px" y="496px"><tspan> </tspan><tspan class="fg-cyan bold">-Z public-dependency </tspan><tspan> Respect a dependency's `public` field in Cargo.toml to control public/private dependencies</tspan>
|
||||
</tspan>
|
||||
<tspan x="10px" y="514px"><tspan> </tspan><tspan class="fg-cyan bold">-Z public-dependency </tspan><tspan> Respect a dependency's `public` field in Cargo.toml to control public/private dependencies</tspan>
|
||||
<tspan x="10px" y="514px"><tspan> </tspan><tspan class="fg-cyan bold">-Z publish-timeout </tspan><tspan> Enable the `publish.timeout` key in .cargo/config.toml file</tspan>
|
||||
</tspan>
|
||||
<tspan x="10px" y="532px"><tspan> </tspan><tspan class="fg-cyan bold">-Z publish-timeout </tspan><tspan> Enable the `publish.timeout` key in .cargo/config.toml file</tspan>
|
||||
<tspan x="10px" y="532px"><tspan> </tspan><tspan class="fg-cyan bold">-Z rustdoc-map </tspan><tspan> Allow passing external documentation mappings to rustdoc</tspan>
|
||||
</tspan>
|
||||
<tspan x="10px" y="550px"><tspan> </tspan><tspan class="fg-cyan bold">-Z rustdoc-map </tspan><tspan> Allow passing external documentation mappings to rustdoc</tspan>
|
||||
<tspan x="10px" y="550px"><tspan> </tspan><tspan class="fg-cyan bold">-Z rustdoc-scrape-examples</tspan><tspan> Allows Rustdoc to scrape code examples from reverse-dependencies</tspan>
|
||||
</tspan>
|
||||
<tspan x="10px" y="568px"><tspan> </tspan><tspan class="fg-cyan bold">-Z rustdoc-scrape-examples</tspan><tspan> Allows Rustdoc to scrape code examples from reverse-dependencies</tspan>
|
||||
<tspan x="10px" y="568px"><tspan> </tspan><tspan class="fg-cyan bold">-Z script </tspan><tspan> Enable support for single-file, `.rs` packages</tspan>
|
||||
</tspan>
|
||||
<tspan x="10px" y="586px"><tspan> </tspan><tspan class="fg-cyan bold">-Z script </tspan><tspan> Enable support for single-file, `.rs` packages</tspan>
|
||||
<tspan x="10px" y="586px"><tspan> </tspan><tspan class="fg-cyan bold">-Z target-applies-to-host </tspan><tspan> Enable the `target-applies-to-host` key in the .cargo/config.toml file</tspan>
|
||||
</tspan>
|
||||
<tspan x="10px" y="604px"><tspan> </tspan><tspan class="fg-cyan bold">-Z target-applies-to-host </tspan><tspan> Enable the `target-applies-to-host` key in the .cargo/config.toml file</tspan>
|
||||
<tspan x="10px" y="604px"><tspan> </tspan><tspan class="fg-cyan bold">-Z trim-paths </tspan><tspan> Enable the `trim-paths` option in profiles</tspan>
|
||||
</tspan>
|
||||
<tspan x="10px" y="622px"><tspan> </tspan><tspan class="fg-cyan bold">-Z trim-paths </tspan><tspan> Enable the `trim-paths` option in profiles</tspan>
|
||||
<tspan x="10px" y="622px"><tspan> </tspan><tspan class="fg-cyan bold">-Z unstable-options </tspan><tspan> Allow the usage of unstable options</tspan>
|
||||
</tspan>
|
||||
<tspan x="10px" y="640px"><tspan> </tspan><tspan class="fg-cyan bold">-Z unstable-options </tspan><tspan> Allow the usage of unstable options</tspan>
|
||||
<tspan x="10px" y="640px">
|
||||
</tspan>
|
||||
<tspan x="10px" y="658px">
|
||||
<tspan x="10px" y="658px"><tspan>Run with `</tspan><tspan class="fg-cyan bold">cargo -Z</tspan><tspan> </tspan><tspan class="fg-cyan">[FLAG] [COMMAND]</tspan><tspan>`</tspan>
|
||||
</tspan>
|
||||
<tspan x="10px" y="676px"><tspan>Run with `</tspan><tspan class="fg-cyan bold">cargo -Z</tspan><tspan> </tspan><tspan class="fg-cyan">[FLAG] [COMMAND]</tspan><tspan>`</tspan>
|
||||
<tspan x="10px" y="676px">
|
||||
</tspan>
|
||||
<tspan x="10px" y="694px">
|
||||
<tspan x="10px" y="694px"><tspan>See https://doc.rust-lang.org/nightly/cargo/reference/unstable.html for more information about these flags.</tspan>
|
||||
</tspan>
|
||||
<tspan x="10px" y="712px"><tspan>See https://doc.rust-lang.org/nightly/cargo/reference/unstable.html for more information about these flags.</tspan>
|
||||
</tspan>
|
||||
<tspan x="10px" y="730px">
|
||||
<tspan x="10px" y="712px">
|
||||
</tspan>
|
||||
</text>
|
||||
|
||||
|
Before Width: | Height: | Size: 7.5 KiB After Width: | Height: | Size: 7.3 KiB |
@ -23,7 +23,7 @@ fn requires_nightly_cargo() {
|
||||
.file("src/lib.rs", "")
|
||||
.build();
|
||||
|
||||
p.cargo("update -p my-dependency --precise 0.1.2-pre.0")
|
||||
p.cargo("update my-dependency --precise 0.1.2-pre.0")
|
||||
.with_status(101)
|
||||
// This error is suffering from #12579 but still demonstrates that updating to
|
||||
// a pre-release does not work on stable
|
||||
@ -41,20 +41,77 @@ perhaps a crate was updated and forgotten to be re-vendored?"#,
|
||||
}
|
||||
|
||||
#[cargo_test]
|
||||
fn feature_exists() {
|
||||
fn update_pre_release() {
|
||||
cargo_test_support::registry::init();
|
||||
|
||||
for version in ["0.1.1", "0.1.2-pre.0"] {
|
||||
cargo_test_support::registry::Package::new("my-dependency", version).publish();
|
||||
}
|
||||
|
||||
let p = project()
|
||||
.file(
|
||||
"Cargo.toml",
|
||||
r#"
|
||||
[package]
|
||||
name = "package"
|
||||
[dependencies]
|
||||
my-dependency = "0.1.1"
|
||||
"#,
|
||||
)
|
||||
.file("src/lib.rs", "")
|
||||
.build();
|
||||
|
||||
p.cargo("-Zprecise-pre-release update")
|
||||
p.cargo("update my-dependency --precise 0.1.2-pre.0 -Zunstable-options")
|
||||
.masquerade_as_nightly_cargo(&["precise-pre-release"])
|
||||
.with_stderr("")
|
||||
.run()
|
||||
.with_stderr(
|
||||
r#"[UPDATING] `dummy-registry` index
|
||||
[UPDATING] my-dependency v0.1.1 -> v0.1.2-pre.0
|
||||
"#,
|
||||
)
|
||||
.run();
|
||||
let lockfile = p.read_lockfile();
|
||||
assert!(lockfile.contains("\nname = \"my-dependency\"\nversion = \"0.1.2-pre.0\""));
|
||||
}
|
||||
|
||||
#[cargo_test]
|
||||
fn update_pre_release_differ() {
|
||||
cargo_test_support::registry::init();
|
||||
|
||||
for version in ["0.1.2", "0.1.2-pre.0", "0.1.2-pre.1"] {
|
||||
cargo_test_support::registry::Package::new("my-dependency", version).publish();
|
||||
}
|
||||
|
||||
let p = project()
|
||||
.file(
|
||||
"Cargo.toml",
|
||||
r#"
|
||||
[package]
|
||||
name = "package"
|
||||
[dependencies]
|
||||
my-dependency = "0.1.2"
|
||||
"#,
|
||||
)
|
||||
.file("src/lib.rs", "")
|
||||
.build();
|
||||
|
||||
p.cargo("update -p my-dependency --precise 0.1.2-pre.0 -Zunstable-options")
|
||||
.masquerade_as_nightly_cargo(&["precise-pre-release"])
|
||||
.with_stderr(
|
||||
r#"[UPDATING] `dummy-registry` index
|
||||
[DOWNGRADING] my-dependency v0.1.2 -> v0.1.2-pre.0
|
||||
"#,
|
||||
)
|
||||
.run();
|
||||
|
||||
p.cargo("update -p my-dependency --precise 0.1.2-pre.1 -Zunstable-options")
|
||||
.masquerade_as_nightly_cargo(&["precise-pre-release"])
|
||||
.with_stderr(
|
||||
r#"[UPDATING] `dummy-registry` index
|
||||
[UPDATING] my-dependency v0.1.2-pre.0 -> v0.1.2-pre.1
|
||||
"#,
|
||||
)
|
||||
.run();
|
||||
|
||||
let lockfile = p.read_lockfile();
|
||||
assert!(lockfile.contains("\nname = \"my-dependency\"\nversion = \"0.1.2-pre.1\""));
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user