Skip to content

Commit

Permalink
refactor alias/default parsing to support imported packages and names…
Browse files Browse the repository at this point in the history
…paces (#203)

fixes #192
  • Loading branch information
natefinch authored Dec 11, 2018
1 parent bddeffb commit edea463
Show file tree
Hide file tree
Showing 7 changed files with 440 additions and 333 deletions.
114 changes: 114 additions & 0 deletions internal/run.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,114 @@
package internal

import (
"bytes"
"fmt"
"io/ioutil"
"log"
"os"
"os/exec"
"runtime"
"strings"
)

var debug *log.Logger = log.New(ioutil.Discard, "", 0)

func SetDebug(l *log.Logger) {
debug = l
}

func RunDebug(cmd string, args ...string) error {
env, err := EnvWithCurrentGOOS()
if err != nil {
return err
}
buf := &bytes.Buffer{}
errbuf := &bytes.Buffer{}
debug.Println("running", cmd, strings.Join(args, " "))
c := exec.Command(cmd, args...)
c.Env = env
c.Stderr = errbuf
c.Stdout = buf
if err := c.Run(); err != nil {
debug.Print("error running '", cmd, strings.Join(args, " "), "': ", err, ": ", errbuf)
return err
}
debug.Println(buf)
return nil
}

func OutputDebug(cmd string, args ...string) (string, error) {
env, err := EnvWithCurrentGOOS()
if err != nil {
return "", err
}
buf := &bytes.Buffer{}
errbuf := &bytes.Buffer{}
debug.Println("running", cmd, strings.Join(args, " "))
c := exec.Command(cmd, args...)
c.Env = env
c.Stderr = errbuf
c.Stdout = buf
if err := c.Run(); err != nil {
debug.Print("error running '", cmd, strings.Join(args, " "), "': ", err, ": ", errbuf)
return "", err
}
return strings.TrimSpace(buf.String()), nil
}

// 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) {
out := map[string]string{}

for _, s := range env {
parts := strings.SplitN(s, "=", 2)
if len(parts) != 2 {
return nil, fmt.Errorf("badly formatted environment variable: %v", s)
}
out[parts[0]] = parts[1]
}
return out, nil
}

// joinEnv converts the given map into a list of foo=bar environment variables,
// such as that outputted by os.Environ().
func joinEnv(env map[string]string) []string {
vals := make([]string, 0, len(env))
for k, v := range env {
vals = append(vals, k+"="+v)
}
return vals
}

// 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())
if err != nil {
return nil, err
}
vals["GOOS"] = runtime.GOOS
vals["GOARCH"] = runtime.GOARCH
return joinEnv(vals), nil
}

// 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())
if err != nil {
return nil, err
}
if goos == "" {
env["GOOS"] = runtime.GOOS
} else {
env["GOOS"] = goos
}
if goarch == "" {
env["GOARCH"] = runtime.GOARCH
} else {
env["GOARCH"] = goarch
}
return joinEnv(env), nil
}
28 changes: 27 additions & 1 deletion mage/import_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -23,10 +23,12 @@ func TestMageImportsList(t *testing.T) {
expected := `
Targets:
root
zz:nS:deploy2 deploys stuff.
zz:nS:deploy2* deploys stuff.
zz:buildSubdir2 Builds stuff.
nS:deploy deploys stuff.
buildSubdir Builds stuff.
* default target
`[1:]

if actual != expected {
Expand Down Expand Up @@ -97,6 +99,9 @@ func TestMageImportsNamedRoot(t *testing.T) {
if actual != expected {
t.Fatalf("expected: %q got: %q", expected, actual)
}
if stderr := stderr.String(); stderr != "" {
t.Fatal("unexpected output to stderr: ", stderr)
}
}

func TestMageImportsRootImportNS(t *testing.T) {
Expand Down Expand Up @@ -140,3 +145,24 @@ func TestMageImportsRootImport(t *testing.T) {
t.Fatalf("expected: %q got: %q", expected, actual)
}
}

func TestMageImportsAliasToNS(t *testing.T) {
stdout := &bytes.Buffer{}
stderr := &bytes.Buffer{}
inv := Invocation{
Dir: "./testdata/mageimport",
Stdout: stdout,
Stderr: stderr,
Args: []string{"nsd2"},
}

code := Invoke(inv)
if code != 0 {
t.Fatalf("expected to exit with code 0, but got %v, stderr:\n%s", code, stderr)
}
actual := stdout.String()
expected := "deploy2\n"
if actual != expected {
t.Fatalf("expected: %q got: %q", expected, actual)
}
}
Loading

0 comments on commit edea463

Please sign in to comment.