Skip to content

Commit a6d2aa3

Browse files
committed
Go: Use SemVer type in project package
1 parent 010df54 commit a6d2aa3

File tree

5 files changed

+29
-41
lines changed

5 files changed

+29
-41
lines changed

go/extractor/autobuilder/build-environment.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -274,7 +274,7 @@ func IdentifyEnvironment() {
274274

275275
// Find the greatest Go version required by any of the workspaces.
276276
greatestGoVersion := project.RequiredGoVersion(&workspaces)
277-
v.goModVersion, v.goModVersionFound = greatestGoVersion.Version, greatestGoVersion.Found
277+
v.goModVersion, v.goModVersionFound = greatestGoVersion.String(), greatestGoVersion != nil
278278

279279
// Find which, if any, version of Go is installed on the system already.
280280
v.goEnvVersionFound = toolchain.IsInstalled()

go/extractor/cli/go-autobuilder/BUILD.bazel

Lines changed: 0 additions & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

go/extractor/cli/go-autobuilder/go-autobuilder.go

Lines changed: 6 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -10,8 +10,6 @@ import (
1010
"runtime"
1111
"strings"
1212

13-
"golang.org/x/mod/semver"
14-
1513
"github.com/github/codeql-go/extractor/autobuilder"
1614
"github.com/github/codeql-go/extractor/diagnostics"
1715
"github.com/github/codeql-go/extractor/project"
@@ -339,7 +337,7 @@ func buildWithoutCustomCommands(modMode project.ModMode) bool {
339337
}
340338

341339
shouldInstallDependencies = true
342-
} else if toolchain.DepErrors("./...", modMode.ArgsForGoVersion(toolchain.GetEnvGoSemVer().String())...) {
340+
} else if toolchain.DepErrors("./...", modMode.ArgsForGoVersion(toolchain.GetEnvGoSemVer())...) {
343341
log.Printf("Dependencies are still not resolving after executing %d build script(s), continuing to install dependencies in the normal way.\n", scriptCount)
344342

345343
shouldInstallDependencies = true
@@ -453,7 +451,7 @@ func extract(workspace project.GoWorkspace) bool {
453451

454452
extractorArgs := []string{}
455453
if workspace.DepMode == project.GoGetWithModules {
456-
extractorArgs = append(extractorArgs, workspace.ModMode.ArgsForGoVersion(toolchain.GetEnvGoSemVer().String())...)
454+
extractorArgs = append(extractorArgs, workspace.ModMode.ArgsForGoVersion(toolchain.GetEnvGoSemVer())...)
457455
}
458456

459457
if len(workspace.Modules) == 0 {
@@ -544,12 +542,12 @@ func installDependenciesAndBuild() {
544542
// This diagnostic is not required if the system Go version is 1.21 or greater, since the
545543
// Go tooling should install required Go versions as needed.
546544
v1_21 := util.NewSemVer("v1.21.0")
547-
if toolchain.GetEnvGoSemVer().IsOlderThan(v1_21) && greatestGoVersion.Found && semver.Compare("v"+greatestGoVersion.Version, toolchain.GetEnvGoSemVer().String()) > 0 {
548-
diagnostics.EmitNewerGoVersionNeeded(toolchain.GetEnvGoSemVer().String(), "v"+greatestGoVersion.Version)
545+
if toolchain.GetEnvGoSemVer().IsOlderThan(v1_21) && greatestGoVersion != nil && greatestGoVersion.IsNewerThan(toolchain.GetEnvGoSemVer()) {
546+
diagnostics.EmitNewerGoVersionNeeded(toolchain.GetEnvGoSemVer().String(), greatestGoVersion.String())
549547
if val, _ := os.LookupEnv("GITHUB_ACTIONS"); val == "true" {
550548
log.Printf(
551549
"A go.mod file requires version %s of Go, but version %s is installed. Consider adding an actions/setup-go step to your workflow.\n",
552-
"v"+greatestGoVersion.Version,
550+
greatestGoVersion,
553551
toolchain.GetEnvGoSemVer())
554552
}
555553
}
@@ -561,7 +559,7 @@ func installDependenciesAndBuild() {
561559
for i, workspace := range workspaces {
562560
goVersionInfo := workspace.RequiredGoVersion()
563561

564-
fixGoVendorIssues(&workspace, goVersionInfo.Found)
562+
fixGoVendorIssues(&workspace, goVersionInfo != nil)
565563

566564
tryUpdateGoModAndGoSum(workspace)
567565

go/extractor/project/BUILD.bazel

Lines changed: 0 additions & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

go/extractor/project/project.go

Lines changed: 22 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,6 @@ import (
1313
"github.com/github/codeql-go/extractor/toolchain"
1414
"github.com/github/codeql-go/extractor/util"
1515
"golang.org/x/mod/modfile"
16-
"golang.org/x/mod/semver"
1716
)
1817

1918
// DependencyInstallerMode is an enum describing how dependencies should be installed
@@ -49,53 +48,47 @@ type GoWorkspace struct {
4948
}
5049

5150
// Represents a nullable version string.
52-
type GoVersionInfo struct {
53-
// The version string, if any
54-
Version string
55-
// A value indicating whether a version string was found
56-
Found bool
57-
}
51+
type GoVersionInfo = util.SemVer
5852

5953
// Determines the version of Go that is required by this workspace. This is, in order of preference:
6054
// 1. The Go version specified in the `go.work` file, if any.
6155
// 2. The greatest Go version specified in any `go.mod` file, if any.
62-
func (workspace *GoWorkspace) RequiredGoVersion() GoVersionInfo {
56+
func (workspace *GoWorkspace) RequiredGoVersion() util.SemVer {
6357
if workspace.WorkspaceFile != nil && workspace.WorkspaceFile.Go != nil {
6458
// If we have parsed a `go.work` file, return the version number from it.
65-
return GoVersionInfo{Version: workspace.WorkspaceFile.Go.Version, Found: true}
59+
return util.NewSemVer(workspace.WorkspaceFile.Go.Version)
6660
} else if workspace.Modules != nil && len(workspace.Modules) > 0 {
6761
// Otherwise, if we have `go.work` files, find the greatest Go version in those.
68-
var greatestVersion string = ""
62+
var greatestVersion util.SemVer = nil
6963
for _, module := range workspace.Modules {
7064
if module.Module != nil && module.Module.Go != nil {
7165
// If we have parsed the file, retrieve the version number we have already obtained.
72-
if greatestVersion == "" || semver.Compare("v"+module.Module.Go.Version, "v"+greatestVersion) > 0 {
73-
greatestVersion = module.Module.Go.Version
66+
modVersion := util.NewSemVer(module.Module.Go.Version)
67+
if greatestVersion == nil || modVersion.IsNewerThan(greatestVersion) {
68+
greatestVersion = modVersion
7469
}
7570
} else {
7671
modVersion := tryReadGoDirective(module.Path)
77-
if modVersion.Found && (greatestVersion == "" || semver.Compare("v"+modVersion.Version, "v"+greatestVersion) > 0) {
78-
greatestVersion = modVersion.Version
72+
if modVersion != nil && (greatestVersion == nil || modVersion.IsNewerThan(greatestVersion)) {
73+
greatestVersion = modVersion
7974
}
8075
}
8176
}
8277

8378
// If we have found some version, return it.
84-
if greatestVersion != "" {
85-
return GoVersionInfo{Version: greatestVersion, Found: true}
86-
}
79+
return greatestVersion
8780
}
8881

89-
return GoVersionInfo{Version: "", Found: false}
82+
return nil
9083
}
9184

9285
// Finds the greatest Go version required by any of the given `workspaces`.
9386
// Returns a `GoVersionInfo` value with `Found: false` if no version information is available.
94-
func RequiredGoVersion(workspaces *[]GoWorkspace) GoVersionInfo {
95-
greatestGoVersion := GoVersionInfo{Version: "", Found: false}
87+
func RequiredGoVersion(workspaces *[]GoWorkspace) util.SemVer {
88+
var greatestGoVersion util.SemVer = nil
9689
for _, workspace := range *workspaces {
9790
goVersionInfo := workspace.RequiredGoVersion()
98-
if goVersionInfo.Found && (!greatestGoVersion.Found || semver.Compare("v"+goVersionInfo.Version, "v"+greatestGoVersion.Version) > 0) {
91+
if goVersionInfo != nil && (greatestGoVersion == nil || goVersionInfo.IsNewerThan(greatestGoVersion)) {
9992
greatestGoVersion = goVersionInfo
10093
}
10194
}
@@ -182,8 +175,9 @@ var toolchainVersionRe *regexp.Regexp = regexp.MustCompile(`(?m)^([0-9]+\.[0-9]+
182175
// Returns true if the `go.mod` file specifies a Go language version, that version is `1.21` or greater, and
183176
// there is no `toolchain` directive, and the Go language version is not a valid toolchain version.
184177
func hasInvalidToolchainVersion(modFile *modfile.File) bool {
178+
v1_21 := util.NewSemVer("v1.21.0")
185179
return modFile.Toolchain == nil && modFile.Go != nil &&
186-
!toolchainVersionRe.Match([]byte(modFile.Go.Version)) && semver.Compare("v"+modFile.Go.Version, "v1.21.0") >= 0
180+
!toolchainVersionRe.Match([]byte(modFile.Go.Version)) && util.NewSemVer(modFile.Go.Version).IsAtLeast(v1_21)
187181
}
188182

189183
// Given a list of `go.mod` file paths, try to parse them all. The resulting array of `GoModule` objects
@@ -537,17 +531,15 @@ const (
537531

538532
// argsForGoVersion returns the arguments to pass to the Go compiler for the given `ModMode` and
539533
// Go version
540-
func (m ModMode) ArgsForGoVersion(version string) []string {
534+
func (m ModMode) ArgsForGoVersion(version util.SemVer) []string {
541535
switch m {
542536
case ModUnset:
543537
return []string{}
544538
case ModReadonly:
545539
return []string{"-mod=readonly"}
546540
case ModMod:
547-
if !semver.IsValid(version) {
548-
log.Fatalf("Invalid Go semver: '%s'", version)
549-
}
550-
if semver.Compare(version, "v1.14") < 0 {
541+
v1_14 := util.NewSemVer("v1.14")
542+
if version.IsOlderThan(v1_14) {
551543
return []string{} // -mod=mod is the default behaviour for go <= 1.13, and is not accepted as an argument
552544
} else {
553545
return []string{"-mod=mod"}
@@ -574,7 +566,7 @@ func getModMode(depMode DependencyInstallerMode, baseDir string) ModMode {
574566

575567
// Tries to open `go.mod` and read a go directive, returning the version and whether it was found.
576568
// The version string is returned in the "1.2.3" format.
577-
func tryReadGoDirective(path string) GoVersionInfo {
569+
func tryReadGoDirective(path string) util.SemVer {
578570
versionRe := regexp.MustCompile(`(?m)^go[ \t\r]+([0-9]+\.[0-9]+(\.[0-9]+)?)`)
579571
goMod, err := os.ReadFile(path)
580572
if err != nil {
@@ -583,9 +575,9 @@ func tryReadGoDirective(path string) GoVersionInfo {
583575
matches := versionRe.FindSubmatch(goMod)
584576
if matches != nil {
585577
if len(matches) > 1 {
586-
return GoVersionInfo{string(matches[1]), true}
578+
return util.NewSemVer(string(matches[1]))
587579
}
588580
}
589581
}
590-
return GoVersionInfo{"", false}
582+
return nil
591583
}

0 commit comments

Comments
 (0)