Skip to content

Commit 26b151c

Browse files
authored
feat!: v5.0.0 (#440)
BREAKING CHANGES ---------------- * Dropped support for python<3.8 ([#436] via [#441]; enable [#433]) * Reworked license related models, collections, and factories ([#365] via [#466]) * Behavior * Method `model.bom.Bom.validate()` will throw `exception.LicenseExpressionAlongWithOthersException`, if detecting invalid license constellation ([#453] via [#452]) * Fixed tuple comparison when unequal lengths (via [#461]) * API * Enum `schema.SchemaVersion` is no longer string-like ([#442] via [#447]) * Enum `schema.OutputVersion` is no longer string-like ([#442] via [#447]) * Abstract class `output.BaseOutput` requires implementation of new method `output_format` ([#446] via [#447]) * Abstract method `output.BaseOutput.output_as_string()` got new optional parameter `indent` ([#437] via [#458]) * Abstract method `output.BaseOutput.output_as_string()` accepts arbitrary kwargs (via [#458], [#462]) * Removed class `factory.license.LicenseChoiceFactory` (via [#466]) The old functionality was integrated into `factory.license.LicenseFactory`. * Method `factory.license.LicenseFactory.make_from_string()`'s parameter `name_or_spdx` was renamed to `value` (via [#466]) * Method `factory.license.LicenseFactory.make_from_string()`'s return value can also be a `LicenseExpression` ([#365] via [#466]) The behavior imitates the old `factory.license.LicenseChoiceFactory.make_from_string()` * Renamed class `module.License` to `module.license.DisjunctliveLicense` ([#365] via [#466]) * Removed class `module.LicenseChoice` ([#365] via [#466]) Use dedicated classes `module.license.DisjunctliveLicense` and `module.license.LicenseExpression` instead * All occurrences of `models.LicenseChoice` were replaced by `models.licenses.License` ([#365] via [#466]) * All occurrences of `SortedSet[LicenseChoice]` were specialized to `models.license.LicenseRepository` ([#365] via [#466]) Fixed ---------------- * Serialization of multy-licenses ([#365] via [#466]) * Detect unused "dependent" components in `model.bom.validate()` (via [#464]) Changed ---------------- * Updated latest supported list of supported SPDX license identifiers (via [#433]) * Shipped schema files are moved to a protected space (via [#433]) These files were never intended for public use. * XML output uses a default namespace, which makes results smaller. ([#438] via [#458]) Added ---------------- * Support for Python 3.12 (via [#460]) * JSON- & XML-Validators ([#432], [#446] via [#433], [#448]) The functionality might require additional dependencies, that can be installed with the extra "validation". See the docs in section "Installation" for details. * JSON & XML can be generated in a more human-friendly form ([#437], [#438] via [#458]) * Type hints, typings & overloads for better integration downstream (via [#463]) * API * New function `output.make_outputter()` (via [#469]) This replaces the deprecated function `output.get_instance()`. * New sub-package `validation` ([#432], [#446] via [#433], [#448], [#469], [#468], [#469]) * New class `exception.MissingOptionalDependencyException` ([#432] via [#433]) * New class `exception.LicenseExpressionAlongWithOthersException` ([#453] via [#452]) * New dictionaries `output.{json,xml}.BY_SCHEMA_VERSION` ([#446] via [#447]) * Existing implementations of class `output.BaseOutput` now have a new method `output_format` ([#446] via [#447]) * Existing implementations of method `output.BaseOutput.output_as_string()` got new optional parameter `indent` ([#437] via [#458]) * Existing implementations of method `output.BaseOutput.output_to_file()` got new optional parameter `indent` ([#437] via [#458]) * New method `factory.license.LicenseFactory.make_with_expression()` (via [#466]) * New class `model.license.DisjunctiveLicense` ([#365] via [#466]) * New class `model.license.LicenseExpression` ([#365] via [#466]) * New class `model.license.LicenseRepository` ([#365] via [#466]) * New class `serialization.LicenseRepositoryHelper` ([#365] via [#466]) Deprecated ---------------- * Function `output.get_instance()` might be removed, use `output.make_outputter()` instead (via [#469]) Tests ---------------- * Added validation tests with official CycloneDX schema test data ([#432] via [#433]) * Use proper snapshots, instead of pseudo comparison ([#437] via [#464]) * Added regression test for bug [#365] (via [#466], [#467]) Misc ---------------- * Dependencies: bumped `py-serializable@^0.15.0`, was `@^0.11.1` (via [#458], [#463], [#464], [#466]) * Style: streamlined quotes and strings (via [#472]) * Chore: bumped internal dev- and QA-tools ([#436] via [#441], [#472]) * Chore: added more QA tools to prevent common security issues (via [#473]) [#432]: #432 [#433]: #433 [#436]: #436 [#437]: #437 [#365]: #365 [#438]: #438 [#440]: #440 [#441]: #441 [#442]: #442 [#446]: #446 [#447]: #447 [#448]: #448 [#452]: #452 [#453]: #453 [#458]: #458 [#460]: #460 [#461]: #461 [#462]: #462 [#463]: #463 [#464]: #464 [#466]: #466 [#467]: #467 [#468]: #468 [#469]: #469 [#472]: #472 [#473]: #473 --------- Signed-off-by: Jan Kowalleck <[email protected]> Signed-off-by: Jan Kowalleck <[email protected]> Signed-off-by: semantic-release <semantic-release> Co-authored-by: semantic-release <semantic-release>
1 parent 50ce108 commit 26b151c

File tree

670 files changed

+27318
-16049
lines changed

Some content is hidden

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

670 files changed

+27318
-16049
lines changed

.editorconfig

+1-1
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,7 @@ trim_trailing_whitespace = false
3131
indent_style = space
3232
indent_size = 4
3333

34-
[*.ini]
34+
[{*.ini,.bandit,.flake8}]
3535
charset = latin1
3636
indent_style = space
3737
indent_size = 4

.flake8

+20
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
[flake8]
2+
## https://flake8.pycqa.org/en/latest/user/configuration.html
3+
## keep in sync with isort config - in `isort.cfg` file
4+
5+
exclude =
6+
build,dist,__pycache__,.eggs,*.egg-info*,
7+
*_cache,*.cache,
8+
.git,.tox,.venv,venv,.venv*,venv*,
9+
_OLD,_TEST,
10+
docs
11+
12+
max-line-length = 120
13+
14+
max-complexity = 10
15+
16+
ignore =
17+
# ignore `self`, `cls` markers of flake8-annotations>=2.0
18+
ANN101,ANN102
19+
# ignore ANN401 for dynamically typed *args and **kwargs
20+
ANN401

.github/workflows/python.yml

+55-27
Original file line numberDiff line numberDiff line change
@@ -46,24 +46,48 @@ jobs:
4646
- name: Install dependencies
4747
run: poetry install --no-root
4848
- name: Run tox
49-
run: poetry run tox -e flake8 -s false
49+
run: poetry run tox run -e flake8 -s false
50+
51+
security-issues:
52+
name: find Security Issues
53+
runs-on: ubuntu-latest
54+
timeout-minutes: 10
55+
steps:
56+
- name: Checkout
57+
# see https://github.com/actions/checkout
58+
uses: actions/checkout@v4
59+
- name: Setup Python Environment
60+
# see https://github.com/actions/setup-python
61+
uses: actions/setup-python@v4
62+
with:
63+
python-version: ${{ env.PYTHON_VERSION_DEFAULT }}
64+
architecture: 'x64'
65+
- name: Install poetry
66+
# see https://github.com/marketplace/actions/setup-poetry
67+
uses: Gr1N/setup-poetry@v8
68+
with:
69+
poetry-version: ${{ env.POETRY_VERSION }}
70+
- name: Install dependencies
71+
run: poetry install --no-root
72+
- name: Run tox
73+
run: poetry run tox run -e bandit -s false
5074

5175
static-code-analysis:
52-
name: StaticCodingAnalysis (py${{ matrix.python-version}} ${{ matrix.toxenv-factor }})
76+
name: StaticCodingAnalysis (py${{ matrix.python-version}} ${{ matrix.toxenv-factors }})
5377
runs-on: ${{ matrix.os }}
5478
timeout-minutes: 10
5579
strategy:
5680
fail-fast: false
5781
matrix:
5882
include:
59-
- # test with the locked dependencies
83+
- # test with the latest dependencies
6084
os: ubuntu-latest
61-
python-version: '3.11'
62-
toxenv-factor: 'locked'
85+
python-version: '3.12'
86+
toxenv-factors: '-current'
6387
- # test with the lowest dependencies
6488
os: ubuntu-latest
65-
python-version: '3.7'
66-
toxenv-factor: 'lowest'
89+
python-version: '3.8'
90+
toxenv-factors: '-lowest'
6791
steps:
6892
- name: Checkout
6993
# see https://github.com/actions/checkout
@@ -82,28 +106,25 @@ jobs:
82106
- name: Install dependencies
83107
run: poetry install --no-root
84108
- name: Run tox
85-
run: poetry run tox -e mypy-${{ matrix.toxenv-factor }} -s false
109+
run: poetry run tox run -e mypy${{ matrix.toxenv-factors }} -s false
86110

87111
build-and-test:
88-
name: Test (${{ matrix.os }} py${{ matrix.python-version }} ${{ matrix.toxenv-factor }})
112+
name: Test (${{ matrix.os }} py${{ matrix.python-version }} ${{ matrix.toxenv-factors }})
89113
runs-on: ${{ matrix.os }}
90114
timeout-minutes: 15
91115
strategy:
92116
fail-fast: false
93117
matrix:
94118
os: ['ubuntu-latest', 'windows-latest', 'macos-latest']
95119
python-version:
96-
- "3.11" # highest supported
120+
- "3.12" # highest supported
121+
- "3.11"
97122
- "3.10"
98123
- "3.9"
99-
- "3.8"
100-
- "3.7" # lowest supported
101-
toxenv-factor: ['locked']
102-
include:
103-
- # test with the lowest dependencies
104-
os: ubuntu-latest
105-
python-version: '3.7'
106-
toxenv-factor: 'lowest'
124+
- "3.8" # lowest supported
125+
toxenv-factors:
126+
- '-allExtras'
127+
- '-noExtras'
107128
steps:
108129
- name: Disabled Git auto EOL CRLF transforms
109130
run: |
@@ -135,14 +156,14 @@ jobs:
135156
- name: Ensure build successful
136157
run: poetry build
137158
- name: Run tox
138-
run: poetry run tox -e py-${{ matrix.toxenv-factor }} -s false
159+
run: poetry run tox run -e py${{ matrix.toxenv-factors }} -s false
139160
- name: Generate coverage reports
161+
if: ${{ failure() || success() }}
140162
shell: bash
141163
run: |
142164
set -eux
143-
poetry run coverage report
144-
poetry run coverage xml -o "$REPORTS_DIR/coverage.${{ matrix.os }}_py${{ matrix.python-version }}_${{ matrix.toxenv-factor }}.cobertura.xml"
145-
# poetry run coverage lcov -o "$REPORTS_DIR/coverage.${{ matrix.os }}_py${{ matrix.python-version }}_${{ matrix.toxenv-factor }}.lcov.xml"
165+
poetry run coverage report -m
166+
poetry run coverage xml -o '${{ env.REPORTS_DIR }}/coverage/${{ matrix.os }}_py${{ matrix.python-version }}_${{ matrix.toxenv-factors }}.cobertura.xml'
146167
- name: Artifact reports
147168
if: ${{ ! cancelled() }}
148169
# see https://github.com/actions/upload-artifact
@@ -172,12 +193,19 @@ jobs:
172193
uses: codacy/codacy-coverage-reporter-action@v1
173194
with:
174195
project-token: ${{ env.CODACY_PROJECT_TOKEN }}
175-
coverage-reports: ${{ env.REPORTS_DIR }}/coverage.*
196+
coverage-reports: ${{ env.REPORTS_DIR }}/coverage/*
176197

177198
examples:
178-
name: Examples
199+
name: Examples E:${{ matrix.install-extras || '<none>' }}
179200
runs-on: ubuntu-latest
180-
timeout-minutes: 15
201+
timeout-minutes: 10
202+
strategy:
203+
fail-fast: false
204+
matrix:
205+
install-extras:
206+
- '' # none
207+
- json-validation
208+
- xml-validation
181209
steps:
182210
- name: Checkout
183211
# see https://github.com/actions/checkout
@@ -186,7 +214,7 @@ jobs:
186214
# see https://github.com/actions/setup-python
187215
uses: actions/setup-python@v4
188216
with:
189-
python-version: '>=3.7 <=3.11' # supported version range
217+
python-version: '>=3.8 <=3.12' # supported version range
190218
- name: Validate Python Environment
191219
shell: python
192220
run: |
@@ -198,7 +226,7 @@ jobs:
198226
with:
199227
poetry-version: ${{ env.POETRY_VERSION }}
200228
- name: Install package and prod dependencies
201-
run: poetry install --only=main -vvv
229+
run: poetry install --only=main --extras='${{ matrix.install-extras }}' -vvv
202230
- name: run all examples
203231
run: >
204232
find examples -type f -name '*.py' -print0

.github/workflows/release.yml

+24
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,31 @@ env:
4242
POETRY_VERSION: "1.4.1"
4343

4444
jobs:
45+
quicktest:
46+
runs-on: ubuntu-latest
47+
steps:
48+
- name: Checkout code
49+
# see https://github.com/actions/checkout
50+
uses: actions/checkout@v4
51+
- name: Setup Python Environment
52+
# see https://github.com/actions/setup-python
53+
uses: actions/setup-python@v4
54+
with:
55+
python-version: ${{ env.PYTHON_VERSION_DEFAULT }}
56+
architecture: 'x64'
57+
- name: Install poetry
58+
# see https://github.com/marketplace/actions/setup-poetry
59+
uses: Gr1N/setup-poetry@v8
60+
with:
61+
poetry-version: ${{ env.POETRY_VERSION }}
62+
- name: Install dependencies
63+
run: poetry install --no-root
64+
- name: Run tox
65+
run: poetry run tox run -e py -s false
66+
4567
release:
68+
needs:
69+
- quicktest
4670
# https://github.community/t/how-do-i-specify-job-dependency-running-in-another-workflow/16482
4771
# limit this to being run on regular commits, not the commits that semantic-release will create
4872
# but also allow manual workflow dispatch

.isort.cfg

+3-1
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
[settings]
22
## read the docs: https://pycqa.github.io/isort/docs/configuration/options.html
3-
## keep in sync with flake8 config - in `tox.ini` file
3+
## keep in sync with flake8 config - in `.flake8` file
44
known_first_party = cyclonedx
55
skip_gitignore = false
66
skip_glob =
@@ -20,3 +20,5 @@ src_paths =
2020
cyclonedx
2121
tests
2222
typings
23+
examples
24+
tools

.mypy.ini

+2-4
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
[mypy]
22

3-
files = cyclonedx/
3+
files = cyclonedx/, examples/
44
mypy_path = $MYPY_CONFIG_FILE_DIR/typings
55

66
show_error_codes = True
@@ -26,9 +26,7 @@ no_implicit_optional = True
2626
warn_redundant_casts = True
2727
warn_return_any = True
2828
no_implicit_reexport = True
29-
30-
# needed to silence some py37|py38 differences
31-
warn_unused_ignores = False
29+
warn_unused_ignores = True
3230

3331
[mypy-pytest.*]
3432
ignore_missing_imports = True

.readthedocs.yaml

+1-3
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,3 @@
1-
# encoding: utf-8
2-
31
# Licensed under the Apache License, Version 2.0 (the "License");
42
# you may not use this file except in compliance with the License.
53
# You may obtain a copy of the License at
@@ -42,4 +40,4 @@ python:
4240
install:
4341
- method: pip
4442
path: .
45-
- requirements: docs/requirements.txt
43+
- requirements: docs/requirements.txt

CONTRIBUTING.md

+7-3
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,9 +23,13 @@ Get it all applied via:
2323

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

29+
This project prefers `f'strings'` over `'string'.format()`.
30+
This project prefers `'single quotes'` over `"double quotes"`.
31+
This project prefers `lower_snake_case` variable names.
32+
2933
## Documentation
3034

3135
This project uses [Sphinx] to generate documentation which is automatically published to [readthedocs.io].
@@ -45,7 +49,7 @@ make html
4549
Run all tests in dedicated environments, via:
4650

4751
```shell
48-
poetry run tox
52+
poetry run tox run
4953
```
5054

5155
## Sign off your commits

README.md

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
# Python Library for generating CycloneDX
1+
# CycloneDX Python Library
22

33
[![shield_pypi-version]][link_pypi]
44
[![shield_conda-forge-version]][link_conda-forge]

bandit.yml

+9
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
# https://bandit.readthedocs.io
2+
# filename must be like this, so codacy can pick it up: https://github.com/codacy/codacy-bandit/blob/master/src/main/scala/codacy/bandit/Bandit.scala#L35C49-L35C59
3+
4+
exclude_dirs:
5+
- docs
6+
- .venv
7+
8+
skips:
9+
- B101

cyclonedx/__init__.py

+4-3
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,3 @@
1-
# encoding: utf-8
2-
31
# Licensed under the Apache License, Version 2.0 (the "License");
42
# you may not use this file except in compliance with the License.
53
# You may obtain a copy of the License at
@@ -13,11 +11,14 @@
1311
# limitations under the License.
1412
#
1513
# SPDX-License-Identifier: Apache-2.0
14+
# Copyright (c) OWASP Foundation. All Rights Reserved.
15+
1616

1717
"""
1818
Python library for generating and representing CycloneDX software bill-of-materials.
1919
"""
2020

2121
# !! version is managed by semantic_release
2222
# do not use typing here, or else `semantic_release` might have issues finding the variable
23-
__version__ = "4.2.3"
23+
# flake8: noqa
24+
__version__ = "5.0.0-rc.2"

cyclonedx/exception/__init__.py

+8-4
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,3 @@
1-
# encoding: utf-8
2-
31
# Licensed under the Apache License, Version 2.0 (the "License");
42
# you may not use this file except in compliance with the License.
53
# You may obtain a copy of the License at
@@ -13,15 +11,21 @@
1311
# limitations under the License.
1412
#
1513
# SPDX-License-Identifier: Apache-2.0
16-
#
14+
# Copyright (c) OWASP Foundation. All Rights Reserved.
15+
1716

1817
"""
1918
Exceptions that are specific to the CycloneDX library implementation.
2019
"""
2120

2221

23-
class CycloneDxException(Exception):
22+
class CycloneDxException(Exception): # noqa: N818
2423
"""
2524
Root exception thrown by this library.
2625
"""
2726
pass
27+
28+
29+
class MissingOptionalDependencyException(CycloneDxException): # noqa: N818
30+
"""Validation did not happen, due to missing dependencies."""
31+
pass

cyclonedx/exception/factory.py

+2-3
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,3 @@
1-
# encoding: utf-8
2-
31
# Licensed under the Apache License, Version 2.0 (the "License");
42
# you may not use this file except in compliance with the License.
53
# You may obtain a copy of the License at
@@ -13,7 +11,8 @@
1311
# limitations under the License.
1412
#
1513
# SPDX-License-Identifier: Apache-2.0
16-
#
14+
# Copyright (c) OWASP Foundation. All Rights Reserved.
15+
1716

1817
"""
1918
Exceptions relating to specific conditions that occur when factoring a model.

0 commit comments

Comments
 (0)