Skip to content

Commit

Permalink
feat(metadata): Add profiles information to cargo metadata
Browse files Browse the repository at this point in the history
This change adds profile information to the output of `cargo metadata`. I opted for serializing this information only when there is information present to minimize changes in the output.

Signed-off-by: David Calavera <david.calavera@gmail.com>
  • Loading branch information
calavera committed Aug 5, 2023
1 parent f761921 commit 18c4f98
Show file tree
Hide file tree
Showing 5 changed files with 282 additions and 3 deletions.
4 changes: 4 additions & 0 deletions src/cargo/core/package.rs
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ use crate::util::network::http::http_handle_and_timeout;
use crate::util::network::http::HttpTimeout;
use crate::util::network::retry::{Retry, RetryResult};
use crate::util::network::sleep::SleepTracker;
use crate::util::toml::TomlProfiles;
use crate::util::{self, internal, Config, Progress, ProgressStyle};

pub const MANIFEST_PREAMBLE: &str = "\
Expand Down Expand Up @@ -104,6 +105,8 @@ pub struct SerializedPackage {
metabuild: Option<Vec<String>>,
default_run: Option<String>,
rust_version: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
profiles: Option<TomlProfiles>,
}

impl Package {
Expand Down Expand Up @@ -263,6 +266,7 @@ impl Package {
publish: self.publish().as_ref().cloned(),
default_run: self.manifest().default_run().map(|s| s.to_owned()),
rust_version: self.rust_version().map(|s| s.to_owned()),
profiles: self.manifest().profiles().cloned(),
}
}
}
Expand Down
11 changes: 10 additions & 1 deletion src/cargo/ops/cargo_output_metadata.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,10 @@ use crate::core::compiler::{CompileKind, RustcTargetData};
use crate::core::dependency::DepKind;
use crate::core::package::SerializedPackage;
use crate::core::resolver::{features::CliFeatures, HasDevUnits, Resolve};
use crate::core::{Package, PackageId, Workspace};
use crate::core::{MaybePackage, Package, PackageId, Workspace};
use crate::ops::{self, Packages};
use crate::util::interning::InternedString;
use crate::util::toml::TomlProfiles;
use crate::util::CargoResult;
use cargo_platform::Platform;
use serde::Serialize;
Expand Down Expand Up @@ -40,6 +41,11 @@ pub fn output_metadata(ws: &Workspace<'_>, opt: &OutputMetadataOptions) -> Cargo
(packages, Some(resolve))
};

let workspace_profiles = match ws.root_maybe() {
MaybePackage::Virtual(vm) => vm.profiles().cloned(),
_ => None, // regular packages include the profile information under their package section
};

Ok(ExportInfo {
packages,
workspace_members: ws.members().map(|pkg| pkg.package_id()).collect(),
Expand All @@ -49,6 +55,7 @@ pub fn output_metadata(ws: &Workspace<'_>, opt: &OutputMetadataOptions) -> Cargo
version: VERSION,
workspace_root: ws.root().to_path_buf(),
metadata: ws.custom_metadata().cloned(),
workspace_profiles,
})
}

Expand All @@ -65,6 +72,8 @@ pub struct ExportInfo {
version: u32,
workspace_root: PathBuf,
metadata: Option<toml::Value>,
#[serde(skip_serializing_if = "Option::is_none")]
workspace_profiles: Option<TomlProfiles>,
}

#[derive(Serialize)]
Expand Down
17 changes: 17 additions & 0 deletions src/cargo/util/toml/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -564,25 +564,42 @@ impl Display for TomlDebugInfo {
#[derive(Deserialize, Serialize, Clone, Debug, Default, Eq, PartialEq)]
#[serde(default, rename_all = "kebab-case")]
pub struct TomlProfile {
#[serde(skip_serializing_if = "Option::is_none")]
pub opt_level: Option<TomlOptLevel>,
#[serde(skip_serializing_if = "Option::is_none")]
pub lto: Option<StringOrBool>,
#[serde(skip_serializing_if = "Option::is_none")]
pub codegen_backend: Option<InternedString>,
#[serde(skip_serializing_if = "Option::is_none")]
pub codegen_units: Option<u32>,
#[serde(skip_serializing_if = "Option::is_none")]
pub debug: Option<TomlDebugInfo>,
#[serde(skip_serializing_if = "Option::is_none")]
pub split_debuginfo: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub debug_assertions: Option<bool>,
#[serde(skip_serializing_if = "Option::is_none")]
pub rpath: Option<bool>,
#[serde(skip_serializing_if = "Option::is_none")]
pub panic: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub overflow_checks: Option<bool>,
#[serde(skip_serializing_if = "Option::is_none")]
pub incremental: Option<bool>,
#[serde(skip_serializing_if = "Option::is_none")]
pub dir_name: Option<InternedString>,
#[serde(skip_serializing_if = "Option::is_none")]
pub inherits: Option<InternedString>,
#[serde(skip_serializing_if = "Option::is_none")]
pub strip: Option<StringOrBool>,
// Note that `rustflags` is used for the cargo-feature `profile_rustflags`
#[serde(skip_serializing_if = "Option::is_none")]
pub rustflags: Option<Vec<InternedString>>,
// These two fields must be last because they are sub-tables, and TOML
// requires all non-tables to be listed first.
#[serde(skip_serializing_if = "Option::is_none")]
pub package: Option<BTreeMap<ProfilePackageSpec, TomlProfile>>,
#[serde(skip_serializing_if = "Option::is_none")]
pub build_override: Option<Box<TomlProfile>>,
}

Expand Down
239 changes: 239 additions & 0 deletions tests/testsuite/metadata.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4248,3 +4248,242 @@ fn workspace_metadata_with_dependencies_no_deps_artifact() {
)
.run();
}

