From 5d482f65aa18320fe002d7b32fb93363b2bfcbc0 Mon Sep 17 00:00:00 2001 From: John Kerl Date: Thu, 1 Apr 2021 00:46:30 +0100 Subject: [PATCH] Getoptish feature: let "-xyz" -> "-x -y -z" in the CLI while leaving "--xyz" as-is (#467) * Getoptish feature: let "-xyz" -> "-x -y -z" in the CLI while leaving "--xyz" as-is * comment-neaten --- go/src/auxents/regtest/entry.go | 6 ---- go/src/entrypoint/entrypoint.go | 10 +++++++ go/src/lib/getoptify.go | 27 +++++++++++++++++ go/src/transformers/sort.go | 52 ++++++++++++++++++++++++++++++--- go/todo.txt | 7 ++--- 5 files changed, 88 insertions(+), 14 deletions(-) create mode 100644 go/src/lib/getoptify.go diff --git a/go/src/auxents/regtest/entry.go b/go/src/auxents/regtest/entry.go index d11c3f073..23bd2a038 100644 --- a/go/src/auxents/regtest/entry.go +++ b/go/src/auxents/regtest/entry.go @@ -64,12 +64,6 @@ func RegTestMain(args []string) int { } else if arg == "-v" { verbosityLevel++ - } else if arg == "-vv" { - verbosityLevel += 2 - } else if arg == "-vvv" { - verbosityLevel += 3 - } else if arg == "-vvvv" { - verbosityLevel += 4 } else { RegTestUsage(verbName, os.Stderr, 1) diff --git a/go/src/entrypoint/entrypoint.go b/go/src/entrypoint/entrypoint.go index b608471bf..711bf55fe 100644 --- a/go/src/entrypoint/entrypoint.go +++ b/go/src/entrypoint/entrypoint.go @@ -8,6 +8,7 @@ import ( "miller/src/auxents" "miller/src/cli" + "miller/src/lib" "miller/src/stream" ) @@ -20,6 +21,15 @@ func Main() { // as on Linux/Unix/MacOS. os.Args = platform.GetArgs() + // Expand "-xyz" into "-x -y -z" while leaving "--xyz" intact. This is a + // keystroke-saver for the user. + // + // This is OK to do globally here since Miller is quite consistent (in + // main, verbs, and auxents) that multi-character options start with two + // dashes, e.g. "--csv". (The sole exception is the sort verb's -nf/-nr + // which are handled specially there.) + os.Args = lib.Getoptify(os.Args) + // 'mlr repl' or 'mlr lecat' or any other non-miller-per-se toolery which // is delivered (for convenience) within the mlr executable. If argv[1] is // found then this function will not return. diff --git a/go/src/lib/getoptify.go b/go/src/lib/getoptify.go new file mode 100644 index 000000000..7eae89611 --- /dev/null +++ b/go/src/lib/getoptify.go @@ -0,0 +1,27 @@ +package lib + +import ( + "regexp" +) + +// Getoptify expands "-xyz" into "-x -y -z" while leaving "--xyz" intact. This +// is a keystroke-saver for the user. +// +// This is OK to do here globally since Miller is quite consistent (in main, +// verbs, and auxents) that multi-character options start with two dashes, e.g. +// "--csv". (The sole exception is the sort verb's -nf/-nr which are handled +// specially there.) +func Getoptify(inargs []string) []string { + regex := regexp.MustCompile("^-[a-zA-Z0-9]+$") + outargs := make([]string, 0) + for _, inarg := range inargs { + if regex.MatchString(inarg) { + for _, c := range inarg[1:] { + outargs = append(outargs, "-"+string(c)) + } + } else { + outargs = append(outargs, inarg) + } + } + return outargs +} diff --git a/go/src/transformers/sort.go b/go/src/transformers/sort.go index ca000b4f7..7c1266846 100644 --- a/go/src/transformers/sort.go +++ b/go/src/transformers/sort.go @@ -135,10 +135,54 @@ func transformerSortParseCLI( } } else if opt == "-n" { - subList := cliutil.VerbGetStringArrayArgOrDie(verb, opt, args, &argi, argc) - for _, item := range subList { - groupByFieldNames = append(groupByFieldNames, item) - comparatorFuncs = append(comparatorFuncs, types.NumericAscendingComparator) + // This is a bit of a hack. + // + // As of Miller 6 we have a getoptish feature wherein "-xyz" is + // expanded to "-x -y -z" while "--xyz" is left intact. This is OK + // to do globally (before any verb such as this one sees the + // command line) since Miller is quite consistent (in main, verbs, + // and auxents) that multi-character options start with two dashes, + // e.g. "--csv" ... + // + // ... with the sole exception being -nf/-nr, right here. This goes + // back to the very start of Miller, and we don't want to break the + // command-line interface to sort. + // + // Before Miller 6, opt and next arg would have been "-nf x,y,z" or + // "-nr x,y,z". Now they're split into "-n -f x,y,z" or "-n -r + // x,y,z", respectively. Note that "-n x,y,z" and "-f x,y,z" and + // "-r x,y,z" are also valid. This means -n needs a field-name list + // after it unless it's followed immediately by -r or -f. + // + // So here we special-case this: if "-n" is followed immediately by + // "-f", we treat it the same as "-nf". Likewise, "-n" followed by + // "-r" is treated like "-nr". + + if args[argi] == "-f" { + // Treat like "-nf" + argi++ + subList := cliutil.VerbGetStringArrayArgOrDie(verb, "-nf", args, &argi, argc) + for _, item := range subList { + groupByFieldNames = append(groupByFieldNames, item) + comparatorFuncs = append(comparatorFuncs, types.NumericAscendingComparator) + } + + } else if args[argi] == "-r" { + // Treat like "-nr" + argi++ + subList := cliutil.VerbGetStringArrayArgOrDie(verb, "-nr", args, &argi, argc) + for _, item := range subList { + groupByFieldNames = append(groupByFieldNames, item) + comparatorFuncs = append(comparatorFuncs, types.NumericDescendingComparator) + } + + } else { + // Treat like "-n" + subList := cliutil.VerbGetStringArrayArgOrDie(verb, opt, args, &argi, argc) + for _, item := range subList { + groupByFieldNames = append(groupByFieldNames, item) + comparatorFuncs = append(comparatorFuncs, types.NumericAscendingComparator) + } } } else if opt == "-nf" { diff --git a/go/todo.txt b/go/todo.txt index f411ba359..984eb1dfa 100644 --- a/go/todo.txt +++ b/go/todo.txt @@ -1,13 +1,13 @@ ================================================================ TOP OF LIST: -! substr operate on runes - * #455 -- doc-neatens re ordering d windows mrpl colors -- ? checking isatty also -- ? * more about HTTP logs in miller -- doc and encapsulate: mlr --icsv --implicit-csv-header --ifs space --oxtab --from elb-log put -q 'print $27' +* something getoptish ... -xyz -> -x -y -z ... + ---------------------------------------------------------------- * regtest .cmd format: o ... add .stdin option, for < -x -y -z ... - ! suppression of 'mlr: ...' diffs ..... o cross-cutting ... search for os.Args[0] / MlrExeName() @@ -546,3 +544,4 @@ i https://en.wikipedia.org/wiki/Delimiter#Delimiter_collision * 123kb/123mb/123gb/123tb fcns (1000/1024) * //go:embed -- ? * github.com/spf13/cobra & viper -- improve CLI/REPL? +* doc getoptish in various spots