JCC-CSScheduler/magefiles/mage_output_file.go

728 lines
20 KiB
Go

// +build ignore
package main
import (
"context"
_flag "flag"
_fmt "fmt"
_ioutil "io/ioutil"
_log "log"
"os"
"os/signal"
_filepath "path/filepath"
_sort "sort"
"strconv"
_strings "strings"
"syscall"
_tabwriter "text/tabwriter"
"time"
)
func main() {
// Use local types and functions in order to avoid name conflicts with additional magefiles.
type arguments struct {
Verbose bool // print out log statements
List bool // print out a list of targets
Help bool // print out help for a specific target
Timeout time.Duration // set a timeout to running the targets
Args []string // args contain the non-flag command-line arguments
}
parseBool := func(env string) bool {
val := os.Getenv(env)
if val == "" {
return false
}
b, err := strconv.ParseBool(val)
if err != nil {
_log.Printf("warning: environment variable %s is not a valid bool value: %v", env, val)
return false
}
return b
}
parseDuration := func(env string) time.Duration {
val := os.Getenv(env)
if val == "" {
return 0
}
d, err := time.ParseDuration(val)
if err != nil {
_log.Printf("warning: environment variable %s is not a valid duration value: %v", env, val)
return 0
}
return d
}
args := arguments{}
fs := _flag.FlagSet{}
fs.SetOutput(os.Stdout)
// default flag set with ExitOnError and auto generated PrintDefaults should be sufficient
fs.BoolVar(&args.Verbose, "v", parseBool("MAGEFILE_VERBOSE"), "show verbose output when running targets")
fs.BoolVar(&args.List, "l", parseBool("MAGEFILE_LIST"), "list targets for this binary")
fs.BoolVar(&args.Help, "h", parseBool("MAGEFILE_HELP"), "print out help for a specific target")
fs.DurationVar(&args.Timeout, "t", parseDuration("MAGEFILE_TIMEOUT"), "timeout in duration parsable format (e.g. 5m30s)")
fs.Usage = func() {
_fmt.Fprintf(os.Stdout, `
%s [options] [target]
Commands:
-l list targets in this binary
-h show this help
Options:
-h show description of a target
-t <string>
timeout in duration parsable format (e.g. 5m30s)
-v show verbose output when running targets
`[1:], _filepath.Base(os.Args[0]))
}
if err := fs.Parse(os.Args[1:]); err != nil {
// flag will have printed out an error already.
return
}
args.Args = fs.Args()
if args.Help && len(args.Args) == 0 {
fs.Usage()
return
}
// color is ANSI color type
type color int
// If you add/change/remove any items in this constant,
// you will need to run "stringer -type=color" in this directory again.
// NOTE: Please keep the list in an alphabetical order.
const (
black color = iota
red
green
yellow
blue
magenta
cyan
white
brightblack
brightred
brightgreen
brightyellow
brightblue
brightmagenta
brightcyan
brightwhite
)
// AnsiColor are ANSI color codes for supported terminal colors.
var ansiColor = map[color]string{
black: "\u001b[30m",
red: "\u001b[31m",
green: "\u001b[32m",
yellow: "\u001b[33m",
blue: "\u001b[34m",
magenta: "\u001b[35m",
cyan: "\u001b[36m",
white: "\u001b[37m",
brightblack: "\u001b[30;1m",
brightred: "\u001b[31;1m",
brightgreen: "\u001b[32;1m",
brightyellow: "\u001b[33;1m",
brightblue: "\u001b[34;1m",
brightmagenta: "\u001b[35;1m",
brightcyan: "\u001b[36;1m",
brightwhite: "\u001b[37;1m",
}
const _color_name = "blackredgreenyellowbluemagentacyanwhitebrightblackbrightredbrightgreenbrightyellowbrightbluebrightmagentabrightcyanbrightwhite"
var _color_index = [...]uint8{0, 5, 8, 13, 19, 23, 30, 34, 39, 50, 59, 70, 82, 92, 105, 115, 126}
colorToLowerString := func (i color) string {
if i < 0 || i >= color(len(_color_index)-1) {
return "color(" + strconv.FormatInt(int64(i), 10) + ")"
}
return _color_name[_color_index[i]:_color_index[i+1]]
}
// ansiColorReset is an ANSI color code to reset the terminal color.
const ansiColorReset = "\033[0m"
// defaultTargetAnsiColor is a default ANSI color for colorizing targets.
// It is set to Cyan as an arbitrary color, because it has a neutral meaning
var defaultTargetAnsiColor = ansiColor[cyan]
getAnsiColor := func(color string) (string, bool) {
colorLower := _strings.ToLower(color)
for k, v := range ansiColor {
colorConstLower := colorToLowerString(k)
if colorConstLower == colorLower {
return v, true
}
}
return "", false
}
// Terminals which don't support color:
// TERM=vt100
// TERM=cygwin
// TERM=xterm-mono
var noColorTerms = map[string]bool{
"vt100": false,
"cygwin": false,
"xterm-mono": false,
}
// terminalSupportsColor checks if the current console supports color output
//
// Supported:
// linux, mac, or windows's ConEmu, Cmder, putty, git-bash.exe, pwsh.exe
// Not supported:
// windows cmd.exe, powerShell.exe
terminalSupportsColor := func() bool {
envTerm := os.Getenv("TERM")
if _, ok := noColorTerms[envTerm]; ok {
return false
}
return true
}
// enableColor reports whether the user has requested to enable a color output.
enableColor := func() bool {
b, _ := strconv.ParseBool(os.Getenv("MAGEFILE_ENABLE_COLOR"))
return b
}
// targetColor returns the ANSI color which should be used to colorize targets.
targetColor := func() string {
s, exists := os.LookupEnv("MAGEFILE_TARGET_COLOR")
if exists == true {
if c, ok := getAnsiColor(s); ok == true {
return c
}
}
return defaultTargetAnsiColor
}
// store the color terminal variables, so that the detection isn't repeated for each target
var enableColorValue = enableColor() && terminalSupportsColor()
var targetColorValue = targetColor()
printName := func(str string) string {
if enableColorValue {
return _fmt.Sprintf("%s%s%s", targetColorValue, str, ansiColorReset)
} else {
return str
}
}
list := func() error {
targets := map[string]string{
"amD64": "[配置项]设置编译架构为amd64",
"advisor": "",
"all": "",
"bin": "",
"client": "",
"collector": "",
"confs": "",
"executor": "",
"linux": "[配置项]设置编译平台为linux",
"manager": "",
"scheduleMiddleware": "",
"scripts": "",
"win": "[配置项]设置编译平台为windows",
}
keys := make([]string, 0, len(targets))
for name := range targets {
keys = append(keys, name)
}
_sort.Strings(keys)
_fmt.Println("Targets:")
w := _tabwriter.NewWriter(os.Stdout, 0, 4, 4, ' ', 0)
for _, name := range keys {
_fmt.Fprintf(w, " %v\t%v\n", printName(name), targets[name])
}
err := w.Flush()
return err
}
var ctx context.Context
ctxCancel := func(){}
// by deferring in a closure, we let the cancel function get replaced
// by the getContext function.
defer func() {
ctxCancel()
}()
getContext := func() (context.Context, func()) {
if ctx == nil {
if args.Timeout != 0 {
ctx, ctxCancel = context.WithTimeout(context.Background(), args.Timeout)
} else {
ctx, ctxCancel = context.WithCancel(context.Background())
}
}
return ctx, ctxCancel
}
runTarget := func(logger *_log.Logger, 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
}()
sigCh := make(chan os.Signal, 1)
signal.Notify(sigCh, syscall.SIGINT)
select {
case <-sigCh:
logger.Println("cancelling mage targets, waiting up to 5 seconds for cleanup...")
cancel()
cleanupCh := time.After(5 * time.Second)
select {
// target exited by itself
case err = <-d:
return err
// cleanup timeout exceeded
case <-cleanupCh:
return _fmt.Errorf("cleanup timeout exceeded")
// second SIGINT received
case <-sigCh:
logger.Println("exiting mage")
return _fmt.Errorf("exit forced")
}
case <-ctx.Done():
cancel()
e := ctx.Err()
_fmt.Printf("ctx err: %v\n", e)
return e
case err = <-d:
// we intentionally don't cancel the context here, because
// the next target will need to run with the same context.
return err
}
}
// This is necessary in case there aren't any targets, to avoid an unused
// variable error.
_ = runTarget
handleError := func(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)
}
}
_ = 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)
}
logger := _log.New(os.Stderr, "", 0)
if args.List {
if err := list(); err != nil {
_log.Println(err)
os.Exit(1)
}
return
}
if args.Help {
if len(args.Args) < 1 {
logger.Println("no target specified")
os.Exit(2)
}
switch _strings.ToLower(args.Args[0]) {
case "amd64":
_fmt.Println("[配置项]设置编译架构为amd64")
_fmt.Println()
_fmt.Print("Usage:\n\n\tmage amd64\n\n")
var aliases []string
if len(aliases) > 0 {
_fmt.Printf("Aliases: %s\n\n", _strings.Join(aliases, ", "))
}
return
case "advisor":
_fmt.Print("Usage:\n\n\tmage advisor\n\n")
var aliases []string
if len(aliases) > 0 {
_fmt.Printf("Aliases: %s\n\n", _strings.Join(aliases, ", "))
}
return
case "all":
_fmt.Print("Usage:\n\n\tmage all\n\n")
var aliases []string
if len(aliases) > 0 {
_fmt.Printf("Aliases: %s\n\n", _strings.Join(aliases, ", "))
}
return
case "bin":
_fmt.Print("Usage:\n\n\tmage bin\n\n")
var aliases []string
if len(aliases) > 0 {
_fmt.Printf("Aliases: %s\n\n", _strings.Join(aliases, ", "))
}
return
case "client":
_fmt.Print("Usage:\n\n\tmage client\n\n")
var aliases []string
if len(aliases) > 0 {
_fmt.Printf("Aliases: %s\n\n", _strings.Join(aliases, ", "))
}
return
case "collector":
_fmt.Print("Usage:\n\n\tmage collector\n\n")
var aliases []string
if len(aliases) > 0 {
_fmt.Printf("Aliases: %s\n\n", _strings.Join(aliases, ", "))
}
return
case "confs":
_fmt.Print("Usage:\n\n\tmage confs\n\n")
var aliases []string
if len(aliases) > 0 {
_fmt.Printf("Aliases: %s\n\n", _strings.Join(aliases, ", "))
}
return
case "executor":
_fmt.Print("Usage:\n\n\tmage executor\n\n")
var aliases []string
if len(aliases) > 0 {
_fmt.Printf("Aliases: %s\n\n", _strings.Join(aliases, ", "))
}
return
case "linux":
_fmt.Println("[配置项]设置编译平台为linux")
_fmt.Println()
_fmt.Print("Usage:\n\n\tmage linux\n\n")
var aliases []string
if len(aliases) > 0 {
_fmt.Printf("Aliases: %s\n\n", _strings.Join(aliases, ", "))
}
return
case "manager":
_fmt.Print("Usage:\n\n\tmage manager\n\n")
var aliases []string
if len(aliases) > 0 {
_fmt.Printf("Aliases: %s\n\n", _strings.Join(aliases, ", "))
}
return
case "schedulemiddleware":
_fmt.Print("Usage:\n\n\tmage schedulemiddleware\n\n")
var aliases []string
if len(aliases) > 0 {
_fmt.Printf("Aliases: %s\n\n", _strings.Join(aliases, ", "))
}
return
case "scripts":
_fmt.Print("Usage:\n\n\tmage scripts\n\n")
var aliases []string
if len(aliases) > 0 {
_fmt.Printf("Aliases: %s\n\n", _strings.Join(aliases, ", "))
}
return
case "win":
_fmt.Println("[配置项]设置编译平台为windows")
_fmt.Println()
_fmt.Print("Usage:\n\n\tmage win\n\n")
var aliases []string
if len(aliases) > 0 {
_fmt.Printf("Aliases: %s\n\n", _strings.Join(aliases, ", "))
}
return
default:
logger.Printf("Unknown target: %q\n", args.Args[0])
os.Exit(2)
}
}
if len(args.Args) < 1 {
if err := list(); err != nil {
logger.Println("Error:", err)
os.Exit(1)
}
return
}
for x := 0; x < len(args.Args); {
target := args.Args[x]
x++
// resolve aliases
switch _strings.ToLower(target) {
}
switch _strings.ToLower(target) {
case "amd64":
expected := x + 0
if expected > len(args.Args) {
// note that expected and args at this point include the arg for the target itself
// so we subtract 1 here to show the number of args without the target.
logger.Printf("not enough arguments for target \"AMD64\", expected %v, got %v\n", expected-1, len(args.Args)-1)
os.Exit(2)
}
if args.Verbose {
logger.Println("Running target:", "AMD64")
}
wrapFn := func(ctx context.Context) error {
AMD64()
return nil
}
ret := runTarget(logger, wrapFn)
handleError(logger, ret)
case "advisor":
expected := x + 0
if expected > len(args.Args) {
// note that expected and args at this point include the arg for the target itself
// so we subtract 1 here to show the number of args without the target.
logger.Printf("not enough arguments for target \"Advisor\", expected %v, got %v\n", expected-1, len(args.Args)-1)
os.Exit(2)
}
if args.Verbose {
logger.Println("Running target:", "Advisor")
}
wrapFn := func(ctx context.Context) error {
return Advisor()
}
ret := runTarget(logger, wrapFn)
handleError(logger, ret)
case "all":
expected := x + 0
if expected > len(args.Args) {
// note that expected and args at this point include the arg for the target itself
// so we subtract 1 here to show the number of args without the target.
logger.Printf("not enough arguments for target \"All\", expected %v, got %v\n", expected-1, len(args.Args)-1)
os.Exit(2)
}
if args.Verbose {
logger.Println("Running target:", "All")
}
wrapFn := func(ctx context.Context) error {
return All()
}
ret := runTarget(logger, wrapFn)
handleError(logger, ret)
case "bin":
expected := x + 0
if expected > len(args.Args) {
// note that expected and args at this point include the arg for the target itself
// so we subtract 1 here to show the number of args without the target.
logger.Printf("not enough arguments for target \"Bin\", expected %v, got %v\n", expected-1, len(args.Args)-1)
os.Exit(2)
}
if args.Verbose {
logger.Println("Running target:", "Bin")
}
wrapFn := func(ctx context.Context) error {
return Bin()
}
ret := runTarget(logger, wrapFn)
handleError(logger, ret)
case "client":
expected := x + 0
if expected > len(args.Args) {
// note that expected and args at this point include the arg for the target itself
// so we subtract 1 here to show the number of args without the target.
logger.Printf("not enough arguments for target \"Client\", expected %v, got %v\n", expected-1, len(args.Args)-1)
os.Exit(2)
}
if args.Verbose {
logger.Println("Running target:", "Client")
}
wrapFn := func(ctx context.Context) error {
return Client()
}
ret := runTarget(logger, wrapFn)
handleError(logger, ret)
case "collector":
expected := x + 0
if expected > len(args.Args) {
// note that expected and args at this point include the arg for the target itself
// so we subtract 1 here to show the number of args without the target.
logger.Printf("not enough arguments for target \"Collector\", expected %v, got %v\n", expected-1, len(args.Args)-1)
os.Exit(2)
}
if args.Verbose {
logger.Println("Running target:", "Collector")
}
wrapFn := func(ctx context.Context) error {
return Collector()
}
ret := runTarget(logger, wrapFn)
handleError(logger, ret)
case "confs":
expected := x + 0
if expected > len(args.Args) {
// note that expected and args at this point include the arg for the target itself
// so we subtract 1 here to show the number of args without the target.
logger.Printf("not enough arguments for target \"Confs\", expected %v, got %v\n", expected-1, len(args.Args)-1)
os.Exit(2)
}
if args.Verbose {
logger.Println("Running target:", "Confs")
}
wrapFn := func(ctx context.Context) error {
return Confs()
}
ret := runTarget(logger, wrapFn)
handleError(logger, ret)
case "executor":
expected := x + 0
if expected > len(args.Args) {
// note that expected and args at this point include the arg for the target itself
// so we subtract 1 here to show the number of args without the target.
logger.Printf("not enough arguments for target \"Executor\", expected %v, got %v\n", expected-1, len(args.Args)-1)
os.Exit(2)
}
if args.Verbose {
logger.Println("Running target:", "Executor")
}
wrapFn := func(ctx context.Context) error {
return Executor()
}
ret := runTarget(logger, wrapFn)
handleError(logger, ret)
case "linux":
expected := x + 0
if expected > len(args.Args) {
// note that expected and args at this point include the arg for the target itself
// so we subtract 1 here to show the number of args without the target.
logger.Printf("not enough arguments for target \"Linux\", expected %v, got %v\n", expected-1, len(args.Args)-1)
os.Exit(2)
}
if args.Verbose {
logger.Println("Running target:", "Linux")
}
wrapFn := func(ctx context.Context) error {
Linux()
return nil
}
ret := runTarget(logger, wrapFn)
handleError(logger, ret)
case "manager":
expected := x + 0
if expected > len(args.Args) {
// note that expected and args at this point include the arg for the target itself
// so we subtract 1 here to show the number of args without the target.
logger.Printf("not enough arguments for target \"Manager\", expected %v, got %v\n", expected-1, len(args.Args)-1)
os.Exit(2)
}
if args.Verbose {
logger.Println("Running target:", "Manager")
}
wrapFn := func(ctx context.Context) error {
return Manager()
}
ret := runTarget(logger, wrapFn)
handleError(logger, ret)
case "schedulemiddleware":
expected := x + 0
if expected > len(args.Args) {
// note that expected and args at this point include the arg for the target itself
// so we subtract 1 here to show the number of args without the target.
logger.Printf("not enough arguments for target \"ScheduleMiddleware\", expected %v, got %v\n", expected-1, len(args.Args)-1)
os.Exit(2)
}
if args.Verbose {
logger.Println("Running target:", "ScheduleMiddleware")
}
wrapFn := func(ctx context.Context) error {
return ScheduleMiddleware()
}
ret := runTarget(logger, wrapFn)
handleError(logger, ret)
case "scripts":
expected := x + 0
if expected > len(args.Args) {
// note that expected and args at this point include the arg for the target itself
// so we subtract 1 here to show the number of args without the target.
logger.Printf("not enough arguments for target \"Scripts\", expected %v, got %v\n", expected-1, len(args.Args)-1)
os.Exit(2)
}
if args.Verbose {
logger.Println("Running target:", "Scripts")
}
wrapFn := func(ctx context.Context) error {
return Scripts()
}
ret := runTarget(logger, wrapFn)
handleError(logger, ret)
case "win":
expected := x + 0
if expected > len(args.Args) {
// note that expected and args at this point include the arg for the target itself
// so we subtract 1 here to show the number of args without the target.
logger.Printf("not enough arguments for target \"Win\", expected %v, got %v\n", expected-1, len(args.Args)-1)
os.Exit(2)
}
if args.Verbose {
logger.Println("Running target:", "Win")
}
wrapFn := func(ctx context.Context) error {
Win()
return nil
}
ret := runTarget(logger, wrapFn)
handleError(logger, ret)
default:
logger.Printf("Unknown target specified: %q\n", target)
os.Exit(2)
}
}
}