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
This commit is contained in:
John Kerl 2021-04-01 00:46:30 +01:00 committed by GitHub
parent a7679e3442
commit 5d482f65aa
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
5 changed files with 88 additions and 14 deletions

View file

@ -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)

View file

@ -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.

27
go/src/lib/getoptify.go Normal file
View file

@ -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
}

View file

@ -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" {

View file

@ -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 <<EOF-ish ...
@ -30,8 +30,6 @@ d windows mrpl colors -- ? checking isatty also -- ?
* port cases gradually over to regtest v2 ...
* something getoptish ... -xyz -> -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