#[cargo_test]
fn library_metadata_with_profiles() {
let p = project()
.file("src/lib.rs", "")
.file(
"Cargo.toml",
r#"
[package]
name = "foo"
version = "0.5.0"
[profile.release]
strip = "symbols"
[profile.custom-lto]
lto = "thin"
"#,
)
.build();

p.cargo("metadata")
.with_json(
r#"
{
"packages": [
{
"authors": [],
"categories": [],
"default_run": null,
"name": "foo",
"readme": null,
"repository": null,
"homepage": null,
"documentation": null,
"version": "0.5.0",
"rust_version": null,
"id": "foo[..]",
"keywords": [],
"source": null,
"dependencies": [],
"edition": "2015",
"license": null,
"license_file": null,
"links": null,
"description": null,
"targets": [
{
"kind": [
"lib"
],
"crate_types": [
"lib"
],
"doc": true,
"doctest": true,
"test": true,
"edition": "2015",
"name": "foo",
"src_path": "[..]/foo/src/lib.rs"
}
],
"features": {},
"manifest_path": "[..]Cargo.toml",
"metadata": null,
"publish": null,
"profiles": {
"custom-lto": {
"lto": "thin"
},
"release": {
"strip": "symbols"
}
}
}
],
"workspace_members": ["foo 0.5.0 (path+file:[..]foo)"],
"workspace_default_members": ["foo 0.5.0 (path+file:[..]foo)"],
"resolve": {
"nodes": [
{
"dependencies": [],
"deps": [],
"features": [],
"id": "foo 0.5.0 (path+file:[..]foo)"
}
],
"root": "foo 0.5.0 (path+file:[..]foo)"
},
"target_directory": "[..]foo/target",
"version": 1,
"workspace_root": "[..]/foo",
"metadata": null
}"#,
)
.run();
}

#[cargo_test]
fn workspace_metadata_with_profiles() {
let p = project()
.file(
"Cargo.toml",
r#"
[workspace]
members = ["bar", "baz"]
[profile.release]
strip = "symbols"
[profile.custom-lto]
lto = "thin"
"#,
)
.file("bar/Cargo.toml", &basic_lib_manifest("bar"))
.file("bar/src/lib.rs", "")
.file("baz/Cargo.toml", &basic_lib_manifest("baz"))
.file("baz/src/lib.rs", "")
.build();

p.cargo("metadata")
.with_json(
r#"
{
"packages": [
{
"authors": [
"wycats@example.com"
],
"categories": [],
"default_run": null,
"name": "bar",
"version": "0.5.0",
"id": "bar[..]",
"readme": null,
"repository": null,
"rust_version": null,
"homepage": null,
"documentation": null,
"keywords": [],
"source": null,
"dependencies": [],
"license": null,
"license_file": null,
"links": null,
"description": null,
"edition": "2015",
"targets": [
{
"kind": [ "lib" ],
"crate_types": [ "lib" ],
"doc": true,
"doctest": true,
"test": true,
"edition": "2015",
"name": "bar",
"src_path": "[..]bar/src/lib.rs"
}
],
"features": {},
"manifest_path": "[..]bar/Cargo.toml",
"metadata": null,
"publish": null
},
{
"authors": [
"wycats@example.com"
],
"categories": [],
"default_run": null,
"name": "baz",
"readme": null,
"repository": null,
"rust_version": null,
"homepage": null,
"documentation": null,
"version": "0.5.0",
"id": "baz[..]",
"keywords": [],
"source": null,
"dependencies": [],
"license": null,
"license_file": null,
"links": null,
"description": null,
"edition": "2015",
"targets": [
{
"kind": [ "lib" ],
"crate_types": [ "lib" ],
"doc": true,
"doctest": true,
"test": true,
"edition": "2015",
"name": "baz",
"src_path": "[..]baz/src/lib.rs"
}
],
"features": {},
"manifest_path": "[..]baz/Cargo.toml",
"metadata": null,
"publish": null
}
],
"workspace_members": ["bar 0.5.0 (path+file:[..]bar)", "baz 0.5.0 (path+file:[..]baz)"],
"workspace_default_members": ["bar 0.5.0 (path+file:[..]bar)", "baz 0.5.0 (path+file:[..]baz)"],
"resolve": {
"nodes": [
{
"dependencies": [],
"deps": [],
"features": [],
"id": "bar 0.5.0 (path+file:[..]bar)"
},
{
"dependencies": [],
"deps": [],
"features": [],
"id": "baz 0.5.0 (path+file:[..]baz)"
}
],
"root": null
},
"target_directory": "[..]foo/target",
"version": 1,
"workspace_root": "[..]/foo",
"metadata": null,
"workspace_profiles": {
"custom-lto": {
"lto": "thin"
},
"release": {
"strip": "symbols"
}
}
}"#,
)
.run();
}
14 changes: 12 additions & 2 deletions tests/testsuite/script.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1061,7 +1061,12 @@ fn cmd_metadata_with_embedded() {
"features": {},
"manifest_path": "[..]script.rs",
"metadata": null,
"publish": []
"publish": [],
"profiles": {
"release": {
"strip": true
}
}
}
],
"workspace_members": ["script 0.0.0 (path+file:[..]foo)"],
Expand Down Expand Up @@ -1136,7 +1141,12 @@ fn cmd_read_manifest_with_embedded() {
"features":{},
"manifest_path":"[..]script.rs",
"metadata": null,
"publish": []
"publish": [],
"profiles": {
"release": {
"strip": true
}
}
}"#,
)
.with_stderr(
Expand Down

0 comments on commit 18c4f98

Please sign in to comment.