Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: support for external components with version-ranges #586

Open
wants to merge 23 commits into
base: 1.7-dev
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from 14 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
17 changes: 15 additions & 2 deletions schema/bom-1.7.proto
Original file line number Diff line number Diff line change
Expand Up @@ -106,8 +106,17 @@
optional string group = 7;
// The name of the component. This will often be a shortened, single name of the component. Examples: commons-lang3 and jquery
string name = 8;
// The component version. The version should ideally comply with semantic versioning but is not enforced. Version was made optional in v1.4 of the spec. For backward compatibility, it is recommended to use an empty string to represent components without version information.
string version = 9;
oneof versionChoice {

Check failure on line 109 in schema/bom-1.7.proto

View workflow job for this annotation

GitHub Actions / test

Oneof name "versionChoice" should be lower_snake_case, such as "version_choice".
// The component version. The version should ideally comply with semantic versioning but is not enforced.
// Version was made optional in v1.4 of the spec.
// For backward compatibility, it is recommended to use an empty string to represent components without version information.
string version = 9;
// For an extraneous component, this is the accepted version range.
// Value MUST follow Package URL Version Range syntax (vers)which is defined at <https://github.com/package-url/purl-spec/blob/master/VERSION-RANGE-SPEC.rst>.
// MAY only occur if property `isExtraneous` is set to 'true'.
// MUST NOT be used for `Bom.metadata.component`.
string versionRange = 33;
}
// Specifies a description for the component
optional string description = 10;
// Specifies the scope of the component. If a scope is not specified, SCOPE_REQUIRED scope should be assumed by the consumer of the BOM
Expand Down Expand Up @@ -154,6 +163,10 @@
repeated string omniborId = 31;
// Specifies the Software Heritage persistent identifier (SWHID). The SWHID, if specified, must be valid and conform to the specification defined at: https://docs.softwareheritage.org/devel/swh-model/persistent-identifiers.html
repeated string swhid = 32;
// Whether this component is extraneous.
// An extraneous component is not part of an assembly, but is (expected to be) provided by the environment, regardless of the component's `scope`.
// MUST be of value `false` for `Bom.metadata.component`.
optional bool isExtraneous = 34; // implicit defaults to `false`
}

// Specifies the data flow.
Expand Down
26 changes: 25 additions & 1 deletion schema/bom-1.7.schema.json
Original file line number Diff line number Diff line change
Expand Up @@ -925,6 +925,18 @@
"title": "Component Version",
"description": "The component version. The version should ideally comply with semantic versioning but is not enforced."
},
"versionRange": {
"$ref": "#/definitions/versionRange",
"title": "Component Version Range",
"description": "For an extraneous component, this is the accepted version range.\nValue MUST follow Package URL Version Range syntax (vers)which is defined at <https://github.com/package-url/purl-spec/blob/master/VERSION-RANGE-SPEC.rst>.\nMAY only occur if property `.isExtraneous` is set to 'true'.\nMUST NOT be used for `$.metadata.component`.",
"$comment": "a rule is taking care of the coherence between `version`/`versionRange` and `isExtraneous`=='true'"
},
"isExtraneous": {
"type": "boolean",
"title": "Component Is Extraneous",
"description": "Whether this component is extraneous.\nAn extraneous component is not part of an assembly, but is (expected to be) provided by the environment, regardless of the component's `.scope`.\nMUST be of value `false` for `$.metadata.component`.",
"default": false
},
"description": {
"type": "string",
"title": "Component Description",
Expand Down Expand Up @@ -1096,7 +1108,19 @@
"title": "Signature",
"description": "Enveloped signature in [JSON Signature Format (JSF)](https://cyberphone.github.io/doc/security/jsf.html)."
}
}
},
"allOf": [
{
"$comment": "properties `.version` and `.versionRange` MUST NOT exist at the same time.",
"not": { "required": ["version", "versionRange"] }
},
{
"$comment": "`.versionRange` MUST only be present if `.isExtraneous` is `true`",
"if": { "properties": { "isExtraneous": { "const": false } } },
"then": { "not": { "required": ["versionRange"] } },
"else": true
}
]
},
"swid": {
"type": "object",
Expand Down
41 changes: 35 additions & 6 deletions schema/bom-1.7.xsd
Original file line number Diff line number Diff line change
Expand Up @@ -554,12 +554,25 @@ limitations under the License.
of the component. Examples: commons-lang3 and jquery</xs:documentation>
</xs:annotation>
</xs:element>
<xs:element name="version" type="bom:versionType" minOccurs="0" maxOccurs="1">
<xs:annotation>
<xs:documentation>The component version. The version should ideally comply with semantic versioning
but is not enforced.</xs:documentation>
</xs:annotation>
</xs:element>
<xs:choice minOccurs="0" maxOccurs="1">
<xs:element name="version" type="bom:versionType">
<xs:annotation>
<xs:documentation>The component version. The version should ideally comply with semantic versioning
but is not enforced.</xs:documentation>
</xs:annotation>
</xs:element>
<xs:element name="versionRange" type="bom:versionRangeType">
<xs:annotation>
<xs:documentation><![CDATA[
For an extraneous component, this is the accepted version range.
Value MUST follow Package URL Version Range syntax (vers)which is defined at <https://github.com/package-url/purl-spec/blob/master/VERSION-RANGE-SPEC.rst>.
The component version range that may be provided to fulfill this capability.
MAY only occur if attribute `@isExtraneous` is set to `true`.
MUST NOT be used for `/metadata/component`.
]]></xs:documentation>
</xs:annotation>
</xs:element>
</xs:choice>
<xs:element name="description" type="xs:normalizedString" minOccurs="0" maxOccurs="1">
<xs:annotation>
<xs:documentation>Specifies a description for the component</xs:documentation>
Expand Down Expand Up @@ -745,6 +758,15 @@ limitations under the License.
</xs:documentation>
</xs:annotation>
</xs:attribute>
<xs:attribute name="isExtraneous" type="xs:boolean" use="optional" default="false">
<xs:annotation>
<xs:documentation>
Whether this component is extraneous.
An extraneous component is not part of an assembly, but is (expected to be) provided by the environment, regardless of the component's `.scope`.
MUST be of value `false` for `/metadata/component`.
</xs:documentation>
</xs:annotation>
</xs:attribute>
<xs:attribute name="bom-ref" type="bom:refType">
<xs:annotation>
<xs:documentation>
Expand All @@ -759,6 +781,13 @@ limitations under the License.
do not have the same name as an existing attribute used by the schema.</xs:documentation>
</xs:annotation>
</xs:anyAttribute>
<!-- Attention:
This would be formal, if the support for XSD1.1's `assert` was properly implemented in validators and tools digesting XML.
<xs:assert id="versionRange_requires_isExtraneous_eq_true"
test="if (versionRange) then (@isExtraneous eq 'true') else true()">
Child `versionRange` MAY only be present, if attribute `isExtraneous`=='true'.
</xs:assert>
-->
</xs:complexType>

<xs:complexType name="licenseType">
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
<?xml version="1.0"?>
<bom xmlns="http://cyclonedx.org/schema/bom/1.7"
serialNumber="urn:uuid:3e671687-395b-41f5-a30f-a58921a69b79" version="1"
>
<!--
this would be formal, if the support for XSD1.1's `assert` was properly implemented
in validators and tools digesting XML.
-->
<components>
<component type="library" isExtraneous="false">
<name>InvalidVersions</name>
<versionRange><![CDATA[vers:pypi/0.0.0|0.0.1|0.0.2|0.0.3|1.0|2.0pre1]]></versionRange>
<description>versionRange may only exist on extraneous components, set `isExtraneous` explicit</description>
</component>
</components>
</bom>
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
<?xml version="1.0"?>
<bom xmlns="http://cyclonedx.org/schema/bom/1.7"
serialNumber="urn:uuid:3e671687-395b-41f5-a30f-a58921a69b79" version="1"
>
<!--
this would be formal, if the support for XSD1.1's `assert` was properly implemented
in validators and tools digesting XML.
-->
<components>
<component type="library">
<!-- @isExtraneous defaults to `false` -->
<name>InvalidVersions</name>
<versionRange><![CDATA[vers:pypi/0.0.0|0.0.1|0.0.2|0.0.3|1.0|2.0pre1]]></versionRange>
<description>versionRange may only exist on extraneous components, set `isExtraneous` implicit by default value</description>
</component>
</components>
</bom>
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
{
"$schema": "http://cyclonedx.org/schema/bom-1.7.schema.json",
"bomFormat": "CycloneDX",
"specVersion": "1.7",
"serialNumber": "urn:uuid:3e671687-395b-41f5-a30f-a58921a69b79",
"version": 1,
"components": [
{
"type": "library",
"name": "InvalidVersions",
"description": "may have `version` or `versionRange`, not both. This one does - it is invalid",
"version": "9.0.14",
"versionRange": "vers:pypi/0.0.0|0.0.1|0.0.2|0.0.3|1.0|2.0pre1",
"isExtraneous": true
}
]
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
<?xml version="1.0"?>
<bom xmlns="http://cyclonedx.org/schema/bom/1.7"
serialNumber="urn:uuid:3e671687-395b-41f5-a30f-a58921a69b79" version="1"
>
<components>
<component type="library" isExtraneous="true">
<name>InvalidVersions</name>
<version>9.0.14</version>
<versionRange><![CDATA[vers:pypi/0.0.0|0.0.1|0.0.2|0.0.3|1.0|2.0pre1]]></versionRange>
<description>may have `version` or `versionRange`, not both. This one does - it is invalid</description>
</component>
</components>
</bom>
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
{
"$schema": "http://cyclonedx.org/schema/bom-1.7.schema.json",
"bomFormat": "CycloneDX",
"specVersion": "1.7",
"serialNumber": "urn:uuid:3e671687-395b-41f5-a30f-a58921a69b79",
"version": 1,
"components": [
{
"type": "library",
"name": "InvalidVersions",
"description": "versionRange may only exist on extraneous components; set `.isExtraneous` explicit",
"isExtraneous": false,
"versionRange": "vers:pypi/0.0.0|0.0.1|0.0.2|0.0.3|1.0|2.0pre1"
}
]
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
{
"$schema": "http://cyclonedx.org/schema/bom-1.7.schema.json",
"bomFormat": "CycloneDX",
"specVersion": "1.7",
"serialNumber": "urn:uuid:3e671687-395b-41f5-a30f-a58921a69b79",
"version": 1,
"components": [
{
"type": "library",
"name": "InvalidVersions",
"description": "versionRange may only exist on extraneous components; set `.isExtraneous` implicit by default value",
"versionRange": "vers:pypi/0.0.0|0.0.1|0.0.2|0.0.3|1.0|2.0pre1"
}
]
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
{
"$schema": "http://cyclonedx.org/schema/bom-1.7.schema.json",
"bomFormat": "CycloneDX",
"specVersion": "1.7",
"serialNumber": "urn:uuid:3e671687-395b-41f5-a30f-a58921a69b79",
"version": 1,
"components": [
{
"type": "library",
"name": "Foo",
"description": "extraneous without any version constraints",
"isExtraneous": true
}
]
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
<?xml version="1.0"?>
<bom xmlns="http://cyclonedx.org/schema/bom/1.7"
serialNumber="urn:uuid:3e671687-395b-41f5-a30f-a58921a69b79" version="1"
>
<components>
<component type="library" isExtraneous="true">
<name>Foo</name>
<description>extraneous without any version constraints</description>
</component>
</components>
</bom>
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
{
"$schema": "http://cyclonedx.org/schema/bom-1.7.schema.json",
"bomFormat": "CycloneDX",
"specVersion": "1.7",
"serialNumber": "urn:uuid:3e671687-395b-41f5-a30f-a58921a69b79",
"version": 1,
"components": [
{
"type": "library",
"name": "Foo",
"description": "extraneous with version constraint",
"isExtraneous": true,
"version": "9.1.24"
}
]
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
# proto-file: schema/bom-1.7.proto
# proto-message: Bom

spec_version: "1.7"
version: 1
serial_number: "urn:uuid:3e671687-395b-41f5-a30f-a58921a69b79"
components {
type: CLASSIFICATION_LIBRARY
name: "Foo"
description: "extraneous with version constraint",
isExtraneous: true
version: "9.1.24"
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
<?xml version="1.0"?>
<bom xmlns="http://cyclonedx.org/schema/bom/1.7"
serialNumber="urn:uuid:3e671687-395b-41f5-a30f-a58921a69b79" version="1"
>
<components>
<component type="library" isExtraneous="true">
<name>Foo</name>
<version>9.1.24</version>
<description>extraneous with version constraint</description>
</component>
</components>
</bom>
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
{
"$schema": "http://cyclonedx.org/schema/bom-1.7.schema.json",
"bomFormat": "CycloneDX",
"specVersion": "1.7",
"serialNumber": "urn:uuid:3e671687-395b-41f5-a30f-a58921a69b79",
"version": 1,
"components": [
{
"type": "library",
"name": "Foo",
"description": "extraneous with version range constraints",
"isExtraneous": true,
"versionRange": "vers:pypi/0.0.0|0.0.1|0.0.2|0.0.3|1.0|2.0pre1"
}
]
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
# proto-file: schema/bom-1.7.proto
# proto-message: Bom

spec_version: "1.7"
version: 1
serial_number: "urn:uuid:3e671687-395b-41f5-a30f-a58921a69b79"
components {
type: CLASSIFICATION_LIBRARY
name: "Foo"
description: "extraneous with version range constraints"
isExtraneous: true
versionRange: "vers:pypi/0.0.0|0.0.1|0.0.2|0.0.3|1.0|2.0pre1"
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
<?xml version="1.0"?>
<bom xmlns="http://cyclonedx.org/schema/bom/1.7"
serialNumber="urn:uuid:3e671687-395b-41f5-a30f-a58921a69b79" version="1"
>
<components>
<component type="library" isExtraneous="true">
<name>Foo</name>
<versionRange><![CDATA[vers:pypi/0.0.0|0.0.1|0.0.2|0.0.3|1.0|2.0pre1]]></versionRange>
<description>extraneous with version range constraints</description>
</component>
</components>
</bom>
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
{
"$schema": "http://cyclonedx.org/schema/bom-1.7.schema.json",
"bomFormat": "CycloneDX",
"specVersion": "1.7",
"serialNumber": "urn:uuid:3e671687-395b-41f5-a30f-a58921a69b79",
"version": 1,
"components": [
{
"type": "library",
"name": "Foo",
"description": "extraneous without version constraint",
"isExtraneous": true
}
]
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
# proto-file: schema/bom-1.7.proto
# proto-message: Bom

spec_version: "1.7"
version: 1
serial_number: "urn:uuid:3e671687-395b-41f5-a30f-a58921a69b79"
components {
type: CLASSIFICATION_LIBRARY
name: "Foo"
description: "extraneous without version constraint",
isExtraneous: true
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
<?xml version="1.0"?>
<bom xmlns="http://cyclonedx.org/schema/bom/1.7"
serialNumber="urn:uuid:3e671687-395b-41f5-a30f-a58921a69b79" version="1"
>
<components>
<component type="library" isExtraneous="true">
<name>Foo</name>
<description>extraneous without version constraint</description>
</component>
</components>
</bom>
Loading