diff --git a/cyclonedx_py/_internal/environment.py b/cyclonedx_py/_internal/environment.py
index b5d3132c..6f39db41 100644
--- a/cyclonedx_py/_internal/environment.py
+++ b/cyclonedx_py/_internal/environment.py
@@ -130,7 +130,7 @@ def __call__(self, *, # type:ignore[override]
rc = None
else:
pyproject = pyproject_load(pyproject_file)
- root_c = pyproject2component(pyproject, type=mc_type)
+ root_c = pyproject2component(pyproject, ctype=mc_type, fpath=pyproject_file)
root_c.bom_ref.value = 'root-component'
root_d = tuple(pyproject2dependencies(pyproject))
rc = (root_c, root_d)
diff --git a/cyclonedx_py/_internal/pipenv.py b/cyclonedx_py/_internal/pipenv.py
index da1b8b99..54fbb041 100644
--- a/cyclonedx_py/_internal/pipenv.py
+++ b/cyclonedx_py/_internal/pipenv.py
@@ -127,7 +127,7 @@ def __call__(self, *, # type:ignore[override]
if pyproject_file is None:
rc = None
else:
- rc = pyproject_file2component(pyproject_file, type=mc_type)
+ rc = pyproject_file2component(pyproject_file, ctype=mc_type)
rc.bom_ref.value = 'root-component'
return self._make_bom(rc,
diff --git a/cyclonedx_py/_internal/poetry.py b/cyclonedx_py/_internal/poetry.py
index 531c55a5..6d80e578 100644
--- a/cyclonedx_py/_internal/poetry.py
+++ b/cyclonedx_py/_internal/poetry.py
@@ -230,7 +230,7 @@ def _make_bom(self, project: 'T_NameDict', locker: 'T_NameDict',
po_cfg = project['tool']['poetry']
- bom.metadata.component = root_c = poetry2component(po_cfg, type=mc_type)
+ bom.metadata.component = root_c = poetry2component(po_cfg, ctype=mc_type)
root_c.bom_ref.value = root_c.name
root_c.properties.update(
Property(
diff --git a/cyclonedx_py/_internal/requirements.py b/cyclonedx_py/_internal/requirements.py
index 059184ee..ee08d562 100644
--- a/cyclonedx_py/_internal/requirements.py
+++ b/cyclonedx_py/_internal/requirements.py
@@ -114,7 +114,7 @@ def __call__(self, *, # type:ignore[override]
if pyproject_file is None:
rc = None
else:
- rc = pyproject_file2component(pyproject_file, type=mc_type)
+ rc = pyproject_file2component(pyproject_file, ctype=mc_type)
rc.bom_ref.value = 'root-component'
if requirements_file == '-':
diff --git a/cyclonedx_py/_internal/utils/packaging.py b/cyclonedx_py/_internal/utils/packaging.py
index cda0ef61..97106916 100644
--- a/cyclonedx_py/_internal/utils/packaging.py
+++ b/cyclonedx_py/_internal/utils/packaging.py
@@ -20,7 +20,8 @@
from cyclonedx.exception.model import InvalidUriException
from cyclonedx.factory.license import LicenseFactory
-from cyclonedx.model import ExternalReference, ExternalReferenceType, XsUri
+from cyclonedx.model import AttachedText, ExternalReference, ExternalReferenceType, XsUri
+from cyclonedx.model.license import DisjunctiveLicense
from .cdx import url_label_to_ert
from .pep621 import classifiers2licenses
@@ -42,9 +43,15 @@ def metadata2licenses(metadata: 'PackageMetadata') -> Generator['License', None,
# see https://packaging.python.org/en/latest/specifications/core-metadata/#classifier-multiple-use
classifiers: List[str] = metadata.get_all('Classifier') # type:ignore[assignment]
yield from classifiers2licenses(classifiers, lfac)
- if 'License' in metadata:
+ if 'License' in metadata and len(mlicense := metadata['License']) > 0:
# see https://packaging.python.org/en/latest/specifications/core-metadata/#license
- yield lfac.make_from_string(metadata['License'])
+ license = lfac.make_from_string(mlicense)
+ if isinstance(license, DisjunctiveLicense) and license.id is None:
+ # per spec, `License` is either a SPDX ID/Expression, or a license text(not name!)
+ yield DisjunctiveLicense(name=f"declared license of '{metadata['Name']}'",
+ text=AttachedText(content=mlicense))
+ else:
+ yield license
def metadata2extrefs(metadata: 'PackageMetadata') -> Generator['ExternalReference', None, None]:
diff --git a/cyclonedx_py/_internal/utils/pep621.py b/cyclonedx_py/_internal/utils/pep621.py
index a449c2e4..838fd956 100644
--- a/cyclonedx_py/_internal/utils/pep621.py
+++ b/cyclonedx_py/_internal/utils/pep621.py
@@ -15,7 +15,6 @@
# SPDX-License-Identifier: Apache-2.0
# Copyright (c) OWASP Foundation. All Rights Reserved.
-
"""
Functionality related to PEP 621.
@@ -23,13 +22,16 @@
See https://peps.python.org/pep-0621/
"""
+from base64 import b64encode
from itertools import chain
+from os.path import dirname, join
from typing import TYPE_CHECKING, Any, Dict, Generator, Iterable, Iterator
from cyclonedx.exception.model import InvalidUriException
from cyclonedx.factory.license import LicenseFactory
-from cyclonedx.model import ExternalReference, XsUri
+from cyclonedx.model import AttachedText, Encoding, ExternalReference, XsUri
from cyclonedx.model.component import Component
+from cyclonedx.model.license import DisjunctiveLicense
from packaging.requirements import Requirement
from .cdx import licenses_fixup, url_label_to_ert
@@ -50,18 +52,37 @@ def classifiers2licenses(classifiers: Iterable[str], lfac: 'LicenseFactory') ->
classifiers)))
-def project2licenses(project: Dict[str, Any], lfac: 'LicenseFactory') -> Generator['License', None, None]:
- if 'classifiers' in project:
+def project2licenses(project: Dict[str, Any], lfac: 'LicenseFactory', *,
+ fpath: str) -> Generator['License', None, None]:
+ if classifiers := project.get('classifiers'):
# https://packaging.python.org/en/latest/specifications/pyproject-toml/#classifiers
# https://peps.python.org/pep-0621/#classifiers
# https://packaging.python.org/en/latest/specifications/core-metadata/#classifier-multiple-use
- yield from classifiers2licenses(project['classifiers'], lfac)
- license = project.get('license')
- # https://packaging.python.org/en/latest/specifications/pyproject-toml/#license
- # https://peps.python.org/pep-0621/#license
- # https://packaging.python.org/en/latest/specifications/core-metadata/#license
- if isinstance(license, dict) and 'text' in license:
- yield lfac.make_from_string(license['text'])
+ yield from classifiers2licenses(classifiers, lfac)
+ if plicense := project.get('license'):
+ # https://packaging.python.org/en/latest/specifications/pyproject-toml/#license
+ # https://peps.python.org/pep-0621/#license
+ # https://packaging.python.org/en/latest/specifications/core-metadata/#license
+ if 'file' in plicense and 'text' in plicense:
+ # per spec:
+ # > These keys are mutually exclusive, so a tool MUST raise an error if the metadata specifies both keys.
+ raise ValueError('`license.file` and `license.text` are mutually exclusive,')
+ if 'file' in plicense:
+ # per spec:
+ # > [...] a string value that is a relative file path [...].
+ # > Tools MUST assume the file’s encoding is UTF-8.
+ with open(join(dirname(fpath), plicense['file']), 'rb') as plicense_fileh:
+ yield DisjunctiveLicense(name=f"declared license of '{project['name']}'",
+ text=AttachedText(encoding=Encoding.BASE_64,
+ content=b64encode(plicense_fileh.read()).decode()))
+ elif len(plicense_text := plicense.get('text', '')) > 0:
+ license = lfac.make_from_string(plicense_text)
+ if isinstance(license, DisjunctiveLicense) and license.id is None:
+ # per spec, `License` is either a SPDX ID/Expression, or a license text(not name!)
+ yield DisjunctiveLicense(name=f"declared license of '{project['name']}'",
+ text=AttachedText(content=plicense_text))
+ else:
+ yield license
def project2extrefs(project: Dict[str, Any]) -> Generator['ExternalReference', None, None]:
@@ -77,14 +98,14 @@ def project2extrefs(project: Dict[str, Any]) -> Generator['ExternalReference', N
def project2component(project: Dict[str, Any], *,
- type: 'ComponentType') -> 'Component':
+ ctype: 'ComponentType', fpath: str) -> 'Component':
dynamic = project.get('dynamic', ())
return Component(
- type=type,
+ type=ctype,
name=project['name'],
version=project.get('version', None) if 'version' not in dynamic else None,
description=project.get('description', None) if 'description' not in dynamic else None,
- licenses=licenses_fixup(project2licenses(project, LicenseFactory())),
+ licenses=licenses_fixup(project2licenses(project, LicenseFactory(), fpath=fpath)),
external_references=project2extrefs(project),
# TODO add more properties according to spec
)
diff --git a/cyclonedx_py/_internal/utils/poetry.py b/cyclonedx_py/_internal/utils/poetry.py
index 2427b83d..15f9b769 100644
--- a/cyclonedx_py/_internal/utils/poetry.py
+++ b/cyclonedx_py/_internal/utils/poetry.py
@@ -61,17 +61,18 @@ def poetry2extrefs(poetry: Dict[str, Any]) -> Generator['ExternalReference', Non
pass
-def poetry2component(poetry: Dict[str, Any], *, type: 'ComponentType') -> 'Component':
+def poetry2component(poetry: Dict[str, Any], *, ctype: 'ComponentType') -> 'Component':
licenses: List['License'] = []
lfac = LicenseFactory()
if 'classifiers' in poetry:
licenses.extend(classifiers2licenses(poetry['classifiers'], lfac))
if 'license' in poetry:
+ # per spec(https://python-poetry.org/docs/pyproject#license):
+ # the `license` is intended to be the name of a license, not the license text itself.
licenses.append(lfac.make_from_string(poetry['license']))
- del lfac
return Component(
- type=type,
+ type=ctype,
name=poetry['name'],
version=poetry.get('version'),
description=poetry.get('description'),
diff --git a/cyclonedx_py/_internal/utils/pyproject.py b/cyclonedx_py/_internal/utils/pyproject.py
index f8028aac..5719936f 100644
--- a/cyclonedx_py/_internal/utils/pyproject.py
+++ b/cyclonedx_py/_internal/utils/pyproject.py
@@ -14,12 +14,12 @@
def pyproject2component(data: Dict[str, Any], *,
- type: 'ComponentType') -> 'Component':
+ ctype: 'ComponentType', fpath: str) -> 'Component':
tool = data.get('tool', {})
- if 'poetry' in tool:
- return poetry2component(tool['poetry'], type=type)
- if 'project' in data:
- return project2component(data['project'], type=type)
+ if poetry := tool.get('poetry'):
+ return poetry2component(poetry, ctype=ctype)
+ if project := data.get('project'):
+ return project2component(project, ctype=ctype, fpath=fpath)
raise ValueError('Unable to build component from pyproject')
@@ -33,10 +33,10 @@ def pyproject_load(pyproject_file: str) -> Dict[str, Any]:
def pyproject_file2component(pyproject_file: str, *,
- type: 'ComponentType') -> 'Component':
+ ctype: 'ComponentType') -> 'Component':
return pyproject2component(
pyproject_load(pyproject_file),
- type=type
+ ctype=ctype, fpath=pyproject_file
)
diff --git a/tests/_data/infiles/.gitattributes b/tests/_data/infiles/.gitattributes
index b1ce527a..f83b23c8 100644
--- a/tests/_data/infiles/.gitattributes
+++ b/tests/_data/infiles/.gitattributes
@@ -1,3 +1,2 @@
*.bin binary
*.txt.bin binary diff=text
-
diff --git a/tests/_data/infiles/_helpers/local_pckages/a/README.md b/tests/_data/infiles/_helpers/local_pckages/a/README.md
index 19e11b7d..f091e5f6 100644
--- a/tests/_data/infiles/_helpers/local_pckages/a/README.md
+++ b/tests/_data/infiles/_helpers/local_pckages/a/README.md
@@ -1 +1,4 @@
-build via `python -m build`
+build via :
+```shell
+python -m build
+```
diff --git a/tests/_data/infiles/_helpers/local_pckages/a/dist/package-a-23.42.tar.gz b/tests/_data/infiles/_helpers/local_pckages/a/dist/package-a-23.42.tar.gz
index 4bc8f095..62bf1071 100644
Binary files a/tests/_data/infiles/_helpers/local_pckages/a/dist/package-a-23.42.tar.gz and b/tests/_data/infiles/_helpers/local_pckages/a/dist/package-a-23.42.tar.gz differ
diff --git a/tests/_data/infiles/_helpers/local_pckages/a/dist/package_a-23.42-py3-none-any.whl b/tests/_data/infiles/_helpers/local_pckages/a/dist/package_a-23.42-py3-none-any.whl
index b546c551..33fc3a04 100644
Binary files a/tests/_data/infiles/_helpers/local_pckages/a/dist/package_a-23.42-py3-none-any.whl and b/tests/_data/infiles/_helpers/local_pckages/a/dist/package_a-23.42-py3-none-any.whl differ
diff --git a/tests/_data/infiles/_helpers/local_pckages/a/pyproject.toml b/tests/_data/infiles/_helpers/local_pckages/a/pyproject.toml
index c9f2cc3b..f055e487 100644
--- a/tests/_data/infiles/_helpers/local_pckages/a/pyproject.toml
+++ b/tests/_data/infiles/_helpers/local_pckages/a/pyproject.toml
@@ -2,7 +2,7 @@
name = "package-a"
version = "23.42"
description = "some package A"
-license = {text = "Apache-2.0"}
+license = { text = "some license text" } # intentional not a SPDX ID/Expression
authors = []
requires-python = ">=3.8"
diff --git a/tests/_data/infiles/_helpers/local_pckages/b/README.md b/tests/_data/infiles/_helpers/local_pckages/b/README.md
index 19e11b7d..93a53cc1 100644
--- a/tests/_data/infiles/_helpers/local_pckages/b/README.md
+++ b/tests/_data/infiles/_helpers/local_pckages/b/README.md
@@ -1 +1,4 @@
-build via `python -m build`
+build via
+```shell
+python -m build
+```
diff --git a/tests/_data/infiles/_helpers/local_pckages/b/dist/package-b-23.42.tar.gz b/tests/_data/infiles/_helpers/local_pckages/b/dist/package-b-23.42.tar.gz
index e5e8b0ef..ae3e9e05 100644
Binary files a/tests/_data/infiles/_helpers/local_pckages/b/dist/package-b-23.42.tar.gz and b/tests/_data/infiles/_helpers/local_pckages/b/dist/package-b-23.42.tar.gz differ
diff --git a/tests/_data/infiles/_helpers/local_pckages/b/dist/package_b-23.42-py3-none-any.whl b/tests/_data/infiles/_helpers/local_pckages/b/dist/package_b-23.42-py3-none-any.whl
index 2ab38d98..86ff81d5 100644
Binary files a/tests/_data/infiles/_helpers/local_pckages/b/dist/package_b-23.42-py3-none-any.whl and b/tests/_data/infiles/_helpers/local_pckages/b/dist/package_b-23.42-py3-none-any.whl differ
diff --git a/tests/_data/infiles/_helpers/local_pckages/b/pyproject.toml b/tests/_data/infiles/_helpers/local_pckages/b/pyproject.toml
index fdc0c21b..4cac7ff2 100644
--- a/tests/_data/infiles/_helpers/local_pckages/b/pyproject.toml
+++ b/tests/_data/infiles/_helpers/local_pckages/b/pyproject.toml
@@ -2,9 +2,12 @@
name = "package-b"
version = "23.42"
description = "some package B"
-license = {text = "Apache-2.0"}
+license = { text = "Apache-2.0" } # intentional same as a classifier
authors = []
requires-python = ">=3.8"
+classifiers = [
+ "License :: OSI Approved :: Apache Software License"
+]
[tool.setuptools]
py-modules = ["module_b"]
diff --git a/tests/_data/infiles/_helpers/local_pckages/c/README.md b/tests/_data/infiles/_helpers/local_pckages/c/README.md
index 19e11b7d..93a53cc1 100644
--- a/tests/_data/infiles/_helpers/local_pckages/c/README.md
+++ b/tests/_data/infiles/_helpers/local_pckages/c/README.md
@@ -1 +1,4 @@
-build via `python -m build`
+build via
+```shell
+python -m build
+```
diff --git a/tests/_data/infiles/_helpers/local_pckages/c/dist/package-c-23.42.tar.gz b/tests/_data/infiles/_helpers/local_pckages/c/dist/package-c-23.42.tar.gz
index ee6890ed..5a7057aa 100644
Binary files a/tests/_data/infiles/_helpers/local_pckages/c/dist/package-c-23.42.tar.gz and b/tests/_data/infiles/_helpers/local_pckages/c/dist/package-c-23.42.tar.gz differ
diff --git a/tests/_data/infiles/_helpers/local_pckages/c/dist/package_c-23.42-py3-none-any.whl b/tests/_data/infiles/_helpers/local_pckages/c/dist/package_c-23.42-py3-none-any.whl
index 1d9fd7c1..feeeb0a4 100644
Binary files a/tests/_data/infiles/_helpers/local_pckages/c/dist/package_c-23.42-py3-none-any.whl and b/tests/_data/infiles/_helpers/local_pckages/c/dist/package_c-23.42-py3-none-any.whl differ
diff --git a/tests/_data/infiles/_helpers/local_pckages/c/module_c.py b/tests/_data/infiles/_helpers/local_pckages/c/module_c.py
index e23e0482..8cc519ad 100644
--- a/tests/_data/infiles/_helpers/local_pckages/c/module_c.py
+++ b/tests/_data/infiles/_helpers/local_pckages/c/module_c.py
@@ -15,5 +15,5 @@
"""
-module B
+module C
"""
diff --git a/tests/_data/infiles/_helpers/local_pckages/c/pyproject.toml b/tests/_data/infiles/_helpers/local_pckages/c/pyproject.toml
index ee21be96..7968205c 100644
--- a/tests/_data/infiles/_helpers/local_pckages/c/pyproject.toml
+++ b/tests/_data/infiles/_helpers/local_pckages/c/pyproject.toml
@@ -2,9 +2,13 @@
name = "package-c"
version = "23.42"
description = "some package C"
-license = {text = "Apache-2.0"}
+license = { text = "Apache-2.0 OR MIT" } # intentional a SPDX Expression
authors = []
requires-python = ">=3.8"
+classifiers = [
+ "License :: OSI Approved :: Apache Software License",
+ "License :: OSI Approved :: MIT License"
+]
[tool.setuptools]
py-modules = ["module_c"]
diff --git a/tests/_data/infiles/environment/with-license-file/init.py b/tests/_data/infiles/environment/with-license-file/init.py
new file mode 100644
index 00000000..38a6cfcb
--- /dev/null
+++ b/tests/_data/infiles/environment/with-license-file/init.py
@@ -0,0 +1,24 @@
+"""
+initialize this testbed.
+"""
+
+from os import name as os_name
+from os.path import dirname, join
+from venv import EnvBuilder
+
+__all__ = ['main']
+
+this_dir = dirname(__file__)
+env_dir = join(this_dir, '.venv')
+
+
+def main() -> None:
+ EnvBuilder(
+ system_site_packages=False,
+ symlinks=os_name != 'nt',
+ with_pip=False,
+ ).create(env_dir)
+
+
+if __name__ == '__main__':
+ main()
diff --git a/tests/_data/infiles/environment/with-license-file/pyproject.toml b/tests/_data/infiles/environment/with-license-file/pyproject.toml
new file mode 100644
index 00000000..427b17b4
--- /dev/null
+++ b/tests/_data/infiles/environment/with-license-file/pyproject.toml
@@ -0,0 +1,7 @@
+[project]
+# https://packaging.python.org/en/latest/specifications/declaring-project-metadata/#declaring-project-metadata
+name = "with-license-file"
+version = "0.1.0"
+description = "with licenses from file, instead of SPDX ID/Expression"
+# see https://packaging.python.org/en/latest/specifications/pyproject-toml/#license
+license = { file = "testing/someLicenseFile.txt.bin" }
diff --git a/tests/_data/infiles/environment/with-license-file/testing/someLicenseFile.txt.bin b/tests/_data/infiles/environment/with-license-file/testing/someLicenseFile.txt.bin
new file mode 100644
index 00000000..1c0bf5b9
--- /dev/null
+++ b/tests/_data/infiles/environment/with-license-file/testing/someLicenseFile.txt.bin
@@ -0,0 +1,2 @@
+This is the license text of this component.
+It is expected to be available in a SBOM.
diff --git a/tests/_data/infiles/environment/with-license-text/init.py b/tests/_data/infiles/environment/with-license-text/init.py
new file mode 100644
index 00000000..9998905e
--- /dev/null
+++ b/tests/_data/infiles/environment/with-license-text/init.py
@@ -0,0 +1,57 @@
+"""
+initialize this testbed.
+"""
+
+from os import name as os_name
+from os.path import abspath, dirname, join
+from subprocess import CompletedProcess, run # nosec:B404
+from sys import executable
+from typing import Any
+from venv import EnvBuilder
+
+__all__ = ['main']
+
+this_dir = dirname(__file__)
+env_dir = join(this_dir, '.venv')
+constraint_file = join(this_dir, 'pinning.txt')
+
+localpackages_dir = abspath(join(dirname(__file__), '..', '..', '_helpers', 'local_pckages'))
+
+
+def pip_run(*args: str, **kwargs: Any) -> CompletedProcess:
+ # pip is not API, but a CLI -- call it like that!
+ call = (
+ executable, '-m', 'pip',
+ '--python', env_dir,
+ *args
+ )
+ print('+ ', *call)
+ res = run(call, **kwargs, cwd=this_dir, shell=False) # nosec:B603
+ if res.returncode != 0:
+ raise RuntimeError('process failed')
+ return res
+
+
+def pip_install(*args: str) -> None:
+ pip_run(
+ 'install', '--require-virtualenv', '--no-input', '--progress-bar=off', '--no-color',
+ *args
+ )
+
+
+def main() -> None:
+ EnvBuilder(
+ system_site_packages=False,
+ symlinks=os_name != 'nt',
+ with_pip=False,
+ ).create(env_dir)
+
+ pip_install(
+ join(localpackages_dir, 'a', 'dist', 'package_a-23.42-py3-none-any.whl'),
+ join(localpackages_dir, 'b', 'dist', 'package_b-23.42-py3-none-any.whl'),
+ join(localpackages_dir, 'c', 'dist', 'package_c-23.42-py3-none-any.whl'),
+ )
+
+
+if __name__ == '__main__':
+ main()
diff --git a/tests/_data/infiles/environment/with-license-text/pyproject.toml b/tests/_data/infiles/environment/with-license-text/pyproject.toml
new file mode 100644
index 00000000..14b0c56a
--- /dev/null
+++ b/tests/_data/infiles/environment/with-license-text/pyproject.toml
@@ -0,0 +1,7 @@
+[project]
+# https://packaging.python.org/en/latest/specifications/declaring-project-metadata/#declaring-project-metadata
+name = "with-license-text"
+version = "0.1.0"
+description = "with licenses as text, instead of SPDX ID/Expression"
+# see https://packaging.python.org/en/latest/specifications/pyproject-toml/#license
+license = { text = "This is the license text of this component.\nIt is expected to be available in a SBOM." }
diff --git a/tests/_data/snapshots/environment/plain_local_1.1.xml.bin b/tests/_data/snapshots/environment/plain_local_1.1.xml.bin
index 74e71ad1..1388cf70 100644
--- a/tests/_data/snapshots/environment/plain_local_1.1.xml.bin
+++ b/tests/_data/snapshots/environment/plain_local_1.1.xml.bin
@@ -7,7 +7,8 @@
some package A
- Apache-2.0
+ declared license of 'package-a'
+ some license text
@@ -38,9 +39,7 @@
23.42
some package C
-
- Apache-2.0
-
+ Apache-2.0 OR MIT
diff --git a/tests/_data/snapshots/environment/plain_local_1.2.json.bin b/tests/_data/snapshots/environment/plain_local_1.2.json.bin
index 83c6d8b0..f1b72c5a 100644
--- a/tests/_data/snapshots/environment/plain_local_1.2.json.bin
+++ b/tests/_data/snapshots/environment/plain_local_1.2.json.bin
@@ -13,7 +13,11 @@
"licenses": [
{
"license": {
- "id": "Apache-2.0"
+ "name": "declared license of 'package-a'",
+ "text": {
+ "content": "some license text",
+ "contentType": "text/plain"
+ }
}
}
],
@@ -54,9 +58,7 @@
],
"licenses": [
{
- "license": {
- "id": "Apache-2.0"
- }
+ "expression": "Apache-2.0 OR MIT"
}
],
"name": "package-c",
diff --git a/tests/_data/snapshots/environment/plain_local_1.2.xml.bin b/tests/_data/snapshots/environment/plain_local_1.2.xml.bin
index 9bd185ef..679e1774 100644
--- a/tests/_data/snapshots/environment/plain_local_1.2.xml.bin
+++ b/tests/_data/snapshots/environment/plain_local_1.2.xml.bin
@@ -26,7 +26,8 @@
some package A
- Apache-2.0
+ declared license of 'package-a'
+ some license text
@@ -57,9 +58,7 @@
23.42
some package C
-
- Apache-2.0
-
+ Apache-2.0 OR MIT
diff --git a/tests/_data/snapshots/environment/plain_local_1.3.json.bin b/tests/_data/snapshots/environment/plain_local_1.3.json.bin
index 3e09434a..b387890d 100644
--- a/tests/_data/snapshots/environment/plain_local_1.3.json.bin
+++ b/tests/_data/snapshots/environment/plain_local_1.3.json.bin
@@ -9,7 +9,7 @@
"hashes": [
{
"alg": "SHA-256",
- "content": "4f37ac4a44c1dcce7f3d6203d45e9d1945a28f69fbfb44f418c44ea73c77de86"
+ "content": "5c8da28603857d4073c67e751ba3cd526a7ef414135faecfec164e7d01be24be"
}
],
"type": "distribution",
@@ -19,7 +19,11 @@
"licenses": [
{
"license": {
- "id": "Apache-2.0"
+ "name": "declared license of 'package-a'",
+ "text": {
+ "content": "some license text",
+ "contentType": "text/plain"
+ }
}
}
],
@@ -36,7 +40,7 @@
"hashes": [
{
"alg": "SHA-256",
- "content": "33d37cf528bc0b20ec8ffd9fa21170e7caadb1b9f15eb559d1937fa4c82d3d40"
+ "content": "20e983935a800046222a02674ed37baf3e7a4ef7cd40e6033d9c0efaeb73206f"
}
],
"type": "distribution",
@@ -66,9 +70,7 @@
],
"licenses": [
{
- "license": {
- "id": "Apache-2.0"
- }
+ "expression": "Apache-2.0 OR MIT"
}
],
"name": "package-c",
diff --git a/tests/_data/snapshots/environment/plain_local_1.3.xml.bin b/tests/_data/snapshots/environment/plain_local_1.3.xml.bin
index 9c663c20..99867867 100644
--- a/tests/_data/snapshots/environment/plain_local_1.3.xml.bin
+++ b/tests/_data/snapshots/environment/plain_local_1.3.xml.bin
@@ -29,7 +29,8 @@
some package A
- Apache-2.0
+ declared license of 'package-a'
+ some license text
@@ -37,7 +38,7 @@
file://.../tests/_data/infiles/_helpers/local_pckages/a/dist/package_a-23.42-py3-none-any.whl
PackageSource: Archive
- 4f37ac4a44c1dcce7f3d6203d45e9d1945a28f69fbfb44f418c44ea73c77de86
+ 5c8da28603857d4073c67e751ba3cd526a7ef414135faecfec164e7d01be24be
@@ -56,7 +57,7 @@
file://.../tests/_data/infiles/_helpers/local_pckages/b/dist/package-b-23.42.tar.gz
PackageSource: Archive
- 33d37cf528bc0b20ec8ffd9fa21170e7caadb1b9f15eb559d1937fa4c82d3d40
+ 20e983935a800046222a02674ed37baf3e7a4ef7cd40e6033d9c0efaeb73206f
@@ -66,9 +67,7 @@
23.42
some package C
-
- Apache-2.0
-
+ Apache-2.0 OR MIT
diff --git a/tests/_data/snapshots/environment/plain_local_1.4.json.bin b/tests/_data/snapshots/environment/plain_local_1.4.json.bin
index e6298492..6bdf4c88 100644
--- a/tests/_data/snapshots/environment/plain_local_1.4.json.bin
+++ b/tests/_data/snapshots/environment/plain_local_1.4.json.bin
@@ -9,7 +9,7 @@
"hashes": [
{
"alg": "SHA-256",
- "content": "4f37ac4a44c1dcce7f3d6203d45e9d1945a28f69fbfb44f418c44ea73c77de86"
+ "content": "5c8da28603857d4073c67e751ba3cd526a7ef414135faecfec164e7d01be24be"
}
],
"type": "distribution",
@@ -19,7 +19,11 @@
"licenses": [
{
"license": {
- "id": "Apache-2.0"
+ "name": "declared license of 'package-a'",
+ "text": {
+ "content": "some license text",
+ "contentType": "text/plain"
+ }
}
}
],
@@ -36,7 +40,7 @@
"hashes": [
{
"alg": "SHA-256",
- "content": "33d37cf528bc0b20ec8ffd9fa21170e7caadb1b9f15eb559d1937fa4c82d3d40"
+ "content": "20e983935a800046222a02674ed37baf3e7a4ef7cd40e6033d9c0efaeb73206f"
}
],
"type": "distribution",
@@ -66,9 +70,7 @@
],
"licenses": [
{
- "license": {
- "id": "Apache-2.0"
- }
+ "expression": "Apache-2.0 OR MIT"
}
],
"name": "package-c",
diff --git a/tests/_data/snapshots/environment/plain_local_1.4.xml.bin b/tests/_data/snapshots/environment/plain_local_1.4.xml.bin
index 4abed8df..22337ef7 100644
--- a/tests/_data/snapshots/environment/plain_local_1.4.xml.bin
+++ b/tests/_data/snapshots/environment/plain_local_1.4.xml.bin
@@ -56,7 +56,8 @@
some package A
- Apache-2.0
+ declared license of 'package-a'
+ some license text
@@ -64,7 +65,7 @@
file://.../tests/_data/infiles/_helpers/local_pckages/a/dist/package_a-23.42-py3-none-any.whl
PackageSource: Archive
- 4f37ac4a44c1dcce7f3d6203d45e9d1945a28f69fbfb44f418c44ea73c77de86
+ 5c8da28603857d4073c67e751ba3cd526a7ef414135faecfec164e7d01be24be
@@ -83,7 +84,7 @@
file://.../tests/_data/infiles/_helpers/local_pckages/b/dist/package-b-23.42.tar.gz
PackageSource: Archive
- 33d37cf528bc0b20ec8ffd9fa21170e7caadb1b9f15eb559d1937fa4c82d3d40
+ 20e983935a800046222a02674ed37baf3e7a4ef7cd40e6033d9c0efaeb73206f
@@ -93,9 +94,7 @@
23.42
some package C
-
- Apache-2.0
-
+ Apache-2.0 OR MIT
diff --git a/tests/_data/snapshots/environment/plain_local_1.5.json.bin b/tests/_data/snapshots/environment/plain_local_1.5.json.bin
index 948eeb0b..ec24b2d8 100644
--- a/tests/_data/snapshots/environment/plain_local_1.5.json.bin
+++ b/tests/_data/snapshots/environment/plain_local_1.5.json.bin
@@ -9,7 +9,7 @@
"hashes": [
{
"alg": "SHA-256",
- "content": "4f37ac4a44c1dcce7f3d6203d45e9d1945a28f69fbfb44f418c44ea73c77de86"
+ "content": "5c8da28603857d4073c67e751ba3cd526a7ef414135faecfec164e7d01be24be"
}
],
"type": "distribution",
@@ -19,7 +19,11 @@
"licenses": [
{
"license": {
- "id": "Apache-2.0"
+ "name": "declared license of 'package-a'",
+ "text": {
+ "content": "some license text",
+ "contentType": "text/plain"
+ }
}
}
],
@@ -36,7 +40,7 @@
"hashes": [
{
"alg": "SHA-256",
- "content": "33d37cf528bc0b20ec8ffd9fa21170e7caadb1b9f15eb559d1937fa4c82d3d40"
+ "content": "20e983935a800046222a02674ed37baf3e7a4ef7cd40e6033d9c0efaeb73206f"
}
],
"type": "distribution",
@@ -66,9 +70,7 @@
],
"licenses": [
{
- "license": {
- "id": "Apache-2.0"
- }
+ "expression": "Apache-2.0 OR MIT"
}
],
"name": "package-c",
diff --git a/tests/_data/snapshots/environment/plain_local_1.5.xml.bin b/tests/_data/snapshots/environment/plain_local_1.5.xml.bin
index 926dc9b3..a59e09f4 100644
--- a/tests/_data/snapshots/environment/plain_local_1.5.xml.bin
+++ b/tests/_data/snapshots/environment/plain_local_1.5.xml.bin
@@ -56,7 +56,8 @@
some package A
- Apache-2.0
+ declared license of 'package-a'
+ some license text
@@ -64,7 +65,7 @@
file://.../tests/_data/infiles/_helpers/local_pckages/a/dist/package_a-23.42-py3-none-any.whl
PackageSource: Archive
- 4f37ac4a44c1dcce7f3d6203d45e9d1945a28f69fbfb44f418c44ea73c77de86
+ 5c8da28603857d4073c67e751ba3cd526a7ef414135faecfec164e7d01be24be
@@ -83,7 +84,7 @@
file://.../tests/_data/infiles/_helpers/local_pckages/b/dist/package-b-23.42.tar.gz
PackageSource: Archive
- 33d37cf528bc0b20ec8ffd9fa21170e7caadb1b9f15eb559d1937fa4c82d3d40
+ 20e983935a800046222a02674ed37baf3e7a4ef7cd40e6033d9c0efaeb73206f
@@ -93,9 +94,7 @@
23.42
some package C
-
- Apache-2.0
-
+ Apache-2.0 OR MIT
diff --git a/tests/_data/snapshots/environment/plain_normalize-packagename_1.1.xml.bin b/tests/_data/snapshots/environment/plain_normalize-packagename_1.1.xml.bin
index 8a805ef6..4c33f517 100644
--- a/tests/_data/snapshots/environment/plain_normalize-packagename_1.1.xml.bin
+++ b/tests/_data/snapshots/environment/plain_normalize-packagename_1.1.xml.bin
@@ -10,7 +10,8 @@
MIT
- MIT license
+ declared license of 'ruamel.yaml'
+ MIT license
pkg:pypi/ruamel.yaml@0.18.5
diff --git a/tests/_data/snapshots/environment/plain_normalize-packagename_1.2.json.bin b/tests/_data/snapshots/environment/plain_normalize-packagename_1.2.json.bin
index 7993a957..bf95cfa4 100644
--- a/tests/_data/snapshots/environment/plain_normalize-packagename_1.2.json.bin
+++ b/tests/_data/snapshots/environment/plain_normalize-packagename_1.2.json.bin
@@ -33,7 +33,11 @@
},
{
"license": {
- "name": "MIT license"
+ "name": "declared license of 'ruamel.yaml'",
+ "text": {
+ "content": "MIT license",
+ "contentType": "text/plain"
+ }
}
}
],
diff --git a/tests/_data/snapshots/environment/plain_normalize-packagename_1.2.xml.bin b/tests/_data/snapshots/environment/plain_normalize-packagename_1.2.xml.bin
index 7f18d55c..ce3a500b 100644
--- a/tests/_data/snapshots/environment/plain_normalize-packagename_1.2.xml.bin
+++ b/tests/_data/snapshots/environment/plain_normalize-packagename_1.2.xml.bin
@@ -29,7 +29,8 @@
MIT
- MIT license
+ declared license of 'ruamel.yaml'
+ MIT license
pkg:pypi/ruamel.yaml@0.18.5
diff --git a/tests/_data/snapshots/environment/plain_normalize-packagename_1.3.json.bin b/tests/_data/snapshots/environment/plain_normalize-packagename_1.3.json.bin
index e7434491..4d73455c 100644
--- a/tests/_data/snapshots/environment/plain_normalize-packagename_1.3.json.bin
+++ b/tests/_data/snapshots/environment/plain_normalize-packagename_1.3.json.bin
@@ -33,7 +33,11 @@
},
{
"license": {
- "name": "MIT license"
+ "name": "declared license of 'ruamel.yaml'",
+ "text": {
+ "content": "MIT license",
+ "contentType": "text/plain"
+ }
}
}
],
diff --git a/tests/_data/snapshots/environment/plain_normalize-packagename_1.3.xml.bin b/tests/_data/snapshots/environment/plain_normalize-packagename_1.3.xml.bin
index c2539a80..75be771b 100644
--- a/tests/_data/snapshots/environment/plain_normalize-packagename_1.3.xml.bin
+++ b/tests/_data/snapshots/environment/plain_normalize-packagename_1.3.xml.bin
@@ -32,7 +32,8 @@
MIT
- MIT license
+ declared license of 'ruamel.yaml'
+ MIT license
pkg:pypi/ruamel.yaml@0.18.5
diff --git a/tests/_data/snapshots/environment/plain_normalize-packagename_1.4.json.bin b/tests/_data/snapshots/environment/plain_normalize-packagename_1.4.json.bin
index cbe7949b..ba9ed46a 100644
--- a/tests/_data/snapshots/environment/plain_normalize-packagename_1.4.json.bin
+++ b/tests/_data/snapshots/environment/plain_normalize-packagename_1.4.json.bin
@@ -33,7 +33,11 @@
},
{
"license": {
- "name": "MIT license"
+ "name": "declared license of 'ruamel.yaml'",
+ "text": {
+ "content": "MIT license",
+ "contentType": "text/plain"
+ }
}
}
],
diff --git a/tests/_data/snapshots/environment/plain_normalize-packagename_1.4.xml.bin b/tests/_data/snapshots/environment/plain_normalize-packagename_1.4.xml.bin
index 356f25ac..deded9be 100644
--- a/tests/_data/snapshots/environment/plain_normalize-packagename_1.4.xml.bin
+++ b/tests/_data/snapshots/environment/plain_normalize-packagename_1.4.xml.bin
@@ -59,7 +59,8 @@
MIT
- MIT license
+ declared license of 'ruamel.yaml'
+ MIT license
pkg:pypi/ruamel.yaml@0.18.5
diff --git a/tests/_data/snapshots/environment/plain_normalize-packagename_1.5.json.bin b/tests/_data/snapshots/environment/plain_normalize-packagename_1.5.json.bin
index 47e61ad6..05011519 100644
--- a/tests/_data/snapshots/environment/plain_normalize-packagename_1.5.json.bin
+++ b/tests/_data/snapshots/environment/plain_normalize-packagename_1.5.json.bin
@@ -33,7 +33,11 @@
},
{
"license": {
- "name": "MIT license"
+ "name": "declared license of 'ruamel.yaml'",
+ "text": {
+ "content": "MIT license",
+ "contentType": "text/plain"
+ }
}
}
],
diff --git a/tests/_data/snapshots/environment/plain_normalize-packagename_1.5.xml.bin b/tests/_data/snapshots/environment/plain_normalize-packagename_1.5.xml.bin
index 4aae0de7..efdf8ff9 100644
--- a/tests/_data/snapshots/environment/plain_normalize-packagename_1.5.xml.bin
+++ b/tests/_data/snapshots/environment/plain_normalize-packagename_1.5.xml.bin
@@ -59,7 +59,8 @@
MIT
- MIT license
+ declared license of 'ruamel.yaml'
+ MIT license
pkg:pypi/ruamel.yaml@0.18.5
diff --git a/tests/_data/snapshots/environment/plain_with-extras_1.1.xml.bin b/tests/_data/snapshots/environment/plain_with-extras_1.1.xml.bin
index 8e7c5574..66824561 100644
--- a/tests/_data/snapshots/environment/plain_with-extras_1.1.xml.bin
+++ b/tests/_data/snapshots/environment/plain_with-extras_1.1.xml.bin
@@ -117,7 +117,8 @@
Python-2.0
- PSFL
+ declared license of 'defusedxml'
+ PSFL
pkg:pypi/defusedxml@0.7.1
@@ -138,7 +139,8 @@
Validates fully-qualified domain names against RFC 1123, so that they are acceptable to modern bowsers
- MPL 2.0
+ declared license of 'fqdn'
+ MPL 2.0
pkg:pypi/fqdn@1.5.1
@@ -194,7 +196,8 @@
ISC
- UNKNOWN
+ declared license of 'isoduration'
+ UNKNOWN
pkg:pypi/isoduration@20.11.0
@@ -223,7 +226,8 @@
Identify specific nodes in a JSON document (RFC 6901)
- Modified BSD License
+ declared license of 'jsonpointer'
+ Modified BSD License
pkg:pypi/jsonpointer@2.4
@@ -415,7 +419,8 @@
Extensions to the standard Python datetime module
- Dual License
+ declared license of 'python-dateutil'
+ Dual License
pkg:pypi/python-dateutil@2.8.2
@@ -480,7 +485,8 @@
MIT
- MIT license
+ declared license of 'rfc3339-validator'
+ MIT license
pkg:pypi/rfc3339-validator@0.1.4
@@ -500,7 +506,8 @@
GPL-3.0-or-later
- GNU GPLv3+
+ declared license of 'rfc3987'
+ GNU GPLv3+
pkg:pypi/rfc3987@1.3.8
@@ -575,7 +582,8 @@
Sorted Containers -- Sorted List, Sorted Dict, Sorted Set
- Apache 2.0
+ declared license of 'sortedcontainers'
+ Apache 2.0
pkg:pypi/sortedcontainers@2.4.0
@@ -592,7 +600,8 @@
Typing stubs for python-dateutil
- Apache-2.0 license
+ declared license of 'types-python-dateutil'
+ Apache-2.0 license
pkg:pypi/types-python-dateutil@2.8.19.14
@@ -628,7 +637,8 @@
MIT
- MIT License
+ declared license of 'uri-template'
+ MIT License
pkg:pypi/uri-template@1.3.0
diff --git a/tests/_data/snapshots/environment/plain_with-extras_1.2.json.bin b/tests/_data/snapshots/environment/plain_with-extras_1.2.json.bin
index 5947ad69..d9573345 100644
--- a/tests/_data/snapshots/environment/plain_with-extras_1.2.json.bin
+++ b/tests/_data/snapshots/environment/plain_with-extras_1.2.json.bin
@@ -159,7 +159,11 @@
},
{
"license": {
- "name": "PSFL"
+ "name": "declared license of 'defusedxml'",
+ "text": {
+ "content": "PSFL",
+ "contentType": "text/plain"
+ }
}
}
],
@@ -181,7 +185,11 @@
"licenses": [
{
"license": {
- "name": "MPL 2.0"
+ "name": "declared license of 'fqdn'",
+ "text": {
+ "content": "MPL 2.0",
+ "contentType": "text/plain"
+ }
}
}
],
@@ -268,7 +276,11 @@
},
{
"license": {
- "name": "UNKNOWN"
+ "name": "declared license of 'isoduration'",
+ "text": {
+ "content": "UNKNOWN",
+ "contentType": "text/plain"
+ }
}
}
],
@@ -290,7 +302,11 @@
"licenses": [
{
"license": {
- "name": "Modified BSD License"
+ "name": "declared license of 'jsonpointer'",
+ "text": {
+ "content": "Modified BSD License",
+ "contentType": "text/plain"
+ }
}
}
],
@@ -546,7 +562,11 @@
"licenses": [
{
"license": {
- "name": "Dual License"
+ "name": "declared license of 'python-dateutil'",
+ "text": {
+ "content": "Dual License",
+ "contentType": "text/plain"
+ }
}
}
],
@@ -620,7 +640,11 @@
},
{
"license": {
- "name": "MIT license"
+ "name": "declared license of 'rfc3339-validator'",
+ "text": {
+ "content": "MIT license",
+ "contentType": "text/plain"
+ }
}
}
],
@@ -652,7 +676,11 @@
},
{
"license": {
- "name": "GNU GPLv3+"
+ "name": "declared license of 'rfc3987'",
+ "text": {
+ "content": "GNU GPLv3+",
+ "contentType": "text/plain"
+ }
}
}
],
@@ -743,7 +771,11 @@
"licenses": [
{
"license": {
- "name": "Apache 2.0"
+ "name": "declared license of 'sortedcontainers'",
+ "text": {
+ "content": "Apache 2.0",
+ "contentType": "text/plain"
+ }
}
}
],
@@ -785,7 +817,11 @@
"licenses": [
{
"license": {
- "name": "Apache-2.0 license"
+ "name": "declared license of 'types-python-dateutil'",
+ "text": {
+ "content": "Apache-2.0 license",
+ "contentType": "text/plain"
+ }
}
}
],
@@ -812,7 +848,11 @@
},
{
"license": {
- "name": "MIT License"
+ "name": "declared license of 'uri-template'",
+ "text": {
+ "content": "MIT License",
+ "contentType": "text/plain"
+ }
}
}
],
diff --git a/tests/_data/snapshots/environment/plain_with-extras_1.2.xml.bin b/tests/_data/snapshots/environment/plain_with-extras_1.2.xml.bin
index 2c3c416c..6d638e79 100644
--- a/tests/_data/snapshots/environment/plain_with-extras_1.2.xml.bin
+++ b/tests/_data/snapshots/environment/plain_with-extras_1.2.xml.bin
@@ -136,7 +136,8 @@
Python-2.0
- PSFL
+ declared license of 'defusedxml'
+ PSFL
pkg:pypi/defusedxml@0.7.1
@@ -157,7 +158,8 @@
Validates fully-qualified domain names against RFC 1123, so that they are acceptable to modern bowsers
- MPL 2.0
+ declared license of 'fqdn'
+ MPL 2.0
pkg:pypi/fqdn@1.5.1
@@ -213,7 +215,8 @@
ISC
- UNKNOWN
+ declared license of 'isoduration'
+ UNKNOWN
pkg:pypi/isoduration@20.11.0
@@ -242,7 +245,8 @@
Identify specific nodes in a JSON document (RFC 6901)
- Modified BSD License
+ declared license of 'jsonpointer'
+ Modified BSD License
pkg:pypi/jsonpointer@2.4
@@ -434,7 +438,8 @@
Extensions to the standard Python datetime module
- Dual License
+ declared license of 'python-dateutil'
+ Dual License
pkg:pypi/python-dateutil@2.8.2
@@ -499,7 +504,8 @@
MIT
- MIT license
+ declared license of 'rfc3339-validator'
+ MIT license
pkg:pypi/rfc3339-validator@0.1.4
@@ -519,7 +525,8 @@
GPL-3.0-or-later
- GNU GPLv3+
+ declared license of 'rfc3987'
+ GNU GPLv3+
pkg:pypi/rfc3987@1.3.8
@@ -594,7 +601,8 @@
Sorted Containers -- Sorted List, Sorted Dict, Sorted Set
- Apache 2.0
+ declared license of 'sortedcontainers'
+ Apache 2.0
pkg:pypi/sortedcontainers@2.4.0
@@ -611,7 +619,8 @@
Typing stubs for python-dateutil
- Apache-2.0 license
+ declared license of 'types-python-dateutil'
+ Apache-2.0 license
pkg:pypi/types-python-dateutil@2.8.19.14
@@ -647,7 +656,8 @@
MIT
- MIT License
+ declared license of 'uri-template'
+ MIT License
pkg:pypi/uri-template@1.3.0
diff --git a/tests/_data/snapshots/environment/plain_with-extras_1.3.json.bin b/tests/_data/snapshots/environment/plain_with-extras_1.3.json.bin
index ac47eb8a..673d3a4d 100644
--- a/tests/_data/snapshots/environment/plain_with-extras_1.3.json.bin
+++ b/tests/_data/snapshots/environment/plain_with-extras_1.3.json.bin
@@ -165,7 +165,11 @@
},
{
"license": {
- "name": "PSFL"
+ "name": "declared license of 'defusedxml'",
+ "text": {
+ "content": "PSFL",
+ "contentType": "text/plain"
+ }
}
}
],
@@ -187,7 +191,11 @@
"licenses": [
{
"license": {
- "name": "MPL 2.0"
+ "name": "declared license of 'fqdn'",
+ "text": {
+ "content": "MPL 2.0",
+ "contentType": "text/plain"
+ }
}
}
],
@@ -274,7 +282,11 @@
},
{
"license": {
- "name": "UNKNOWN"
+ "name": "declared license of 'isoduration'",
+ "text": {
+ "content": "UNKNOWN",
+ "contentType": "text/plain"
+ }
}
}
],
@@ -296,7 +308,11 @@
"licenses": [
{
"license": {
- "name": "Modified BSD License"
+ "name": "declared license of 'jsonpointer'",
+ "text": {
+ "content": "Modified BSD License",
+ "contentType": "text/plain"
+ }
}
}
],
@@ -558,7 +574,11 @@
"licenses": [
{
"license": {
- "name": "Dual License"
+ "name": "declared license of 'python-dateutil'",
+ "text": {
+ "content": "Dual License",
+ "contentType": "text/plain"
+ }
}
}
],
@@ -632,7 +652,11 @@
},
{
"license": {
- "name": "MIT license"
+ "name": "declared license of 'rfc3339-validator'",
+ "text": {
+ "content": "MIT license",
+ "contentType": "text/plain"
+ }
}
}
],
@@ -664,7 +688,11 @@
},
{
"license": {
- "name": "GNU GPLv3+"
+ "name": "declared license of 'rfc3987'",
+ "text": {
+ "content": "GNU GPLv3+",
+ "contentType": "text/plain"
+ }
}
}
],
@@ -755,7 +783,11 @@
"licenses": [
{
"license": {
- "name": "Apache 2.0"
+ "name": "declared license of 'sortedcontainers'",
+ "text": {
+ "content": "Apache 2.0",
+ "contentType": "text/plain"
+ }
}
}
],
@@ -797,7 +829,11 @@
"licenses": [
{
"license": {
- "name": "Apache-2.0 license"
+ "name": "declared license of 'types-python-dateutil'",
+ "text": {
+ "content": "Apache-2.0 license",
+ "contentType": "text/plain"
+ }
}
}
],
@@ -824,7 +860,11 @@
},
{
"license": {
- "name": "MIT License"
+ "name": "declared license of 'uri-template'",
+ "text": {
+ "content": "MIT License",
+ "contentType": "text/plain"
+ }
}
}
],
diff --git a/tests/_data/snapshots/environment/plain_with-extras_1.3.xml.bin b/tests/_data/snapshots/environment/plain_with-extras_1.3.xml.bin
index 984c9fee..deb346e6 100644
--- a/tests/_data/snapshots/environment/plain_with-extras_1.3.xml.bin
+++ b/tests/_data/snapshots/environment/plain_with-extras_1.3.xml.bin
@@ -142,7 +142,8 @@
Python-2.0
- PSFL
+ declared license of 'defusedxml'
+ PSFL
pkg:pypi/defusedxml@0.7.1
@@ -163,7 +164,8 @@
Validates fully-qualified domain names against RFC 1123, so that they are acceptable to modern bowsers
- MPL 2.0
+ declared license of 'fqdn'
+ MPL 2.0
pkg:pypi/fqdn@1.5.1
@@ -219,7 +221,8 @@
ISC
- UNKNOWN
+ declared license of 'isoduration'
+ UNKNOWN
pkg:pypi/isoduration@20.11.0
@@ -248,7 +251,8 @@
Identify specific nodes in a JSON document (RFC 6901)
- Modified BSD License
+ declared license of 'jsonpointer'
+ Modified BSD License
pkg:pypi/jsonpointer@2.4
@@ -443,7 +447,8 @@
Extensions to the standard Python datetime module
- Dual License
+ declared license of 'python-dateutil'
+ Dual License
pkg:pypi/python-dateutil@2.8.2
@@ -508,7 +513,8 @@
MIT
- MIT license
+ declared license of 'rfc3339-validator'
+ MIT license
pkg:pypi/rfc3339-validator@0.1.4
@@ -528,7 +534,8 @@
GPL-3.0-or-later
- GNU GPLv3+
+ declared license of 'rfc3987'
+ GNU GPLv3+
pkg:pypi/rfc3987@1.3.8
@@ -603,7 +610,8 @@
Sorted Containers -- Sorted List, Sorted Dict, Sorted Set
- Apache 2.0
+ declared license of 'sortedcontainers'
+ Apache 2.0
pkg:pypi/sortedcontainers@2.4.0
@@ -620,7 +628,8 @@
Typing stubs for python-dateutil
- Apache-2.0 license
+ declared license of 'types-python-dateutil'
+ Apache-2.0 license
pkg:pypi/types-python-dateutil@2.8.19.14
@@ -656,7 +665,8 @@
MIT
- MIT License
+ declared license of 'uri-template'
+ MIT License
pkg:pypi/uri-template@1.3.0
diff --git a/tests/_data/snapshots/environment/plain_with-extras_1.4.json.bin b/tests/_data/snapshots/environment/plain_with-extras_1.4.json.bin
index 354a3737..25ea23d5 100644
--- a/tests/_data/snapshots/environment/plain_with-extras_1.4.json.bin
+++ b/tests/_data/snapshots/environment/plain_with-extras_1.4.json.bin
@@ -165,7 +165,11 @@
},
{
"license": {
- "name": "PSFL"
+ "name": "declared license of 'defusedxml'",
+ "text": {
+ "content": "PSFL",
+ "contentType": "text/plain"
+ }
}
}
],
@@ -187,7 +191,11 @@
"licenses": [
{
"license": {
- "name": "MPL 2.0"
+ "name": "declared license of 'fqdn'",
+ "text": {
+ "content": "MPL 2.0",
+ "contentType": "text/plain"
+ }
}
}
],
@@ -274,7 +282,11 @@
},
{
"license": {
- "name": "UNKNOWN"
+ "name": "declared license of 'isoduration'",
+ "text": {
+ "content": "UNKNOWN",
+ "contentType": "text/plain"
+ }
}
}
],
@@ -296,7 +308,11 @@
"licenses": [
{
"license": {
- "name": "Modified BSD License"
+ "name": "declared license of 'jsonpointer'",
+ "text": {
+ "content": "Modified BSD License",
+ "contentType": "text/plain"
+ }
}
}
],
@@ -558,7 +574,11 @@
"licenses": [
{
"license": {
- "name": "Dual License"
+ "name": "declared license of 'python-dateutil'",
+ "text": {
+ "content": "Dual License",
+ "contentType": "text/plain"
+ }
}
}
],
@@ -632,7 +652,11 @@
},
{
"license": {
- "name": "MIT license"
+ "name": "declared license of 'rfc3339-validator'",
+ "text": {
+ "content": "MIT license",
+ "contentType": "text/plain"
+ }
}
}
],
@@ -664,7 +688,11 @@
},
{
"license": {
- "name": "GNU GPLv3+"
+ "name": "declared license of 'rfc3987'",
+ "text": {
+ "content": "GNU GPLv3+",
+ "contentType": "text/plain"
+ }
}
}
],
@@ -755,7 +783,11 @@
"licenses": [
{
"license": {
- "name": "Apache 2.0"
+ "name": "declared license of 'sortedcontainers'",
+ "text": {
+ "content": "Apache 2.0",
+ "contentType": "text/plain"
+ }
}
}
],
@@ -797,7 +829,11 @@
"licenses": [
{
"license": {
- "name": "Apache-2.0 license"
+ "name": "declared license of 'types-python-dateutil'",
+ "text": {
+ "content": "Apache-2.0 license",
+ "contentType": "text/plain"
+ }
}
}
],
@@ -824,7 +860,11 @@
},
{
"license": {
- "name": "MIT License"
+ "name": "declared license of 'uri-template'",
+ "text": {
+ "content": "MIT License",
+ "contentType": "text/plain"
+ }
}
}
],
diff --git a/tests/_data/snapshots/environment/plain_with-extras_1.4.xml.bin b/tests/_data/snapshots/environment/plain_with-extras_1.4.xml.bin
index 6d289b3f..91dd03a1 100644
--- a/tests/_data/snapshots/environment/plain_with-extras_1.4.xml.bin
+++ b/tests/_data/snapshots/environment/plain_with-extras_1.4.xml.bin
@@ -169,7 +169,8 @@
Python-2.0
- PSFL
+ declared license of 'defusedxml'
+ PSFL
pkg:pypi/defusedxml@0.7.1
@@ -190,7 +191,8 @@
Validates fully-qualified domain names against RFC 1123, so that they are acceptable to modern bowsers
- MPL 2.0
+ declared license of 'fqdn'
+ MPL 2.0
pkg:pypi/fqdn@1.5.1
@@ -246,7 +248,8 @@
ISC
- UNKNOWN
+ declared license of 'isoduration'
+ UNKNOWN
pkg:pypi/isoduration@20.11.0
@@ -275,7 +278,8 @@
Identify specific nodes in a JSON document (RFC 6901)
- Modified BSD License
+ declared license of 'jsonpointer'
+ Modified BSD License
pkg:pypi/jsonpointer@2.4
@@ -470,7 +474,8 @@
Extensions to the standard Python datetime module
- Dual License
+ declared license of 'python-dateutil'
+ Dual License
pkg:pypi/python-dateutil@2.8.2
@@ -535,7 +540,8 @@
MIT
- MIT license
+ declared license of 'rfc3339-validator'
+ MIT license
pkg:pypi/rfc3339-validator@0.1.4
@@ -555,7 +561,8 @@
GPL-3.0-or-later
- GNU GPLv3+
+ declared license of 'rfc3987'
+ GNU GPLv3+
pkg:pypi/rfc3987@1.3.8
@@ -630,7 +637,8 @@
Sorted Containers -- Sorted List, Sorted Dict, Sorted Set
- Apache 2.0
+ declared license of 'sortedcontainers'
+ Apache 2.0
pkg:pypi/sortedcontainers@2.4.0
@@ -647,7 +655,8 @@
Typing stubs for python-dateutil
- Apache-2.0 license
+ declared license of 'types-python-dateutil'
+ Apache-2.0 license
pkg:pypi/types-python-dateutil@2.8.19.14
@@ -683,7 +692,8 @@
MIT
- MIT License
+ declared license of 'uri-template'
+ MIT License
pkg:pypi/uri-template@1.3.0
diff --git a/tests/_data/snapshots/environment/plain_with-extras_1.5.json.bin b/tests/_data/snapshots/environment/plain_with-extras_1.5.json.bin
index 147b5ec9..79464274 100644
--- a/tests/_data/snapshots/environment/plain_with-extras_1.5.json.bin
+++ b/tests/_data/snapshots/environment/plain_with-extras_1.5.json.bin
@@ -165,7 +165,11 @@
},
{
"license": {
- "name": "PSFL"
+ "name": "declared license of 'defusedxml'",
+ "text": {
+ "content": "PSFL",
+ "contentType": "text/plain"
+ }
}
}
],
@@ -187,7 +191,11 @@
"licenses": [
{
"license": {
- "name": "MPL 2.0"
+ "name": "declared license of 'fqdn'",
+ "text": {
+ "content": "MPL 2.0",
+ "contentType": "text/plain"
+ }
}
}
],
@@ -274,7 +282,11 @@
},
{
"license": {
- "name": "UNKNOWN"
+ "name": "declared license of 'isoduration'",
+ "text": {
+ "content": "UNKNOWN",
+ "contentType": "text/plain"
+ }
}
}
],
@@ -296,7 +308,11 @@
"licenses": [
{
"license": {
- "name": "Modified BSD License"
+ "name": "declared license of 'jsonpointer'",
+ "text": {
+ "content": "Modified BSD License",
+ "contentType": "text/plain"
+ }
}
}
],
@@ -558,7 +574,11 @@
"licenses": [
{
"license": {
- "name": "Dual License"
+ "name": "declared license of 'python-dateutil'",
+ "text": {
+ "content": "Dual License",
+ "contentType": "text/plain"
+ }
}
}
],
@@ -632,7 +652,11 @@
},
{
"license": {
- "name": "MIT license"
+ "name": "declared license of 'rfc3339-validator'",
+ "text": {
+ "content": "MIT license",
+ "contentType": "text/plain"
+ }
}
}
],
@@ -664,7 +688,11 @@
},
{
"license": {
- "name": "GNU GPLv3+"
+ "name": "declared license of 'rfc3987'",
+ "text": {
+ "content": "GNU GPLv3+",
+ "contentType": "text/plain"
+ }
}
}
],
@@ -755,7 +783,11 @@
"licenses": [
{
"license": {
- "name": "Apache 2.0"
+ "name": "declared license of 'sortedcontainers'",
+ "text": {
+ "content": "Apache 2.0",
+ "contentType": "text/plain"
+ }
}
}
],
@@ -797,7 +829,11 @@
"licenses": [
{
"license": {
- "name": "Apache-2.0 license"
+ "name": "declared license of 'types-python-dateutil'",
+ "text": {
+ "content": "Apache-2.0 license",
+ "contentType": "text/plain"
+ }
}
}
],
@@ -824,7 +860,11 @@
},
{
"license": {
- "name": "MIT License"
+ "name": "declared license of 'uri-template'",
+ "text": {
+ "content": "MIT License",
+ "contentType": "text/plain"
+ }
}
}
],
diff --git a/tests/_data/snapshots/environment/plain_with-extras_1.5.xml.bin b/tests/_data/snapshots/environment/plain_with-extras_1.5.xml.bin
index 1606c3ec..295897a7 100644
--- a/tests/_data/snapshots/environment/plain_with-extras_1.5.xml.bin
+++ b/tests/_data/snapshots/environment/plain_with-extras_1.5.xml.bin
@@ -169,7 +169,8 @@
Python-2.0
- PSFL
+ declared license of 'defusedxml'
+ PSFL
pkg:pypi/defusedxml@0.7.1
@@ -190,7 +191,8 @@
Validates fully-qualified domain names against RFC 1123, so that they are acceptable to modern bowsers
- MPL 2.0
+ declared license of 'fqdn'
+ MPL 2.0
pkg:pypi/fqdn@1.5.1
@@ -246,7 +248,8 @@
ISC
- UNKNOWN
+ declared license of 'isoduration'
+ UNKNOWN
pkg:pypi/isoduration@20.11.0
@@ -275,7 +278,8 @@
Identify specific nodes in a JSON document (RFC 6901)
- Modified BSD License
+ declared license of 'jsonpointer'
+ Modified BSD License
pkg:pypi/jsonpointer@2.4
@@ -470,7 +474,8 @@
Extensions to the standard Python datetime module
- Dual License
+ declared license of 'python-dateutil'
+ Dual License
pkg:pypi/python-dateutil@2.8.2
@@ -535,7 +540,8 @@
MIT
- MIT license
+ declared license of 'rfc3339-validator'
+ MIT license
pkg:pypi/rfc3339-validator@0.1.4
@@ -555,7 +561,8 @@
GPL-3.0-or-later
- GNU GPLv3+
+ declared license of 'rfc3987'
+ GNU GPLv3+
pkg:pypi/rfc3987@1.3.8
@@ -630,7 +637,8 @@
Sorted Containers -- Sorted List, Sorted Dict, Sorted Set
- Apache 2.0
+ declared license of 'sortedcontainers'
+ Apache 2.0
pkg:pypi/sortedcontainers@2.4.0
@@ -647,7 +655,8 @@
Typing stubs for python-dateutil
- Apache-2.0 license
+ declared license of 'types-python-dateutil'
+ Apache-2.0 license
pkg:pypi/types-python-dateutil@2.8.19.14
@@ -683,7 +692,8 @@
MIT
- MIT License
+ declared license of 'uri-template'
+ MIT License
pkg:pypi/uri-template@1.3.0
diff --git a/tests/_data/snapshots/environment/plain_with-license-file_1.0.xml.bin b/tests/_data/snapshots/environment/plain_with-license-file_1.0.xml.bin
new file mode 100644
index 00000000..acb06612
--- /dev/null
+++ b/tests/_data/snapshots/environment/plain_with-license-file_1.0.xml.bin
@@ -0,0 +1,4 @@
+
+
+
+
diff --git a/tests/_data/snapshots/environment/plain_with-license-file_1.1.xml.bin b/tests/_data/snapshots/environment/plain_with-license-file_1.1.xml.bin
new file mode 100644
index 00000000..640f73ff
--- /dev/null
+++ b/tests/_data/snapshots/environment/plain_with-license-file_1.1.xml.bin
@@ -0,0 +1,4 @@
+
+
+
+
diff --git a/tests/_data/snapshots/environment/plain_with-license-file_1.2.json.bin b/tests/_data/snapshots/environment/plain_with-license-file_1.2.json.bin
new file mode 100644
index 00000000..1ee914a9
--- /dev/null
+++ b/tests/_data/snapshots/environment/plain_with-license-file_1.2.json.bin
@@ -0,0 +1,44 @@
+{
+ "dependencies": [
+ {
+ "ref": "root-component"
+ }
+ ],
+ "metadata": {
+ "component": {
+ "bom-ref": "root-component",
+ "description": "with licenses from file, instead of SPDX ID/Expression",
+ "licenses": [
+ {
+ "license": {
+ "name": "declared license of 'with-license-file'",
+ "text": {
+ "content": "VGhpcyBpcyB0aGUgbGljZW5zZSB0ZXh0IG9mIHRoaXMgY29tcG9uZW50LgpJdCBpcyBleHBlY3RlZCB0byBiZSBhdmFpbGFibGUgaW4gYSBTQk9NLgo=",
+ "contentType": "text/plain",
+ "encoding": "base64"
+ }
+ }
+ }
+ ],
+ "name": "with-license-file",
+ "type": "application",
+ "version": "0.1.0"
+ },
+ "tools": [
+ {
+ "name": "cyclonedx-bom",
+ "vendor": "CycloneDX",
+ "version": "thisVersion-testing"
+ },
+ {
+ "name": "cyclonedx-python-lib",
+ "vendor": "CycloneDX",
+ "version": "libVersion-testing"
+ }
+ ]
+ },
+ "version": 1,
+ "$schema": "http://cyclonedx.org/schema/bom-1.2b.schema.json",
+ "bomFormat": "CycloneDX",
+ "specVersion": "1.2"
+}
\ No newline at end of file
diff --git a/tests/_data/snapshots/environment/plain_with-license-file_1.2.xml.bin b/tests/_data/snapshots/environment/plain_with-license-file_1.2.xml.bin
new file mode 100644
index 00000000..8b335021
--- /dev/null
+++ b/tests/_data/snapshots/environment/plain_with-license-file_1.2.xml.bin
@@ -0,0 +1,31 @@
+
+
+
+
+
+ CycloneDX
+ cyclonedx-bom
+ thisVersion-testing
+
+
+ CycloneDX
+ cyclonedx-python-lib
+ libVersion-testing
+
+
+
+ with-license-file
+ 0.1.0
+ with licenses from file, instead of SPDX ID/Expression
+
+
+ declared license of 'with-license-file'
+ VGhpcyBpcyB0aGUgbGljZW5zZSB0ZXh0IG9mIHRoaXMgY29tcG9uZW50LgpJdCBpcyBleHBlY3RlZCB0byBiZSBhdmFpbGFibGUgaW4gYSBTQk9NLgo=
+
+
+
+
+
+
+
+
diff --git a/tests/_data/snapshots/environment/plain_with-license-file_1.3.json.bin b/tests/_data/snapshots/environment/plain_with-license-file_1.3.json.bin
new file mode 100644
index 00000000..0c62fac8
--- /dev/null
+++ b/tests/_data/snapshots/environment/plain_with-license-file_1.3.json.bin
@@ -0,0 +1,50 @@
+{
+ "dependencies": [
+ {
+ "ref": "root-component"
+ }
+ ],
+ "metadata": {
+ "component": {
+ "bom-ref": "root-component",
+ "description": "with licenses from file, instead of SPDX ID/Expression",
+ "licenses": [
+ {
+ "license": {
+ "name": "declared license of 'with-license-file'",
+ "text": {
+ "content": "VGhpcyBpcyB0aGUgbGljZW5zZSB0ZXh0IG9mIHRoaXMgY29tcG9uZW50LgpJdCBpcyBleHBlY3RlZCB0byBiZSBhdmFpbGFibGUgaW4gYSBTQk9NLgo=",
+ "contentType": "text/plain",
+ "encoding": "base64"
+ }
+ }
+ }
+ ],
+ "name": "with-license-file",
+ "type": "application",
+ "version": "0.1.0"
+ },
+ "properties": [
+ {
+ "name": "cdx:reproducible",
+ "value": "true"
+ }
+ ],
+ "tools": [
+ {
+ "name": "cyclonedx-bom",
+ "vendor": "CycloneDX",
+ "version": "thisVersion-testing"
+ },
+ {
+ "name": "cyclonedx-python-lib",
+ "vendor": "CycloneDX",
+ "version": "libVersion-testing"
+ }
+ ]
+ },
+ "version": 1,
+ "$schema": "http://cyclonedx.org/schema/bom-1.3a.schema.json",
+ "bomFormat": "CycloneDX",
+ "specVersion": "1.3"
+}
\ No newline at end of file
diff --git a/tests/_data/snapshots/environment/plain_with-license-file_1.3.xml.bin b/tests/_data/snapshots/environment/plain_with-license-file_1.3.xml.bin
new file mode 100644
index 00000000..ca266c8c
--- /dev/null
+++ b/tests/_data/snapshots/environment/plain_with-license-file_1.3.xml.bin
@@ -0,0 +1,34 @@
+
+
+
+
+
+ CycloneDX
+ cyclonedx-bom
+ thisVersion-testing
+
+
+ CycloneDX
+ cyclonedx-python-lib
+ libVersion-testing
+
+
+
+ with-license-file
+ 0.1.0
+ with licenses from file, instead of SPDX ID/Expression
+
+
+ declared license of 'with-license-file'
+ VGhpcyBpcyB0aGUgbGljZW5zZSB0ZXh0IG9mIHRoaXMgY29tcG9uZW50LgpJdCBpcyBleHBlY3RlZCB0byBiZSBhdmFpbGFibGUgaW4gYSBTQk9NLgo=
+
+
+
+
+ true
+
+
+
+
+
+
diff --git a/tests/_data/snapshots/environment/plain_with-license-file_1.4.json.bin b/tests/_data/snapshots/environment/plain_with-license-file_1.4.json.bin
new file mode 100644
index 00000000..c913eef1
--- /dev/null
+++ b/tests/_data/snapshots/environment/plain_with-license-file_1.4.json.bin
@@ -0,0 +1,46 @@
+{
+ "dependencies": [
+ {
+ "ref": "root-component"
+ }
+ ],
+ "metadata": {
+ "component": {
+ "bom-ref": "root-component",
+ "description": "with licenses from file, instead of SPDX ID/Expression",
+ "licenses": [
+ {
+ "license": {
+ "name": "declared license of 'with-license-file'",
+ "text": {
+ "content": "VGhpcyBpcyB0aGUgbGljZW5zZSB0ZXh0IG9mIHRoaXMgY29tcG9uZW50LgpJdCBpcyBleHBlY3RlZCB0byBiZSBhdmFpbGFibGUgaW4gYSBTQk9NLgo=",
+ "contentType": "text/plain",
+ "encoding": "base64"
+ }
+ }
+ }
+ ],
+ "name": "with-license-file",
+ "type": "application",
+ "version": "0.1.0"
+ },
+ "properties": [
+ {
+ "name": "cdx:reproducible",
+ "value": "true"
+ }
+ ],
+ "tools": [
+ {
+ "externalReferences": [ ],
+ "name": "cyclonedx-python-lib",
+ "vendor": "CycloneDX",
+ "version": "libVersion-testing"
+ }
+ ]
+ },
+ "version": 1,
+ "$schema": "http://cyclonedx.org/schema/bom-1.4.schema.json",
+ "bomFormat": "CycloneDX",
+ "specVersion": "1.4"
+}
\ No newline at end of file
diff --git a/tests/_data/snapshots/environment/plain_with-license-file_1.4.xml.bin b/tests/_data/snapshots/environment/plain_with-license-file_1.4.xml.bin
new file mode 100644
index 00000000..51e9cbe4
--- /dev/null
+++ b/tests/_data/snapshots/environment/plain_with-license-file_1.4.xml.bin
@@ -0,0 +1,61 @@
+
+
+
+
+
+ CycloneDX
+ cyclonedx-bom
+ thisVersion-testing
+
+
+ https://github.com/CycloneDX/cyclonedx-python/actions
+
+
+ https://pypi.org/project/cyclonedx-bom/
+
+
+ https://cyclonedx-bom-tool.readthedocs.io/
+
+
+ https://github.com/CycloneDX/cyclonedx-python/issues
+
+
+ https://github.com/CycloneDX/cyclonedx-python/blob/main/LICENSE
+
+
+ https://github.com/CycloneDX/cyclonedx-python/blob/main/CHANGELOG.md
+
+
+ https://github.com/CycloneDX/cyclonedx-python/
+
+
+ https://github.com/CycloneDX/cyclonedx-python/#readme
+
+
+
+
+ CycloneDX
+ cyclonedx-python-lib
+ libVersion-testing
+
+
+
+
+ with-license-file
+ 0.1.0
+ with licenses from file, instead of SPDX ID/Expression
+
+
+ declared license of 'with-license-file'
+ VGhpcyBpcyB0aGUgbGljZW5zZSB0ZXh0IG9mIHRoaXMgY29tcG9uZW50LgpJdCBpcyBleHBlY3RlZCB0byBiZSBhdmFpbGFibGUgaW4gYSBTQk9NLgo=
+
+
+
+
+ true
+
+
+
+
+
+
diff --git a/tests/_data/snapshots/environment/plain_with-license-file_1.5.json.bin b/tests/_data/snapshots/environment/plain_with-license-file_1.5.json.bin
new file mode 100644
index 00000000..01298deb
--- /dev/null
+++ b/tests/_data/snapshots/environment/plain_with-license-file_1.5.json.bin
@@ -0,0 +1,46 @@
+{
+ "dependencies": [
+ {
+ "ref": "root-component"
+ }
+ ],
+ "metadata": {
+ "component": {
+ "bom-ref": "root-component",
+ "description": "with licenses from file, instead of SPDX ID/Expression",
+ "licenses": [
+ {
+ "license": {
+ "name": "declared license of 'with-license-file'",
+ "text": {
+ "content": "VGhpcyBpcyB0aGUgbGljZW5zZSB0ZXh0IG9mIHRoaXMgY29tcG9uZW50LgpJdCBpcyBleHBlY3RlZCB0byBiZSBhdmFpbGFibGUgaW4gYSBTQk9NLgo=",
+ "contentType": "text/plain",
+ "encoding": "base64"
+ }
+ }
+ }
+ ],
+ "name": "with-license-file",
+ "type": "application",
+ "version": "0.1.0"
+ },
+ "properties": [
+ {
+ "name": "cdx:reproducible",
+ "value": "true"
+ }
+ ],
+ "tools": [
+ {
+ "externalReferences": [ ],
+ "name": "cyclonedx-python-lib",
+ "vendor": "CycloneDX",
+ "version": "libVersion-testing"
+ }
+ ]
+ },
+ "version": 1,
+ "$schema": "http://cyclonedx.org/schema/bom-1.5.schema.json",
+ "bomFormat": "CycloneDX",
+ "specVersion": "1.5"
+}
\ No newline at end of file
diff --git a/tests/_data/snapshots/environment/plain_with-license-file_1.5.xml.bin b/tests/_data/snapshots/environment/plain_with-license-file_1.5.xml.bin
new file mode 100644
index 00000000..0dc1b63d
--- /dev/null
+++ b/tests/_data/snapshots/environment/plain_with-license-file_1.5.xml.bin
@@ -0,0 +1,61 @@
+
+
+
+
+
+ CycloneDX
+ cyclonedx-bom
+ thisVersion-testing
+
+
+ https://github.com/CycloneDX/cyclonedx-python/actions
+
+
+ https://pypi.org/project/cyclonedx-bom/
+
+
+ https://cyclonedx-bom-tool.readthedocs.io/
+
+
+ https://github.com/CycloneDX/cyclonedx-python/issues
+
+
+ https://github.com/CycloneDX/cyclonedx-python/blob/main/LICENSE
+
+
+ https://github.com/CycloneDX/cyclonedx-python/blob/main/CHANGELOG.md
+
+
+ https://github.com/CycloneDX/cyclonedx-python/
+
+
+ https://github.com/CycloneDX/cyclonedx-python/#readme
+
+
+
+
+ CycloneDX
+ cyclonedx-python-lib
+ libVersion-testing
+
+
+
+
+ with-license-file
+ 0.1.0
+ with licenses from file, instead of SPDX ID/Expression
+
+
+ declared license of 'with-license-file'
+ VGhpcyBpcyB0aGUgbGljZW5zZSB0ZXh0IG9mIHRoaXMgY29tcG9uZW50LgpJdCBpcyBleHBlY3RlZCB0byBiZSBhdmFpbGFibGUgaW4gYSBTQk9NLgo=
+
+
+
+
+ true
+
+
+
+
+
+
diff --git a/tests/_data/snapshots/environment/plain_with-license-text_1.0.xml.bin b/tests/_data/snapshots/environment/plain_with-license-text_1.0.xml.bin
new file mode 100644
index 00000000..13deb487
--- /dev/null
+++ b/tests/_data/snapshots/environment/plain_with-license-text_1.0.xml.bin
@@ -0,0 +1,23 @@
+
+
+
+
+ package-a
+ 23.42
+ some package A
+ false
+
+
+ package-b
+ 23.42
+ some package B
+ false
+
+
+ package-c
+ 23.42
+ some package C
+ false
+
+
+
diff --git a/tests/_data/snapshots/environment/plain_with-license-text_1.1.xml.bin b/tests/_data/snapshots/environment/plain_with-license-text_1.1.xml.bin
new file mode 100644
index 00000000..b57c90f3
--- /dev/null
+++ b/tests/_data/snapshots/environment/plain_with-license-text_1.1.xml.bin
@@ -0,0 +1,52 @@
+
+
+
+
+ package-a
+ 23.42
+ some package A
+
+
+ declared license of 'package-a'
+ some license text
+
+
+
+
+ file://.../tests/_data/infiles/_helpers/local_pckages/a/dist/package_a-23.42-py3-none-any.whl
+ PackageSource: Archive
+
+
+
+
+ package-b
+ 23.42
+ some package B
+
+
+ Apache-2.0
+
+
+
+
+ file://.../tests/_data/infiles/_helpers/local_pckages/b/dist/package_b-23.42-py3-none-any.whl
+ PackageSource: Archive
+
+
+
+
+ package-c
+ 23.42
+ some package C
+
+ Apache-2.0 OR MIT
+
+
+
+ file://.../tests/_data/infiles/_helpers/local_pckages/c/dist/package_c-23.42-py3-none-any.whl
+ PackageSource: Archive
+
+
+
+
+
diff --git a/tests/_data/snapshots/environment/plain_with-license-text_1.2.json.bin b/tests/_data/snapshots/environment/plain_with-license-text_1.2.json.bin
new file mode 100644
index 00000000..a07cf4c4
--- /dev/null
+++ b/tests/_data/snapshots/environment/plain_with-license-text_1.2.json.bin
@@ -0,0 +1,119 @@
+{
+ "components": [
+ {
+ "bom-ref": "package-a==23.42",
+ "description": "some package A",
+ "externalReferences": [
+ {
+ "comment": "PackageSource: Archive",
+ "type": "distribution",
+ "url": "file://.../tests/_data/infiles/_helpers/local_pckages/a/dist/package_a-23.42-py3-none-any.whl"
+ }
+ ],
+ "licenses": [
+ {
+ "license": {
+ "name": "declared license of 'package-a'",
+ "text": {
+ "content": "some license text",
+ "contentType": "text/plain"
+ }
+ }
+ }
+ ],
+ "name": "package-a",
+ "type": "library",
+ "version": "23.42"
+ },
+ {
+ "bom-ref": "package-b==23.42",
+ "description": "some package B",
+ "externalReferences": [
+ {
+ "comment": "PackageSource: Archive",
+ "type": "distribution",
+ "url": "file://.../tests/_data/infiles/_helpers/local_pckages/b/dist/package_b-23.42-py3-none-any.whl"
+ }
+ ],
+ "licenses": [
+ {
+ "license": {
+ "id": "Apache-2.0"
+ }
+ }
+ ],
+ "name": "package-b",
+ "type": "library",
+ "version": "23.42"
+ },
+ {
+ "bom-ref": "package-c==23.42",
+ "description": "some package C",
+ "externalReferences": [
+ {
+ "comment": "PackageSource: Archive",
+ "type": "distribution",
+ "url": "file://.../tests/_data/infiles/_helpers/local_pckages/c/dist/package_c-23.42-py3-none-any.whl"
+ }
+ ],
+ "licenses": [
+ {
+ "expression": "Apache-2.0 OR MIT"
+ }
+ ],
+ "name": "package-c",
+ "type": "library",
+ "version": "23.42"
+ }
+ ],
+ "dependencies": [
+ {
+ "ref": "package-a==23.42"
+ },
+ {
+ "ref": "package-b==23.42"
+ },
+ {
+ "ref": "package-c==23.42"
+ },
+ {
+ "ref": "root-component"
+ }
+ ],
+ "metadata": {
+ "component": {
+ "bom-ref": "root-component",
+ "description": "with licenses as text, instead of SPDX ID/Expression",
+ "licenses": [
+ {
+ "license": {
+ "name": "declared license of 'with-license-text'",
+ "text": {
+ "content": "This is the license text of this component.\nIt is expected to be available in a SBOM.",
+ "contentType": "text/plain"
+ }
+ }
+ }
+ ],
+ "name": "with-license-text",
+ "type": "application",
+ "version": "0.1.0"
+ },
+ "tools": [
+ {
+ "name": "cyclonedx-bom",
+ "vendor": "CycloneDX",
+ "version": "thisVersion-testing"
+ },
+ {
+ "name": "cyclonedx-python-lib",
+ "vendor": "CycloneDX",
+ "version": "libVersion-testing"
+ }
+ ]
+ },
+ "version": 1,
+ "$schema": "http://cyclonedx.org/schema/bom-1.2b.schema.json",
+ "bomFormat": "CycloneDX",
+ "specVersion": "1.2"
+}
\ No newline at end of file
diff --git a/tests/_data/snapshots/environment/plain_with-license-text_1.2.xml.bin b/tests/_data/snapshots/environment/plain_with-license-text_1.2.xml.bin
new file mode 100644
index 00000000..d924cabd
--- /dev/null
+++ b/tests/_data/snapshots/environment/plain_with-license-text_1.2.xml.bin
@@ -0,0 +1,84 @@
+
+
+
+
+
+ CycloneDX
+ cyclonedx-bom
+ thisVersion-testing
+
+
+ CycloneDX
+ cyclonedx-python-lib
+ libVersion-testing
+
+
+
+ with-license-text
+ 0.1.0
+ with licenses as text, instead of SPDX ID/Expression
+
+
+ declared license of 'with-license-text'
+ This is the license text of this component.
+It is expected to be available in a SBOM.
+
+
+
+
+
+
+ package-a
+ 23.42
+ some package A
+
+
+ declared license of 'package-a'
+ some license text
+
+
+
+
+ file://.../tests/_data/infiles/_helpers/local_pckages/a/dist/package_a-23.42-py3-none-any.whl
+ PackageSource: Archive
+
+
+
+
+ package-b
+ 23.42
+ some package B
+
+
+ Apache-2.0
+
+
+
+
+ file://.../tests/_data/infiles/_helpers/local_pckages/b/dist/package_b-23.42-py3-none-any.whl
+ PackageSource: Archive
+
+
+
+
+ package-c
+ 23.42
+ some package C
+
+ Apache-2.0 OR MIT
+
+
+
+ file://.../tests/_data/infiles/_helpers/local_pckages/c/dist/package_c-23.42-py3-none-any.whl
+ PackageSource: Archive
+
+
+
+
+
+
+
+
+
+
+
diff --git a/tests/_data/snapshots/environment/plain_with-license-text_1.3.json.bin b/tests/_data/snapshots/environment/plain_with-license-text_1.3.json.bin
new file mode 100644
index 00000000..5fc0ff8c
--- /dev/null
+++ b/tests/_data/snapshots/environment/plain_with-license-text_1.3.json.bin
@@ -0,0 +1,143 @@
+{
+ "components": [
+ {
+ "bom-ref": "package-a==23.42",
+ "description": "some package A",
+ "externalReferences": [
+ {
+ "comment": "PackageSource: Archive",
+ "hashes": [
+ {
+ "alg": "SHA-256",
+ "content": "5c8da28603857d4073c67e751ba3cd526a7ef414135faecfec164e7d01be24be"
+ }
+ ],
+ "type": "distribution",
+ "url": "file://.../tests/_data/infiles/_helpers/local_pckages/a/dist/package_a-23.42-py3-none-any.whl"
+ }
+ ],
+ "licenses": [
+ {
+ "license": {
+ "name": "declared license of 'package-a'",
+ "text": {
+ "content": "some license text",
+ "contentType": "text/plain"
+ }
+ }
+ }
+ ],
+ "name": "package-a",
+ "type": "library",
+ "version": "23.42"
+ },
+ {
+ "bom-ref": "package-b==23.42",
+ "description": "some package B",
+ "externalReferences": [
+ {
+ "comment": "PackageSource: Archive",
+ "hashes": [
+ {
+ "alg": "SHA-256",
+ "content": "583f7cb9db5c26194e8004ac82a90d7b46664da8da674919d3e2189c332a1f78"
+ }
+ ],
+ "type": "distribution",
+ "url": "file://.../tests/_data/infiles/_helpers/local_pckages/b/dist/package_b-23.42-py3-none-any.whl"
+ }
+ ],
+ "licenses": [
+ {
+ "license": {
+ "id": "Apache-2.0"
+ }
+ }
+ ],
+ "name": "package-b",
+ "type": "library",
+ "version": "23.42"
+ },
+ {
+ "bom-ref": "package-c==23.42",
+ "description": "some package C",
+ "externalReferences": [
+ {
+ "comment": "PackageSource: Archive",
+ "hashes": [
+ {
+ "alg": "SHA-256",
+ "content": "c1ac59f18ed20f2e651a37f74134ade2a396e27513ef1c73461873c49058f641"
+ }
+ ],
+ "type": "distribution",
+ "url": "file://.../tests/_data/infiles/_helpers/local_pckages/c/dist/package_c-23.42-py3-none-any.whl"
+ }
+ ],
+ "licenses": [
+ {
+ "expression": "Apache-2.0 OR MIT"
+ }
+ ],
+ "name": "package-c",
+ "type": "library",
+ "version": "23.42"
+ }
+ ],
+ "dependencies": [
+ {
+ "ref": "package-a==23.42"
+ },
+ {
+ "ref": "package-b==23.42"
+ },
+ {
+ "ref": "package-c==23.42"
+ },
+ {
+ "ref": "root-component"
+ }
+ ],
+ "metadata": {
+ "component": {
+ "bom-ref": "root-component",
+ "description": "with licenses as text, instead of SPDX ID/Expression",
+ "licenses": [
+ {
+ "license": {
+ "name": "declared license of 'with-license-text'",
+ "text": {
+ "content": "This is the license text of this component.\nIt is expected to be available in a SBOM.",
+ "contentType": "text/plain"
+ }
+ }
+ }
+ ],
+ "name": "with-license-text",
+ "type": "application",
+ "version": "0.1.0"
+ },
+ "properties": [
+ {
+ "name": "cdx:reproducible",
+ "value": "true"
+ }
+ ],
+ "tools": [
+ {
+ "name": "cyclonedx-bom",
+ "vendor": "CycloneDX",
+ "version": "thisVersion-testing"
+ },
+ {
+ "name": "cyclonedx-python-lib",
+ "vendor": "CycloneDX",
+ "version": "libVersion-testing"
+ }
+ ]
+ },
+ "version": 1,
+ "$schema": "http://cyclonedx.org/schema/bom-1.3a.schema.json",
+ "bomFormat": "CycloneDX",
+ "specVersion": "1.3"
+}
\ No newline at end of file
diff --git a/tests/_data/snapshots/environment/plain_with-license-text_1.3.xml.bin b/tests/_data/snapshots/environment/plain_with-license-text_1.3.xml.bin
new file mode 100644
index 00000000..9929fff1
--- /dev/null
+++ b/tests/_data/snapshots/environment/plain_with-license-text_1.3.xml.bin
@@ -0,0 +1,96 @@
+
+
+
+
+
+ CycloneDX
+ cyclonedx-bom
+ thisVersion-testing
+
+
+ CycloneDX
+ cyclonedx-python-lib
+ libVersion-testing
+
+
+
+ with-license-text
+ 0.1.0
+ with licenses as text, instead of SPDX ID/Expression
+
+
+ declared license of 'with-license-text'
+ This is the license text of this component.
+It is expected to be available in a SBOM.
+
+
+
+
+ true
+
+
+
+
+ package-a
+ 23.42
+ some package A
+
+
+ declared license of 'package-a'
+ some license text
+
+
+
+
+ file://.../tests/_data/infiles/_helpers/local_pckages/a/dist/package_a-23.42-py3-none-any.whl
+ PackageSource: Archive
+
+ 5c8da28603857d4073c67e751ba3cd526a7ef414135faecfec164e7d01be24be
+
+
+
+
+
+ package-b
+ 23.42
+ some package B
+
+
+ Apache-2.0
+
+
+
+
+ file://.../tests/_data/infiles/_helpers/local_pckages/b/dist/package_b-23.42-py3-none-any.whl
+ PackageSource: Archive
+
+ 583f7cb9db5c26194e8004ac82a90d7b46664da8da674919d3e2189c332a1f78
+
+
+
+
+
+ package-c
+ 23.42
+ some package C
+
+ Apache-2.0 OR MIT
+
+
+
+ file://.../tests/_data/infiles/_helpers/local_pckages/c/dist/package_c-23.42-py3-none-any.whl
+ PackageSource: Archive
+
+ c1ac59f18ed20f2e651a37f74134ade2a396e27513ef1c73461873c49058f641
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/tests/_data/snapshots/environment/plain_with-license-text_1.4.json.bin b/tests/_data/snapshots/environment/plain_with-license-text_1.4.json.bin
new file mode 100644
index 00000000..e41eff71
--- /dev/null
+++ b/tests/_data/snapshots/environment/plain_with-license-text_1.4.json.bin
@@ -0,0 +1,139 @@
+{
+ "components": [
+ {
+ "bom-ref": "package-a==23.42",
+ "description": "some package A",
+ "externalReferences": [
+ {
+ "comment": "PackageSource: Archive",
+ "hashes": [
+ {
+ "alg": "SHA-256",
+ "content": "5c8da28603857d4073c67e751ba3cd526a7ef414135faecfec164e7d01be24be"
+ }
+ ],
+ "type": "distribution",
+ "url": "file://.../tests/_data/infiles/_helpers/local_pckages/a/dist/package_a-23.42-py3-none-any.whl"
+ }
+ ],
+ "licenses": [
+ {
+ "license": {
+ "name": "declared license of 'package-a'",
+ "text": {
+ "content": "some license text",
+ "contentType": "text/plain"
+ }
+ }
+ }
+ ],
+ "name": "package-a",
+ "type": "library",
+ "version": "23.42"
+ },
+ {
+ "bom-ref": "package-b==23.42",
+ "description": "some package B",
+ "externalReferences": [
+ {
+ "comment": "PackageSource: Archive",
+ "hashes": [
+ {
+ "alg": "SHA-256",
+ "content": "583f7cb9db5c26194e8004ac82a90d7b46664da8da674919d3e2189c332a1f78"
+ }
+ ],
+ "type": "distribution",
+ "url": "file://.../tests/_data/infiles/_helpers/local_pckages/b/dist/package_b-23.42-py3-none-any.whl"
+ }
+ ],
+ "licenses": [
+ {
+ "license": {
+ "id": "Apache-2.0"
+ }
+ }
+ ],
+ "name": "package-b",
+ "type": "library",
+ "version": "23.42"
+ },
+ {
+ "bom-ref": "package-c==23.42",
+ "description": "some package C",
+ "externalReferences": [
+ {
+ "comment": "PackageSource: Archive",
+ "hashes": [
+ {
+ "alg": "SHA-256",
+ "content": "c1ac59f18ed20f2e651a37f74134ade2a396e27513ef1c73461873c49058f641"
+ }
+ ],
+ "type": "distribution",
+ "url": "file://.../tests/_data/infiles/_helpers/local_pckages/c/dist/package_c-23.42-py3-none-any.whl"
+ }
+ ],
+ "licenses": [
+ {
+ "expression": "Apache-2.0 OR MIT"
+ }
+ ],
+ "name": "package-c",
+ "type": "library",
+ "version": "23.42"
+ }
+ ],
+ "dependencies": [
+ {
+ "ref": "package-a==23.42"
+ },
+ {
+ "ref": "package-b==23.42"
+ },
+ {
+ "ref": "package-c==23.42"
+ },
+ {
+ "ref": "root-component"
+ }
+ ],
+ "metadata": {
+ "component": {
+ "bom-ref": "root-component",
+ "description": "with licenses as text, instead of SPDX ID/Expression",
+ "licenses": [
+ {
+ "license": {
+ "name": "declared license of 'with-license-text'",
+ "text": {
+ "content": "This is the license text of this component.\nIt is expected to be available in a SBOM.",
+ "contentType": "text/plain"
+ }
+ }
+ }
+ ],
+ "name": "with-license-text",
+ "type": "application",
+ "version": "0.1.0"
+ },
+ "properties": [
+ {
+ "name": "cdx:reproducible",
+ "value": "true"
+ }
+ ],
+ "tools": [
+ {
+ "externalReferences": [ ],
+ "name": "cyclonedx-python-lib",
+ "vendor": "CycloneDX",
+ "version": "libVersion-testing"
+ }
+ ]
+ },
+ "version": 1,
+ "$schema": "http://cyclonedx.org/schema/bom-1.4.schema.json",
+ "bomFormat": "CycloneDX",
+ "specVersion": "1.4"
+}
\ No newline at end of file
diff --git a/tests/_data/snapshots/environment/plain_with-license-text_1.4.xml.bin b/tests/_data/snapshots/environment/plain_with-license-text_1.4.xml.bin
new file mode 100644
index 00000000..f4b58571
--- /dev/null
+++ b/tests/_data/snapshots/environment/plain_with-license-text_1.4.xml.bin
@@ -0,0 +1,123 @@
+
+
+
+
+
+ CycloneDX
+ cyclonedx-bom
+ thisVersion-testing
+
+
+ https://github.com/CycloneDX/cyclonedx-python/actions
+
+
+ https://pypi.org/project/cyclonedx-bom/
+
+
+ https://cyclonedx-bom-tool.readthedocs.io/
+
+
+ https://github.com/CycloneDX/cyclonedx-python/issues
+
+
+ https://github.com/CycloneDX/cyclonedx-python/blob/main/LICENSE
+
+
+ https://github.com/CycloneDX/cyclonedx-python/blob/main/CHANGELOG.md
+
+
+ https://github.com/CycloneDX/cyclonedx-python/
+
+
+ https://github.com/CycloneDX/cyclonedx-python/#readme
+
+
+
+
+ CycloneDX
+ cyclonedx-python-lib
+ libVersion-testing
+
+
+
+
+ with-license-text
+ 0.1.0
+ with licenses as text, instead of SPDX ID/Expression
+
+
+ declared license of 'with-license-text'
+ This is the license text of this component.
+It is expected to be available in a SBOM.
+
+
+
+
+ true
+
+
+
+
+ package-a
+ 23.42
+ some package A
+
+
+ declared license of 'package-a'
+ some license text
+
+
+
+
+ file://.../tests/_data/infiles/_helpers/local_pckages/a/dist/package_a-23.42-py3-none-any.whl
+ PackageSource: Archive
+
+ 5c8da28603857d4073c67e751ba3cd526a7ef414135faecfec164e7d01be24be
+
+
+
+
+
+ package-b
+ 23.42
+ some package B
+
+
+ Apache-2.0
+
+
+
+
+ file://.../tests/_data/infiles/_helpers/local_pckages/b/dist/package_b-23.42-py3-none-any.whl
+ PackageSource: Archive
+
+ 583f7cb9db5c26194e8004ac82a90d7b46664da8da674919d3e2189c332a1f78
+
+
+
+
+
+ package-c
+ 23.42
+ some package C
+
+ Apache-2.0 OR MIT
+
+
+
+ file://.../tests/_data/infiles/_helpers/local_pckages/c/dist/package_c-23.42-py3-none-any.whl
+ PackageSource: Archive
+
+ c1ac59f18ed20f2e651a37f74134ade2a396e27513ef1c73461873c49058f641
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/tests/_data/snapshots/environment/plain_with-license-text_1.5.json.bin b/tests/_data/snapshots/environment/plain_with-license-text_1.5.json.bin
new file mode 100644
index 00000000..1215ff89
--- /dev/null
+++ b/tests/_data/snapshots/environment/plain_with-license-text_1.5.json.bin
@@ -0,0 +1,139 @@
+{
+ "components": [
+ {
+ "bom-ref": "package-a==23.42",
+ "description": "some package A",
+ "externalReferences": [
+ {
+ "comment": "PackageSource: Archive",
+ "hashes": [
+ {
+ "alg": "SHA-256",
+ "content": "5c8da28603857d4073c67e751ba3cd526a7ef414135faecfec164e7d01be24be"
+ }
+ ],
+ "type": "distribution",
+ "url": "file://.../tests/_data/infiles/_helpers/local_pckages/a/dist/package_a-23.42-py3-none-any.whl"
+ }
+ ],
+ "licenses": [
+ {
+ "license": {
+ "name": "declared license of 'package-a'",
+ "text": {
+ "content": "some license text",
+ "contentType": "text/plain"
+ }
+ }
+ }
+ ],
+ "name": "package-a",
+ "type": "library",
+ "version": "23.42"
+ },
+ {
+ "bom-ref": "package-b==23.42",
+ "description": "some package B",
+ "externalReferences": [
+ {
+ "comment": "PackageSource: Archive",
+ "hashes": [
+ {
+ "alg": "SHA-256",
+ "content": "583f7cb9db5c26194e8004ac82a90d7b46664da8da674919d3e2189c332a1f78"
+ }
+ ],
+ "type": "distribution",
+ "url": "file://.../tests/_data/infiles/_helpers/local_pckages/b/dist/package_b-23.42-py3-none-any.whl"
+ }
+ ],
+ "licenses": [
+ {
+ "license": {
+ "id": "Apache-2.0"
+ }
+ }
+ ],
+ "name": "package-b",
+ "type": "library",
+ "version": "23.42"
+ },
+ {
+ "bom-ref": "package-c==23.42",
+ "description": "some package C",
+ "externalReferences": [
+ {
+ "comment": "PackageSource: Archive",
+ "hashes": [
+ {
+ "alg": "SHA-256",
+ "content": "c1ac59f18ed20f2e651a37f74134ade2a396e27513ef1c73461873c49058f641"
+ }
+ ],
+ "type": "distribution",
+ "url": "file://.../tests/_data/infiles/_helpers/local_pckages/c/dist/package_c-23.42-py3-none-any.whl"
+ }
+ ],
+ "licenses": [
+ {
+ "expression": "Apache-2.0 OR MIT"
+ }
+ ],
+ "name": "package-c",
+ "type": "library",
+ "version": "23.42"
+ }
+ ],
+ "dependencies": [
+ {
+ "ref": "package-a==23.42"
+ },
+ {
+ "ref": "package-b==23.42"
+ },
+ {
+ "ref": "package-c==23.42"
+ },
+ {
+ "ref": "root-component"
+ }
+ ],
+ "metadata": {
+ "component": {
+ "bom-ref": "root-component",
+ "description": "with licenses as text, instead of SPDX ID/Expression",
+ "licenses": [
+ {
+ "license": {
+ "name": "declared license of 'with-license-text'",
+ "text": {
+ "content": "This is the license text of this component.\nIt is expected to be available in a SBOM.",
+ "contentType": "text/plain"
+ }
+ }
+ }
+ ],
+ "name": "with-license-text",
+ "type": "application",
+ "version": "0.1.0"
+ },
+ "properties": [
+ {
+ "name": "cdx:reproducible",
+ "value": "true"
+ }
+ ],
+ "tools": [
+ {
+ "externalReferences": [ ],
+ "name": "cyclonedx-python-lib",
+ "vendor": "CycloneDX",
+ "version": "libVersion-testing"
+ }
+ ]
+ },
+ "version": 1,
+ "$schema": "http://cyclonedx.org/schema/bom-1.5.schema.json",
+ "bomFormat": "CycloneDX",
+ "specVersion": "1.5"
+}
\ No newline at end of file
diff --git a/tests/_data/snapshots/environment/plain_with-license-text_1.5.xml.bin b/tests/_data/snapshots/environment/plain_with-license-text_1.5.xml.bin
new file mode 100644
index 00000000..71e31ea7
--- /dev/null
+++ b/tests/_data/snapshots/environment/plain_with-license-text_1.5.xml.bin
@@ -0,0 +1,123 @@
+
+
+
+
+
+ CycloneDX
+ cyclonedx-bom
+ thisVersion-testing
+
+
+ https://github.com/CycloneDX/cyclonedx-python/actions
+
+
+ https://pypi.org/project/cyclonedx-bom/
+
+
+ https://cyclonedx-bom-tool.readthedocs.io/
+
+
+ https://github.com/CycloneDX/cyclonedx-python/issues
+
+
+ https://github.com/CycloneDX/cyclonedx-python/blob/main/LICENSE
+
+
+ https://github.com/CycloneDX/cyclonedx-python/blob/main/CHANGELOG.md
+
+
+ https://github.com/CycloneDX/cyclonedx-python/
+
+
+ https://github.com/CycloneDX/cyclonedx-python/#readme
+
+
+
+
+ CycloneDX
+ cyclonedx-python-lib
+ libVersion-testing
+
+
+
+
+ with-license-text
+ 0.1.0
+ with licenses as text, instead of SPDX ID/Expression
+
+
+ declared license of 'with-license-text'
+ This is the license text of this component.
+It is expected to be available in a SBOM.
+
+
+
+
+ true
+
+
+
+
+ package-a
+ 23.42
+ some package A
+
+
+ declared license of 'package-a'
+ some license text
+
+
+
+
+ file://.../tests/_data/infiles/_helpers/local_pckages/a/dist/package_a-23.42-py3-none-any.whl
+ PackageSource: Archive
+
+ 5c8da28603857d4073c67e751ba3cd526a7ef414135faecfec164e7d01be24be
+
+
+
+
+
+ package-b
+ 23.42
+ some package B
+
+
+ Apache-2.0
+
+
+
+
+ file://.../tests/_data/infiles/_helpers/local_pckages/b/dist/package_b-23.42-py3-none-any.whl
+ PackageSource: Archive
+
+ 583f7cb9db5c26194e8004ac82a90d7b46664da8da674919d3e2189c332a1f78
+
+
+
+
+
+ package-c
+ 23.42
+ some package C
+
+ Apache-2.0 OR MIT
+
+
+
+ file://.../tests/_data/infiles/_helpers/local_pckages/c/dist/package_c-23.42-py3-none-any.whl
+ PackageSource: Archive
+
+ c1ac59f18ed20f2e651a37f74134ade2a396e27513ef1c73461873c49058f641
+
+
+
+
+
+
+
+
+
+
+
+