Skip to content

Commit 51dc5db

Browse files
committed
Reserve some names for named profiles.
Just to give a little flexibility in the future in case we want to use these, or that they could cause confusion. Also updated the error text a little.
1 parent 090eb42 commit 51dc5db

File tree

4 files changed

+254
-97
lines changed

4 files changed

+254
-97
lines changed

src/cargo/util/command_prelude.rs

Lines changed: 54 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -343,13 +343,7 @@ pub trait ArgMatchesExt {
343343
default: &str,
344344
profile_checking: ProfileChecking,
345345
) -> CargoResult<InternedString> {
346-
let specified_profile = match self._value_of("profile") {
347-
None => None,
348-
Some(name) => {
349-
TomlProfile::validate_name(name, "profile name")?;
350-
Some(InternedString::new(name))
351-
}
352-
};
346+
let specified_profile = self._value_of("profile");
353347

354348
match profile_checking {
355349
ProfileChecking::Unchecked => {}
@@ -360,31 +354,62 @@ pub trait ArgMatchesExt {
360354
}
361355
}
362356

363-
if self._is_present("release") {
364-
if !config.cli_unstable().unstable_options {
365-
Ok(InternedString::new("release"))
366-
} else {
367-
match specified_profile {
368-
Some(name) if name != "release" => {
369-
anyhow::bail!("Conflicting usage of --profile and --release")
370-
}
371-
_ => Ok(InternedString::new("release")),
357+
let conflict = |flag: &str, equiv: &str, specified: &str| -> anyhow::Error {
358+
anyhow::format_err!(
359+
"conflicting usage of --profile={} and --{flag}\n\
360+
The `--{flag}` flag is the same as `--profile={equiv}`.\n\
361+
Remove one flag or the other to continue.",
362+
specified,
363+
flag = flag,
364+
equiv = equiv
365+
)
366+
};
367+
368+
let name = match (
369+
self._is_present("release"),
370+
self._is_present("debug"),
371+
specified_profile,
372+
) {
373+
(false, false, None) => default,
374+
// `check` is separate from all other reservations because
375+
// `--profile=check` has been stable for the `cargo rustc` command
376+
// for a long time. The Unchecked commands (check, fix, rustc)
377+
// have their own validation.
378+
//
379+
// This is explicitly ordered before the --release conflict check
380+
// since `cargo rustc --profile=check --release` means to check in
381+
// release mode.
382+
//
383+
// When stabilizing, only `cargo rustc` should be allowed to use
384+
// `check` with the old semantics.
385+
(_, _, Some(name @ ("test" | "bench" | "check"))) => match profile_checking {
386+
ProfileChecking::Unchecked => name,
387+
ProfileChecking::Checked => {
388+
bail!(
389+
"profile `{}` is reserved and not allowed to be explicitly specified",
390+
name
391+
)
372392
}
393+
},
394+
(true, _, None | Some("release")) => "release",
395+
(true, _, Some(name)) => return Err(conflict("release", "release", name)),
396+
(_, true, None | Some("dev")) => "dev",
397+
(_, true, Some(name)) => return Err(conflict("debug", "dev", name)),
398+
// `doc` is separate from all the other reservations because
399+
// [profile.doc] was historically allowed, but is deprecated and
400+
// has no effect. To avoid potentially breaking projects, it is a
401+
// warning, but since `--profile` is new, we can reject it
402+
// completely here.
403+
(_, _, Some("doc")) => {
404+
bail!("profile `doc` is reserved and not allowed to be explicitly specified")
373405
}
374-
} else if self._is_present("debug") {
375-
if !config.cli_unstable().unstable_options {
376-
Ok(InternedString::new("dev"))
377-
} else {
378-
match specified_profile {
379-
Some(name) if name != "dev" => {
380-
anyhow::bail!("Conflicting usage of --profile and --debug")
381-
}
382-
_ => Ok(InternedString::new("dev")),
383-
}
406+
(_, _, Some(name)) => {
407+
TomlProfile::validate_name(name)?;
408+
name
384409
}
385-
} else {
386-
Ok(specified_profile.unwrap_or_else(|| InternedString::new(default)))
387-
}
410+
};
411+
412+
Ok(InternedString::new(name))
388413
}
389414

390415
fn packages_from_flags(&self) -> CargoResult<Packages> {

src/cargo/util/toml/mod.rs

Lines changed: 72 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -489,10 +489,6 @@ impl TomlProfile {
489489
features: &Features,
490490
warnings: &mut Vec<String>,
491491
) -> CargoResult<()> {
492-
if name == "debug" {
493-
warnings.push("use `[profile.dev]` to configure debug builds".to_string());
494-
}
495-
496492
if let Some(ref profile) = self.build_override {
497493
features.require(Feature::profile_overrides())?;
498494
profile.validate_override("build-override")?;
@@ -513,7 +509,7 @@ impl TomlProfile {
513509
}
514510

515511
// Profile name validation
516-
Self::validate_name(name, "profile name")?;
512+
Self::validate_name(name)?;
517513

518514
// Feature gate on uses of keys related to named profiles
519515
if self.inherits.is_some() {
@@ -533,11 +529,12 @@ impl TomlProfile {
533529
}
534530

535531
// `inherits` validation
536-
match &self.inherits {
537-
None => {}
538-
Some(inherits) => {
539-
Self::validate_name(inherits, "inherits")?;
540-
}
532+
if matches!(self.inherits.map(|s| s.as_str()), Some("debug")) {
533+
bail!(
534+
"profile.{}.inherits=\"debug\" should be profile.{}.inherits=\"dev\"",
535+
name,
536+
name
537+
);
541538
}
542539

543540
match name {
@@ -569,29 +566,77 @@ impl TomlProfile {
569566
}
570567

571568
/// Validate dir-names and profile names according to RFC 2678.
572-
pub fn validate_name(name: &str, what: &str) -> CargoResult<()> {
569+
pub fn validate_name(name: &str) -> CargoResult<()> {
573570
if let Some(ch) = name
574571
.chars()
575572
.find(|ch| !ch.is_alphanumeric() && *ch != '_' && *ch != '-')
576573
{
577-
bail!("Invalid character `{}` in {}: `{}`", ch, what, name);
574+
bail!(
575+
"invalid character `{}` in profile name `{}`\n\
576+
Allowed characters are letters, numbers, underscore, and hyphen.",
577+
ch,
578+
name
579+
);
578580
}
579581

580-
match name {
581-
"package" | "build" => {
582-
bail!("Invalid {}: `{}`", what, name);
583-
}
584-
"debug" if what == "profile" => {
585-
if what == "profile name" {
586-
// Allowed, but will emit warnings
587-
} else {
588-
bail!("Invalid {}: `{}`", what, name);
589-
}
590-
}
591-
"doc" if what == "dir-name" => {
592-
bail!("Invalid {}: `{}`", what, name);
593-
}
594-
_ => {}
582+
const SEE_DOCS: &str = "See https://doc.rust-lang.org/cargo/reference/profiles.html \
583+
for more on configuring profiles.";
584+
585+
let lower_name = name.to_lowercase();
586+
if lower_name == "debug" {
587+
bail!(
588+
"profile name `{}` is reserved\n\
589+
To configure the default development profile, use the name `dev` \
590+
as in [profile.dev]\n\
591+
{}",
592+
name,
593+
SEE_DOCS
594+
);
595+
}
596+
if lower_name == "build-override" {
597+
bail!(
598+
"profile name `{}` is reserved\n\
599+
To configure build dependency settings, use [profile.dev.build-override] \
600+
and [profile.release.build-override]\n\
601+
{}",
602+
name,
603+
SEE_DOCS
604+
);
605+
}
606+
607+
// These are some arbitrary reservations. We have no plans to use
608+
// these, but it seems safer to reserve a few just in case we want to
609+
// add more built-in profiles in the future. We can also uses special
610+
// syntax like cargo:foo if needed. But it is unlikely these will ever
611+
// be used.
612+
if matches!(
613+
lower_name.as_str(),
614+
"build"
615+
| "check"
616+
| "clean"
617+
| "config"
618+
| "fetch"
619+
| "fix"
620+
| "install"
621+
| "metadata"
622+
| "package"
623+
| "publish"
624+
| "report"
625+
| "root"
626+
| "run"
627+
| "rust"
628+
| "rustc"
629+
| "rustdoc"
630+
| "uninstall"
631+
) || lower_name.starts_with("cargo")
632+
{
633+
bail!(
634+
"profile name `{}` is reserved\n\
635+
Please choose a different name.\n\
636+
{}",
637+
name,
638+
SEE_DOCS
639+
);
595640
}
596641

597642
Ok(())

tests/testsuite/bad_config.rs

Lines changed: 0 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -665,39 +665,6 @@ warning: unused manifest key: target.foo.bar
665665
)
666666
.run();
667667

668-
let p = project()
669-
.file(
670-
"Cargo.toml",
671-
r#"
672-
cargo-features = ["named-profiles"]
673-
674-
[package]
675-
name = "foo"
676-
version = "0.1.0"
677-
authors = []
678-
679-
[profile.debug]
680-
debug = 1
681-
inherits = "dev"
682-
"#,
683-
)
684-
.file("src/lib.rs", "")
685-
.build();
686-
687-
p.cargo("build -Z named-profiles")
688-
.masquerade_as_nightly_cargo()
689-
.with_stderr(
690-
"\
691-
warning: use `[profile.dev]` to configure debug builds
692-
[..]
693-
[..]",
694-
)
695-
.run();
696-
697-
p.cargo("build -Z named-profiles")
698-
.masquerade_as_nightly_cargo()
699-
.run();
700-
701668
let p = project()
702669
.file(
703670
"Cargo.toml",

0 commit comments

Comments
 (0)