Skip to content

Commit 4e143fd

Browse files
committed
Auto merge of #9685 - ehuss:named-profile-updates, r=alexcrichton
Named profile updates A few updates for named profiles to push them closer to stabilization: - Disable the `dir-name` profile setting. `dir-name` primarily exists for translating the built-in profiles or sharing artifacts between profiles. In order to simplify the UI, we would like to not expose it to the user for the initial stabilization. The code to support it is kept in case we want to add it in the future. - Reserve some profile names. 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. - Add support for custom profiles to legacy commands. Their old behavior is still retained for backwards compatibility. That is: * `cargo check` * `--profile=test`: This forces the test mode. For example, `cargo check --lib --profile=test` will check the library as a unit test (with `--test`). * `cargo fix` * `--profile=test`: Forces test mode, same as above. * `cargo rustc` * `--profile=test`: Forces test mode, same as above. * `--profile=bench`: Forces bench mode. * `--profile=check`: Forces check mode. - These commands also allow mixing the above options with `--release`, which is normally not allowed. - Fix `cargo bench` to support the `--profile` option. I think it was just forgotten.
2 parents adde602 + 73dba76 commit 4e143fd

File tree

16 files changed

+380
-173
lines changed

16 files changed

+380
-173
lines changed

src/bin/cargo/commands/bench.rs

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,7 @@ pub fn cli() -> App {
3535
"Exclude packages from the benchmark",
3636
)
3737
.arg_jobs()
38+
.arg_profile("Build artifacts with the specified profile")
3839
.arg_features()
3940
.arg_target_triple("Build for the target triple")
4041
.arg_target_dir()
@@ -55,11 +56,11 @@ pub fn exec(config: &mut Config, args: &ArgMatches<'_>) -> CliResult {
5556
config,
5657
CompileMode::Bench,
5758
Some(&ws),
58-
ProfileChecking::Checked,
59+
ProfileChecking::Custom,
5960
)?;
6061

6162
compile_opts.build_config.requested_profile =
62-
args.get_profile_name(config, "bench", ProfileChecking::Checked)?;
63+
args.get_profile_name(config, "bench", ProfileChecking::Custom)?;
6364

