Skip to content
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

refactor(listGoFiles): remove go list dependency #440

Merged
merged 6 commits into from Sep 15, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
8 changes: 4 additions & 4 deletions internal/run.go
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
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