Skip to content

Commit edea463

Browse files
authored
refactor alias/default parsing to support imported packages and namespaces (#203)
fixes #192
1 parent bddeffb commit edea463

File tree

7 files changed

+440
-333
lines changed

7 files changed

+440
-333
lines changed

internal/run.go

Lines changed: 114 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,114 @@
1+
package internal
2+
3+
import (
4+
"bytes"
5+
"fmt"
6+
"io/ioutil"
7+
"log"
8+
"os"
9+
"os/exec"
10+
"runtime"
11+
"strings"
12+
)
13+
14+
var debug *log.Logger = log.New(ioutil.Discard, "", 0)
15+
16+
func SetDebug(l *log.Logger) {
17+
debug = l
18+
}
19+
20+
func RunDebug(cmd string, args ...string) error {
21+
env, err := EnvWithCurrentGOOS()
22+
if err != nil {
23+
return err
24+
}
25+
buf := &bytes.Buffer{}
26+
errbuf := &bytes.Buffer{}
27+
debug.Println("running", cmd, strings.Join(args, " "))
28+
c := exec.Command(cmd, args...)
29+
c.Env = env
30+
c.Stderr = errbuf
31+
c.Stdout = buf
32+
if err := c.Run(); err != nil {
33+
debug.Print("error running '", cmd, strings.Join(args, " "), "': ", err, ": ", errbuf)
34+
return err
35+
}
36+
debug.Println(buf)
37+
return nil
38+
}
39+
40+
func OutputDebug(cmd string, args ...string) (string, error) {
41+
env, err := EnvWithCurrentGOOS()
42+
if err != nil {
43+
return "", err
44+
}
45+
buf := &bytes.Buffer{}
46+
errbuf := &bytes.Buffer{}
47+
debug.Println("running", cmd, strings.Join(args, " "))
48+
c := exec.Command(cmd, args...)
49+
c.Env = env
50+
c.Stderr = errbuf
51+
c.Stdout = buf
52+
if err := c.Run(); err != nil {
53+
debug.Print("error running '", cmd, strings.Join(args, " "), "': ", err, ": ", errbuf)
54+
return "", err
55+
}
56+
return strings.TrimSpace(buf.String()), nil
57+
}
58+
59+
// splitEnv takes the results from os.Environ() (a []string of foo=bar values)
60+
// and makes a map[string]string out of it.
61+
func splitEnv(env []string) (map[string]string, error) {
62+
out := map[string]string{}
63+
64+
for _, s := range env {
65+
parts := strings.SplitN(s, "=", 2)
66+
if len(parts) != 2 {
67+
return nil, fmt.Errorf("badly formatted environment variable: %v", s)
68+
}
69+
out[parts[0]] = parts[1]
70+
}
71+
return out, nil
72+
}
73+
74+
// joinEnv converts the given map into a list of foo=bar environment variables,
75+
// such as that outputted by os.Environ().
76+
func joinEnv(env map[string]string) []string {
77+
vals := make([]string, 0, len(env))
78+
for k, v := range env {
79+
vals = append(vals, k+"="+v)
80+
}
81+
return vals
82+
}
83+
84+
// EnvWithCurrentGOOS returns a copy of os.Environ with the GOOS and GOARCH set
85+
// to runtime.GOOS and runtime.GOARCH.
86+
func EnvWithCurrentGOOS() ([]string, error) {
87+
vals, err := splitEnv(os.Environ())
88+
if err != nil {
89+
return nil, err
90+
}
91+
vals["GOOS"] = runtime.GOOS
92+
vals["GOARCH"] = runtime.GOARCH
93+
return joinEnv(vals), nil
94+
}
95+
96+
// EnvWithGOOS retuns the os.Environ() values with GOOS and/or GOARCH either set
97+
// to their runtime value, or the given value if non-empty.
98+
func EnvWithGOOS(goos, goarch string) ([]string, error) {
99+
env, err := splitEnv(os.Environ())
100+
if err != nil {
101+
return nil, err
102+
}
103+
if goos == "" {
104+
env["GOOS"] = runtime.GOOS
105+
} else {
106+
env["GOOS"] = goos
107+
}
108+
if goarch == "" {
109+
env["GOARCH"] = runtime.GOARCH
110+
} else {
111+
env["GOARCH"] = goarch
112+
}
113+
return joinEnv(env), nil
114+
}

mage/import_test.go

Lines changed: 27 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,10 +23,12 @@ func TestMageImportsList(t *testing.T) {
2323
expected := `
2424
Targets:
2525
root
26-
zz:nS:deploy2 deploys stuff.
26+
zz:nS:deploy2* deploys stuff.
2727
zz:buildSubdir2 Builds stuff.
2828
nS:deploy deploys stuff.
2929
buildSubdir Builds stuff.
30+
31+
* default target
3032
`[1:]
3133

3234
if actual != expected {
@@ -97,6 +99,9 @@ func TestMageImportsNamedRoot(t *testing.T) {
9799
if actual != expected {
98100
t.Fatalf("expected: %q got: %q", expected, actual)
99101
}
102+
if stderr := stderr.String(); stderr != "" {
103+
t.Fatal("unexpected output to stderr: ", stderr)
104+
}
100105
}
101106

102107
func TestMageImportsRootImportNS(t *testing.T) {
@@ -140,3 +145,24 @@ func TestMageImportsRootImport(t *testing.T) {
140145
t.Fatalf("expected: %q got: %q", expected, actual)
141146
}
142147
}
148+
149+
func TestMageImportsAliasToNS(t *testing.T) {
150+
stdout := &bytes.Buffer{}
151+
stderr := &bytes.Buffer{}
152+
inv := Invocation{
153+
Dir: "./testdata/mageimport",
154+
Stdout: stdout,
155+
Stderr: stderr,
156+
Args: []string{"nsd2"},
157+
}
158+
159+
code := Invoke(inv)
160+
if code != 0 {
161+
t.Fatalf("expected to exit with code 0, but got %v, stderr:\n%s", code, stderr)
162+
}
163+
actual := stdout.String()
164+
expected := "deploy2\n"
165+
if actual != expected {
166+
t.Fatalf("expected: %q got: %q", expected, actual)
167+
}
168+
}

0 commit comments

Comments
 (0)