Skip to content

Commit

Permalink
fix(ensure): packages.Load().Module is nil (#372)
Browse files Browse the repository at this point in the history
Fixes #371 

See golang/go#65816

---------

Signed-off-by: Eliott Bouhana <[email protected]>
Co-authored-by: Romain Marcadier <[email protected]>
  • Loading branch information
eliottness and RomainMuller authored Nov 4, 2024
1 parent 893ac3d commit e8e08e1
Show file tree
Hide file tree
Showing 4 changed files with 40 additions and 23 deletions.
7 changes: 7 additions & 0 deletions internal/ensure/requiredversion.go
Original file line number Diff line number Diff line change
Expand Up @@ -147,6 +147,13 @@ func goModVersion(dir string) (moduleVersion string, moduleDir string, err error
return "", "", errors.Join(errs...)
}

// Shouldn't happen but does when the current working directory is not
// part of a go module's source tree.
// See: https://github.com/golang/go/issues/65816
if pkg.Module == nil {
return "", "", fmt.Errorf("no module information found for package %q", pkg.PkgPath)
}

if pkg.Module.Replace != nil {
// If there's a replace directive, that's what we need to be honoring instead.
return pkg.Module.Replace.Version, pkg.Module.Replace.Dir, nil
Expand Down
17 changes: 17 additions & 0 deletions internal/ensure/requiredversion_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -85,6 +85,23 @@ func TestGoModVersion(t *testing.T) {
}
})
}

t.Run("no-go-mod", func(t *testing.T) {
tmp, err := os.MkdirTemp("", "ensure-*")
require.NoError(t, err, "failed to create temporary directory")
defer os.RemoveAll(tmp)

os.WriteFile(filepath.Join(tmp, "main.go"), []byte(`
package main
func main() {}
`), 0o644)

require.NotPanics(t, func() {
_, _, err = goModVersion(tmp)
})
require.ErrorContains(t, err, "go.mod file not found in current directory")
})
}

func TestRequiredVersion(t *testing.T) {
Expand Down
35 changes: 15 additions & 20 deletions internal/pin/pin.go
Original file line number Diff line number Diff line change
Expand Up @@ -28,19 +28,28 @@ const (
envValTrue = "true"
)

var (
requiredVersionError error // Whether the go.mod version check succeeded
)

// AutoPinOrchestrion automatically runs `pinOrchestrion` if the necessary
// requirements are not already met. It prints messages to `os.Stderr` to inform
// the user about what is going on.
func AutoPinOrchestrion() {
if os.Getenv(envVarCheckedGoMod) == envValTrue {
// A parent process (or ourselves earlier) has already done the check
return
}

requiredVersionError := ensure.RequiredVersion()
if requiredVersionError == nil {
// Nothing to do!
// We're good to go, just make sure we don't do this again
_ = os.Setenv(envVarCheckedGoMod, envValTrue)
return
}

log.Tracef("Failed to detect required version of orchestrion from go.mod: %v\n", requiredVersionError)
if wd, err := os.Getwd(); err == nil {
log.Tracef("Working directory: %q\n", wd)
}
log.Tracef("GOMOD=%s\n", os.Getenv("GOMOD"))

var (
box = lipgloss.NewStyle()
stylePath = lipgloss.NewStyle()
Expand Down Expand Up @@ -87,7 +96,7 @@ func AutoPinOrchestrion() {
os.Exit(1)
}

requiredVersionError = nil
_ = os.Setenv(envVarCheckedGoMod, envValTrue)
}

func PinOrchestrion() error {
Expand Down Expand Up @@ -138,18 +147,4 @@ func PinOrchestrion() error {
}

func init() {
if os.Getenv(envVarCheckedGoMod) == envValTrue {
// A parent process has already done the check for us!!
return
}

if requiredVersionError = ensure.RequiredVersion(); requiredVersionError != nil {
log.Tracef("Failed to detect required version of orchestrion from go.mod: %v\n", requiredVersionError)
if wd, err := os.Getwd(); err == nil {
log.Tracef("Working directory: %q\n", wd)
}
log.Tracef("GOMOD=%s\n", os.Getenv("GOMOD"))
} else {
_ = os.Setenv(envVarCheckedGoMod, envValTrue)
}
}
4 changes: 1 addition & 3 deletions internal/pin/pin_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@
package pin

import (
"errors"
"fmt"
"os"
"path/filepath"
Expand All @@ -25,9 +24,8 @@ func TestPin(t *testing.T) {

require.NoError(t, scaffold(tmp))
require.NoError(t, os.Chdir(tmp))
requiredVersionError = errors.New("test")
AutoPinOrchestrion()
require.NoError(t, requiredVersionError)
require.NotEmpty(t, os.Getenv(envVarCheckedGoMod))

require.FileExists(t, filepath.Join(tmp, orchestrionToolGo))
require.FileExists(t, filepath.Join(tmp, "go.sum"))
Expand Down

0 comments on commit e8e08e1

Please sign in to comment.