Skip to content

Commit

Permalink
refactor(listGoFiles): remove go list dependency (#440)
Browse files Browse the repository at this point in the history
* refactor(listGoFiles): remove go list dependency
* refactor to use go/build package to cover all usecases
  • Loading branch information
jaredallard committed Sep 15, 2022
1 parent 26cdb5c commit 85ed9df
Show file tree
Hide file tree
Showing 2 changed files with 49 additions and 29 deletions.
8 changes: 4 additions & 4 deletions internal/run.go
Original file line number Diff line number Diff line change
Expand Up @@ -57,9 +57,9 @@ func OutputDebug(cmd string, args ...string) (string, error) {
return strings.TrimSpace(buf.String()), nil
}

// splitEnv takes the results from os.Environ() (a []string of foo=bar values)
// SplitEnv takes the results from os.Environ() (a []string of foo=bar values)
// and makes a map[string]string out of it.
func splitEnv(env []string) (map[string]string, error) {
func SplitEnv(env []string) (map[string]string, error) {
out := map[string]string{}

for _, s := range env {
Expand All @@ -85,7 +85,7 @@ func joinEnv(env map[string]string) []string {
// EnvWithCurrentGOOS returns a copy of os.Environ with the GOOS and GOARCH set
// to runtime.GOOS and runtime.GOARCH.
func EnvWithCurrentGOOS() ([]string, error) {
vals, err := splitEnv(os.Environ())
vals, err := SplitEnv(os.Environ())
if err != nil {
return nil, err
}
Expand All @@ -97,7 +97,7 @@ func EnvWithCurrentGOOS() ([]string, error) {
// EnvWithGOOS retuns the os.Environ() values with GOOS and/or GOARCH either set
// to their runtime value, or the given value if non-empty.
func EnvWithGOOS(goos, goarch string) ([]string, error) {
env, err := splitEnv(os.Environ())
env, err := SplitEnv(os.Environ())
if err != nil {
return nil, err
}
Expand Down
70 changes: 45 additions & 25 deletions mage/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import (
"errors"
"flag"
"fmt"
"go/build"
"io"
"io/ioutil"
"log"
Expand Down Expand Up @@ -468,35 +469,53 @@ type mainfileTemplateData struct {
BinaryName string
}

func listGoFiles(magePath, goCmd, tags string, env []string) ([]string, error) {
args := []string{"list"}
if tags != "" {
args = append(args, fmt.Sprintf("-tags=%s", tags))
}
args = append(args, "-e", "-f", `{{join .GoFiles "||"}}`)
cmd := exec.Command(goCmd, args...)
cmd.Env = env
buf := &bytes.Buffer{}
cmd.Stderr = buf
cmd.Dir = magePath
b, err := cmd.Output()
// listGoFiles returns a list of all .go files in a given directory,
// matching the provided tag
func listGoFiles(magePath, goCmd, tag string, envStr []string) ([]string, error) {
origMagePath := magePath
if !filepath.IsAbs(magePath) {
cwd, err := os.Getwd()
if err != nil {
return nil, fmt.Errorf("can't get current working directory: %v", err)
}
magePath = filepath.Join(cwd, magePath)
}

env, err := internal.SplitEnv(envStr)
if err != nil {
stderr := buf.String()
// if the error is "cannot find module", that can mean that there's no
// non-mage files, which is fine, so ignore it.
if !strings.Contains(stderr, "cannot find module for path") {
if tags == "" {
return nil, fmt.Errorf("failed to list un-tagged gofiles: %v: %s", err, stderr)
}
return nil, fmt.Errorf("failed to list gofiles tagged with %q: %v: %s", tags, err, stderr)
return nil, fmt.Errorf("error parsing environment variables: %v", err)
}

bctx := build.Default
bctx.BuildTags = []string{tag}

if _, ok := env["GOOS"]; ok {
bctx.GOOS = env["GOOS"]
}

if _, ok := env["GOARCH"]; ok {
bctx.GOARCH = env["GOARCH"]
}

pkg, err := bctx.Import(".", magePath, 0)
if err != nil {
if _, ok := err.(*build.NoGoError); ok {
return []string{}, nil
}

// Allow multiple packages in the same directory
if _, ok := err.(*build.MultiplePackageError); !ok {
return nil, fmt.Errorf("failed to parse go source files: %v", err)
}
}
out := strings.TrimSpace(string(b))
list := strings.Split(out, "||")
for i := range list {
list[i] = filepath.Join(magePath, list[i])

goFiles := make([]string, len(pkg.GoFiles))
for i := range pkg.GoFiles {
goFiles[i] = filepath.Join(origMagePath, pkg.GoFiles[i])
}
return list, nil

debug.Printf("found %d go files with build tag %s (files: %v)", len(goFiles), tag, goFiles)
return goFiles, nil
}

// Magefiles returns the list of magefiles in dir.
Expand Down Expand Up @@ -549,6 +568,7 @@ func Magefiles(magePath, goos, goarch, goCmd string, stderr io.Writer, isMagefil
files = append(files, f)
}
}

return files, nil
}

Expand Down

0 comments on commit 85ed9df

Please sign in to comment.