Skip to content

feat: add support for component's evidences according to spec #810

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 28 commits into from
Jun 7, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
28 commits
Select commit Hold shift + click to select a range
849c7a4
feat: add support for component's evidences according to spec
OxPirates May 3, 2025
f92dcc5
Merge branch 'main' into main
jkowalleck May 26, 2025
a65cc0e
prep extraxtion of component_evidence
jkowalleck May 27, 2025
63c1cc5
prep extraxtion of component_evidence
jkowalleck May 27, 2025
7b30eff
refactor: compoennt evidence
jkowalleck May 27, 2025
45abefe
prep extraxtion of component_evidence
jkowalleck May 27, 2025
392e61d
prep extraxtion of component_evidence
jkowalleck May 27, 2025
cbb7370
refactor: compoennt evidence
jkowalleck May 27, 2025
ec89ae7
wip
jkowalleck May 27, 2025
da433b6
tests
jkowalleck May 27, 2025
564b3e6
wip
jkowalleck May 27, 2025
23fdd94
wip
jkowalleck May 27, 2025
88bcc20
wip
jkowalleck May 27, 2025
9382ad4
Fix for pipeline failures, improvement for Identity, spec v1.5, v1.6
OxPirates May 29, 2025
1a7b41f
tests: bring backtest case with multiple evidence identities
jkowalleck May 31, 2025
95df588
modified `_IdentityToolRepositorySerializationHelper`
jkowalleck May 31, 2025
b66ecc3
reverted callstack frames as lists
jkowalleck May 31, 2025
47a1ef4
clean `_IdentityRepositorySerializationHelper`
jkowalleck May 31, 2025
5de7307
fix component evidence serialization
jkowalleck May 31, 2025
0ee583e
tidy
jkowalleck May 31, 2025
78fd4db
cleanup
jkowalleck May 31, 2025
7aef6e1
typing for serialization lib
jkowalleck May 31, 2025
de6d628
remove TODO
jkowalleck May 31, 2025
57625da
Merge remote-tracking branch 'origin/main' into OxPirates_main
jkowalleck Jun 2, 2025
c4a0218
style: remove no longer used typehint-ignores
jkowalleck Jun 2, 2025
bb111c3
Merge remote-tracking branch 'origin/main' into OxPirates_main
jkowalleck Jun 2, 2025
d2f93aa
Merge branch 'main' into main
jkowalleck Jun 5, 2025
8aac643
style: upgrade code style
jkowalleck Jun 5, 2025
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
12 changes: 12 additions & 0 deletions cyclonedx/exception/model.py
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,10 @@ class CycloneDxModelException(CycloneDxException):
pass


class InvalidValueException(CycloneDxModelException):
pass


class InvalidLocaleTypeException(CycloneDxModelException):
"""
Raised when the supplied locale does not conform to ISO-639 specification.
Expand Down Expand Up @@ -131,3 +135,11 @@ class InvalidCreIdException(CycloneDxModelException):
as defined at https://opencre.org/
"""
pass


class InvalidConfidenceException(CycloneDxModelException):
"""
Raised when an invalid value is provided for a Confidence.
The confidence of the evidence from 0 - 1, where 1 is 100% confidence.
"""
pass
105 changes: 2 additions & 103 deletions cyclonedx/model/component.py
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,6 @@
from ..serialization import PackageUrl as PackageUrlSH
from . import (
AttachedText,
Copyright,
ExternalReference,
HashAlgorithm,
HashType,
Expand All @@ -58,6 +57,7 @@
_HashTypeRepositorySerializationHelper,
)
from .bom_ref import BomRef
from .component_evidence import ComponentEvidence, _ComponentEvidenceSerializationHelper
from .contact import OrganizationalContact, OrganizationalEntity
from .crypto import CryptoProperties
from .dependency import Dependable
Expand Down Expand Up @@ -191,108 +191,6 @@ def __repr__(self) -> str:
return f'<Commit uid={self.uid}, url={self.url}, message={self.message}>'


@serializable.serializable_class
class ComponentEvidence:
"""
Our internal representation of the `componentEvidenceType` complex type.

Provides the ability to document evidence collected through various forms of extraction or analysis.

.. note::
See the CycloneDX Schema definition: https://cyclonedx.org/docs/1.6/xml/#type_componentEvidenceType
"""

def __init__(
self, *,
licenses: Optional[Iterable[License]] = None,
copyright: Optional[Iterable[Copyright]] = None,
) -> None:
self.licenses = licenses or []
self.copyright = copyright or []

# @property
# ...
# @serializable.view(SchemaVersion1Dot5)
# @serializable.xml_sequence(1)
# def identity(self) -> ...:
# ... # TODO since CDX1.5
#
# @identity.setter
# def identity(self, ...) -> None:
# ... # TODO since CDX1.5

# @property
# ...
# @serializable.view(SchemaVersion1Dot5)
# @serializable.xml_sequence(2)
# def occurrences(self) -> ...:
# ... # TODO since CDX1.5
#
# @occurrences.setter
# def occurrences(self, ...) -> None:
# ... # TODO since CDX1.5

# @property
# ...
# @serializable.view(SchemaVersion1Dot5)
# @serializable.xml_sequence(3)
# def callstack(self) -> ...:
# ... # TODO since CDX1.5
#
# @callstack.setter
# def callstack(self, ...) -> None:
# ... # TODO since CDX1.5

@property
@serializable.type_mapping(_LicenseRepositorySerializationHelper)
@serializable.xml_sequence(4)
def licenses(self) -> LicenseRepository:
"""
Optional list of licenses obtained during analysis.

Returns:
Set of `LicenseChoice`
"""
return self._licenses

@licenses.setter
def licenses(self, licenses: Iterable[License]) -> None:
self._licenses = LicenseRepository(licenses)

@property
@serializable.xml_array(serializable.XmlArraySerializationType.NESTED, 'text')
@serializable.xml_sequence(5)
def copyright(self) -> 'SortedSet[Copyright]':
"""
Optional list of copyright statements.

Returns:
Set of `Copyright`
"""
return self._copyright

@copyright.setter
def copyright(self, copyright: Iterable[Copyright]) -> None:
self._copyright = SortedSet(copyright)

def __comparable_tuple(self) -> _ComparableTuple:
return _ComparableTuple((
_ComparableTuple(self.licenses),
_ComparableTuple(self.copyright),
))

def __eq__(self, other: object) -> bool:
if isinstance(other, ComponentEvidence):
return self.__comparable_tuple() == other.__comparable_tuple()
return False

def __hash__(self) -> int:
return hash(self.__comparable_tuple())

def __repr__(self) -> str:
return f'<ComponentEvidence id={id(self)}>'


@serializable.serializable_enum
class ComponentScope(str, Enum):
"""
Expand Down Expand Up @@ -1644,6 +1542,7 @@ def components(self, components: Iterable['Component']) -> None:
@serializable.view(SchemaVersion1Dot5)
@serializable.view(SchemaVersion1Dot6)
@serializable.xml_sequence(24)
@serializable.type_mapping(_ComponentEvidenceSerializationHelper)
def evidence(self) -> Optional[ComponentEvidence]:
"""
Provides the ability to document evidence collected through various forms of extraction or analysis.
Expand Down
Loading