Compare commits
63 Commits
0ccb9e582d
...
024ac489a9
Author | SHA1 | Date |
---|---|---|
Ed Page | 024ac489a9 | |
bors | eee4ea2f5a | |
bors | c4e19cc890 | |
Eric Huss | 06fb65e753 | |
Scott Schafer | cf197fc499 | |
Scott Schafer | c3b104e11e | |
bors | b60a155515 | |
Ed Page | 8ab7683f93 | |
Ed Page | 57b4ab90a6 | |
bors | 1dadee6d8b | |
Weihang Lo | ba5ec686f9 | |
Weihang Lo | f70bfd3f4a | |
bors | e91b58d252 | |
Ed Page | 5f5e0fc504 | |
Ed Page | 50adf47c18 | |
Ed Page | 2289026d70 | |
Ed Page | 58415ff288 | |
Ed Page | 0b15bef075 | |
Ed Page | 6a213f792e | |
Ed Page | a71b8fecf3 | |
bors | cb1123f4f2 | |
Ed Page | bcf032e5be | |
Weihang Lo | d855cd634a | |
Weihang Lo | 7ed7612a79 | |
Weihang Lo | 4b0fac9c05 | |
Weihang Lo | cc7fcaf57c | |
Weihang Lo | 3505b05792 | |
Weihang Lo | a5d2a1d3dc | |
bors | 93edfb9206 | |
Ed Page | aecb40baac | |
Scott Schafer | dfc9bd2068 | |
Scott Schafer | d5bc35d844 | |
Scott Schafer | 2655b069c6 | |
Scott Schafer | b83c0a4939 | |
bors | 955503e1de | |
bors | e3d42b6019 | |
Ed Page | 751fd47d34 | |
Ed Page | 4cc82833bd | |
Ed Page | b81f94a8e9 | |
bors | 52dae0c1f6 | |
bors | 70fb498994 | |
Ian Jackson | 2f16838385 | |
Ian Jackson | 23440c0dcd | |
Ian Jackson | 91f3e457ab | |
Ian Jackson | dcce00745d | |
Ian Jackson | 13be0cfa8b | |
bors | c939267591 | |
Ed Page | dcbf2b5d32 | |
Ed Page | cd8d5f7c10 | |
bors | 125aa57ad2 | |
bors | b89b81a6c7 | |
bors | 11d5b73b29 | |
Josh Stone | 6dda4e006b | |
Ed Page | 034ef3c27b | |
Ed Page | 9ee41598e8 | |
Ed Page | 706f8a71c8 | |
Scott Schafer | 11d6013c1d | |
Scott Schafer | 2d40a475d9 | |
Scott Schafer | 00a64e4da3 | |
Scott Schafer | b89864cc3b | |
klensy | 57e820e329 | |
klensy | ef39fbf231 | |
klensy | 3215929365 |
|
@ -350,7 +350,7 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "cargo-credential"
|
||||
version = "0.4.4"
|
||||
version = "0.4.5"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"libc",
|
||||
|
@ -2481,7 +2481,6 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
|||
checksum = "ae99c7fa6dd38c7cafe1ec085e804f8f555a2f8659b0dbe03f1f9963a9b51092"
|
||||
dependencies = [
|
||||
"log",
|
||||
"serde",
|
||||
"windows-sys 0.52.0",
|
||||
]
|
||||
|
||||
|
|
|
@ -68,7 +68,7 @@ miow = "0.6.0"
|
|||
opener = "0.7.0"
|
||||
openssl = "0.10.57"
|
||||
openssl-sys = "=0.9.92" # See rust-lang/cargo#13546 and openssl/openssl#23376 for pinning
|
||||
os_info = "3.8.2"
|
||||
os_info = { version = "3.8.2", default-features = false }
|
||||
pasetors = { version = "0.6.8", features = ["v3", "paserk", "std", "serde"] }
|
||||
pathdiff = "0.2"
|
||||
percent-encoding = "2.3"
|
||||
|
@ -173,7 +173,6 @@ indexmap.workspace = true
|
|||
itertools.workspace = true
|
||||
jobserver.workspace = true
|
||||
lazycell.workspace = true
|
||||
libc.workspace = true
|
||||
libgit2-sys.workspace = true
|
||||
memchr.workspace = true
|
||||
opener.workspace = true
|
||||
|
@ -184,6 +183,7 @@ rand.workspace = true
|
|||
regex.workspace = true
|
||||
rusqlite.workspace = true
|
||||
rustfix.workspace = true
|
||||
same-file.workspace = true
|
||||
semver.workspace = true
|
||||
serde = { workspace = true, features = ["derive"] }
|
||||
serde-untagged.workspace = true
|
||||
|
@ -208,6 +208,9 @@ supports-unicode = "3.0.0"
|
|||
[target.'cfg(target_has_atomic = "64")'.dependencies]
|
||||
tracing-chrome.workspace = true
|
||||
|
||||
[target.'cfg(unix)'.dependencies]
|
||||
libc.workspace = true
|
||||
|
||||
[target.'cfg(target_os = "linux")'.dependencies]
|
||||
cargo-credential-libsecret.workspace = true
|
||||
|
||||
|
|
|
@ -51,7 +51,7 @@ pub struct TomlManifest {
|
|||
pub replace: Option<BTreeMap<String, TomlDependency>>,
|
||||
pub patch: Option<BTreeMap<String, BTreeMap<PackageName, TomlDependency>>>,
|
||||
pub workspace: Option<TomlWorkspace>,
|
||||
pub badges: Option<InheritableBtreeMap>,
|
||||
pub badges: Option<BTreeMap<String, BTreeMap<String, String>>>,
|
||||
pub lints: Option<InheritableLints>,
|
||||
|
||||
/// Report unused keys (see also nested `_unused_keys`)
|
||||
|
@ -106,12 +106,6 @@ impl TomlManifest {
|
|||
self.features.as_ref()
|
||||
}
|
||||
|
||||
pub fn resolved_badges(
|
||||
&self,
|
||||
) -> Result<Option<&BTreeMap<String, BTreeMap<String, String>>>, UnresolvedError> {
|
||||
self.badges.as_ref().map(|l| l.resolved()).transpose()
|
||||
}
|
||||
|
||||
pub fn resolved_lints(&self) -> Result<Option<&TomlLints>, UnresolvedError> {
|
||||
self.lints.as_ref().map(|l| l.resolved()).transpose()
|
||||
}
|
||||
|
@ -1506,7 +1500,7 @@ pub struct TomlLintConfig {
|
|||
pub priority: i8,
|
||||
}
|
||||
|
||||
#[derive(Serialize, Deserialize, Debug, Copy, Clone)]
|
||||
#[derive(Serialize, Deserialize, Debug, Copy, Clone, Eq, PartialEq)]
|
||||
#[serde(rename_all = "kebab-case")]
|
||||
pub enum TomlLintLevel {
|
||||
Forbid,
|
||||
|
|
|
@ -14,7 +14,6 @@ filetime.workspace = true
|
|||
hex.workspace = true
|
||||
ignore.workspace = true
|
||||
jobserver.workspace = true
|
||||
libc.workspace = true
|
||||
same-file.workspace = true
|
||||
sha2.workspace = true
|
||||
shell-escape.workspace = true
|
||||
|
@ -25,6 +24,9 @@ walkdir.workspace = true
|
|||
[target.'cfg(target_os = "macos")'.dependencies]
|
||||
core-foundation.workspace = true
|
||||
|
||||
[target.'cfg(unix)'.dependencies]
|
||||
libc.workspace = true
|
||||
|
||||
[target.'cfg(windows)'.dependencies]
|
||||
miow.workspace = true
|
||||
windows-sys = { workspace = true, features = ["Win32_Storage_FileSystem", "Win32_Foundation", "Win32_System_Console"] }
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
[package]
|
||||
name = "cargo-credential"
|
||||
version = "0.4.4"
|
||||
version = "0.4.5"
|
||||
rust-version.workspace = true
|
||||
edition.workspace = true
|
||||
license.workspace = true
|
||||
|
@ -10,12 +10,14 @@ description = "A library to assist writing Cargo credential helpers."
|
|||
|
||||
[dependencies]
|
||||
anyhow.workspace = true
|
||||
libc.workspace = true
|
||||
serde = { workspace = true, features = ["derive"] }
|
||||
serde_json.workspace = true
|
||||
thiserror.workspace = true
|
||||
time.workspace = true
|
||||
|
||||
[target.'cfg(unix)'.dependencies]
|
||||
libc.workspace = true
|
||||
|
||||
[target.'cfg(windows)'.dependencies]
|
||||
windows-sys = { workspace = true, features = ["Win32_System_Console", "Win32_Foundation"] }
|
||||
|
||||
|
|
|
@ -72,7 +72,7 @@ pub fn exec(gctx: &mut GlobalContext, args: &ArgMatches) -> CliResult {
|
|||
// code as we can.
|
||||
let root_manifest = args.root_manifest(gctx)?;
|
||||
let mut ws = Workspace::new(&root_manifest, gctx)?;
|
||||
ws.set_honor_rust_version(args.honor_rust_version());
|
||||
ws.set_resolve_honors_rust_version(args.honor_rust_version());
|
||||
let mut opts = args.compile_options(gctx, mode, Some(&ws), ProfileChecking::LegacyTestOnly)?;
|
||||
|
||||
if !opts.filter.is_specific() {
|
||||
|
|
|
@ -724,10 +724,9 @@ impl BuildOutput {
|
|||
pkg_descr: &str,
|
||||
msrv: &Option<RustVersion>,
|
||||
) -> CargoResult<()> {
|
||||
let new_syntax_added_in = &RustVersion::from_str("1.77.0")?;
|
||||
|
||||
if let Some(msrv) = msrv {
|
||||
if msrv < new_syntax_added_in {
|
||||
let new_syntax_added_in = RustVersion::from_str("1.77.0")?;
|
||||
if !new_syntax_added_in.is_compatible_with(msrv.as_partial()) {
|
||||
bail!(
|
||||
"the `cargo::` syntax for build script output instructions was added in \
|
||||
Rust 1.77.0, but the minimum supported Rust version of `{pkg_descr}` is {msrv}.\n\
|
||||
|
|
|
@ -300,7 +300,9 @@ impl Edition {
|
|||
}
|
||||
|
||||
pub(crate) fn default_resolve_behavior(&self) -> ResolveBehavior {
|
||||
if *self >= Edition::Edition2021 {
|
||||
if *self >= Edition::Edition2024 {
|
||||
ResolveBehavior::V3
|
||||
} else if *self >= Edition::Edition2021 {
|
||||
ResolveBehavior::V2
|
||||
} else {
|
||||
ResolveBehavior::V1
|
||||
|
|
|
@ -24,7 +24,7 @@ use crate::sources::{PathSource, CRATES_IO_INDEX, CRATES_IO_REGISTRY};
|
|||
use crate::util::edit_distance;
|
||||
use crate::util::errors::{CargoResult, ManifestError};
|
||||
use crate::util::interning::InternedString;
|
||||
use crate::util::lints::{check_implicit_features, unused_dependencies};
|
||||
use crate::util::lints::{check_im_a_teapot, check_implicit_features, unused_dependencies};
|
||||
use crate::util::toml::{read_manifest, InheritableFields};
|
||||
use crate::util::{
|
||||
context::CargoResolverConfig, context::CargoResolverPrecedence, context::ConfigRelativePath,
|
||||
|
@ -104,7 +104,6 @@ pub struct Workspace<'gctx> {
|
|||
/// The resolver behavior specified with the `resolver` field.
|
||||
resolve_behavior: ResolveBehavior,
|
||||
resolve_honors_rust_version: bool,
|
||||
honor_rust_version: Option<bool>,
|
||||
|
||||
/// Workspace-level custom metadata
|
||||
custom_metadata: Option<toml::Value>,
|
||||
|
@ -235,7 +234,6 @@ impl<'gctx> Workspace<'gctx> {
|
|||
ignore_lock: false,
|
||||
resolve_behavior: ResolveBehavior::V1,
|
||||
resolve_honors_rust_version: false,
|
||||
honor_rust_version: None,
|
||||
custom_metadata: None,
|
||||
}
|
||||
}
|
||||
|
@ -310,9 +308,6 @@ impl<'gctx> Workspace<'gctx> {
|
|||
ResolveBehavior::V1 | ResolveBehavior::V2 => {}
|
||||
ResolveBehavior::V3 => {
|
||||
if self.resolve_behavior == ResolveBehavior::V3 {
|
||||
if !self.gctx().cli_unstable().msrv_policy {
|
||||
anyhow::bail!("`resolver=\"3\"` requires `-Zmsrv-policy`");
|
||||
}
|
||||
self.resolve_honors_rust_version = true;
|
||||
}
|
||||
}
|
||||
|
@ -652,18 +647,14 @@ impl<'gctx> Workspace<'gctx> {
|
|||
self.members().filter_map(|pkg| pkg.rust_version()).min()
|
||||
}
|
||||
|
||||
pub fn set_honor_rust_version(&mut self, honor_rust_version: Option<bool>) {
|
||||
self.honor_rust_version = honor_rust_version;
|
||||
}
|
||||
|
||||
pub fn honor_rust_version(&self) -> Option<bool> {
|
||||
self.honor_rust_version
|
||||
pub fn set_resolve_honors_rust_version(&mut self, honor_rust_version: Option<bool>) {
|
||||
if let Some(honor_rust_version) = honor_rust_version {
|
||||
self.resolve_honors_rust_version = honor_rust_version;
|
||||
}
|
||||
}
|
||||
|
||||
pub fn resolve_honors_rust_version(&self) -> bool {
|
||||
// Give CLI precedence
|
||||
self.honor_rust_version
|
||||
.unwrap_or(self.resolve_honors_rust_version)
|
||||
self.resolve_honors_rust_version
|
||||
}
|
||||
|
||||
pub fn custom_metadata(&self) -> Option<&toml::Value> {
|
||||
|
@ -1156,10 +1147,27 @@ impl<'gctx> Workspace<'gctx> {
|
|||
}
|
||||
|
||||
pub fn emit_warnings(&self) -> CargoResult<()> {
|
||||
let ws_lints = self
|
||||
.root_maybe()
|
||||
.workspace_config()
|
||||
.inheritable()
|
||||
.and_then(|i| i.lints().ok())
|
||||
.unwrap_or_default();
|
||||
|
||||
let ws_cargo_lints = ws_lints
|
||||
.get("cargo")
|
||||
.cloned()
|
||||
.unwrap_or_default()
|
||||
.into_iter()
|
||||
.map(|(k, v)| (k.replace('-', "_"), v))
|
||||
.collect();
|
||||
|
||||
for (path, maybe_pkg) in &self.packages.packages {
|
||||
let path = path.join("Cargo.toml");
|
||||
if let MaybePackage::Package(pkg) = maybe_pkg {
|
||||
self.emit_lints(pkg, &path)?
|
||||
if self.gctx.cli_unstable().cargo_lints {
|
||||
self.emit_lints(pkg, &path, &ws_cargo_lints)?
|
||||
}
|
||||
}
|
||||
let warnings = match maybe_pkg {
|
||||
MaybePackage::Package(pkg) => pkg.manifest().warnings().warnings(),
|
||||
|
@ -1186,7 +1194,12 @@ impl<'gctx> Workspace<'gctx> {
|
|||
Ok(())
|
||||
}
|
||||
|
||||
pub fn emit_lints(&self, pkg: &Package, path: &Path) -> CargoResult<()> {
|
||||
pub fn emit_lints(
|
||||
&self,
|
||||
pkg: &Package,
|
||||
path: &Path,
|
||||
ws_cargo_lints: &manifest::TomlToolLints,
|
||||
) -> CargoResult<()> {
|
||||
let mut error_count = 0;
|
||||
let toml_lints = pkg
|
||||
.manifest()
|
||||
|
@ -1204,8 +1217,40 @@ impl<'gctx> Workspace<'gctx> {
|
|||
.map(|(name, lint)| (name.replace('-', "_"), lint))
|
||||
.collect();
|
||||
|
||||
check_implicit_features(pkg, &path, &normalized_lints, &mut error_count, self.gctx)?;
|
||||
unused_dependencies(pkg, &path, &normalized_lints, &mut error_count, self.gctx)?;
|
||||
// We should only be using workspace lints if the `[lints]` table is
|
||||
// present in the manifest, and `workspace` is set to `true`
|
||||
let ws_cargo_lints = pkg
|
||||
.manifest()
|
||||
.resolved_toml()
|
||||
.lints
|
||||
.as_ref()
|
||||
.is_some_and(|l| l.workspace)
|
||||
.then(|| ws_cargo_lints);
|
||||
|
||||
check_im_a_teapot(
|
||||
pkg,
|
||||
&path,
|
||||
&normalized_lints,
|
||||
ws_cargo_lints,
|
||||
&mut error_count,
|
||||
self.gctx,
|
||||
)?;
|
||||
check_implicit_features(
|
||||
pkg,
|
||||
&path,
|
||||
&normalized_lints,
|
||||
ws_cargo_lints,
|
||||
&mut error_count,
|
||||
self.gctx,
|
||||
)?;
|
||||
unused_dependencies(
|
||||
pkg,
|
||||
&path,
|
||||
&normalized_lints,
|
||||
ws_cargo_lints,
|
||||
&mut error_count,
|
||||
self.gctx,
|
||||
)?;
|
||||
if error_count > 0 {
|
||||
Err(crate::util::errors::AlreadyPrintedError::new(anyhow!(
|
||||
"encountered {error_count} errors(s) while running lints"
|
||||
|
|
|
@ -819,7 +819,9 @@ fn make_ws_rustc_target<'gctx>(
|
|||
let mut ws = if source_id.is_git() || source_id.is_path() {
|
||||
Workspace::new(pkg.manifest_path(), gctx)?
|
||||
} else {
|
||||
Workspace::ephemeral(pkg, gctx, None, false)?
|
||||
let mut ws = Workspace::ephemeral(pkg, gctx, None, false)?;
|
||||
ws.set_resolve_honors_rust_version(Some(false));
|
||||
ws
|
||||
};
|
||||
ws.set_ignore_lock(gctx.lock_update_allowed());
|
||||
ws.set_require_optional_deps(false);
|
||||
|
|
|
@ -108,7 +108,7 @@ pub fn fix(
|
|||
check_resolver_change(&original_ws, opts)?;
|
||||
}
|
||||
let mut ws = Workspace::new(&root_manifest, gctx)?;
|
||||
ws.set_honor_rust_version(original_ws.honor_rust_version());
|
||||
ws.set_resolve_honors_rust_version(Some(original_ws.resolve_honors_rust_version()));
|
||||
|
||||
// Spin up our lock server, which our subprocesses will use to synchronize fixes.
|
||||
let lock_server = LockServer::new()?;
|
||||
|
@ -254,9 +254,42 @@ fn migrate_manifests(ws: &Workspace<'_>, pkgs: &[&Package]) -> CargoResult<()> {
|
|||
let mut fixes = 0;
|
||||
|
||||
let root = document.as_table_mut();
|
||||
|
||||
if let Some(workspace) = root
|
||||
.get_mut("workspace")
|
||||
.and_then(|t| t.as_table_like_mut())
|
||||
{
|
||||
// strictly speaking, the edition doesn't apply to this table but it should be safe
|
||||
// enough
|
||||
fixes += rename_dep_fields_2024(workspace, "dependencies");
|
||||
}
|
||||
|
||||
fixes += add_feature_for_unused_deps(pkg, root);
|
||||
if rename_table(root, "project", "package") {
|
||||
fixes += 1;
|
||||
fixes += rename_table(root, "project", "package");
|
||||
if let Some(target) = root.get_mut("lib").and_then(|t| t.as_table_like_mut()) {
|
||||
fixes += rename_target_fields_2024(target);
|
||||
}
|
||||
fixes += rename_array_of_target_fields_2024(root, "bin");
|
||||
fixes += rename_array_of_target_fields_2024(root, "example");
|
||||
fixes += rename_array_of_target_fields_2024(root, "test");
|
||||
fixes += rename_array_of_target_fields_2024(root, "bench");
|
||||
fixes += rename_dep_fields_2024(root, "dependencies");
|
||||
fixes += rename_table(root, "dev_dependencies", "dev-dependencies");
|
||||
fixes += rename_dep_fields_2024(root, "dev-dependencies");
|
||||
fixes += rename_table(root, "build_dependencies", "build-dependencies");
|
||||
fixes += rename_dep_fields_2024(root, "build-dependencies");
|
||||
for target in root
|
||||
.get_mut("target")
|
||||
.and_then(|t| t.as_table_like_mut())
|
||||
.iter_mut()
|
||||
.flat_map(|t| t.iter_mut())
|
||||
.filter_map(|(_k, t)| t.as_table_like_mut())
|
||||
{
|
||||
fixes += rename_dep_fields_2024(target, "dependencies");
|
||||
fixes += rename_table(target, "dev_dependencies", "dev-dependencies");
|
||||
fixes += rename_dep_fields_2024(target, "dev-dependencies");
|
||||
fixes += rename_table(target, "build_dependencies", "build-dependencies");
|
||||
fixes += rename_dep_fields_2024(target, "build-dependencies");
|
||||
}
|
||||
|
||||
if 0 < fixes {
|
||||
|
@ -274,9 +307,43 @@ fn migrate_manifests(ws: &Workspace<'_>, pkgs: &[&Package]) -> CargoResult<()> {
|
|||
Ok(())
|
||||
}
|
||||
|
||||
fn rename_table(parent: &mut dyn toml_edit::TableLike, old: &str, new: &str) -> bool {
|
||||
fn rename_dep_fields_2024(parent: &mut dyn toml_edit::TableLike, dep_kind: &str) -> usize {
|
||||
let mut fixes = 0;
|
||||
for target in parent
|
||||
.get_mut(dep_kind)
|
||||
.and_then(|t| t.as_table_like_mut())
|
||||
.iter_mut()
|
||||
.flat_map(|t| t.iter_mut())
|
||||
.filter_map(|(_k, t)| t.as_table_like_mut())
|
||||
{
|
||||
fixes += rename_table(target, "default_features", "default-features");
|
||||
}
|
||||
fixes
|
||||
}
|
||||
|
||||
fn rename_array_of_target_fields_2024(root: &mut dyn toml_edit::TableLike, kind: &str) -> usize {
|
||||
let mut fixes = 0;
|
||||
for target in root
|
||||
.get_mut(kind)
|
||||
.and_then(|t| t.as_array_of_tables_mut())
|
||||
.iter_mut()
|
||||
.flat_map(|t| t.iter_mut())
|
||||
{
|
||||
fixes += rename_target_fields_2024(target);
|
||||
}
|
||||
fixes
|
||||
}
|
||||
|
||||
fn rename_target_fields_2024(target: &mut dyn toml_edit::TableLike) -> usize {
|
||||
let mut fixes = 0;
|
||||
fixes += rename_table(target, "crate_type", "crate-type");
|
||||
fixes += rename_table(target, "proc_macro", "proc-macro");
|
||||
fixes
|
||||
}
|
||||
|
||||
fn rename_table(parent: &mut dyn toml_edit::TableLike, old: &str, new: &str) -> usize {
|
||||
let Some(old_key) = parent.key(old).cloned() else {
|
||||
return false;
|
||||
return 0;
|
||||
};
|
||||
|
||||
let project = parent.remove(old).expect("returned early");
|
||||
|
@ -286,7 +353,7 @@ fn rename_table(parent: &mut dyn toml_edit::TableLike, old: &str, new: &str) ->
|
|||
*new_key.dotted_decor_mut() = old_key.dotted_decor().clone();
|
||||
*new_key.leaf_decor_mut() = old_key.leaf_decor().clone();
|
||||
}
|
||||
true
|
||||
1
|
||||
}
|
||||
|
||||
fn add_feature_for_unused_deps(pkg: &Package, parent: &mut dyn toml_edit::TableLike) -> usize {
|
||||
|
|
|
@ -505,7 +505,7 @@ pub trait ArgMatchesExt {
|
|||
fn workspace<'a>(&self, gctx: &'a GlobalContext) -> CargoResult<Workspace<'a>> {
|
||||
let root = self.root_manifest(gctx)?;
|
||||
let mut ws = Workspace::new(&root, gctx)?;
|
||||
ws.set_honor_rust_version(self.honor_rust_version());
|
||||
ws.set_resolve_honors_rust_version(self.honor_rust_version());
|
||||
if gctx.cli_unstable().avoid_dev_deps {
|
||||
ws.set_require_optional_deps(false);
|
||||
}
|
||||
|
|
|
@ -1537,36 +1537,32 @@ impl GlobalContext {
|
|||
let possible = dir.join(filename_without_extension);
|
||||
let possible_with_extension = dir.join(format!("{}.toml", filename_without_extension));
|
||||
|
||||
if possible.exists() {
|
||||
if let Ok(possible_handle) = same_file::Handle::from_path(&possible) {
|
||||
if warn {
|
||||
// We don't want to print a warning if the version
|
||||
// without the extension is just a symlink to the version
|
||||
// WITH an extension, which people may want to do to
|
||||
// support multiple Cargo versions at once and not
|
||||
// get a warning.
|
||||
let skip_warning = if let Ok(target_path) = fs::read_link(&possible) {
|
||||
target_path == possible_with_extension
|
||||
} else {
|
||||
false
|
||||
};
|
||||
|
||||
if !skip_warning {
|
||||
if possible_with_extension.exists() {
|
||||
if let Ok(possible_with_extension_handle) =
|
||||
same_file::Handle::from_path(&possible_with_extension)
|
||||
{
|
||||
// We don't want to print a warning if the version
|
||||
// without the extension is just a symlink to the version
|
||||
// WITH an extension, which people may want to do to
|
||||
// support multiple Cargo versions at once and not
|
||||
// get a warning.
|
||||
if possible_handle != possible_with_extension_handle {
|
||||
self.shell().warn(format!(
|
||||
"both `{}` and `{}` exist. Using `{}`",
|
||||
possible.display(),
|
||||
possible_with_extension.display(),
|
||||
possible.display()
|
||||
))?;
|
||||
} else {
|
||||
self.shell().warn(format!(
|
||||
"`{}` is deprecated in favor of `{filename_without_extension}.toml`",
|
||||
possible.display(),
|
||||
))?;
|
||||
self.shell().note(
|
||||
format!("if you need to support cargo 1.38 or earlier, you can symlink `{filename_without_extension}` to `{filename_without_extension}.toml`"),
|
||||
)?;
|
||||
}
|
||||
} else {
|
||||
self.shell().warn(format!(
|
||||
"`{}` is deprecated in favor of `{filename_without_extension}.toml`",
|
||||
possible.display(),
|
||||
))?;
|
||||
self.shell().note(
|
||||
format!("if you need to support cargo 1.38 or earlier, you can symlink `{filename_without_extension}` to `{filename_without_extension}.toml`"),
|
||||
)?;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -68,6 +68,13 @@ pub struct LintGroup {
|
|||
pub edition_lint_opts: Option<(Edition, LintLevel)>,
|
||||
}
|
||||
|
||||
const TEST_DUMMY_UNSTABLE: LintGroup = LintGroup {
|
||||
name: "test_dummy_unstable",
|
||||
desc: "test_dummy_unstable is meant to only be used in tests",
|
||||
default_level: LintLevel::Allow,
|
||||
edition_lint_opts: None,
|
||||
};
|
||||
|
||||
#[derive(Copy, Clone, Debug)]
|
||||
pub struct Lint {
|
||||
pub name: &'static str,
|
||||
|
@ -78,26 +85,41 @@ pub struct Lint {
|
|||
}
|
||||
|
||||
impl Lint {
|
||||
pub fn level(&self, lints: &TomlToolLints, edition: Edition) -> LintLevel {
|
||||
let level = self
|
||||
.groups
|
||||
pub fn level(
|
||||
&self,
|
||||
pkg_lints: &TomlToolLints,
|
||||
ws_lints: Option<&TomlToolLints>,
|
||||
edition: Edition,
|
||||
) -> (LintLevel, LintLevelReason) {
|
||||
self.groups
|
||||
.iter()
|
||||
.map(|g| g.name)
|
||||
.chain(std::iter::once(self.name))
|
||||
.filter_map(|n| lints.get(n).map(|l| (n, l)))
|
||||
.max_by_key(|(n, l)| (l.priority(), std::cmp::Reverse(*n)));
|
||||
|
||||
match level {
|
||||
Some((_, toml_lint)) => toml_lint.level().into(),
|
||||
None => {
|
||||
if let Some((lint_edition, lint_level)) = self.edition_lint_opts {
|
||||
if edition >= lint_edition {
|
||||
return lint_level;
|
||||
}
|
||||
}
|
||||
self.default_level
|
||||
}
|
||||
}
|
||||
.map(|g| {
|
||||
(
|
||||
g.name,
|
||||
level_priority(
|
||||
g.name,
|
||||
g.default_level,
|
||||
g.edition_lint_opts,
|
||||
pkg_lints,
|
||||
ws_lints,
|
||||
edition,
|
||||
),
|
||||
)
|
||||
})
|
||||
.chain(std::iter::once((
|
||||
self.name,
|
||||
level_priority(
|
||||
self.name,
|
||||
self.default_level,
|
||||
self.edition_lint_opts,
|
||||
pkg_lints,
|
||||
ws_lints,
|
||||
edition,
|
||||
),
|
||||
)))
|
||||
.max_by_key(|(n, (l, _, p))| (l == &LintLevel::Forbid, *p, std::cmp::Reverse(*n)))
|
||||
.map(|(_, (l, r, _))| (l, r))
|
||||
.unwrap()
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -123,7 +145,7 @@ impl Display for LintLevel {
|
|||
impl LintLevel {
|
||||
pub fn to_diagnostic_level(self) -> Level {
|
||||
match self {
|
||||
LintLevel::Allow => Level::Note,
|
||||
LintLevel::Allow => unreachable!("allow does not map to a diagnostic level"),
|
||||
LintLevel::Warn => Level::Warning,
|
||||
LintLevel::Deny => Level::Error,
|
||||
LintLevel::Forbid => Level::Error,
|
||||
|
@ -142,6 +164,123 @@ impl From<TomlLintLevel> for LintLevel {
|
|||
}
|
||||
}
|
||||
|
||||
#[derive(Copy, Clone, Debug)]
|
||||
pub enum LintLevelReason {
|
||||
Default,
|
||||
Edition(Edition),
|
||||
Package,
|
||||
Workspace,
|
||||
}
|
||||
|
||||
impl Display for LintLevelReason {
|
||||
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||
match self {
|
||||
LintLevelReason::Default => write!(f, "by default"),
|
||||
LintLevelReason::Edition(edition) => write!(f, "in edition {}", edition),
|
||||
LintLevelReason::Package => write!(f, "in `[lints]`"),
|
||||
LintLevelReason::Workspace => write!(f, "in `[workspace.lints]`"),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn level_priority(
|
||||
name: &str,
|
||||
default_level: LintLevel,
|
||||
edition_lint_opts: Option<(Edition, LintLevel)>,
|
||||
pkg_lints: &TomlToolLints,
|
||||
ws_lints: Option<&TomlToolLints>,
|
||||
edition: Edition,
|
||||
) -> (LintLevel, LintLevelReason, i8) {
|
||||
let (unspecified_level, reason) = if let Some(level) = edition_lint_opts
|
||||
.filter(|(e, _)| edition >= *e)
|
||||
.map(|(_, l)| l)
|
||||
{
|
||||
(level, LintLevelReason::Edition(edition))
|
||||
} else {
|
||||
(default_level, LintLevelReason::Default)
|
||||
};
|
||||
|
||||
// Don't allow the group to be overridden if the level is `Forbid`
|
||||
if unspecified_level == LintLevel::Forbid {
|
||||
return (unspecified_level, reason, 0);
|
||||
}
|
||||
|
||||
if let Some(defined_level) = pkg_lints.get(name) {
|
||||
(
|
||||
defined_level.level().into(),
|
||||
LintLevelReason::Package,
|
||||
defined_level.priority(),
|
||||
)
|
||||
} else if let Some(defined_level) = ws_lints.and_then(|l| l.get(name)) {
|
||||
(
|
||||
defined_level.level().into(),
|
||||
LintLevelReason::Workspace,
|
||||
defined_level.priority(),
|
||||
)
|
||||
} else {
|
||||
(unspecified_level, reason, 0)
|
||||
}
|
||||
}
|
||||
|
||||
const IM_A_TEAPOT: Lint = Lint {
|
||||
name: "im_a_teapot",
|
||||
desc: "`im_a_teapot` is specified",
|
||||
groups: &[TEST_DUMMY_UNSTABLE],
|
||||
default_level: LintLevel::Allow,
|
||||
edition_lint_opts: None,
|
||||
};
|
||||
|
||||
pub fn check_im_a_teapot(
|
||||
pkg: &Package,
|
||||
path: &Path,
|
||||
pkg_lints: &TomlToolLints,
|
||||
ws_lints: Option<&TomlToolLints>,
|
||||
error_count: &mut usize,
|
||||
gctx: &GlobalContext,
|
||||
) -> CargoResult<()> {
|
||||
let manifest = pkg.manifest();
|
||||
let (lint_level, reason) = IM_A_TEAPOT.level(pkg_lints, ws_lints, manifest.edition());
|
||||
if lint_level == LintLevel::Allow {
|
||||
return Ok(());
|
||||
}
|
||||
|
||||
if manifest
|
||||
.resolved_toml()
|
||||
.package()
|
||||
.is_some_and(|p| p.im_a_teapot.is_some())
|
||||
{
|
||||
if lint_level == LintLevel::Forbid || lint_level == LintLevel::Deny {
|
||||
*error_count += 1;
|
||||
}
|
||||
let level = lint_level.to_diagnostic_level();
|
||||
let manifest_path = rel_cwd_manifest_path(path, gctx);
|
||||
let emitted_reason = format!(
|
||||
"`cargo::{}` is set to `{lint_level}` {reason}",
|
||||
IM_A_TEAPOT.name
|
||||
);
|
||||
|
||||
let key_span = get_span(manifest.document(), &["package", "im-a-teapot"], false).unwrap();
|
||||
let value_span = get_span(manifest.document(), &["package", "im-a-teapot"], true).unwrap();
|
||||
let message = level
|
||||
.title(IM_A_TEAPOT.desc)
|
||||
.snippet(
|
||||
Snippet::source(manifest.contents())
|
||||
.origin(&manifest_path)
|
||||
.annotation(level.span(key_span.start..value_span.end))
|
||||
.fold(true),
|
||||
)
|
||||
.footer(Level::Note.title(&emitted_reason));
|
||||
let renderer = Renderer::styled().term_width(
|
||||
gctx.shell()
|
||||
.err_width()
|
||||
.diagnostic_terminal_width()
|
||||
.unwrap_or(annotate_snippets::renderer::DEFAULT_TERM_WIDTH),
|
||||
);
|
||||
writeln!(gctx.shell().err(), "{}", renderer.render(message))?;
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
|
||||
/// By default, cargo will treat any optional dependency as a [feature]. As of
|
||||
/// cargo 1.60, these can be disabled by declaring a feature that activates the
|
||||
/// optional dependency as `dep:<name>` (see [RFC #3143]).
|
||||
|
@ -166,7 +305,8 @@ const IMPLICIT_FEATURES: Lint = Lint {
|
|||
pub fn check_implicit_features(
|
||||
pkg: &Package,
|
||||
path: &Path,
|
||||
lints: &TomlToolLints,
|
||||
pkg_lints: &TomlToolLints,
|
||||
ws_lints: Option<&TomlToolLints>,
|
||||
error_count: &mut usize,
|
||||
gctx: &GlobalContext,
|
||||
) -> CargoResult<()> {
|
||||
|
@ -177,7 +317,7 @@ pub fn check_implicit_features(
|
|||
return Ok(());
|
||||
}
|
||||
|
||||
let lint_level = IMPLICIT_FEATURES.level(lints, edition);
|
||||
let (lint_level, reason) = IMPLICIT_FEATURES.level(pkg_lints, ws_lints, edition);
|
||||
if lint_level == LintLevel::Allow {
|
||||
return Ok(());
|
||||
}
|
||||
|
@ -222,7 +362,7 @@ pub fn check_implicit_features(
|
|||
);
|
||||
if emitted_source.is_none() {
|
||||
emitted_source = Some(format!(
|
||||
"`cargo::{}` is set to `{lint_level}`",
|
||||
"`cargo::{}` is set to `{lint_level}` {reason}",
|
||||
IMPLICIT_FEATURES.name
|
||||
));
|
||||
message = message.footer(Level::Note.title(emitted_source.as_ref().unwrap()));
|
||||
|
@ -249,7 +389,8 @@ const UNUSED_OPTIONAL_DEPENDENCY: Lint = Lint {
|
|||
pub fn unused_dependencies(
|
||||
pkg: &Package,
|
||||
path: &Path,
|
||||
lints: &TomlToolLints,
|
||||
pkg_lints: &TomlToolLints,
|
||||
ws_lints: Option<&TomlToolLints>,
|
||||
error_count: &mut usize,
|
||||
gctx: &GlobalContext,
|
||||
) -> CargoResult<()> {
|
||||
|
@ -259,7 +400,7 @@ pub fn unused_dependencies(
|
|||
return Ok(());
|
||||
}
|
||||
|
||||
let lint_level = UNUSED_OPTIONAL_DEPENDENCY.level(lints, edition);
|
||||
let (lint_level, reason) = UNUSED_OPTIONAL_DEPENDENCY.level(pkg_lints, ws_lints, edition);
|
||||
if lint_level == LintLevel::Allow {
|
||||
return Ok(());
|
||||
}
|
||||
|
@ -325,7 +466,7 @@ pub fn unused_dependencies(
|
|||
);
|
||||
if emitted_source.is_none() {
|
||||
emitted_source = Some(format!(
|
||||
"`cargo::{}` is set to `{lint_level}`",
|
||||
"`cargo::{}` is set to `{lint_level}` {reason}",
|
||||
UNUSED_OPTIONAL_DEPENDENCY.name
|
||||
));
|
||||
message =
|
||||
|
|
|
@ -90,13 +90,15 @@ impl<T> SleepTracker<T> {
|
|||
#[test]
|
||||
fn returns_in_order() {
|
||||
let mut s = SleepTracker::new();
|
||||
s.push(3, 3);
|
||||
s.push(30_000, 30_000);
|
||||
s.push(1, 1);
|
||||
s.push(6, 6);
|
||||
s.push(5, 5);
|
||||
s.push(2, 2);
|
||||
s.push(10000, 10000);
|
||||
assert_eq!(s.len(), 6);
|
||||
std::thread::sleep(Duration::from_millis(100));
|
||||
assert_eq!(s.to_retry(), &[1, 2, 3, 5, 6]);
|
||||
assert_eq!(s.len(), 2);
|
||||
std::thread::sleep(Duration::from_millis(2));
|
||||
assert_eq!(s.to_retry(), &[1]);
|
||||
assert!(s.to_retry().is_empty());
|
||||
let next = s.time_to_next().expect("should be next");
|
||||
assert!(
|
||||
next < Duration::from_millis(30_000),
|
||||
"{next:?} should be less than 30s"
|
||||
);
|
||||
}
|
||||
|
|
|
@ -306,6 +306,8 @@ fn resolve_toml(
|
|||
};
|
||||
|
||||
if let Some(original_package) = original_toml.package() {
|
||||
let package_name = &original_package.name;
|
||||
|
||||
let resolved_package =
|
||||
resolve_package_toml(original_package, features, package_root, &inherit)?;
|
||||
let edition = resolved_package
|
||||
|
@ -341,6 +343,15 @@ fn resolve_toml(
|
|||
package_root,
|
||||
warnings,
|
||||
)?;
|
||||
deprecated_underscore(
|
||||
&original_toml.dev_dependencies2,
|
||||
&original_toml.dev_dependencies,
|
||||
"dev-dependencies",
|
||||
package_name,
|
||||
"package",
|
||||
edition,
|
||||
warnings,
|
||||
)?;
|
||||
resolved_toml.dev_dependencies = resolve_dependencies(
|
||||
gctx,
|
||||
edition,
|
||||
|
@ -352,6 +363,15 @@ fn resolve_toml(
|
|||
package_root,
|
||||
warnings,
|
||||
)?;
|
||||
deprecated_underscore(
|
||||
&original_toml.build_dependencies2,
|
||||
&original_toml.build_dependencies,
|
||||
"build-dependencies",
|
||||
package_name,
|
||||
"package",
|
||||
edition,
|
||||
warnings,
|
||||
)?;
|
||||
resolved_toml.build_dependencies = resolve_dependencies(
|
||||
gctx,
|
||||
edition,
|
||||
|
@ -376,6 +396,15 @@ fn resolve_toml(
|
|||
package_root,
|
||||
warnings,
|
||||
)?;
|
||||
deprecated_underscore(
|
||||
&platform.dev_dependencies2,
|
||||
&platform.dev_dependencies,
|
||||
"dev-dependencies",
|
||||
name,
|
||||
"platform target",
|
||||
edition,
|
||||
warnings,
|
||||
)?;
|
||||
let resolved_dev_dependencies = resolve_dependencies(
|
||||
gctx,
|
||||
edition,
|
||||
|
@ -387,6 +416,15 @@ fn resolve_toml(
|
|||
package_root,
|
||||
warnings,
|
||||
)?;
|
||||
deprecated_underscore(
|
||||
&platform.build_dependencies2,
|
||||
&platform.build_dependencies,
|
||||
"build-dependencies",
|
||||
name,
|
||||
"platform target",
|
||||
edition,
|
||||
warnings,
|
||||
)?;
|
||||
let resolved_build_dependencies = resolve_dependencies(
|
||||
gctx,
|
||||
edition,
|
||||
|
@ -411,22 +449,9 @@ fn resolve_toml(
|
|||
}
|
||||
resolved_toml.target = (!resolved_target.is_empty()).then_some(resolved_target);
|
||||
|
||||
let resolved_lints = original_toml
|
||||
.lints
|
||||
.clone()
|
||||
.map(|value| lints_inherit_with(value, || inherit()?.lints()))
|
||||
.transpose()?;
|
||||
resolved_toml.lints = resolved_lints.map(|lints| manifest::InheritableLints {
|
||||
workspace: false,
|
||||
lints,
|
||||
});
|
||||
resolved_toml.lints = original_toml.lints.clone();
|
||||
|
||||
let resolved_badges = original_toml
|
||||
.badges
|
||||
.clone()
|
||||
.map(|mw| field_inherit_with(mw, "badges", || inherit()?.badges()))
|
||||
.transpose()?;
|
||||
resolved_toml.badges = resolved_badges.map(manifest::InheritableField::Value);
|
||||
resolved_toml.badges = original_toml.badges.clone();
|
||||
} else {
|
||||
for field in original_toml.requires_package() {
|
||||
bail!("this virtual manifest specifies a `{field}` section, which is not allowed");
|
||||
|
@ -625,6 +650,15 @@ fn resolve_dependencies<'a>(
|
|||
let mut resolved =
|
||||
dependency_inherit_with(v.clone(), name_in_toml, inherit, package_root, warnings)?;
|
||||
if let manifest::TomlDependency::Detailed(ref mut d) = resolved {
|
||||
deprecated_underscore(
|
||||
&d.default_features2,
|
||||
&d.default_features,
|
||||
"default-features",
|
||||
name_in_toml,
|
||||
"dependency",
|
||||
edition,
|
||||
warnings,
|
||||
)?;
|
||||
if d.public.is_some() {
|
||||
let public_feature = features.require(Feature::public_dependency());
|
||||
let with_public_feature = public_feature.is_ok();
|
||||
|
@ -760,7 +794,6 @@ impl InheritableFields {
|
|||
package_field_getter! {
|
||||
// Please keep this list lexicographically ordered.
|
||||
("authors", authors -> Vec<String>),
|
||||
("badges", badges -> BTreeMap<String, BTreeMap<String, String>>),
|
||||
("categories", categories -> Vec<String>),
|
||||
("description", description -> String),
|
||||
("documentation", documentation -> String),
|
||||
|
@ -803,7 +836,7 @@ impl InheritableFields {
|
|||
}
|
||||
|
||||
/// Gets the field `workspace.lint`.
|
||||
fn lints(&self) -> CargoResult<manifest::TomlLints> {
|
||||
pub fn lints(&self) -> CargoResult<manifest::TomlLints> {
|
||||
let Some(val) = &self.lints else {
|
||||
bail!("`workspace.lints` was not defined");
|
||||
};
|
||||
|
@ -904,14 +937,6 @@ fn inner_dependency_inherit_with<'a>(
|
|||
this could become a hard error in the future"
|
||||
))
|
||||
}
|
||||
deprecated_underscore(
|
||||
&dependency.default_features2,
|
||||
&dependency.default_features,
|
||||
"default-features",
|
||||
name,
|
||||
"dependency",
|
||||
warnings,
|
||||
);
|
||||
inherit()?.get_dependency(name, package_root).map(|d| {
|
||||
match d {
|
||||
manifest::TomlDependency::Simple(s) => {
|
||||
|
@ -1162,28 +1187,12 @@ fn to_real_manifest(
|
|||
}
|
||||
|
||||
validate_dependencies(original_toml.dependencies.as_ref(), None, None, warnings)?;
|
||||
deprecated_underscore(
|
||||
&original_toml.dev_dependencies2,
|
||||
&original_toml.dev_dependencies,
|
||||
"dev-dependencies",
|
||||
package_name,
|
||||
"package",
|
||||
warnings,
|
||||
);
|
||||
validate_dependencies(
|
||||
original_toml.dev_dependencies(),
|
||||
None,
|
||||
Some(DepKind::Development),
|
||||
warnings,
|
||||
)?;
|
||||
deprecated_underscore(
|
||||
&original_toml.build_dependencies2,
|
||||
&original_toml.build_dependencies,
|
||||
"build-dependencies",
|
||||
package_name,
|
||||
"package",
|
||||
warnings,
|
||||
);
|
||||
validate_dependencies(
|
||||
original_toml.build_dependencies(),
|
||||
None,
|
||||
|
@ -1200,28 +1209,12 @@ fn to_real_manifest(
|
|||
None,
|
||||
warnings,
|
||||
)?;
|
||||
deprecated_underscore(
|
||||
&platform.build_dependencies2,
|
||||
&platform.build_dependencies,
|
||||
"build-dependencies",
|
||||
name,
|
||||
"platform target",
|
||||
warnings,
|
||||
);
|
||||
validate_dependencies(
|
||||
platform.build_dependencies(),
|
||||
platform_kind.as_ref(),
|
||||
Some(DepKind::Build),
|
||||
warnings,
|
||||
)?;
|
||||
deprecated_underscore(
|
||||
&platform.dev_dependencies2,
|
||||
&platform.dev_dependencies,
|
||||
"dev-dependencies",
|
||||
name,
|
||||
"platform target",
|
||||
warnings,
|
||||
);
|
||||
validate_dependencies(
|
||||
platform.dev_dependencies(),
|
||||
platform_kind.as_ref(),
|
||||
|
@ -1284,18 +1277,18 @@ fn to_real_manifest(
|
|||
}
|
||||
}
|
||||
|
||||
verify_lints(
|
||||
resolved_toml.resolved_lints().expect("previously resolved"),
|
||||
gctx,
|
||||
warnings,
|
||||
)?;
|
||||
let default = manifest::TomlLints::default();
|
||||
let rustflags = lints_to_rustflags(
|
||||
resolved_toml
|
||||
.resolved_lints()
|
||||
.expect("previously resolved")
|
||||
.unwrap_or(&default),
|
||||
);
|
||||
let resolved_lints = resolved_toml
|
||||
.lints
|
||||
.clone()
|
||||
.map(|value| {
|
||||
lints_inherit_with(value, || {
|
||||
load_inheritable_fields(gctx, manifest_file, &workspace_config)?.lints()
|
||||
})
|
||||
})
|
||||
.transpose()?;
|
||||
|
||||
verify_lints(resolved_lints.as_ref(), gctx, warnings)?;
|
||||
let rustflags = lints_to_rustflags(&resolved_lints.unwrap_or_default());
|
||||
|
||||
let metadata = ManifestMetadata {
|
||||
description: resolved_package
|
||||
|
@ -1341,11 +1334,7 @@ fn to_real_manifest(
|
|||
.expect("previously resolved")
|
||||
.cloned()
|
||||
.unwrap_or_default(),
|
||||
badges: resolved_toml
|
||||
.resolved_badges()
|
||||
.expect("previously resolved")
|
||||
.cloned()
|
||||
.unwrap_or_default(),
|
||||
badges: resolved_toml.badges.clone().unwrap_or_default(),
|
||||
links: resolved_package.links.clone(),
|
||||
rust_version: rust_version.clone(),
|
||||
};
|
||||
|
@ -1818,90 +1807,7 @@ fn detailed_dep_to_dependency<P: ResolveToPath + Clone>(
|
|||
}
|
||||
}
|
||||
|
||||
let new_source_id = match (
|
||||
orig.git.as_ref(),
|
||||
orig.path.as_ref(),
|
||||
orig.registry.as_ref(),
|
||||
orig.registry_index.as_ref(),
|
||||
) {
|
||||
(Some(_), _, Some(_), _) | (Some(_), _, _, Some(_)) => bail!(
|
||||
"dependency ({}) specification is ambiguous. \
|
||||
Only one of `git` or `registry` is allowed.",
|
||||
name_in_toml
|
||||
),
|
||||
(_, _, Some(_), Some(_)) => bail!(
|
||||
"dependency ({}) specification is ambiguous. \
|
||||
Only one of `registry` or `registry-index` is allowed.",
|
||||
name_in_toml
|
||||
),
|
||||
(Some(git), maybe_path, _, _) => {
|
||||
if maybe_path.is_some() {
|
||||
bail!(
|
||||
"dependency ({}) specification is ambiguous. \
|
||||
Only one of `git` or `path` is allowed.",
|
||||
name_in_toml
|
||||
);
|
||||
}
|
||||
|
||||
let n_details = [&orig.branch, &orig.tag, &orig.rev]
|
||||
.iter()
|
||||
.filter(|d| d.is_some())
|
||||
.count();
|
||||
|
||||
if n_details > 1 {
|
||||
bail!(
|
||||
"dependency ({}) specification is ambiguous. \
|
||||
Only one of `branch`, `tag` or `rev` is allowed.",
|
||||
name_in_toml
|
||||
);
|
||||
}
|
||||
|
||||
let reference = orig
|
||||
.branch
|
||||
.clone()
|
||||
.map(GitReference::Branch)
|
||||
.or_else(|| orig.tag.clone().map(GitReference::Tag))
|
||||
.or_else(|| orig.rev.clone().map(GitReference::Rev))
|
||||
.unwrap_or(GitReference::DefaultBranch);
|
||||
let loc = git.into_url()?;
|
||||
|
||||
if let Some(fragment) = loc.fragment() {
|
||||
let msg = format!(
|
||||
"URL fragment `#{}` in git URL is ignored for dependency ({}). \
|
||||
If you were trying to specify a specific git revision, \
|
||||
use `rev = \"{}\"` in the dependency declaration.",
|
||||
fragment, name_in_toml, fragment
|
||||
);
|
||||
manifest_ctx.warnings.push(msg)
|
||||
}
|
||||
|
||||
SourceId::for_git(&loc, reference)?
|
||||
}
|
||||
(None, Some(path), _, _) => {
|
||||
let path = path.resolve(manifest_ctx.gctx);
|
||||
// If the source ID for the package we're parsing is a path
|
||||
// source, then we normalize the path here to get rid of
|
||||
// components like `..`.
|
||||
//
|
||||
// The purpose of this is to get a canonical ID for the package
|
||||
// that we're depending on to ensure that builds of this package
|
||||
// always end up hashing to the same value no matter where it's
|
||||
// built from.
|
||||
if manifest_ctx.source_id.is_path() {
|
||||
let path = manifest_ctx.root.join(path);
|
||||
let path = paths::normalize_path(&path);
|
||||
SourceId::for_path(&path)?
|
||||
} else {
|
||||
manifest_ctx.source_id
|
||||
}
|
||||
}
|
||||
(None, None, Some(registry), None) => SourceId::alt_registry(manifest_ctx.gctx, registry)?,
|
||||
(None, None, None, Some(registry_index)) => {
|
||||
let url = registry_index.into_url()?;
|
||||
SourceId::for_registry(&url)?
|
||||
}
|
||||
(None, None, None, None) => SourceId::crates_io(manifest_ctx.gctx)?,
|
||||
};
|
||||
let new_source_id = to_dependency_source_id(orig, name_in_toml, manifest_ctx)?;
|
||||
|
||||
let (pkg_name, explicit_name_in_toml) = match orig.package {
|
||||
Some(ref s) => (&s[..], Some(name_in_toml)),
|
||||
|
@ -1910,14 +1816,6 @@ fn detailed_dep_to_dependency<P: ResolveToPath + Clone>(
|
|||
|
||||
let version = orig.version.as_deref();
|
||||
let mut dep = Dependency::parse(pkg_name, version, new_source_id)?;
|
||||
deprecated_underscore(
|
||||
&orig.default_features2,
|
||||
&orig.default_features,
|
||||
"default-features",
|
||||
name_in_toml,
|
||||
"dependency",
|
||||
manifest_ctx.warnings,
|
||||
);
|
||||
dep.set_features(orig.features.iter().flatten())
|
||||
.set_default_features(orig.default_features().unwrap_or(true))
|
||||
.set_optional(orig.optional.unwrap_or(false))
|
||||
|
@ -1980,6 +1878,91 @@ fn detailed_dep_to_dependency<P: ResolveToPath + Clone>(
|
|||
Ok(dep)
|
||||
}
|
||||
|
||||
fn to_dependency_source_id<P: ResolveToPath + Clone>(
|
||||
orig: &manifest::TomlDetailedDependency<P>,
|
||||
name_in_toml: &str,
|
||||
manifest_ctx: &mut ManifestContext<'_, '_>,
|
||||
) -> CargoResult<SourceId> {
|
||||
match (
|
||||
orig.git.as_ref(),
|
||||
orig.path.as_ref(),
|
||||
orig.registry.as_deref(),
|
||||
orig.registry_index.as_ref(),
|
||||
) {
|
||||
(Some(_git), _, Some(_registry), _) | (Some(_git), _, _, Some(_registry)) => bail!(
|
||||
"dependency ({name_in_toml}) specification is ambiguous. \
|
||||
Only one of `git` or `registry` is allowed.",
|
||||
),
|
||||
(_, _, Some(_registry), Some(_registry_index)) => bail!(
|
||||
"dependency ({name_in_toml}) specification is ambiguous. \
|
||||
Only one of `registry` or `registry-index` is allowed.",
|
||||
),
|
||||
(Some(_git), Some(_path), None, None) => {
|
||||
bail!(
|
||||
"dependency ({name_in_toml}) specification is ambiguous. \
|
||||
Only one of `git` or `path` is allowed.",
|
||||
);
|
||||
}
|
||||
(Some(git), None, None, None) => {
|
||||
let n_details = [&orig.branch, &orig.tag, &orig.rev]
|
||||
.iter()
|
||||
.filter(|d| d.is_some())
|
||||
.count();
|
||||
|
||||
if n_details > 1 {
|
||||
bail!(
|
||||
"dependency ({name_in_toml}) specification is ambiguous. \
|
||||
Only one of `branch`, `tag` or `rev` is allowed.",
|
||||
);
|
||||
}
|
||||
|
||||
let reference = orig
|
||||
.branch
|
||||
.clone()
|
||||
.map(GitReference::Branch)
|
||||
.or_else(|| orig.tag.clone().map(GitReference::Tag))
|
||||
.or_else(|| orig.rev.clone().map(GitReference::Rev))
|
||||
.unwrap_or(GitReference::DefaultBranch);
|
||||
let loc = git.into_url()?;
|
||||
|
||||
if let Some(fragment) = loc.fragment() {
|
||||
let msg = format!(
|
||||
"URL fragment `#{fragment}` in git URL is ignored for dependency ({name_in_toml}). \
|
||||
If you were trying to specify a specific git revision, \
|
||||
use `rev = \"{fragment}\"` in the dependency declaration.",
|
||||
);
|
||||
manifest_ctx.warnings.push(msg);
|
||||
}
|
||||
|
||||
SourceId::for_git(&loc, reference)
|
||||
}
|
||||
(None, Some(path), _, _) => {
|
||||
let path = path.resolve(manifest_ctx.gctx);
|
||||
// If the source ID for the package we're parsing is a path
|
||||
// source, then we normalize the path here to get rid of
|
||||
// components like `..`.
|
||||
//
|
||||
// The purpose of this is to get a canonical ID for the package
|
||||
// that we're depending on to ensure that builds of this package
|
||||
// always end up hashing to the same value no matter where it's
|
||||
// built from.
|
||||
if manifest_ctx.source_id.is_path() {
|
||||
let path = manifest_ctx.root.join(path);
|
||||
let path = paths::normalize_path(&path);
|
||||
SourceId::for_path(&path)
|
||||
} else {
|
||||
Ok(manifest_ctx.source_id)
|
||||
}
|
||||
}
|
||||
(None, None, Some(registry), None) => SourceId::alt_registry(manifest_ctx.gctx, registry),
|
||||
(None, None, None, Some(registry_index)) => {
|
||||
let url = registry_index.into_url()?;
|
||||
SourceId::for_registry(&url)
|
||||
}
|
||||
(None, None, None, None) => SourceId::crates_io(manifest_ctx.gctx),
|
||||
}
|
||||
}
|
||||
|
||||
pub trait ResolveToPath {
|
||||
fn resolve(&self, gctx: &GlobalContext) -> PathBuf;
|
||||
}
|
||||
|
@ -2335,19 +2318,22 @@ fn deprecated_underscore<T>(
|
|||
new_path: &str,
|
||||
name: &str,
|
||||
kind: &str,
|
||||
edition: Edition,
|
||||
warnings: &mut Vec<String>,
|
||||
) {
|
||||
if old.is_some() && new.is_some() {
|
||||
let old_path = new_path.replace("-", "_");
|
||||
) -> CargoResult<()> {
|
||||
let old_path = new_path.replace("-", "_");
|
||||
if old.is_some() && Edition::Edition2024 <= edition {
|
||||
anyhow::bail!("`{old_path}` is unsupported as of the 2024 edition; instead use `{new_path}`\n(in the `{name}` {kind})");
|
||||
} else if old.is_some() && new.is_some() {
|
||||
warnings.push(format!(
|
||||
"unused manifest key `{old_path}` in the `{name}` {kind}"
|
||||
"`{old_path}` is redundant with `{new_path}`, preferring `{new_path}` in the `{name}` {kind}"
|
||||
))
|
||||
} else if old.is_some() {
|
||||
let old_path = new_path.replace("-", "_");
|
||||
warnings.push(format!(
|
||||
"`{old_path}` is deprecated in favor of `{new_path}` and will not work in the 2024 edition\n(in the `{name}` {kind})"
|
||||
))
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn warn_on_unused(unused: &BTreeSet<String>, warnings: &mut Vec<String>) {
|
||||
|
|
|
@ -97,12 +97,7 @@ pub(super) fn to_targets(
|
|||
warnings,
|
||||
errors,
|
||||
)?;
|
||||
targets.extend(to_example_targets(
|
||||
&toml_examples,
|
||||
package_root,
|
||||
edition,
|
||||
warnings,
|
||||
)?);
|
||||
targets.extend(to_example_targets(&toml_examples, package_root, edition)?);
|
||||
|
||||
let toml_tests = resolve_tests(
|
||||
resolved_toml.test.as_ref(),
|
||||
|
@ -183,6 +178,10 @@ fn resolve_lib(
|
|||
// Check early to improve error messages
|
||||
validate_lib_name(&lib, warnings)?;
|
||||
|
||||
// Checking the original lib
|
||||
validate_proc_macro(&lib, "library", edition, warnings)?;
|
||||
validate_crate_types(&lib, "library", edition, warnings)?;
|
||||
|
||||
if lib.path.is_none() {
|
||||
if let Some(inferred) = inferred {
|
||||
lib.path = Some(PathValue(inferred));
|
||||
|
@ -218,8 +217,6 @@ fn to_lib_target(
|
|||
let Some(lib) = resolved_lib else {
|
||||
return Ok(None);
|
||||
};
|
||||
validate_proc_macro(lib, "library", warnings);
|
||||
validate_crate_types(lib, "library", warnings);
|
||||
|
||||
let path = lib.path.as_ref().expect("previously resolved");
|
||||
let path = package_root.join(&path.0);
|
||||
|
@ -442,14 +439,12 @@ fn to_example_targets(
|
|||
targets: &[TomlExampleTarget],
|
||||
package_root: &Path,
|
||||
edition: Edition,
|
||||
warnings: &mut Vec<String>,
|
||||
) -> CargoResult<Vec<Target>> {
|
||||
validate_unique_names(&targets, "example")?;
|
||||
|
||||
let mut result = Vec::new();
|
||||
for toml in targets {
|
||||
let path = package_root.join(&toml.path.as_ref().expect("previously resolved").0);
|
||||
validate_crate_types(&toml, "example", warnings);
|
||||
let crate_types = match toml.crate_types() {
|
||||
Some(kinds) => kinds.iter().map(|s| s.into()).collect(),
|
||||
None => Vec::new(),
|
||||
|
@ -637,6 +632,8 @@ fn resolve_targets_with_legacy_path(
|
|||
|
||||
for target in &toml_targets {
|
||||
validate_target_name(target, target_kind_human, target_kind, warnings)?;
|
||||
validate_proc_macro(target, target_kind_human, edition, warnings)?;
|
||||
validate_crate_types(target, target_kind_human, edition, warnings)?;
|
||||
}
|
||||
|
||||
let mut result = Vec::new();
|
||||
|
@ -1101,24 +1098,36 @@ fn name_or_panic(target: &TomlTarget) -> &str {
|
|||
.unwrap_or_else(|| panic!("target name is required"))
|
||||
}
|
||||
|
||||
fn validate_proc_macro(target: &TomlTarget, kind: &str, warnings: &mut Vec<String>) {
|
||||
fn validate_proc_macro(
|
||||
target: &TomlTarget,
|
||||
kind: &str,
|
||||
edition: Edition,
|
||||
warnings: &mut Vec<String>,
|
||||
) -> CargoResult<()> {
|
||||
deprecated_underscore(
|
||||
&target.proc_macro2,
|
||||
&target.proc_macro,
|
||||
"proc-macro",
|
||||
name_or_panic(target),
|
||||
format!("{kind} target").as_str(),
|
||||
edition,
|
||||
warnings,
|
||||
);
|
||||
)
|
||||
}
|
||||
|
||||
fn validate_crate_types(target: &TomlTarget, kind: &str, warnings: &mut Vec<String>) {
|
||||
fn validate_crate_types(
|
||||
target: &TomlTarget,
|
||||
kind: &str,
|
||||
edition: Edition,
|
||||
warnings: &mut Vec<String>,
|
||||
) -> CargoResult<()> {
|
||||
deprecated_underscore(
|
||||
&target.crate_type2,
|
||||
&target.crate_type,
|
||||
"crate-type",
|
||||
name_or_panic(target),
|
||||
format!("{kind} target").as_str(),
|
||||
edition,
|
||||
warnings,
|
||||
);
|
||||
)
|
||||
}
|
||||
|
|
|
@ -339,6 +339,7 @@ This was stabilized in 1.79 in [#13608](https://github.com/rust-lang/cargo/pull/
|
|||
`-Zmsrv-policy` allows access to an MSRV-aware resolver which can be enabled with:
|
||||
- `resolver.something-like-precedence` config field
|
||||
- `workspace.resolver = "3"` / `package.resolver = "3"`
|
||||
- `package.edition = "2024"` (only in workspace root)
|
||||
|
||||
The resolver will prefer dependencies with a `package.rust-version` that is the same or older than your project's MSRV.
|
||||
Your project's MSRV is determined by taking the lowest `package.rust-version` set among your workspace members.
|
||||
|
|
|
@ -80,10 +80,14 @@ edition = "2021" # the edition, will have no effect on a resolver used in th
|
|||
authors = ["Alice <a@example.com>", "Bob <b@example.com>"]
|
||||
```
|
||||
|
||||
Note that in a virtual manifest the [`resolver = "2"`](resolver.md#resolver-versions)
|
||||
should be specified manually. It is usually deduced from the [`package.edition`][package-edition]
|
||||
field which is absent in virtual manifests and the edition field of a member
|
||||
won't affect the resolver used by the workspace.
|
||||
By having a workspace without a root package,
|
||||
|
||||
- [`resolver`](resolver.md#resolver-versions) must be
|
||||
set explicitly in virtual workspaces as they have no
|
||||
[`package.edition`][package-edition] to infer it from
|
||||
[resolver version](resolver.md#resolver-versions).
|
||||
- Commands run in the workspace root will run against all workspace
|
||||
members by default, see [`default-members`](#the-default-members-field).
|
||||
|
||||
## The `members` and `exclude` fields
|
||||
|
||||
|
@ -120,14 +124,12 @@ is not inside a subdirectory of the workspace root.
|
|||
In a workspace, package-related Cargo commands like [`cargo build`] can use
|
||||
the `-p` / `--package` or `--workspace` command-line flags to determine which
|
||||
packages to operate on. If neither of those flags are specified, Cargo will
|
||||
use the package in the current working directory. If the current directory is
|
||||
a [virtual workspace](#virtual-workspace), it will apply to all members (as if
|
||||
`--workspace` were specified on the command-line). See also
|
||||
[`default-members`](#the-default-members-field).
|
||||
use the package in the current working directory. However, if the current directory is
|
||||
a workspace root, the [`default-members`](#the-default-members-field) will be used.
|
||||
|
||||
## The `default-members` field
|
||||
|
||||
The optional `default-members` key can be specified to set the members to
|
||||
The `default-members` field specifies paths of [members](#the-members-and-exclude-fields) to
|
||||
operate on when in the workspace root and the package selection flags are not
|
||||
used:
|
||||
|
||||
|
@ -137,7 +139,12 @@ members = ["path/to/member1", "path/to/member2", "path/to/member3/*"]
|
|||
default-members = ["path/to/member2", "path/to/member3/foo"]
|
||||
```
|
||||
|
||||
When specified, `default-members` must expand to a subset of `members`.
|
||||
> Note: when a [root package](#root-package) is present,
|
||||
> you can only operate on it using `--package` and `--workspace` flags.
|
||||
|
||||
When unspecified, the [root package](#root-package) will be used.
|
||||
In the case of a [virtual workspace](#virtual-workspace), all members will be used
|
||||
(as if `--workspace` were specified on the command-line).
|
||||
|
||||
## The `package` table
|
||||
|
||||
|
|
|
@ -1572,7 +1572,11 @@ or use environment variable CARGO_REGISTRIES_ALTERNATIVE_TOKEN",
|
|||
)
|
||||
.run();
|
||||
|
||||
let crates_io = registry::RegistryBuilder::new()
|
||||
.no_configure_token()
|
||||
.build();
|
||||
p.cargo("publish --registry crates-io")
|
||||
.replace_crates_io(crates_io.index_url())
|
||||
.with_status(101)
|
||||
.with_stderr(
|
||||
"\
|
||||
|
|
|
@ -841,6 +841,50 @@ fn dev_dependencies2() {
|
|||
.run();
|
||||
}
|
||||
|
||||
#[cargo_test(nightly, reason = "edition2024 is not stable")]
|
||||
fn dev_dependencies2_2024() {
|
||||
let p = project()
|
||||
.file(
|
||||
"Cargo.toml",
|
||||
r#"
|
||||
cargo-features = ["edition2024"]
|
||||
|
||||
[package]
|
||||
name = "foo"
|
||||
version = "0.1.0"
|
||||
edition = "2024"
|
||||
|
||||
[dev_dependencies]
|
||||
a = {path = "a"}
|
||||
"#,
|
||||
)
|
||||
.file("src/lib.rs", "")
|
||||
.file(
|
||||
"a/Cargo.toml",
|
||||
r#"
|
||||
[package]
|
||||
name = "a"
|
||||
version = "0.0.1"
|
||||
edition = "2015"
|
||||
"#,
|
||||
)
|
||||
.file("a/src/lib.rs", "")
|
||||
.build();
|
||||
p.cargo("check")
|
||||
.masquerade_as_nightly_cargo(&["edition2024"])
|
||||
.with_status(101)
|
||||
.with_stderr(
|
||||
"\
|
||||
[ERROR] failed to parse manifest at `[CWD]/Cargo.toml`
|
||||
|
||||
Caused by:
|
||||
`dev_dependencies` is unsupported as of the 2024 edition; instead use `dev-dependencies`
|
||||
(in the `foo` package)
|
||||
",
|
||||
)
|
||||
.run();
|
||||
}
|
||||
|
||||
#[cargo_test]
|
||||
fn dev_dependencies2_conflict() {
|
||||
let p = project()
|
||||
|
@ -873,7 +917,7 @@ fn dev_dependencies2_conflict() {
|
|||
p.cargo("check")
|
||||
.with_stderr_contains(
|
||||
"\
|
||||
[WARNING] unused manifest key `dev_dependencies` in the `foo` package
|
||||
[WARNING] `dev_dependencies` is redundant with `dev-dependencies`, preferring `dev-dependencies` in the `foo` package
|
||||
",
|
||||
)
|
||||
.run();
|
||||
|
@ -916,6 +960,50 @@ fn build_dependencies2() {
|
|||
.run();
|
||||
}
|
||||
|
||||
#[cargo_test(nightly, reason = "edition2024 is not stable")]
|
||||
fn build_dependencies2_2024() {
|
||||
let p = project()
|
||||
.file(
|
||||
"Cargo.toml",
|
||||
r#"
|
||||
cargo-features = ["edition2024"]
|
||||
|
||||
[package]
|
||||
name = "foo"
|
||||
version = "0.1.0"
|
||||
edition = "2024"
|
||||
|
||||
[build_dependencies]
|
||||
a = {path = "a"}
|
||||
"#,
|
||||
)
|
||||
.file("src/lib.rs", "")
|
||||
.file(
|
||||
"a/Cargo.toml",
|
||||
r#"
|
||||
[package]
|
||||
name = "a"
|
||||
version = "0.0.1"
|
||||
edition = "2015"
|
||||
"#,
|
||||
)
|
||||
.file("a/src/lib.rs", "")
|
||||
.build();
|
||||
p.cargo("check")
|
||||
.masquerade_as_nightly_cargo(&["edition2024"])
|
||||
.with_status(101)
|
||||
.with_stderr(
|
||||
"\
|
||||
[ERROR] failed to parse manifest at `[CWD]/Cargo.toml`
|
||||
|
||||
Caused by:
|
||||
`build_dependencies` is unsupported as of the 2024 edition; instead use `build-dependencies`
|
||||
(in the `foo` package)
|
||||
",
|
||||
)
|
||||
.run();
|
||||
}
|
||||
|
||||
#[cargo_test]
|
||||
fn build_dependencies2_conflict() {
|
||||
let p = project()
|
||||
|
@ -948,7 +1036,7 @@ fn build_dependencies2_conflict() {
|
|||
p.cargo("check")
|
||||
.with_stderr_contains(
|
||||
"\
|
||||
[WARNING] unused manifest key `build_dependencies` in the `foo` package
|
||||
[WARNING] `build_dependencies` is redundant with `build-dependencies`, preferring `build-dependencies` in the `foo` package
|
||||
",
|
||||
)
|
||||
.run();
|
||||
|
@ -983,6 +1071,42 @@ fn lib_crate_type2() {
|
|||
.run();
|
||||
}
|
||||
|
||||
#[cargo_test(nightly, reason = "edition2024 is not stable")]
|
||||
fn lib_crate_type2_2024() {
|
||||
let p = project()
|
||||
.file(
|
||||
"Cargo.toml",
|
||||
r#"
|
||||
cargo-features = ["edition2024"]
|
||||
|
||||
[package]
|
||||
name = "foo"
|
||||
version = "0.5.0"
|
||||
edition = "2024"
|
||||
authors = ["wycats@example.com"]
|
||||
|
||||
[lib]
|
||||
name = "foo"
|
||||
crate_type = ["staticlib", "dylib"]
|
||||
"#,
|
||||
)
|
||||
.file("src/lib.rs", "pub fn foo() {}")
|
||||
.build();
|
||||
p.cargo("check")
|
||||
.masquerade_as_nightly_cargo(&["edition2024"])
|
||||
.with_status(101)
|
||||
.with_stderr(
|
||||
"\
|
||||
[ERROR] failed to parse manifest at `[CWD]/Cargo.toml`
|
||||
|
||||
Caused by:
|
||||
`crate_type` is unsupported as of the 2024 edition; instead use `crate-type`
|
||||
(in the `foo` library target)
|
||||
",
|
||||
)
|
||||
.run();
|
||||
}
|
||||
|
||||
#[cargo_test]
|
||||
fn lib_crate_type2_conflict() {
|
||||
let p = project()
|
||||
|
@ -1006,7 +1130,7 @@ fn lib_crate_type2_conflict() {
|
|||
p.cargo("check")
|
||||
.with_stderr_contains(
|
||||
"\
|
||||
[WARNING] unused manifest key `crate_type` in the `foo` library target
|
||||
[WARNING] `crate_type` is redundant with `crate-type`, preferring `crate-type` in the `foo` library target
|
||||
",
|
||||
)
|
||||
.run();
|
||||
|
@ -1060,6 +1184,59 @@ fn examples_crate_type2() {
|
|||
.run();
|
||||
}
|
||||
|
||||
#[cargo_test(nightly, reason = "edition2024 is not stable")]
|
||||
fn examples_crate_type2_2024() {
|
||||
let p = project()
|
||||
.file(
|
||||
"Cargo.toml",
|
||||
r#"
|
||||
cargo-features = ["edition2024"]
|
||||
|
||||
[package]
|
||||
name = "foo"
|
||||
version = "0.5.0"
|
||||
edition = "2024"
|
||||
authors = ["wycats@example.com"]
|
||||
|
||||
[[example]]
|
||||
name = "ex"
|
||||
path = "examples/ex.rs"
|
||||
crate_type = ["proc_macro"]
|
||||
[[example]]
|
||||
name = "goodbye"
|
||||
path = "examples/ex-goodbye.rs"
|
||||
crate_type = ["rlib", "staticlib"]
|
||||
"#,
|
||||
)
|
||||
.file("src/lib.rs", "")
|
||||
.file(
|
||||
"examples/ex.rs",
|
||||
r#"
|
||||
fn main() { println!("ex"); }
|
||||
"#,
|
||||
)
|
||||
.file(
|
||||
"examples/ex-goodbye.rs",
|
||||
r#"
|
||||
fn main() { println!("goodbye"); }
|
||||
"#,
|
||||
)
|
||||
.build();
|
||||
p.cargo("check")
|
||||
.masquerade_as_nightly_cargo(&["edition2024"])
|
||||
.with_status(101)
|
||||
.with_stderr(
|
||||
"\
|
||||
[ERROR] failed to parse manifest at `[CWD]/Cargo.toml`
|
||||
|
||||
Caused by:
|
||||
`crate_type` is unsupported as of the 2024 edition; instead use `crate-type`
|
||||
(in the `ex` example target)
|
||||
",
|
||||
)
|
||||
.run();
|
||||
}
|
||||
|
||||
#[cargo_test]
|
||||
fn examples_crate_type2_conflict() {
|
||||
let p = project()
|
||||
|
@ -1101,8 +1278,8 @@ fn examples_crate_type2_conflict() {
|
|||
p.cargo("check")
|
||||
.with_stderr_contains(
|
||||
"\
|
||||
[WARNING] unused manifest key `crate_type` in the `ex` example target
|
||||
[WARNING] unused manifest key `crate_type` in the `goodbye` example target
|
||||
[WARNING] `crate_type` is redundant with `crate-type`, preferring `crate-type` in the `ex` example target
|
||||
[WARNING] `crate_type` is redundant with `crate-type`, preferring `crate-type` in the `goodbye` example target
|
||||
",
|
||||
)
|
||||
.run();
|
||||
|
@ -1148,6 +1325,53 @@ fn cargo_platform_build_dependencies2() {
|
|||
.run();
|
||||
}
|
||||
|
||||
#[cargo_test(nightly, reason = "edition2024 is not stable")]
|
||||
fn cargo_platform_build_dependencies2_2024() {
|
||||
let host = rustc_host();
|
||||
let p = project()
|
||||
.file(
|
||||
"Cargo.toml",
|
||||
&format!(
|
||||
r#"
|
||||
cargo-features = ["edition2024"]
|
||||
|
||||
[package]
|
||||
name = "foo"
|
||||
version = "0.5.0"
|
||||
edition = "2024"
|
||||
authors = ["wycats@example.com"]
|
||||
build = "build.rs"
|
||||
|
||||
[target.{host}.build_dependencies]
|
||||
build = {{ path = "build" }}
|
||||
"#,
|
||||
host = host
|
||||
),
|
||||
)
|
||||
.file("src/main.rs", "fn main() { }")
|
||||
.file(
|
||||
"build.rs",
|
||||
"extern crate build; fn main() { build::build(); }",
|
||||
)
|
||||
.file("build/Cargo.toml", &basic_manifest("build", "0.5.0"))
|
||||
.file("build/src/lib.rs", "pub fn build() {}")
|
||||
.build();
|
||||
|
||||
p.cargo("check")
|
||||
.masquerade_as_nightly_cargo(&["edition2024"])
|
||||
.with_status(101)
|
||||
.with_stderr(format!(
|
||||
"\
|
||||
[ERROR] failed to parse manifest at `[CWD]/Cargo.toml`
|
||||
|
||||
Caused by:
|
||||
`build_dependencies` is unsupported as of the 2024 edition; instead use `build-dependencies`
|
||||
(in the `{host}` platform target)
|
||||
"
|
||||
))
|
||||
.run();
|
||||
}
|
||||
|
||||
#[cargo_test]
|
||||
fn cargo_platform_build_dependencies2_conflict() {
|
||||
let host = rustc_host();
|
||||
|
@ -1183,7 +1407,7 @@ fn cargo_platform_build_dependencies2_conflict() {
|
|||
p.cargo("check")
|
||||
.with_stderr_contains(format!(
|
||||
"\
|
||||
[WARNING] unused manifest key `build_dependencies` in the `{host}` platform target
|
||||
[WARNING] `build_dependencies` is redundant with `build-dependencies`, preferring `build-dependencies` in the `{host}` platform target
|
||||
"
|
||||
))
|
||||
.run();
|
||||
|
@ -1228,6 +1452,52 @@ fn cargo_platform_dev_dependencies2() {
|
|||
.run();
|
||||
}
|
||||
|
||||
#[cargo_test(nightly, reason = "edition2024 is not stable")]
|
||||
fn cargo_platform_dev_dependencies2_2024() {
|
||||
let host = rustc_host();
|
||||
let p = project()
|
||||
.file(
|
||||
"Cargo.toml",
|
||||
&format!(
|
||||
r#"
|
||||
cargo-features = ["edition2024"]
|
||||
|
||||
[package]
|
||||
name = "foo"
|
||||
version = "0.5.0"
|
||||
edition = "2024"
|
||||
authors = ["wycats@example.com"]
|
||||
|
||||
[target.{host}.dev_dependencies]
|
||||
dev = {{ path = "dev" }}
|
||||
"#,
|
||||
host = host
|
||||
),
|
||||
)
|
||||
.file("src/main.rs", "fn main() { }")
|
||||
.file(
|
||||
"tests/foo.rs",
|
||||
"extern crate dev; #[test] fn foo() { dev::dev() }",
|
||||
)
|
||||
.file("dev/Cargo.toml", &basic_manifest("dev", "0.5.0"))
|
||||
.file("dev/src/lib.rs", "pub fn dev() {}")
|
||||
.build();
|
||||
|
||||
p.cargo("check")
|
||||
.masquerade_as_nightly_cargo(&["edition2024"])
|
||||
.with_status(101)
|
||||
.with_stderr(format!(
|
||||
"\
|
||||
[ERROR] failed to parse manifest at `[CWD]/Cargo.toml`
|
||||
|
||||
Caused by:
|
||||
`dev_dependencies` is unsupported as of the 2024 edition; instead use `dev-dependencies`
|
||||
(in the `{host}` platform target)
|
||||
"
|
||||
))
|
||||
.run();
|
||||
}
|
||||
|
||||
#[cargo_test]
|
||||
fn cargo_platform_dev_dependencies2_conflict() {
|
||||
let host = rustc_host();
|
||||
|
@ -1262,7 +1532,7 @@ fn cargo_platform_dev_dependencies2_conflict() {
|
|||
p.cargo("check")
|
||||
.with_stderr_contains(format!(
|
||||
"\
|
||||
[WARNING] unused manifest key `dev_dependencies` in the `{host}` platform target
|
||||
[WARNING] `dev_dependencies` is redundant with `dev-dependencies`, preferring `dev-dependencies` in the `{host}` platform target
|
||||
"
|
||||
))
|
||||
.run();
|
||||
|
@ -1312,6 +1582,57 @@ fn default_features2() {
|
|||
.run();
|
||||
}
|
||||
|
||||
#[cargo_test(nightly, reason = "edition2024 is not stable")]
|
||||
fn default_features2_2024() {
|
||||
let p = project()
|
||||
.file(
|
||||
"Cargo.toml",
|
||||
r#"
|
||||
cargo-features = ["edition2024"]
|
||||
|
||||
[package]
|
||||
name = "foo"
|
||||
version = "0.1.0"
|
||||
edition = "2024"
|
||||
authors = []
|
||||
|
||||
[dependencies]
|
||||
a = { path = "a", features = ["f1"], default_features = false }
|
||||
"#,
|
||||
)
|
||||
.file("src/lib.rs", "")
|
||||
.file(
|
||||
"a/Cargo.toml",
|
||||
r#"
|
||||
[package]
|
||||
name = "a"
|
||||
version = "0.1.0"
|
||||
edition = "2015"
|
||||
authors = []
|
||||
|
||||
[features]
|
||||
default = ["f1"]
|
||||
f1 = []
|
||||
"#,
|
||||
)
|
||||
.file("a/src/lib.rs", "")
|
||||
.build();
|
||||
|
||||
p.cargo("check")
|
||||
.masquerade_as_nightly_cargo(&["edition2024"])
|
||||
.with_status(101)
|
||||
.with_stderr(
|
||||
"\
|
||||
[ERROR] failed to parse manifest at `[CWD]/Cargo.toml`
|
||||
|
||||
Caused by:
|
||||
`default_features` is unsupported as of the 2024 edition; instead use `default-features`
|
||||
(in the `a` dependency)
|
||||
",
|
||||
)
|
||||
.run();
|
||||
}
|
||||
|
||||
#[cargo_test]
|
||||
fn default_features2_conflict() {
|
||||
let p = project()
|
||||
|
@ -1349,7 +1670,182 @@ fn default_features2_conflict() {
|
|||
p.cargo("check")
|
||||
.with_stderr_contains(
|
||||
"\
|
||||
[WARNING] unused manifest key `default_features` in the `a` dependency
|
||||
[WARNING] `default_features` is redundant with `default-features`, preferring `default-features` in the `a` dependency
|
||||
",
|
||||
)
|
||||
.run();
|
||||
}
|
||||
|
||||
#[cargo_test]
|
||||
fn workspace_default_features2() {
|
||||
let p = project()
|
||||
.file(
|
||||
"Cargo.toml",
|
||||
r#"
|
||||
[workspace]
|
||||
members = ["workspace_only", "dep_workspace_only", "package_only", "dep_package_only"]
|
||||
|
||||
[workspace.dependencies]
|
||||
dep_workspace_only = { path = "dep_workspace_only", default_features = true }
|
||||
dep_package_only = { path = "dep_package_only" }
|
||||
"#,
|
||||
)
|
||||
.file(
|
||||
"workspace_only/Cargo.toml",
|
||||
r#"
|
||||
[package]
|
||||
name = "workspace_only"
|
||||
version = "0.1.0"
|
||||
edition = "2015"
|
||||
authors = []
|
||||
|
||||
[dependencies]
|
||||
dep_workspace_only.workspace = true
|
||||
"#,
|
||||
)
|
||||
.file("workspace_only/src/lib.rs", "")
|
||||
.file(
|
||||
"dep_workspace_only/Cargo.toml",
|
||||
r#"
|
||||
[package]
|
||||
name = "dep_workspace_only"
|
||||
version = "0.1.0"
|
||||
edition = "2015"
|
||||
authors = []
|
||||
"#,
|
||||
)
|
||||
.file("dep_workspace_only/src/lib.rs", "")
|
||||
.file(
|
||||
"package_only/Cargo.toml",
|
||||
r#"
|
||||
[package]
|
||||
name = "package_only"
|
||||
version = "0.1.0"
|
||||
edition = "2015"
|
||||
authors = []
|
||||
|
||||
[dependencies]
|
||||
dep_package_only = { workspace = true, default_features = true }
|
||||
"#,
|
||||
)
|
||||
.file("package_only/src/lib.rs", "")
|
||||
.file(
|
||||
"dep_package_only/Cargo.toml",
|
||||
r#"
|
||||
[package]
|
||||
name = "dep_package_only"
|
||||
version = "0.1.0"
|
||||
edition = "2015"
|
||||
authors = []
|
||||
"#,
|
||||
)
|
||||
.file("dep_package_only/src/lib.rs", "")
|
||||
.build();
|
||||
|
||||
p.cargo("check")
|
||||
.with_stderr_unordered(
|
||||
"\
|
||||
warning: [CWD]/workspace_only/Cargo.toml: `default_features` is deprecated in favor of `default-features` and will not work in the 2024 edition
|
||||
(in the `dep_workspace_only` dependency)
|
||||
Locking 4 packages to latest compatible versions
|
||||
Checking dep_package_only v0.1.0 ([CWD]/dep_package_only)
|
||||
Checking dep_workspace_only v0.1.0 ([CWD]/dep_workspace_only)
|
||||
Checking package_only v0.1.0 ([CWD]/package_only)
|
||||
Checking workspace_only v0.1.0 ([CWD]/workspace_only)
|
||||
Finished `dev` profile [unoptimized + debuginfo] target(s) in [..]s
|
||||
"
|
||||
)
|
||||
.run();
|
||||
}
|
||||
|
||||
#[cargo_test(nightly, reason = "edition2024 is not stable")]
|
||||
fn workspace_default_features2_2024() {
|
||||
let p = project()
|
||||
.file(
|
||||
"Cargo.toml",
|
||||
r#"
|
||||
[workspace]
|
||||
members = ["workspace_only", "dep_workspace_only", "package_only", "dep_package_only"]
|
||||
|
||||
[workspace.dependencies]
|
||||
dep_workspace_only = { path = "dep_workspace_only", default_features = true }
|
||||
dep_package_only = { path = "dep_package_only" }
|
||||
"#,
|
||||
)
|
||||
.file(
|
||||
"workspace_only/Cargo.toml",
|
||||
r#"
|
||||
cargo-features = ["edition2024"]
|
||||
|
||||
[package]
|
||||
name = "workspace_only"
|
||||
version = "0.1.0"
|
||||
edition = "2024"
|
||||
authors = []
|
||||
|
||||
[dependencies]
|
||||
dep_workspace_only.workspace = true
|
||||
"#,
|
||||
)
|
||||
.file("workspace_only/src/lib.rs", "")
|
||||
.file(
|
||||
"dep_workspace_only/Cargo.toml",
|
||||
r#"
|
||||
cargo-features = ["edition2024"]
|
||||
|
||||
[package]
|
||||
name = "dep_workspace_only"
|
||||
version = "0.1.0"
|
||||
edition = "2024"
|
||||
authors = []
|
||||
"#,
|
||||
)
|
||||
.file("dep_workspace_only/src/lib.rs", "")
|
||||
.file(
|
||||
"package_only/Cargo.toml",
|
||||
r#"
|
||||
cargo-features = ["edition2024"]
|
||||
|
||||
[package]
|
||||
name = "package_only"
|
||||
version = "0.1.0"
|
||||
edition = "2024"
|
||||
authors = []
|
||||
|
||||
[dependencies]
|
||||
dep_package_only = { workspace = true, default_features = true }
|
||||
"#,
|
||||
)
|
||||
.file("package_only/src/lib.rs", "")
|
||||
.file(
|
||||
"dep_package_only/Cargo.toml",
|
||||
r#"
|
||||
cargo-features = ["edition2024"]
|
||||
|
||||
[package]
|
||||
name = "dep_package_only"
|
||||
version = "0.1.0"
|
||||
edition = "2024"
|
||||
authors = []
|
||||
"#,
|
||||
)
|
||||
.file("dep_package_only/src/lib.rs", "")
|
||||
.build();
|
||||
|
||||
p.cargo("check")
|
||||
.masquerade_as_nightly_cargo(&["edition2024"])
|
||||
.with_status(101)
|
||||
.with_stderr(
|
||||
"\
|
||||
[ERROR] failed to load manifest for workspace member `[CWD]/workspace_only`
|
||||
referenced by workspace at `[CWD]/Cargo.toml`
|
||||
|
||||
Caused by:
|
||||
failed to parse manifest at `[CWD]/workspace_only/Cargo.toml`
|
||||
|
||||
Caused by:
|
||||
`default_features` is unsupported as of the 2024 edition; instead use `default-features`
|
||||
(in the `dep_workspace_only` dependency)
|
||||
",
|
||||
)
|
||||
.run();
|
||||
|
@ -1382,6 +1878,40 @@ fn proc_macro2() {
|
|||
.run();
|
||||
}
|
||||
|
||||
#[cargo_test(nightly, reason = "edition2024 is not stable")]
|
||||
fn proc_macro2_2024() {
|
||||
let foo = project()
|
||||
.file(
|
||||
"Cargo.toml",
|
||||
r#"
|
||||
cargo-features = ["edition2024"]
|
||||
|
||||
[package]
|
||||
name = "foo"
|
||||
version = "0.1.0"
|
||||
edition = "2024"
|
||||
[lib]
|
||||
proc_macro = true
|
||||
"#,
|
||||
)
|
||||
.file("src/lib.rs", "")
|
||||
.build();
|
||||
|
||||
foo.cargo("check")
|
||||
.masquerade_as_nightly_cargo(&["edition2024"])
|
||||
.with_status(101)
|
||||
.with_stderr(
|
||||
"\
|
||||
[ERROR] failed to parse manifest at `[CWD]/Cargo.toml`
|
||||
|
||||
Caused by:
|
||||
`proc_macro` is unsupported as of the 2024 edition; instead use `proc-macro`
|
||||
(in the `foo` library target)
|
||||
",
|
||||
)
|
||||
.run();
|
||||
}
|
||||
|
||||
#[cargo_test]
|
||||
fn proc_macro2_conflict() {
|
||||
let foo = project()
|
||||
|
@ -1403,7 +1933,7 @@ fn proc_macro2_conflict() {
|
|||
foo.cargo("check")
|
||||
.with_stderr_contains(
|
||||
"\
|
||||
[WARNING] unused manifest key `proc_macro` in the `foo` library target
|
||||
[WARNING] `proc_macro` is redundant with `proc-macro`, preferring `proc-macro` in the `foo` library target
|
||||
",
|
||||
)
|
||||
.run();
|
||||
|
|
|
@ -5502,6 +5502,39 @@ for more information about build script outputs.
|
|||
.run();
|
||||
}
|
||||
|
||||
#[cargo_test]
|
||||
fn test_new_syntax_with_compatible_partial_msrv() {
|
||||
let p = project()
|
||||
.file(
|
||||
"Cargo.toml",
|
||||
r#"
|
||||
[package]
|
||||
name = "foo"
|
||||
edition = "2015"
|
||||
build = "build.rs"
|
||||
rust-version = "1.77"
|
||||
"#,
|
||||
)
|
||||
.file("src/lib.rs", "")
|
||||
.file(
|
||||
"build.rs",
|
||||
r#"
|
||||
fn main() {
|
||||
println!("cargo::metadata=foo=bar");
|
||||
}
|
||||
"#,
|
||||
)
|
||||
.build();
|
||||
|
||||
p.cargo("check")
|
||||
.with_stderr_contains(
|
||||
"\
|
||||
[COMPILING] foo [..]
|
||||
",
|
||||
)
|
||||
.run();
|
||||
}
|
||||
|
||||
#[cargo_test]
|
||||
fn test_old_syntax_with_old_msrv() {
|
||||
let p = project()
|
||||
|
|
|
@ -184,12 +184,29 @@ fn symlink_file(target: &Path, link: &Path) -> io::Result<()> {
|
|||
os::windows::fs::symlink_file(target, link)
|
||||
}
|
||||
|
||||
fn symlink_config_to_config_toml() {
|
||||
fn make_config_symlink_to_config_toml_absolute() {
|
||||
let toml_path = paths::root().join(".cargo/config.toml");
|
||||
let symlink_path = paths::root().join(".cargo/config");
|
||||
t!(symlink_file(&toml_path, &symlink_path));
|
||||
}
|
||||
|
||||
fn make_config_symlink_to_config_toml_relative() {
|
||||
let symlink_path = paths::root().join(".cargo/config");
|
||||
t!(symlink_file(Path::new("config.toml"), &symlink_path));
|
||||
}
|
||||
|
||||
fn rename_config_toml_to_config_replacing_with_symlink() {
|
||||
let root = paths::root();
|
||||
t!(fs::rename(
|
||||
root.join(".cargo/config.toml"),
|
||||
root.join(".cargo/config")
|
||||
));
|
||||
t!(symlink_file(
|
||||
Path::new("config"),
|
||||
&root.join(".cargo/config.toml")
|
||||
));
|
||||
}
|
||||
|
||||
#[track_caller]
|
||||
pub fn assert_error<E: Borrow<anyhow::Error>>(error: E, msgs: &str) {
|
||||
let causes = error
|
||||
|
@ -298,7 +315,7 @@ f1 = 1
|
|||
",
|
||||
);
|
||||
|
||||
symlink_config_to_config_toml();
|
||||
make_config_symlink_to_config_toml_absolute();
|
||||
|
||||
let gctx = new_gctx();
|
||||
|
||||
|
@ -309,6 +326,58 @@ f1 = 1
|
|||
assert_match("", &output);
|
||||
}
|
||||
|
||||
#[cargo_test]
|
||||
fn config_ambiguous_filename_symlink_doesnt_warn_relative() {
|
||||
// Windows requires special permissions to create symlinks.
|
||||
// If we don't have permission, just skip this test.
|
||||
if !symlink_supported() {
|
||||
return;
|
||||
};
|
||||
|
||||
write_config_toml(
|
||||
"\
|
||||
[foo]
|
||||
f1 = 1
|
||||
",
|
||||
);
|
||||
|
||||
make_config_symlink_to_config_toml_relative();
|
||||
|
||||
let gctx = new_gctx();
|
||||
|
||||
assert_eq!(gctx.get::<Option<i32>>("foo.f1").unwrap(), Some(1));
|
||||
|
||||
// It should NOT have warned for the symlink.
|
||||
let output = read_output(gctx);
|
||||
assert_match("", &output);
|
||||
}
|
||||
|
||||
#[cargo_test]
|
||||
fn config_ambiguous_filename_symlink_doesnt_warn_backward() {
|
||||
// Windows requires special permissions to create symlinks.
|
||||
// If we don't have permission, just skip this test.
|
||||
if !symlink_supported() {
|
||||
return;
|
||||
};
|
||||
|
||||
write_config_toml(
|
||||
"\
|
||||
[foo]
|
||||
f1 = 1
|
||||
",
|
||||
);
|
||||
|
||||
rename_config_toml_to_config_replacing_with_symlink();
|
||||
|
||||
let gctx = new_gctx();
|
||||
|
||||
assert_eq!(gctx.get::<Option<i32>>("foo.f1").unwrap(), Some(1));
|
||||
|
||||
// It should NOT have warned for this situation.
|
||||
let output = read_output(gctx);
|
||||
assert_match("", &output);
|
||||
}
|
||||
|
||||
#[cargo_test]
|
||||
fn config_ambiguous_filename() {
|
||||
write_config_extless(
|
||||
|
|
|
@ -2050,6 +2050,149 @@ edition = "2021"
|
|||
);
|
||||
}
|
||||
|
||||
#[cargo_test]
|
||||
fn migrate_rename_underscore_fields() {
|
||||
let p = project()
|
||||
.file(
|
||||
"Cargo.toml",
|
||||
r#"
|
||||
cargo-features = ["edition2024"]
|
||||
|
||||
[workspace.dependencies]
|
||||
# Before default_features
|
||||
a = {path = "a", default_features = false} # After default_features value
|
||||
# After default_features line
|
||||
|
||||
[package]
|
||||
name = "foo"
|
||||
edition = "2021"
|
||||
|
||||
[lib]
|
||||
name = "foo"
|
||||
# Before crate_type
|
||||
crate_type = ["staticlib", "dylib"] # After crate_type value
|
||||
# After crate_type line
|
||||
|
||||
[[example]]
|
||||
name = "ex"
|
||||
path = "examples/ex.rs"
|
||||
# Before crate_type
|
||||
crate_type = ["proc-macro"] # After crate_type value
|
||||
# After crate_type line
|
||||
|
||||
# Before dev_dependencies
|
||||
[ dev_dependencies ] # After dev_dependencies header
|
||||
# After dev_dependencies line
|
||||
a = {path = "a", default_features = false}
|
||||
# After dev_dependencies table
|
||||
|
||||
# Before build_dependencies
|
||||
[ build_dependencies ] # After build_dependencies header
|
||||
# After build_dependencies line
|
||||
a = {path = "a", default_features = false}
|
||||
# After build_dependencies table
|
||||
|
||||
# Before dev_dependencies
|
||||
[ target.'cfg(any())'.dev_dependencies ] # After dev_dependencies header
|
||||
# After dev_dependencies line
|
||||
a = {path = "a", default_features = false}
|
||||
# After dev_dependencies table
|
||||
|
||||
# Before build_dependencies
|
||||
[ target.'cfg(any())'.build_dependencies ] # After build_dependencies header
|
||||
# After build_dependencies line
|
||||
a = {path = "a", default_features = false}
|
||||
# After build_dependencies table
|
||||
"#,
|
||||
)
|
||||
.file("src/lib.rs", "")
|
||||
.file(
|
||||
"examples/ex.rs",
|
||||
r#"
|
||||
fn main() { println!("ex"); }
|
||||
"#,
|
||||
)
|
||||
.file(
|
||||
"a/Cargo.toml",
|
||||
r#"
|
||||
[package]
|
||||
name = "a"
|
||||
version = "0.0.1"
|
||||
edition = "2015"
|
||||
"#,
|
||||
)
|
||||
.file("a/src/lib.rs", "")
|
||||
.build();
|
||||
|
||||
p.cargo("fix --edition --allow-no-vcs")
|
||||
.masquerade_as_nightly_cargo(&["edition2024"])
|
||||
.with_stderr(
|
||||
"\
|
||||
[MIGRATING] Cargo.toml from 2021 edition to 2024
|
||||
[FIXED] Cargo.toml (11 fixes)
|
||||
Locking 2 packages to latest compatible versions
|
||||
Checking a v0.0.1 ([CWD]/a)
|
||||
[CHECKING] foo v0.0.0 ([CWD])
|
||||
[MIGRATING] src/lib.rs from 2021 edition to 2024
|
||||
[MIGRATING] examples/ex.rs from 2021 edition to 2024
|
||||
[FINISHED] `dev` profile [unoptimized + debuginfo] target(s) in [..]s
|
||||
",
|
||||
)
|
||||
.run();
|
||||
assert_eq!(
|
||||
p.read_file("Cargo.toml"),
|
||||
r#"
|
||||
cargo-features = ["edition2024"]
|
||||
|
||||
[workspace.dependencies]
|
||||
# Before default_features
|
||||
a = {path = "a", default-features = false} # After default_features value
|
||||
# After default_features line
|
||||
|
||||
[package]
|
||||
name = "foo"
|
||||
edition = "2021"
|
||||
|
||||
[lib]
|
||||
name = "foo"
|
||||
# Before crate_type
|
||||
crate-type = ["staticlib", "dylib"] # After crate_type value
|
||||
# After crate_type line
|
||||
|
||||
[[example]]
|
||||
name = "ex"
|
||||
path = "examples/ex.rs"
|
||||
# Before crate_type
|
||||
crate-type = ["proc-macro"] # After crate_type value
|
||||
# After crate_type line
|
||||
|
||||
# Before dev_dependencies
|
||||
[ dev-dependencies ] # After dev_dependencies header
|
||||
# After dev_dependencies line
|
||||
a = {path = "a", default-features = false}
|
||||
# After dev_dependencies table
|
||||
|
||||
# Before build_dependencies
|
||||
[ build-dependencies ] # After build_dependencies header
|
||||
# After build_dependencies line
|
||||
a = {path = "a", default-features = false}
|
||||
# After build_dependencies table
|
||||
|
||||
# Before dev_dependencies
|
||||
[ target.'cfg(any())'.dev-dependencies ] # After dev_dependencies header
|
||||
# After dev_dependencies line
|
||||
a = {path = "a", default-features = false}
|
||||
# After dev_dependencies table
|
||||
|
||||
# Before build_dependencies
|
||||
[ target.'cfg(any())'.build-dependencies ] # After build_dependencies header
|
||||
# After build_dependencies line
|
||||
a = {path = "a", default-features = false}
|
||||
# After build_dependencies table
|
||||
"#,
|
||||
);
|
||||
}
|
||||
|
||||
#[cargo_test]
|
||||
fn add_feature_for_unused_dep() {
|
||||
Package::new("bar", "0.1.0").publish();
|
||||
|
|
|
@ -30,9 +30,6 @@ fn permit_additional_workspace_fields() {
|
|||
exclude = ["foo.txt"]
|
||||
include = ["bar.txt", "**/*.rs", "Cargo.toml", "LICENSE", "README.md"]
|
||||
|
||||
[workspace.package.badges]
|
||||
gitlab = { repository = "https://gitlab.com/rust-lang/rust", branch = "master" }
|
||||
|
||||
[workspace.dependencies]
|
||||
dep = "0.1"
|
||||
"#,
|
||||
|
@ -117,8 +114,6 @@ fn inherit_own_workspace_fields() {
|
|||
.file(
|
||||
"Cargo.toml",
|
||||
r#"
|
||||
badges.workspace = true
|
||||
|
||||
[package]
|
||||
name = "foo"
|
||||
version.workspace = true
|
||||
|
@ -153,8 +148,6 @@ fn inherit_own_workspace_fields() {
|
|||
rust-version = "1.60"
|
||||
exclude = ["foo.txt"]
|
||||
include = ["bar.txt", "**/*.rs", "Cargo.toml"]
|
||||
[workspace.package.badges]
|
||||
gitlab = { repository = "https://gitlab.com/rust-lang/rust", branch = "master" }
|
||||
"#,
|
||||
)
|
||||
.file("src/main.rs", "fn main() {}")
|
||||
|
@ -186,9 +179,7 @@ You may press ctrl-c to skip waiting; the crate should be available shortly.
|
|||
r#"
|
||||
{
|
||||
"authors": ["Rustaceans"],
|
||||
"badges": {
|
||||
"gitlab": { "branch": "master", "repository": "https://gitlab.com/rust-lang/rust" }
|
||||
},
|
||||
"badges": {},
|
||||
"categories": ["development-tools"],
|
||||
"deps": [],
|
||||
"description": "This is a crate",
|
||||
|
@ -240,10 +231,6 @@ keywords = ["cli"]
|
|||
categories = ["development-tools"]
|
||||
license = "MIT"
|
||||
repository = "https://github.com/example/example"
|
||||
|
||||
[badges.gitlab]
|
||||
branch = "master"
|
||||
repository = "https://gitlab.com/rust-lang/rust"
|
||||
"#,
|
||||
cargo::core::manifest::MANIFEST_PREAMBLE
|
||||
),
|
||||
|
@ -665,15 +652,12 @@ fn inherit_workspace_fields() {
|
|||
rust-version = "1.60"
|
||||
exclude = ["foo.txt"]
|
||||
include = ["bar.txt", "**/*.rs", "Cargo.toml", "LICENSE", "README.md"]
|
||||
[workspace.package.badges]
|
||||
gitlab = { repository = "https://gitlab.com/rust-lang/rust", branch = "master" }
|
||||
"#,
|
||||
)
|
||||
.file("src/main.rs", "fn main() {}")
|
||||
.file(
|
||||
"bar/Cargo.toml",
|
||||
r#"
|
||||
badges.workspace = true
|
||||
[package]
|
||||
name = "bar"
|
||||
workspace = ".."
|
||||
|
@ -731,9 +715,7 @@ You may press ctrl-c to skip waiting; the crate should be available shortly.
|
|||
r#"
|
||||
{
|
||||
"authors": ["Rustaceans"],
|
||||
"badges": {
|
||||
"gitlab": { "branch": "master", "repository": "https://gitlab.com/rust-lang/rust" }
|
||||
},
|
||||
"badges": {},
|
||||
"categories": ["development-tools"],
|
||||
"deps": [],
|
||||
"description": "This is a crate",
|
||||
|
@ -791,10 +773,6 @@ categories = ["development-tools"]
|
|||
license = "MIT"
|
||||
license-file = "LICENSE"
|
||||
repository = "https://github.com/example/example"
|
||||
|
||||
[badges.gitlab]
|
||||
branch = "master"
|
||||
repository = "https://gitlab.com/rust-lang/rust"
|
||||
"#,
|
||||
cargo::core::manifest::MANIFEST_PREAMBLE
|
||||
),
|
||||
|
@ -1715,8 +1693,6 @@ fn warn_inherit_unused_manifest_key_package() {
|
|||
.file(
|
||||
"Cargo.toml",
|
||||
r#"
|
||||
badges = { workspace = true, xyz = "abc"}
|
||||
|
||||
[workspace]
|
||||
members = []
|
||||
[workspace.package]
|
||||
|
@ -1734,8 +1710,6 @@ fn warn_inherit_unused_manifest_key_package() {
|
|||
rust-version = "1.60"
|
||||
exclude = ["foo.txt"]
|
||||
include = ["bar.txt", "**/*.rs", "Cargo.toml"]
|
||||
[workspace.package.badges]
|
||||
gitlab = { repository = "https://gitlab.com/rust-lang/rust", branch = "master" }
|
||||
|
||||
[package]
|
||||
name = "bar"
|
||||
|
|
|
@ -1981,7 +1981,7 @@ fn install_ignores_unstable_table_in_local_cargo_config() {
|
|||
fn install_global_cargo_config() {
|
||||
pkg("bar", "0.0.1");
|
||||
|
||||
let config = cargo_home().join("config");
|
||||
let config = cargo_home().join("config.toml");
|
||||
let mut toml = fs::read_to_string(&config).unwrap_or_default();
|
||||
|
||||
toml.push_str(
|
||||
|
@ -1994,6 +1994,7 @@ fn install_global_cargo_config() {
|
|||
|
||||
cargo_process("install bar")
|
||||
.with_status(101)
|
||||
.with_stderr_contains("[INSTALLING] bar v0.0.1")
|
||||
.with_stderr_contains("[..]--target nonexistent[..]")
|
||||
.run();
|
||||
}
|
||||
|
|
|
@ -33,7 +33,7 @@
|
|||
</tspan>
|
||||
<tspan x="10px" y="118px"><tspan class="fg-bright-blue bold"> |</tspan>
|
||||
</tspan>
|
||||
<tspan x="10px" y="136px"><tspan> </tspan><tspan class="fg-bright-blue bold">=</tspan><tspan> </tspan><tspan class="fg-bright-green bold">note</tspan><tspan>: `cargo::implicit_features` is set to `warn`</tspan>
|
||||
<tspan x="10px" y="136px"><tspan> </tspan><tspan class="fg-bright-blue bold">=</tspan><tspan> </tspan><tspan class="fg-bright-green bold">note</tspan><tspan>: `cargo::implicit_features` is set to `warn` in `[lints]`</tspan>
|
||||
</tspan>
|
||||
<tspan x="10px" y="154px"><tspan class="fg-yellow bold">warning</tspan><tspan>: </tspan><tspan class="bold">implicit features for optional dependencies is deprecated and will be unavailable in the 2024 edition</tspan>
|
||||
</tspan>
|
||||
|
|
Before Width: | Height: | Size: 3.8 KiB After Width: | Height: | Size: 3.8 KiB |
|
@ -20,7 +20,7 @@
|
|||
<text xml:space="preserve" class="container fg">
|
||||
<tspan x="10px" y="28px"><tspan class="fg-green bold"> Updating</tspan><tspan> `dummy-registry` index</tspan>
|
||||
</tspan>
|
||||
<tspan x="10px" y="46px"><tspan class="fg-green bold"> Locking</tspan><tspan> 2 packages to latest compatible versions</tspan>
|
||||
<tspan x="10px" y="46px"><tspan class="fg-green bold"> Locking</tspan><tspan> 2 packages to latest Rust [..] compatible versions</tspan>
|
||||
</tspan>
|
||||
<tspan x="10px" y="64px"><tspan class="fg-green bold"> Checking</tspan><tspan> foo v0.1.0 ([ROOT]/foo)</tspan>
|
||||
</tspan>
|
||||
|
|
Before Width: | Height: | Size: 1.1 KiB After Width: | Height: | Size: 1.1 KiB |
|
@ -33,9 +33,10 @@ target-dep = { version = "0.1.0", optional = true }
|
|||
.build();
|
||||
|
||||
snapbox::cmd::Command::cargo_ui()
|
||||
.masquerade_as_nightly_cargo(&["edition2024"])
|
||||
.masquerade_as_nightly_cargo(&["cargo-lints", "edition2024"])
|
||||
.current_dir(p.root())
|
||||
.arg("check")
|
||||
.arg("-Zcargo-lints")
|
||||
.assert()
|
||||
.success()
|
||||
.stdout_matches(str![""])
|
||||
|
|
|
@ -34,7 +34,7 @@
|
|||
</tspan>
|
||||
<tspan x="10px" y="118px"><tspan class="fg-bright-blue bold"> |</tspan>
|
||||
</tspan>
|
||||
<tspan x="10px" y="136px"><tspan> </tspan><tspan class="fg-bright-blue bold">=</tspan><tspan> </tspan><tspan class="fg-bright-green bold">note</tspan><tspan>: `cargo::unused_optional_dependency` is set to `warn`</tspan>
|
||||
<tspan x="10px" y="136px"><tspan> </tspan><tspan class="fg-bright-blue bold">=</tspan><tspan> </tspan><tspan class="fg-bright-green bold">note</tspan><tspan>: `cargo::unused_optional_dependency` is set to `warn` by default</tspan>
|
||||
</tspan>
|
||||
<tspan x="10px" y="154px"><tspan> </tspan><tspan class="fg-bright-blue bold">=</tspan><tspan> </tspan><tspan class="fg-bright-cyan bold">help</tspan><tspan>: remove the dependency or activate it in a feature with `dep:bar`</tspan>
|
||||
</tspan>
|
||||
|
|
Before Width: | Height: | Size: 4.1 KiB After Width: | Height: | Size: 4.1 KiB |
|
@ -32,9 +32,10 @@ target-dep = { version = "0.1.0", optional = true }
|
|||
.build();
|
||||
|
||||
snapbox::cmd::Command::cargo_ui()
|
||||
.masquerade_as_nightly_cargo(&["edition2024"])
|
||||
.masquerade_as_nightly_cargo(&["cargo-lints", "edition2024"])
|
||||
.current_dir(p.root())
|
||||
.arg("check")
|
||||
.arg("-Zcargo-lints")
|
||||
.assert()
|
||||
.success()
|
||||
.stdout_matches(str![""])
|
||||
|
|
|
@ -34,7 +34,7 @@
|
|||
</tspan>
|
||||
<tspan x="10px" y="118px"><tspan class="fg-bright-blue bold"> |</tspan>
|
||||
</tspan>
|
||||
<tspan x="10px" y="136px"><tspan> </tspan><tspan class="fg-bright-blue bold">=</tspan><tspan> </tspan><tspan class="fg-bright-green bold">note</tspan><tspan>: `cargo::unused_optional_dependency` is set to `warn`</tspan>
|
||||
<tspan x="10px" y="136px"><tspan> </tspan><tspan class="fg-bright-blue bold">=</tspan><tspan> </tspan><tspan class="fg-bright-green bold">note</tspan><tspan>: `cargo::unused_optional_dependency` is set to `warn` by default</tspan>
|
||||
</tspan>
|
||||
<tspan x="10px" y="154px"><tspan> </tspan><tspan class="fg-bright-blue bold">=</tspan><tspan> </tspan><tspan class="fg-bright-cyan bold">help</tspan><tspan>: remove the dependency or activate it in a feature with `dep:bar`</tspan>
|
||||
</tspan>
|
||||
|
|
Before Width: | Height: | Size: 4.1 KiB After Width: | Height: | Size: 4.1 KiB |
|
@ -756,14 +756,14 @@ fn cargo_lints_nightly_required() {
|
|||
.file(
|
||||
"Cargo.toml",
|
||||
r#"
|
||||
[package]
|
||||
name = "foo"
|
||||
version = "0.0.1"
|
||||
edition = "2015"
|
||||
authors = []
|
||||
[package]
|
||||
name = "foo"
|
||||
version = "0.0.1"
|
||||
edition = "2015"
|
||||
authors = []
|
||||
|
||||
[lints.cargo]
|
||||
"unused-features" = "deny"
|
||||
[lints.cargo]
|
||||
im-a-teapot = "warn"
|
||||
"#,
|
||||
)
|
||||
.file("src/lib.rs", "")
|
||||
|
@ -790,21 +790,24 @@ fn cargo_lints_no_z_flag() {
|
|||
.file(
|
||||
"Cargo.toml",
|
||||
r#"
|
||||
[package]
|
||||
name = "foo"
|
||||
version = "0.0.1"
|
||||
edition = "2015"
|
||||
authors = []
|
||||
cargo-features = ["test-dummy-unstable"]
|
||||
|
||||
[lints.cargo]
|
||||
"unused-features" = "deny"
|
||||
[package]
|
||||
name = "foo"
|
||||
version = "0.0.1"
|
||||
edition = "2015"
|
||||
authors = []
|
||||
im-a-teapot = true
|
||||
|
||||
[lints.cargo]
|
||||
im-a-teapot = "warn"
|
||||
"#,
|
||||
)
|
||||
.file("src/lib.rs", "")
|
||||
.build();
|
||||
|
||||
foo.cargo("check")
|
||||
.masquerade_as_nightly_cargo(&["-Zcargo-lints"])
|
||||
.masquerade_as_nightly_cargo(&["cargo-lints", "test-dummy-unstable"])
|
||||
.with_stderr(
|
||||
"\
|
||||
[WARNING] unused manifest key `lints.cargo` (may be supported in a future version)
|
||||
|
@ -819,27 +822,37 @@ consider passing `-Zcargo-lints` to enable this feature.
|
|||
|
||||
#[cargo_test]
|
||||
fn cargo_lints_success() {
|
||||
let foo = project()
|
||||
let p = project()
|
||||
.file(
|
||||
"Cargo.toml",
|
||||
r#"
|
||||
[package]
|
||||
name = "foo"
|
||||
version = "0.0.1"
|
||||
edition = "2015"
|
||||
authors = []
|
||||
cargo-features = ["test-dummy-unstable"]
|
||||
|
||||
[lints.cargo]
|
||||
"unused-features" = "deny"
|
||||
[package]
|
||||
name = "foo"
|
||||
version = "0.0.1"
|
||||
edition = "2015"
|
||||
authors = []
|
||||
im-a-teapot = true
|
||||
|
||||
[lints.cargo]
|
||||
im-a-teapot = "warn"
|
||||
"#,
|
||||
)
|
||||
.file("src/lib.rs", "")
|
||||
.build();
|
||||
|
||||
foo.cargo("check -Zcargo-lints")
|
||||
.masquerade_as_nightly_cargo(&["-Zcargo-lints"])
|
||||
p.cargo("check -Zcargo-lints")
|
||||
.masquerade_as_nightly_cargo(&["cargo-lints", "test-dummy-unstable"])
|
||||
.with_stderr(
|
||||
"\
|
||||
warning: `im_a_teapot` is specified
|
||||
--> Cargo.toml:9:1
|
||||
|
|
||||
9 | im-a-teapot = true
|
||||
| ------------------
|
||||
|
|
||||
= note: `cargo::im_a_teapot` is set to `warn` in `[lints]`
|
||||
[CHECKING] foo v0.0.1 ([CWD])
|
||||
[FINISHED] [..]
|
||||
",
|
||||
|
@ -849,43 +862,163 @@ fn cargo_lints_success() {
|
|||
|
||||
#[cargo_test]
|
||||
fn cargo_lints_underscore_supported() {
|
||||
Package::new("bar", "0.1.0").publish();
|
||||
let foo = project()
|
||||
.file(
|
||||
"Cargo.toml",
|
||||
r#"
|
||||
[package]
|
||||
name = "foo"
|
||||
version = "0.0.1"
|
||||
edition = "2021"
|
||||
authors = []
|
||||
cargo-features = ["test-dummy-unstable"]
|
||||
|
||||
[lints.cargo]
|
||||
"implicit_features" = "warn"
|
||||
[package]
|
||||
name = "foo"
|
||||
version = "0.0.1"
|
||||
edition = "2015"
|
||||
authors = []
|
||||
im-a-teapot = true
|
||||
|
||||
[dependencies]
|
||||
bar = { version = "0.1.0", optional = true }
|
||||
[lints.cargo]
|
||||
im_a_teapot = "warn"
|
||||
"#,
|
||||
)
|
||||
.file("src/lib.rs", "")
|
||||
.build();
|
||||
|
||||
foo.cargo("check -Zcargo-lints")
|
||||
.masquerade_as_nightly_cargo(&["-Zcargo-lints"])
|
||||
.masquerade_as_nightly_cargo(&["cargo-lints", "test-dummy-unstable"])
|
||||
.with_stderr(
|
||||
"\
|
||||
warning: implicit features for optional dependencies is deprecated and will be unavailable in the 2024 edition
|
||||
--> Cargo.toml:12:17
|
||||
|
|
||||
12 | bar = { version = \"0.1.0\", optional = true }
|
||||
| ---
|
||||
|
|
||||
= note: `cargo::implicit_features` is set to `warn`
|
||||
[UPDATING] `dummy-registry` index
|
||||
[LOCKING] [..]
|
||||
warning: `im_a_teapot` is specified
|
||||
--> Cargo.toml:9:1
|
||||
|
|
||||
9 | im-a-teapot = true
|
||||
| ------------------
|
||||
|
|
||||
= note: `cargo::im_a_teapot` is set to `warn` in `[lints]`
|
||||
[CHECKING] foo v0.0.1 ([CWD])
|
||||
[FINISHED] [..]
|
||||
",
|
||||
)
|
||||
.run();
|
||||
}
|
||||
|
||||
#[cargo_test]
|
||||
fn forbid_not_overridden() {
|
||||
let p = project()
|
||||
.file(
|
||||
"Cargo.toml",
|
||||
r#"
|
||||
cargo-features = ["test-dummy-unstable"]
|
||||
|
||||
[package]
|
||||
name = "foo"
|
||||
version = "0.0.1"
|
||||
edition = "2015"
|
||||
authors = []
|
||||
im-a-teapot = true
|
||||
|
||||
[lints.cargo]
|
||||
im-a-teapot = { level = "warn", priority = 10 }
|
||||
test-dummy-unstable = { level = "forbid", priority = -1 }
|
||||
"#,
|
||||
)
|
||||
.file("src/lib.rs", "")
|
||||
.build();
|
||||
|
||||
p.cargo("check -Zcargo-lints")
|
||||
.masquerade_as_nightly_cargo(&["cargo-lints", "test-dummy-unstable"])
|
||||
.with_status(101)
|
||||
.with_stderr(
|
||||
"\
|
||||
error: `im_a_teapot` is specified
|
||||
--> Cargo.toml:9:1
|
||||
|
|
||||
9 | im-a-teapot = true
|
||||
| ^^^^^^^^^^^^^^^^^^
|
||||
|
|
||||
= note: `cargo::im_a_teapot` is set to `forbid` in `[lints]`
|
||||
",
|
||||
)
|
||||
.run();
|
||||
}
|
||||
|
||||
#[cargo_test]
|
||||
fn workspace_cargo_lints() {
|
||||
let p = project()
|
||||
.file(
|
||||
"Cargo.toml",
|
||||
r#"
|
||||
cargo-features = ["test-dummy-unstable"]
|
||||
|
||||
[workspace.lints.cargo]
|
||||
im-a-teapot = { level = "warn", priority = 10 }
|
||||
test-dummy-unstable = { level = "forbid", priority = -1 }
|
||||
|
||||
[package]
|
||||
name = "foo"
|
||||
version = "0.0.1"
|
||||
edition = "2015"
|
||||
authors = []
|
||||
im-a-teapot = true
|
||||
|
||||
[lints]
|
||||
workspace = true
|
||||
"#,
|
||||
)
|
||||
.file("src/lib.rs", "")
|
||||
.build();
|
||||
|
||||
p.cargo("check -Zcargo-lints")
|
||||
.masquerade_as_nightly_cargo(&["cargo-lints", "test-dummy-unstable"])
|
||||
.with_status(101)
|
||||
.with_stderr(
|
||||
"\
|
||||
error: `im_a_teapot` is specified
|
||||
--> Cargo.toml:13:1
|
||||
|
|
||||
13 | im-a-teapot = true
|
||||
| ^^^^^^^^^^^^^^^^^^
|
||||
|
|
||||
= note: `cargo::im_a_teapot` is set to `forbid` in `[workspace.lints]`
|
||||
",
|
||||
)
|
||||
.run();
|
||||
}
|
||||
|
||||
#[cargo_test]
|
||||
fn dont_always_inherit_workspace_lints() {
|
||||
let p = project()
|
||||
.file(
|
||||
"Cargo.toml",
|
||||
r#"
|
||||
[workspace]
|
||||
members = ["foo"]
|
||||
|
||||
[workspace.lints.cargo]
|
||||
im-a-teapot = "warn"
|
||||
"#,
|
||||
)
|
||||
.file(
|
||||
"foo/Cargo.toml",
|
||||
r#"
|
||||
cargo-features = ["test-dummy-unstable"]
|
||||
|
||||
[package]
|
||||
name = "foo"
|
||||
version = "0.0.1"
|
||||
edition = "2015"
|
||||
authors = []
|
||||
im-a-teapot = true
|
||||
"#,
|
||||
)
|
||||
.file("foo/src/lib.rs", "")
|
||||
.build();
|
||||
|
||||
p.cargo("check -Zcargo-lints")
|
||||
.masquerade_as_nightly_cargo(&["cargo-lints"])
|
||||
.with_stderr(
|
||||
"\
|
||||
[CHECKING] foo v0.0.1 ([CWD]/foo)
|
||||
[FINISHED] [..]
|
||||
",
|
||||
)
|
||||
.run();
|
||||
}
|
||||
|
|
|
@ -613,6 +613,117 @@ foo v0.0.1 ([CWD])
|
|||
.run();
|
||||
}
|
||||
|
||||
#[cargo_test(nightly, reason = "edition2024 in rustc is unstable")]
|
||||
fn resolve_edition2024() {
|
||||
Package::new("only-newer", "1.6.0")
|
||||
.rust_version("1.65.0")
|
||||
.file("src/lib.rs", "fn other_stuff() {}")
|
||||
.publish();
|
||||
Package::new("newer-and-older", "1.5.0")
|
||||
.rust_version("1.55.0")
|
||||
.file("src/lib.rs", "fn other_stuff() {}")
|
||||
.publish();
|
||||
Package::new("newer-and-older", "1.6.0")
|
||||
.rust_version("1.65.0")
|
||||
.file("src/lib.rs", "fn other_stuff() {}")
|
||||
.publish();
|
||||
|
||||
let p = project()
|
||||
.file(
|
||||
"Cargo.toml",
|
||||
r#"
|
||||
cargo-features = ["edition2024"]
|
||||
|
||||
[package]
|
||||
name = "foo"
|
||||
version = "0.0.1"
|
||||
edition = "2024"
|
||||
authors = []
|
||||
rust-version = "1.60.0"
|
||||
|
||||
[dependencies]
|
||||
only-newer = "1.0.0"
|
||||
newer-and-older = "1.0.0"
|
||||
"#,
|
||||
)
|
||||
.file("src/main.rs", "fn main(){}")
|
||||
.build();
|
||||
|
||||
// Edition2024 should resolve for MSRV
|
||||
p.cargo("generate-lockfile")
|
||||
.arg("-Zmsrv-policy")
|
||||
.masquerade_as_nightly_cargo(&["edition2024", "msrv-policy"])
|
||||
.with_stderr(
|
||||
"\
|
||||
[UPDATING] `dummy-registry` index
|
||||
[LOCKING] 3 packages to latest Rust 1.60.0 compatible versions
|
||||
[ADDING] newer-and-older v1.5.0 (latest: v1.6.0)
|
||||
",
|
||||
)
|
||||
.run();
|
||||
p.cargo("tree")
|
||||
.arg("-Zmsrv-policy")
|
||||
.masquerade_as_nightly_cargo(&["edition2024", "msrv-policy"])
|
||||
.with_stdout(
|
||||
"\
|
||||
foo v0.0.1 ([CWD])
|
||||
├── newer-and-older v1.5.0
|
||||
└── only-newer v1.6.0
|
||||
",
|
||||
)
|
||||
.run();
|
||||
|
||||
// `--ignore-rust-version` has precedence over Edition2024
|
||||
p.cargo("generate-lockfile --ignore-rust-version")
|
||||
.with_stderr(
|
||||
"\
|
||||
[UPDATING] `dummy-registry` index
|
||||
[LOCKING] 3 packages to latest compatible versions
|
||||
",
|
||||
)
|
||||
.arg("-Zmsrv-policy")
|
||||
.masquerade_as_nightly_cargo(&["msrv-policy"])
|
||||
.run();
|
||||
p.cargo("tree")
|
||||
.arg("-Zmsrv-policy")
|
||||
.masquerade_as_nightly_cargo(&["edition2024", "msrv-policy"])
|
||||
.with_stdout(
|
||||
"\
|
||||
foo v0.0.1 ([CWD])
|
||||
├── newer-and-older v1.6.0
|
||||
└── only-newer v1.6.0
|
||||
",
|
||||
)
|
||||
.run();
|
||||
|
||||
// config has precedence over Edition2024
|
||||
p.cargo("generate-lockfile")
|
||||
.env(
|
||||
"CARGO_RESOLVER_SOMETHING_LIKE_PRECEDENCE",
|
||||
"something-like-maximum",
|
||||
)
|
||||
.with_stderr(
|
||||
"\
|
||||
[UPDATING] `dummy-registry` index
|
||||
[LOCKING] 3 packages to latest compatible versions
|
||||
",
|
||||
)
|
||||
.arg("-Zmsrv-policy")
|
||||
.masquerade_as_nightly_cargo(&["msrv-policy"])
|
||||
.run();
|
||||
p.cargo("tree")
|
||||
.arg("-Zmsrv-policy")
|
||||
.masquerade_as_nightly_cargo(&["edition2024", "msrv-policy"])
|
||||
.with_stdout(
|
||||
"\
|
||||
foo v0.0.1 ([CWD])
|
||||
├── newer-and-older v1.6.0
|
||||
└── only-newer v1.6.0
|
||||
",
|
||||
)
|
||||
.run();
|
||||
}
|
||||
|
||||
#[cargo_test(nightly, reason = "edition2024 in rustc is unstable")]
|
||||
fn resolve_v3() {
|
||||
Package::new("only-newer", "1.6.0")
|
||||
|
@ -1035,11 +1146,10 @@ fn cargo_install_ignores_msrv_config() {
|
|||
[DOWNLOADING] crates ...
|
||||
[DOWNLOADED] foo v0.0.1 (registry [..])
|
||||
[INSTALLING] foo v0.0.1
|
||||
[LOCKING] 2 packages to latest Rust 1.60 compatible versions
|
||||
[ADDING] dep v1.0.0 (latest: v1.1.0)
|
||||
[LOCKING] 2 packages to latest compatible versions
|
||||
[DOWNLOADING] crates ...
|
||||
[DOWNLOADED] dep v1.0.0 (registry [..])
|
||||
[COMPILING] dep v1.0.0
|
||||
[DOWNLOADED] dep v1.1.0 (registry [..])
|
||||
[COMPILING] dep v1.1.0
|
||||
[COMPILING] foo v0.0.1
|
||||
[FINISHED] `release` profile [optimized] target(s) in [..]
|
||||
[INSTALLING] [CWD]/home/.cargo/bin/foo[EXE]
|
||||
|
|