Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
20 changes: 1 addition & 19 deletions cyclonedx/_internal/compare.py
Original file line number Diff line number Diff line change
Expand Up @@ -22,10 +22,7 @@
"""

from itertools import zip_longest
from typing import TYPE_CHECKING, Any, Optional

if TYPE_CHECKING: # pragma: no cover
from packageurl import PackageURL
from typing import Any, Optional


class ComparableTuple(tuple[Optional[Any], ...]):
Expand Down Expand Up @@ -65,18 +62,3 @@ class ComparableDict(ComparableTuple):

def __new__(cls, d: dict[Any, Any]) -> 'ComparableDict':
return super().__new__(cls, sorted(d.items()))


class ComparablePackageURL(ComparableTuple):
"""
Allows comparison of PackageURL, allowing for qualifiers.
"""

def __new__(cls, p: 'PackageURL') -> 'ComparablePackageURL':
return super().__new__(cls, (
p.type,
p.namespace,
p.version,
ComparableDict(p.qualifiers) if isinstance(p.qualifiers, dict) else p.qualifiers,
p.subpath
))
9 changes: 3 additions & 6 deletions cyclonedx/model/bom.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@
from datetime import datetime
from enum import Enum
from itertools import chain
from typing import TYPE_CHECKING, Optional, Union
from typing import Optional, Union
from uuid import UUID, uuid4
from warnings import warn

Expand Down Expand Up @@ -54,9 +54,6 @@
from .tool import Tool, ToolRepository, _ToolRepositoryHelper
from .vulnerability import Vulnerability

if TYPE_CHECKING: # pragma: no cover
from packageurl import PackageURL


@serializable.serializable_enum
class TlpClassification(str, Enum):
Expand Down Expand Up @@ -694,13 +691,13 @@ def definitions(self) -> Optional[Definitions]:
def definitions(self, definitions: Definitions) -> None:
self._definitions = definitions

def get_component_by_purl(self, purl: Optional['PackageURL']) -> Optional[Component]:
def get_component_by_purl(self, purl: Optional[str]) -> Optional[Component]:
"""
Get a Component already in the Bom by its PURL

Args:
purl:
An instance of `packageurl.PackageURL` to look and find `Component`.
A PURL string to look and find `Component`.

Returns:
`Component` or `None`
Expand Down
26 changes: 11 additions & 15 deletions cyclonedx/model/component.py
Original file line number Diff line number Diff line change
Expand Up @@ -27,13 +27,11 @@
else:
from typing_extensions import deprecated

# See https://github.com/package-url/packageurl-python/issues/65
import py_serializable as serializable
from packageurl import PackageURL
from sortedcontainers import SortedSet

