dave/vendor/github.com/magefile/mage/mage/template.go
2018-04-12 21:16:38 +02:00

180 lines
3.4 KiB
Go

package mage
// var only for tests
var tpl = `// +build ignore
package main
import (
"context"
"fmt"
"io/ioutil"
"log"
"os"
"strings"
"text/tabwriter"
"time"
)
func main() {
log.SetFlags(0)
if os.Getenv("MAGEFILE_VERBOSE") == "" {
log.SetOutput(ioutil.Discard)
}
logger := log.New(os.Stderr, "", 0)
if os.Getenv("MAGEFILE_LIST") != "" {
if err := list(); err != nil {
log.Println(err)
os.Exit(1)
}
return
}
targets := map[string]bool {
{{range .Funcs}}"{{lower .Name}}": true,
{{end}}
}
var unknown []string
for _, arg := range os.Args[1:] {
if !targets[strings.ToLower(arg)] {
unknown = append(unknown, arg)
}
}
if len(unknown) == 1 {
logger.Println("Unknown target specified:", unknown[0])
os.Exit(2)
}
if len(unknown) > 1 {
logger.Println("Unknown targets specified:", strings.Join(unknown, ", "))
os.Exit(2)
}
if os.Getenv("MAGEFILE_HELP") != "" {
if len(os.Args) < 2 {
logger.Println("no target specified")
os.Exit(1)
}
switch strings.ToLower(os.Args[1]) {
{{range .Funcs}}case "{{lower .Name}}":
fmt.Print("mage {{lower .Name}}:\n\n")
fmt.Println({{printf "%q" .Comment}})
return
{{end}}
default:
logger.Printf("Unknown target: %q\n", os.Args[1])
os.Exit(1)
}
}
if len(os.Args) < 2 {
{{- if .Default}}
{{.DefaultFunc.TemplateString}}
handleError(logger, err)
return
{{- else}}
if err := list(); err != nil {
logger.Println("Error:", err)
os.Exit(1)
}
return
{{- end}}
}
for _, target := range os.Args[1:] {
switch strings.ToLower(target) {
{{range .Funcs }}
case "{{lower .Name}}":
if os.Getenv("MAGEFILE_VERBOSE") != "" {
logger.Println("Running target:", "{{.Name}}")
}
{{.TemplateString}}
handleError(logger, err)
{{- end}}
default:
// should be impossible since we check this above.
logger.Printf("Unknown target: %q\n", os.Args[1])
os.Exit(1)
}
}
}
func list() error {
{{- $default := .Default}}
w := tabwriter.NewWriter(os.Stdout, 0, 4, 4, ' ', 0)
fmt.Println("Targets:")
{{- range .Funcs}}
fmt.Fprintln(w, " {{lowerfirst .Name}}{{if eq .Name $default}}*{{end}}\t" + {{printf "%q" .Synopsis}})
{{- end}}
err := w.Flush()
{{- if .Default}}
if err == nil {
fmt.Println("\n* default target")
}
{{- end}}
return err
}
func handleError(logger *log.Logger, err interface{}) {
if err != nil {
logger.Printf("Error: %v\n", err)
type code interface {
ExitStatus() int
}
if c, ok := err.(code); ok {
os.Exit(c.ExitStatus())
}
os.Exit(1)
}
}
func runTarget(fn func(context.Context) error) interface{} {
var err interface{}
ctx, cancel := getContext()
d := make(chan interface{})
go func() {
defer func() {
err := recover()
d <- err
}()
err := fn(ctx)
d <- err
}()
select {
case <-ctx.Done():
cancel()
e := ctx.Err()
fmt.Printf("ctx err: %v\n", e)
return e
case err = <-d:
cancel()
return err
}
}
var ctx context.Context
var ctxCancel func()
func getContext() (context.Context, func()) {
if ctx != nil {
return ctx, ctxCancel
}
if os.Getenv("MAGEFILE_TIMEOUT") != "" {
timeout, err := time.ParseDuration(os.Getenv("MAGEFILE_TIMEOUT"))
if err != nil {
fmt.Printf("timeout error: %v\n", err)
os.Exit(1)
}
ctx, ctxCancel = context.WithTimeout(context.Background(), timeout)
} else {
ctx = context.Background()
ctxCancel = func() {}
}
return ctx, ctxCancel
}
`