-
Notifications
You must be signed in to change notification settings - Fork 54
feat: format v3 #249
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: main
Are you sure you want to change the base?
feat: format v3 #249
Conversation
Format v3 uses a map instead of a list for `essential` and deprecates the field `v3-essential` which is only used during the transition from v2 to v3.
|
niemeyer
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.
On a first pass, as detailed below it's surprising and unfortunate that this PR seems to make things significantly worse almost everywhere it touches. This was supposed to be a cleanup PR ideally.
internal/setup/yaml.go
Outdated
| }, | ||
| } | ||
|
|
||
| func parseSliceEssential(yamlPkg *yamlPackage, yamlSlice *yamlSlice, slice *Slice) error { |
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.
This refactoring makes it hard to track what changed compared to the previous implementation. Could we do the extraction in a dedicated function in another PR?
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 thought about that but it is a bit overkill because what happens if we end up changing the approach, then we merged a PR for a refactor that wasn't actually fully needed. As I told you offline, this function needs a bit of love to make it more readable but, if done properly, I think it is easy to see the logic just moved. I will make the changes and we can discuss.
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 think with the latest changes it is easier to see that the diff is the same.
|
As discussed with @niemeyer this week and the previous one, I have changed the PR. The current approach does not need two separate definitions of the same type and instead just changes how the conflicting field is parsed (in > v3 as a map, in v1, v2 as a list). This solution is not as strict as the previous one in regards to The complexity that still exists in the current approach is mainly because we need to produce good error messages and discern between all combinations of format + fields. For the record, Paul and me spent even more time this week thinking about the problem and we also tried:
|
upils
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.
Thanks @letFunny. I have a couple of questions, mainly about tests, but overall it LGTM.
| // 'v3-essential' to the shape expected by the v3 format. | ||
| // skip is set to true when an accurate translation of the test is not | ||
| // possible, for example having duplicates in the list. | ||
| func oldEssentialToV3(c *C, input []byte) (out string, skip bool) { |
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.
[nitpick]: This is a clever solution to avoid duplicating the test cases but given the complexity I find it a bit hard to know what the final input to the test is.
I also wonder if we really need to rerun this many tests when many of them are not testing the essential resolution logic. I guess we are better safe than sorry but I wonder how hard that will be to maintain, especially when adding new tests.
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.
Yeah, related to my earlier comment above. I would like to do the opposite: keep tests compatible with the latest version, and backport it to the old ones. Eventually we can just drop the backports.
Or, alternatively, drop this whole multi-version logic and have just specific tests that cover the difference. Yeah, that's probably better actually.
niemeyer
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.
This is looking good, thank you. A few comments:
internal/setup/setup_test.go
Outdated
| `, | ||
| }, | ||
| relerror: `cannot add slice to itself as essential "mypkg_slice1" in slices/mydir/mypkg.yaml`, | ||
| relerror: `package "mypkg": cannot add slice to itself as essential "mypkg_slice1"`, |
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.
Can we please not fiddle with unrelated messages unless it's clearly a fix or improvement? Some of these messages have been extensively discussed, and this is one example where it is clearly making it significantly worse and out of convention, and this is all a distraction given the main topic of the PR.
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.
My intention was to make them fit with the convention I saw elsewhere in the code as we have slightly different error messages when "decoding" from yaml vs when we are parsing or validating the contents. But you are right here, let's not discuss it as part of this PR.
| runParseReleaseTests(c, v2FormatTests) | ||
|
|
||
| // Run tests for "v3" format. | ||
| v3FormatTests := make([]setupTest, 0, len(setupTests)) |
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.
In a follow up PR, can we please invert this whole logic so that the tests are actually reflecting v3, and then we fiddle backwards instead of forwards? Otherwise we keep adding more work to the tip, which is where we care the most about, and eventually we'll have an issue because we'll want to drop v1.
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.
Discussed offline: agree on testing v3. About the other point of manually testing, it comes a point where the testing code is so complex that we are not sure it is correct anymore. We can rely on the knowledge about the difference between v1, v2 and v3.
| // 'v3-essential' to the shape expected by the v3 format. | ||
| // skip is set to true when an accurate translation of the test is not | ||
| // possible, for example having duplicates in the list. | ||
| func oldEssentialToV3(c *C, input []byte) (out string, skip bool) { |
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.
Yeah, related to my earlier comment above. I would like to do the opposite: keep tests compatible with the latest version, and backport it to the old ones. Eventually we can just drop the backports.
Or, alternatively, drop this whole multi-version logic and have just specific tests that cover the difference. Yeah, that's probably better actually.
internal/setup/yaml.go
Outdated
| } | ||
| } else { | ||
| if yamlPkg.V3Essential != nil { | ||
| return nil, fmt.Errorf("cannot parse package %q: v3-essential is deprecated since format v3", pkgName) |
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.
s/deprecated/obsolete/
Deprecation is typically something that still works but shouldn't be used.
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 have the same error message for v2-archive and default, I will change all of them for consistency.
niemeyer
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.
Comments are above.
upils
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.
Thanks @letFunny !
Format v3 uses a map instead of a list for
essentialand deprecates the fieldv3-essentialwhich is only used during the transition from v2 to v3.