Reduce utility duplication by implementing document conversions
kzantow opened this issue · 0 comments
As part of the suggested refactorings I proposed, it was noted that the utility functions such as idsearcher.go
, which duplicate functionality for SPDX 2.1, 2.2, etc. could be made more generic using some reflection (and/or generics, which I don't think will help here).
Additionally, there is a desire to have the ability to convert between format versions. I propose using a "migration" approach for this and have created some functionality that does quite a lot of the work automatically, with heavy use of reflection.
I've created a draft PR here: kzantow-anchore#2 to illustrate how this can work, along with a full document conversion from a 2_2 to a 2_3 struct.
The gist of this approach is twofold:
- Use reflection to recursively map all fields from one struct to another based on convertible fields:
- fields with the same name and convertible types are automatically handled
- slices, maps, structs, and primitive types are currently handled
- each struct may implement a
ConvertFrom
method, which runs after the automatic conversion to correct, add, or modify the resulting struct, being passed the struct from which it was originally converted
- Set up a migration list so each version (v2_2, v2_3) can implement a
ConvertFrom
method from the previous (and possibly next) version. Implement a function that, given a specific version and a specific target, walks the list through each intermediate version conversion.
A ConvertFrom
function for v2_3.Document
would look something like:
func (t *Document) ConvertFrom(in interface{}) error {
if prior, ok := in.(v2_2.Document); ok {
// do any specific stuff here
}
t.SPDXVersion = "SPDX-2.3"
return nil
}