未验证 提交 9281087d 编写于 作者: D Davies Liu 提交者: GitHub

re-order the arguments (#274)

上级 b65998e4
......@@ -79,7 +79,7 @@ func main() {
}
}
err := app.Run(os.Args)
err := app.Run(reorderOptions(app, os.Args))
if err != nil {
log.Fatal(err)
}
......@@ -160,6 +160,74 @@ func stringContains(s []string, e string) bool {
return false
}
func isFlag(flags []cli.Flag, option string) (bool, bool) {
if !strings.HasPrefix(option, "-") {
return false, false
}
// --V or -v work the same
option = strings.TrimLeft(option, "-")
for _, flag := range flags {
_, isBool := flag.(*cli.BoolFlag)
for _, name := range flag.Names() {
if option == name || strings.HasPrefix(option, name+"=") {
return true, !isBool && !strings.Contains(option, "=")
}
}
}
return false, false
}
func reorderOptions(app *cli.App, args []string) []string {
var newArgs = []string{args[0]}
var others []string
globalFlags := append(app.Flags, cli.VersionFlag)
for i := 1; i < len(args); i++ {
option := args[i]
if ok, hasValue := isFlag(globalFlags, option); ok {
newArgs = append(newArgs, option)
if hasValue {
i++
newArgs = append(newArgs, args[i])
}
} else {
others = append(others, option)
}
}
// no command
if len(others) == 0 {
return newArgs
}
cmdName := others[0]
var cmd *cli.Command
for _, c := range app.Commands {
if c.Name == cmdName {
cmd = c
}
}
if cmd == nil {
// can't recognize the command, skip it
return append(newArgs, others...)
}
newArgs = append(newArgs, cmdName)
args, others = others[1:], nil
// -h is valid for all the commands
cmdFlags := append(cmd.Flags, cli.HelpFlag)
for i := 0; i < len(args); i++ {
option := args[i]
if ok, hasValue := isFlag(cmdFlags, option); ok {
newArgs = append(newArgs, option)
if hasValue {
i++
newArgs = append(newArgs, args[i])
}
} else {
others = append(others, option)
}
}
return append(newArgs, others...)
}
func setLoggerLevel(c *cli.Context) {
if c.Bool("trace") {
utils.SetLogLevel(logrus.TraceLevel)
......
/*
* JuiceFS, Copyright (C) 2020 Juicedata, Inc.
*
* This program is free software: you can use, redistribute, and/or modify
* it under the terms of the GNU Affero General Public License, version 3
* or later ("AGPL"), as published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package main
import (
"reflect"
"testing"
"github.com/urfave/cli/v2"
)
func TestArgsOrder(t *testing.T) {
var app = &cli.App{
Flags: []cli.Flag{
&cli.BoolFlag{
Name: "verbose",
Aliases: []string{"v"},
},
&cli.Int64Flag{
Name: "key",
Aliases: []string{"k"},
},
},
Commands: []*cli.Command{
{
Name: "cmd",
Flags: []cli.Flag{
&cli.Int64Flag{
Name: "k2",
},
},
},
},
}
var cases = [][]string{
{"test", "cmd", "a", "-k2", "v2", "b", "--v"},
{"test", "--v", "cmd", "-k2", "v2", "a", "b"},
{"test", "cmd", "a", "-k2=v", "--h"},
{"test", "cmd", "-k2=v", "--h", "a"},
}
for i := 0; i < len(cases); i += 2 {
oreded := reorderOptions(app, cases[i])
if !reflect.DeepEqual(cases[i+1], oreded) {
t.Fatalf("expecte %v, but got %v", cases[i+1], oreded)
}
}
}
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册