-
Notifications
You must be signed in to change notification settings - Fork 1.6k
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
Go: Use new type for all semantic versions #16460
Conversation
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 largely looks good. Only one important comment, and quite a few questions to check that you've thought about the consequences of some changes.
if v.goEnvVersionFound { | ||
v.goEnvVersion = toolchain.GetEnvGoVersion()[2:] | ||
} | ||
v.goEnvVersion = toolchain.GetEnvGoSemVer() |
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've lost a call to toolchain.IsInstalled()
. Are you sure that that isn't needed? Do we have any tests that cover that case?
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.
Good point! Thanks for spotting this.
toolchain.IsInstalled()
just looks up the path of the go
executable with exec.LookPath
and returns true
or false
depending on whether that succeeded.
Meanwhile, toolchain.GetEnvGoSemVer()
calls toolchain.GetEnvGoVersion()
which invokes go version
. Unlike toolchain.IsInstalled()
this fails if something goes wrong.
So, if go
is not installed, then previously we would have ended up with no goEnvVersion
, but now that would actually terminate the process. So that's definitely a problem.
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.
With respect to tests, I have some work on testing resolve build-environment
specifically. I will try to get that done ASAP as well.
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.
No need to expedite the tests - I just meant that you could add it to your list of things that need testing.
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.
The work on those tests is almost done (I did 99% of it a few weeks ago) and they would have caught this.
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.
Actually those tests wouldn't have caught it either, because there is no nice way to simulate go
not being installed in an integration test. I played around with different approaches, but I am not too keen on any of them. Happy to discuss the options I tried with you.
I instead looked at migrating our old resolve build-environment
tests from when we initially worked on the feature to the internal repo, and have a draft PR for that there now.
I am also wondering if GetEnvGoSemVer
should really use log.Fatalf
or if we could just get away with returning nil
or throwing it at util.NewSemVer
to see if it can make sense of it. We'd have to consider the downstream implications of doing that, though.
For now, I have addressed this specific issue by restoring the check for toolchain.IsInstalled()
// A value indicating whether a version string was found | ||
Found bool | ||
} | ||
type GoVersionInfo = util.SemVer |
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're now combining what used to be two different states: "found a go version, but it was invalid" and "didn't find a go version". Is it okay that we can't distinguish those any more?
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 I checked to see if there were any cases where we cared about that distinction, but I'll check again to make sure.
After the set of most recent changes, some things to check:
|
Context
Throughout the Go autobuilder, we handle semantic versions. The
semver
package has no dedicated type for them and all functions from the package work onstring
values. This makes it difficult to understand where in the code we have something that we know is a valid semantic version and where we might have astring
value that isn't. This is made worse bysemver
requiring all semantic versions to have av
prefix.What this PR does
We introduce a new
SemVer
interface, backed by an implementation based on a private type, which is intended to guarantee that aSemVer
value is a valid semantic version. Since the type is not exported, theNewSemVer
function must be used to constructSemVer
values. This function expects any version string as input and formats it according tosemver
's requirements.All existing code in the autobuilder is modified to use the
SemVer
type whereever we would previously have used functions from thesemver
package.How to review
Best reviewed commit-by-commit.