Skip to content

Commit 355b429

Browse files
feat: add rootComponentVCS configuration (#1350)
resolves #1344 --------- Signed-off-by: Jeremy Long <[email protected]> Signed-off-by: Jan Kowalleck <[email protected]> Co-authored-by: Jan Kowalleck <[email protected]>
1 parent 48701a7 commit 355b429

File tree

17 files changed

+9393
-3
lines changed

17 files changed

+9393
-3
lines changed

HISTORY.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,11 @@ All notable changes to this project will be documented in this file.
55
## unreleased
66

77
<!-- unreleased changes go here -->
8+
* Added
9+
* Configuration option for `rootComponentVCS` ([#1344] via [#1350])
10+
11+
[#1344]: https://github.com/CycloneDX/cyclonedx-webpack-plugin/issues/1344
12+
[#1350]: https://github.com/CycloneDX/cyclonedx-webpack-plugin/pull/1350
813

914
## 3.16.0 - 2025-01-08
1015

README.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,7 @@ new CycloneDxWebpackPlugin(options?: object)
5757
| **`rootComponentName`** | optional `{string}` | `undefined` | If `rootComponentAutodetect` is disabled, then this value is assumed as the "name" of the `package.json`. |
5858
| **`rootComponentVersion`** | optional `{string}` | `undefined` | If `rootComponentAutodetect` is disabled, then this value is assumed as the "version" of the `package.json`. |
5959
| **`rootComponentBuildSystem`** | optional `{string}` | `undefined` | Set's the URL for the RootComponent's External References' build-system. |
60+
| **`rootComponentVCS`** | optional `{string}` | `undefined` | If `rootComponentAutodetect` is disabled or the VCS is not defined in the package.json, then this value is used as the URL for the RootComponent's External Referencees' Version Control System. |
6061
| **`collectEvidence`** | `{boolean}` | `false` | Whether to collect (license) evidence and attach them to the resulting SBOM. |
6162

6263
### Example

examples/simple/webpack.config.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@ const cycloneDxWebpackPluginOptions = {
3333
rootComponentName: undefined,
3434
rootComponentVersion: undefined,
3535
rootComponentBuildSystem: undefined,
36+
rootComponentVCS: undefined,
3637
collectEvidence: true
3738
}
3839

src/_helpers.ts

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -130,3 +130,17 @@ export function getMimeForLicenseFile (filename: string): MimeType | undefined {
130130
}
131131

132132
// endregion MIME
133+
134+
// region polyfills
135+
136+
/** Polyfill for Iterator.some() */
137+
export function iterableSome<T> (i: Iterable<T>, t: (v: T) => boolean): boolean {
138+
for (const v of i) {
139+
if (t(v)) {
140+
return true
141+
}
142+
}
143+
return false
144+
}
145+
146+
// endregion polyfills

src/plugin.ts

Lines changed: 30 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@ import * as normalizePackageJson from 'normalize-package-data'
2323
import { join as joinPath, resolve } from 'path'
2424
import { Compilation, type Compiler, sources } from 'webpack'
2525

26-
import { getPackageDescription, loadJsonFile } from './_helpers'
26+
import { getPackageDescription, iterableSome, loadJsonFile } from './_helpers'
2727
import { Extractor } from './extractor'
2828

2929
type WebpackLogger = Compilation['logger']
@@ -110,6 +110,11 @@ export interface CycloneDxWebpackPluginOptions {
110110
* See {@link https://cyclonedx.org/docs/1.6/json/#metadata_component_externalReferences}.
111111
*/
112112
rootComponentBuildSystem?: CycloneDxWebpackPlugin['rootComponentBuildSystem']
113+
/**
114+
* Set the externalReference URL for the version control system for the RootComponent.
115+
* See {@link https://cyclonedx.org/docs/1.6/json/#metadata_component_externalReferences}.
116+
*/
117+
rootComponentVCS?: CycloneDxWebpackPlugin['rootComponentVCS']
113118

114119
/**
115120
* Whether to collect (license) evidence and attach them to the resulting SBOM.
@@ -142,6 +147,7 @@ export class CycloneDxWebpackPlugin {
142147
rootComponentName: CDX.Models.Component['name'] | undefined
143148
rootComponentVersion: CDX.Models.Component['version'] | undefined
144149
rootComponentBuildSystem: CDX.Models.ExternalReference['url'] | undefined
150+
rootComponentVCS: CDX.Models.ExternalReference['url'] | undefined
145151

146152
collectEvidence: boolean
147153

@@ -157,6 +163,7 @@ export class CycloneDxWebpackPlugin {
157163
rootComponentName = undefined,
158164
rootComponentVersion = undefined,
159165
rootComponentBuildSystem = undefined,
166+
rootComponentVCS = undefined,
160167
collectEvidence = false
161168
}: CycloneDxWebpackPluginOptions = {}) {
162169
this.specVersion = specVersion
@@ -172,6 +179,7 @@ export class CycloneDxWebpackPlugin {
172179
this.rootComponentName = rootComponentName
173180
this.rootComponentVersion = rootComponentVersion
174181
this.rootComponentBuildSystem = rootComponentBuildSystem
182+
this.rootComponentVCS = rootComponentVCS
175183
this.collectEvidence = collectEvidence
176184
}
177185

@@ -318,7 +326,10 @@ export class CycloneDxWebpackPlugin {
318326

319327
#addRootComponentExtRefs (component: CDX.Models.Component | undefined, logger: WebpackLogger): void {
320328
if (component === undefined) { return }
321-
if (typeof this.rootComponentBuildSystem === 'string' && this.rootComponentBuildSystem.length > 0) {
329+
if (
330+
typeof this.rootComponentBuildSystem === 'string' &&
331+
this.rootComponentBuildSystem.length > 0
332+
) {
322333
component.externalReferences.add(
323334
new CDX.Models.ExternalReference(
324335
this.rootComponentBuildSystem,
@@ -328,6 +339,23 @@ export class CycloneDxWebpackPlugin {
328339
)
329340
logger.debug('Added rootComponent BuildSystem URL:', this.rootComponentBuildSystem)
330341
}
342+
if (
343+
typeof this.rootComponentVCS === 'string' &&
344+
this.rootComponentVCS.length > 0 &&
345+
!iterableSome(
346+
component.externalReferences,
347+
ref => ref.type === CDX.Enums.ExternalReferenceType.VCS
348+
)
349+
) {
350+
component.externalReferences.add(
351+
new CDX.Models.ExternalReference(
352+
this.rootComponentVCS,
353+
CDX.Enums.ExternalReferenceType.VCS,
354+
{ comment: 'as declared via cyclonedx-webpack-plugin config "rootComponentVCS"' }
355+
)
356+
)
357+
logger.debug('Added rootComponent VCS URL:', this.rootComponentVCS)
358+
}
331359
}
332360

333361
#makeRootComponent (

0 commit comments

Comments
 (0)