from .._internal.bom_ref import bom_ref_from_str as _bom_ref_from_str
from .._internal.compare import ComparablePackageURL as _ComparablePackageURL, ComparableTuple as _ComparableTuple
from .._internal.compare import ComparableTuple as _ComparableTuple
from ..exception.model import InvalidOmniBorIdException, InvalidSwhidException
from ..exception.serialization import (
CycloneDxDeserializationException,
Expand All @@ -51,7 +49,6 @@
SchemaVersion1Dot6,
SchemaVersion1Dot7,
)
from ..serialization import PackageUrl as PackageUrlSH
from . import (
AttachedText,
ExternalReference,
Expand Down Expand Up @@ -974,11 +971,10 @@ def for_file(absolute_file_path: str, path_for_bom: Optional[str]) -> 'Component
component = ComponentBuilder().make_for_file(absolute_file_path, name=path_for_bom)
sha1_hash = next((h.content for h in component.hashes if h.alg is HashAlgorithm.SHA_1), None)
assert sha1_hash is not None
component.version = f'0.0.0-{sha1_hash[0:12]}'
component.purl = PackageURL( # DEPRECATED: a file has no PURL!
type='generic', name=path_for_bom if path_for_bom else absolute_file_path,
version=f'0.0.0-{sha1_hash[0:12]}'
)
version = f'0.0.0-{sha1_hash[0:12]}'
name = path_for_bom if path_for_bom else absolute_file_path
component.version = version
component.purl = f'pkg:generic/{name}@{version}' # DEPRECATED: a file has no PURL!
return component

def __init__(
Expand All @@ -996,7 +992,7 @@ def __init__(
hashes: Optional[Iterable[HashType]] = None,
licenses: Optional[Iterable[License]] = None,
copyright: Optional[str] = None,
purl: Optional[PackageURL] = None,
purl: Optional[str] = None,
external_references: Optional[Iterable[ExternalReference]] = None,
properties: Optional[Iterable[Property]] = None,
release_notes: Optional[ReleaseNotes] = None,
Expand Down Expand Up @@ -1377,22 +1373,22 @@ def cpe(self, cpe: Optional[str]) -> None:
self._cpe = cpe

@property
@serializable.type_mapping(PackageUrlSH)
@serializable.xml_sequence(15)
def purl(self) -> Optional[PackageURL]:
@serializable.xml_string(serializable.XmlStringSerializationType.NORMALIZED_STRING)
def purl(self) -> Optional[str]:
"""
Specifies the package-url (PURL).

The purl, if specified, must be valid and conform to the specification defined at:
https://github.com/package-url/purl-spec

Returns:
`PackageURL` or `None`
`str` or `None`
"""
return self._purl

@purl.setter
def purl(self, purl: Optional[PackageURL]) -> None:
def purl(self, purl: Optional[str]) -> None:
self._purl = purl

@property
Expand Down Expand Up @@ -1679,7 +1675,7 @@ def __comparable_tuple(self) -> _ComparableTuple:
return _ComparableTuple((
self.type, self.group, self.name, self.version,
self.bom_ref.value,
None if self.purl is None else _ComparablePackageURL(self.purl),
self.purl,
self.swid, self.cpe, _ComparableTuple(self.swhids),
self.supplier, self.author, self.publisher,
self.description,
Expand Down
1 change: 0 additions & 1 deletion cyclonedx/model/component_evidence.py
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,6 @@
from warnings import warn
from xml.etree.ElementTree import Element as XmlElement # nosec B405

# See https://github.com/package-url/packageurl-python/issues/65
import py_serializable as serializable
from sortedcontainers import SortedSet

Expand Down
21 changes: 0 additions & 21 deletions cyclonedx/serialization/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -24,8 +24,6 @@
from typing import Any, Optional
from uuid import UUID

# See https://github.com/package-url/packageurl-python/issues/65
from packageurl import PackageURL
from py_serializable.helpers import BaseHelper

if sys.version_info >= (3, 13):
Expand Down Expand Up @@ -57,25 +55,6 @@ def deserialize(cls, o: Any) -> BomRef:
return BomRef.deserialize(o)


class PackageUrl(BaseHelper):

@classmethod
def serialize(cls, o: Any, ) -> str:
if isinstance(o, PackageURL):
return str(o.to_string())
raise SerializationOfUnexpectedValueException(
f'Attempt to serialize a non-PackageURL: {o!r}')

@classmethod
def deserialize(cls, o: Any) -> PackageURL:
try:
return PackageURL.from_string(purl=str(o))
except ValueError as err:
raise CycloneDxDeserializationException(
f'PURL string supplied does not parse: {o!r}'
) from err


class UrnUuidHelper(BaseHelper):

@classmethod
Expand Down
4 changes: 1 addition & 3 deletions examples/complex_serialize.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,8 +18,6 @@
import sys
from typing import TYPE_CHECKING

from packageurl import PackageURL

from cyclonedx.contrib.license.factories import LicenseFactory
from cyclonedx.contrib.this.builders import this_component as cdx_lib_component
from cyclonedx.exception import MissingOptionalDependencyException
Expand Down Expand Up @@ -68,7 +66,7 @@
urls=[XsUri('https://www.acme.org')]
),
bom_ref='myComponent@1.33.7-beta.1',
purl=PackageURL('generic', 'acme', 'some-component', '1.33.7-beta.1')
purl='pkg:generic/acme/some-component@1.33.7-beta.1'
)
bom.components.add(component1)
bom.register_dependency(root_component, [component1])
Expand Down
1 change: 0 additions & 1 deletion pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -70,7 +70,6 @@ keywords = [

[tool.poetry.dependencies]
python = "^3.9"
packageurl-python = ">=0.11, <2"
py-serializable = "^2.1.0"
sortedcontainers = "^2.4.0"
license-expression = "^30"
Expand Down
35 changes: 9 additions & 26 deletions tests/_data/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -24,9 +24,6 @@
from typing import Any, Optional
from uuid import UUID

# See https://github.com/package-url/packageurl-python/issues/65
from packageurl import PackageURL

from cyclonedx.builder.this import this_component, this_tool
from cyclonedx.model import (
AttachedText,
Expand Down Expand Up @@ -482,9 +479,7 @@ def get_bom_with_component_evidence() -> Bom:
component = Component(
name='setuptools', version='50.3.2',
bom_ref='pkg:pypi/setuptools@50.3.2?extension=tar.gz',
purl=PackageURL(
type='pypi', name='setuptools', version='50.3.2', qualifiers='extension=tar.gz'
),
purl='pkg:pypi/setuptools@50.3.2?extension=tar.gz',
licenses=[DisjunctiveLicense(id='MIT')],
author='Test Author'
)
Expand Down Expand Up @@ -550,7 +545,7 @@ def get_bom_with_component_setuptools_with_vulnerability() -> Bom:
),
affects=[
BomTarget(
ref=component.purl.to_string(),
ref=component.purl,
versions=[BomTargetVersionRange(
range='49.0.0 - 54.0.0', status=ImpactAnalysisAffectedStatus.AFFECTED
)]
Expand Down Expand Up @@ -845,9 +840,7 @@ def get_component_setuptools_simple(
return Component(
name='setuptools', version='50.3.2',
bom_ref=bom_ref,
purl=PackageURL(
type='pypi', name='setuptools', version='50.3.2', qualifiers='extension=tar.gz'
),
purl='pkg:pypi/setuptools@50.3.2?extension=tar.gz',
licenses=[DisjunctiveLicense(id='MIT')],
author='Test Author'
)
Expand All @@ -856,9 +849,7 @@ def get_component_setuptools_simple(
def get_component_setuptools_simple_no_version(bom_ref: Optional[str] = None) -> Component:
return Component(
name='setuptools', bom_ref=bom_ref or 'pkg:pypi/setuptools?extension=tar.gz',
purl=PackageURL(
type='pypi', name='setuptools', qualifiers='extension=tar.gz'
),
purl='pkg:pypi/setuptools?extension=tar.gz',
licenses=[DisjunctiveLicense(id='MIT')],
author='Test Author'
)
Expand All @@ -867,9 +858,7 @@ def get_component_setuptools_simple_no_version(bom_ref: Optional[str] = None) ->
def get_component_toml_with_hashes_with_references(bom_ref: Optional[str] = None) -> Component:
return Component(
name='toml', version='0.10.2', bom_ref=bom_ref or 'pkg:pypi/toml@0.10.2?extension=tar.gz',
purl=PackageURL(
type='pypi', name='toml', version='0.10.2', qualifiers='extension=tar.gz'
), hashes=[
purl='pkg:pypi/toml@0.10.2?extension=tar.gz', hashes=[
HashType.from_composite_str('sha256:806143ae5bfb6a3c6e736a764057db0e6a0e05e338b5630894a5f779cabb4f9b')
], external_references=[
get_external_reference_1()
Expand Down Expand Up @@ -1365,19 +1354,13 @@ def get_bom_for_issue_598_multiple_components_with_purl_qualifiers() -> Bom:
return _make_bom(components=[
Component(
name='dummy', version='2.3.5', bom_ref='dummy-a',
purl=PackageURL(
type='pypi', namespace=None, name='pathlib2', version='2.3.5', subpath=None,
qualifiers={}
)
purl='pkg:pypi/pathlib2@2.3.5'
),
Component(
name='dummy', version='2.3.5', bom_ref='dummy-b',
purl=PackageURL(
type='pypi', namespace=None, name='pathlib2', version='2.3.5', subpath=None,
qualifiers={
'vcs_url': 'git+https://github.com/jazzband/pathlib2.git@5a6a88db3cc1d08dbc86fbe15edfb69fb5f5a3d6'
}
)
purl='pkg:pypi/pathlib2@2.3.5'
'?vcs_url=git%2Bhttps:%2F%2Fgithub.com%2Fjazzband%2Fpathlib2.git'
'%405a6a88db3cc1d08dbc86fbe15edfb69fb5f5a3d6'
)
])

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
<component type="library">
<name>dummy</name>
<version>2.3.5</version>
<purl>pkg:pypi/pathlib2@2.3.5?vcs_url=git%2Bhttps://github.com/jazzband/pathlib2.git%405a6a88db3cc1d08dbc86fbe15edfb69fb5f5a3d6</purl>
<purl>pkg:pypi/pathlib2@2.3.5?vcs_url=git%2Bhttps:%2F%2Fgithub.com%2Fjazzband%2Fpathlib2.git%405a6a88db3cc1d08dbc86fbe15edfb69fb5f5a3d6</purl>
<modified>false</modified>
</component>
</components>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
<component type="library" bom-ref="dummy-b">
<name>dummy</name>
<version>2.3.5</version>
<purl>pkg:pypi/pathlib2@2.3.5?vcs_url=git%2Bhttps://github.com/jazzband/pathlib2.git%405a6a88db3cc1d08dbc86fbe15edfb69fb5f5a3d6</purl>
<purl>pkg:pypi/pathlib2@2.3.5?vcs_url=git%2Bhttps:%2F%2Fgithub.com%2Fjazzband%2Fpathlib2.git%405a6a88db3cc1d08dbc86fbe15edfb69fb5f5a3d6</purl>
</component>
</components>
</bom>
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
{
"bom-ref": "dummy-b",
"name": "dummy",
"purl": "pkg:pypi/pathlib2@2.3.5?vcs_url=git%2Bhttps://github.com/jazzband/pathlib2.git%405a6a88db3cc1d08dbc86fbe15edfb69fb5f5a3d6",
"purl": "pkg:pypi/pathlib2@2.3.5?vcs_url=git%2Bhttps:%2F%2Fgithub.com%2Fjazzband%2Fpathlib2.git%405a6a88db3cc1d08dbc86fbe15edfb69fb5f5a3d6",
"type": "library",
"version": "2.3.5"
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@
<component type="library" bom-ref="dummy-b">
<name>dummy</name>
<version>2.3.5</version>
<purl>pkg:pypi/pathlib2@2.3.5?vcs_url=git%2Bhttps://github.com/jazzband/pathlib2.git%405a6a88db3cc1d08dbc86fbe15edfb69fb5f5a3d6</purl>
<purl>pkg:pypi/pathlib2@2.3.5?vcs_url=git%2Bhttps:%2F%2Fgithub.com%2Fjazzband%2Fpathlib2.git%405a6a88db3cc1d08dbc86fbe15edfb69fb5f5a3d6</purl>
</component>
</components>
<dependencies>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
{
"bom-ref": "dummy-b",
"name": "dummy",
"purl": "pkg:pypi/pathlib2@2.3.5?vcs_url=git%2Bhttps://github.com/jazzband/pathlib2.git%405a6a88db3cc1d08dbc86fbe15edfb69fb5f5a3d6",
"purl": "pkg:pypi/pathlib2@2.3.5?vcs_url=git%2Bhttps:%2F%2Fgithub.com%2Fjazzband%2Fpathlib2.git%405a6a88db3cc1d08dbc86fbe15edfb69fb5f5a3d6",
"type": "library",
"version": "2.3.5"
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@
<component type="library" bom-ref="dummy-b">
<name>dummy</name>
<version>2.3.5</version>
<purl>pkg:pypi/pathlib2@2.3.5?vcs_url=git%2Bhttps://github.com/jazzband/pathlib2.git%405a6a88db3cc1d08dbc86fbe15edfb69fb5f5a3d6</purl>
<purl>pkg:pypi/pathlib2@2.3.5?vcs_url=git%2Bhttps:%2F%2Fgithub.com%2Fjazzband%2Fpathlib2.git%405a6a88db3cc1d08dbc86fbe15edfb69fb5f5a3d6</purl>
</component>
</components>
<dependencies>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
{
"bom-ref": "dummy-b",
"name": "dummy",
"purl": "pkg:pypi/pathlib2@2.3.5?vcs_url=git%2Bhttps://github.com/jazzband/pathlib2.git%405a6a88db3cc1d08dbc86fbe15edfb69fb5f5a3d6",
"purl": "pkg:pypi/pathlib2@2.3.5?vcs_url=git%2Bhttps:%2F%2Fgithub.com%2Fjazzband%2Fpathlib2.git%405a6a88db3cc1d08dbc86fbe15edfb69fb5f5a3d6",
"type": "library",
"version": "2.3.5"
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@
<component type="library" bom-ref="dummy-b">
<name>dummy</name>
<version>2.3.5</version>
<purl>pkg:pypi/pathlib2@2.3.5?vcs_url=git%2Bhttps://github.com/jazzband/pathlib2.git%405a6a88db3cc1d08dbc86fbe15edfb69fb5f5a3d6</purl>
<purl>pkg:pypi/pathlib2@2.3.5?vcs_url=git%2Bhttps:%2F%2Fgithub.com%2Fjazzband%2Fpathlib2.git%405a6a88db3cc1d08dbc86fbe15edfb69fb5f5a3d6</purl>
</component>
</components>
<dependencies>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
{
"bom-ref": "dummy-b",
"name": "dummy",
"purl": "pkg:pypi/pathlib2@2.3.5?vcs_url=git%2Bhttps://github.com/jazzband/pathlib2.git%405a6a88db3cc1d08dbc86fbe15edfb69fb5f5a3d6",
"purl": "pkg:pypi/pathlib2@2.3.5?vcs_url=git%2Bhttps:%2F%2Fgithub.com%2Fjazzband%2Fpathlib2.git%405a6a88db3cc1d08dbc86fbe15edfb69fb5f5a3d6",
"type": "library",
"version": "2.3.5"
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@
<component type="library" bom-ref="dummy-b">
<name>dummy</name>
<version>2.3.5</version>
<purl>pkg:pypi/pathlib2@2.3.5?vcs_url=git%2Bhttps://github.com/jazzband/pathlib2.git%405a6a88db3cc1d08dbc86fbe15edfb69fb5f5a3d6</purl>
<purl>pkg:pypi/pathlib2@2.3.5?vcs_url=git%2Bhttps:%2F%2Fgithub.com%2Fjazzband%2Fpathlib2.git%405a6a88db3cc1d08dbc86fbe15edfb69fb5f5a3d6</purl>
</component>
</components>
<dependencies>
Expand Down
Loading
Loading