Skip to content

Commit c8e1bc8

Browse files
committed
Integrate review feedback
* use `PackageIdSpec` instead of only `PackageId` in SBOM output * change `version` of a dependency to `Option<Version>` * output `Vec<CrateType>` instead of only the first found crate type * output rustc workspace wrapper * update 'warning' string in test using `[WARNING]` * use `serde_json::to_writer` to serialize SBOM
1 parent 6a05ed9 commit c8e1bc8

File tree

3 files changed

+52
-32
lines changed

3 files changed

+52
-32
lines changed

src/cargo/core/compiler/output_sbom.rs

Lines changed: 17 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -2,16 +2,17 @@
22
//! See [`output_sbom`] for more.
33
44
use std::collections::BTreeSet;
5-
use std::io::{BufWriter, Write};
5+
use std::io::BufWriter;
66
use std::path::PathBuf;
77

88
use cargo_util::paths::{self};
99
use cargo_util_schemas::core::PackageIdSpec;
1010
use itertools::Itertools;
11+
use semver::Version;
1112
use serde::Serialize;
1213

1314
use crate::{
14-
core::{profiles::Profile, PackageId, Target, TargetKind},
15+
core::{profiles::Profile, Target, TargetKind},
1516
util::Rustc,
1617
CargoResult,
1718
};
@@ -43,16 +44,16 @@ impl<const V: u32> Serialize for SbomFormatVersion<V> {
4344
#[derive(Serialize, Clone, Debug)]
4445
struct SbomDependency {
4546
name: String,
46-
package_id: PackageId,
47-
version: String,
47+
package_id: PackageIdSpec,
48+
version: Option<Version>,
4849
features: Vec<String>,
4950
}
5051

5152
impl From<&UnitDep> for SbomDependency {
5253
fn from(dep: &UnitDep) -> Self {
53-
let package_id = dep.unit.pkg.package_id();
54+
let package_id = dep.unit.pkg.package_id().to_spec();
5455
let name = package_id.name().to_string();
55-
let version = package_id.version().to_string();
56+
let version = package_id.version();
5657
let features = dep
5758
.unit
5859
.features
@@ -71,9 +72,9 @@ impl From<&UnitDep> for SbomDependency {
7172

7273
#[derive(Serialize, Clone, Debug)]
7374
struct SbomPackage {
74-
package_id: PackageId,
75+
package_id: PackageIdSpec,
7576
package: String,
76-
version: String,
77+
version: Option<Version>,
7778
features: Vec<String>,
7879
build_type: SbomBuildType,
7980
extern_crate_name: String,
@@ -86,9 +87,9 @@ impl SbomPackage {
8687
dependencies: Vec<SbomDependency>,
8788
build_type: SbomBuildType,
8889
) -> Self {
89-
let package_id = dep.unit.pkg.package_id();
90+
let package_id = dep.unit.pkg.package_id().to_spec();
9091
let package = package_id.name().to_string();
91-
let version = package_id.version().to_string();
92+
let version = package_id.version();
9293
let features = dep
9394
.unit
9495
.features
@@ -111,7 +112,7 @@ impl SbomPackage {
111112
#[derive(Serialize)]
112113
struct SbomTarget {
113114
kind: TargetKind,
114-
crate_type: Option<CrateType>,
115+
crate_types: Vec<CrateType>,
115116
name: String,
116117
edition: String,
117118
}
@@ -120,7 +121,7 @@ impl From<&Target> for SbomTarget {
120121
fn from(target: &Target) -> Self {
121122
SbomTarget {
122123
kind: target.kind().clone(),
123-
crate_type: target.kind().rustc_crate_types().first().cloned(),
124+
crate_types: target.kind().rustc_crate_types().clone(),
124125
name: target.name().to_string(),
125126
edition: target.edition().to_string(),
126127
}
@@ -131,6 +132,7 @@ impl From<&Target> for SbomTarget {
131132
struct SbomRustc {
132133
version: String,
133134
wrapper: Option<PathBuf>,
135+
workspace_wrapper: Option<PathBuf>,
134136
commit_hash: Option<String>,
135137
host: String,
136138
}
@@ -140,6 +142,7 @@ impl From<&Rustc> for SbomRustc {
140142
Self {
141143
version: rustc.version.to_string(),
142144
wrapper: rustc.wrapper.clone(),
145+
workspace_wrapper: rustc.workspace_wrapper.clone(),
143146
commit_hash: rustc.commit_hash.clone(),
144147
host: rustc.host.to_string(),
145148
}
@@ -196,9 +199,8 @@ pub fn output_sbom(build_runner: &mut BuildRunner<'_, '_>, unit: &Unit) -> Cargo
196199
for sbom_output_file in build_runner.sbom_output_files(unit)? {
197200
let sbom = Sbom::new(unit, packages.clone(), rustc.clone());
198201

199-
let mut outfile = BufWriter::new(paths::create(sbom_output_file)?);
200-
let output = serde_json::to_string(&sbom)?;
201-
write!(outfile, "{}", output)?;
202+
let outfile = BufWriter::new(paths::create(sbom_output_file)?);
203+
serde_json::to_writer(outfile, &sbom)?;
202204
}
203205

204206
Ok(())

src/doc/src/reference/unstable.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -390,6 +390,9 @@ build process that are difficult or impossible to obtain in another way.
390390
To enable this feature either set the `sbom` field in the `.cargo/config.toml`
391391

392392
```toml
393+
[unstable]
394+
sbom = true
395+
393396
[build]
394397
sbom = true
395398
```

tests/testsuite/sbom.rs

Lines changed: 32 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,7 @@ fn build_sbom_without_passing_unstable_flag() {
3939
.masquerade_as_nightly_cargo(&["sbom"])
4040
.with_stderr(
4141
"\
42-
warning: ignoring 'sbom' config, pass `-Zsbom` to enable it\n\
42+
[WARNING] ignoring 'sbom' config, pass `-Zsbom` to enable it\n\
4343
[COMPILING] foo v0.5.0 ([..])\n\
4444
[FINISHED] `dev` profile [unoptimized + debuginfo] target(s) in [..]\n",
4545
)
@@ -74,7 +74,9 @@ fn build_sbom_using_cargo_config() {
7474
"kind": [
7575
"bin"
7676
],
77-
"crate_type": "bin",
77+
"crate_types": [
78+
"bin"
79+
],
7880
"name": "foo",
7981
"edition": "2015"
8082
},
@@ -100,6 +102,7 @@ fn build_sbom_using_cargo_config() {
100102
"rustc": {
101103
"version": "[..]",
102104
"wrapper": null,
105+
"workspace_wrapper": null,
103106
"commit_hash": "[..]",
104107
"host": "[..]"
105108
}
@@ -171,7 +174,10 @@ fn build_sbom_with_simple_build_script() {
171174
.file("src/main.rs", "#[cfg(foo)] fn main() {}")
172175
.file(
173176
"build.rs",
174-
r#"fn main() { println!("cargo::rustc-cfg=foo"); }"#,
177+
r#"fn main() {
178+
println!("cargo::rustc-check-cfg=cfg(foo)");
179+
println!("cargo::rustc-cfg=foo");
180+
}"#,
175181
)
176182
.build();
177183

@@ -187,15 +193,17 @@ fn build_sbom_with_simple_build_script() {
187193
r#"
188194
{
189195
"format_version": 1,
190-
"package_id": "path+file:///[..]/foo#0.0.1",
196+
"package_id": "path+file://[ROOT]/foo#0.0.1",
191197
"name": "foo",
192198
"version": "0.0.1",
193199
"source": "[ROOT]/foo",
194200
"target": {
195201
"kind": [
196202
"bin"
197203
],
198-
"crate_type": "bin",
204+
"crate_types": [
205+
"bin"
206+
],
199207
"name": "foo",
200208
"edition": "2015"
201209
},
@@ -223,18 +231,18 @@ fn build_sbom_with_simple_build_script() {
223231
{
224232
"features": [],
225233
"name": "foo",
226-
"package_id": "foo 0.0.1 (path+file:///[..]/foo)",
234+
"package_id": "path+file://[ROOT]/foo#0.0.1",
227235
"version": "0.0.1"
228236
}
229237
],
230238
"extern_crate_name": "build_script_build",
231239
"features": [],
232240
"package": "foo",
233-
"package_id": "foo 0.0.1 (path+file:///[..]/foo)",
241+
"package_id": "path+file://[ROOT]/foo#0.0.1",
234242
"version": "0.0.1"
235243
},
236244
{
237-
"package_id": "foo 0.0.1 (path+file:///[..]/foo)",
245+
"package_id": "path+file://[ROOT]/foo#0.0.1",
238246
"package": "foo",
239247
"version": "0.0.1",
240248
"features": [],
@@ -247,6 +255,7 @@ fn build_sbom_with_simple_build_script() {
247255
"rustc": {
248256
"version": "[..]",
249257
"wrapper": null,
258+
"workspace_wrapper": null,
250259
"commit_hash": "[..]",
251260
"host": "[..]"
252261
}
@@ -274,7 +283,10 @@ fn build_sbom_with_build_dependencies() {
274283
.file("src/lib.rs", "pub fn bar() -> i32 { 2 }")
275284
.file(
276285
"build.rs",
277-
r#"fn main() { println!("cargo::rustc-cfg=foo"); }"#,
286+
r#"fn main() {
287+
println!("cargo::rustc-check-cfg=cfg(foo)");
288+
println!("cargo::rustc-cfg=foo");
289+
}"#,
278290
)
279291
.publish();
280292

@@ -312,7 +324,9 @@ fn build_sbom_with_build_dependencies() {
312324
"kind": [
313325
"bin"
314326
],
315-
"crate_type": "bin",
327+
"crate_types": [
328+
"bin"
329+
],
316330
"name": "foo",
317331
"edition": "2015"
318332
},
@@ -335,7 +349,7 @@ fn build_sbom_with_build_dependencies() {
335349
},
336350
"packages": [
337351
{
338-
"package_id": "bar 0.1.0 (registry+[..])",
352+
"package_id": "registry+[..]#[email protected]",
339353
"package": "bar",
340354
"version": "0.1.0",
341355
"features": [],
@@ -344,14 +358,14 @@ fn build_sbom_with_build_dependencies() {
344358
"dependencies": [
345359
{
346360
"name": "bar",
347-
"package_id": "bar 0.1.0 (registry+[..])",
361+
"package_id": "registry+[..]#[email protected]",
348362
"version": "0.1.0",
349363
"features": []
350364
}
351365
]
352366
},
353367
{
354-
"package_id": "bar 0.1.0 (registry+[..])",
368+
"package_id": "registry+[..]#[email protected]",
355369
"package": "bar",
356370
"version": "0.1.0",
357371
"features": [],
@@ -360,14 +374,14 @@ fn build_sbom_with_build_dependencies() {
360374
"dependencies": [
361375
{
362376
"name": "bar",
363-
"package_id": "bar 0.1.0 (registry+[..])",
377+
"package_id": "registry+[..]#[email protected]",
364378
"version": "0.1.0",
365379
"features": []
366380
}
367381
]
368382
},
369383
{
370-
"package_id": "bar 0.1.0 (registry+[..])",
384+
"package_id": "registry+[..]#[email protected]",
371385
"package": "bar",
372386
"version": "0.1.0",
373387
"features": [],
@@ -376,14 +390,14 @@ fn build_sbom_with_build_dependencies() {
376390
"dependencies": [
377391
{
378392
"name": "baz",
379-
"package_id": "baz 0.1.0 (registry+[..])",
393+
"package_id": "registry+[..]#[email protected]",
380394
"version": "0.1.0",
381395
"features": []
382396
}
383397
]
384398
},
385399
{
386-
"package_id": "baz 0.1.0 (registry+[..])",
400+
"package_id": "registry+[..]#[email protected]",
387401
"package": "baz",
388402
"version": "0.1.0",
389403
"features": [],
@@ -396,6 +410,7 @@ fn build_sbom_with_build_dependencies() {
396410
"rustc": {
397411
"version": "[..]",
398412
"wrapper": null,
413+
"workspace_wrapper": null,
399414
"commit_hash": "[..]",
400415
"host": "[..]"
401416
}

0 commit comments

Comments
 (0)