Skip to content
Merged
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
16 changes: 8 additions & 8 deletions cyclonedx/model/bom.py
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@
from .dependency import Dependable, Dependency
from .license import License, LicenseExpression, LicenseRepository
from .service import Service
from .tool import Tool, ToolsRepository, _ToolsRepositoryHelper
from .tool import Tool, ToolRepository, _ToolRepositoryHelper
from .vulnerability import Vulnerability

if TYPE_CHECKING: # pragma: no cover
Expand All @@ -62,7 +62,7 @@ class BomMetaData:

def __init__(
self, *,
tools: Optional[Union[Iterable[Tool], ToolsRepository]] = None,
tools: Optional[Union[Iterable[Tool], ToolRepository]] = None,
authors: Optional[Iterable[OrganizationalContact]] = None,
component: Optional[Component] = None,
supplier: Optional[OrganizationalEntity] = None,
Expand Down Expand Up @@ -117,22 +117,22 @@ def timestamp(self, timestamp: datetime) -> None:
# ... # TODO since CDX1.5

@property
@serializable.type_mapping(_ToolsRepositoryHelper)
@serializable.type_mapping(_ToolRepositoryHelper)
@serializable.xml_sequence(3)
def tools(self) -> ToolsRepository:
def tools(self) -> ToolRepository:
"""
Tools used to create this BOM.

Returns:
`ToolsRepository` objects.
:class:`ToolRepository` object.
"""
return self._tools

@tools.setter
def tools(self, tools: Union[Iterable[Tool], ToolsRepository]) -> None:
def tools(self, tools: Union[Iterable[Tool], ToolRepository]) -> None:
self._tools = tools \
if isinstance(tools, ToolsRepository) \
else ToolsRepository(tools=tools)
if isinstance(tools, ToolRepository) \
else ToolRepository(tools=tools)

@property
@serializable.xml_array(serializable.XmlArraySerializationType.NESTED, 'author')
Expand Down
20 changes: 10 additions & 10 deletions cyclonedx/model/tool.py
Original file line number Diff line number Diff line change
Expand Up @@ -188,7 +188,7 @@ def from_service(cls: Type['Tool'], service: 'Service') -> 'Tool':
)


class ToolsRepository:
class ToolRepository:
"""
The repository of tool formats
"""
Expand Down Expand Up @@ -251,7 +251,7 @@ def __bool__(self) -> bool:
or len(self._services) > 0

def __eq__(self, other: object) -> bool:
if not isinstance(other, ToolsRepository):
if not isinstance(other, ToolRepository):
return False

return self._tools == other._tools \
Expand All @@ -262,10 +262,10 @@ def __hash__(self) -> int:
return hash((tuple(self._tools), tuple(self._components), tuple(self._services)))


class _ToolsRepositoryHelper(BaseHelper):
class _ToolRepositoryHelper(BaseHelper):

