Skip to content

fix: set license and manufacturer for the main component #654 - #836

Open
dimitarp wants to merge 2 commits into
CycloneDX:masterfrom
dimitarp:fix/654-license-and-manufacturer
Open

fix: set license and manufacturer for the main component #654#836
dimitarp wants to merge 2 commits into
CycloneDX:masterfrom
dimitarp:fix/654-license-and-manufacturer

Conversation

@dimitarp

@dimitarp dimitarp commented Apr 30, 2026

Copy link
Copy Markdown

Put license and manufacturer data under $.metadata.component.licenses and $.metadata.component.manufacturer instead of $.metadata.licenses and $.metadata.manufacturer. The latter refers to the license and manufacturer of the SBOM itself and not of the main component. The plugin README states that licenseChoice is the "License information for the main component".

fixes #654

@dimitarp
dimitarp requested a review from a team as a code owner April 30, 2026 10:04
@codacy-production

codacy-production Bot commented Apr 30, 2026

Copy link
Copy Markdown

Up to standards ✅

🟢 Issues 0 issues

Results:
0 new issues

View in Codacy

🟢 Metrics 0 complexity · 0 duplication

Metric Results
Complexity 0
Duplication 0

View in Codacy

NEW Get contextual insights on your PRs based on Codacy's metrics, along with PR and Jira context, without leaving GitHub. Enable AI reviewer
TIP This summary will be updated as you push new changes.

Signed-off-by: Dimitar Popov <dimitar.popov@seitenbau.com>
@dimitarp
dimitarp force-pushed the fix/654-license-and-manufacturer branch from 611c0a6 to 5865449 Compare April 30, 2026 10:52
@dimitarp
dimitarp marked this pull request as draft May 19, 2026 14:00
@dimitarp
dimitarp force-pushed the fix/654-license-and-manufacturer branch from 5865449 to 32f3ef4 Compare May 20, 2026 10:08
@dimitarp
dimitarp marked this pull request as ready for review May 20, 2026 10:09

@skhokhlov skhokhlov left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for this! It is a correct per the CycloneDX spec.

However, this is a breaking change to the generated SBOM, which we treat as public API. It needs a major version bump (4.x.x). So the merge might be delayed until we understand full scope go the next major release.

task.getExternalReferences().get().forEach(component::addExternalReference);
}
if (task.getLicenseChoice().isPresent()) {
component.setLicenses(task.getLicenseChoice().get());

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Note that toComponent (line ~264) may already set this component's licenses from resolved project metadata, and this line overwrites them. That's the behavior we want - a configured licenseChoice is the single source of truth for the main component's license - so no change needed here. Please add a sentence to the README's licenseChoice docs stating that a configured value replaces any auto-detected license for the main component.

component.setLicenses(task.getLicenseChoice().get());
}
if (task.getOrganizationalEntity().isPresent()
&& !new OrganizationalEntity()

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This presence + not-empty check duplicates lines 118-120; only the version comparison differs. Optional cleanup - extract a small helper and reuse it in both branches:

private Optional<OrganizationalEntity> configuredManufacturer() {
    if (!task.getOrganizationalEntity().isPresent()) {
        return Optional.empty();
    }
    OrganizationalEntity oe = task.getOrganizationalEntity().get();
    return new OrganizationalEntity().equals(oe) ? Optional.empty() : Optional.of(oe);
 }

Happy to merge without this.

assert !licenseChoice.getLicenses().findAll({
it.getAttachmentText().getText() == "This is a Licenses-Test" &&
it.getUrl() == "https://www.test-Url.org/"
}).isEmpty()

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please also assert the data left the old (document-level) location, otherwise a regression that writes to both places would pass:

assert bom.getMetadata().getLicenses() == null
assert bom.getMetadata().getManufacturer() == null

assert !licenseChoice.getLicenses().findAll({
it.getAttachmentText().getText() == "This is a Licenses-Test" &&
it.getUrl() == "https://www.test-Url.org/"
}).isEmpty()

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Same here. Add the negative assertions so the old paths are verified empty:

assert bom.getMetadata().getLicenses() == null
assert bom.getMetadata().getManufacturer() == null

assert jsonBom.getMetadata().getManufacturer().getName() == "name"
assert xmlBom.getMetadata().getManufacturer().getName() == "name"
assert jsonBom.getMetadata().getComponent().getManufacturer().getName() == "name"
assert xmlBom.getMetadata().getComponent().getManufacturer().getName() == "name"

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This branch asserts metadata.manufacture == null but not the BOM-level metadata.manufacturer. Please add the following so a manufacturer accidentally written to both the component and the document level is caught:

assert jsonBom.getMetadata().getManufacturer() == null
assert xmlBom.getMetadata().getManufacturer() == null

@dimitarp

dimitarp commented Jun 8, 2026

Copy link
Copy Markdown
Author

Thanks for the review! I'll look into it the next days.

@dimitarp

Copy link
Copy Markdown
Author

Thanks for this! It is a correct per the CycloneDX spec.

However, this is a breaking change to the generated SBOM, which we treat as public API. It needs a major version bump (4.x.x). So the merge might be delayed until we understand full scope go the next major release.

I understand your concern. However, maybe the README should describe the actual behavior for the licenseChoice and organizationalEntity parameters.

Optionally, implementing new parameters componentLicenseChoice and componentOrganizationalEntity (similar to componentName, componentVersion and componentGroup) would avoid the breaking change. What are your thoughts on this approach?

Signed-off-by: Dimitar Popov <dimitar.popov@seitenbau.com>
@dimitarp
dimitarp force-pushed the fix/654-license-and-manufacturer branch from 32f3ef4 to fc9e827 Compare June 10, 2026 15:25
@dimitarp
dimitarp requested a review from skhokhlov June 10, 2026 17:05
@Zuplyx

Zuplyx commented Jul 14, 2026

Copy link
Copy Markdown

Personally I think it would be best to add new parameters for the component manufacturer. This way the manufacturer can be set both for the SBOM itself and the main component. Additionally some Guidelines (e.g. the German BSI TR-03183) actually require the manufacturer on both levels.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Cannot set license for project dependency

3 participants