|
27 | 27 | from textwrap import dedent |
28 | 28 | from typing import TYPE_CHECKING, Any, Optional |
29 | 29 |
|
| 30 | +from cyclonedx.factory.license import LicenseFactory |
30 | 31 | from cyclonedx.model import Property |
31 | | -from cyclonedx.model.component import ( # type:ignore[attr-defined] # ComponentEvidence was moved, but is still importable - ignore/wont-fix for backwards compatibility # noqa:E501 |
32 | | - Component, |
33 | | - ComponentEvidence, |
34 | | - ComponentType, |
35 | | -) |
| 32 | +from cyclonedx.model.component import Component, ComponentType |
36 | 33 | from packageurl import PackageURL |
37 | 34 | from packaging.requirements import Requirement |
38 | 35 |
|
39 | 36 | from . import BomBuilder, PropertyName, PurlTypePypi |
40 | 37 | from .cli_common import add_argument_mc_type, add_argument_pyproject |
41 | | -from .utils.cdx import find_LicenseExpression, licenses_fixup, make_bom |
| 38 | +from .utils.cdx import licenses_fixup, make_bom |
42 | 39 | from .utils.packaging import metadata2extrefs, metadata2licenses, normalize_packagename |
43 | 40 | from .utils.pep610 import PackageSourceArchive, PackageSourceVcs, packagesource2extref, packagesource4dist |
44 | | -from .utils.pep639 import dist2licenses as dist2licenses_pep639 |
| 41 | +from .utils.pep639 import dist2licenses as pep639_dist2licenses |
45 | 42 | from .utils.pyproject import pyproject2component, pyproject2dependencies, pyproject_load |
46 | 43 |
|
47 | 44 | if TYPE_CHECKING: # pragma: no cover |
@@ -114,12 +111,6 @@ def make_argument_parser(**kwargs: Any) -> 'ArgumentParser': |
114 | 111 | • Build an SBOM from uv environment: |
115 | 112 | $ %(prog)s "$(uv python find)" |
116 | 113 | """) |
117 | | - p.add_argument('--PEP-639', |
118 | | - action='store_true', |
119 | | - dest='pep639', |
120 | | - help='Enable license gathering according to PEP 639 ' |
121 | | - '(improving license clarity with better package metadata).\n' |
122 | | - 'The behavior may change during the draft development of the PEP.') |
123 | 114 | p.add_argument('--gather-license-texts', |
124 | 115 | action='store_true', |
125 | 116 | dest='gather_license_texts', |
@@ -156,7 +147,7 @@ def __call__(self, *, # type:ignore[override] |
156 | 147 | rc = None |
157 | 148 | else: |
158 | 149 | pyproject = pyproject_load(pyproject_file) |
159 | | - root_c = pyproject2component(pyproject, ctype=mc_type, fpath=pyproject_file) |
| 150 | + root_c = pyproject2component(pyproject, ctype=mc_type, fpath=pyproject_file, gather_license_texts=False) |
160 | 151 | root_c.bom_ref.value = 'root-component' |
161 | 152 | root_d = tuple(pyproject2dependencies(pyproject)) |
162 | 153 | rc = (root_c, root_d) |
@@ -189,25 +180,20 @@ def __add_components(self, bom: 'Bom', |
189 | 180 | name=dist_name, |
190 | 181 | version=dist_version, |
191 | 182 | description=dist_meta['Summary'] if 'Summary' in dist_meta else None, |
192 | | - licenses=licenses_fixup(metadata2licenses(dist_meta)), |
193 | 183 | external_references=metadata2extrefs(dist_meta), |
194 | 184 | # path of dist-package on disc? naaa... a package may have multiple files/folders on disc |
195 | 185 | ) |
196 | | - if self._pep639: |
197 | | - pep639_licenses = list(dist2licenses_pep639(dist, self._gather_license_texts, self._logger)) |
198 | | - pep639_lexp = find_LicenseExpression(pep639_licenses) |
199 | | - if pep639_lexp is not None: |
200 | | - component.licenses = (pep639_lexp,) |
201 | | - pep639_licenses.remove(pep639_lexp) |
202 | | - if len(pep639_licenses) > 0: |
203 | | - if find_LicenseExpression(component.licenses) is None: |
204 | | - component.licenses.update(pep639_licenses) |
205 | | - else: |
206 | | - # hack for preventing expressions AND named licenses. |
207 | | - # see https://github.com/CycloneDX/cyclonedx-python/issues/826 |
208 | | - # see https://github.com/CycloneDX/specification/issues/454 |
209 | | - component.evidence = ComponentEvidence(licenses=pep639_licenses) |
210 | | - del pep639_lexp, pep639_licenses |
| 186 | + |
| 187 | + # region licenses |
| 188 | + lfac = LicenseFactory() |
| 189 | + component.licenses.update(pep639_dist2licenses(dist, lfac, self._gather_license_texts, self._logger)) |
| 190 | + if len(component.licenses) == 0: |
| 191 | + # According to PEP 639 spec, if licenses are declared in the "new" style, |
| 192 | + # all other license declarations MUST be ignored. |
| 193 | + # https://peps.python.org/pep-0639/#converting-legacy-metadata |
| 194 | + component.licenses.update(metadata2licenses(dist_meta, lfac)) |
| 195 | + licenses_fixup(component) |
| 196 | + # endregion licenses |
211 | 197 |
|
212 | 198 | del dist_meta, dist_name, dist_version |
213 | 199 | self.__component_add_extref_and_purl(component, packagesource4dist(dist)) |
|
0 commit comments