Auto merge of #7823 - ehuss:stabilize-config-profile, r=alexcrichton

Stabilize config-profile.

This is a proposal to stabilize config-profiles. This feature was proposed in [RFC 2282](https://github.com/rust-lang/rfcs/pull/2282) and implemented in #5506. Tracking issue is rust-lang/rust#48683.

This is intended to land in 1.43 which will reach the stable channel on April 23rd.

This is a fairly straightforward extension of profiles where the exact same syntax from `Cargo.toml` can be specified in a config file. Environment variables are supported for everything except the `package` override table, where we do not support the ability to read arbitrary keys in the environment name.
This commit is contained in:
bors 2020-01-31 11:50:31 +00:00
commit f9132126af
8 changed files with 142 additions and 86 deletions

View File

@ -36,7 +36,6 @@ Available unstable (nightly-only) flags:
-Z minimal-versions -- Install minimal dependency versions instead of maximum -Z minimal-versions -- Install minimal dependency versions instead of maximum
-Z no-index-update -- Do not update the registry, avoids a network request for benchmarking -Z no-index-update -- Do not update the registry, avoids a network request for benchmarking
-Z unstable-options -- Allow the usage of unstable options -Z unstable-options -- Allow the usage of unstable options
-Z config-profile -- Read profiles from .cargo/config files
-Z timings -- Display concurrency information -Z timings -- Display concurrency information
-Z doctest-xcompile -- Compile and run doctests for non-host target using runner config -Z doctest-xcompile -- Compile and run doctests for non-host target using runner config

View File

@ -331,7 +331,6 @@ pub struct CliUnstable {
pub minimal_versions: bool, pub minimal_versions: bool,
pub package_features: bool, pub package_features: bool,
pub advanced_env: bool, pub advanced_env: bool,
pub config_profile: bool,
pub config_include: bool, pub config_include: bool,
pub dual_proc_macros: bool, pub dual_proc_macros: bool,
pub mtime_on_use: bool, pub mtime_on_use: bool,
@ -397,7 +396,6 @@ impl CliUnstable {
"minimal-versions" => self.minimal_versions = parse_empty(k, v)?, "minimal-versions" => self.minimal_versions = parse_empty(k, v)?,
"package-features" => self.package_features = parse_empty(k, v)?, "package-features" => self.package_features = parse_empty(k, v)?,
"advanced-env" => self.advanced_env = parse_empty(k, v)?, "advanced-env" => self.advanced_env = parse_empty(k, v)?,
"config-profile" => self.config_profile = parse_empty(k, v)?,
"config-include" => self.config_include = parse_empty(k, v)?, "config-include" => self.config_include = parse_empty(k, v)?,
"dual-proc-macros" => self.dual_proc_macros = parse_empty(k, v)?, "dual-proc-macros" => self.dual_proc_macros = parse_empty(k, v)?,
// can also be set in .cargo/config or with and ENV // can also be set in .cargo/config or with and ENV

View File

@ -908,13 +908,9 @@ fn merge_config_profiles(
}; };
// List of profile names to check if defined in config only. // List of profile names to check if defined in config only.
let mut check_to_add = vec![requested_profile]; let mut check_to_add = vec![requested_profile];
// Flag so -Zconfig-profile warning is only printed once.
let mut unstable_warned = false;
// Merge config onto manifest profiles. // Merge config onto manifest profiles.
for (name, profile) in &mut profiles { for (name, profile) in &mut profiles {
if let Some(config_profile) = if let Some(config_profile) = get_config_profile(name, config, features)? {
get_config_profile(name, config, features, &mut unstable_warned)?
{
profile.merge(&config_profile); profile.merge(&config_profile);
} }
if let Some(inherits) = &profile.inherits { if let Some(inherits) = &profile.inherits {
@ -928,9 +924,7 @@ fn merge_config_profiles(
std::mem::swap(&mut current, &mut check_to_add); std::mem::swap(&mut current, &mut check_to_add);
for name in current.drain(..) { for name in current.drain(..) {
if !profiles.contains_key(&name) { if !profiles.contains_key(&name) {
if let Some(config_profile) = if let Some(config_profile) = get_config_profile(&name, config, features)? {
get_config_profile(&name, config, features, &mut unstable_warned)?
{
if let Some(inherits) = &config_profile.inherits { if let Some(inherits) = &config_profile.inherits {
check_to_add.push(*inherits); check_to_add.push(*inherits);
} }
@ -947,20 +941,12 @@ fn get_config_profile(
name: &str, name: &str,
config: &Config, config: &Config,
features: &Features, features: &Features,
unstable_warned: &mut bool,
) -> CargoResult<Option<TomlProfile>> { ) -> CargoResult<Option<TomlProfile>> {
let profile: Option<config::Value<TomlProfile>> = config.get(&format!("profile.{}", name))?; let profile: Option<config::Value<TomlProfile>> = config.get(&format!("profile.{}", name))?;
let profile = match profile { let profile = match profile {
Some(profile) => profile, Some(profile) => profile,
None => return Ok(None), None => return Ok(None),
}; };
if !*unstable_warned && !config.cli_unstable().config_profile {
config.shell().warn(format!(
"config profiles require the `-Z config-profile` command-line option (found profile `{}` in {})",
name, profile.definition))?;
*unstable_warned = true;
return Ok(None);
}
let mut warnings = Vec::new(); let mut warnings = Vec::new();
profile profile
.val .val

View File

@ -87,6 +87,21 @@ retry = 2 # network retries
git-fetch-with-cli = true # use the `git` executable for git operations git-fetch-with-cli = true # use the `git` executable for git operations
offline = false # do not access the network offline = false # do not access the network
[profile.<name>] # Modify profile settings via config.
opt-level = 0 # Optimization level.
debug = true # Include debug info.
debug-assertions = true # Enables debug assertions.
overflow-checks = true # Enables runtime integer overflow checks.
lto = false # Sets link-time optimization.
panic = 'unwind' # The panic strategy.
incremental = true # Incremental compilation.
codegen-units = 16 # Number of code generation units.
rpath = false # Sets the rpath linking option.
[profile.<name>.build-override] # Overrides build-script settings.
# Same keys for a normal profile.
[profile.<name>.package.<name>] # Override profile for a package.
# Same keys for a normal profile (minus `panic`, `lto`, and `rpath`).
[registries.<name>] # registries other than crates.io [registries.<name>] # registries other than crates.io
index = "…" # URL of the registry index index = "…" # URL of the registry index
token = "…" # authentication token for the registry token = "…" # authentication token for the registry
@ -549,6 +564,93 @@ needed, and generate an error if it encounters a network error.
Can be overridden with the `--offline` command-line option. Can be overridden with the `--offline` command-line option.
#### `[profile]`
The `[profile]` table can be used to globally change profile settings, and
override settings specified in `Cargo.toml`. It has the same syntax and
options as profiles specified in `Cargo.toml`. See the [Profiles chapter] for
details about the options.
[Profiles chapter]: profiles.md
##### `[profile.<name>.build-override]`
* Environment: `CARGO_PROFILE_<name>_BUILD_OVERRIDE_<key>`
The build-override table overrides settings for build scripts, proc macros,
and their dependencies. It has the same keys as a normal profile. See the
[overrides section](profiles.md#overrides) for more details.
##### `[profile.<name>.package.<name>]`
* Environment: not supported
The package table overrides settings for specific packages. It has the same
keys as a normal profile, minus the `panic`, `lto`, and `rpath` settings. See
the [overrides section](profiles.md#overrides) for more details.
##### `profile.<name>.codegen-units`
* Type: integer
* Default: See profile docs.
* Environment: `CARGO_PROFILE_<name>_CODEGEN_UNITS`
See [codegen-units](profiles.md#codegen-units).
##### `profile.<name>.debug`
* Type: integer or boolean
* Default: See profile docs.
* Environment: `CARGO_PROFILE_<name>_DEBUG`
See [debug](profiles.md#debug).
##### `profile.<name>.debug-assertions`
* Type: boolean
* Default: See profile docs.
* Environment: `CARGO_PROFILE_<name>_DEBUG_ASSERTIONS`
See [debug-assertions](profiles.md#debug-assertions).
##### `profile.<name>.incremental`
* Type: boolean
* Default: See profile docs.
* Environment: `CARGO_PROFILE_<name>_INCREMENTAL`
See [incremental](profiles.md#incremental).
##### `profile.<name>.lto`
* Type: string or boolean
* Default: See profile docs.
* Environment: `CARGO_PROFILE_<name>_LTO`
See [lto](profiles.md#lto).
##### `profile.<name>.overflow-checks`
* Type: boolean
* Default: See profile docs.
* Environment: `CARGO_PROFILE_<name>_OVERFLOW_CHECKS`
See [overflow-checks](profiles.md#overflow-checks).
##### `profile.<name>.opt-level`
* Type: integer or string
* Default: See profile docs.
* Environment: `CARGO_PROFILE_<name>_OPT_LEVEL`
See [opt-level](profiles.md#opt-level).
##### `profile.<name>.panic`
* Type: string
* default: See profile docs.
* Environment: `CARGO_PROFILE_<name>_PANIC`
See [panic](profiles.md#panic).
##### `profile.<name>.rpath`
* Type: boolean
* default: See profile docs.
* Environment: `CARGO_PROFILE_<name>_RPATH`
See [rpath](profiles.md#rpath).
#### `[registries]` #### `[registries]`
The `[registries]` table is used for specifying additional [registries]. It The `[registries]` table is used for specifying additional [registries]. It

View File

@ -84,6 +84,16 @@ supported environment variables are:
* `CARGO_NET_RETRY` — Number of times to retry network errors, see [`net.retry`]. * `CARGO_NET_RETRY` — Number of times to retry network errors, see [`net.retry`].
* `CARGO_NET_GIT_FETCH_WITH_CLI` — Enables the use of the `git` executable to fetch, see [`net.git-fetch-with-cli`]. * `CARGO_NET_GIT_FETCH_WITH_CLI` — Enables the use of the `git` executable to fetch, see [`net.git-fetch-with-cli`].
* `CARGO_NET_OFFLINE` — Offline mode, see [`net.offline`]. * `CARGO_NET_OFFLINE` — Offline mode, see [`net.offline`].
* `CARGO_PROFILE_<name>_BUILD_OVERRIDE_<key>` Override build script profile, see [`profile.<name>.build-override`].
* `CARGO_PROFILE_<name>_CODEGEN_UNITS` Set code generation units, see [`profile.<name>.codegen-units`].
* `CARGO_PROFILE_<name>_DEBUG` What kind of debug info to include, see [`profile.<name>.debug`].
* `CARGO_PROFILE_<name>_DEBUG_ASSERTIONS` — Enable/disable debug assertions, see [`profile.<name>.debug-assertions`].
* `CARGO_PROFILE_<name>_INCREMENTAL` Enable/disable incremental compilation, see [`profile.<name>.incremental`].
* `CARGO_PROFILE_<name>_LTO` Link-time optimization, see [`profile.<name>.lto`].
* `CARGO_PROFILE_<name>_OVERFLOW_CHECKS` Enable/disable overflow checks, see [`profile.<name>.overflow-checks`].
* `CARGO_PROFILE_<name>_OPT_LEVEL` Set the optimization level, see [`profile.<name>.opt-level`].
* `CARGO_PROFILE_<name>_PANIC` The panic strategy to use, see [`profile.<name>.panic`].
* `CARGO_PROFILE_<name>_RPATH` The rpath linking option, see [`profile.<name>.rpath`].
* `CARGO_REGISTRIES_<name>_INDEX` — URL of a registry index, see [`registries.<name>.index`]. * `CARGO_REGISTRIES_<name>_INDEX` — URL of a registry index, see [`registries.<name>.index`].
* `CARGO_REGISTRIES_<name>_TOKEN` — Authentication token of a registry, see [`registries.<name>.token`]. * `CARGO_REGISTRIES_<name>_TOKEN` — Authentication token of a registry, see [`registries.<name>.token`].
* `CARGO_REGISTRY_DEFAULT` — Default registry for the `--registry` flag, see [`registry.default`]. * `CARGO_REGISTRY_DEFAULT` — Default registry for the `--registry` flag, see [`registry.default`].
@ -129,6 +139,16 @@ supported environment variables are:
[`net.retry`]: config.md#netretry [`net.retry`]: config.md#netretry
[`net.git-fetch-with-cli`]: config.md#netgit-fetch-with-cli [`net.git-fetch-with-cli`]: config.md#netgit-fetch-with-cli
[`net.offline`]: config.md#netoffline [`net.offline`]: config.md#netoffline
[`profile.<name>.build-override`]: config.md#profilenamebuild-override
[`profile.<name>.codegen-units`]: config.md#profilenamecodegen-units
[`profile.<name>.debug`]: config.md#profilenamedebug
[`profile.<name>.debug-assertions`]: config.md#profilenamedebug-assertions
[`profile.<name>.incremental`]: config.md#profilenameincremental
[`profile.<name>.lto`]: config.md#profilenamelto
[`profile.<name>.overflow-checks`]: config.md#profilenameoverflow-checks
[`profile.<name>.opt-level`]: config.md#profilenameopt-level
[`profile.<name>.panic`]: config.md#profilenamepanic
[`profile.<name>.rpath`]: config.md#profilenamerpath
[`registries.<name>.index`]: config.md#registriesnameindex [`registries.<name>.index`]: config.md#registriesnameindex
[`registries.<name>.token`]: config.md#registriesnametoken [`registries.<name>.token`]: config.md#registriesnametoken
[`registry.default`]: config.md#registrydefault [`registry.default`]: config.md#registrydefault

View File

@ -22,6 +22,12 @@ Cargo only looks at the profile settings in the `Cargo.toml` manifest at the
root of the workspace. Profile settings defined in dependencies will be root of the workspace. Profile settings defined in dependencies will be
ignored. ignored.
Additionally, profiles can be overridden from a [config] definition.
Specifying a profile in a config file or environment variable will override
the settings from `Cargo.toml`.
[config]: config.md
### Profile settings ### Profile settings
The following is a list of settings that can be controlled in a profile. The following is a list of settings that can be controlled in a profile.
@ -393,5 +399,4 @@ crates. When experimenting with optimizing dependencies for development,
consider trying opt-level 1, which will apply some optimizations while still consider trying opt-level 1, which will apply some optimizations while still
allowing monomorphized items to be shared. allowing monomorphized items to be shared.
[nalgebra]: https://crates.io/crates/nalgebra [nalgebra]: https://crates.io/crates/nalgebra

View File

@ -158,26 +158,6 @@ lto = true
``` ```
### Config Profiles
* Tracking Issue: [rust-lang/rust#48683](https://github.com/rust-lang/rust/issues/48683)
* RFC: [#2282](https://github.com/rust-lang/rfcs/blob/master/text/2282-profile-dependencies.md)
Profiles can be specified in `.cargo/config` files. The `-Z config-profile`
command-line flag is required to use this feature. The format is the same as
in a `Cargo.toml` manifest. If found in multiple config files, settings will
be merged using the regular [config hierarchy](config.md#hierarchical-structure).
Config settings take precedence over manifest settings.
```toml
[profile.dev]
opt-level = 3
```
```
cargo +nightly build -Z config-profile
```
### Namespaced features ### Namespaced features
* Original issue: [#1286](https://github.com/rust-lang/cargo/issues/1286) * Original issue: [#1286](https://github.com/rust-lang/cargo/issues/1286)
* Tracking Issue: [#5565](https://github.com/rust-lang/cargo/issues/5565) * Tracking Issue: [#5565](https://github.com/rust-lang/cargo/issues/5565)

View File

@ -3,31 +3,6 @@
use cargo_test_support::paths::CargoPathExt; use cargo_test_support::paths::CargoPathExt;
use cargo_test_support::{basic_lib_manifest, paths, project}; use cargo_test_support::{basic_lib_manifest, paths, project};
#[cargo_test]
fn profile_config_gated() {
let p = project()
.file("Cargo.toml", &basic_lib_manifest("foo"))
.file("src/lib.rs", "")
.file(
".cargo/config",
r#"
[profile.dev]
debug = 1
"#,
)
.build();
p.cargo("build -v")
.with_stderr_contains(
"\
[WARNING] config profiles require the `-Z config-profile` command-line option \
(found profile `dev` in [..]/foo/.cargo/config)
",
)
.with_stderr_contains("[..]-C debuginfo=2[..]")
.run();
}
#[cargo_test] #[cargo_test]
fn named_profile_gated() { fn named_profile_gated() {
// Named profile in config requires enabling in Cargo.toml. // Named profile in config requires enabling in Cargo.toml.
@ -42,7 +17,7 @@ fn named_profile_gated() {
"#, "#,
) )
.build(); .build();
p.cargo("build --profile foo -Zunstable-options -Zconfig-profile") p.cargo("build --profile foo -Zunstable-options")
.masquerade_as_nightly_cargo() .masquerade_as_nightly_cargo()
.with_stderr( .with_stderr(
"\ "\
@ -84,8 +59,7 @@ fn profile_config_validate_warnings() {
) )
.build(); .build();
p.cargo("build -Z config-profile") p.cargo("build")
.masquerade_as_nightly_cargo()
.with_stderr_unordered( .with_stderr_unordered(
"\ "\
[WARNING] unused config key `profile.dev.bad-key` in `[..].cargo/config` [WARNING] unused config key `profile.dev.bad-key` in `[..].cargo/config`
@ -120,8 +94,7 @@ fn profile_config_error_paths() {
) )
.build(); .build();
p.cargo("build -Z config-profile") p.cargo("build")
.masquerade_as_nightly_cargo()
.with_status(101) .with_status(101)
.with_stderr( .with_stderr(
"\ "\
@ -148,8 +121,7 @@ fn profile_config_validate_errors() {
) )
.build(); .build();
p.cargo("build -Z config-profile") p.cargo("build")
.masquerade_as_nightly_cargo()
.with_status(101) .with_status(101)
.with_stderr( .with_stderr(
"\ "\
@ -176,8 +148,7 @@ fn profile_config_syntax_errors() {
) )
.build(); .build();
p.cargo("build -Z config-profile") p.cargo("build")
.masquerade_as_nightly_cargo()
.with_status(101) .with_status(101)
.with_stderr( .with_stderr(
"\ "\
@ -221,8 +192,7 @@ fn profile_config_override_spec_multiple() {
// Unfortunately this doesn't tell you which file, hopefully it's not too // Unfortunately this doesn't tell you which file, hopefully it's not too
// much of a problem. // much of a problem.
p.cargo("build -v -Z config-profile") p.cargo("build -v")
.masquerade_as_nightly_cargo()
.with_status(101) .with_status(101)
.with_stderr( .with_stderr(
"\ "\
@ -254,8 +224,7 @@ fn profile_config_all_options() {
) )
.build(); .build();
p.cargo("build --release -v -Z config-profile") p.cargo("build --release -v")
.masquerade_as_nightly_cargo()
.env_remove("CARGO_INCREMENTAL") .env_remove("CARGO_INCREMENTAL")
.with_stderr( .with_stderr(
"\ "\
@ -309,8 +278,7 @@ fn profile_config_override_precedence() {
) )
.build(); .build();
p.cargo("build -v -Z config-profile") p.cargo("build -v")
.masquerade_as_nightly_cargo()
.with_stderr( .with_stderr(
"\ "\
[COMPILING] bar [..] [COMPILING] bar [..]
@ -336,8 +304,7 @@ fn profile_config_no_warn_unknown_override() {
) )
.build(); .build();
p.cargo("build -Z config-profile") p.cargo("build")
.masquerade_as_nightly_cargo()
.with_stderr_does_not_contain("[..]warning[..]") .with_stderr_does_not_contain("[..]warning[..]")
.run(); .run();
} }
@ -363,8 +330,7 @@ fn profile_config_mixed_types() {
) )
.build(); .build();
p.cargo("build -v -Z config-profile") p.cargo("build -v")
.masquerade_as_nightly_cargo()
.with_stderr_contains("[..]-C opt-level=3 [..]") .with_stderr_contains("[..]-C opt-level=3 [..]")
.run(); .run();
} }
@ -406,7 +372,7 @@ fn named_config_profile() {
"#, "#,
) )
.unwrap(); .unwrap();
let config = ConfigBuilder::new().unstable_flag("config-profile").build(); let config = ConfigBuilder::new().build();
let mut warnings = Vec::new(); let mut warnings = Vec::new();
let features = Features::new(&["named-profiles".to_string()], &mut warnings).unwrap(); let features = Features::new(&["named-profiles".to_string()], &mut warnings).unwrap();
assert_eq!(warnings.len(), 0); assert_eq!(warnings.len(), 0);
@ -481,7 +447,7 @@ fn named_env_profile() {
.file("src/lib.rs", "") .file("src/lib.rs", "")
.build(); .build();
p.cargo("build -v -Zconfig-profile -Zunstable-options --profile=other") p.cargo("build -v -Zunstable-options --profile=other")
.masquerade_as_nightly_cargo() .masquerade_as_nightly_cargo()
.env("CARGO_PROFILE_OTHER_CODEGEN_UNITS", "1") .env("CARGO_PROFILE_OTHER_CODEGEN_UNITS", "1")
.env("CARGO_PROFILE_OTHER_INHERITS", "dev") .env("CARGO_PROFILE_OTHER_INHERITS", "dev")