Skip to content

Commit 5f404e6

Browse files
authored
feat: add CycloneDX document validators to public API (#433)
Signed-off-by: Jan Kowalleck <[email protected]>
1 parent e55437b commit 5f404e6

File tree

499 files changed

+15182
-5259
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

499 files changed

+15182
-5259
lines changed

.github/workflows/python.yml

+22-18
Original file line numberDiff line numberDiff line change
@@ -49,21 +49,21 @@ jobs:
4949
run: poetry run tox run -e flake8 -s false
5050

5151
static-code-analysis:
52-
name: StaticCodingAnalysis (py${{ matrix.python-version}} ${{ matrix.toxenv-factor }})
52+
name: StaticCodingAnalysis (py${{ matrix.python-version}} ${{ matrix.toxenv-factors }})
5353
runs-on: ${{ matrix.os }}
5454
timeout-minutes: 10
5555
strategy:
5656
fail-fast: false
5757
matrix:
5858
include:
59-
- # test with the locked dependencies
59+
- # test with the latest dependencies
6060
os: ubuntu-latest
6161
python-version: '3.11'
62-
toxenv-factor: 'locked'
62+
toxenv-factors: '-current'
6363
- # test with the lowest dependencies
6464
os: ubuntu-latest
6565
python-version: '3.8'
66-
toxenv-factor: 'lowest'
66+
toxenv-factors: '-lowest'
6767
steps:
6868
- name: Checkout
6969
# see https://github.com/actions/checkout
@@ -82,10 +82,10 @@ jobs:
8282
- name: Install dependencies
8383
run: poetry install --no-root
8484
- name: Run tox
85-
run: poetry run tox run -e mypy-${{ matrix.toxenv-factor }} -s false
85+
run: poetry run tox run -e mypy${{ matrix.toxenv-factors }} -s false
8686

8787
build-and-test:
88-
name: Test (${{ matrix.os }} py${{ matrix.python-version }} ${{ matrix.toxenv-factor }})
88+
name: Test (${{ matrix.os }} py${{ matrix.python-version }} ${{ matrix.toxenv-factors }})
8989
runs-on: ${{ matrix.os }}
9090
timeout-minutes: 15
9191
strategy:
@@ -97,12 +97,9 @@ jobs:
9797
- "3.10"
9898
- "3.9"
9999
- "3.8" # lowest supported
100-
toxenv-factor: ['locked']
101-
include:
102-
- # test with the lowest dependencies
103-
os: ubuntu-latest
104-
python-version: '3.8'
105-
toxenv-factor: 'lowest'
100+
toxenv-factors:
101+
- '-allExtras'
102+
- '-noExtras'
106103
steps:
107104
- name: Disabled Git auto EOL CRLF transforms
108105
run: |
@@ -134,14 +131,14 @@ jobs:
134131
- name: Ensure build successful
135132
run: poetry build
136133
- name: Run tox
137-
run: poetry run tox run -e py-${{ matrix.toxenv-factor }} -s false
134+
run: poetry run tox run -e py${{ matrix.toxenv-factors }} -s false
138135
- name: Generate coverage reports
139136
shell: bash
140137
run: |
141138
set -eux
142139
poetry run coverage report
143-
poetry run coverage xml -o "$REPORTS_DIR/coverage.${{ matrix.os }}_py${{ matrix.python-version }}_${{ matrix.toxenv-factor }}.cobertura.xml"
144-
# poetry run coverage lcov -o "$REPORTS_DIR/coverage.${{ matrix.os }}_py${{ matrix.python-version }}_${{ matrix.toxenv-factor }}.lcov.xml"
140+
poetry run coverage xml -o "$REPORTS_DIR/coverage.${{ matrix.os }}_py${{ matrix.python-version }}_${{ matrix.toxenv-factors }}.cobertura.xml"
141+
# poetry run coverage lcov -o "$REPORTS_DIR/coverage.${{ matrix.os }}_py${{ matrix.python-version }}_${{ matrix.toxenv-factors }}.lcov.xml"
145142
- name: Artifact reports
146143
if: ${{ ! cancelled() }}
147144
# see https://github.com/actions/upload-artifact
@@ -174,9 +171,16 @@ jobs:
174171
coverage-reports: ${{ env.REPORTS_DIR }}/coverage.*
175172

176173
examples:
177-
name: Examples
174+
name: Examples E:${{ matrix.install-extras || '<none>' }}
178175
runs-on: ubuntu-latest
179-
timeout-minutes: 15
176+
timeout-minutes: 10
177+
strategy:
178+
fail-fast: false
179+
matrix:
180+
install-extras:
181+
- '' # none
182+
- json-validation
183+
- xml-validation
180184
steps:
181185
- name: Checkout
182186
# see https://github.com/actions/checkout
@@ -197,7 +201,7 @@ jobs:
197201
with:
198202
poetry-version: ${{ env.POETRY_VERSION }}
199203
- name: Install package and prod dependencies
200-
run: poetry install --only=main -vvv
204+
run: poetry install --only=main --extras='${{ matrix.install-extras }}' -vvv
201205
- name: run all examples
202206
run: >
203207
find examples -type f -name '*.py' -print0

.isort.cfg

+2
Original file line numberDiff line numberDiff line change
@@ -20,3 +20,5 @@ src_paths =
2020
cyclonedx
2121
tests
2222
typings
23+
examples
24+
tools

CONTRIBUTING.md

+2-2
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ This project uses [poetry]. Have it installed and setup first.
1212
To install dev-dependencies and tools:
1313

1414
```shell
15-
poetry install
15+
poetry install --all-extras
1616
```
1717

1818
## Code style
@@ -23,7 +23,7 @@ Get it all applied via:
2323

2424
```shell
2525
poetry run isort .
26-
poetry run autopep8 -ir cyclonedx/ tests/ typings/
26+
poetry run autopep8 -ir cyclonedx/ tests/ typings/ examples/
2727
```
2828

2929
## Documentation

cyclonedx/exception/__init__.py

+5
Original file line numberDiff line numberDiff line change
@@ -25,3 +25,8 @@ class CycloneDxException(Exception):
2525
Root exception thrown by this library.
2626
"""
2727
pass
28+
29+
30+
class MissingOptionalDependencyException(CycloneDxException):
31+
"""Validation did not happen, due to missing dependencies."""
32+
pass

cyclonedx/schema/_res/.editorconfig

+10
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
2+
# fix settings for files that are copied over, to keep them as is
3+
[*.SNAPSHOT.xsd]
4+
indent_size = 4
5+
indent_style = space
6+
trim_trailing_whitespace = false
7+
[*.SNAPSHOT.schema.json]
8+
indent_size = 2
9+
indent_style = space
10+
trim_trailing_whitespace = false

cyclonedx/schema/_res/.gitattributes

+6
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
# snapshots are vendored for offline use
2+
*.SNAPSHOT.* linguist-vendored
3+
4+
# specs are vendored for offline use
5+
*.xsd linguist-vendored
6+
*.schema.json linguist-vendored

cyclonedx/schema/_res/README.md

+30
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
# Resources: Schema files
2+
3+
some schema for offline use as download via [script](../../../tools/schema-downloader.py).
4+
original sources: <https://github.com/CycloneDX/specification/tree/master/schema>
5+
6+
Currently using version
7+
[fd4d383658196992364e5d62568a48c431ace515](https://github.com/CycloneDX/specification/commit/fd4d383658196992364e5d62568a48c431ace515)
8+
9+
| file | note |
10+
|------|------|
11+
| [`bom-1.0.SNAPSHOT.xsd`](bom-1.0.SNAPSHOT.xsd) | applied changes: 1 |
12+
| [`bom-1.1.SNAPSHOT.xsd`](bom-1.1.SNAPSHOT.xsd) | applied changes: 1 |
13+
| [`bom-1.2.SNAPSHOT.xsd`](bom-1.2.SNAPSHOT.xsd) | applied changes: 1 |
14+
| [`bom-1.3.SNAPSHOT.xsd`](bom-1.3.SNAPSHOT.xsd) | applied changes: 1 |
15+
| [`bom-1.4.SNAPSHOT.xsd`](bom-1.4.SNAPSHOT.xsd) | applied changes: 1 |
16+
| [`bom-1.2.SNAPSHOT.schema.json`](bom-1.2.SNAPSHOT.schema.json) | applied changes: 2,3,4,5 |
17+
| [`bom-1.3.SNAPSHOT.schema.json`](bom-1.3.SNAPSHOT.schema.json) | applied changes: 2,3,4,5 |
18+
| [`bom-1.4.SNAPSHOT.schema.json`](bom-1.4.SNAPSHOT.schema.json) | applied changes: 2,3,4,5 |
19+
| [`bom-1.2-strict.SNAPSHOT.schema.json`](bom-1.2-strict.SNAPSHOT.schema.json) | applied changes: 2,3,4,5 |
20+
| [`bom-1.3-strict.SNAPSHOT.schema.json`](bom-1.3-strict.SNAPSHOT.schema.json) | applied changes: 2,3,4,5 |
21+
| [`spdx.SNAPSHOT.xsd`](spdx.SNAPSHOT.xsd) | |
22+
| [`spdx.SNAPSHOT.schema.json`](spdx.SNAPSHOT.schema.json) | |
23+
| [`jsf-0.82.SNAPSHOT.schema.json`](jsf-0.82.SNAPSHOT.schema.json) | |
24+
25+
changes:
26+
1. `https?://cyclonedx.org/schema/spdx` was replaced with `spdx.SNAPSHOT.xsd`
27+
2. `spdx.schema.json` was replaced with `spdx.SNAPSHOT.schema.json`
28+
3. `jsf-0.82.schema.json` was replaced with `jsf-0.82.SNAPSHOT.schema.json`
29+
4. `properties.$schema.enum` was fixed to match `$id`
30+
5. `required.version` removed, as it is actually optional with default value

cyclonedx/schema/_res/__init__.py

+60
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,60 @@
1+
# encoding: utf-8
2+
3+
# Licensed under the Apache License, Version 2.0 (the "License");
4+
# you may not use this file except in compliance with the License.
5+
# You may obtain a copy of the License at
6+
#
7+
# http://www.apache.org/licenses/LICENSE-2.0
8+
#
9+
# Unless required by applicable law or agreed to in writing, software
10+
# distributed under the License is distributed on an "AS IS" BASIS,
11+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
# See the License for the specific language governing permissions and
13+
# limitations under the License.
14+
#
15+
# SPDX-License-Identifier: Apache-2.0
16+
17+
from os.path import dirname, join
18+
from typing import Dict, Optional
19+
20+
from .. import SchemaVersion
21+
22+
"""
23+
Content in here is internal, not for public use.
24+
Breaking changes without notice may happen.
25+
"""
26+
27+
__DIR = dirname(__file__)
28+
29+
BOM_XML: Dict[SchemaVersion, Optional[str]] = {
30+
SchemaVersion.V1_4: join(__DIR, 'bom-1.4.SNAPSHOT.xsd'),
31+
SchemaVersion.V1_3: join(__DIR, 'bom-1.3.SNAPSHOT.xsd'),
32+
SchemaVersion.V1_2: join(__DIR, 'bom-1.2.SNAPSHOT.xsd'),
33+
SchemaVersion.V1_1: join(__DIR, 'bom-1.1.SNAPSHOT.xsd'),
34+
SchemaVersion.V1_0: join(__DIR, 'bom-1.0.SNAPSHOT.xsd'),
35+
}
36+
37+
BOM_JSON: Dict[SchemaVersion, Optional[str]] = {
38+
SchemaVersion.V1_4: join(__DIR, 'bom-1.4.SNAPSHOT.schema.json'),
39+
SchemaVersion.V1_3: join(__DIR, 'bom-1.3.SNAPSHOT.schema.json'),
40+
SchemaVersion.V1_2: join(__DIR, 'bom-1.2.SNAPSHOT.schema.json'),
41+
# <= v1.1 is not defined in JSON
42+
SchemaVersion.V1_1: None,
43+
SchemaVersion.V1_0: None,
44+
}
45+
46+
BOM_JSON_STRICT: Dict[SchemaVersion, Optional[str]] = {
47+
# >= v1.4 is already strict - no special file here
48+
SchemaVersion.V1_4: join(__DIR, 'bom-1.4.SNAPSHOT.schema.json'),
49+
# <= 1.3 need special files
50+
SchemaVersion.V1_3: join(__DIR, 'bom-1.3-strict.SNAPSHOT.schema.json'),
51+
SchemaVersion.V1_2: join(__DIR, 'bom-1.2-strict.SNAPSHOT.schema.json'),
52+
# <= v1.1 is not defined in JSON
53+
SchemaVersion.V1_1: None,
54+
SchemaVersion.V1_0: None,
55+
}
56+
57+
SPDX_JSON = join(__DIR, 'spdx.SNAPSHOT.schema.json')
58+
SPDX_XML = join(__DIR, 'spdx.SNAPSHOT.xsd')
59+
60+
JSF = join(__DIR, 'jsf-0.82.SNAPSHOT.schema.json')

cyclonedx/schema/bom-1.0.xsd renamed to cyclonedx/schema/_res/bom-1.0.SNAPSHOT.xsd

+2-2
Original file line numberDiff line numberDiff line change
@@ -7,9 +7,9 @@
77
targetNamespace="http://cyclonedx.org/schema/bom/1.0"
88
vc:minVersion="1.0"
99
vc:maxVersion="1.1"
10-
version="1.0">
10+
version="1.0.1">
1111

12-
<xs:import namespace="http://cyclonedx.org/schema/spdx" schemaLocation="spdx.xsd"/>
12+
<xs:import namespace="http://cyclonedx.org/schema/spdx" schemaLocation="spdx.SNAPSHOT.xsd"/>
1313

1414
<xs:complexType name="component">
1515
<xs:sequence>

cyclonedx/schema/bom-1.1.xsd renamed to cyclonedx/schema/_res/bom-1.1.SNAPSHOT.xsd

+9-2
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@ limitations under the License.
2424
vc:maxVersion="1.1"
2525
version="1.1">
2626

27-
<xs:import namespace="http://cyclonedx.org/schema/spdx" schemaLocation="spdx.xsd"/>
27+
<xs:import namespace="http://cyclonedx.org/schema/spdx" schemaLocation="spdx.SNAPSHOT.xsd"/>
2828

2929
<xs:annotation>
3030
<xs:documentation>
@@ -38,6 +38,13 @@ limitations under the License.
3838
</xs:documentation>
3939
</xs:annotation>
4040

41+
<xs:simpleType name="refType">
42+
<xs:annotation>
43+
<xs:documentation>Identifier-DataType for interlinked elements.</xs:documentation>
44+
</xs:annotation>
45+
<xs:restriction base="xs:string" />
46+
</xs:simpleType>
47+
4148
<xs:complexType name="componentsType">
4249
<xs:sequence minOccurs="0" maxOccurs="unbounded">
4350
<xs:element name="component" type="bom:component"/>
@@ -201,7 +208,7 @@ limitations under the License.
201208
</xs:documentation>
202209
</xs:annotation>
203210
</xs:attribute>
204-
<xs:attribute name="bom-ref" type="xs:string">
211+
<xs:attribute name="bom-ref" type="bom:refType">
205212
<xs:annotation>
206213
<xs:documentation>
207214
An optional identifier which can be used to reference the component elsewhere in the BOM.

cyclonedx/schema/bom-1.2b.schema.json renamed to cyclonedx/schema/_res/bom-1.2-strict.SNAPSHOT.schema.json

+11-9
Original file line numberDiff line numberDiff line change
@@ -6,15 +6,14 @@
66
"$comment" : "CycloneDX JSON schema is published under the terms of the Apache License 2.0.",
77
"required": [
88
"bomFormat",
9-
"specVersion",
10-
"version"
9+
"specVersion"
1110
],
1211
"additionalProperties": false,
1312
"properties": {
1413
"$schema": {
1514
"type": "string",
1615
"enum": [
17-
"http://cyclonedx.org/schema/bom-1.2a.schema.json"
16+
"http://cyclonedx.org/schema/bom-1.2b.schema.json"
1817
]
1918
},
2019
"bomFormat": {
@@ -87,6 +86,10 @@
8786
}
8887
},
8988
"definitions": {
89+
"refType": {
90+
"$comment": "Identifier-DataType for interlinked elements.",
91+
"type": "string"
92+
},
9093
"metadata": {
9194
"type": "object",
9295
"title": "BOM Metadata Object",
@@ -261,7 +264,7 @@
261264
"pattern": "^[-+a-z0-9.]+/[-+a-z0-9.]+$"
262265
},
263266
"bom-ref": {
264-
"type": "string",
267+
"$ref": "#/definitions/refType",
265268
"title": "BOM Reference",
266269
"description": "An optional identifier which can be used to reference the component elsewhere in the BOM. Every bom-ref should be unique.",
267270
"default": "",
@@ -595,7 +598,7 @@
595598
"additionalProperties": false,
596599
"properties": {
597600
"id": {
598-
"$ref": "spdx.schema.json",
601+
"$ref": "spdx.SNAPSHOT.schema.json",
599602
"title": "License ID (SPDX)",
600603
"description": "A valid SPDX license ID",
601604
"examples": ["Apache-2.0"]
@@ -859,16 +862,15 @@
859862
"additionalProperties": false,
860863
"properties": {
861864
"ref": {
862-
"type": "string",
863-
"format": "string",
865+
"$ref": "#/definitions/refType",
864866
"title": "Reference",
865867
"description": "References a component by the components bom-ref attribute"
866868
},
867869
"dependsOn": {
868870
"type": "array",
869871
"uniqueItems": true,
870872
"items": {
871-
"type": "string"
873+
"$ref": "#/definitions/refType"
872874
},
873875
"title": "Depends On",
874876
"description": "The bom-ref identifiers of the components that are dependencies of this dependency object."
@@ -884,7 +886,7 @@
884886
"additionalProperties": false,
885887
"properties": {
886888
"bom-ref": {
887-
"type": "string",
889+
"$ref": "#/definitions/refType",
888890
"title": "BOM Reference",
889891
"description": "An optional identifier which can be used to reference the service elsewhere in the BOM. Every bom-ref should be unique.",
890892
"default": "",

0 commit comments

Comments
 (0)