Skip to content

Commit 08b44bf

Browse files
committed
feat(metadata): Add profiles information to cargo metadata
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>
1 parent bfb0d19 commit 08b44bf

File tree

4 files changed

+270
-1
lines changed

4 files changed

+270
-1
lines changed

src/cargo/core/package.rs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@ use crate::util::network::http::http_handle_and_timeout;
3131
use crate::util::network::http::HttpTimeout;
3232
use crate::util::network::retry::{Retry, RetryResult};
3333
use crate::util::network::sleep::SleepTracker;
34+
use crate::util::toml::TomlProfiles;
3435
use crate::util::{self, internal, Config, Progress, ProgressStyle};
3536

3637
pub const MANIFEST_PREAMBLE: &str = "\
@@ -104,6 +105,8 @@ pub struct SerializedPackage {
104105
metabuild: Option<Vec<String>>,
105106
default_run: Option<String>,
106107
rust_version: Option<String>,
108+
#[serde(skip_serializing_if = "Option::is_none")]
109+
profiles: Option<TomlProfiles>,
107110
}
108111

109112
impl Package {
@@ -263,6 +266,7 @@ impl Package {
263266
publish: self.publish().as_ref().cloned(),
264267
default_run: self.manifest().default_run().map(|s| s.to_owned()),
265268
rust_version: self.rust_version().map(|s| s.to_owned()),
269+
profiles: self.manifest().profiles().cloned(),
266270
}
267271
}
268272
}

src/cargo/ops/cargo_output_metadata.rs

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,9 +3,10 @@ use crate::core::compiler::{CompileKind, RustcTargetData};
33
use crate::core::dependency::DepKind;
44
use crate::core::package::SerializedPackage;
55
use crate::core::resolver::{features::CliFeatures, HasDevUnits, Resolve};
6-
use crate::core::{Package, PackageId, Workspace};
6+
use crate::core::{MaybePackage, Package, PackageId, Workspace};
77
use crate::ops::{self, Packages};
88
use crate::util::interning::InternedString;
9+
use crate::util::toml::TomlProfiles;
910
use crate::util::CargoResult;
1011
use cargo_platform::Platform;
1112
use serde::Serialize;
@@ -40,6 +41,11 @@ pub fn output_metadata(ws: &Workspace<'_>, opt: &OutputMetadataOptions) -> Cargo
4041
(packages, Some(resolve))
4142
};
4243

44+
let workspace_profiles = match ws.root_maybe() {
45+
MaybePackage::Virtual(vm) => vm.profiles().cloned(),
46+
_ => None, // regular packages include the profile information under their package section
47+
};
48+
4349
Ok(ExportInfo {
4450
packages,
4551
workspace_members: ws.members().map(|pkg| pkg.package_id()).collect(),
@@ -49,6 +55,7 @@ pub fn output_metadata(ws: &Workspace<'_>, opt: &OutputMetadataOptions) -> Cargo
4955
version: VERSION,
5056
workspace_root: ws.root().to_path_buf(),
5157
metadata: ws.custom_metadata().cloned(),
58+
workspace_profiles,
5259
})
5360
}
5461

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

7079
#[derive(Serialize)]