6465
let ops = TestOptions {
6566
no_run: args.is_present("no-run"),

src/bin/cargo/commands/build.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -53,7 +53,7 @@ pub fn exec(config: &mut Config, args: &ArgMatches<'_>) -> CliResult {
5353
config,
5454
CompileMode::Build,
5555
Some(&ws),
56-
ProfileChecking::Checked,
56+
ProfileChecking::Custom,
5757
)?;
5858

5959
if let Some(out_dir) = args.value_of_path("out-dir", config) {

src/bin/cargo/commands/check.rs

Lines changed: 4 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -41,20 +41,11 @@ pub fn cli() -> App {
4141

4242
pub fn exec(config: &mut Config, args: &ArgMatches<'_>) -> CliResult {
4343
let ws = args.workspace(config)?;
44-
let test = match args.value_of("profile") {
45-
Some("test") => true,
46-
None => false,
47-
Some(profile) => {
48-
let err = anyhow::format_err!(
49-
"unknown profile: `{}`, only `test` is \
50-
currently supported",
51-
profile
52-
);
53-
return Err(CliError::new(err, 101));
54-
}
55-
};
44+
// This is a legacy behavior that causes `cargo check` to pass `--test`.
45+
let test = matches!(args.value_of("profile"), Some("test"));
5646
let mode = CompileMode::Check { test };
57-
let compile_opts = args.compile_options(config, mode, Some(&ws), ProfileChecking::Unchecked)?;
47+
let compile_opts =
48+
args.compile_options(config, mode, Some(&ws), ProfileChecking::LegacyTestOnly)?;
5849

5950
ops::compile(&ws, &compile_opts)?;
6051
Ok(())

src/bin/cargo/commands/clean.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@ pub fn exec(config: &mut Config, args: &ArgMatches<'_>) -> CliResult {
2828
config,
2929
spec: values(args, "package"),
3030
targets: args.targets(),
31-
requested_profile: args.get_profile_name(config, "dev", ProfileChecking::Checked)?,
31+
requested_profile: args.get_profile_name(config, "dev", ProfileChecking::Custom)?,
3232
profile_specified: args.is_present("profile") || args.is_present("release"),
3333
doc: args.is_present("doc"),
3434
};

src/bin/cargo/commands/doc.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,7 @@ pub fn exec(config: &mut Config, args: &ArgMatches<'_>) -> CliResult {
4343
deps: !args.is_present("no-deps"),
4444
};
4545
let mut compile_opts =
46-
args.compile_options(config, mode, Some(&ws), ProfileChecking::Checked)?;
46+
args.compile_options(config, mode, Some(&ws), ProfileChecking::Custom)?;
4747
compile_opts.rustdoc_document_private_items = args.is_present("document-private-items");
4848

4949
let doc_opts = DocOptions {

src/bin/cargo/commands/fix.rs

Lines changed: 4 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -67,23 +67,14 @@ pub fn cli() -> App {
6767

6868
pub fn exec(config: &mut Config, args: &ArgMatches<'_>) -> CliResult {
6969
let ws = args.workspace(config)?;
70-
let test = match args.value_of("profile") {
71-
Some("test") => true,
72-
None => false,
73-
Some(profile) => {
74-
let err = anyhow::format_err!(
75-
"unknown profile: `{}`, only `test` is \
76-
currently supported",
77-
profile
78-
);
79-
return Err(CliError::new(err, 101));
80-
}
81-
};
70+
// This is a legacy behavior that causes `cargo fix` to pass `--test`.
71+
let test = matches!(args.value_of("profile"), Some("test"));
8272
let mode = CompileMode::Check { test };
8373

8474
// Unlike other commands default `cargo fix` to all targets to fix as much
8575
// code as we can.
86-
let mut opts = args.compile_options(config, mode, Some(&ws), ProfileChecking::Unchecked)?;
76+
let mut opts =
77+
args.compile_options(config, mode, Some(&ws), ProfileChecking::LegacyTestOnly)?;
8778

8879
if let CompileFilter::Default { .. } = opts.filter {
8980
opts.filter = CompileFilter::Only {

src/bin/cargo/commands/install.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -131,11 +131,11 @@ pub fn exec(config: &mut Config, args: &ArgMatches<'_>) -> CliResult {
131131
config,
132132
CompileMode::Build,
133133
workspace.as_ref(),
134-
ProfileChecking::Checked,
134+
ProfileChecking::Custom,
135135
)?;
136136

137137
compile_opts.build_config.requested_profile =
138-
args.get_profile_name(config, "release", ProfileChecking::Checked)?;
138+
args.get_profile_name(config, "release", ProfileChecking::Custom)?;
139139

140140
if args.is_present("list") {
141141
ops::install_list(root, config)?;

src/bin/cargo/commands/run.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,7 @@ pub fn exec(config: &mut Config, args: &ArgMatches<'_>) -> CliResult {
3737
config,
3838
CompileMode::Build,
3939
Some(&ws),
40-
ProfileChecking::Checked,
40+
ProfileChecking::Custom,
4141
)?;
4242

4343
// Disallow `spec` to be an glob pattern

src/bin/cargo/commands/rustc.rs

Lines changed: 9 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
use crate::command_prelude::*;
2-
32
use cargo::ops;
3+
use cargo::util::interning::InternedString;
44

55
const PRINT_ARG_NAME: &str = "print";
66

@@ -46,26 +46,24 @@ pub fn cli() -> App {
4646

4747
pub fn exec(config: &mut Config, args: &ArgMatches<'_>) -> CliResult {
4848
let ws = args.workspace(config)?;
49+
// This is a legacy behavior that changes the behavior based on the profile.
50+
// If we want to support this more formally, I think adding a --mode flag
51+
// would be warranted.
4952
let mode = match args.value_of("profile") {
50-
Some("dev") | None => CompileMode::Build,
5153
Some("test") => CompileMode::Test,
5254
Some("bench") => CompileMode::Bench,
5355
Some("check") => CompileMode::Check { test: false },
54-
Some(mode) => {
55-
let err = anyhow::format_err!(
56-
"unknown profile: `{}`, use dev,
57-
test, or bench",
58-
mode
59-
);
60-
return Err(CliError::new(err, 101));
61-
}
56+
_ => CompileMode::Build,
6257
};
6358
let mut compile_opts = args.compile_options_for_single_package(
6459
config,
6560
mode,
6661
Some(&ws),
67-
ProfileChecking::Unchecked,
62+
ProfileChecking::LegacyRustc,
6863
)?;
64+
if compile_opts.build_config.requested_profile == "check" {
65+
compile_opts.build_config.requested_profile = InternedString::new("dev");
66+
}
6967
let target_args = values(args, "args");
7068
compile_opts.target_rustc_args = if target_args.is_empty() {
7169
None

src/bin/cargo/commands/rustdoc.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,7 @@ pub fn exec(config: &mut Config, args: &ArgMatches<'_>) -> CliResult {
4444
config,
4545
CompileMode::Doc { deps: false },
4646
Some(&ws),
47-
ProfileChecking::Checked,
47+
ProfileChecking::Custom,
4848
)?;
4949
let target_args = values(args, "args");
5050
compile_opts.target_rustdoc_args = if target_args.is_empty() {

src/bin/cargo/commands/test.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -66,11 +66,11 @@ pub fn exec(config: &mut Config, args: &ArgMatches<'_>) -> CliResult {
6666
config,
6767
CompileMode::Test,
6868
Some(&ws),
69-
ProfileChecking::Checked,
69+
ProfileChecking::Custom,
7070
)?;
7171

7272
compile_opts.build_config.requested_profile =
73-
args.get_profile_name(config, "test", ProfileChecking::Checked)?;
73+
args.get_profile_name(config, "test", ProfileChecking::Custom)?;
7474

7575
// `TESTNAME` is actually an argument of the test binary, but it's
7676
// important, so we explicitly mention it and reconfigure.

src/cargo/core/profiles.rs

Lines changed: 0 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -133,7 +133,6 @@ impl Profiles {
133133
fn predefined_dir_names() -> HashMap<InternedString, InternedString> {
134134
let mut dir_names = HashMap::new();
135135
dir_names.insert(InternedString::new("dev"), InternedString::new("debug"));
136-
dir_names.insert(InternedString::new("check"), InternedString::new("debug"));
137136
dir_names.insert(InternedString::new("test"), InternedString::new("debug"));
138137
dir_names.insert(InternedString::new("bench"), InternedString::new("release"));
139138
dir_names
@@ -174,13 +173,6 @@ impl Profiles {
174173
..TomlProfile::default()
175174
},
176175
),
177-
(
178-
"check",
179-
TomlProfile {
180-
inherits: Some(InternedString::new("dev")),
181-
..TomlProfile::default()
182-
},
183-
),
184176
(
185177
"doc",
186178
TomlProfile {

src/cargo/util/command_prelude.rs

Lines changed: 55 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -281,8 +281,14 @@ pub fn subcommand(name: &'static str) -> App {
281281

282282
// Determines whether or not to gate `--profile` as unstable when resolving it.
283283
pub enum ProfileChecking {
284-
Checked,
285-
Unchecked,
284+
// `cargo rustc` historically has allowed "test", "bench", and "check". This
285+
// variant explicitly allows those.
286+
LegacyRustc,
287+
// `cargo check` and `cargo fix` historically has allowed "test". This variant
288+
// explicitly allows that on stable.
289+
LegacyTestOnly,
290+
// All other commands, which allow any valid custom named profile.
291+
Custom,
286292
}
287293

288294
pub trait ArgMatchesExt {
@@ -343,48 +349,58 @@ pub trait ArgMatchesExt {
343349
default: &str,
344350
profile_checking: ProfileChecking,
345351
) -> 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-
};
352+
let specified_profile = self._value_of("profile");
353+
354+
// Check for allowed legacy names.
355+
// This is an early exit, since it allows combination with `--release`.
356+
match (specified_profile, profile_checking) {
357+
// `cargo rustc` has legacy handling of these names
358+
(Some(name @ ("test" | "bench" | "check")), ProfileChecking::LegacyRustc) |
359+
// `cargo fix` and `cargo check` has legacy handling of this profile name
360+
(Some(name @ "test"), ProfileChecking::LegacyTestOnly) => return Ok(InternedString::new(name)),
361+
_ => {}
362+
}
353363

354-
match profile_checking {
355-
ProfileChecking::Unchecked => {}
356-
ProfileChecking::Checked => {
357-
if specified_profile.is_some() && !config.cli_unstable().unstable_options {
358-
anyhow::bail!("Usage of `--profile` requires `-Z unstable-options`")
359-
}
360-
}
364+
if specified_profile.is_some() && !config.cli_unstable().unstable_options {
365+
bail!("usage of `--profile` requires `-Z unstable-options`");
361366
}
362367

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")),
372-
}
368+
let conflict = |flag: &str, equiv: &str, specified: &str| -> anyhow::Error {
369+
anyhow::format_err!(
370+
"conflicting usage of --profile={} and --{flag}\n\
371+
The `--{flag}` flag is the same as `--profile={equiv}`.\n\
372+
Remove one flag or the other to continue.",
373+
specified,
374+
flag = flag,
375+
equiv = equiv
376+
)
377+
};
378+
379+
let name = match (
380+
self._is_present("release"),
381+
self._is_present("debug"),
382+
specified_profile,
383+
) {
384+
(false, false, None) => default,
385+
(true, _, None | Some("release")) => "release",
386+
(true, _, Some(name)) => return Err(conflict("release", "release", name)),
387+
(_, true, None | Some("dev")) => "dev",
388+
(_, true, Some(name)) => return Err(conflict("debug", "dev", name)),
389+
// `doc` is separate from all the other reservations because
390+
// [profile.doc] was historically allowed, but is deprecated and
391+
// has no effect. To avoid potentially breaking projects, it is a
392+
// warning in Cargo.toml, but since `--profile` is new, we can
393+
// reject it completely here.
394+
(_, _, Some("doc")) => {
395+
bail!("profile `doc` is reserved and not allowed to be explicitly specified")
373396
}
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-
}
397+
(_, _, Some(name)) => {
398+
TomlProfile::validate_name(name)?;
399+
name
384400
}
385-
} else {
386-
Ok(specified_profile.unwrap_or_else(|| InternedString::new(default)))
387-
}
401+
};
402+
403+
Ok(InternedString::new(name))
388404
}
389405

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

0 commit comments

Comments
 (0)