diff --git a/args.go b/args.go index 1317105..6206a47 100644 --- a/args.go +++ b/args.go @@ -5,6 +5,8 @@ import ( "fmt" "strconv" "time" + + "github.com/spf13/pflag" ) type Arguments struct { @@ -27,68 +29,55 @@ var ( ) func parseArguments(args []string) (*Arguments, error) { - argument := Arguments{ - interval: 2 * time.Second, + var argument Arguments + + var intervalStr string + + flagSet := pflag.NewFlagSet("", pflag.ExitOnError) + 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, "") + flagSet.BoolVarP(&argument.isDiff, "differences", "d", false, "highlight changes between updates") + flagSet.BoolVarP(&argument.isNoTitle, "no-title", "t", false, "turn off header") + flagSet.BoolVarP(&argument.isHelp, "help", "h", false, "display this help and exit") + flagSet.BoolVarP(&argument.isVersion, "version", "v", false, "output version information and exit") + + flagSet.SetInterspersed(false) + + if err := flagSet.Parse(args); err != nil { + return &argument, err } - var err error - -LOOP: - for len(args) != 0 { - arg := args[0] - args = args[1:] - - switch arg { - case "-n", "--interval": - if len(args) == 0 { - return nil, errors.New("-n or --interval require argument") - } - interval := args[0] - args = args[1:] - argument.interval, err = time.ParseDuration(interval) - if err != nil { - seconds, err := strconv.Atoi(interval) - if err != nil { - return nil, err - } - argument.interval = time.Duration(seconds) * time.Second - } - case "-p", "--precise": - argument.isPrecise = true - case "-c", "--clockwork": - argument.isClockwork = true - case "--debug": - argument.isDebug = true - case "-d", "--differences": - argument.isDiff = true - case "-t", "--no-title": - argument.isNoTitle = true - case "-h", "--help": - argument.isHelp = true - case "-v", "--version": - argument.isVersion = true - default: - args = append([]string{arg}, args...) - break LOOP + + 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 len(args) == 0 { - return &argument, NoCommand + if interval < 10 * time.Millisecond { + return nil, IntervalTooSmall } - if argument.interval < 10*time.Millisecond { - return nil, IntervalTooSmall + rest := flagSet.Args() + + if len(rest) == 0 { + return &argument, NoCommand } - argument.cmd = args[0] - argument.args = args[1:] + argument.cmd = rest[0] + argument.args = rest[1:] return &argument, nil } func help() { fmt.Println(` -Viddy well, gopher. viddy well. +Viddy well, gopher. Viddy well. Usage: viddy [options] command @@ -103,3 +92,4 @@ Options: -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 1c6f124..956b952 100644 --- a/args_test.go +++ b/args_test.go @@ -1,9 +1,10 @@ package main import ( - "github.com/stretchr/testify/assert" "testing" "time" + + "github.com/stretchr/testify/assert" ) func Test_parseArguments(t *testing.T) { @@ -35,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"}, diff --git a/go.mod b/go.mod index fef63a8..ec7e83e 100644 --- a/go.mod +++ b/go.mod @@ -7,5 +7,6 @@ require ( github.com/gdamore/tcell/v2 v2.3.3 github.com/rivo/tview v0.0.0-20210624165335-29d673af0ce2 github.com/sergi/go-diff v1.2.0 + github.com/spf13/pflag v1.0.5 github.com/stretchr/testify v1.7.0 ) diff --git a/go.sum b/go.sum index f69878a..9f5657e 100644 --- a/go.sum +++ b/go.sum @@ -30,6 +30,8 @@ github.com/rivo/uniseg v0.2.0 h1:S1pD9weZBuJdFmowNwbpi7BJ8TNftyUImj/0WQi72jY= github.com/rivo/uniseg v0.2.0/go.mod h1:J6wj4VEh+S6ZtnVlnTBMWIodfgj8LQOQFoIToxlJtxc= github.com/sergi/go-diff v1.2.0 h1:XU+rvMAioB0UC3q1MFrIQy4Vo5/4VsRDQQXHsEya6xQ= github.com/sergi/go-diff v1.2.0/go.mod h1:STckp+ISIX8hZLjrqAeVduY0gWCT9IjLuqbuNXdaHfM= +github.com/spf13/pflag v1.0.5 h1:iy+VFUOCP1a+8yFto/drg2CJ5u0yRoB7fZw3DKv/JXA= +github.com/spf13/pflag v1.0.5/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg= github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4= github.com/stretchr/testify v1.7.0 h1:nwc3DEeHmmLAfoZucVR881uASk0Mfjw8xYJ99tb5CcY= diff --git a/main.go b/main.go index 6e37df0..c64f6bb 100644 --- a/main.go +++ b/main.go @@ -9,16 +9,14 @@ var version string func main() { arguments, 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) - } + 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: