From 655b716f74518076d89cb5892eb44e0c28324482 Mon Sep 17 00:00:00 2001 From: Takumasa Sakao Date: Sat, 21 Aug 2021 09:16:19 +0900 Subject: [PATCH] Disable pflags interspersed --- args.go | 69 +++++++++++++++++++++++++++++++++++----------------- args_test.go | 35 +++++++++++++++++++++++++- main.go | 21 ++++++++-------- 3 files changed, 91 insertions(+), 34 deletions(-) diff --git a/args.go b/args.go index 43e0b00..6206a47 100644 --- a/args.go +++ b/args.go @@ -2,7 +2,8 @@ package main import ( "errors" - "strings" + "fmt" + "strconv" "time" "github.com/spf13/pflag" @@ -27,11 +28,13 @@ var ( IntervalTooSmall = errors.New("interval too small") ) -func parseArguments(args []string) (*Arguments, func(), error) { +func parseArguments(args []string) (*Arguments, error) { var argument Arguments + var intervalStr string + flagSet := pflag.NewFlagSet("", pflag.ExitOnError) - flagSet.DurationVarP(&argument.interval, "interval", "n", 2*time.Second, "seconds to wait between updates") + flagSet.StringVarP(&intervalStr, "interval", "n", "2s", "seconds to wait between updates") flagSet.BoolVarP(&argument.isPrecise, "precise", "p", false, "attempt run command in precise intervals") flagSet.BoolVarP(&argument.isClockwork, "clockwork", "c", false, "run command in precise intervals forcibly") flagSet.BoolVar(&argument.isDebug, "debug", false, "") @@ -40,31 +43,53 @@ func parseArguments(args []string) (*Arguments, func(), error) { flagSet.BoolVarP(&argument.isHelp, "help", "h", false, "display this help and exit") flagSet.BoolVarP(&argument.isVersion, "version", "v", false, "output version information and exit") - if len(args) == 0 { - return &argument, flagSet.Usage, NoCommand + flagSet.SetInterspersed(false) + + if err := flagSet.Parse(args); err != nil { + return &argument, err } - for i := 0; i < len(args); i++ { - if strings.HasPrefix(args[i], "-") { - continue + interval, err := time.ParseDuration(intervalStr) + if err != nil { + intervalFloat, err := strconv.ParseFloat(intervalStr, 64) + if err != nil { + return &argument, err } + interval = time.Duration(intervalFloat * float64(time.Second)) + } + argument.interval = interval - if i > 0 { - prev := args[i-1] - switch prev { - case "--interval", "-n": - continue - } - } + if interval < 10 * time.Millisecond { + return nil, IntervalTooSmall + } - argument.cmd = args[i] - if i+1 <= len(args) { - argument.args = args[i+1:] - } + rest := flagSet.Args() - _ = flagSet.Parse(args[:i]) - break + if len(rest) == 0 { + return &argument, NoCommand } - return &argument, flagSet.Usage, nil + argument.cmd = rest[0] + argument.args = rest[1:] + + return &argument, nil } + +func help() { + fmt.Println(` +Viddy well, gopher. Viddy well. + +Usage: + viddy [options] command + +Options: + -d, --differences highlight changes between updates + -n, --interval seconds to wait between updates (default "2s") + -p, --precise attempt run command in precise intervals + -c, --clockwork run command in precise intervals forcibly + -t, --no-title turn off header + + -h, --help display this help and exit + -v, --version output version information and exit`) +} + diff --git a/args_test.go b/args_test.go index 9133eff..956b952 100644 --- a/args_test.go +++ b/args_test.go @@ -36,6 +36,39 @@ func Test_parseArguments(t *testing.T) { args: []string{"-l"}, }, }, + { + name: "-n1 tail -n 1 hoge", + args: []string{"-n1", "tail", "-n", "1", "hoge"}, + exp: &Arguments{ + interval: 1 * time.Second, + isPrecise: false, + isClockwork: false, + cmd: "tail", + args: []string{"-n", "1", "hoge"}, + }, + }, + { + name: "tail -n 1 hoge", + args: []string{"tail", "-n", "1", "hoge"}, + exp: &Arguments{ + interval: 2 * time.Second, + isPrecise: false, + isClockwork: false, + cmd: "tail", + args: []string{"-n", "1", "hoge"}, + }, + }, + { + name: "-n 0.5 ls", + args: []string{"-n", "0.5", "ls"}, + exp: &Arguments{ + interval: 500 * time.Millisecond, + isPrecise: false, + isClockwork: false, + cmd: "ls", + args: []string{}, + }, + }, { name: "invalid interval", args: []string{"-n", "1ms", "ls", "-l"}, @@ -47,7 +80,7 @@ func Test_parseArguments(t *testing.T) { for _, tt := range testCases { tt := tt t.Run(tt.name, func(t *testing.T) { - argument, _, err := parseArguments(tt.args) + argument, err := parseArguments(tt.args) assert.Equal(t, tt.expErr, err) assert.Equal(t, tt.exp, argument) }) diff --git a/main.go b/main.go index 9430894..c64f6bb 100644 --- a/main.go +++ b/main.go @@ -8,17 +8,15 @@ import ( var version string func main() { - arguments, help, err := parseArguments(os.Args[1:]) - if err == NoCommand { - if arguments.isHelp { - help() - os.Exit(0) - } - - if arguments.isVersion { - fmt.Printf("viddy version: %s\n", version) - os.Exit(0) - } + arguments, err := parseArguments(os.Args[1:]) + if arguments.isHelp { + help() + os.Exit(0) + } + + if arguments.isVersion { + fmt.Printf("viddy version: %s\n", version) + os.Exit(0) } if err != nil { @@ -26,6 +24,7 @@ func main() { os.Exit(1) } + var mode ViddyIntervalMode switch { case arguments.isPrecise: