Skip to content

Commit 74865f8

Browse files
jkowalleckChurro
andauthored
feat!: v6.0.0 (#492)
### Breaking Changes * Removed symbols that were already marked as deprecated (via [#493]) * Removed symbols in `parser.*` ([#489] via [#495]) * Removed `output.LATEST_SUPPORTED_SCHEMA_VERSION` ([#491] via [#494]) * Serialization of unsupported enum values might downgrade/migrate/omit them ([#490] via [#496]) Handling might raise warnings if a data loss occurred due to omitting. The result is a guaranteed valid XML/JSON, since no (enum-)invalid values are rendered. * Serialization of any `model.component.Component` with unsupported `type` raises `exception.serialization.SerializationOfUnsupportedComponentTypeException` ([#490] via [#496]) * Object `model.bom_ref.BomRef`'s property `value` defaults to `Null`, was arbitrary `UUID` ([#504] via [#505]) This change does not affect serialization. All `bom-ref`s are guaranteed to have unique values on rendering. * Removed helpers from public API ([#503] via [#506]) ### Added * Basic support for CycloneDX 1.5 ([#404] via [#488]) * No data models were enhanced nor added, yet. Pull requests to add functionality are welcome. * Existing enumerable got new cases, to reflect features of CycloneDX 1.5 ([#404] via [#488]) * Outputters were enabled to render CycloneDX 1.5 ([#404] via [#488]) ### Tests * Created (regression/unit/integration/functional) tests for CycloneDX 1.5 ([#404] via [#488]) * Created (regression/functional) tests for Enums' handling and completeness ([#490] via [#496]) ### Misc * Bumped dependency `py-serializable@^0.16`, was `@^0.15` (via [#496]) ---- ### API Changes — the details for migration * Added new sub-package `exception.serialization` (via [#496]) * Removed class `models.ComparableTuple` ([#503] via [#506]) * Enum `model.ExternalReferenceType` got new cases, to reflect features for CycloneDX 1.5 ([#404] via [#488]) * Removed function `models.get_now_utc` ([#503] via [#506]) * Removed function `models.sha1sum` ([#503] via [#506]) * Enum `model.component.ComponentType` got new cases, to reflect features for CycloneDX 1.5 ([#404] via [#488]) * Removed `model.component.Component.__init__()`'s deprecated optional kwarg `namespace` (via [#493]) Use kwarg `group` instead. * Removed `model.component.Component.__init__()`'s deprecated optional kwarg `license_str` (via [#493]) Use kwarg `licenses` instead. * Removed deprecated method `model.component.Component.get_namespace()` (via [#493]) * Removed class `models.dependency.DependencyDependencies` ([#503] via [#506]) * Removed `model.vulnerability.Vulnerability.__init__()`'s deprecated optional kwarg `source_name` (via [#493]) Use kwarg `source` instead. * Removed `model.vulnerability.Vulnerability.__init__()`'s deprecated optional kwarg `source_url` (via [#493]) Use kwarg `source` instead. * Removed `model.vulnerability.Vulnerability.__init__()`'s deprecated optional kwarg `recommendations` (via [#493]) Use kwarg `recommendation` instead. * Removed `model.vulnerability.VulnerabilityRating.__init__()`'s deprecated optional kwarg `score_base` (via [#493]) Use kwarg `score` instead. * Enum `model.vulnerability.VulnerabilityScoreSource` got new cases, to reflect features for CycloneDX 1.5 ([#404] via [#488]) * Removed `output.LATEST_SUPPORTED_SCHEMA_VERSION` ([#491] via [#494]) * Removed deprecated function `output.get_instance()` (via [#493]) Use function `output.make_outputter()` instead. * Added new class `output.json.JsonV1Dot5`, to reflect CycloneDX 1.5 ([#404] via [#488]) * Added new item to dict `output.json.BY_SCHEMA_VERSION`, to reflect CycloneDX 1.5 ([#404] via [#488]) * Added new class `output.xml.XmlV1Dot5`, to reflect CycloneDX 1.5 ([#404] via [#488]) * Added new item to dict `output.xml.BY_SCHEMA_VERSION`, to reflect CycloneDX 1.5 ([#404] via [#488]) * Removed class `parser.ParserWarning` ([#489] via [#495]) * Removed class `parser.BaseParser` ([#489] via [#495]) * Enum `schema.SchemaVersion` got new case `V1_5`, to reflect CycloneDX 1.5 ([#404] via [#488]) [#404]: #404 [#488]: #488 [#489]: #489 [#490]: #490 [#491]: #491 [#493]: #493 [#494]: #494 [#495]: #495 [#496]: #496 [#503]: #503 [#504]: #504 [#505]: #505 [#506]: #506 --------- Signed-off-by: Johannes Feichtner <[email protected]> Signed-off-by: Jan Kowalleck <[email protected]> Signed-off-by: semantic-release <semantic-release> Co-authored-by: Johannes Feichtner <[email protected]> Co-authored-by: semantic-release <semantic-release>
1 parent 9ed9ab1 commit 74865f8

File tree

238 files changed

+23574
-737
lines changed

Some content is hidden

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

238 files changed

+23574
-737
lines changed

.github/workflows/python.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ concurrency:
2020
env:
2121
REPORTS_DIR: CI_reports
2222
PYTHON_VERSION_DEFAULT: "3.11"
23-
POETRY_VERSION: "1.4.1"
23+
POETRY_VERSION: "1.7.1"
2424
TESTS_REPORTS_ARTIFACT: tests-reports
2525

2626
jobs:

.github/workflows/release.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,7 @@ concurrency:
3939

4040
env:
4141
PYTHON_VERSION_DEFAULT: "3.11"
42-
POETRY_VERSION: "1.4.1"
42+
POETRY_VERSION: "1.7.1"
4343

4444
jobs:
4545
quicktest:

README.md

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -13,10 +13,13 @@
1313

1414
----
1515

16-
This Python package can render and read valid [CycloneDX][link_website] documents.
17-
CycloneDX is a lightweight BOM specification that is easily created, human-readable, and simple to parse.
16+
OWASP [CycloneDX][link_website] is a full-stack Bill of Materials (BOM) standard
17+
that provides advanced supply chain capabilities for cyber risk reduction.
1818

19-
**This module is not designed for standalone use.**
19+
This Python package provides data models, validators and more,
20+
to help you create/render/read CycloneDX documents.
21+
22+
**This package is not designed for standalone use. It is a library.**
2023

2124
As of version `3.0.0`, the internal data model was adjusted to allow CycloneDX VEX documents to be produced as per
2225
[official examples](https://cyclonedx.org/capabilities/bomlink/#linking-external-vex-to-bom-inventory) linking a VEX
@@ -27,6 +30,8 @@ If you're looking for a CycloneDX tool to run to generate (SBOM) software bill-o
2730

2831
Alternatively, you can use this module yourself in your application to programmatically generate CycloneDX BOMs.
2932

33+
## Documentation
34+
3035
View the documentation [here](https://cyclonedx-python-library.readthedocs.io/).
3136

3237
## Python Support

cyclonedx/__init__.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,4 +21,4 @@
2121
# !! version is managed by semantic_release
2222
# do not use typing here, or else `semantic_release` might have issues finding the variable
2323
# flake8: noqa
24-
__version__ = "5.2.0"
24+
__version__ = "6.0.0-rc.3"

cyclonedx/_internal/__init__.py

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
# Licensed under the Apache License, Version 2.0 (the "License");
2+
# you may not use this file except in compliance with the License.
3+
# You may obtain a copy of the License at
4+
#
5+
# http://www.apache.org/licenses/LICENSE-2.0
6+
#
7+
# Unless required by applicable law or agreed to in writing, software
8+
# distributed under the License is distributed on an "AS IS" BASIS,
9+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
10+
# See the License for the specific language governing permissions and
11+
# limitations under the License.
12+
#
13+
# SPDX-License-Identifier: Apache-2.0
14+
# Copyright (c) OWASP Foundation. All Rights Reserved.
15+
16+
17+
"""
18+
!!! ALL SYMBOLS IN HERE ARE INTERNAL.
19+
Everything might change without any notice.
20+
"""

cyclonedx/_internal/compare.py

Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
# Licensed under the Apache License, Version 2.0 (the "License");
2+
# you may not use this file except in compliance with the License.
3+
# You may obtain a copy of the License at
4+
#
5+
# http://www.apache.org/licenses/LICENSE-2.0
6+
#
7+
# Unless required by applicable law or agreed to in writing, software
8+
# distributed under the License is distributed on an "AS IS" BASIS,
9+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
10+
# See the License for the specific language governing permissions and
11+
# limitations under the License.
12+
#
13+
# SPDX-License-Identifier: Apache-2.0
14+
# Copyright (c) OWASP Foundation. All Rights Reserved.
15+
16+
17+
"""
18+
!!! ALL SYMBOLS IN HERE ARE INTERNAL.
19+
Everything might change without any notice.
20+
"""
21+
22+
23+
from itertools import zip_longest
24+
from typing import Any, Optional, Tuple
25+
26+
27+
class ComparableTuple(Tuple[Optional[Any], ...]):
28+
"""
29+
Allows comparison of tuples, allowing for None values.
30+
"""
31+
32+
def __lt__(self, other: Any) -> bool:
33+
for s, o in zip_longest(self, other):
34+
if s == o:
35+
continue
36+
# the idea is to have any consistent order, not necessarily "natural" order.
37+
if s is None:
38+
return False
39+
if o is None:
40+
return True
41+
return True if s < o else False
42+
return False
43+
44+
def __gt__(self, other: Any) -> bool:
45+
for s, o in zip_longest(self, other):
46+
if s == o:
47+
continue
48+
# the idea is to have any consistent order, not necessarily "natural" order.
49+
if s is None:
50+
return True
51+
if o is None:
52+
return False
53+
return True if s > o else False
54+
return False

cyclonedx/_internal/hash.py

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
# Licensed under the Apache License, Version 2.0 (the "License");
2+
# you may not use this file except in compliance with the License.
3+
# You may obtain a copy of the License at
4+
#
5+
# http://www.apache.org/licenses/LICENSE-2.0
6+
#
7+
# Unless required by applicable law or agreed to in writing, software
8+
# distributed under the License is distributed on an "AS IS" BASIS,
9+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
10+
# See the License for the specific language governing permissions and
11+
# limitations under the License.
12+
#
13+
# SPDX-License-Identifier: Apache-2.0
14+
# Copyright (c) OWASP Foundation. All Rights Reserved.
15+
16+
17+
"""
18+
!!! ALL SYMBOLS IN HERE ARE INTERNAL.
19+
Everything might change without any notice.
20+
"""
21+
22+
23+
from hashlib import sha1
24+
25+
26+
def file_sha1sum(filename: str) -> str:
27+
"""
28+
Generate a SHA1 hash of the provided file.
29+
30+
Args:
31+
filename:
32+
Absolute path to file to hash as `str`
33+
34+
Returns:
35+
SHA-1 hash
36+
"""
37+
h = sha1() # nosec B303, B324
38+
with open(filename, 'rb') as f:
39+
for byte_block in iter(lambda: f.read(4096), b''):
40+
h.update(byte_block)
41+
return h.hexdigest()

cyclonedx/_internal/time.py

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
# Licensed under the Apache License, Version 2.0 (the "License");
2+
# you may not use this file except in compliance with the License.
3+
# You may obtain a copy of the License at
4+
#
5+
# http://www.apache.org/licenses/LICENSE-2.0
6+
#
7+
# Unless required by applicable law or agreed to in writing, software
8+
# distributed under the License is distributed on an "AS IS" BASIS,
9+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
10+
# See the License for the specific language governing permissions and
11+
# limitations under the License.
12+
#
13+
# SPDX-License-Identifier: Apache-2.0
14+
# Copyright (c) OWASP Foundation. All Rights Reserved.
15+
16+
17+
"""
18+
!!! ALL SYMBOLS IN HERE ARE INTERNAL.
19+
Everything might change without any notice.
20+
"""
21+
22+
23+
from datetime import datetime, timezone
24+
25+
26+
def get_now_utc() -> datetime:
27+
return datetime.now(tz=timezone.utc)

cyclonedx/exception/model.py

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -63,7 +63,6 @@ class NoPropertiesProvidedException(CycloneDxModelException):
6363
"""
6464
Raised when attempting to construct a model class and providing NO values (where all properites are defined as
6565
Optional, but at least one is required).
66-
6766
"""
6867
pass
6968

cyclonedx/exception/serialization.py

Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
# Licensed under the Apache License, Version 2.0 (the "License");
2+
# you may not use this file except in compliance with the License.
3+
# You may obtain a copy of the License at
4+
#
5+
# http://www.apache.org/licenses/LICENSE-2.0
6+
#
7+
# Unless required by applicable law or agreed to in writing, software
8+
# distributed under the License is distributed on an "AS IS" BASIS,
9+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
10+
# See the License for the specific language governing permissions and
11+
# limitations under the License.
12+
#
13+
# SPDX-License-Identifier: Apache-2.0
14+
# Copyright (c) OWASP Foundation. All Rights Reserved.
15+
16+
17+
"""
18+
Exceptions relating to specific conditions that occur when (de)serializing/(de)normalizing CycloneDX BOM.
19+
"""
20+
21+
from . import CycloneDxException
22+
23+
24+
class CycloneDxSerializationException(CycloneDxException):
25+
"""
26+
Base exception that covers all exceptions that may be thrown during model serializing/normalizing.
27+
"""
28+
pass
29+
30+
31+
class CycloneDxDeserializationException(CycloneDxException):
32+
"""
33+
Base exception that covers all exceptions that may be thrown during model deserializing/denormalizing.
34+
"""
35+
pass
36+
37+
38+
class SerializationOfUnsupportedComponentTypeException(CycloneDxSerializationException):
39+
"""
40+
Raised when attempting serializing/normalizing a :py:class:`cyclonedx.model.component.Component`
41+
to a :py:class:`cyclonedx.schema.schema.BaseSchemaVersion`
42+
which does not support that :py:class:`cyclonedx.model.component.ComponentType`
43+
.
44+
"""
45+
46+
47+
class SerializationOfUnexpectedValueException(CycloneDxSerializationException, ValueError):
48+
"""
49+
Raised when attempting serializing/normalizing a type that is not expected there.
50+
"""

0 commit comments

Comments
 (0)