Skip to content

Go: Add go-autobuilder --identify-environment #12957

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

Merged
merged 15 commits into from
May 3, 2023

Conversation

owen-mc
Copy link
Contributor

@owen-mc owen-mc commented Apr 27, 2023

Step 1 of https://github.com/github/codeql-go-team/issues/329.

Integration tests look tricky. I will instead use unit tests in ql/go/extractor/cli/go-autobuilder/go-autobuilder_test.go and some manual end-to-end testing. Once other languages have also implemented this flag we can set up everything up to make integration testing possible.

@owen-mc owen-mc requested a review from a team as a code owner April 27, 2023 14:59
@github-actions github-actions bot added the Go label Apr 27, 2023
@owen-mc owen-mc marked this pull request as draft April 27, 2023 14:59
@owen-mc owen-mc force-pushed the go/autobuilder-identify-environment branch from 44396a8 to c02edb0 Compare May 2, 2023 13:15
@owen-mc owen-mc marked this pull request as ready for review May 2, 2023 13:16
@owen-mc owen-mc force-pushed the go/autobuilder-identify-environment branch from c02edb0 to 0c6efb8 Compare May 2, 2023 16:17
Comment on lines 25 to 26
`%s is a wrapper script that installs dependencies and calls the extractor, or if '--identify-environment'
is passed then it produces a file 'environment.json' which specifies what go version is needed.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It would probably be nice to format this across multiple lines, something like:

%s is a wrapper script that installs dependencies and calls the extractor

Options:
--identify-environment   If this flag is specified, then ...

content = `{ "include": [ { "go": { "version": "` + version + `" } } ] }`
}

targetFile, err := os.Create("environment.json")
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

As we have talked about, this should probably be a value from an environment variable (with this as a fallback).


func EmitUnsupportedVersionGoMod(msg string) {
emitDiagnostic(
"go/identify-environment/unsupported-version-in-go-mod",
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I wonder if this should still be go/autobuilder/.. for these diagnostics, since that part of the identifier refers to the tool rather than a particular sub-command.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I've changed it so that go/autobuilder/env- is a common prefix to all the these new diagnostics.

func EmitVersionGoModNotHigherVersionEnvironment(msg string) {
emitDiagnostic(
"go/identify-environment/version-go-mod-not-higher-than-go-env",
"The Go version in `go.mod` file is not higher than the Go version in environment",
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

"not higher" is strange wording. Should this be "lower"? Or "not equal to or greater than"?

if v.goDirectiveFound && outsideSupportedRange(v.goModVersion) {
msg = "The version of Go found in the `go.mod` file (" + v.goModVersion +
") is outside of the supported range (" + minGoVersion + "-" + maxGoVersion + ")."
version = ""
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Would it be better to return nil instead of an empty string if these functions cannot determine which go version to install? And have msg as an error rather than a string?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I like the nil idea but strings can't be nil in go. I have effectively given the empty string a special meaning, and I've been careful to always assign a value to version even when I could leave it as the default value so that it's easier to spot any places where it hasn't been considered.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't think msg should be an error because then people will assume that it's only non-nil if something has gone wrong, whereas it's actually non-nil on every path through the code.

Comment on lines +768 to +781
func getVersionToInstall(v versionInfo) (msg, version string) {
msg, version = checkForUnsupportedVersions(v)
if msg != "" {
return msg, version
}

msg, version = checkForVersionsNotFound(v)
if msg != "" {
return msg, version
}

msg, version = compareVersions(v)
return msg, version
}
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The logic implemented in these functions is relatively complicated and tricky to follow / it is easy to miss corner cases. Once tests are added, those will increase confidence, but it would also be good to add documentation and more explicitly document assumptions/invariants throughout these functions.

Copy link
Contributor Author

@owen-mc owen-mc May 3, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'll add docstrings to the functions. (With a lot of help from Copilot 😄 .)

func checkForVersionsNotFound(v versionInfo) (msg, version string) {
if !v.goInstallationFound && !v.goDirectiveFound {
msg = "No version of Go installed and no `go.mod` file found. Writing an " +
"`environment.json` file specifying the maximum supported version of Go (" +
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

For all the occurrences of environment.json here, you can probably use a generic name here.

Copy link
Member

@mbg mbg left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks good to me for now

@owen-mc owen-mc merged commit 4de4f35 into github:main May 3, 2023
@owen-mc owen-mc deleted the go/autobuilder-identify-environment branch May 3, 2023 15:01
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants