-
-
Notifications
You must be signed in to change notification settings - Fork 49
feat!: Add component and services for tools #635
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
feat!: Add component and services for tools #635
Conversation
CycloneDX spec 1.5 depcreated an array of tools in bom.metadata and instead prefers object with an array of components and an array of services. This PR implements that. Signed-off-by: Joshua Kugler <[email protected]>
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
i dislike the current concept of ToolRepository
that holds tools
, services
and components
at the same time.
This is an abomination of a data type, and teaching people how to use it properly will just be a hack of an effort.
i'd rather have a type ToolRepository
that holds services
and components
and no Tool
!
So, Metadata.tools
would be truly Union[ToolRepository, SortedSet[Tool]]
.
The (de)serialize would be handled by a (de)normaliser (aka "Helper" and thats it.
Is there something that speaks against this very simple and still pythonic solution?
a feature i would love to see in the end: metadata tools converters, that allow me to have a bunch of |
So drivers for my approach were two-fold:
Thus, the reason for ToolRepository which combined the three types. I wanted to be able to initialize and empty
as well as be able to do:
If we don't have an object in
That would be really neat. Do you mean a stand-alone tool? Or built in to the new type? Is there a way to know in the normalizing functions which version we're serializing for? I did not see that anywhere in the docs, but it would be great if we could do that. |
Thank you for the explanation. A need for API backwards compatibility is not really needed. Clean code and documentation are more important. An improvement I could imagine: class ToolsRepository:
"""our implementation of the tools repo"""
tools: SortedSet[Tool]
"""DEPRECATED tools"""
components: SortedSet[Component]
"""docstring here..."""
services: SortedSet[Service]
"""docstring here..."""
def __init__(self, *,
components: Optional[Iterable[Components]] = None,
services: Optional[Iterable[Service]] = None,
# Deprecated in v1.x
tools: Optional[Iterable[Tool]] = None,
):
if tools:
warn("deprecation message here...", DeprecationWarning)
self.tools = SortedSet(tools or ())
self.components = SortedSet(components or ())
self.services = SortedSet(services or ()) |
cyclonedx/model/__init__.py
Outdated
@@ -1321,7 +1195,8 @@ def __hash__(self) -> int: | |||
def __repr__(self) -> str: | |||
return f'<Copyright text={self.text}>' | |||
|
|||
|
|||
# Importing here to avoid a circular import | |||
from .tool import Tool # pylint: disable=wrong-import-position |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't know if this is the best solution. We could just put all the Tools stuff into this file, and avoid the circular-imports work-around.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
sure. put all in the __init__.py
.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I spent a few hours trying to solve circular import errors in cylclonedx.model.bom
(after putting all the tool stuff in __init__.py
and then gave up when I hit a circular import error in cyclonedx.serialization
. If I don't stop, I'm going to end up owning all the code . :D I'll leave this as-is for now, and we can do a code restructuring as part of another PR.
Thanks for the explanation. Given the comment here: https://github.com/CycloneDX/cyclonedx-python-lib/blob/main/cyclonedx/model/__init__.py#L1079 I'd like to try to keep backward compatibility for now. The code to maintain this is probably only 60 to 70 or so lines more than breaking backward compatibility, and once the support for List[Tool] goes away completely, the semantics for tools.components and tools.services won't change. Everything seems to be working, save the problem I mentioned here: https://cyclonedx.slack.com/archives/CVA0QJEVA/p1718821402381719 |
e9652cc
to
9a939ad
Compare
Tests for new functionality are in place. Pretty sure I didn't do it the best way, but just wanted to show the new functionality works. :) We can re-work the tests before merge if need be. |
BTW, maintains 93% test coverage. I have a few more code paths I want to test as well. |
9a939ad
to
4289859
Compare
@jkugler, before we can use your contribution, we need you to sign-off your commits. here is why this is required and what it implies: https://github.com/CycloneDX/cyclonedx-python-lib/blob/main/CONTRIBUTING.md#sign-off-your-commits here is a step-by-step instruction on how to do this: https://github.com/CycloneDX/cyclonedx-python-lib/pull/635/checks?check_run_id=26536713378 |
There is a decision we'll need to make in how to handle the current behavior in if not tools:
self.tools.add(ThisTool) This adds the CycloneDX information if none is provided when initializing BomMetaData, and the will generate an error if someone, later does this: bom.metadata.tools.components = ...
# or
bom.metadata.tools.services = However, there will not be an error if a developer does bom.metadata.tools.components.add(...) or similar with services, and if there are components or services, those will be rendered and not the If we're OK with that behavior, that is, telling users to provide a |
Signed-off-by: Joshua Kugler <[email protected]>
* XML serialization function * No ERRORs in tests, but still plenty of FAILUREs Signed-off-by: Joshua Kugler <[email protected]>
Signed-off-by: Joshua Kugler <[email protected]>
Signed-off-by: Joshua Kugler <[email protected]>
(migrated to model/tool.py to avoid circular imports) Signed-off-by: Joshua Kugler <[email protected]>
Also fixed an import Need to fix an circular import still... Signed-off-by: Joshua Kugler <[email protected]>
Signed-off-by: Joshua Kugler <[email protected]>
Also a small formatting change Signed-off-by: Joshua Kugler <[email protected]>
Signed-off-by: Jan Kowalleck <[email protected]>
Signed-off-by: Jan Kowalleck <[email protected]>
376dfa8
to
427add4
Compare
so cyclic imports are prevented Signed-off-by: Jan Kowalleck <[email protected]>
Signed-off-by: Jan Kowalleck <[email protected]>
Signed-off-by: Jan Kowalleck <[email protected]>
Signed-off-by: Jan Kowalleck <[email protected]>
Signed-off-by: Jan Kowalleck <[email protected]>
Signed-off-by: Jan Kowalleck <[email protected]>
Signed-off-by: Jan Kowalleck <[email protected]>
Signed-off-by: Jan Kowalleck <[email protected]>
Signed-off-by: Jan Kowalleck <[email protected]>
Signed-off-by: Jan Kowalleck <[email protected]>
I am trying to go through the changes made, but I'm not understanding where the code is. I see a bunch of code was moved to Sorry for the confusionl. |
i am very sorry for the inconvenience. maybe this helps to see the actual changes: |
I noticed the test coverage for cyclonedx/model/tool.py went from 100% to 97% after the recent changes. Would you like me to make sure the missed statements are checked? |
Signed-off-by: Jan Kowalleck <[email protected]>
Signed-off-by: Jan Kowalleck <[email protected]>
Signed-off-by: Jan Kowalleck <[email protected]>
Signed-off-by: Jan Kowalleck <[email protected]>
did that, cov at 100% now. please review |
Signed-off-by: Jan Kowalleck <[email protected]>
Looks great! Let's get it merged! Thanks again for all your help and patience on this. |
reworked `ThisTool` for #635 --------- Signed-off-by: Jan Kowalleck <[email protected]>
CycloneDX spec 1.5 deprecated an array of tools in bom.metadata and instead prefers object with an array of components and an array of services.
This PR implements that.
This works de-serializing a Syft SBOM with a tool section like so:
Next up: docs, XML (de)serialization code, and tests.
fixes #561