-
Notifications
You must be signed in to change notification settings - Fork 40
Generic Source Provenance #2099
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
base: master
Are you sure you want to change the base?
Generic Source Provenance #2099
Conversation
d18f672 to
6894c4f
Compare
src/buildstream/source.py
Outdated
| def load_source_provenance(self, node: MappingNode) -> None: | ||
| raise ImplError("Source plugin '{}' does not implement load_source_provenance()".format(self.get_kind())) | ||
|
|
||
| def get_source_provenance(self) -> SourceProvenance: | ||
| raise ImplError("Source plugin '{}' does not implement get_source_provenance()".format(self.get_kind())) | ||
|
|
||
| def set_source_provenance(self, source_provenance: SourceProvenance): | ||
| raise ImplError("Source plugin '{}' does not implement set_source_provenance()".format(self.get_kind())) |
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.
To retain backward compatibility, we can't require source plugins to implement these methods. I.e., we need (trivial) default implementations for any method that is called unconditionally by the core. API documentation will be required as well, of course.
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.
That's easy enough if we just go with a "do nothing" implementation
src/buildstream/source.py
Outdated
| def set_source_provenance(self, source_provenance: SourceProvenance): | ||
| raise ImplError("Source plugin '{}' does not implement set_source_provenance()".format(self.get_kind())) | ||
|
|
||
| def track(self, *, previous_sources_dir: Optional[str] = None) -> (SourceRef, SourceProvenance): |
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.
We need to find a way to allow returning a SourceProvenance without breaking API.
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.
Hmm, that might be more difficult to work out. I'll see if I can work something sensible out
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.
For now I've gone with combining the old and new return signatures (https://github.com/apache/buildstream/pull/2099/files#diff-48200ef302e5d841cce81834e8879a65e59db922a22605b9d7fa16b4dd5c7067R941) and added some logic to unpackage it appropriately (https://github.com/apache/buildstream/pull/2099/files#diff-48200ef302e5d841cce81834e8879a65e59db922a22605b9d7fa16b4dd5c7067R1811). I believe that's all that's required to not break the API here
51ff651 to
98735d0
Compare
182c33a to
74c718a
Compare
src/buildstream/element.py
Outdated
| project._project_conf.get_mapping("source-provenance-fields", None) | ||
| or project.source_provenance_fields |
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.
Is this the logic to handle the default on a project level? I'm not sure whether this works correctly, however, this logic should in any case be in the Project class such that Element and Source can simply use project.source_provenance_fields (_project.conf is considered private and should not be accessed from other classes). Or am I missing a reason why this can't be done in the Project class?
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.
Thanks, I've made the change to move the logic to Project instead
|
Have you already started looking into adding test(s) for this? |
src/buildstream/source.py
Outdated
| ) | ||
|
|
||
| # Make sure everything is a string | ||
| provenance = MappingNode.from_dict({key: value.as_str() for key, value in provenance_node.items()}) |
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.
Is there a reason we actually need to use a newly created MappingNode instead of directly using provenance_node (after verification)? I suspect that this recreation loses provenance of the provenance node (i.e., .bst file name and line number).
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 wasn't aware I could simply write back to a MappingNode like a dictionary, even though the docs clearly state that. Regardless, this is no longer being used since this logic has been changed to throwing an error in the event that the value could not be parsed as a string
| self.homepage: Optional[str] = homepage | ||
| """ | ||
| The project homepage URL | ||
| """ | ||
|
|
||
| self.issue_tracker: Optional[str] = issue_tracker |
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.
These attributes are public, we can't drop them. We need to populate them from generic source provenance for backwards compatibility.
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.
Sorry, I keep messing up the backwards compatibility. I've added these back in
df0f7d9 to
a91adf9
Compare
3f4f475 to
34dd8b0
Compare
juergbi
left a comment
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.
Somewhat of a nit but it seems we're mixing two terms for the same thing. I'm not sure whether "source provenance field" or "source provenance attribute" is a better fit. However, whatever we choose, we should be consistent to avoid confusion. Or is there a semantic distinction that I'm overlooking?
I think I used the term 'field' first because I thought the same term was used in the documentation already, but I may be mistaken. I'm not dead-set on the 'field' term. If 'attribute' is a better fit with the rest of BuildStream's API and documentation, I'm happy to settle on that as long as we're consistent.
I've noticed this too and haven't got a fixed opinion on which we use. I was just using "attributes" since #2069 uses the term. I'm not seeing any deciding usage in the docs. In context of errors that already exist, it seems "attribute" reads better than "field", to me at least, but that's just how I've been reading it all this time anyway. I'll change up the error messages as per your suggestions and make the term used consistent based on what reads best from there |
34dd8b0 to
1ea1f4d
Compare
|
I've seemingly messed something up with the source provenance attribute tests so they're currently failing. I'll look at this next week |
1ea1f4d to
a13a331
Compare
This allows multi-source source plugins to provide this information per source rather than as a singular top level. This is done by adding a `provenance_node` parameter to `create_source_info()` that when specified overrides the use of the source's top level source provenance info. Co-authored-by: Joshua Zivkovic <joshua.zivkovic@codethink.co.uk>
Remove harcoded SPDX attributes and make them be generic instead. Project allowed attributes are configured via the project config, these supported values a determined by buildstream-sbom's support Co-authored-by: Jürg Billeter <j@bitron.ch> Co-authored-by: Joshua Zivkovic <joshuazivkovic@codethink.co.uk>
a13a331 to
749602a
Compare
Towards #2069
This PR changes the approach to how buildstream handles source provenance information, moving from a hard coded implementation of attributes (which buildstream core needs to know nothing about) to a more generic, user defined approach where buildstream only needs to carry the values to the next step.
Users can now define their projects allowed set of source provenance attributes using the
source_provenance_fieldskey in the project.conf. Where attributes are used in source provenance but not defined in the project.conf, buildstream will refuse attribute and throw an error informing the user that the attribute is not present in the project.confCurrently there is no limitation on these values since neither plugins nor buildstream sbom are yet using this approach so there is no defined set of attributes plugins and users should refer to but this will soon be added to buildstream-sbom as it will depend on what buildstream-sbom supports for SPDX generation.
Note: This PR previously included updates to
source trackto allow plugins to automatically populate these source attributes where possible; this has been moved to a follow up PR.