2021-04-19 02:18:37 +00:00
|
|
|
|
package flag
|
|
|
|
|
|
|
|
|
|
import (
|
|
|
|
|
"flag"
|
2021-06-20 13:14:21 +00:00
|
|
|
|
"os"
|
|
|
|
|
"path/filepath"
|
2021-04-19 02:18:37 +00:00
|
|
|
|
|
2021-06-20 13:14:21 +00:00
|
|
|
|
"github.com/qiniu/goc/v2/pkg/config"
|
2021-04-19 02:18:37 +00:00
|
|
|
|
"github.com/qiniu/goc/v2/pkg/log"
|
|
|
|
|
"github.com/spf13/cobra"
|
|
|
|
|
"github.com/spf13/pflag"
|
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
var buildUsage string = `Usage:
|
|
|
|
|
goc build [-o output] [build flags] [packages] [goc flags]
|
|
|
|
|
|
|
|
|
|
The [goc flags] can be placed in anywhere in the command line.
|
|
|
|
|
However, other flags' order are same with the go official command.
|
|
|
|
|
`
|
|
|
|
|
|
2021-06-20 13:14:21 +00:00
|
|
|
|
// BuildCmdArgsParse parse both go flags and goc flags, it rewrite go flags if
|
|
|
|
|
// necessary, and returns all non-flag arguments.
|
2021-05-23 14:23:35 +00:00
|
|
|
|
//
|
|
|
|
|
// 吞下 [packages] 之前所有的 flags.
|
2021-04-19 02:18:37 +00:00
|
|
|
|
func BuildCmdArgsParse(cmd *cobra.Command, args []string) []string {
|
|
|
|
|
// 首先解析 cobra 定义的 flag
|
|
|
|
|
allFlagSets := cmd.Flags()
|
|
|
|
|
// 因为 args 里面含有 go 的 flag,所以需要忽略解析 go flag 的错误
|
|
|
|
|
allFlagSets.Init("GOC", pflag.ContinueOnError)
|
|
|
|
|
allFlagSets.Parse(args)
|
|
|
|
|
|
|
|
|
|
// 重写 help
|
|
|
|
|
helpFlag := allFlagSets.Lookup("help")
|
|
|
|
|
|
|
|
|
|
if helpFlag.Changed {
|
|
|
|
|
printHelp(buildUsage, cmd)
|
|
|
|
|
}
|
|
|
|
|
// 删除 help flag
|
|
|
|
|
args = findAndDelHelpFlag(args)
|
|
|
|
|
|
|
|
|
|
// 必须手动调用
|
|
|
|
|
// 由于关闭了 cobra 的 flag parse,root PersistentPreRun 调用时,log.NewLogger 并没有拿到 debug 值
|
|
|
|
|
log.NewLogger()
|
|
|
|
|
|
|
|
|
|
// 删除 cobra 定义的 flag
|
|
|
|
|
allFlagSets.Visit(func(f *pflag.Flag) {
|
|
|
|
|
args = findAndDelGocFlag(args, f.Name)
|
|
|
|
|
})
|
|
|
|
|
|
|
|
|
|
// 然后解析 go 的 flag
|
|
|
|
|
goFlagSets := flag.NewFlagSet("GO", flag.ContinueOnError)
|
|
|
|
|
addBuildFlags(goFlagSets)
|
|
|
|
|
addOutputFlags(goFlagSets)
|
|
|
|
|
err := goFlagSets.Parse(args)
|
|
|
|
|
if err != nil {
|
|
|
|
|
log.Fatalf("%v", err)
|
|
|
|
|
}
|
|
|
|
|
|
2021-06-20 13:14:21 +00:00
|
|
|
|
// 找出设置的 go flag
|
|
|
|
|
curWd, err := os.Getwd()
|
|
|
|
|
if err != nil {
|
|
|
|
|
log.Fatalf("fail to get current working directory: %v", err)
|
|
|
|
|
}
|
|
|
|
|
config.GocConfig.CurWd = curWd
|
|
|
|
|
flags := make([]string, 0)
|
|
|
|
|
goFlagSets.Visit(func(f *flag.Flag) {
|
|
|
|
|
// 将用户指定 -o 改成绝对目录
|
|
|
|
|
if f.Name == "o" {
|
|
|
|
|
outputDir := f.Value.String()
|
|
|
|
|
outputDir, err := filepath.Abs(outputDir)
|
|
|
|
|
if err != nil {
|
|
|
|
|
log.Fatalf("output flag is not valid: %v", err)
|
|
|
|
|
}
|
|
|
|
|
flags = append(flags, "-o", outputDir)
|
|
|
|
|
} else {
|
|
|
|
|
flags = append(flags, "-"+f.Name, f.Value.String())
|
|
|
|
|
}
|
|
|
|
|
})
|
|
|
|
|
|
|
|
|
|
config.GocConfig.Goflags = flags
|
|
|
|
|
|
2021-04-19 02:18:37 +00:00
|
|
|
|
return goFlagSets.Args()
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func findAndDelGocFlag(a []string, x string) []string {
|
|
|
|
|
new := make([]string, 0, len(a))
|
|
|
|
|
x = "--" + x
|
|
|
|
|
for _, v := range a {
|
|
|
|
|
if v == x {
|
|
|
|
|
continue
|
|
|
|
|
} else {
|
|
|
|
|
new = append(new, v)
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return new
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func findAndDelHelpFlag(a []string) []string {
|
|
|
|
|
new := make([]string, 0, len(a))
|
|
|
|
|
for _, v := range a {
|
|
|
|
|
if v == "--help" || v == "-h" {
|
|
|
|
|
continue
|
|
|
|
|
} else {
|
|
|
|
|
new = append(new, v)
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return new
|
|
|
|
|
}
|