Skip to content

Commit e95af17

Browse files
authored
feat: support multi license mix (#582)
As discussed in ticket #454, this PR adds the following abilities: - have multiple license expressions - have a mix of license expressions, SPDX license IDs, and named licenses Please read the original ticket and see the provided example data for use-cases. fixes #454
2 parents d88ff39 + 32b73df commit e95af17

11 files changed

+696
-41
lines changed

schema/bom-1.7.proto

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -123,7 +123,7 @@ message Component {
123123
optional Scope scope = 11;
124124
// The hashes of the component.
125125
repeated Hash hashes = 12;
126-
// EITHER (list of SPDX licenses and/or named licenses) OR (tuple of one SPDX License Expression)
126+
// A list of SPDX licenses and/or named licenses and/or SPDX License Expression.
127127
repeated LicenseChoice licenses = 13;
128128
// An optional copyright notice informing users of the underlying claims to copyright ownership in a published work.
129129
optional string copyright = 14;
@@ -573,7 +573,7 @@ message Metadata {
573573
// The organization that supplied the component that the BOM describes. The supplier may often be the manufacture, but may also be a distributor or repackager.
574574
optional OrganizationalEntity supplier = 6;
575575
// The license information for the BOM document. This may be different from the license(s) of the component(s) that the BOM describes.
576-
// EITHER (list of SPDX licenses and/or named licenses) OR (tuple of one SPDX License Expression)
576+
// A list of SPDX licenses and/or named licenses and/or SPDX License Expression.
577577
repeated LicenseChoice licenses = 7;
578578
// Specifies optional, custom, properties
579579
repeated Property properties = 8;
@@ -710,7 +710,7 @@ message Service {
710710
optional bool x_trust_boundary = 9;
711711
// Specifies information about the data including the directional flow of data and the data classification.
712712
repeated DataFlow data = 10;
713-
// EITHER (list of SPDX licenses and/or named licenses) OR (tuple of one SPDX License Expression)
713+
// A list of SPDX licenses and/or named licenses and/or SPDX License Expression.
714714
repeated LicenseChoice licenses = 11;
715715
// Provides the ability to document external references related to the service.
716716
repeated ExternalReference external_references = 12;
@@ -832,7 +832,7 @@ message EvidenceCopyright {
832832

833833
// Provides the ability to document evidence collected through various forms of extraction or analysis.
834834
message Evidence {
835-
// EITHER (list of SPDX licenses and/or named licenses) OR (tuple of one SPDX License Expression)
835+
// A list of SPDX licenses and/or named licenses and/or SPDX License Expression.
836836
repeated LicenseChoice licenses = 1;
837837
// Copyright evidence captures intellectual property assertions, providing evidence of possible ownership and legal protection.
838838
repeated EvidenceCopyright copyright = 2;

schema/bom-1.7.schema.json

Lines changed: 27 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -1525,36 +1525,31 @@
15251525
},
15261526
"licenseChoice": {
15271527
"title": "License Choice",
1528-
"description": "EITHER (list of SPDX licenses and/or named licenses) OR (tuple of one SPDX License Expression)",
1528+
"description": "A list of SPDX licenses and/or named licenses and/or SPDX License Expression.",
15291529
"type": "array",
1530-
"oneOf": [
1531-
{
1532-
"title": "Multiple licenses",
1533-
"description": "A list of SPDX licenses and/or named licenses.",
1534-
"type": "array",
1535-
"items": {
1530+
"items": {
1531+
"oneOf": [
1532+
{
15361533
"type": "object",
15371534
"title": "License",
1538-
"required": ["license"],
1535+
"required": [
1536+
"license"
1537+
],
15391538
"additionalProperties": false,
15401539
"properties": {
1541-
"license": {"$ref": "#/definitions/license"}
1540+
"license": {
1541+
"$ref": "#/definitions/license"
1542+
}
15421543
}
1543-
}
1544-
},
1545-
{
1546-
"title": "SPDX License Expression",
1547-
"description": "A tuple of exactly one SPDX License Expression.",
1548-
"type": "array",
1549-
"additionalItems": false,
1550-
"minItems": 1,
1551-
"maxItems": 1,
1552-
"items": [{
1544+
},
1545+
{
15531546
"title": "License Expression",
15541547
"description": "Specifies the details and attributes related to a software license.\nIt must be a valid SPDX license expression, along with additional properties such as license acknowledgment.",
15551548
"type": "object",
15561549
"additionalProperties": false,
1557-
"required": ["expression"],
1550+
"required": [
1551+
"expression"
1552+
],
15581553
"properties": {
15591554
"expression": {
15601555
"type": "string",
@@ -1600,7 +1595,9 @@
16001595
"type": "string",
16011596
"title": "License URL",
16021597
"description": "The URL to the license file. If specified, a 'license' externalReference should also be specified for completeness",
1603-
"examples": ["https://www.apache.org/licenses/LICENSE-2.0.txt"],
1598+
"examples": [
1599+
"https://www.apache.org/licenses/LICENSE-2.0.txt"
1600+
],
16041601
"format": "iri-reference"
16051602
}
16061603
},
@@ -1615,17 +1612,21 @@
16151612
"title": "BOM Reference",
16161613
"description": "An optional identifier which can be used to reference the license elsewhere in the BOM. Every bom-ref must be unique within the BOM.\nValue SHOULD not start with the BOM-Link intro 'urn:cdx:' to avoid conflicts with BOM-Links."
16171614
},
1618-
"licensing": {"$ref": "#/definitions/licensing"},
1615+
"licensing": {
1616+
"$ref": "#/definitions/licensing"
1617+
},
16191618
"properties": {
16201619
"type": "array",
16211620
"title": "Properties",
16221621
"description": "Provides the ability to document properties in a name-value store. This provides flexibility to include data not officially supported in the standard without having to use additional namespaces or create extensions. Unlike key-value stores, properties support duplicate names, each potentially having different values. Property names of interest to the general public are encouraged to be registered in the [CycloneDX Property Taxonomy](https://github.com/CycloneDX/cyclonedx-property-taxonomy). Formal registration is optional.",
1623-
"items": {"$ref": "#/definitions/property"}
1622+
"items": {
1623+
"$ref": "#/definitions/property"
1624+
}
16241625
}
16251626
}
1626-
}]
1627-
}
1628-
]
1627+
}
1628+
]
1629+
}
16291630
},
16301631
"commit": {
16311632
"type": "object",

schema/bom-1.7.xsd

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2556,10 +2556,13 @@ limitations under the License.
25562556
</xs:simpleType>
25572557

25582558
<xs:complexType name="licenseChoiceType">
2559-
<xs:choice>
2560-
<xs:element name="license" type="bom:licenseType" minOccurs="0" maxOccurs="unbounded"/>
2561-
<xs:element name="expression" type="bom:licenseExpressionType" minOccurs="0" maxOccurs="1" />
2562-
<xs:element name="expression-detailed" type="bom:licenseExpressionDetailedType" minOccurs="0" maxOccurs="1" />
2559+
<xs:annotation>
2560+
<xs:documentation>A list of SPDX licenses and/or named licenses and/or SPDX License Expression.</xs:documentation>
2561+
</xs:annotation>
2562+
<xs:choice minOccurs="0" maxOccurs="unbounded">
2563+
<xs:element name="license" type="bom:licenseType"/>
2564+
<xs:element name="expression" type="bom:licenseExpressionType"/>
2565+
<xs:element name="expression-detailed" type="bom:licenseExpressionDetailedType"/>
25632566
</xs:choice>
25642567
</xs:complexType>
25652568

Lines changed: 79 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,79 @@
1+
{
2+
"$schema": "http://cyclonedx.org/schema/bom-1.6.schema.json",
3+
"bomFormat": "CycloneDX",
4+
"specVersion": "1.6",
5+
"serialNumber": "urn:uuid:df628836-6b9b-41c9-a724-b44743c54d42",
6+
"version": 1,
7+
"metadata": {
8+
"lifecycles": [{"phase": "design"}]
9+
},
10+
"components": [
11+
{
12+
"type": "library",
13+
"group": "com.example",
14+
"name": "situation-A",
15+
"version": "1",
16+
"description": "Multiple licenses: declared ids/names, and a concluded expression",
17+
"licenses": [
18+
{
19+
"license": {
20+
"id": "MIT",
21+
"acknowledgement": "declared"
22+
}
23+
},
24+
{
25+
"license": {
26+
"id": "PostgreSQL",
27+
"acknowledgement": "declared"
28+
}
29+
},
30+
{
31+
"license": {
32+
"name": "Apache Software License",
33+
"acknowledgement": "declared"
34+
}
35+
},
36+
{
37+
"expression": "(MIT OR PostgreSQL OR Apache-2.0)",
38+
"acknowledgement": "concluded"
39+
}
40+
]
41+
},
42+
{
43+
"type": "library",
44+
"group": "com.example",
45+
"name": "situation-B",
46+
"version": "1",
47+
"description": "Multiple license expressions: one declared, one concluded",
48+
"licenses": [
49+
{
50+
"expression": "MIT OR (GPL-3.0 OR GPL-2.0)",
51+
"acknowledgement": "declared"
52+
},
53+
{
54+
"expression": "(GPL-3.0-only AND LGPL-2.0-only)",
55+
"acknowledgement": "concluded"
56+
}
57+
]
58+
},
59+
{
60+
"type": "library",
61+
"group": "com.example",
62+
"name": "situation-C",
63+
"version": "1",
64+
"description": "Multiple license: one declared expression, one concluded id",
65+
"licenses": [
66+
{
67+
"expression": "GPL-3.0-or-later OR GPL-2.0",
68+
"acknowledgement": "declared"
69+
},
70+
{
71+
"license": {
72+
"id": "GPL-3.0-only",
73+
"acknowledgement": "concluded"
74+
}
75+
}
76+
]
77+
}
78+
]
79+
}
Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
<?xml version="1.0"?>
2+
<bom xmlns="http://cyclonedx.org/schema/bom/1.6"
3+
serialNumber="urn:uuid:df628836-6b9b-41c9-a724-b44743c54d42"
4+
>
5+
<!--
6+
All license posture in here is for show-case ony.
7+
This is not a real law-case!
8+
-->
9+
<metadata>
10+
<lifecycles><lifecycle><phase>design</phase></lifecycle></lifecycles>
11+
</metadata>
12+
<components>
13+
<component type="library">
14+
<group>com.example</group>
15+
<name>situation-A</name>
16+
<version>1</version>
17+
<description>Multiple licenses: declared ids/names, and a concluded expression</description>
18+
<licenses>
19+
<license acknowledgement="declared"><id>MIT</id></license>
20+
<license acknowledgement="declared"><id>PostgreSQL</id></license>
21+
<license acknowledgement="declared"><name>Apache Software License</name></license>
22+
<expression acknowledgement="concluded">(MIT OR PostgreSQL OR Apache-2.0)</expression>
23+
</licenses>
24+
</component>
25+
<component type="library">
26+
<group>com.example</group>
27+
<name>situation-B</name>
28+
<version>1</version>
29+
<description>Multiple license expressions: one declared, one concluded</description>
30+
<licenses>
31+
<expression acknowledgement="declared">MIT OR (GPL-3.0 OR GPL-2.0)</expression>
32+
<expression acknowledgement="concluded">(GPL-3.0-only AND LGPL-2.0-only)</expression>
33+
</licenses>
34+
</component>
35+
<component type="library">
36+
<group>com.example</group>
37+
<name>situation-C</name>
38+
<version>1</version>
39+
<description>Multiple license: one declared expression, one concluded id</description>
40+
<licenses>
41+
<expression acknowledgement="declared">GPL-3.0-or-later OR GPL-2.0</expression>
42+
<license acknowledgement="concluded"><id>GPL-3.0-only</id></license>
43+
</licenses>
44+
</component>
45+
</components>
46+
</bom>
Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
{
2+
"$schema": "http://cyclonedx.org/schema/bom-1.7.schema.json",
3+
"bomFormat": "CycloneDX",
4+
"specVersion": "1.7",
5+
"serialNumber": "urn:uuid:3e671687-395b-41f5-a30f-a58921a69b79",
6+
"version": 1,
7+
"components": [
8+
{
9+
"type": "application",
10+
"publisher": "Acme Inc",
11+
"group": "com.acme",
12+
"name": "tomcat-catalina",
13+
"version": "9.0.14",
14+
"description": "Modified version of Apache Catalina",
15+
"scope": "required",
16+
"licenses": [
17+
{
18+
"license": {
19+
"id": "Apache-2.0"
20+
}
21+
},
22+
{
23+
"expression": "EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0"
24+
},
25+
{
26+
"license": {
27+
"name": "My Own License",
28+
"text": {
29+
"content": "Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua."
30+
}
31+
}
32+
},
33+
{
34+
"expression": "LicenseRef-MIT-Style-2",
35+
"expressionDetails": [
36+
{
37+
"licenseIdentifier": "LicenseRef-MIT-Style-2",
38+
"url": "https://example.com/license"
39+
}
40+
]
41+
}
42+
]
43+
}
44+
]
45+
}
Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
# proto-file: schema/bom-1.7.proto
2+
# proto-message: Bom
3+
4+
# All license posture in here is for show-case ony.
5+
# This is not a real law-case!
6+
7+
spec_version: "1.7"
8+
serial_number: "urn:uuid:b1ef52c6-7cd8-43d5-9e42-5e69044bbe9e"
9+
version: 1
10+
components {
11+
type: CLASSIFICATION_APPLICATION
12+
publisher: "Acme Inc"
13+
group: "com.acme"
14+
name: "tomcat-catalina"
15+
version: "9.0.14"
16+
description: "Modified version of Apache Catalina"
17+
scope: SCOPE_REQUIRED
18+
licenses {
19+
license {
20+
id: "Apache-2.0"
21+
}
22+
}
23+
licenses {
24+
expression: "EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0"
25+
}
26+
licenses {
27+
license {
28+
name: "My Own License"
29+
text {
30+
value: "Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua."
31+
}
32+
}
33+
}
34+
licenses {
35+
expression_detailed {
36+
expression: "LicenseRef-MIT-Style-2"
37+
details {
38+
license_identifier: "LicenseRef-MIT-Style-2"
39+
url: "https://example.com/license"
40+
}
41+
}
42+
}
43+
}

tools/src/test/resources/1.7/invalid-license-choice-1.7.xml renamed to tools/src/test/resources/1.7/valid-license-choice-1.7.xml

Lines changed: 13 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,8 @@
11
<?xml version="1.0"?>
2-
<bom serialNumber="urn:uuid:3e671687-395b-41f5-a30f-a58921a69b79" version="1" xmlns="http://cyclonedx.org/schema/bom/1.7">
2+
<bom xmlns="http://cyclonedx.org/schema/bom/1.7"
3+
serialNumber="urn:uuid:b1ef52c6-7cd8-43d5-9e42-5e69044bbe9e"
4+
version="1"
5+
>
36
<components>
47
<component type="application">
58
<publisher>Acme Inc</publisher>
@@ -8,17 +11,20 @@
811
<version>9.0.14</version>
912
<description>Modified version of Apache Catalina</description>
1013
<scope>required</scope>
11-
<hashes>
12-
<hash alg="MD5">3942447fac867ae5cdb3229b658f4d48</hash>
13-
<hash alg="SHA-1">e6b1000b94e835ffd37f4c6dcbdad43f4b48a02a</hash>
14-
<hash alg="SHA-256">f498a8ff2dd007e29c2074f5e4b01a9a01775c3ff3aeaf6906ea503bc5791b7b</hash>
15-
<hash alg="SHA-512">e8f33e424f3f4ed6db76a482fde1a5298970e442c531729119e37991884bdffab4f9426b7ee11fccd074eeda0634d71697d6f88a460dce0ac8d627a29f7d1282</hash>
16-
</hashes>
1714
<licenses>
1815
<license>
1916
<id>Apache-2.0</id>
2017
</license>
2118
<expression>EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0</expression>
19+
<license>
20+
<name>My Own License</name>
21+
<text><![CDATA[Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.]]></text>
22+
</license>
23+
<expression-detailed expression="LicenseRef-MIT-Style-2">
24+
<details license-identifier="LicenseRef-MIT-Style-2">
25+
<url>https://example.com/license</url>
26+
</details>
27+
</expression-detailed>
2228
</licenses>
2329
<purl>pkg:maven/com.acme/[email protected]?packaging=jar</purl>
2430
</component>

0 commit comments

Comments
 (0)