@staticmethod
def __all_as_tools(o: ToolsRepository) -> Tuple[Tool, ...]:
def __all_as_tools(o: ToolRepository) -> Tuple[Tool, ...]:
return (
*o.tools,
*map(Tool.from_component, o.components),
Expand All @@ -280,7 +280,7 @@ def __supports_components_and_services(view: Any) -> bool:
return False

@classmethod
def json_normalize(cls, o: ToolsRepository, *,
def json_normalize(cls, o: ToolRepository, *,
view: Optional[Type['ViewType']],
**__: Any) -> Any:
if len(o.tools) > 0 or not cls.__supports_components_and_services(view):
Expand All @@ -294,7 +294,7 @@ def json_normalize(cls, o: ToolsRepository, *,

@classmethod
def json_denormalize(cls, o: Union[List[Dict[str, Any]], Dict[str, Any]],
**__: Any) -> ToolsRepository:
**__: Any) -> ToolRepository:
tools = None
components = None
services = None
Expand All @@ -305,10 +305,10 @@ def json_denormalize(cls, o: Union[List[Dict[str, Any]], Dict[str, Any]],
s), o.get('services', ()))
elif isinstance(o, Iterable):
tools = map(lambda t: Tool.from_json(t), o) # type:ignore[attr-defined]
return ToolsRepository(components=components, services=services, tools=tools)
return ToolRepository(components=components, services=services, tools=tools)

@classmethod
def xml_normalize(cls, o: ToolsRepository, *,
def xml_normalize(cls, o: ToolRepository, *,
element_name: str,
view: Optional[Type['ViewType']],
xmlns: Optional[str],
Expand Down Expand Up @@ -344,7 +344,7 @@ def xml_denormalize(cls, o: Element, *,
default_ns: Optional[str],
prop_info: 'ObjectMetadataLibrary.SerializableProperty',
ctx: Type[Any],
**kwargs: Any) -> ToolsRepository:
**kwargs: Any) -> ToolRepository:
tools = []
components = None
services = None
Expand All @@ -361,7 +361,7 @@ def xml_denormalize(cls, o: Element, *,
s, default_ns), e)
else:
raise CycloneDxDeserializationException(f'unexpected: {e!r}')
return ToolsRepository(
return ToolRepository(
tools=tools,
components=components,
services=services)
16 changes: 8 additions & 8 deletions cyclonedx/model/vulnerability.py
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@
ImpactAnalysisResponse,
ImpactAnalysisState,
)
from .tool import Tool, ToolsRepository, _ToolsRepositoryHelper
from .tool import Tool, ToolRepository, _ToolRepositoryHelper


@serializable.serializable_class
Expand Down Expand Up @@ -954,7 +954,7 @@ def __init__(
published: Optional[datetime] = None,
updated: Optional[datetime] = None,
credits: Optional[VulnerabilityCredits] = None,
tools: Optional[Union[Iterable[Tool], ToolsRepository]] = None,
tools: Optional[Union[Iterable[Tool], ToolRepository]] = None,
analysis: Optional[VulnerabilityAnalysis] = None,
affects: Optional[Iterable[BomTarget]] = None,
properties: Optional[Iterable[Property]] = None,
Expand Down Expand Up @@ -1247,22 +1247,22 @@ def credits(self, credits: Optional[VulnerabilityCredits]) -> None:
self._credits = credits

@property
@serializable.type_mapping(_ToolsRepositoryHelper)
@serializable.type_mapping(_ToolRepositoryHelper)
@serializable.xml_sequence(17)
def tools(self) -> ToolsRepository:
def tools(self) -> ToolRepository:
"""
Tools used to create this BOM.

Returns:
`ToolsRepository` objects.
:class:`ToolRepository` object.
"""
return self._tools

@tools.setter
def tools(self, tools: Union[Iterable[Tool], ToolsRepository]) -> None:
def tools(self, tools: Union[Iterable[Tool], ToolRepository]) -> None:
self._tools = tools \
if isinstance(tools, ToolsRepository) \
else ToolsRepository(tools=tools)
if isinstance(tools, ToolRepository) \
else ToolRepository(tools=tools)

@property
@serializable.xml_sequence(18)
Expand Down
4 changes: 2 additions & 2 deletions docs/upgrading.rst
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ New: ``from cyclonedx.model.tool import Tool``
Alter Metadata Tools
--------------------

Property :attr:`cyclonedx.model.bom.BomMetaData.tools` is an instance of :class:`cyclonedx.model.tool.ToolsRepository`, now.
Property :attr:`cyclonedx.model.bom.BomMetaData.tools` is an instance of :class:`cyclonedx.model.tool.ToolRepository`, now.
Therefore, the process of adding new tools needs to be migrated changed.

Old: ``my_bom.metadata.tools.add(my_tool)``
Expand All @@ -45,7 +45,7 @@ New: ``my_bom.metadata.tools.tools.add(my_tool)``
Alter Vulnerability Tools
-------------------------

Property :attr:`cyclonedx.model.vulnerability.Vulnerability.tools` is an instance of :class:`cyclonedx.model.tool.ToolsRepository`, now.
Property :attr:`cyclonedx.model.vulnerability.Vulnerability.tools` is an instance of :class:`cyclonedx.model.tool.ToolRepository`, now.
Therefore, the process of adding new tools needs to be migrated changed.

Old: ``my_vulnerability.tools.add(my_tool)``
Expand Down
12 changes: 6 additions & 6 deletions tests/_data/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -89,7 +89,7 @@
from cyclonedx.model.license import DisjunctiveLicense, License, LicenseAcknowledgement, LicenseExpression
from cyclonedx.model.release_note import ReleaseNotes
from cyclonedx.model.service import Service
from cyclonedx.model.tool import Tool, ToolsRepository
from cyclonedx.model.tool import Tool, ToolRepository
from cyclonedx.model.vulnerability import (
BomTarget,
BomTargetVersionRange,
Expand Down Expand Up @@ -495,7 +495,7 @@ def get_bom_with_component_setuptools_with_vulnerability() -> Bom:
],
individuals=[get_org_contact_2()]
),
tools=ToolsRepository(tools=(
tools=ToolRepository(tools=(
Tool(vendor='CycloneDX', name='cyclonedx-python-lib'),
)),
analysis=VulnerabilityAnalysis(
Expand Down Expand Up @@ -1069,7 +1069,7 @@ def get_bom_with_tools() -> Bom:
def get_bom_with_tools_with_component_migrate() -> Bom:
return _make_bom(
metadata=BomMetaData(
tools=ToolsRepository(
tools=ToolRepository(
components=(
this_component(),
Component(name='test-component', bom_ref='test-component'),
Expand All @@ -1090,7 +1090,7 @@ def get_bom_with_tools_with_component_migrate() -> Bom:
def get_bom_with_tools_with_service_migrate() -> Bom:
return _make_bom(
metadata=BomMetaData(
tools=ToolsRepository(
tools=ToolRepository(
services=(
Service(name='test-service', bom_ref='test-service'),
Service(group='acme',
Expand All @@ -1107,7 +1107,7 @@ def get_bom_with_tools_with_service_migrate() -> Bom:
def get_bom_with_tools_with_component_and_service_migrate() -> Bom:
return _make_bom(
metadata=BomMetaData(
tools=ToolsRepository(
tools=ToolRepository(
components=(
this_component(),
Component(name='test-component', bom_ref='test-component'),
Expand All @@ -1134,7 +1134,7 @@ def get_bom_with_tools_with_component_and_service_migrate() -> Bom:


def get_bom_with_tools_with_component_and_service_and_tools_irreversible_migrate() -> Bom:
tools = ToolsRepository()
tools = ToolRepository()
tcomp = tools.components
tserv = tools.services
ttools = tools.tools
Expand Down
2 changes: 1 addition & 1 deletion tests/test_deserialize_xml.py
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@ def test_prepared(self, get_bom: Callable[[], Bom], *_: Any, **__: Any) -> None:
self.assertBomDeepEqual(expected, bom,
fuzzy_deps=get_bom in all_get_bom_funct_with_incomplete_deps)

def test_unexpected_toolsrepository_item(self) -> None:
def test_unexpected_toolrepository_item(self) -> None:
with open(join(OWN_DATA_DIRECTORY, 'xml', '1.5', 'invalid-tool.xml')) as input_xml:
with self.assertRaisesRegex(CycloneDxDeserializationException,
r"^unexpected: <Element '{.+?}foo' at 0x[0-9a-fA-F]+>$"):
Expand Down
20 changes: 10 additions & 10 deletions tests/test_model_tool_repository.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,16 +20,16 @@

from cyclonedx.model.component import Component
from cyclonedx.model.service import Service
from cyclonedx.model.tool import Tool, ToolsRepository
from cyclonedx.model.tool import Tool, ToolRepository


class TestModelToolRepository(TestCase):

def test_init(self) -> ToolsRepository:
def test_init(self) -> ToolRepository:
c = Component(name='test-component')
s = Service(name='test-service')
t = Tool(name='test-tool')
tr = ToolsRepository(
tr = ToolRepository(
components=(c,),
services=(s,),
tools=(t,)
Expand All @@ -45,36 +45,36 @@ def test_filled(self) -> None:
self.assertTrue(tr)

def test_empty(self) -> None:
tr = ToolsRepository()
tr = ToolRepository()
self.assertEqual(0, len(tr))
self.assertFalse(tr)

def test_unequal_different_type(self) -> None:
tr = ToolsRepository()
tr = ToolRepository()
self.assertFalse(tr == 'other')

def test_equal_self(self) -> None:
tr = ToolsRepository()
tr = ToolRepository()
tr.tools.add(Tool(name='my-tool'))
self.assertTrue(tr == tr)

def test_unequal(self) -> None:
tr1 = ToolsRepository()
tr1 = ToolRepository()
tr1.components.add(Component(name='my-component'))
tr1.services.add(Service(name='my-service'))
tr1.tools.add(Tool(name='my-tool'))
tr2 = ToolsRepository()
tr2 = ToolRepository()
self.assertFalse(tr1 == tr2)

def test_equal(self) -> None:
c = Component(name='my-component')
s = Service(name='my-service')
t = Tool(name='my-tool')
tr1 = ToolsRepository()
tr1 = ToolRepository()
tr1.components.add(c)
tr1.services.add(s)
tr1.tools.add(t)
tr2 = ToolsRepository()
tr2 = ToolRepository()
tr2.components.add(c)
tr2.services.add(s)
tr2.tools.add(t)
Expand Down