src/cargo/util/toml/mod.rs

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -564,25 +564,42 @@ impl Display for TomlDebugInfo {
564564
#[derive(Deserialize, Serialize, Clone, Debug, Default, Eq, PartialEq)]
565565
#[serde(default, rename_all = "kebab-case")]
566566
pub struct TomlProfile {
567+
#[serde(skip_serializing_if = "Option::is_none")]
567568
pub opt_level: Option<TomlOptLevel>,
569+
#[serde(skip_serializing_if = "Option::is_none")]
568570
pub lto: Option<StringOrBool>,
571+
#[serde(skip_serializing_if = "Option::is_none")]
569572
pub codegen_backend: Option<InternedString>,
573+
#[serde(skip_serializing_if = "Option::is_none")]
570574
pub codegen_units: Option<u32>,
575+
#[serde(skip_serializing_if = "Option::is_none")]
571576
pub debug: Option<TomlDebugInfo>,
577+
#[serde(skip_serializing_if = "Option::is_none")]
572578
pub split_debuginfo: Option<String>,
579+
#[serde(skip_serializing_if = "Option::is_none")]
573580
pub debug_assertions: Option<bool>,
581+
#[serde(skip_serializing_if = "Option::is_none")]
574582
pub rpath: Option<bool>,
583+
#[serde(skip_serializing_if = "Option::is_none")]
575584
pub panic: Option<String>,
585+
#[serde(skip_serializing_if = "Option::is_none")]
576586
pub overflow_checks: Option<bool>,
587+
#[serde(skip_serializing_if = "Option::is_none")]
577588
pub incremental: Option<bool>,
589+
#[serde(skip_serializing_if = "Option::is_none")]
578590
pub dir_name: Option<InternedString>,
591+
#[serde(skip_serializing_if = "Option::is_none")]
579592
pub inherits: Option<InternedString>,
593+
#[serde(skip_serializing_if = "Option::is_none")]
580594
pub strip: Option<StringOrBool>,
581595
// Note that `rustflags` is used for the cargo-feature `profile_rustflags`
596+
#[serde(skip_serializing_if = "Option::is_none")]
582597
pub rustflags: Option<Vec<InternedString>>,
583598
// These two fields must be last because they are sub-tables, and TOML
584599
// requires all non-tables to be listed first.
600+
#[serde(skip_serializing_if = "Option::is_none")]
585601
pub package: Option<BTreeMap<ProfilePackageSpec, TomlProfile>>,
602+
#[serde(skip_serializing_if = "Option::is_none")]
586603
pub build_override: Option<Box<TomlProfile>>,
587604
}
588605

tests/testsuite/metadata.rs

Lines changed: 239 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4248,3 +4248,242 @@ fn workspace_metadata_with_dependencies_no_deps_artifact() {
42484248
)
42494249
.run();
42504250
}
4251+
4252+
#[cargo_test]
4253+
fn library_metadata_with_profiles() {
4254+
let p = project()
4255+
.file("src/lib.rs", "")
4256+
.file(
4257+
"Cargo.toml",
4258+
r#"
4259+
[package]
4260+
name = "foo"
4261+
version = "0.5.0"
4262+
4263+
[profile.release]
4264+
strip = "symbols"
4265+
4266+
[profile.custom-lto]
4267+
lto = "thin"
4268+
"#,
4269+
)
4270+
.build();
4271+
4272+
p.cargo("metadata")
4273+
.with_json(
4274+
r#"
4275+
{
4276+
"packages": [
4277+
{
4278+
"authors": [],
4279+
"categories": [],
4280+
"default_run": null,
4281+
"name": "foo",
4282+
"readme": null,
4283+
"repository": null,
4284+
"homepage": null,
4285+
"documentation": null,
4286+
"version": "0.5.0",
4287+
"rust_version": null,
4288+
"id": "foo[..]",
4289+
"keywords": [],
4290+
"source": null,
4291+
"dependencies": [],
4292+
"edition": "2015",
4293+
"license": null,
4294+
"license_file": null,
4295+
"links": null,
4296+
"description": null,
4297+
"targets": [
4298+
{
4299+
"kind": [
4300+
"lib"
4301+
],
4302+
"crate_types": [
4303+
"lib"
4304+
],
4305+
"doc": true,
4306+
"doctest": true,
4307+
"test": true,
4308+
"edition": "2015",
4309+
"name": "foo",
4310+
"src_path": "[..]/foo/src/lib.rs"
4311+
}
4312+
],
4313+
"features": {},
4314+
"manifest_path": "[..]Cargo.toml",
4315+
"metadata": null,
4316+
"publish": null,
4317+
"profiles": {
4318+
"custom-lto": {
4319+
"lto": "thin"
4320+
},
4321+
"release": {
4322+
"strip": "symbols"
4323+
}
4324+
}
4325+
}
4326+
],
4327+
"workspace_members": ["foo 0.5.0 (path+file:[..]foo)"],
4328+
"workspace_default_members": ["foo 0.5.0 (path+file:[..]foo)"],
4329+
"resolve": {
4330+
"nodes": [
4331+
{
4332+
"dependencies": [],
4333+
"deps": [],
4334+
"features": [],
4335+
"id": "foo 0.5.0 (path+file:[..]foo)"
4336+
}
4337+
],
4338+
"root": "foo 0.5.0 (path+file:[..]foo)"
4339+
},
4340+
"target_directory": "[..]foo/target",
4341+
"version": 1,
4342+
"workspace_root": "[..]/foo",
4343+
"metadata": null
4344+
}"#,
4345+
)
4346+
.run();
4347+
}
4348+
4349+
#[cargo_test]
4350+
fn workspace_metadata_with_profiles() {
4351+
let p = project()
4352+
.file(
4353+
"Cargo.toml",
4354+
r#"
4355+
[workspace]
4356+
members = ["bar", "baz"]
4357+
4358+
[profile.release]
4359+
strip = "symbols"
4360+
4361+
[profile.custom-lto]
4362+
lto = "thin"
4363+
"#,
4364+
)
4365+
.file("bar/Cargo.toml", &basic_lib_manifest("bar"))
4366+
.file("bar/src/lib.rs", "")
4367+
.file("baz/Cargo.toml", &basic_lib_manifest("baz"))
4368+
.file("baz/src/lib.rs", "")
4369+
.build();
4370+
4371+
p.cargo("metadata")
4372+
.with_json(
4373+
r#"
4374+
{
4375+
"packages": [
4376+
{
4377+
"authors": [
4378+
"wycats@example.com"
4379+
],
4380+
"categories": [],
4381+
"default_run": null,
4382+
"name": "bar",
4383+
"version": "0.5.0",
4384+
"id": "bar[..]",
4385+
"readme": null,
4386+
"repository": null,
4387+
"rust_version": null,
4388+
"homepage": null,
4389+
"documentation": null,
4390+
"keywords": [],
4391+
"source": null,
4392+
"dependencies": [],
4393+
"license": null,
4394+
"license_file": null,
4395+
"links": null,
4396+
"description": null,
4397+
"edition": "2015",
4398+
"targets": [
4399+
{
4400+
"kind": [ "lib" ],
4401+
"crate_types": [ "lib" ],
4402+
"doc": true,
4403+
"doctest": true,
4404+
"test": true,
4405+
"edition": "2015",
4406+
"name": "bar",
4407+
"src_path": "[..]bar/src/lib.rs"
4408+
}
4409+
],
4410+
"features": {},
4411+
"manifest_path": "[..]bar/Cargo.toml",
4412+
"metadata": null,
4413+
"publish": null
4414+
},
4415+
{
4416+
"authors": [
4417+
"wycats@example.com"
4418+
],
4419+
"categories": [],
4420+
"default_run": null,
4421+
"name": "baz",
4422+
"readme": null,
4423+
"repository": null,
4424+
"rust_version": null,
4425+
"homepage": null,
4426+
"documentation": null,
4427+
"version": "0.5.0",
4428+
"id": "baz[..]",
4429+
"keywords": [],
4430+
"source": null,
4431+
"dependencies": [],
4432+
"license": null,
4433+
"license_file": null,
4434+
"links": null,
4435+
"description": null,
4436+
"edition": "2015",
4437+
"targets": [
4438+
{
4439+
"kind": [ "lib" ],
4440+
"crate_types": [ "lib" ],
4441+
"doc": true,
4442+
"doctest": true,
4443+
"test": true,
4444+
"edition": "2015",
4445+
"name": "baz",
4446+
"src_path": "[..]baz/src/lib.rs"
4447+
}
4448+
],
4449+
"features": {},
4450+
"manifest_path": "[..]baz/Cargo.toml",
4451+
"metadata": null,
4452+
"publish": null
4453+
}
4454+
],
4455+
"workspace_members": ["bar 0.5.0 (path+file:[..]bar)", "baz 0.5.0 (path+file:[..]baz)"],
4456+
"workspace_default_members": ["bar 0.5.0 (path+file:[..]bar)", "baz 0.5.0 (path+file:[..]baz)"],
4457+
"resolve": {
4458+
"nodes": [
4459+
{
4460+
"dependencies": [],
4461+
"deps": [],
4462+
"features": [],
4463+
"id": "bar 0.5.0 (path+file:[..]bar)"
4464+
},
4465+
{
4466+
"dependencies": [],
4467+
"deps": [],
4468+
"features": [],
4469+
"id": "baz 0.5.0 (path+file:[..]baz)"
4470+
}
4471+
],
4472+
"root": null
4473+
},
4474+
"target_directory": "[..]foo/target",
4475+
"version": 1,
4476+
"workspace_root": "[..]/foo",
4477+
"metadata": null,
4478+
"workspace_profiles": {
4479+
"custom-lto": {
4480+
"lto": "thin"
4481+
},
4482+
"release": {
4483+
"strip": "symbols"
4484+
}
4485+
}
4486+
}"#,
4487+
)
4488+
.run();
4489+
}

0 commit comments

Comments
 (0)