Skip to content

Commit 3cb14e0

Browse files
authored
Merge pull request #311 from CycloneDX/feat/update-lib-2.0.x
BREAKING CHANGE: update to latest RC of `cyclonedx-python-lib`
2 parents 8379712 + e193521 commit 3cb14e0

17 files changed

+111
-70
lines changed

README.md

+3-3
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,7 @@ Once installed, you can access the full documentation by running `--help`:
4444
```text
4545
$ cyclonedx-bom --help
4646
usage: cyclonedx-bom [-h] (-c | -cj | -e | -p | -pip | -r) [-i FILE_PATH]
47-
[--format {json,xml}] [--schema-version {1.3,1.2,1.1,1.0}]
47+
[--format {json,xml}] [--schema-version {1.4,1.3,1.2,1.1,1.0}]
4848
[-o FILE_PATH] [-F] [-X]
4949
5050
CycloneDX SBOM Generator
@@ -83,9 +83,9 @@ SBOM Output Configuration:
8383
Choose the output format and schema version
8484
8585
--format {json,xml} The output format for your SBOM (default: xml)
86-
--schema-version {1.3,1.2,1.1,1.0}
86+
--schema-version {1.4,1.3,1.2,1.1,1.0}
8787
The CycloneDX schema version for your SBOM (default:
88-
1.3)
88+
1.4)
8989
-o FILE_PATH, --o FILE_PATH, --output FILE_PATH
9090
Output file path for your SBOM (set to '-' to output
9191
to STDOUT)

cyclonedx_py/__init__.py

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

cyclonedx_py/client.py

+2-2
Original file line numberDiff line numberDiff line change
@@ -89,7 +89,7 @@ def get_output(self) -> BaseOutput:
8989
from importlib.metadata import version as md_version
9090
else:
9191
from importlib_metadata import version as md_version # type: ignore
92-
bom.metadata.add_tool(tool=Tool(
92+
bom.metadata.tools.add(Tool(
9393
vendor='CycloneDX', name='cyclonedx-bom', version=md_version('cyclonedx-bom')
9494
))
9595

@@ -181,7 +181,7 @@ def get_arg_parser() -> argparse.ArgumentParser:
181181
dest='output_format'
182182
)
183183
output_group.add_argument(
184-
'--schema-version', action='store', choices=['1.4', '1.3', '1.2', '1.1', '1.0'], default='1.3',
184+
'--schema-version', action='store', choices=['1.4', '1.3', '1.2', '1.1', '1.0'], default='1.4',
185185
help='The CycloneDX schema version for your SBOM (default: %(default)s)',
186186
dest='output_schema_version'
187187
)

cyclonedx_py/parser/__init__.py

+1
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@
1313
# limitations under the License.
1414
#
1515
# SPDX-License-Identifier: Apache-2.0
16+
# Copyright (c) OWASP Foundation. All Rights Reserved.
1617

1718
"""
1819
Set of concrete classes and methods which allow for quick creation of a Bom instance from your environment or Python

cyclonedx_py/parser/conda.py

+3-3
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@
2121
from abc import ABCMeta, abstractmethod
2222
from typing import List
2323

24-
from cyclonedx.model import ExternalReference, ExternalReferenceType
24+
from cyclonedx.model import ExternalReference, ExternalReferenceType, XsUri
2525
from cyclonedx.model.component import Component
2626
from cyclonedx.parser import BaseParser
2727
# See https://github.com/package-url/packageurl-python/issues/65
@@ -65,9 +65,9 @@ def _conda_packages_to_components(self) -> None:
6565
type='pypi', name=conda_package['name'], version=str(conda_package['version'])
6666
)
6767
)
68-
c.add_external_reference(ExternalReference(
68+
c.external_references.add(ExternalReference(
6969
reference_type=ExternalReferenceType.DISTRIBUTION,
70-
url=conda_package['base_url'],
70+
url=XsUri(conda_package['base_url']),
7171
comment=f"Distribution name {conda_package['dist_name']}"
7272
))
7373

cyclonedx_py/parser/environment.py

+2-4
Original file line numberDiff line numberDiff line change
@@ -68,14 +68,12 @@ def __init__(self) -> None:
6868
c.author = i_metadata['Author']
6969

7070
if 'License' in i_metadata and i_metadata['License'] != 'UNKNOWN':
71-
c.licenses.append(
72-
LicenseChoice(license_expression=i_metadata['License'])
73-
)
71+
c.licenses.add(LicenseChoice(license_expression=i_metadata['License']))
7472

7573
if 'Classifier' in i_metadata:
7674
for classifier in i_metadata['Classifier']:
7775
if str(classifier).startswith('License :: OSI Approved :: '):
78-
c.licenses.append(
76+
c.licenses.add(
7977
LicenseChoice(
8078
license_expression=str(classifier).replace('License :: OSI Approved :: ', '').strip()
8179
)

cyclonedx_py/parser/pipenv.py

+4-4
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@
2020
import json
2121
from typing import Any, Dict
2222

23-
from cyclonedx.model import ExternalReference, ExternalReferenceType, HashType
23+
from cyclonedx.model import ExternalReference, ExternalReferenceType, HashType, XsUri
2424
from cyclonedx.model.component import Component
2525
from cyclonedx.parser import BaseParser
2626
# See https://github.com/package-url/packageurl-python/issues/65
@@ -48,11 +48,11 @@ def __init__(self, pipenv_contents: str) -> None:
4848
for pip_hash in package_data['hashes']:
4949
ext_ref = ExternalReference(
5050
reference_type=ExternalReferenceType.DISTRIBUTION,
51-
url=c.get_pypi_url(),
51+
url=XsUri(c.get_pypi_url()),
5252
comment='Distribution available from pypi.org'
5353
)
54-
ext_ref.add_hash(HashType.from_composite_str(pip_hash))
55-
c.add_external_reference(ext_ref)
54+
ext_ref.hashes.add(HashType.from_composite_str(pip_hash))
55+
c.external_references.add(ext_ref)
5656

5757
self._components.append(c)
5858

cyclonedx_py/parser/poetry.py

+3-3
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@
1818
# Copyright (c) OWASP Foundation. All Rights Reserved.
1919

2020
from cyclonedx.exception.model import UnknownHashTypeException
21-
from cyclonedx.model import ExternalReference, ExternalReferenceType, HashType
21+
from cyclonedx.model import ExternalReference, ExternalReferenceType, HashType, XsUri
2222
from cyclonedx.model.component import Component
2323
from cyclonedx.parser import BaseParser
2424
# See https://github.com/package-url/packageurl-python/issues/65
@@ -41,9 +41,9 @@ def __init__(self, poetry_lock_contents: str) -> None:
4141

4242
for file_metadata in poetry_lock['metadata']['files'][package['name']]:
4343
try:
44-
component.add_external_reference(ExternalReference(
44+
component.external_references.add(ExternalReference(
4545
reference_type=ExternalReferenceType.DISTRIBUTION,
46-
url=component.get_pypi_url(),
46+
url=XsUri(component.get_pypi_url()),
4747
comment=f'Distribution file: {file_metadata["file"]}',
4848
hashes=[HashType.from_composite_str(file_metadata['hash'])]
4949
))

cyclonedx_py/py.typed

+2
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
# Marker file for PEP 561. This package uses inline types.
2+
# This file is needed to allow other packages to type-check their code against this package.

cyclonedx_py/utils/__init__.py

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

poetry.lock

+17-17
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

pyproject.toml

+12-2
Original file line numberDiff line numberDiff line change
@@ -16,16 +16,26 @@ include = [
1616
classifiers = [
1717
# Trove classifiers - https://packaging.python.org/specifications/core-metadata/#metadata-classifier
1818
# Full list: https://pypi.python.org/pypi?%3Aaction=list_classifiers
19+
'Development Status :: 5 - Production/Stable',
20+
'Intended Audience :: Developers',
21+
'Intended Audience :: Information Technology',
22+
'Intended Audience :: Legal Industry',
23+
'Intended Audience :: System Administrators',
24+
'Topic :: Security',
25+
'Topic :: Software Development',
26+
'Topic :: System :: Software Distribution',
27+
'License :: OSI Approved :: Apache Software License',
1928
'Programming Language :: Python :: 3.6',
2029
'Programming Language :: Python :: 3.7',
2130
'Programming Language :: Python :: 3.8',
2231
'Programming Language :: Python :: 3.9',
23-
'Programming Language :: Python :: 3.10'
32+
'Programming Language :: Python :: 3.10',
33+
'Typing :: Typed'
2434
]
2535

2636
[tool.poetry.dependencies]
2737
python = "^3.6"
28-
cyclonedx-python-lib = "^1.3.0"
38+
cyclonedx-python-lib = ">= 2.0.0rc4, < 3.0.0"
2939

3040
[tool.poetry.dev-dependencies]
3141
autopep8 = "^1.6.0"

tests/test_parser_conda.py

+6-9
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,6 @@
1616
#
1717
# SPDX-License-Identifier: Apache-2.0
1818
# Copyright (c) OWASP Foundation. All Rights Reserved.
19-
2019
import os
2120
from unittest import TestCase
2221

@@ -33,13 +32,12 @@ def test_conda_list_json(self) -> None:
3332
conda_list_ouptut_fh.close()
3433

3534
self.assertEqual(34, parser.component_count())
36-
components = parser.get_components()
37-
38-
c_noarch = [x for x in components if x.name == 'idna'][0]
35+
c_noarch = next(filter(lambda c: c.name == 'idna', parser.get_components()), parser.get_components)
36+
self.assertIsNotNone(c_noarch)
3937
self.assertEqual('idna', c_noarch.name)
4038
self.assertEqual('2.10', c_noarch.version)
4139
self.assertEqual(1, len(c_noarch.external_references))
42-
self.assertEqual(0, len(c_noarch.external_references[0].get_hashes()))
40+
self.assertEqual(0, len(c_noarch.external_references.pop().hashes))
4341

4442
def test_conda_list_explicit_md5(self) -> None:
4543
conda_list_ouptut_file = os.path.join(os.path.dirname(__file__), 'fixtures/conda-list-explicit-md5.txt')
@@ -49,10 +47,9 @@ def test_conda_list_explicit_md5(self) -> None:
4947
conda_list_ouptut_fh.close()
5048

5149
self.assertEqual(34, parser.component_count())
52-
components = parser.get_components()
53-
54-
c_noarch = [x for x in components if x.name == 'idna'][0]
50+
c_noarch = next(filter(lambda c: c.name == 'idna', parser.get_components()), parser.get_components)
51+
self.assertIsNotNone(c_noarch)
5552
self.assertEqual('idna', c_noarch.name)
5653
self.assertEqual('2.10', c_noarch.version)
5754
self.assertEqual(1, len(c_noarch.external_references))
58-
self.assertEqual(0, len(c_noarch.external_references[0].get_hashes()))
55+
self.assertEqual(0, len(c_noarch.external_references.pop().hashes))

tests/test_parser_environment.py

+3-5
Original file line numberDiff line numberDiff line change
@@ -16,11 +16,8 @@
1616
#
1717
# SPDX-License-Identifier: Apache-2.0
1818
# Copyright (c) OWASP Foundation. All Rights Reserved.
19-
2019
from unittest import TestCase
2120

22-
from cyclonedx.model.component import Component
23-
2421
from cyclonedx_py.parser.environment import EnvironmentParser
2522

2623

@@ -37,6 +34,7 @@ def test_simple(self) -> None:
3734
self.assertGreater(parser.component_count(), 1)
3835

3936
# We can only be sure that tox is in the environment, for example as we use tox to run tests
40-
c_tox: Component = [x for x in parser.get_components() if x.name == 'tox'][0]
37+
c_tox = next(filter(lambda c: c.name == 'tox', parser.get_components()), parser.get_components)
38+
self.assertIsNotNone(c_tox)
4139
self.assertIsNotNone(c_tox.licenses)
42-
self.assertEqual('MIT', c_tox.licenses[0].expression)
40+
self.assertEqual('MIT', c_tox.licenses.pop().expression)

0 commit comments

Comments
 (0)