Skip to content

Commit

Permalink
feat!: v5.0.0 (#440)
Browse files Browse the repository at this point in the history
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 <jan.kowalleck@gmail.com>
Signed-off-by: Jan Kowalleck <jan.kowalleck@owasp.org>
Signed-off-by: semantic-release <semantic-release>
Co-authored-by: semantic-release <semantic-release>
  • Loading branch information
jkowalleck authored Oct 24, 2023
1 parent 50ce108 commit 26b151c
Show file tree
Hide file tree
Showing 670 changed files with 27,318 additions and 16,049 deletions.
2 changes: 1 addition & 1 deletion .editorconfig
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ trim_trailing_whitespace = false
indent_style = space
indent_size = 4

[*.ini]
[{*.ini,.bandit,.flake8}]
charset = latin1
indent_style = space
indent_size = 4
20 changes: 20 additions & 0 deletions .flake8
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
[flake8]
## https://flake8.pycqa.org/en/latest/user/configuration.html
## keep in sync with isort config - in `isort.cfg` file

exclude =
build,dist,__pycache__,.eggs,*.egg-info*,
*_cache,*.cache,
.git,.tox,.venv,venv,.venv*,venv*,
_OLD,_TEST,
docs

max-line-length = 120

max-complexity = 10

ignore =
# ignore `self`, `cls` markers of flake8-annotations>=2.0
ANN101,ANN102
# ignore ANN401 for dynamically typed *args and **kwargs
ANN401
82 changes: 55 additions & 27 deletions .github/workflows/python.yml
Original file line number Diff line number Diff line change
Expand Up @@ -46,24 +46,48 @@ jobs:
- name: Install dependencies
run: poetry install --no-root
- name: Run tox
run: poetry run tox -e flake8 -s false
run: poetry run tox run -e flake8 -s false

security-issues:
name: find Security Issues
runs-on: ubuntu-latest
timeout-minutes: 10
steps:
- name: Checkout
# see https://github.com/actions/checkout
uses: actions/checkout@v4
- name: Setup Python Environment
# see https://github.com/actions/setup-python
uses: actions/setup-python@v4
with:
python-version: ${{ env.PYTHON_VERSION_DEFAULT }}
architecture: 'x64'
- name: Install poetry
# see https://github.com/marketplace/actions/setup-poetry
uses: Gr1N/setup-poetry@v8
with:
poetry-version: ${{ env.POETRY_VERSION }}
- name: Install dependencies
run: poetry install --no-root
- name: Run tox
run: poetry run tox run -e bandit -s false

static-code-analysis:
name: StaticCodingAnalysis (py${{ matrix.python-version}} ${{ matrix.toxenv-factor }})
name: StaticCodingAnalysis (py${{ matrix.python-version}} ${{ matrix.toxenv-factors }})
runs-on: ${{ matrix.os }}
timeout-minutes: 10
strategy:
fail-fast: false
matrix:
include:
- # test with the locked dependencies
- # test with the latest dependencies
os: ubuntu-latest
python-version: '3.11'
toxenv-factor: 'locked'
python-version: '3.12'
toxenv-factors: '-current'
- # test with the lowest dependencies
os: ubuntu-latest
python-version: '3.7'
toxenv-factor: 'lowest'
python-version: '3.8'
toxenv-factors: '-lowest'
steps:
- name: Checkout
# see https://github.com/actions/checkout
Expand All @@ -82,28 +106,25 @@ jobs:
- name: Install dependencies
run: poetry install --no-root
- name: Run tox
run: poetry run tox -e mypy-${{ matrix.toxenv-factor }} -s false
run: poetry run tox run -e mypy${{ matrix.toxenv-factors }} -s false

build-and-test:
name: Test (${{ matrix.os }} py${{ matrix.python-version }} ${{ matrix.toxenv-factor }})
name: Test (${{ matrix.os }} py${{ matrix.python-version }} ${{ matrix.toxenv-factors }})
runs-on: ${{ matrix.os }}
timeout-minutes: 15
strategy:
fail-fast: false
matrix:
os: ['ubuntu-latest', 'windows-latest', 'macos-latest']
python-version:
- "3.11" # highest supported
- "3.12" # highest supported
- "3.11"
- "3.10"
- "3.9"
- "3.8"
- "3.7" # lowest supported
toxenv-factor: ['locked']
include:
- # test with the lowest dependencies
os: ubuntu-latest
python-version: '3.7'
toxenv-factor: 'lowest'
- "3.8" # lowest supported
toxenv-factors:
- '-allExtras'
- '-noExtras'
steps:
- name: Disabled Git auto EOL CRLF transforms
run: |
Expand Down Expand Up @@ -135,14 +156,14 @@ jobs:
- name: Ensure build successful
run: poetry build
- name: Run tox
run: poetry run tox -e py-${{ matrix.toxenv-factor }} -s false
run: poetry run tox run -e py${{ matrix.toxenv-factors }} -s false
- name: Generate coverage reports
if: ${{ failure() || success() }}
shell: bash
run: |
set -eux
poetry run coverage report
poetry run coverage xml -o "$REPORTS_DIR/coverage.${{ matrix.os }}_py${{ matrix.python-version }}_${{ matrix.toxenv-factor }}.cobertura.xml"
# poetry run coverage lcov -o "$REPORTS_DIR/coverage.${{ matrix.os }}_py${{ matrix.python-version }}_${{ matrix.toxenv-factor }}.lcov.xml"
poetry run coverage report -m
poetry run coverage xml -o '${{ env.REPORTS_DIR }}/coverage/${{ matrix.os }}_py${{ matrix.python-version }}_${{ matrix.toxenv-factors }}.cobertura.xml'
- name: Artifact reports
if: ${{ ! cancelled() }}
# see https://github.com/actions/upload-artifact
Expand Down Expand Up @@ -172,12 +193,19 @@ jobs:
uses: codacy/codacy-coverage-reporter-action@v1
with:
project-token: ${{ env.CODACY_PROJECT_TOKEN }}
coverage-reports: ${{ env.REPORTS_DIR }}/coverage.*
coverage-reports: ${{ env.REPORTS_DIR }}/coverage/*

examples:
name: Examples
name: Examples E:${{ matrix.install-extras || '<none>' }}
runs-on: ubuntu-latest
timeout-minutes: 15
timeout-minutes: 10
strategy:
fail-fast: false
matrix:
install-extras:
- '' # none
- json-validation
- xml-validation
steps:
- name: Checkout
# see https://github.com/actions/checkout
Expand All @@ -186,7 +214,7 @@ jobs:
# see https://github.com/actions/setup-python
uses: actions/setup-python@v4
with:
python-version: '>=3.7 <=3.11' # supported version range
python-version: '>=3.8 <=3.12' # supported version range
- name: Validate Python Environment
shell: python
run: |
Expand All @@ -198,7 +226,7 @@ jobs:
with:
poetry-version: ${{ env.POETRY_VERSION }}
- name: Install package and prod dependencies
run: poetry install --only=main -vvv
run: poetry install --only=main --extras='${{ matrix.install-extras }}' -vvv
- name: run all examples
run: >
find examples -type f -name '*.py' -print0
Expand Down
24 changes: 24 additions & 0 deletions .github/workflows/release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,31 @@ env:
POETRY_VERSION: "1.4.1"

jobs:
quicktest:
runs-on: ubuntu-latest
steps:
- name: Checkout code
# see https://github.com/actions/checkout
uses: actions/checkout@v4
- name: Setup Python Environment
# see https://github.com/actions/setup-python
uses: actions/setup-python@v4
with:
python-version: ${{ env.PYTHON_VERSION_DEFAULT }}
architecture: 'x64'
- name: Install poetry
# see https://github.com/marketplace/actions/setup-poetry
uses: Gr1N/setup-poetry@v8
with:
poetry-version: ${{ env.POETRY_VERSION }}
- name: Install dependencies
run: poetry install --no-root
- name: Run tox
run: poetry run tox run -e py -s false

release:
needs:
- quicktest
# https://github.community/t/how-do-i-specify-job-dependency-running-in-another-workflow/16482
# limit this to being run on regular commits, not the commits that semantic-release will create
# but also allow manual workflow dispatch
Expand Down
4 changes: 3 additions & 1 deletion .isort.cfg
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[settings]
## read the docs: https://pycqa.github.io/isort/docs/configuration/options.html
## keep in sync with flake8 config - in `tox.ini` file
## keep in sync with flake8 config - in `.flake8` file
known_first_party = cyclonedx
skip_gitignore = false
skip_glob =
Expand All @@ -20,3 +20,5 @@ src_paths =
cyclonedx
tests
typings
examples
tools
6 changes: 2 additions & 4 deletions .mypy.ini
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[mypy]

files = cyclonedx/
files = cyclonedx/, examples/
mypy_path = $MYPY_CONFIG_FILE_DIR/typings

show_error_codes = True
Expand All @@ -26,9 +26,7 @@ no_implicit_optional = True
warn_redundant_casts = True
warn_return_any = True
no_implicit_reexport = True

# needed to silence some py37|py38 differences
warn_unused_ignores = False
warn_unused_ignores = True

[mypy-pytest.*]
ignore_missing_imports = True
Expand Down
4 changes: 1 addition & 3 deletions .readthedocs.yaml
Original file line number Diff line number Diff line change
@@ -1,5 +1,3 @@
# encoding: utf-8

# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
Expand Down Expand Up @@ -42,4 +40,4 @@ python:
install:
- method: pip
path: .
- requirements: docs/requirements.txt
- requirements: docs/requirements.txt
10 changes: 7 additions & 3 deletions CONTRIBUTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ This project uses [poetry]. Have it installed and setup first.
To install dev-dependencies and tools:

```shell
poetry install
poetry install --all-extras
```

## Code style
Expand All @@ -23,9 +23,13 @@ Get it all applied via:

```shell
poetry run isort .
poetry run flake8 cyclonedx/ tests/ typings/
poetry run autopep8 -ir cyclonedx/ tests/ typings/ examples/
```

This project prefers `f'strings'` over `'string'.format()`.
This project prefers `'single quotes'` over `"double quotes"`.
This project prefers `lower_snake_case` variable names.

## Documentation

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

```shell
poetry run tox
poetry run tox run
```

## Sign off your commits
Expand Down
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
# Python Library for generating CycloneDX
# CycloneDX Python Library

[![shield_pypi-version]][link_pypi]
[![shield_conda-forge-version]][link_conda-forge]
Expand Down
9 changes: 9 additions & 0 deletions bandit.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
# https://bandit.readthedocs.io
# 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

exclude_dirs:
- docs
- .venv

skips:
- B101
7 changes: 4 additions & 3 deletions cyclonedx/__init__.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,3 @@
# encoding: utf-8

# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
Expand All @@ -13,11 +11,14 @@
# limitations under the License.
#
# SPDX-License-Identifier: Apache-2.0
# Copyright (c) OWASP Foundation. All Rights Reserved.


"""
Python library for generating and representing CycloneDX software bill-of-materials.
"""

# !! version is managed by semantic_release
# do not use typing here, or else `semantic_release` might have issues finding the variable
__version__ = "4.2.3"
# flake8: noqa
__version__ = "5.0.0-rc.2"
12 changes: 8 additions & 4 deletions cyclonedx/exception/__init__.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,3 @@
# encoding: utf-8

# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
Expand All @@ -13,15 +11,21 @@
# limitations under the License.
#
# SPDX-License-Identifier: Apache-2.0
#
# Copyright (c) OWASP Foundation. All Rights Reserved.


"""
Exceptions that are specific to the CycloneDX library implementation.
"""


class CycloneDxException(Exception):
class CycloneDxException(Exception): # noqa: N818
"""
Root exception thrown by this library.
"""
pass


class MissingOptionalDependencyException(CycloneDxException): # noqa: N818
"""Validation did not happen, due to missing dependencies."""
pass
5 changes: 2 additions & 3 deletions cyclonedx/exception/factory.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,3 @@
# encoding: utf-8

# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
Expand All @@ -13,7 +11,8 @@
# limitations under the License.
#
# SPDX-License-Identifier: Apache-2.0
#
# Copyright (c) OWASP Foundation. All Rights Reserved.


"""
Exceptions relating to specific conditions that occur when factoring a model.
Expand Down
Loading

0 comments on commit 26b151c

Please sign in to comment.