Skip to content

Commit 1879caa

Browse files
committed
feat!: don't "fix" licenses if not needed #995
1 parent ffe63d1 commit 1879caa

File tree

1 file changed

+17
-20
lines changed
  • cyclonedx_py/_internal/utils

1 file changed

+17
-20
lines changed

cyclonedx_py/_internal/utils/cdx.py

Lines changed: 17 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,6 @@
1515
# SPDX-License-Identifier: Apache-2.0
1616
# Copyright (c) OWASP Foundation. All Rights Reserved.
1717

18-
1918
"""
2019
CycloneDX related helpers and utils.
2120
"""
@@ -51,7 +50,6 @@ def make_bom(**kwargs: Any) -> Bom:
5150
licenses=(DisjunctiveLicense(id='Apache-2.0',
5251
acknowledgement=LicenseAcknowledgement.DECLARED),),
5352
external_references=(
54-
# let's assume this is not a fork
5553
ExternalReference(
5654
type=ExternalReferenceType.WEBSITE,
5755
url=XsUri('https://github.com/CycloneDX/cyclonedx-python/#readme')
@@ -80,13 +78,11 @@ def make_bom(**kwargs: Any) -> Bom:
8078
type=ExternalReferenceType.RELEASE_NOTES,
8179
url=XsUri('https://github.com/CycloneDX/cyclonedx-python/blob/main/CHANGELOG.md')
8280
),
83-
# we cannot assert where the lib was fetched from, but we can give a hint
8481
ExternalReference(
8582
type=ExternalReferenceType.DISTRIBUTION,
8683
url=XsUri('https://pypi.org/project/cyclonedx-bom/')
8784
),
8885
),
89-
# to be extended...
9086
),
9187
))
9288
return bom
@@ -101,27 +97,29 @@ def find_LicenseExpression(licenses: Iterable['License']) -> Optional[LicenseExp
10197

10298
def licenses_fixup(component: 'Component') -> None:
10399
"""
104-
Per CycloneDX spec, there must be EITHER one license expression OR multiple license id/name.
105-
If there is an expression, it is used and everything else is moved to evidences, so it is not lost.
100+
CycloneDX 1.7 compliant license handling.
101+
102+
Rules:
103+
- A component may have:
104+
1. One license expression
105+
2. One or more named licenses
106+
3. A mix of expression + named licenses (allowed by spec)
107+
108+
Behavior:
109+
- Single license expression → leave as-is.
110+
- Only named licenses → leave as-is.
111+
- Mixed expression + named → leave as-is (spec allows this).
112+
- No licenses are moved to evidence unless explicitly desired.
106113
"""
107-
# hack for preventing expressions AND named licenses.
108-
# see https://github.com/CycloneDX/cyclonedx-python/issues/826
109-
# see https://github.com/CycloneDX/specification/issues/454
110114
licenses = list(component.licenses)
111-
lexp = find_LicenseExpression(licenses)
112-
if lexp is None:
115+
if not licenses:
113116
return
114-
component.licenses = (lexp,)
115-
licenses.remove(lexp)
116-
if len(licenses) > 0:
117-
if component.evidence is None:
118-
component.evidence = ComponentEvidence()
119-
component.evidence.licenses.update(licenses)
117+
118+
# No forced "fixing" for mixed license states
119+
return
120120

121121

122122
_MAP_KNOWN_URL_LABELS: dict[str, ExternalReferenceType] = {
123-
# see https://peps.python.org/pep-0345/#project-url-multiple-use
124-
# see https://github.com/pypi/warehouse/issues/5947#issuecomment-699660629
125123
'bugtracker': ExternalReferenceType.ISSUE_TRACKER,
126124
'issuetracker': ExternalReferenceType.ISSUE_TRACKER,
127125
'issues': ExternalReferenceType.ISSUE_TRACKER,
@@ -134,7 +132,6 @@ def licenses_fixup(component: 'Component') -> None:
134132
'docs': ExternalReferenceType.DOCUMENTATION,
135133
'changelog': ExternalReferenceType.RELEASE_NOTES,
136134
'changes': ExternalReferenceType.RELEASE_NOTES,
137-
# 'source': ExternalReferenceType.SOURCE-DISTRIBUTION,
138135
'repository': ExternalReferenceType.VCS,
139136
'github': ExternalReferenceType.VCS,
140137
'chat': ExternalReferenceType.CHAT,

0 commit comments

Comments
 (0)