Repository: magefile/mage
Pull request #300 (2020-04-15 03:42:05)

Ensure MAGEFILE_VERBOSE set in compiled magefile
When using `mage -compile=foo`, ensure that passing
`-v` to the produced binary sets MAGEFILE_VERBOSE.
This is necessary for `mg.Verbose()` to return the
correct value.

Fixes https://github.com/magefile/mage/issues/248

axw: I've reverted the change to TestVerbose, and introduced a new target and test.

Patch:
diff --git a/mage/template.go b/mage/template.go
index 6bc6e48..f361ab8 100644
--- a/mage/template.go
+++ b/mage/template.go
@@ -186,6 +186,13 @@ Options:
 	}
 	_ = handleError
 
+	// Set MAGEFILE_VERBOSE so mg.Verbose() reflects the flag value.
+	if args.Verbose {
+		os.Setenv("MAGEFILE_VERBOSE", "1")
+	} else {
+		os.Setenv("MAGEFILE_VERBOSE", "0")
+	}
+
 	log.SetFlags(0)
 	if !args.Verbose {
 		log.SetOutput(ioutil.Discard)


Test patch:
diff --git a/mage/main_test.go b/mage/main_test.go
index aac8888..defd509 100644
--- a/mage/main_test.go
+++ b/mage/main_test.go
@@ -1143,6 +1143,69 @@ func TestCompiledEnvironmentVars(t *testing.T) {
 	}
 }
 
+func TestCompiledVerboseFlag(t *testing.T) {
+	stderr := &bytes.Buffer{}
+	stdout := &bytes.Buffer{}
+	dir := "./testdata/compiled"
+	compileDir, err := ioutil.TempDir(dir, "")
+	if err != nil {
+		t.Fatal(err)
+	}
+	filename := filepath.Join(compileDir, "mage_out")
+	// The CompileOut directory is relative to the
+	// invocation directory, so chop off the invocation dir.
+	outName := "./" + filename[len(dir)-1:]
+	defer os.RemoveAll(compileDir)
+	inv := Invocation{
+		Dir:        dir,
+		Stdout:     stdout,
+		Stderr:     stderr,
+		CompileOut: outName,
+	}
+	code := Invoke(inv)
+	if code != 0 {
+		t.Errorf("expected to exit with code 0, but got %v, stderr: %s", code, stderr)
+	}
+
+	run := func(verboseEnv string, args ...string) string {
+		var stdout, stderr bytes.Buffer
+		args = append(args, "printverboseflag")
+		cmd := exec.Command(filename, args...)
+		cmd.Env = []string{verboseEnv}
+		cmd.Stderr = &stderr
+		cmd.Stdout = &stdout
+		if err := cmd.Run(); err != nil {
+			t.Fatalf("running '%s %s' with env %s failed with: %v\nstdout: %s\nstderr: %s",
+				filename, strings.Join(args, " "), verboseEnv, err, stdout.String(), stderr.String())
+		}
+		return strings.TrimSpace(stdout.String())
+	}
+
+	got := run("MAGEFILE_VERBOSE=false")
+	want := "mg.Verbose()==false"
+	if got != want {
+		t.Errorf("got %q, expected %q", got, want)
+	}
+
+	got = run("MAGEFILE_VERBOSE=false", "-v")
+	want = "mg.Verbose()==true"
+	if got != want {
+		t.Errorf("got %q, expected %q", got, want)
+	}
+
+	got = run("MAGEFILE_VERBOSE=true")
+	want = "mg.Verbose()==true"
+	if got != want {
+		t.Errorf("got %q, expected %q", got, want)
+	}
+
+	got = run("MAGEFILE_VERBOSE=true", "-v=false")
+	want = "mg.Verbose()==false"
+	if got != want {
+		t.Errorf("got %q, expected %q", got, want)
+	}
+}
+
 func TestClean(t *testing.T) {
 	if err := os.RemoveAll(mg.CacheDir()); err != nil {
 		t.Error("error removing cache dir:", err)
diff --git a/mage/testdata/compiled/custom.go b/mage/testdata/compiled/custom.go
index 1a0f4c3..41aaabe 100644
--- a/mage/testdata/compiled/custom.go
+++ b/mage/testdata/compiled/custom.go
@@ -4,6 +4,7 @@
 package main
 
 import (
+	"fmt"
 	"log"
 	"time"
 
@@ -17,6 +18,11 @@ func TestVerbose() {
 	log.Println("hi!")
 }
 
+// PrintVerboseFlag prints the value of mg.Verbose() to stdout.
+func PrintVerboseFlag() {
+	fmt.Printf("mg.Verbose()==%v", mg.Verbose())
+}
+
 // This is the synopsis for Deploy. This part shouldn't show up.
 func Deploy() {
 	mg.Deps(f)