mirror of
https://github.com/johnkerl/miller.git
synced 2026-07-17 16:38:54 +00:00
Improve error propagation (#1975)
This commit is contained in:
parent
1e762d7c4c
commit
e1346691da
71 changed files with 1252 additions and 911 deletions
13
pkg/cli/errors.go
Normal file
13
pkg/cli/errors.go
Normal file
|
|
@ -0,0 +1,13 @@
|
|||
package cli
|
||||
|
||||
import "errors"
|
||||
|
||||
// ErrHelpRequested is returned by verb ParseCLIFunc when -h or --help is used.
|
||||
// The caller (CLI layer) should exit with code 0 after the verb has printed its
|
||||
// usage to stdout.
|
||||
var ErrHelpRequested = errors.New("help requested")
|
||||
|
||||
// ErrUsagePrinted is returned by verb ParseCLIFunc when validation fails. The
|
||||
// verb has already printed its usage to stderr. The caller should exit 1
|
||||
// without printing the error again.
|
||||
var ErrUsagePrinted = errors.New("usage printed")
|
||||
|
|
@ -1,70 +1,83 @@
|
|||
// Utilities for Miller verbs to share for command-line parsing.
|
||||
// These return error instead of os.Exit, so callers (e.g. transformer ParseCLIFunc)
|
||||
// can propagate errors to the CLI entrypoint layer.
|
||||
|
||||
package cli
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"os"
|
||||
"strconv"
|
||||
|
||||
"github.com/johnkerl/miller/v6/pkg/lib"
|
||||
)
|
||||
|
||||
// For flags with values, e.g. ["-n" "10"], while we're looking at the "-n" this let us see if the "10" slot exists.
|
||||
// The verb is nominally something from a ways earlier in args[]; the opt is nominally what's at args[argi-1].
|
||||
// So this function should be called with args[argi] pointing to the "10" slot.
|
||||
func VerbCheckArgCount(verb string, opt string, args []string, argi int, argc int, n int) {
|
||||
// VerbCheckArgCount returns an error if there aren't enough args remaining.
|
||||
// For flags with values, e.g. ["-n" "10"], while we're looking at the "-n"
|
||||
// this lets us see if the "10" slot exists. The verb is nominally something
|
||||
// from a ways earlier in args[]; the opt is nominally what's at args[argi-1].
|
||||
// This function should be called with args[argi] pointing to the "10" slot.
|
||||
func VerbCheckArgCount(verb string, opt string, args []string, argi int, argc int, n int) error {
|
||||
if (argc - argi) < n {
|
||||
fmt.Fprintf(os.Stderr, "%s %s: option \"%s\" missing argument(s).\n",
|
||||
"mlr", verb, opt,
|
||||
)
|
||||
os.Exit(1)
|
||||
return fmt.Errorf("%s %s: option \"%s\" missing argument(s)", "mlr", verb, opt)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// E.g. with ["-f", "a,b,c"], makes sure there is something in the "a,b,c" position, and returns it.
|
||||
func VerbGetStringArgOrDie(verb string, opt string, args []string, pargi *int, argc int) string {
|
||||
VerbCheckArgCount(verb, opt, args, *pargi, argc, 1)
|
||||
// VerbGetStringArg ensures there is something in the value position and returns it.
|
||||
// E.g. with ["-f", "a,b,c"], returns "a,b,c".
|
||||
func VerbGetStringArg(verb string, opt string, args []string, pargi *int, argc int) (string, error) {
|
||||
if err := VerbCheckArgCount(verb, opt, args, *pargi, argc, 1); err != nil {
|
||||
return "", err
|
||||
}
|
||||
retval := args[*pargi]
|
||||
*pargi += 1
|
||||
return retval
|
||||
return retval, nil
|
||||
}
|
||||
|
||||
// E.g. with ["-f", "a,b,c"], makes sure there is something in the "a,b,c" position,
|
||||
// splits it on commas, and returns it.
|
||||
func VerbGetStringArrayArgOrDie(verb string, opt string, args []string, pargi *int, argc int) []string {
|
||||
stringArg := VerbGetStringArgOrDie(verb, opt, args, pargi, argc)
|
||||
return lib.SplitString(stringArg, ",")
|
||||
// VerbGetStringArrayArg ensures there is something in the value position,
|
||||
// splits it on commas, and returns it. E.g. with ["-f", "a,b,c"], returns ["a","b","c"].
|
||||
func VerbGetStringArrayArg(verb string, opt string, args []string, pargi *int, argc int) ([]string, error) {
|
||||
stringArg, err := VerbGetStringArg(verb, opt, args, pargi, argc)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return lib.SplitString(stringArg, ","), nil
|
||||
}
|
||||
|
||||
// E.g. with ["-n", "10"], makes sure there is something in the "10" position,
|
||||
// scans it as int, and returns it.
|
||||
func VerbGetIntArgOrDie(verb string, opt string, args []string, pargi *int, argc int) int64 {
|
||||
// VerbErrorf returns an error prefixed with "mlr {verb}: " so the entrypoint
|
||||
// can print it without double-prefixing.
|
||||
func VerbErrorf(verb, format string, args ...interface{}) error {
|
||||
return fmt.Errorf("mlr "+verb+": "+format, args...)
|
||||
}
|
||||
|
||||
// VerbGetIntArg ensures there is something in the value position and parses it as int64.
|
||||
// E.g. with ["-n", "10"], returns 10.
|
||||
func VerbGetIntArg(verb string, opt string, args []string, pargi *int, argc int) (int64, error) {
|
||||
flag := args[*pargi]
|
||||
stringArg := VerbGetStringArgOrDie(verb, opt, args, pargi, argc)
|
||||
stringArg, err := VerbGetStringArg(verb, opt, args, pargi, argc)
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
retval, err := strconv.ParseInt(stringArg, 10, 64)
|
||||
if err != nil {
|
||||
fmt.Fprintf(os.Stderr,
|
||||
"%s %s: could not scan flag \"%s\" argument \"%s\" as int.\n",
|
||||
"mlr", verb, flag, stringArg,
|
||||
)
|
||||
os.Exit(1)
|
||||
return 0, fmt.Errorf("%s %s: could not scan flag \"%s\" argument \"%s\" as int",
|
||||
"mlr", verb, flag, stringArg)
|
||||
}
|
||||
return retval
|
||||
return retval, nil
|
||||
}
|
||||
|
||||
// E.g. with ["-n", "10.3"], makes sure there is something in the "10.3"
|
||||
// position, scans it as float, and returns it.
|
||||
func VerbGetFloatArgOrDie(verb string, opt string, args []string, pargi *int, argc int) float64 {
|
||||
// VerbGetFloatArg ensures there is something in the value position and parses it as float64.
|
||||
// E.g. with ["-n", "10.3"], returns 10.3.
|
||||
func VerbGetFloatArg(verb string, opt string, args []string, pargi *int, argc int) (float64, error) {
|
||||
flag := args[*pargi]
|
||||
stringArg := VerbGetStringArgOrDie(verb, opt, args, pargi, argc)
|
||||
stringArg, err := VerbGetStringArg(verb, opt, args, pargi, argc)
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
retval, err := strconv.ParseFloat(stringArg, 64)
|
||||
if err != nil {
|
||||
fmt.Fprintf(os.Stderr,
|
||||
"%s %s: could not scan flag \"%s\" argument \"%s\" as float.\n",
|
||||
"mlr", verb, flag, stringArg,
|
||||
)
|
||||
os.Exit(1)
|
||||
return 0, fmt.Errorf("%s %s: could not scan flag \"%s\" argument \"%s\" as float",
|
||||
"mlr", verb, flag, stringArg)
|
||||
}
|
||||
return retval
|
||||
return retval, nil
|
||||
}
|
||||
|
|
|
|||
|
|
@ -69,6 +69,7 @@
|
|||
package climain
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"os"
|
||||
|
||||
|
|
@ -205,16 +206,24 @@ func parseCommandLinePassOne(
|
|||
os.Exit(1)
|
||||
}
|
||||
|
||||
// It's up to the parse func to print its usage, and exit 1, on
|
||||
// CLI-parse failure. Also note: this assumes main reader/writer opts
|
||||
// are all parsed *before* transformer parse-CLI methods are invoked.
|
||||
transformer := transformerSetup.ParseCLIFunc(
|
||||
// ParseCLIFunc returns (nil, nil) on pass-one success, (nil, err) on failure.
|
||||
transformer, err := transformerSetup.ParseCLIFunc(
|
||||
&argi,
|
||||
argc,
|
||||
args,
|
||||
options,
|
||||
false, // false for first pass of CLI-parse, true for second pass -- this is the first pass
|
||||
)
|
||||
if err != nil {
|
||||
if errors.Is(err, cli.ErrHelpRequested) {
|
||||
os.Exit(0)
|
||||
}
|
||||
if errors.Is(err, cli.ErrUsagePrinted) {
|
||||
os.Exit(1)
|
||||
}
|
||||
fmt.Fprintf(os.Stderr, "mlr: %v\n", err)
|
||||
os.Exit(1)
|
||||
}
|
||||
// For pass one we want the verbs to identify the arg-sequences
|
||||
// they own within the command line, but not construct
|
||||
// transformers.
|
||||
|
|
@ -348,15 +357,22 @@ func parseCommandLinePassTwo(
|
|||
transformerSetup := transformers.LookUp(args[0])
|
||||
lib.InternalCodingErrorIf(transformerSetup == nil)
|
||||
|
||||
// It's up to the parse func to print its usage, and exit 1, on
|
||||
// CLI-parse failure.
|
||||
transformer := transformerSetup.ParseCLIFunc(
|
||||
transformer, err := transformerSetup.ParseCLIFunc(
|
||||
&argi,
|
||||
argc,
|
||||
args,
|
||||
options,
|
||||
true, // false for first pass of CLI-parse, true for second pass -- this is the first pass
|
||||
true, // false for first pass of CLI-parse, true for second pass -- this is pass two
|
||||
)
|
||||
if err != nil {
|
||||
if errors.Is(err, cli.ErrHelpRequested) {
|
||||
os.Exit(0)
|
||||
}
|
||||
if errors.Is(err, cli.ErrUsagePrinted) {
|
||||
os.Exit(1)
|
||||
}
|
||||
return nil, nil, err
|
||||
}
|
||||
// Unparsable verb-setups should have been found in pass one.
|
||||
lib.InternalCodingErrorIf(transformer == nil)
|
||||
// Make sure we consumed the entire verb sequence as parsed by pass one.
|
||||
|
|
|
|||
|
|
@ -7,6 +7,7 @@ import (
|
|||
"fmt"
|
||||
"os"
|
||||
"path"
|
||||
"strings"
|
||||
|
||||
"github.com/johnkerl/miller/v6/pkg/auxents"
|
||||
"github.com/johnkerl/miller/v6/pkg/cli"
|
||||
|
|
@ -41,7 +42,7 @@ func Main() MainReturn {
|
|||
|
||||
options, recordTransformers, err := climain.ParseCommandLine(os.Args)
|
||||
if err != nil {
|
||||
fmt.Fprintf(os.Stderr, "mlr: %v\n", err)
|
||||
printError(err)
|
||||
os.Exit(1)
|
||||
}
|
||||
|
||||
|
|
@ -51,7 +52,7 @@ func Main() MainReturn {
|
|||
err = processFilesInPlace(options)
|
||||
}
|
||||
if err != nil {
|
||||
fmt.Fprintf(os.Stderr, "mlr: %v\n", err)
|
||||
printError(err)
|
||||
os.Exit(1)
|
||||
}
|
||||
|
||||
|
|
@ -60,6 +61,16 @@ func Main() MainReturn {
|
|||
}
|
||||
}
|
||||
|
||||
// printError prints err to stderr. Errors that already start with "mlr " (e.g.
|
||||
// "mlr stats1: ...") are printed as-is to avoid double-prefixing.
|
||||
func printError(err error) {
|
||||
if strings.HasPrefix(err.Error(), "mlr ") {
|
||||
fmt.Fprintf(os.Stderr, "%v\n", err)
|
||||
} else {
|
||||
fmt.Fprintf(os.Stderr, "mlr: %v\n", err)
|
||||
}
|
||||
}
|
||||
|
||||
// processToStdout is normal processing without mlr -I.
|
||||
|
||||
func processToStdout(
|
||||
|
|
|
|||
|
|
@ -7,8 +7,10 @@ import (
|
|||
"runtime"
|
||||
)
|
||||
|
||||
// InternalCodingErrorIf is a lookalike for C's __FILE__ and __LINE__ printing,
|
||||
// with exit 1 if the condition is true.
|
||||
// InternalCodingErrorIf reports an internal bug and exits. Use only for
|
||||
// "should never happen" conditions (assertions), not for user or I/O errors.
|
||||
// This is intentionally an exit helper: these indicate programmer error,
|
||||
// and the codebase prefers returning error for recoverable failures.
|
||||
func InternalCodingErrorIf(condition bool) {
|
||||
if !condition {
|
||||
return
|
||||
|
|
|
|||
|
|
@ -36,13 +36,18 @@ type TransformerUsageFunc func(
|
|||
ostream *os.File,
|
||||
)
|
||||
|
||||
// TransformerParseCLIFunc parses verb options from the CLI. Returns (nil, nil) on
|
||||
// success for pass one (doConstruct=false). Returns (transformer, nil) on success
|
||||
// for pass two (doConstruct=true). Returns (nil, cli.ErrHelpRequested) when -h/--help
|
||||
// was used (caller should exit 0; usage already printed). Returns (nil, err) on
|
||||
// parse or constructor failure (caller should print and exit 1).
|
||||
type TransformerParseCLIFunc func(
|
||||
pargi *int,
|
||||
argc int,
|
||||
args []string,
|
||||
mainOptions *cli.TOptions,
|
||||
doConstruct bool, // false for first pass of CLI-parse, true for second pass
|
||||
) RecordTransformer
|
||||
) (RecordTransformer, error)
|
||||
|
||||
type TransformerSetup struct {
|
||||
Verb string
|
||||
|
|
|
|||
|
|
@ -35,7 +35,7 @@ func transformerAltkvParseCLI(
|
|||
args []string,
|
||||
_ *cli.TOptions,
|
||||
doConstruct bool, // false for first pass of CLI-parse, true for second pass
|
||||
) RecordTransformer {
|
||||
) (RecordTransformer, error) {
|
||||
|
||||
// Skip the verb name from the current spot in the mlr command line
|
||||
argi := *pargi
|
||||
|
|
@ -53,25 +53,23 @@ func transformerAltkvParseCLI(
|
|||
|
||||
if opt == "-h" || opt == "--help" {
|
||||
transformerAltkvUsage(os.Stdout)
|
||||
os.Exit(0)
|
||||
|
||||
return nil, cli.ErrHelpRequested
|
||||
}
|
||||
transformerAltkvUsage(os.Stderr)
|
||||
os.Exit(1)
|
||||
return nil, fmt.Errorf("%s %s: option \"%s\" not recognized", "mlr", verbNameAltkv, opt)
|
||||
}
|
||||
|
||||
*pargi = argi
|
||||
if !doConstruct { // All transformers must do this for main command-line parsing
|
||||
return nil
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
transformer, err := NewTransformerAltkv()
|
||||
if err != nil {
|
||||
fmt.Fprintf(os.Stderr, "mlr: %v\n", err)
|
||||
os.Exit(1)
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return transformer
|
||||
return transformer, nil
|
||||
}
|
||||
|
||||
type TransformerAltkv struct {
|
||||
|
|
|
|||
|
|
@ -54,7 +54,7 @@ func transformerBarParseCLI(
|
|||
args []string,
|
||||
_ *cli.TOptions,
|
||||
doConstruct bool, // false for first pass of CLI-parse, true for second pass
|
||||
) RecordTransformer {
|
||||
) (RecordTransformer, error) {
|
||||
|
||||
// Skip the verb name from the current spot in the mlr command line
|
||||
argi := *pargi
|
||||
|
|
@ -62,6 +62,7 @@ func transformerBarParseCLI(
|
|||
argi++
|
||||
|
||||
// Parse local flags
|
||||
var err error
|
||||
var fieldNames []string = nil
|
||||
lo := barDefaultLo
|
||||
hi := barDefaultHi
|
||||
|
|
@ -83,42 +84,61 @@ func transformerBarParseCLI(
|
|||
|
||||
if opt == "-h" || opt == "--help" {
|
||||
transformerBarUsage(os.Stdout)
|
||||
os.Exit(0)
|
||||
return nil, cli.ErrHelpRequested
|
||||
|
||||
} else if opt == "-f" {
|
||||
fieldNames = cli.VerbGetStringArrayArgOrDie(verb, opt, args, &argi, argc)
|
||||
fieldNames, err = cli.VerbGetStringArrayArg(verb, opt, args, &argi, argc)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
} else if opt == "--lo" {
|
||||
lo = cli.VerbGetFloatArgOrDie(verb, opt, args, &argi, argc)
|
||||
lo, err = cli.VerbGetFloatArg(verb, opt, args, &argi, argc)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
} else if opt == "-w" {
|
||||
width = cli.VerbGetIntArgOrDie(verb, opt, args, &argi, argc)
|
||||
width, err = cli.VerbGetIntArg(verb, opt, args, &argi, argc)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
} else if opt == "--hi" {
|
||||
hi = cli.VerbGetFloatArgOrDie(verb, opt, args, &argi, argc)
|
||||
hi, err = cli.VerbGetFloatArg(verb, opt, args, &argi, argc)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
} else if opt == "-c" {
|
||||
fillString = cli.VerbGetStringArgOrDie(verb, opt, args, &argi, argc)
|
||||
fillString, err = cli.VerbGetStringArg(verb, opt, args, &argi, argc)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
} else if opt == "-x" {
|
||||
oobString = cli.VerbGetStringArgOrDie(verb, opt, args, &argi, argc)
|
||||
oobString, err = cli.VerbGetStringArg(verb, opt, args, &argi, argc)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
} else if opt == "-b" {
|
||||
blankString = cli.VerbGetStringArgOrDie(verb, opt, args, &argi, argc)
|
||||
blankString, err = cli.VerbGetStringArg(verb, opt, args, &argi, argc)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
} else if opt == "--auto" {
|
||||
doAuto = true
|
||||
|
||||
} else {
|
||||
transformerBarUsage(os.Stderr)
|
||||
os.Exit(1)
|
||||
return nil, cli.VerbErrorf(verb, "option \"%s\" not recognized", opt)
|
||||
}
|
||||
}
|
||||
|
||||
if fieldNames == nil {
|
||||
transformerBarUsage(os.Stderr)
|
||||
os.Exit(1)
|
||||
return nil, cli.VerbErrorf(verb, "-f field names required")
|
||||
}
|
||||
|
||||
*pargi = argi
|
||||
if !doConstruct { // All transformers must do this for main command-line parsing
|
||||
return nil
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
transformer, err := NewTransformerBar(
|
||||
|
|
@ -132,11 +152,10 @@ func transformerBarParseCLI(
|
|||
blankString,
|
||||
)
|
||||
if err != nil {
|
||||
fmt.Fprintf(os.Stderr, "mlr: %v\n", err)
|
||||
os.Exit(1)
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return transformer
|
||||
return transformer, nil
|
||||
}
|
||||
|
||||
type TransformerBar struct {
|
||||
|
|
|
|||
|
|
@ -41,13 +41,14 @@ func transformerBootstrapParseCLI(
|
|||
args []string,
|
||||
_ *cli.TOptions,
|
||||
doConstruct bool, // false for first pass of CLI-parse, true for second pass
|
||||
) RecordTransformer {
|
||||
) (RecordTransformer, error) {
|
||||
|
||||
// Skip the verb name from the current spot in the mlr command line
|
||||
argi := *pargi
|
||||
verb := args[argi]
|
||||
argi++
|
||||
|
||||
var err error
|
||||
nout := int64(-1)
|
||||
|
||||
for argi < argc /* variable increment: 1 or 2 depending on flag */ {
|
||||
|
|
@ -62,29 +63,30 @@ func transformerBootstrapParseCLI(
|
|||
|
||||
if opt == "-h" || opt == "--help" {
|
||||
transformerBootstrapUsage(os.Stdout)
|
||||
os.Exit(0)
|
||||
return nil, cli.ErrHelpRequested
|
||||
|
||||
} else if opt == "-n" {
|
||||
nout = cli.VerbGetIntArgOrDie(verb, opt, args, &argi, argc)
|
||||
nout, err = cli.VerbGetIntArg(verb, opt, args, &argi, argc)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
} else {
|
||||
transformerBootstrapUsage(os.Stderr)
|
||||
os.Exit(1)
|
||||
return nil, cli.VerbErrorf(verb, "option \"%s\" not recognized", opt)
|
||||
}
|
||||
}
|
||||
|
||||
*pargi = argi
|
||||
if !doConstruct { // All transformers must do this for main command-line parsing
|
||||
return nil
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
transformer, err := NewTransformerBootstrap(nout)
|
||||
if err != nil {
|
||||
fmt.Fprintf(os.Stderr, "mlr: %v\n", err)
|
||||
os.Exit(1)
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return transformer
|
||||
return transformer, nil
|
||||
}
|
||||
|
||||
type TransformerBootstrap struct {
|
||||
|
|
|
|||
|
|
@ -53,13 +53,14 @@ func transformerCaseParseCLI(
|
|||
args []string,
|
||||
_ *cli.TOptions,
|
||||
doConstruct bool, // false for first pass of CLI-parse, true for second pass
|
||||
) RecordTransformer {
|
||||
) (RecordTransformer, error) {
|
||||
|
||||
// Skip the verb name from the current spot in the mlr command line
|
||||
argi := *pargi
|
||||
verb := args[argi]
|
||||
argi++
|
||||
|
||||
var err error
|
||||
which := "keys_and_values"
|
||||
style := e_UNSPECIFIED_CASE
|
||||
var fieldNames []string = nil
|
||||
|
|
@ -76,7 +77,7 @@ func transformerCaseParseCLI(
|
|||
|
||||
if opt == "-h" || opt == "--help" {
|
||||
transformerCaseUsage(os.Stdout)
|
||||
os.Exit(0)
|
||||
return nil, cli.ErrHelpRequested
|
||||
|
||||
} else if opt == "-k" {
|
||||
which = "keys_only"
|
||||
|
|
@ -85,7 +86,10 @@ func transformerCaseParseCLI(
|
|||
which = "values_only"
|
||||
|
||||
} else if opt == "-f" {
|
||||
fieldNames = cli.VerbGetStringArrayArgOrDie(verb, opt, args, &argi, argc)
|
||||
fieldNames, err = cli.VerbGetStringArrayArg(verb, opt, args, &argi, argc)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
} else if opt == "-u" {
|
||||
style = e_UPPER_CASE
|
||||
|
|
@ -97,23 +101,21 @@ func transformerCaseParseCLI(
|
|||
style = e_TITLE_CASE
|
||||
|
||||
} else {
|
||||
transformerCaseUsage(os.Stderr)
|
||||
os.Exit(1)
|
||||
return nil, cli.VerbErrorf(verb, "option \"%s\" not recognized", opt)
|
||||
}
|
||||
}
|
||||
|
||||
*pargi = argi
|
||||
if !doConstruct { // All transformers must do this for main command-line parsing
|
||||
return nil
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
transformer, err := NewTransformerCase(which, fieldNames, style)
|
||||
if err != nil {
|
||||
fmt.Fprintf(os.Stderr, "mlr: %v\n", err)
|
||||
os.Exit(1)
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return transformer
|
||||
return transformer, nil
|
||||
}
|
||||
|
||||
type caserFuncT func(input string) string
|
||||
|
|
|
|||
|
|
@ -39,13 +39,14 @@ func transformerCatParseCLI(
|
|||
args []string,
|
||||
_ *cli.TOptions,
|
||||
doConstruct bool, // false for first pass of CLI-parse, true for second pass
|
||||
) RecordTransformer {
|
||||
) (RecordTransformer, error) {
|
||||
|
||||
// Skip the verb name from the current spot in the mlr command line
|
||||
argi := *pargi
|
||||
verb := args[argi]
|
||||
argi++
|
||||
|
||||
var err error
|
||||
// Parse local flags
|
||||
doCounters := false
|
||||
counterFieldName := ""
|
||||
|
|
@ -65,16 +66,22 @@ func transformerCatParseCLI(
|
|||
|
||||
if opt == "-h" || opt == "--help" {
|
||||
transformerCatUsage(os.Stdout)
|
||||
os.Exit(0)
|
||||
return nil, cli.ErrHelpRequested
|
||||
|
||||
} else if opt == "-n" {
|
||||
counterFieldName = "n"
|
||||
|
||||
} else if opt == "-N" {
|
||||
counterFieldName = cli.VerbGetStringArgOrDie(verb, opt, args, &argi, argc)
|
||||
counterFieldName, err = cli.VerbGetStringArg(verb, opt, args, &argi, argc)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
} else if opt == "-g" {
|
||||
groupByFieldNames = cli.VerbGetStringArrayArgOrDie(verb, opt, args, &argi, argc)
|
||||
groupByFieldNames, err = cli.VerbGetStringArrayArg(verb, opt, args, &argi, argc)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
} else if opt == "--filename" {
|
||||
doFileName = true
|
||||
|
|
@ -83,14 +90,13 @@ func transformerCatParseCLI(
|
|||
doFileNum = true
|
||||
|
||||
} else {
|
||||
transformerCatUsage(os.Stderr)
|
||||
os.Exit(1)
|
||||
return nil, cli.VerbErrorf(verb, "option \"%s\" not recognized", opt)
|
||||
}
|
||||
}
|
||||
|
||||
*pargi = argi
|
||||
if !doConstruct { // All transformers must do this for main command-line parsing
|
||||
return nil
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
transformer, err := NewTransformerCat(
|
||||
|
|
@ -101,11 +107,10 @@ func transformerCatParseCLI(
|
|||
doFileNum,
|
||||
)
|
||||
if err != nil {
|
||||
fmt.Fprintf(os.Stderr, "mlr: %v\n", err)
|
||||
os.Exit(1)
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return transformer
|
||||
return transformer, nil
|
||||
}
|
||||
|
||||
type TransformerCat struct {
|
||||
|
|
|
|||
|
|
@ -38,7 +38,7 @@ func transformerCheckParseCLI(
|
|||
args []string,
|
||||
_ *cli.TOptions,
|
||||
doConstruct bool, // false for first pass of CLI-parse, true for second pass
|
||||
) RecordTransformer {
|
||||
) (RecordTransformer, error) {
|
||||
|
||||
// Skip the verb name from the current spot in the mlr command line
|
||||
argi := *pargi
|
||||
|
|
@ -56,25 +56,23 @@ func transformerCheckParseCLI(
|
|||
|
||||
if opt == "-h" || opt == "--help" {
|
||||
transformerCheckUsage(os.Stdout)
|
||||
os.Exit(0)
|
||||
return nil, cli.ErrHelpRequested
|
||||
|
||||
}
|
||||
transformerCheckUsage(os.Stderr)
|
||||
os.Exit(1)
|
||||
return nil, cli.VerbErrorf(verbNameCheck, "option \"%s\" not recognized", opt)
|
||||
}
|
||||
|
||||
*pargi = argi
|
||||
if !doConstruct { // All transformers must do this for main command-line parsing
|
||||
return nil
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
transformer, err := NewTransformerCheck()
|
||||
if err != nil {
|
||||
fmt.Fprintf(os.Stderr, "mlr: %v\n", err)
|
||||
os.Exit(1)
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return transformer
|
||||
return transformer, nil
|
||||
}
|
||||
|
||||
type TransformerCheck struct {
|
||||
|
|
|
|||
|
|
@ -44,7 +44,7 @@ func transformerCleanWhitespaceParseCLI(
|
|||
args []string,
|
||||
_ *cli.TOptions,
|
||||
doConstruct bool, // false for first pass of CLI-parse, true for second pass
|
||||
) RecordTransformer {
|
||||
) (RecordTransformer, error) {
|
||||
|
||||
doKeys := true
|
||||
doValues := true
|
||||
|
|
@ -65,7 +65,7 @@ func transformerCleanWhitespaceParseCLI(
|
|||
|
||||
if opt == "-h" || opt == "--help" {
|
||||
transformerCleanWhitespaceUsage(os.Stdout)
|
||||
os.Exit(0)
|
||||
return nil, cli.ErrHelpRequested
|
||||
|
||||
} else if opt == "-k" || opt == "--keys-only" {
|
||||
doKeys = true
|
||||
|
|
@ -75,19 +75,17 @@ func transformerCleanWhitespaceParseCLI(
|
|||
doValues = true
|
||||
|
||||
} else {
|
||||
transformerCleanWhitespaceUsage(os.Stderr)
|
||||
os.Exit(1)
|
||||
return nil, cli.VerbErrorf(verbNameCleanWhitespace, "option \"%s\" not recognized", opt)
|
||||
}
|
||||
}
|
||||
|
||||
if !doKeys && !doValues {
|
||||
transformerCleanWhitespaceUsage(os.Stderr)
|
||||
os.Exit(1)
|
||||
return nil, cli.VerbErrorf(verbNameCleanWhitespace, "-k or -v is required")
|
||||
}
|
||||
|
||||
*pargi = argi
|
||||
if !doConstruct { // All transformers must do this for main command-line parsing
|
||||
return nil
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
transformer, err := NewTransformerCleanWhitespace(
|
||||
|
|
@ -95,11 +93,10 @@ func transformerCleanWhitespaceParseCLI(
|
|||
doValues,
|
||||
)
|
||||
if err != nil {
|
||||
fmt.Fprintf(os.Stderr, "mlr: %v\n", err)
|
||||
os.Exit(1)
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return transformer
|
||||
return transformer, nil
|
||||
}
|
||||
|
||||
type TransformerCleanWhitespace struct {
|
||||
|
|
|
|||
|
|
@ -40,7 +40,7 @@ func transformerCountParseCLI(
|
|||
args []string,
|
||||
_ *cli.TOptions,
|
||||
doConstruct bool, // false for first pass of CLI-parse, true for second pass
|
||||
) RecordTransformer {
|
||||
) (RecordTransformer, error) {
|
||||
|
||||
// Skip the verb name from the current spot in the mlr command line
|
||||
argi := *pargi
|
||||
|
|
@ -51,6 +51,7 @@ func transformerCountParseCLI(
|
|||
showCountsOnly := false
|
||||
outputFieldName := "count"
|
||||
|
||||
var err error
|
||||
for argi < argc /* variable increment: 1 or 2 depending on flag */ {
|
||||
opt := args[argi]
|
||||
if !strings.HasPrefix(opt, "-") {
|
||||
|
|
@ -63,26 +64,31 @@ func transformerCountParseCLI(
|
|||
|
||||
if opt == "-h" || opt == "--help" {
|
||||
transformerCountUsage(os.Stdout)
|
||||
os.Exit(0)
|
||||
return nil, cli.ErrHelpRequested
|
||||
|
||||
} else if opt == "-g" {
|
||||
groupByFieldNames = cli.VerbGetStringArrayArgOrDie(verb, opt, args, &argi, argc)
|
||||
groupByFieldNames, err = cli.VerbGetStringArrayArg(verb, opt, args, &argi, argc)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
} else if opt == "-n" {
|
||||
showCountsOnly = true
|
||||
|
||||
} else if opt == "-o" {
|
||||
outputFieldName = cli.VerbGetStringArgOrDie(verb, opt, args, &argi, argc)
|
||||
outputFieldName, err = cli.VerbGetStringArg(verb, opt, args, &argi, argc)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
} else {
|
||||
transformerCountUsage(os.Stderr)
|
||||
os.Exit(1)
|
||||
return nil, cli.VerbErrorf(verb, "option \"%s\" not recognized", opt)
|
||||
}
|
||||
}
|
||||
|
||||
*pargi = argi
|
||||
if !doConstruct { // All transformers must do this for main command-line parsing
|
||||
return nil
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
transformer, err := NewTransformerCount(
|
||||
|
|
@ -91,11 +97,10 @@ func transformerCountParseCLI(
|
|||
outputFieldName,
|
||||
)
|
||||
if err != nil {
|
||||
fmt.Fprintf(os.Stderr, "mlr: %v\n", err)
|
||||
os.Exit(1)
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return transformer
|
||||
return transformer, nil
|
||||
}
|
||||
|
||||
type TransformerCount struct {
|
||||
|
|
|
|||
|
|
@ -38,7 +38,7 @@ func transformerCountSimilarParseCLI(
|
|||
args []string,
|
||||
_ *cli.TOptions,
|
||||
doConstruct bool, // false for first pass of CLI-parse, true for second pass
|
||||
) RecordTransformer {
|
||||
) (RecordTransformer, error) {
|
||||
|
||||
// Skip the verb name from the current spot in the mlr command line
|
||||
argi := *pargi
|
||||
|
|
@ -48,6 +48,7 @@ func transformerCountSimilarParseCLI(
|
|||
var groupByFieldNames []string = nil
|
||||
counterFieldName := "count"
|
||||
|
||||
var err error
|
||||
for argi < argc /* variable increment: 1 or 2 depending on flag */ {
|
||||
opt := args[argi]
|
||||
if !strings.HasPrefix(opt, "-") {
|
||||
|
|
@ -60,28 +61,32 @@ func transformerCountSimilarParseCLI(
|
|||
|
||||
if opt == "-h" || opt == "--help" {
|
||||
transformerCountSimilarUsage(os.Stdout)
|
||||
os.Exit(0)
|
||||
return nil, cli.ErrHelpRequested
|
||||
|
||||
} else if opt == "-g" {
|
||||
groupByFieldNames = cli.VerbGetStringArrayArgOrDie(verb, opt, args, &argi, argc)
|
||||
groupByFieldNames, err = cli.VerbGetStringArrayArg(verb, opt, args, &argi, argc)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
} else if opt == "-o" {
|
||||
counterFieldName = cli.VerbGetStringArgOrDie(verb, opt, args, &argi, argc)
|
||||
counterFieldName, err = cli.VerbGetStringArg(verb, opt, args, &argi, argc)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
} else {
|
||||
transformerCountSimilarUsage(os.Stderr)
|
||||
os.Exit(1)
|
||||
return nil, cli.VerbErrorf(verb, "option \"%s\" not recognized", opt)
|
||||
}
|
||||
}
|
||||
|
||||
if groupByFieldNames == nil {
|
||||
transformerCountSimilarUsage(os.Stderr)
|
||||
os.Exit(1)
|
||||
return nil, cli.VerbErrorf(verb, "-g field names required")
|
||||
}
|
||||
|
||||
*pargi = argi
|
||||
if !doConstruct { // All transformers must do this for main command-line parsing
|
||||
return nil
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
transformer, err := NewTransformerCountSimilar(
|
||||
|
|
@ -89,11 +94,10 @@ func transformerCountSimilarParseCLI(
|
|||
counterFieldName,
|
||||
)
|
||||
if err != nil {
|
||||
fmt.Fprintf(os.Stderr, "mlr: %v\n", err)
|
||||
os.Exit(1)
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return transformer
|
||||
return transformer, nil
|
||||
}
|
||||
|
||||
type TransformerCountSimilar struct {
|
||||
|
|
|
|||
|
|
@ -52,13 +52,14 @@ func transformerCutParseCLI(
|
|||
args []string,
|
||||
_ *cli.TOptions,
|
||||
doConstruct bool, // false for first pass of CLI-parse, true for second pass
|
||||
) RecordTransformer {
|
||||
) (RecordTransformer, error) {
|
||||
|
||||
// Skip the verb name from the current spot in the mlr command line
|
||||
argi := *pargi
|
||||
verb := args[argi]
|
||||
argi++
|
||||
|
||||
var err error
|
||||
var fieldNames []string = nil
|
||||
doArgOrder := false
|
||||
doComplement := false
|
||||
|
|
@ -76,10 +77,13 @@ func transformerCutParseCLI(
|
|||
|
||||
if opt == "-h" || opt == "--help" {
|
||||
transformerCutUsage(os.Stdout)
|
||||
os.Exit(0)
|
||||
return nil, cli.ErrHelpRequested
|
||||
|
||||
} else if opt == "-f" {
|
||||
fieldNames = cli.VerbGetStringArrayArgOrDie(verb, opt, args, &argi, argc)
|
||||
fieldNames, err = cli.VerbGetStringArrayArg(verb, opt, args, &argi, argc)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
} else if opt == "-o" {
|
||||
doArgOrder = true
|
||||
|
|
@ -94,19 +98,17 @@ func transformerCutParseCLI(
|
|||
doRegexes = true
|
||||
|
||||
} else {
|
||||
transformerCutUsage(os.Stderr)
|
||||
os.Exit(1)
|
||||
return nil, cli.VerbErrorf(verb, "option \"%s\" not recognized", opt)
|
||||
}
|
||||
}
|
||||
|
||||
if fieldNames == nil {
|
||||
transformerCutUsage(os.Stderr)
|
||||
os.Exit(1)
|
||||
return nil, cli.VerbErrorf(verb, "-f field names required")
|
||||
}
|
||||
|
||||
*pargi = argi
|
||||
if !doConstruct { // All transformers must do this for main command-line parsing
|
||||
return nil
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
transformer, err := NewTransformerCut(
|
||||
|
|
@ -116,11 +118,10 @@ func transformerCutParseCLI(
|
|||
doRegexes,
|
||||
)
|
||||
if err != nil {
|
||||
fmt.Fprintf(os.Stderr, "mlr: %v\n", err)
|
||||
os.Exit(1)
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return transformer
|
||||
return transformer, nil
|
||||
}
|
||||
|
||||
type TransformerCut struct {
|
||||
|
|
|
|||
|
|
@ -37,13 +37,14 @@ func transformerDecimateParseCLI(
|
|||
args []string,
|
||||
_ *cli.TOptions,
|
||||
doConstruct bool, // false for first pass of CLI-parse, true for second pass
|
||||
) RecordTransformer {
|
||||
) (RecordTransformer, error) {
|
||||
|
||||
// Skip the verb name from the current spot in the mlr command line
|
||||
argi := *pargi
|
||||
verb := args[argi]
|
||||
argi++
|
||||
|
||||
var err error
|
||||
decimateCount := int64(10)
|
||||
atStart := false
|
||||
atEnd := false
|
||||
|
|
@ -61,13 +62,15 @@ func transformerDecimateParseCLI(
|
|||
|
||||
if opt == "-h" || opt == "--help" {
|
||||
transformerDecimateUsage(os.Stdout)
|
||||
os.Exit(0)
|
||||
return nil, cli.ErrHelpRequested
|
||||
|
||||
} else if opt == "-n" {
|
||||
decimateCount = cli.VerbGetIntArgOrDie(verb, opt, args, &argi, argc)
|
||||
decimateCount, err = cli.VerbGetIntArg(verb, opt, args, &argi, argc)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if decimateCount <= 0 {
|
||||
transformerDecimateUsage(os.Stderr)
|
||||
os.Exit(1)
|
||||
return nil, cli.VerbErrorf(verb, "-n must be positive")
|
||||
}
|
||||
|
||||
} else if opt == "-b" {
|
||||
|
|
@ -77,17 +80,19 @@ func transformerDecimateParseCLI(
|
|||
atEnd = true
|
||||
|
||||
} else if opt == "-g" {
|
||||
groupByFieldNames = cli.VerbGetStringArrayArgOrDie(verb, opt, args, &argi, argc)
|
||||
groupByFieldNames, err = cli.VerbGetStringArrayArg(verb, opt, args, &argi, argc)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
} else {
|
||||
transformerDecimateUsage(os.Stderr)
|
||||
os.Exit(1)
|
||||
return nil, cli.VerbErrorf(verb, "option \"%s\" not recognized", opt)
|
||||
}
|
||||
}
|
||||
|
||||
*pargi = argi
|
||||
if !doConstruct { // All transformers must do this for main command-line parsing
|
||||
return nil
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
transformer, err := NewTransformerDecimate(
|
||||
|
|
@ -97,11 +102,10 @@ func transformerDecimateParseCLI(
|
|||
groupByFieldNames,
|
||||
)
|
||||
if err != nil {
|
||||
fmt.Fprintf(os.Stderr, "mlr: %v\n", err)
|
||||
os.Exit(1)
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return transformer
|
||||
return transformer, nil
|
||||
}
|
||||
|
||||
type TransformerDecimate struct {
|
||||
|
|
|
|||
|
|
@ -44,7 +44,7 @@ func transformerFillDownParseCLI(
|
|||
args []string,
|
||||
_ *cli.TOptions,
|
||||
doConstruct bool, // false for first pass of CLI-parse, true for second pass
|
||||
) RecordTransformer {
|
||||
) (RecordTransformer, error) {
|
||||
|
||||
// Skip the verb name from the current spot in the mlr command line
|
||||
argi := *pargi
|
||||
|
|
@ -55,6 +55,7 @@ func transformerFillDownParseCLI(
|
|||
doAll := false
|
||||
onlyIfAbsent := false
|
||||
|
||||
var err error
|
||||
for argi < argc /* variable increment: 1 or 2 depending on flag */ {
|
||||
opt := args[argi]
|
||||
if !strings.HasPrefix(opt, "-") {
|
||||
|
|
@ -67,10 +68,13 @@ func transformerFillDownParseCLI(
|
|||
|
||||
if opt == "-h" || opt == "--help" {
|
||||
transformerFillDownUsage(os.Stdout)
|
||||
os.Exit(0)
|
||||
return nil, cli.ErrHelpRequested
|
||||
|
||||
} else if opt == "-f" {
|
||||
fillDownFieldNames = cli.VerbGetStringArrayArgOrDie(verb, opt, args, &argi, argc)
|
||||
fillDownFieldNames, err = cli.VerbGetStringArrayArg(verb, opt, args, &argi, argc)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
} else if opt == "--all" {
|
||||
doAll = true
|
||||
|
|
@ -82,19 +86,17 @@ func transformerFillDownParseCLI(
|
|||
onlyIfAbsent = true
|
||||
|
||||
} else {
|
||||
transformerFillDownUsage(os.Stderr)
|
||||
os.Exit(1)
|
||||
return nil, cli.VerbErrorf(verb, "option \"%s\" not recognized", opt)
|
||||
}
|
||||
}
|
||||
|
||||
if fillDownFieldNames == nil && !doAll {
|
||||
transformerFillDownUsage(os.Stderr)
|
||||
os.Exit(1)
|
||||
return nil, cli.VerbErrorf(verb, "-f field names or --all required")
|
||||
}
|
||||
|
||||
*pargi = argi
|
||||
if !doConstruct { // All transformers must do this for main command-line parsing
|
||||
return nil
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
transformer, err := NewTransformerFillDown(
|
||||
|
|
@ -103,11 +105,10 @@ func transformerFillDownParseCLI(
|
|||
onlyIfAbsent,
|
||||
)
|
||||
if err != nil {
|
||||
fmt.Fprintf(os.Stderr, "mlr: %v\n", err)
|
||||
os.Exit(1)
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return transformer
|
||||
return transformer, nil
|
||||
}
|
||||
|
||||
type TransformerFillDown struct {
|
||||
|
|
|
|||
|
|
@ -36,7 +36,7 @@ func transformerFillEmptyParseCLI(
|
|||
args []string,
|
||||
_ *cli.TOptions,
|
||||
doConstruct bool, // false for first pass of CLI-parse, true for second pass
|
||||
) RecordTransformer {
|
||||
) (RecordTransformer, error) {
|
||||
|
||||
// Skip the verb name from the current spot in the mlr command line
|
||||
argi := *pargi
|
||||
|
|
@ -46,6 +46,7 @@ func transformerFillEmptyParseCLI(
|
|||
fillString := defaultFillEmptyString
|
||||
inferType := true
|
||||
|
||||
var err error
|
||||
for argi < argc /* variable increment: 1 or 2 depending on flag */ {
|
||||
opt := args[argi]
|
||||
if !strings.HasPrefix(opt, "-") {
|
||||
|
|
@ -58,32 +59,33 @@ func transformerFillEmptyParseCLI(
|
|||
|
||||
if opt == "-h" || opt == "--help" {
|
||||
transformerFillEmptyUsage(os.Stdout)
|
||||
os.Exit(0)
|
||||
return nil, cli.ErrHelpRequested
|
||||
|
||||
} else if opt == "-v" {
|
||||
fillString = cli.VerbGetStringArgOrDie(verb, opt, args, &argi, argc)
|
||||
fillString, err = cli.VerbGetStringArg(verb, opt, args, &argi, argc)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
} else if opt == "-S" {
|
||||
inferType = false
|
||||
|
||||
} else {
|
||||
transformerFillEmptyUsage(os.Stderr)
|
||||
os.Exit(1)
|
||||
return nil, cli.VerbErrorf(verb, "option \"%s\" not recognized", opt)
|
||||
}
|
||||
}
|
||||
|
||||
*pargi = argi
|
||||
if !doConstruct { // All transformers must do this for main command-line parsing
|
||||
return nil
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
transformer, err := NewTransformerFillEmpty(fillString, inferType)
|
||||
if err != nil {
|
||||
fmt.Fprintf(os.Stderr, "mlr: %v\n", err)
|
||||
os.Exit(1)
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return transformer
|
||||
return transformer, nil
|
||||
}
|
||||
|
||||
type TransformerFillEmpty struct {
|
||||
|
|
|
|||
|
|
@ -39,7 +39,7 @@ func transformerFlattenParseCLI(
|
|||
args []string,
|
||||
options *cli.TOptions,
|
||||
doConstruct bool, // false for first pass of CLI-parse, true for second pass
|
||||
) RecordTransformer {
|
||||
) (RecordTransformer, error) {
|
||||
|
||||
// Skip the verb name from the current spot in the mlr command line
|
||||
argi := *pargi
|
||||
|
|
@ -49,6 +49,7 @@ func transformerFlattenParseCLI(
|
|||
oFlatSep := "" // means take it from the record context
|
||||
var fieldNames []string = nil
|
||||
|
||||
var err error
|
||||
for argi < argc /* variable increment: 1 or 2 depending on flag */ {
|
||||
opt := args[argi]
|
||||
if !strings.HasPrefix(opt, "-") {
|
||||
|
|
@ -61,23 +62,28 @@ func transformerFlattenParseCLI(
|
|||
|
||||
if opt == "-h" || opt == "--help" {
|
||||
transformerFlattenUsage(os.Stdout)
|
||||
os.Exit(0)
|
||||
return nil, cli.ErrHelpRequested
|
||||
|
||||
} else if opt == "-s" {
|
||||
oFlatSep = cli.VerbGetStringArgOrDie(verb, opt, args, &argi, argc)
|
||||
oFlatSep, err = cli.VerbGetStringArg(verb, opt, args, &argi, argc)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
} else if opt == "-f" {
|
||||
fieldNames = cli.VerbGetStringArrayArgOrDie(verb, opt, args, &argi, argc)
|
||||
fieldNames, err = cli.VerbGetStringArrayArg(verb, opt, args, &argi, argc)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
} else {
|
||||
transformerFlattenUsage(os.Stderr)
|
||||
os.Exit(1)
|
||||
return nil, cli.VerbErrorf(verb, "option \"%s\" not recognized", opt)
|
||||
}
|
||||
}
|
||||
|
||||
*pargi = argi
|
||||
if !doConstruct { // All transformers must do this for main command-line parsing
|
||||
return nil
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
transformer, err := NewTransformerFlatten(
|
||||
|
|
@ -86,11 +92,10 @@ func transformerFlattenParseCLI(
|
|||
fieldNames,
|
||||
)
|
||||
if err != nil {
|
||||
fmt.Fprintf(os.Stderr, "mlr: %v\n", err)
|
||||
os.Exit(1)
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return transformer
|
||||
return transformer, nil
|
||||
}
|
||||
|
||||
type TransformerFlatten struct {
|
||||
|
|
|
|||
|
|
@ -63,7 +63,7 @@ func transformerFormatValuesParseCLI(
|
|||
args []string,
|
||||
_ *cli.TOptions,
|
||||
doConstruct bool, // false for first pass of CLI-parse, true for second pass
|
||||
) RecordTransformer {
|
||||
) (RecordTransformer, error) {
|
||||
|
||||
// Skip the verb name from the current spot in the mlr command line
|
||||
argi := *pargi
|
||||
|
|
@ -75,6 +75,7 @@ func transformerFormatValuesParseCLI(
|
|||
floatFormat := defaultFormatValuesFloatFormat
|
||||
coerceIntToFloat := false
|
||||
|
||||
var err error
|
||||
for argi < argc /* variable increment: 1 or 2 depending on flag */ {
|
||||
opt := args[argi]
|
||||
if !strings.HasPrefix(opt, "-") {
|
||||
|
|
@ -87,26 +88,34 @@ func transformerFormatValuesParseCLI(
|
|||
|
||||
if opt == "-h" || opt == "--help" {
|
||||
transformerFormatValuesUsage(os.Stdout)
|
||||
os.Exit(0)
|
||||
return nil, cli.ErrHelpRequested
|
||||
|
||||
} else if opt == "-s" {
|
||||
stringFormat = cli.VerbGetStringArgOrDie(verb, opt, args, &argi, argc)
|
||||
stringFormat, err = cli.VerbGetStringArg(verb, opt, args, &argi, argc)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
} else if opt == "-i" {
|
||||
intFormat = cli.VerbGetStringArgOrDie(verb, opt, args, &argi, argc)
|
||||
intFormat, err = cli.VerbGetStringArg(verb, opt, args, &argi, argc)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
} else if opt == "-f" {
|
||||
floatFormat = cli.VerbGetStringArgOrDie(verb, opt, args, &argi, argc)
|
||||
floatFormat, err = cli.VerbGetStringArg(verb, opt, args, &argi, argc)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
} else if opt == "-n" {
|
||||
coerceIntToFloat = true
|
||||
|
||||
} else {
|
||||
transformerFormatValuesUsage(os.Stderr)
|
||||
os.Exit(1)
|
||||
return nil, cli.VerbErrorf(verb, "option \"%s\" not recognized", opt)
|
||||
}
|
||||
}
|
||||
|
||||
*pargi = argi
|
||||
if !doConstruct { // All transformers must do this for main command-line parsing
|
||||
return nil
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
transformer, err := NewTransformerFormatValues(
|
||||
|
|
@ -116,11 +125,10 @@ func transformerFormatValuesParseCLI(
|
|||
coerceIntToFloat,
|
||||
)
|
||||
if err != nil {
|
||||
fmt.Fprintf(os.Stderr, "mlr: %v\n", err)
|
||||
os.Exit(1)
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return transformer
|
||||
return transformer, nil
|
||||
}
|
||||
|
||||
type TransformerFormatValues struct {
|
||||
|
|
|
|||
|
|
@ -55,7 +55,7 @@ func transformerFractionParseCLI(
|
|||
args []string,
|
||||
_ *cli.TOptions,
|
||||
doConstruct bool, // false for first pass of CLI-parse, true for second pass
|
||||
) RecordTransformer {
|
||||
) (RecordTransformer, error) {
|
||||
|
||||
// Skip the verb name from the current spot in the mlr command line
|
||||
argi := *pargi
|
||||
|
|
@ -68,6 +68,7 @@ func transformerFractionParseCLI(
|
|||
doPercents := false
|
||||
doCumu := false
|
||||
|
||||
var err error
|
||||
for argi < argc /* variable increment: 1 or 2 depending on flag */ {
|
||||
opt := args[argi]
|
||||
if !strings.HasPrefix(opt, "-") {
|
||||
|
|
@ -80,13 +81,19 @@ func transformerFractionParseCLI(
|
|||
|
||||
if opt == "-h" || opt == "--help" {
|
||||
transformerFractionUsage(os.Stdout)
|
||||
os.Exit(0)
|
||||
return nil, cli.ErrHelpRequested
|
||||
|
||||
} else if opt == "-f" {
|
||||
fractionFieldNames = cli.VerbGetStringArrayArgOrDie(verb, opt, args, &argi, argc)
|
||||
fractionFieldNames, err = cli.VerbGetStringArrayArg(verb, opt, args, &argi, argc)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
} else if opt == "-g" {
|
||||
groupByFieldNames = cli.VerbGetStringArrayArgOrDie(verb, opt, args, &argi, argc)
|
||||
groupByFieldNames, err = cli.VerbGetStringArrayArg(verb, opt, args, &argi, argc)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
} else if opt == "-p" {
|
||||
doPercents = true
|
||||
|
|
@ -95,19 +102,17 @@ func transformerFractionParseCLI(
|
|||
doCumu = true
|
||||
|
||||
} else {
|
||||
transformerFractionUsage(os.Stderr)
|
||||
os.Exit(1)
|
||||
return nil, cli.VerbErrorf(verb, "option \"%s\" not recognized", opt)
|
||||
}
|
||||
}
|
||||
|
||||
if fractionFieldNames == nil {
|
||||
transformerFractionUsage(os.Stderr)
|
||||
os.Exit(1)
|
||||
return nil, cli.VerbErrorf(verb, "-f field names required")
|
||||
}
|
||||
|
||||
*pargi = argi
|
||||
if !doConstruct { // All transformers must do this for main command-line parsing
|
||||
return nil
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
transformer, err := NewTransformerFraction(
|
||||
|
|
@ -117,11 +122,10 @@ func transformerFractionParseCLI(
|
|||
doCumu,
|
||||
)
|
||||
if err != nil {
|
||||
fmt.Fprintf(os.Stderr, "mlr: %v\n", err)
|
||||
os.Exit(1)
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return transformer
|
||||
return transformer, nil
|
||||
}
|
||||
|
||||
type TransformerFraction struct {
|
||||
|
|
|
|||
|
|
@ -40,7 +40,7 @@ func transformerGapParseCLI(
|
|||
args []string,
|
||||
_ *cli.TOptions,
|
||||
doConstruct bool, // false for first pass of CLI-parse, true for second pass
|
||||
) RecordTransformer {
|
||||
) (RecordTransformer, error) {
|
||||
|
||||
// Skip the verb name from the current spot in the mlr command line
|
||||
argi := *pargi
|
||||
|
|
@ -50,6 +50,7 @@ func transformerGapParseCLI(
|
|||
gapCount := int64(-1)
|
||||
var groupByFieldNames []string = nil
|
||||
|
||||
var err error
|
||||
for argi < argc /* variable increment: 1 or 2 depending on flag */ {
|
||||
opt := args[argi]
|
||||
if !strings.HasPrefix(opt, "-") {
|
||||
|
|
@ -62,28 +63,33 @@ func transformerGapParseCLI(
|
|||
|
||||
if opt == "-h" || opt == "--help" {
|
||||
transformerGapUsage(os.Stdout)
|
||||
os.Exit(0)
|
||||
return nil, cli.ErrHelpRequested
|
||||
|
||||
} else if opt == "-n" {
|
||||
gapCount = cli.VerbGetIntArgOrDie(verb, opt, args, &argi, argc)
|
||||
gapCount, err = cli.VerbGetIntArg(verb, opt, args, &argi, argc)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
} else if opt == "-g" {
|
||||
groupByFieldNames = cli.VerbGetStringArrayArgOrDie(verb, opt, args, &argi, argc)
|
||||
groupByFieldNames, err = cli.VerbGetStringArrayArg(verb, opt, args, &argi, argc)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
} else {
|
||||
transformerGapUsage(os.Stderr)
|
||||
os.Exit(1)
|
||||
return nil, cli.VerbErrorf(verb, "option \"%s\" not recognized", opt)
|
||||
}
|
||||
}
|
||||
|
||||
if gapCount == -1 && groupByFieldNames == nil {
|
||||
transformerGapUsage(os.Stderr)
|
||||
os.Exit(1)
|
||||
return nil, cli.ErrUsagePrinted
|
||||
}
|
||||
|
||||
*pargi = argi
|
||||
if !doConstruct { // All transformers must do this for main command-line parsing
|
||||
return nil
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
transformer, err := NewTransformerGap(
|
||||
|
|
@ -91,11 +97,10 @@ func transformerGapParseCLI(
|
|||
groupByFieldNames,
|
||||
)
|
||||
if err != nil {
|
||||
fmt.Fprintf(os.Stderr, "mlr: %v\n", err)
|
||||
os.Exit(1)
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return transformer
|
||||
return transformer, nil
|
||||
}
|
||||
|
||||
type TransformerGap struct {
|
||||
|
|
|
|||
|
|
@ -51,7 +51,7 @@ func transformerGrepParseCLI(
|
|||
args []string,
|
||||
_ *cli.TOptions,
|
||||
doConstruct bool, // false for first pass of CLI-parse, true for second pass
|
||||
) RecordTransformer {
|
||||
) (RecordTransformer, error) {
|
||||
|
||||
// Skip the verb name from the current spot in the mlr command line
|
||||
argi := *pargi
|
||||
|
|
@ -74,7 +74,7 @@ func transformerGrepParseCLI(
|
|||
|
||||
if opt == "-h" || opt == "--help" {
|
||||
transformerGrepUsage(os.Stdout)
|
||||
os.Exit(0)
|
||||
return nil, cli.ErrHelpRequested
|
||||
|
||||
} else if opt == "-i" {
|
||||
ignoreCase = true
|
||||
|
|
@ -86,15 +86,13 @@ func transformerGrepParseCLI(
|
|||
valuesOnly = true
|
||||
|
||||
} else {
|
||||
transformerGrepUsage(os.Stderr)
|
||||
os.Exit(1)
|
||||
return nil, cli.VerbErrorf(verb, "option \"%s\" not recognized", opt)
|
||||
}
|
||||
}
|
||||
|
||||
// Get the regex from the command line
|
||||
if argi >= argc {
|
||||
transformerGrepUsage(os.Stderr)
|
||||
os.Exit(1)
|
||||
return nil, cli.VerbErrorf(verb, "pattern required")
|
||||
}
|
||||
pattern := args[argi]
|
||||
argi++
|
||||
|
|
@ -106,14 +104,12 @@ func transformerGrepParseCLI(
|
|||
// TODO: maybe CompilePOSIX
|
||||
regexp, err := regexp.Compile(pattern)
|
||||
if err != nil {
|
||||
fmt.Fprintf(os.Stderr, "%s %s: couldn't compile regex \"%s\"\n",
|
||||
"mlr", verb, pattern)
|
||||
os.Exit(1)
|
||||
return nil, cli.VerbErrorf(verb, "invalid regex \"%s\": %w", pattern, err)
|
||||
}
|
||||
|
||||
*pargi = argi
|
||||
if !doConstruct { // All transformers must do this for main command-line parsing
|
||||
return nil
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
transformer, err := NewTransformerGrep(
|
||||
|
|
@ -122,11 +118,10 @@ func transformerGrepParseCLI(
|
|||
valuesOnly,
|
||||
)
|
||||
if err != nil {
|
||||
fmt.Fprintf(os.Stderr, "mlr: %v\n", err)
|
||||
os.Exit(1)
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return transformer
|
||||
return transformer, nil
|
||||
}
|
||||
|
||||
type TransformerGrep struct {
|
||||
|
|
|
|||
|
|
@ -34,7 +34,7 @@ func transformerGroupByParseCLI(
|
|||
args []string,
|
||||
_ *cli.TOptions,
|
||||
doConstruct bool, // false for first pass of CLI-parse, true for second pass
|
||||
) RecordTransformer {
|
||||
) (RecordTransformer, error) {
|
||||
|
||||
// Skip the verb name from the current spot in the mlr command line
|
||||
argi := *pargi
|
||||
|
|
@ -52,35 +52,32 @@ func transformerGroupByParseCLI(
|
|||
|
||||
if opt == "-h" || opt == "--help" {
|
||||
transformerGroupByUsage(os.Stdout)
|
||||
os.Exit(0)
|
||||
return nil, cli.ErrHelpRequested
|
||||
|
||||
}
|
||||
transformerGroupByUsage(os.Stderr)
|
||||
os.Exit(1)
|
||||
return nil, cli.VerbErrorf(verbNameGroupBy, "option \"%s\" not recognized", opt)
|
||||
}
|
||||
|
||||
// Get the group-by field names from the command line
|
||||
if argi >= argc {
|
||||
transformerGroupByUsage(os.Stderr)
|
||||
os.Exit(1)
|
||||
return nil, cli.VerbErrorf(verbNameGroupBy, "group-by field names required")
|
||||
}
|
||||
groupByFieldNames := lib.SplitString(args[argi], ",")
|
||||
argi++
|
||||
|
||||
*pargi = argi
|
||||
if !doConstruct { // All transformers must do this for main command-line parsing
|
||||
return nil
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
transformer, err := NewTransformerGroupBy(
|
||||
groupByFieldNames,
|
||||
)
|
||||
if err != nil {
|
||||
fmt.Fprintf(os.Stderr, "mlr: %v\n", err)
|
||||
os.Exit(1)
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return transformer
|
||||
return transformer, nil
|
||||
}
|
||||
|
||||
type TransformerGroupBy struct {
|
||||
|
|
|
|||
|
|
@ -34,7 +34,7 @@ func transformerGroupLikeParseCLI(
|
|||
args []string,
|
||||
_ *cli.TOptions,
|
||||
doConstruct bool, // false for first pass of CLI-parse, true for second pass
|
||||
) RecordTransformer {
|
||||
) (RecordTransformer, error) {
|
||||
|
||||
// Skip the verb name from the current spot in the mlr command line
|
||||
argi := *pargi
|
||||
|
|
@ -52,25 +52,23 @@ func transformerGroupLikeParseCLI(
|
|||
|
||||
if opt == "-h" || opt == "--help" {
|
||||
transformerGroupLikeUsage(os.Stdout)
|
||||
os.Exit(0)
|
||||
return nil, cli.ErrHelpRequested
|
||||
|
||||
}
|
||||
transformerGroupLikeUsage(os.Stderr)
|
||||
os.Exit(1)
|
||||
return nil, cli.VerbErrorf(verbNameGroupLike, "option \"%s\" not recognized", opt)
|
||||
}
|
||||
|
||||
*pargi = argi
|
||||
if !doConstruct { // All transformers must do this for main command-line parsing
|
||||
return nil
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
transformer, err := NewTransformerGroupLike()
|
||||
if err != nil {
|
||||
fmt.Fprintf(os.Stderr, "mlr: %v\n", err)
|
||||
os.Exit(1)
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return transformer
|
||||
return transformer, nil
|
||||
}
|
||||
|
||||
type TransformerGroupLike struct {
|
||||
|
|
|
|||
|
|
@ -61,7 +61,7 @@ func transformerHavingFieldsParseCLI(
|
|||
args []string,
|
||||
_ *cli.TOptions,
|
||||
doConstruct bool, // false for first pass of CLI-parse, true for second pass
|
||||
) RecordTransformer {
|
||||
) (RecordTransformer, error) {
|
||||
|
||||
havingFieldsCriterion := havingFieldsCriterionUnspecified
|
||||
var fieldNames []string = nil
|
||||
|
|
@ -72,6 +72,7 @@ func transformerHavingFieldsParseCLI(
|
|||
verb := args[argi]
|
||||
argi++
|
||||
|
||||
var err error
|
||||
for argi < argc /* variable increment: 1 or 2 depending on flag */ {
|
||||
opt := args[argi]
|
||||
if !strings.HasPrefix(opt, "-") {
|
||||
|
|
@ -84,56 +85,71 @@ func transformerHavingFieldsParseCLI(
|
|||
|
||||
if opt == "-h" || opt == "--help" {
|
||||
transformerHavingFieldsUsage(os.Stdout)
|
||||
os.Exit(0)
|
||||
return nil, cli.ErrHelpRequested
|
||||
|
||||
} else if opt == "--at-least" {
|
||||
havingFieldsCriterion = havingFieldsAtLeast
|
||||
fieldNames = cli.VerbGetStringArrayArgOrDie(verb, opt, args, &argi, argc)
|
||||
fieldNames, err = cli.VerbGetStringArrayArg(verb, opt, args, &argi, argc)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
regexString = ""
|
||||
|
||||
} else if opt == "--which-are" {
|
||||
havingFieldsCriterion = havingFieldsWhichAre
|
||||
fieldNames = cli.VerbGetStringArrayArgOrDie(verb, opt, args, &argi, argc)
|
||||
fieldNames, err = cli.VerbGetStringArrayArg(verb, opt, args, &argi, argc)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
regexString = ""
|
||||
|
||||
} else if opt == "--at-most" {
|
||||
havingFieldsCriterion = havingFieldsAtMost
|
||||
fieldNames = cli.VerbGetStringArrayArgOrDie(verb, opt, args, &argi, argc)
|
||||
fieldNames, err = cli.VerbGetStringArrayArg(verb, opt, args, &argi, argc)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
regexString = ""
|
||||
|
||||
} else if opt == "--all-matching" {
|
||||
havingFieldsCriterion = havingAllFieldsMatching
|
||||
regexString = cli.VerbGetStringArgOrDie(verb, opt, args, &argi, argc)
|
||||
regexString, err = cli.VerbGetStringArg(verb, opt, args, &argi, argc)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
fieldNames = nil
|
||||
|
||||
} else if opt == "--any-matching" {
|
||||
havingFieldsCriterion = havingAnyFieldsMatching
|
||||
regexString = cli.VerbGetStringArgOrDie(verb, opt, args, &argi, argc)
|
||||
regexString, err = cli.VerbGetStringArg(verb, opt, args, &argi, argc)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
fieldNames = nil
|
||||
|
||||
} else if opt == "--none-matching" {
|
||||
havingFieldsCriterion = havingNoFieldsMatching
|
||||
regexString = cli.VerbGetStringArgOrDie(verb, opt, args, &argi, argc)
|
||||
regexString, err = cli.VerbGetStringArg(verb, opt, args, &argi, argc)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
fieldNames = nil
|
||||
|
||||
} else {
|
||||
transformerHavingFieldsUsage(os.Stderr)
|
||||
os.Exit(1)
|
||||
return nil, cli.VerbErrorf(verb, "option \"%s\" not recognized", opt)
|
||||
}
|
||||
}
|
||||
|
||||
if havingFieldsCriterion == havingFieldsCriterionUnspecified {
|
||||
transformerHavingFieldsUsage(os.Stderr)
|
||||
os.Exit(1)
|
||||
return nil, cli.VerbErrorf(verb, "-a, -b, -n, or --any-matching/--all-matching/--none-matching is required")
|
||||
}
|
||||
if fieldNames == nil && regexString == "" {
|
||||
transformerHavingFieldsUsage(os.Stderr)
|
||||
os.Exit(1)
|
||||
return nil, cli.VerbErrorf(verb, "field names or regex required")
|
||||
}
|
||||
|
||||
*pargi = argi
|
||||
if !doConstruct { // All transformers must do this for main command-line parsing
|
||||
return nil
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
transformer, err := NewTransformerHavingFields(
|
||||
|
|
@ -142,11 +158,10 @@ func transformerHavingFieldsParseCLI(
|
|||
regexString,
|
||||
)
|
||||
if err != nil {
|
||||
fmt.Fprintf(os.Stderr, "mlr: %v\n", err)
|
||||
os.Exit(1)
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return transformer
|
||||
return transformer, nil
|
||||
}
|
||||
|
||||
type TransformerHavingFields struct {
|
||||
|
|
|
|||
|
|
@ -37,7 +37,7 @@ func transformerHeadParseCLI(
|
|||
args []string,
|
||||
_ *cli.TOptions,
|
||||
doConstruct bool, // false for first pass of CLI-parse, true for second pass
|
||||
) RecordTransformer {
|
||||
) (RecordTransformer, error) {
|
||||
|
||||
// Skip the verb name from the current spot in the mlr command line
|
||||
argi := *pargi
|
||||
|
|
@ -59,10 +59,14 @@ func transformerHeadParseCLI(
|
|||
|
||||
if opt == "-h" || opt == "--help" {
|
||||
transformerHeadUsage(os.Stdout)
|
||||
os.Exit(0)
|
||||
return nil, cli.ErrHelpRequested
|
||||
|
||||
} else if opt == "-n" {
|
||||
headCount = cli.VerbGetIntArgOrDie(verb, opt, args, &argi, argc)
|
||||
n, err := cli.VerbGetIntArg(verb, opt, args, &argi, argc)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
headCount = n
|
||||
|
||||
// This is a bit of a hack. In our Getoptify routine we preprocess
|
||||
// the command line sending '-xyz' to '-x -y -z', but leaving
|
||||
|
|
@ -75,17 +79,21 @@ func transformerHeadParseCLI(
|
|||
}
|
||||
|
||||
} else if opt == "-g" {
|
||||
groupByFieldNames = cli.VerbGetStringArrayArgOrDie(verb, opt, args, &argi, argc)
|
||||
names, err := cli.VerbGetStringArrayArg(verb, opt, args, &argi, argc)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
groupByFieldNames = names
|
||||
|
||||
} else {
|
||||
transformerHeadUsage(os.Stderr)
|
||||
os.Exit(1)
|
||||
return nil, fmt.Errorf("%s %s: option \"%s\" not recognized", "mlr", verb, opt)
|
||||
}
|
||||
}
|
||||
|
||||
*pargi = argi
|
||||
if !doConstruct { // All transformers must do this for main command-line parsing
|
||||
return nil
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
transformer, err := NewTransformerHead(
|
||||
|
|
@ -93,11 +101,10 @@ func transformerHeadParseCLI(
|
|||
groupByFieldNames,
|
||||
)
|
||||
if err != nil {
|
||||
fmt.Fprintf(os.Stderr, "mlr: %v\n", err)
|
||||
os.Exit(1)
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return transformer
|
||||
return transformer, nil
|
||||
}
|
||||
|
||||
type TransformerHead struct {
|
||||
|
|
|
|||
|
|
@ -44,7 +44,7 @@ func transformerHistogramParseCLI(
|
|||
args []string,
|
||||
_ *cli.TOptions,
|
||||
doConstruct bool, // false for first pass of CLI-parse, true for second pass
|
||||
) RecordTransformer {
|
||||
) (RecordTransformer, error) {
|
||||
|
||||
// Skip the verb name from the current spot in the mlr command line
|
||||
argi := *pargi
|
||||
|
|
@ -59,6 +59,7 @@ func transformerHistogramParseCLI(
|
|||
doAuto := false
|
||||
outputPrefix := ""
|
||||
|
||||
var err error
|
||||
for argi < argc /* variable increment: 1 or 2 depending on flag */ {
|
||||
opt := args[argi]
|
||||
if !strings.HasPrefix(opt, "-") {
|
||||
|
|
@ -71,50 +72,61 @@ func transformerHistogramParseCLI(
|
|||
|
||||
if opt == "-h" || opt == "--help" {
|
||||
transformerHistogramUsage(os.Stdout)
|
||||
os.Exit(0)
|
||||
return nil, cli.ErrHelpRequested
|
||||
|
||||
} else if opt == "-f" {
|
||||
valueFieldNames = cli.VerbGetStringArrayArgOrDie(verb, opt, args, &argi, argc)
|
||||
valueFieldNames, err = cli.VerbGetStringArrayArg(verb, opt, args, &argi, argc)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
} else if opt == "--lo" {
|
||||
lo = cli.VerbGetFloatArgOrDie(verb, opt, args, &argi, argc)
|
||||
lo, err = cli.VerbGetFloatArg(verb, opt, args, &argi, argc)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
} else if opt == "--nbins" {
|
||||
nbins = cli.VerbGetIntArgOrDie(verb, opt, args, &argi, argc)
|
||||
nbins, err = cli.VerbGetIntArg(verb, opt, args, &argi, argc)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
} else if opt == "--hi" {
|
||||
hi = cli.VerbGetFloatArgOrDie(verb, opt, args, &argi, argc)
|
||||
hi, err = cli.VerbGetFloatArg(verb, opt, args, &argi, argc)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
} else if opt == "--auto" {
|
||||
doAuto = true
|
||||
|
||||
} else if opt == "-o" {
|
||||
outputPrefix = cli.VerbGetStringArgOrDie(verb, opt, args, &argi, argc)
|
||||
outputPrefix, err = cli.VerbGetStringArg(verb, opt, args, &argi, argc)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
} else {
|
||||
transformerHistogramUsage(os.Stderr)
|
||||
os.Exit(1)
|
||||
return nil, cli.VerbErrorf(verb, "option \"%s\" not recognized", opt)
|
||||
}
|
||||
}
|
||||
|
||||
if valueFieldNames == nil {
|
||||
transformerHistogramUsage(os.Stderr)
|
||||
os.Exit(1)
|
||||
return nil, cli.VerbErrorf(verb, "-f field names required")
|
||||
}
|
||||
|
||||
if nbins <= 0 {
|
||||
transformerHistogramUsage(os.Stderr)
|
||||
os.Exit(1)
|
||||
return nil, cli.VerbErrorf(verb, "number of bins must be positive")
|
||||
}
|
||||
|
||||
if lo == hi && !doAuto {
|
||||
transformerHistogramUsage(os.Stderr)
|
||||
os.Exit(1)
|
||||
return nil, cli.VerbErrorf(verb, "lo and hi must differ, or use --auto")
|
||||
}
|
||||
|
||||
*pargi = argi
|
||||
if !doConstruct { // All transformers must do this for main command-line parsing
|
||||
return nil
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
transformer, err := NewTransformerHistogram(
|
||||
|
|
@ -126,11 +138,10 @@ func transformerHistogramParseCLI(
|
|||
outputPrefix,
|
||||
)
|
||||
if err != nil {
|
||||
fmt.Fprintf(os.Stderr, "mlr: %v\n", err)
|
||||
os.Exit(1)
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return transformer
|
||||
return transformer, nil
|
||||
}
|
||||
|
||||
const histogramVectorInitialSize = 1024
|
||||
|
|
|
|||
|
|
@ -136,7 +136,7 @@ func transformerJoinParseCLI(
|
|||
args []string,
|
||||
mainOptions *cli.TOptions, // Options for the right-files
|
||||
doConstruct bool, // false for first pass of CLI-parse, true for second pass
|
||||
) RecordTransformer {
|
||||
) (RecordTransformer, error) {
|
||||
|
||||
// Skip the verb name from the current spot in the mlr command line
|
||||
argi := *pargi
|
||||
|
|
@ -151,6 +151,7 @@ func transformerJoinParseCLI(
|
|||
opts.joinFlagOptions = *mainOptions // struct copy
|
||||
}
|
||||
|
||||
var err error
|
||||
for argi < argc /* variable increment: 1 or 2 depending on flag */ {
|
||||
opt := args[argi]
|
||||
if !strings.HasPrefix(opt, "-") {
|
||||
|
|
@ -163,36 +164,63 @@ func transformerJoinParseCLI(
|
|||
|
||||
if opt == "-h" || opt == "--help" {
|
||||
transformerJoinUsage(os.Stdout)
|
||||
os.Exit(0)
|
||||
return nil, cli.ErrHelpRequested
|
||||
|
||||
} else if opt == "--prepipe" {
|
||||
opts.prepipe = cli.VerbGetStringArgOrDie(verb, opt, args, &argi, argc)
|
||||
opts.prepipe, err = cli.VerbGetStringArg(verb, opt, args, &argi, argc)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
opts.prepipeIsRaw = false
|
||||
|
||||
} else if opt == "--prepipex" {
|
||||
opts.prepipe = cli.VerbGetStringArgOrDie(verb, opt, args, &argi, argc)
|
||||
opts.prepipe, err = cli.VerbGetStringArg(verb, opt, args, &argi, argc)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
opts.prepipeIsRaw = true
|
||||
|
||||
} else if opt == "-f" {
|
||||
opts.leftFileName = cli.VerbGetStringArgOrDie(verb, opt, args, &argi, argc)
|
||||
opts.leftFileName, err = cli.VerbGetStringArg(verb, opt, args, &argi, argc)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
} else if opt == "-j" {
|
||||
opts.outputJoinFieldNames = cli.VerbGetStringArrayArgOrDie(verb, opt, args, &argi, argc)
|
||||
opts.outputJoinFieldNames, err = cli.VerbGetStringArrayArg(verb, opt, args, &argi, argc)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
} else if opt == "-l" {
|
||||
opts.leftJoinFieldNames = cli.VerbGetStringArrayArgOrDie(verb, opt, args, &argi, argc)
|
||||
opts.leftJoinFieldNames, err = cli.VerbGetStringArrayArg(verb, opt, args, &argi, argc)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
} else if opt == "--lk" || opt == "--left-keep-field-names" {
|
||||
opts.leftKeepFieldNames = cli.VerbGetStringArrayArgOrDie(verb, opt, args, &argi, argc)
|
||||
opts.leftKeepFieldNames, err = cli.VerbGetStringArrayArg(verb, opt, args, &argi, argc)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
} else if opt == "-r" {
|
||||
opts.rightJoinFieldNames = cli.VerbGetStringArrayArgOrDie(verb, opt, args, &argi, argc)
|
||||
opts.rightJoinFieldNames, err = cli.VerbGetStringArrayArg(verb, opt, args, &argi, argc)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
} else if opt == "--lp" {
|
||||
opts.leftPrefix = cli.VerbGetStringArgOrDie(verb, opt, args, &argi, argc)
|
||||
opts.leftPrefix, err = cli.VerbGetStringArg(verb, opt, args, &argi, argc)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
} else if opt == "--rp" {
|
||||
opts.rightPrefix = cli.VerbGetStringArgOrDie(verb, opt, args, &argi, argc)
|
||||
opts.rightPrefix, err = cli.VerbGetStringArg(verb, opt, args, &argi, argc)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
} else if opt == "--np" {
|
||||
opts.emitPairables = false
|
||||
|
|
@ -219,8 +247,7 @@ func transformerJoinParseCLI(
|
|||
// Nothing else to handle here.
|
||||
argi = largi
|
||||
} else {
|
||||
transformerJoinUsage(os.Stderr)
|
||||
os.Exit(1)
|
||||
return nil, cli.VerbErrorf(verb, "input format option not recognized")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -228,25 +255,15 @@ func transformerJoinParseCLI(
|
|||
cli.FinalizeReaderOptions(&opts.joinFlagOptions.ReaderOptions)
|
||||
|
||||
if opts.leftFileName == "" {
|
||||
fmt.Fprintf(os.Stderr, "%s %s: need left file name\n", "mlr", verb)
|
||||
transformerJoinUsage(os.Stderr)
|
||||
os.Exit(1)
|
||||
return nil
|
||||
return nil, cli.VerbErrorf(verb, "need left file name")
|
||||
}
|
||||
|
||||
if !opts.emitPairables && !opts.emitLeftUnpairables && !opts.emitRightUnpairables {
|
||||
fmt.Fprintf(os.Stderr, "%s %s: all emit flags are unset; no output is possible.\n",
|
||||
"mlr", verb)
|
||||
transformerJoinUsage(os.Stderr)
|
||||
os.Exit(1)
|
||||
return nil
|
||||
return nil, cli.VerbErrorf(verb, "all emit flags are unset; no output is possible")
|
||||
}
|
||||
|
||||
if opts.outputJoinFieldNames == nil {
|
||||
fmt.Fprintf(os.Stderr, "%s %s: need output field names\n", "mlr", verb)
|
||||
transformerJoinUsage(os.Stderr)
|
||||
os.Exit(1)
|
||||
return nil
|
||||
return nil, cli.VerbErrorf(verb, "need output field names")
|
||||
}
|
||||
|
||||
if opts.leftJoinFieldNames == nil {
|
||||
|
|
@ -260,24 +277,20 @@ func transformerJoinParseCLI(
|
|||
rlen := len(opts.rightJoinFieldNames)
|
||||
olen := len(opts.outputJoinFieldNames)
|
||||
if llen != rlen || llen != olen {
|
||||
fmt.Fprintf(os.Stderr,
|
||||
"%s %s: must have equal left,right,output field-name lists; got lengths %d,%d,%d.\n",
|
||||
"mlr", verb, llen, rlen, olen)
|
||||
os.Exit(1)
|
||||
return nil, cli.VerbErrorf(verb, "left, right, and output field lists must have same length")
|
||||
}
|
||||
|
||||
*pargi = argi
|
||||
if !doConstruct { // All transformers must do this for main command-line parsing
|
||||
return nil
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
transformer, err := NewTransformerJoin(opts)
|
||||
if err != nil {
|
||||
fmt.Fprintf(os.Stderr, "mlr: %v\n", err)
|
||||
os.Exit(1)
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return transformer
|
||||
return transformer, nil
|
||||
}
|
||||
|
||||
type TransformerJoin struct {
|
||||
|
|
@ -470,9 +483,9 @@ func (tr *TransformerJoin) ingestLeftFile() {
|
|||
// Instantiate the record-reader
|
||||
// TODO: perhaps increase recordsPerBatch, and/or refactor
|
||||
recordReader, err := input.Create(readerOpts, 1)
|
||||
if recordReader == nil {
|
||||
fmt.Fprintf(os.Stderr, "mlr join: %v\n", err)
|
||||
os.Exit(1)
|
||||
if err != nil {
|
||||
// TODO: propagate error to caller
|
||||
return
|
||||
}
|
||||
|
||||
// Set the initial context for the left-file.
|
||||
|
|
@ -501,8 +514,9 @@ func (tr *TransformerJoin) ingestLeftFile() {
|
|||
select {
|
||||
|
||||
case err := <-errorChannel:
|
||||
fmt.Fprintf(os.Stderr, "mlr: %v\n", err)
|
||||
os.Exit(1)
|
||||
// TODO: propagate error to caller
|
||||
_ = err
|
||||
return
|
||||
|
||||
case leftrecsAndContexts := <-readerChannel:
|
||||
// TODO: temp for batch-reader refactor
|
||||
|
|
|
|||
|
|
@ -40,7 +40,7 @@ func transformerJSONParseParseCLI(
|
|||
args []string,
|
||||
_ *cli.TOptions,
|
||||
doConstruct bool, // false for first pass of CLI-parse, true for second pass
|
||||
) RecordTransformer {
|
||||
) (RecordTransformer, error) {
|
||||
|
||||
// Skip the verb name from the current spot in the mlr command line
|
||||
argi := *pargi
|
||||
|
|
@ -50,6 +50,7 @@ func transformerJSONParseParseCLI(
|
|||
|
||||
var fieldNames []string = nil
|
||||
|
||||
var err error
|
||||
for argi < argc /* variable increment: 1 or 2 depending on flag */ {
|
||||
opt := args[argi]
|
||||
if !strings.HasPrefix(opt, "-") {
|
||||
|
|
@ -62,23 +63,25 @@ func transformerJSONParseParseCLI(
|
|||
|
||||
if opt == "-h" || opt == "--help" {
|
||||
transformerJSONParseUsage(os.Stdout)
|
||||
os.Exit(0)
|
||||
return nil, cli.ErrHelpRequested
|
||||
|
||||
} else if opt == "-f" {
|
||||
fieldNames = cli.VerbGetStringArrayArgOrDie(verb, opt, args, &argi, argc)
|
||||
fieldNames, err = cli.VerbGetStringArrayArg(verb, opt, args, &argi, argc)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
} else if opt == "-k" {
|
||||
keepFailed = true
|
||||
|
||||
} else {
|
||||
transformerJSONParseUsage(os.Stderr)
|
||||
os.Exit(1)
|
||||
return nil, cli.VerbErrorf(verb, "option \"%s\" not recognized", opt)
|
||||
}
|
||||
}
|
||||
|
||||
*pargi = argi
|
||||
if !doConstruct { // All transformers must do this for main command-line parsing
|
||||
return nil
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
transformer, err := NewTransformerJSONParse(
|
||||
|
|
@ -86,11 +89,10 @@ func transformerJSONParseParseCLI(
|
|||
keepFailed,
|
||||
)
|
||||
if err != nil {
|
||||
fmt.Fprintf(os.Stderr, "mlr: %v\n", err)
|
||||
os.Exit(1)
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return transformer
|
||||
return transformer, nil
|
||||
}
|
||||
|
||||
type TransformerJSONParse struct {
|
||||
|
|
|
|||
|
|
@ -40,7 +40,7 @@ func transformerJSONStringifyParseCLI(
|
|||
args []string,
|
||||
_ *cli.TOptions,
|
||||
doConstruct bool, // false for first pass of CLI-parse, true for second pass
|
||||
) RecordTransformer {
|
||||
) (RecordTransformer, error) {
|
||||
|
||||
// Skip the verb name from the current spot in the mlr command line
|
||||
argi := *pargi
|
||||
|
|
@ -50,6 +50,7 @@ func transformerJSONStringifyParseCLI(
|
|||
var fieldNames []string = nil
|
||||
jvStack := false // TODO: ??
|
||||
|
||||
var err error
|
||||
for argi < argc /* variable increment: 1 or 2 depending on flag */ {
|
||||
opt := args[argi]
|
||||
if !strings.HasPrefix(opt, "-") {
|
||||
|
|
@ -62,10 +63,13 @@ func transformerJSONStringifyParseCLI(
|
|||
|
||||
if opt == "-h" || opt == "--help" {
|
||||
transformerJSONStringifyUsage(os.Stdout)
|
||||
os.Exit(0)
|
||||
return nil, cli.ErrHelpRequested
|
||||
|
||||
} else if opt == "-f" {
|
||||
fieldNames = cli.VerbGetStringArrayArgOrDie(verb, opt, args, &argi, argc)
|
||||
fieldNames, err = cli.VerbGetStringArrayArg(verb, opt, args, &argi, argc)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
} else if opt == "--jvstack" {
|
||||
jvStack = true
|
||||
|
|
@ -74,8 +78,7 @@ func transformerJSONStringifyParseCLI(
|
|||
jvStack = false
|
||||
|
||||
} else {
|
||||
transformerJSONStringifyUsage(os.Stderr)
|
||||
os.Exit(1)
|
||||
return nil, cli.VerbErrorf(verb, "option \"%s\" not recognized", opt)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -88,7 +91,7 @@ func transformerJSONStringifyParseCLI(
|
|||
|
||||
*pargi = argi
|
||||
if !doConstruct { // All transformers must do this for main command-line parsing
|
||||
return nil
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
transformer, err := NewTransformerJSONStringify(
|
||||
|
|
@ -96,11 +99,10 @@ func transformerJSONStringifyParseCLI(
|
|||
fieldNames,
|
||||
)
|
||||
if err != nil {
|
||||
fmt.Fprintf(os.Stderr, "mlr: %v\n", err)
|
||||
os.Exit(1)
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return transformer
|
||||
return transformer, nil
|
||||
}
|
||||
|
||||
type TransformerJSONStringify struct {
|
||||
|
|
|
|||
|
|
@ -38,7 +38,7 @@ func transformerLabelParseCLI(
|
|||
args []string,
|
||||
_ *cli.TOptions,
|
||||
doConstruct bool, // false for first pass of CLI-parse, true for second pass
|
||||
) RecordTransformer {
|
||||
) (RecordTransformer, error) {
|
||||
|
||||
// Skip the verb name from the current spot in the mlr command line
|
||||
argi := *pargi
|
||||
|
|
@ -56,36 +56,32 @@ func transformerLabelParseCLI(
|
|||
|
||||
if opt == "-h" || opt == "--help" {
|
||||
transformerLabelUsage(os.Stdout)
|
||||
os.Exit(0)
|
||||
return nil, cli.ErrHelpRequested
|
||||
|
||||
}
|
||||
transformerLabelUsage(os.Stderr)
|
||||
os.Exit(1)
|
||||
return nil, cli.VerbErrorf(verbNameLabel, "option \"%s\" not recognized", opt)
|
||||
}
|
||||
|
||||
// Get the label field names from the command line
|
||||
if argi >= argc {
|
||||
transformerLabelUsage(os.Stderr)
|
||||
os.Exit(1)
|
||||
return nil, cli.VerbErrorf(verbNameLabel, "field names required")
|
||||
}
|
||||
newNames := lib.SplitString(args[argi], ",")
|
||||
argi++
|
||||
|
||||
*pargi = argi
|
||||
if !doConstruct { // All transformers must do this for main command-line parsing
|
||||
return nil
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
transformer, err := NewTransformerLabel(
|
||||
newNames,
|
||||
)
|
||||
if err != nil {
|
||||
fmt.Fprintf(os.Stderr, "mlr label: %v\n", err)
|
||||
os.Exit(1)
|
||||
// TODO: return nil to caller and have it exit, maybe
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return transformer
|
||||
return transformer, nil
|
||||
}
|
||||
|
||||
type TransformerLabel struct {
|
||||
|
|
@ -100,7 +96,7 @@ func NewTransformerLabel(
|
|||
for _, newName := range newNames {
|
||||
_, ok := uniquenessChecker[newName]
|
||||
if ok {
|
||||
return nil, fmt.Errorf(`labels must be unique; got duplicate "%s"`, newName)
|
||||
return nil, fmt.Errorf(`mlr label: labels must be unique; got duplicate "%s"`, newName)
|
||||
}
|
||||
uniquenessChecker[newName] = true
|
||||
}
|
||||
|
|
|
|||
|
|
@ -36,7 +36,7 @@ func transformerLatin1ToUTF8ParseCLI(
|
|||
args []string,
|
||||
_ *cli.TOptions,
|
||||
doConstruct bool, // false for first pass of CLI-parse, true for second pass
|
||||
) RecordTransformer {
|
||||
) (RecordTransformer, error) {
|
||||
|
||||
// Skip the verb name from the current spot in the mlr command line
|
||||
argi := *pargi
|
||||
|
|
@ -54,25 +54,23 @@ func transformerLatin1ToUTF8ParseCLI(
|
|||
|
||||
if opt == "-h" || opt == "--help" {
|
||||
transformerLatin1ToUTF8Usage(os.Stdout)
|
||||
os.Exit(0)
|
||||
return nil, cli.ErrHelpRequested
|
||||
|
||||
}
|
||||
transformerLatin1ToUTF8Usage(os.Stderr)
|
||||
os.Exit(1)
|
||||
return nil, cli.VerbErrorf(verbNameLatin1ToUTF8, "option \"%s\" not recognized", opt)
|
||||
}
|
||||
|
||||
*pargi = argi
|
||||
if !doConstruct { // All transformers must do this for main command-line parsing
|
||||
return nil
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
transformer, err := NewTransformerLatin1ToUTF8()
|
||||
if err != nil {
|
||||
fmt.Fprintf(os.Stderr, "mlr: %v\n", err)
|
||||
os.Exit(1)
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return transformer
|
||||
return transformer, nil
|
||||
}
|
||||
|
||||
type TransformerLatin1ToUTF8 struct {
|
||||
|
|
|
|||
|
|
@ -75,7 +75,7 @@ func transformerMergeFieldsParseCLI(
|
|||
args []string,
|
||||
_ *cli.TOptions,
|
||||
doConstruct bool, // false for first pass of CLI-parse, true for second pass
|
||||
) RecordTransformer {
|
||||
) (RecordTransformer, error) {
|
||||
|
||||
// Skip the verb name from the current spot in the mlr command line
|
||||
argi := *pargi
|
||||
|
|
@ -89,6 +89,7 @@ func transformerMergeFieldsParseCLI(
|
|||
keepInputFields := false
|
||||
doInterpolatedPercentiles := false
|
||||
|
||||
var err error
|
||||
for argi < argc /* variable increment: 1 or 2 depending on flag */ {
|
||||
opt := args[argi]
|
||||
if !strings.HasPrefix(opt, "-") {
|
||||
|
|
@ -101,25 +102,40 @@ func transformerMergeFieldsParseCLI(
|
|||
|
||||
if opt == "-h" || opt == "--help" {
|
||||
transformerMergeFieldsUsage(os.Stdout)
|
||||
os.Exit(0)
|
||||
return nil, cli.ErrHelpRequested
|
||||
|
||||
} else if opt == "-a" {
|
||||
accumulatorNameList = cli.VerbGetStringArrayArgOrDie(verb, opt, args, &argi, argc)
|
||||
accumulatorNameList, err = cli.VerbGetStringArrayArg(verb, opt, args, &argi, argc)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
} else if opt == "-f" {
|
||||
valueFieldNameList = cli.VerbGetStringArrayArgOrDie(verb, opt, args, &argi, argc)
|
||||
valueFieldNameList, err = cli.VerbGetStringArrayArg(verb, opt, args, &argi, argc)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
doWhich = e_MERGE_BY_NAME_LIST
|
||||
|
||||
} else if opt == "-r" {
|
||||
valueFieldNameList = cli.VerbGetStringArrayArgOrDie(verb, opt, args, &argi, argc)
|
||||
valueFieldNameList, err = cli.VerbGetStringArrayArg(verb, opt, args, &argi, argc)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
doWhich = e_MERGE_BY_NAME_REGEX
|
||||
|
||||
} else if opt == "-c" {
|
||||
valueFieldNameList = cli.VerbGetStringArrayArgOrDie(verb, opt, args, &argi, argc)
|
||||
valueFieldNameList, err = cli.VerbGetStringArrayArg(verb, opt, args, &argi, argc)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
doWhich = e_MERGE_BY_COLLAPSING
|
||||
|
||||
} else if opt == "-o" {
|
||||
outputFieldBasename = cli.VerbGetStringArgOrDie(verb, opt, args, &argi, argc)
|
||||
outputFieldBasename, err = cli.VerbGetStringArg(verb, opt, args, &argi, argc)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
} else if opt == "-k" {
|
||||
keepInputFields = true
|
||||
|
|
@ -134,32 +150,26 @@ func transformerMergeFieldsParseCLI(
|
|||
// No-op pass-through for backward compatibility with Miller 5
|
||||
|
||||
} else {
|
||||
transformerMergeFieldsUsage(os.Stderr)
|
||||
os.Exit(1)
|
||||
return nil, cli.VerbErrorf(verb, "option \"%s\" not recognized", opt)
|
||||
}
|
||||
}
|
||||
|
||||
// TODO: libify for use across verbs.
|
||||
if len(accumulatorNameList) == 0 {
|
||||
fmt.Fprintf(os.Stderr, "%s %s: -a option is required.\n", "mlr", verbNameMergeFields)
|
||||
fmt.Fprintf(os.Stderr, "Please see %s %s --help for more information.\n", "mlr", verbNameMergeFields)
|
||||
os.Exit(1)
|
||||
return nil, cli.VerbErrorf(verbNameMergeFields, "-a option is required")
|
||||
}
|
||||
if len(valueFieldNameList) == 0 {
|
||||
fmt.Fprintf(os.Stderr, "%s %s: -f option is required.\n", "mlr", verbNameMergeFields)
|
||||
fmt.Fprintf(os.Stderr, "Please see %s %s --help for more information.\n", "mlr", verbNameMergeFields)
|
||||
os.Exit(1)
|
||||
return nil, cli.VerbErrorf(verbNameMergeFields, "-f option is required")
|
||||
}
|
||||
if outputFieldBasename == "" {
|
||||
if doWhich == e_MERGE_BY_NAME_LIST || doWhich == e_MERGE_BY_NAME_REGEX {
|
||||
transformerMergeFieldsUsage(os.Stderr)
|
||||
os.Exit(1)
|
||||
return nil, cli.VerbErrorf(verbNameMergeFields, "-o output field basename required")
|
||||
}
|
||||
}
|
||||
|
||||
*pargi = argi
|
||||
if !doConstruct { // All transformers must do this for main command-line parsing
|
||||
return nil
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
transformer, err := NewTransformerMergeFields(
|
||||
|
|
@ -171,11 +181,10 @@ func transformerMergeFieldsParseCLI(
|
|||
keepInputFields,
|
||||
)
|
||||
if err != nil {
|
||||
fmt.Fprintf(os.Stderr, "mlr: %v\n", err)
|
||||
os.Exit(1)
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return transformer
|
||||
return transformer, nil
|
||||
}
|
||||
|
||||
// Given: accumulate count,sum on values x,y group by a,b.
|
||||
|
|
|
|||
|
|
@ -70,7 +70,7 @@ func transformerMostFrequentParseCLI(
|
|||
args []string,
|
||||
_ *cli.TOptions,
|
||||
doConstruct bool, // false for first pass of CLI-parse, true for second pass
|
||||
) RecordTransformer {
|
||||
) (RecordTransformer, error) {
|
||||
return transformerMostOrLeastFrequentParseCLI(pargi, argc, args, true, transformerMostFrequentUsage, doConstruct)
|
||||
}
|
||||
|
||||
|
|
@ -80,7 +80,7 @@ func transformerLeastFrequentParseCLI(
|
|||
args []string,
|
||||
_ *cli.TOptions,
|
||||
doConstruct bool, // false for first pass of CLI-parse, true for second pass
|
||||
) RecordTransformer {
|
||||
) (RecordTransformer, error) {
|
||||
return transformerMostOrLeastFrequentParseCLI(pargi, argc, args, false, transformerLeastFrequentUsage, doConstruct)
|
||||
}
|
||||
|
||||
|
|
@ -91,7 +91,7 @@ func transformerMostOrLeastFrequentParseCLI(
|
|||
descending bool,
|
||||
usageFunc TransformerUsageFunc,
|
||||
doConstruct bool, // false for first pass of CLI-parse, true for second pass
|
||||
) RecordTransformer {
|
||||
) (RecordTransformer, error) {
|
||||
|
||||
// Skip the verb name from the current spot in the mlr command line
|
||||
argi := *pargi
|
||||
|
|
@ -104,6 +104,7 @@ func transformerMostOrLeastFrequentParseCLI(
|
|||
showCounts := true
|
||||
outputFieldName := mostLeastFrequentDefaultOutputFieldName
|
||||
|
||||
var err error
|
||||
for argi < argc /* variable increment: 1 or 2 depending on flag */ {
|
||||
opt := args[argi]
|
||||
if !strings.HasPrefix(opt, "-") {
|
||||
|
|
@ -116,35 +117,41 @@ func transformerMostOrLeastFrequentParseCLI(
|
|||
|
||||
if opt == "-h" || opt == "--help" {
|
||||
usageFunc(os.Stdout)
|
||||
os.Exit(0)
|
||||
return nil, cli.ErrHelpRequested
|
||||
|
||||
} else if opt == "-f" {
|
||||
groupByFieldNames = cli.VerbGetStringArrayArgOrDie(verb, opt, args, &argi, argc)
|
||||
groupByFieldNames, err = cli.VerbGetStringArrayArg(verb, opt, args, &argi, argc)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
} else if opt == "-n" {
|
||||
maxOutputLength = cli.VerbGetIntArgOrDie(verb, opt, args, &argi, argc)
|
||||
maxOutputLength, err = cli.VerbGetIntArg(verb, opt, args, &argi, argc)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
} else if opt == "-b" {
|
||||
showCounts = false
|
||||
|
||||
} else if opt == "-o" {
|
||||
outputFieldName = cli.VerbGetStringArgOrDie(verb, opt, args, &argi, argc)
|
||||
outputFieldName, err = cli.VerbGetStringArg(verb, opt, args, &argi, argc)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
} else {
|
||||
usageFunc(os.Stderr)
|
||||
os.Exit(1)
|
||||
return nil, cli.VerbErrorf(verb, "option \"%s\" not recognized", opt)
|
||||
}
|
||||
}
|
||||
|
||||
if groupByFieldNames == nil {
|
||||
usageFunc(os.Stderr)
|
||||
os.Exit(1)
|
||||
return nil
|
||||
return nil, cli.VerbErrorf(verb, "-f field names required")
|
||||
}
|
||||
|
||||
*pargi = argi
|
||||
if !doConstruct { // All transformers must do this for main command-line parsing
|
||||
return nil
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
transformer, err := NewTransformerMostOrLeastFrequent(
|
||||
|
|
@ -155,11 +162,10 @@ func transformerMostOrLeastFrequentParseCLI(
|
|||
descending,
|
||||
)
|
||||
if err != nil {
|
||||
fmt.Fprintf(os.Stderr, "mlr: %v\n", err)
|
||||
os.Exit(1)
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return transformer
|
||||
return transformer, nil
|
||||
}
|
||||
|
||||
type TransformerMostOrLeastFrequent struct {
|
||||
|
|
|
|||
|
|
@ -94,7 +94,7 @@ func transformerNestParseCLI(
|
|||
args []string,
|
||||
_ *cli.TOptions,
|
||||
doConstruct bool, // false for first pass of CLI-parse, true for second pass
|
||||
) RecordTransformer {
|
||||
) (RecordTransformer, error) {
|
||||
|
||||
// Skip the verb name from the current spot in the mlr command line
|
||||
argi := *pargi
|
||||
|
|
@ -127,14 +127,22 @@ func transformerNestParseCLI(
|
|||
|
||||
if opt == "-h" || opt == "--help" {
|
||||
transformerNestUsage(os.Stdout)
|
||||
os.Exit(0)
|
||||
return nil, cli.ErrHelpRequested
|
||||
|
||||
} else if opt == "-f" {
|
||||
fieldName = cli.VerbGetStringArgOrDie(verb, opt, args, &argi, argc)
|
||||
s, err := cli.VerbGetStringArg(verb, opt, args, &argi, argc)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
fieldName = s
|
||||
|
||||
} else if opt == "-r" {
|
||||
doRegexes = true
|
||||
fieldName = cli.VerbGetStringArgOrDie(verb, opt, args, &argi, argc)
|
||||
s, err := cli.VerbGetStringArg(verb, opt, args, &argi, argc)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
fieldName = s
|
||||
|
||||
} else if opt == "--explode" || opt == "-e" {
|
||||
doExplode = true
|
||||
|
|
@ -158,12 +166,24 @@ func transformerNestParseCLI(
|
|||
doAcrossFieldsSpecified = true
|
||||
|
||||
} else if opt == "--nested-fs" || opt == "-S" {
|
||||
nestedFS = cli.VerbGetStringArgOrDie(verb, opt, args, &argi, argc)
|
||||
s, err := cli.VerbGetStringArg(verb, opt, args, &argi, argc)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
nestedFS = s
|
||||
} else if opt == "--nested-ps" || opt == "-P" {
|
||||
nestedPS = cli.VerbGetStringArgOrDie(verb, opt, args, &argi, argc)
|
||||
s, err := cli.VerbGetStringArg(verb, opt, args, &argi, argc)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
nestedPS = s
|
||||
|
||||
} else if opt == "--evar" {
|
||||
evfs = cli.VerbGetStringArgOrDie(verb, opt, args, &argi, argc)
|
||||
s, err := cli.VerbGetStringArg(verb, opt, args, &argi, argc)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
evfs = s
|
||||
doExplode = true
|
||||
doExplodeSpecified = true
|
||||
doPairs = false
|
||||
|
|
@ -172,7 +192,11 @@ func transformerNestParseCLI(
|
|||
doAcrossFieldsSpecified = true
|
||||
|
||||
} else if opt == "--ivar" {
|
||||
ivfs = cli.VerbGetStringArgOrDie(verb, opt, args, &argi, argc)
|
||||
s, err := cli.VerbGetStringArg(verb, opt, args, &argi, argc)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
ivfs = s
|
||||
doExplode = false
|
||||
doExplodeSpecified = true
|
||||
doPairs = false
|
||||
|
|
@ -182,7 +206,7 @@ func transformerNestParseCLI(
|
|||
|
||||
} else {
|
||||
transformerNestUsage(os.Stderr)
|
||||
os.Exit(1)
|
||||
return nil, fmt.Errorf("%s %s: option \"%s\" not recognized", "mlr", verb, opt)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -201,32 +225,31 @@ func transformerNestParseCLI(
|
|||
|
||||
if fieldName == "" {
|
||||
transformerNestUsage(os.Stderr)
|
||||
os.Exit(1)
|
||||
return nil, fmt.Errorf("%s %s: -f or -r is required", "mlr", verb)
|
||||
}
|
||||
if !doExplodeSpecified {
|
||||
transformerNestUsage(os.Stderr)
|
||||
os.Exit(1)
|
||||
return nil, fmt.Errorf("%s %s: --explode or --implode is required", "mlr", verb)
|
||||
}
|
||||
if !doPairsSpecified {
|
||||
transformerNestUsage(os.Stderr)
|
||||
os.Exit(1)
|
||||
return nil, fmt.Errorf("%s %s: --values or --pairs is required", "mlr", verb)
|
||||
}
|
||||
if !doAcrossFieldsSpecified {
|
||||
transformerNestUsage(os.Stderr)
|
||||
os.Exit(1)
|
||||
return nil, fmt.Errorf("%s %s: --across-records or --across-fields is required", "mlr", verb)
|
||||
}
|
||||
if doPairs && !doExplode {
|
||||
transformerNestUsage(os.Stderr)
|
||||
os.Exit(1)
|
||||
return nil, fmt.Errorf("%s %s: --implode with --pairs doesn't make sense", "mlr", verb)
|
||||
}
|
||||
if doRegexes && !doExplode {
|
||||
fmt.Fprintf(os.Stderr, "mlr nest: -r is only supported with --explode, not --implode.\n")
|
||||
os.Exit(1)
|
||||
return nil, fmt.Errorf("mlr nest: -r is only supported with --explode, not --implode")
|
||||
}
|
||||
|
||||
*pargi = argi
|
||||
if !doConstruct { // All transformers must do this for main command-line parsing
|
||||
return nil
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
transformer, err := NewTransformerNest(
|
||||
|
|
@ -239,11 +262,10 @@ func transformerNestParseCLI(
|
|||
doAcrossFields,
|
||||
)
|
||||
if err != nil {
|
||||
fmt.Fprintf(os.Stderr, "mlr: %v\n", err)
|
||||
os.Exit(1)
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return transformer
|
||||
return transformer, nil
|
||||
}
|
||||
|
||||
type TransformerNest struct {
|
||||
|
|
|
|||
|
|
@ -34,7 +34,7 @@ func transformerNothingParseCLI(
|
|||
args []string,
|
||||
_ *cli.TOptions,
|
||||
doConstruct bool, // false for first pass of CLI-parse, true for second pass
|
||||
) RecordTransformer {
|
||||
) (RecordTransformer, error) {
|
||||
|
||||
// Skip the verb name from the current spot in the mlr command line
|
||||
argi := *pargi
|
||||
|
|
@ -52,25 +52,23 @@ func transformerNothingParseCLI(
|
|||
|
||||
if opt == "-h" || opt == "--help" {
|
||||
transformerNothingUsage(os.Stdout)
|
||||
os.Exit(0)
|
||||
|
||||
return nil, cli.ErrHelpRequested
|
||||
}
|
||||
transformerNothingUsage(os.Stderr)
|
||||
os.Exit(1)
|
||||
return nil, fmt.Errorf("%s %s: option \"%s\" not recognized", "mlr", verbNameNothing, opt)
|
||||
}
|
||||
|
||||
*pargi = argi
|
||||
if !doConstruct { // All transformers must do this for main command-line parsing
|
||||
return nil
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
transformer, err := NewTransformerNothing()
|
||||
if err != nil {
|
||||
fmt.Fprintf(os.Stderr, "mlr: %v\n", err)
|
||||
os.Exit(1)
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return transformer
|
||||
return transformer, nil
|
||||
}
|
||||
|
||||
type TransformerNothing struct {
|
||||
|
|
|
|||
|
|
@ -184,7 +184,7 @@ func transformerPutOrFilterParseCLI(
|
|||
args []string,
|
||||
mainOptions *cli.TOptions,
|
||||
doConstruct bool, // false for first pass of CLI-parse, true for second pass
|
||||
) RecordTransformer {
|
||||
) (RecordTransformer, error) {
|
||||
|
||||
// Skip the verb name from the current spot in the mlr command line
|
||||
argi := *pargi
|
||||
|
|
@ -217,10 +217,8 @@ func transformerPutOrFilterParseCLI(
|
|||
for _, filename := range options.DSLPreloadFileNames {
|
||||
theseDSLStrings, err := lib.LoadStringsFromFileOrDir(filename, ".mlr")
|
||||
if err != nil {
|
||||
fmt.Fprintf(os.Stderr, "%s %s: cannot load DSL expression from \"%s\": ",
|
||||
"mlr", verb, filename)
|
||||
fmt.Println(err)
|
||||
os.Exit(1)
|
||||
return nil, fmt.Errorf("%s %s: cannot load DSL expression from \"%s\": %w",
|
||||
"mlr", verb, filename, err)
|
||||
}
|
||||
dslStrings = append(dslStrings, theseDSLStrings...)
|
||||
}
|
||||
|
|
@ -238,11 +236,14 @@ func transformerPutOrFilterParseCLI(
|
|||
|
||||
if opt == "-h" || opt == "--help" {
|
||||
transformerPutOrFilterUsage(os.Stdout, verb)
|
||||
os.Exit(0)
|
||||
return nil, cli.ErrHelpRequested
|
||||
|
||||
} else if opt == "-f" {
|
||||
// Get a DSL string from the user-specified filename
|
||||
filename := cli.VerbGetStringArgOrDie(verb, opt, args, &argi, argc)
|
||||
filename, err := cli.VerbGetStringArg(verb, opt, args, &argi, argc)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// Miller has a two-pass command-line parser. If the user does
|
||||
// `mlr put -f foo.mlr`
|
||||
|
|
@ -258,17 +259,18 @@ func transformerPutOrFilterParseCLI(
|
|||
if doConstruct {
|
||||
theseDSLStrings, err := lib.LoadStringsFromFileOrDir(filename, ".mlr")
|
||||
if err != nil {
|
||||
fmt.Fprintf(os.Stderr, "%s %s: cannot load DSL expression from file \"%s\": ",
|
||||
"mlr", verb, filename)
|
||||
fmt.Println(err)
|
||||
os.Exit(1)
|
||||
return nil, fmt.Errorf("%s %s: cannot load DSL expression from file \"%s\": %w",
|
||||
"mlr", verb, filename, err)
|
||||
}
|
||||
dslStrings = append(dslStrings, theseDSLStrings...)
|
||||
}
|
||||
haveDSLStringsHere = true
|
||||
|
||||
} else if opt == "-e" {
|
||||
dslString := cli.VerbGetStringArgOrDie(verb, opt, args, &argi, argc)
|
||||
dslString, err := cli.VerbGetStringArg(verb, opt, args, &argi, argc)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
dslStrings = append(dslStrings, dslString)
|
||||
haveDSLStringsHere = true
|
||||
|
||||
|
|
@ -277,7 +279,10 @@ func transformerPutOrFilterParseCLI(
|
|||
// mlr put -s sum=0
|
||||
// is like
|
||||
// mlr put -s 'begin {@sum = 0}'
|
||||
preset := cli.VerbGetStringArgOrDie(verb, opt, args, &argi, argc)
|
||||
preset, err := cli.VerbGetStringArg(verb, opt, args, &argi, argc)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
presets = append(presets, preset)
|
||||
|
||||
} else if opt == "-x" {
|
||||
|
|
@ -328,8 +333,7 @@ func transformerPutOrFilterParseCLI(
|
|||
// Nothing else to handle here.
|
||||
argi = largi
|
||||
} else {
|
||||
transformerPutOrFilterUsage(os.Stderr, verb)
|
||||
os.Exit(1)
|
||||
return nil, cli.VerbErrorf(verb, "option not recognized")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -342,8 +346,7 @@ func transformerPutOrFilterParseCLI(
|
|||
if !haveDSLStringsHere {
|
||||
// Get the DSL string from the command line, after the flags
|
||||
if argi >= argc {
|
||||
fmt.Fprintf(os.Stderr, "mlr %s: -f/-e requires a filename as argument.\n", verb)
|
||||
os.Exit(1)
|
||||
return nil, cli.VerbErrorf(verb, "expression or -f/-e is required")
|
||||
}
|
||||
dslString := args[argi]
|
||||
dslStrings = append(dslStrings, dslString)
|
||||
|
|
@ -352,7 +355,7 @@ func transformerPutOrFilterParseCLI(
|
|||
|
||||
*pargi = argi
|
||||
if !doConstruct { // All transformers must do this for main command-line parsing
|
||||
return nil
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
var dslInstanceType cst.DSLInstanceType = cst.DSLInstanceTypePut
|
||||
|
|
@ -380,11 +383,10 @@ func transformerPutOrFilterParseCLI(
|
|||
options,
|
||||
)
|
||||
if err != nil {
|
||||
fmt.Fprintf(os.Stderr, "mlr: %v\n", err)
|
||||
os.Exit(1)
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return transformer
|
||||
return transformer, nil
|
||||
}
|
||||
|
||||
type TransformerPut struct {
|
||||
|
|
|
|||
|
|
@ -35,7 +35,7 @@ func transformerRegularizeParseCLI(
|
|||
args []string,
|
||||
_ *cli.TOptions,
|
||||
doConstruct bool, // false for first pass of CLI-parse, true for second pass
|
||||
) RecordTransformer {
|
||||
) (RecordTransformer, error) {
|
||||
|
||||
// Skip the verb name from the current spot in the mlr command line
|
||||
argi := *pargi
|
||||
|
|
@ -53,25 +53,23 @@ func transformerRegularizeParseCLI(
|
|||
|
||||
if opt == "-h" || opt == "--help" {
|
||||
transformerRegularizeUsage(os.Stdout)
|
||||
os.Exit(0)
|
||||
return nil, cli.ErrHelpRequested
|
||||
|
||||
}
|
||||
transformerRegularizeUsage(os.Stderr)
|
||||
os.Exit(1)
|
||||
return nil, cli.VerbErrorf(verbNameRegularize, "option \"%s\" not recognized", opt)
|
||||
}
|
||||
|
||||
*pargi = argi
|
||||
if !doConstruct { // All transformers must do this for main command-line parsing
|
||||
return nil
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
transformer, err := NewTransformerRegularize()
|
||||
if err != nil {
|
||||
fmt.Fprintf(os.Stderr, "mlr: %v\n", err)
|
||||
os.Exit(1)
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return transformer
|
||||
return transformer, nil
|
||||
}
|
||||
|
||||
type TransformerRegularize struct {
|
||||
|
|
|
|||
|
|
@ -34,7 +34,7 @@ func transformerRemoveEmptyColumnsParseCLI(
|
|||
args []string,
|
||||
_ *cli.TOptions,
|
||||
doConstruct bool, // false for first pass of CLI-parse, true for second pass
|
||||
) RecordTransformer {
|
||||
) (RecordTransformer, error) {
|
||||
|
||||
// Skip the verb name from the current spot in the mlr command line
|
||||
argi := *pargi
|
||||
|
|
@ -52,25 +52,23 @@ func transformerRemoveEmptyColumnsParseCLI(
|
|||
|
||||
if opt == "-h" || opt == "--help" {
|
||||
transformerRemoveEmptyColumnsUsage(os.Stdout)
|
||||
os.Exit(0)
|
||||
return nil, cli.ErrHelpRequested
|
||||
|
||||
}
|
||||
transformerRemoveEmptyColumnsUsage(os.Stderr)
|
||||
os.Exit(1)
|
||||
return nil, cli.VerbErrorf(verbNameRemoveEmptyColumns, "option \"%s\" not recognized", opt)
|
||||
}
|
||||
|
||||
*pargi = argi
|
||||
if !doConstruct { // All transformers must do this for main command-line parsing
|
||||
return nil
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
transformer, err := NewTransformerRemoveEmptyColumns()
|
||||
if err != nil {
|
||||
fmt.Fprintf(os.Stderr, "mlr: %v\n", err)
|
||||
os.Exit(1)
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return transformer
|
||||
return transformer, nil
|
||||
}
|
||||
|
||||
type TransformerRemoveEmptyColumns struct {
|
||||
|
|
|
|||
|
|
@ -55,7 +55,7 @@ func transformerRenameParseCLI(
|
|||
args []string,
|
||||
_ *cli.TOptions,
|
||||
doConstruct bool, // false for first pass of CLI-parse, true for second pass
|
||||
) RecordTransformer {
|
||||
) (RecordTransformer, error) {
|
||||
|
||||
// Skip the verb name from the current spot in the mlr command line
|
||||
argi := *pargi
|
||||
|
|
@ -76,7 +76,7 @@ func transformerRenameParseCLI(
|
|||
|
||||
if opt == "-h" || opt == "--help" {
|
||||
transformerRenameUsage(os.Stdout)
|
||||
os.Exit(0)
|
||||
return nil, cli.ErrHelpRequested
|
||||
|
||||
} else if opt == "-r" {
|
||||
doRegexes = true
|
||||
|
|
@ -85,8 +85,7 @@ func transformerRenameParseCLI(
|
|||
doGsub = true
|
||||
|
||||
} else {
|
||||
transformerRenameUsage(os.Stderr)
|
||||
os.Exit(1)
|
||||
return nil, cli.VerbErrorf(verbNameRename, "option \"%s\" not recognized", opt)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -96,19 +95,17 @@ func transformerRenameParseCLI(
|
|||
|
||||
// Get the rename field names from the command line
|
||||
if argi >= argc {
|
||||
transformerRenameUsage(os.Stderr)
|
||||
os.Exit(1)
|
||||
return nil, cli.VerbErrorf(verbNameRename, "old1,new1,old2,new2,... required")
|
||||
}
|
||||
names := lib.SplitString(args[argi], ",")
|
||||
if len(names)%2 != 0 {
|
||||
transformerRenameUsage(os.Stderr)
|
||||
os.Exit(1)
|
||||
return nil, cli.VerbErrorf(verbNameRename, "names string must have even length")
|
||||
}
|
||||
argi++
|
||||
|
||||
*pargi = argi
|
||||
if !doConstruct { // All transformers must do this for main command-line parsing
|
||||
return nil
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
transformer, err := NewTransformerRename(
|
||||
|
|
@ -117,11 +114,10 @@ func transformerRenameParseCLI(
|
|||
doGsub,
|
||||
)
|
||||
if err != nil {
|
||||
fmt.Fprintf(os.Stderr, "mlr: %v\n", err)
|
||||
os.Exit(1)
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return transformer
|
||||
return transformer, nil
|
||||
}
|
||||
|
||||
type tRegexAndReplacement struct {
|
||||
|
|
|
|||
|
|
@ -56,7 +56,7 @@ func transformerReorderParseCLI(
|
|||
args []string,
|
||||
_ *cli.TOptions,
|
||||
doConstruct bool, // false for first pass of CLI-parse, true for second pass
|
||||
) RecordTransformer {
|
||||
) (RecordTransformer, error) {
|
||||
|
||||
// Skip the verb name from the current spot in the mlr command line
|
||||
argi := *pargi
|
||||
|
|
@ -68,6 +68,7 @@ func transformerReorderParseCLI(
|
|||
putAfter := false
|
||||
centerFieldName := ""
|
||||
|
||||
var err error
|
||||
for argi < argc /* variable increment: 1 or 2 depending on flag */ {
|
||||
opt := args[argi]
|
||||
if !strings.HasPrefix(opt, "-") {
|
||||
|
|
@ -80,22 +81,34 @@ func transformerReorderParseCLI(
|
|||
|
||||
if opt == "-h" || opt == "--help" {
|
||||
transformerReorderUsage(os.Stdout)
|
||||
os.Exit(0)
|
||||
return nil, cli.ErrHelpRequested
|
||||
|
||||
} else if opt == "-f" {
|
||||
fieldNames = cli.VerbGetStringArrayArgOrDie(verb, opt, args, &argi, argc)
|
||||
fieldNames, err = cli.VerbGetStringArrayArg(verb, opt, args, &argi, argc)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
doRegexes = false
|
||||
|
||||
} else if opt == "-r" {
|
||||
fieldNames = cli.VerbGetStringArrayArgOrDie(verb, opt, args, &argi, argc)
|
||||
fieldNames, err = cli.VerbGetStringArrayArg(verb, opt, args, &argi, argc)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
doRegexes = true
|
||||
|
||||
} else if opt == "-b" {
|
||||
centerFieldName = cli.VerbGetStringArgOrDie(verb, opt, args, &argi, argc)
|
||||
centerFieldName, err = cli.VerbGetStringArg(verb, opt, args, &argi, argc)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
putAfter = false
|
||||
|
||||
} else if opt == "-a" {
|
||||
centerFieldName = cli.VerbGetStringArgOrDie(verb, opt, args, &argi, argc)
|
||||
centerFieldName, err = cli.VerbGetStringArg(verb, opt, args, &argi, argc)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
putAfter = true
|
||||
|
||||
} else if opt == "-e" {
|
||||
|
|
@ -103,19 +116,17 @@ func transformerReorderParseCLI(
|
|||
centerFieldName = ""
|
||||
|
||||
} else {
|
||||
transformerReorderUsage(os.Stderr)
|
||||
os.Exit(1)
|
||||
return nil, cli.VerbErrorf(verb, "option \"%s\" not recognized", opt)
|
||||
}
|
||||
}
|
||||
|
||||
if fieldNames == nil {
|
||||
transformerReorderUsage(os.Stderr)
|
||||
os.Exit(1)
|
||||
return nil, cli.VerbErrorf(verb, "-f field names required")
|
||||
}
|
||||
|
||||
*pargi = argi
|
||||
if !doConstruct { // All transformers must do this for main command-line parsing
|
||||
return nil
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
transformer, err := NewTransformerReorder(
|
||||
|
|
@ -125,11 +136,10 @@ func transformerReorderParseCLI(
|
|||
centerFieldName,
|
||||
)
|
||||
if err != nil {
|
||||
fmt.Fprintf(os.Stderr, "mlr: %v\n", err)
|
||||
os.Exit(1)
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return transformer
|
||||
return transformer, nil
|
||||
}
|
||||
|
||||
type TransformerReorder struct {
|
||||
|
|
|
|||
|
|
@ -63,7 +63,7 @@ func transformerRepeatParseCLI(
|
|||
args []string,
|
||||
_ *cli.TOptions,
|
||||
doConstruct bool, // false for first pass of CLI-parse, true for second pass
|
||||
) RecordTransformer {
|
||||
) (RecordTransformer, error) {
|
||||
|
||||
repeatCountSource := repeatCountSourceUnspecified
|
||||
repeatCount := int64(0)
|
||||
|
|
@ -74,6 +74,7 @@ func transformerRepeatParseCLI(
|
|||
verb := args[argi]
|
||||
argi++
|
||||
|
||||
var err error
|
||||
for argi < argc /* variable increment: 1 or 2 depending on flag */ {
|
||||
opt := args[argi]
|
||||
if !strings.HasPrefix(opt, "-") {
|
||||
|
|
@ -86,30 +87,34 @@ func transformerRepeatParseCLI(
|
|||
|
||||
if opt == "-h" || opt == "--help" {
|
||||
transformerRepeatUsage(os.Stdout)
|
||||
os.Exit(0)
|
||||
return nil, cli.ErrHelpRequested
|
||||
|
||||
} else if opt == "-n" {
|
||||
repeatCount = cli.VerbGetIntArgOrDie(verb, opt, args, &argi, argc)
|
||||
repeatCount, err = cli.VerbGetIntArg(verb, opt, args, &argi, argc)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
repeatCountSource = repeatCountFromInt
|
||||
|
||||
} else if opt == "-f" {
|
||||
repeatCountFieldName = cli.VerbGetStringArgOrDie(verb, opt, args, &argi, argc)
|
||||
repeatCountFieldName, err = cli.VerbGetStringArg(verb, opt, args, &argi, argc)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
repeatCountSource = repeatCountFromFieldName
|
||||
|
||||
} else {
|
||||
transformerRepeatUsage(os.Stderr)
|
||||
os.Exit(1)
|
||||
return nil, cli.VerbErrorf(verb, "option \"%s\" not recognized", opt)
|
||||
}
|
||||
}
|
||||
|
||||
if repeatCountSource == repeatCountSourceUnspecified {
|
||||
transformerRepeatUsage(os.Stderr)
|
||||
os.Exit(1)
|
||||
return nil, cli.VerbErrorf(verb, "-n or -f is required")
|
||||
}
|
||||
|
||||
*pargi = argi
|
||||
if !doConstruct { // All transformers must do this for main command-line parsing
|
||||
return nil
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
transformer, err := NewTransformerRepeat(
|
||||
|
|
@ -118,11 +123,10 @@ func transformerRepeatParseCLI(
|
|||
repeatCountFieldName,
|
||||
)
|
||||
if err != nil {
|
||||
fmt.Fprintf(os.Stderr, "mlr: %v\n", err)
|
||||
os.Exit(1)
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return transformer
|
||||
return transformer, nil
|
||||
}
|
||||
|
||||
type TransformerRepeat struct {
|
||||
|
|
|
|||
|
|
@ -120,7 +120,7 @@ func transformerReshapeParseCLI(
|
|||
args []string,
|
||||
_ *cli.TOptions,
|
||||
doConstruct bool, // false for first pass of CLI-parse, true for second pass
|
||||
) RecordTransformer {
|
||||
) (RecordTransformer, error) {
|
||||
|
||||
// Skip the verb name from the current spot in the mlr command line
|
||||
argi := *pargi
|
||||
|
|
@ -133,6 +133,7 @@ func transformerReshapeParseCLI(
|
|||
var outputFieldNames []string = nil
|
||||
var splitOutFieldNames []string = nil
|
||||
|
||||
var err error
|
||||
for argi < argc /* variable increment: 1 or 2 depending on flag */ {
|
||||
opt := args[argi]
|
||||
if !strings.HasPrefix(opt, "-") {
|
||||
|
|
@ -145,24 +146,35 @@ func transformerReshapeParseCLI(
|
|||
|
||||
if opt == "-h" || opt == "--help" {
|
||||
transformerReshapeUsage(os.Stdout)
|
||||
os.Exit(0)
|
||||
return nil, cli.ErrHelpRequested
|
||||
|
||||
} else if opt == "-i" {
|
||||
inputFieldNames = cli.VerbGetStringArrayArgOrDie(verb, opt, args, &argi, argc)
|
||||
inputFieldNames, err = cli.VerbGetStringArrayArg(verb, opt, args, &argi, argc)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
} else if opt == "-r" {
|
||||
inputFieldRegexString := cli.VerbGetStringArgOrDie(verb, opt, args, &argi, argc)
|
||||
inputFieldRegexString, err := cli.VerbGetStringArg(verb, opt, args, &argi, argc)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if inputFieldRegexStrings == nil {
|
||||
inputFieldRegexStrings = []string{}
|
||||
}
|
||||
inputFieldRegexStrings = append(inputFieldRegexStrings, inputFieldRegexString)
|
||||
} else if opt == "-o" {
|
||||
outputFieldNames = cli.VerbGetStringArrayArgOrDie(verb, opt, args, &argi, argc)
|
||||
outputFieldNames, err = cli.VerbGetStringArrayArg(verb, opt, args, &argi, argc)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
} else if opt == "-s" {
|
||||
splitOutFieldNames = cli.VerbGetStringArrayArgOrDie(verb, opt, args, &argi, argc)
|
||||
splitOutFieldNames, err = cli.VerbGetStringArrayArg(verb, opt, args, &argi, argc)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
} else {
|
||||
transformerReshapeUsage(os.Stderr)
|
||||
os.Exit(1)
|
||||
return nil, cli.VerbErrorf(verb, "option \"%s\" not recognized", opt)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -174,25 +186,21 @@ func transformerReshapeParseCLI(
|
|||
if splitOutFieldNames == nil {
|
||||
// wide to long
|
||||
if inputFieldNames == nil && inputFieldRegexStrings == nil {
|
||||
transformerReshapeUsage(os.Stderr)
|
||||
os.Exit(1)
|
||||
return nil, cli.VerbErrorf(verb, "-i or -r is required for wide-to-long")
|
||||
}
|
||||
|
||||
if outputFieldNames == nil {
|
||||
transformerReshapeUsage(os.Stderr)
|
||||
os.Exit(1)
|
||||
return nil, cli.VerbErrorf(verb, "-o is required for wide-to-long")
|
||||
}
|
||||
if len(outputFieldNames) != 2 {
|
||||
transformerReshapeUsage(os.Stderr)
|
||||
os.Exit(1)
|
||||
return nil, cli.VerbErrorf(verb, "-o must have exactly 2 field names for wide-to-long")
|
||||
}
|
||||
outputKeyFieldName = outputFieldNames[0]
|
||||
outputValueFieldName = outputFieldNames[1]
|
||||
} else {
|
||||
// long to wide
|
||||
if len(splitOutFieldNames) != 2 {
|
||||
transformerReshapeUsage(os.Stderr)
|
||||
os.Exit(1)
|
||||
return nil, cli.VerbErrorf(verb, "-s must have exactly 2 field names for long-to-wide")
|
||||
}
|
||||
splitOutKeyFieldName = splitOutFieldNames[0]
|
||||
splitOutValueFieldName = splitOutFieldNames[1]
|
||||
|
|
@ -200,7 +208,7 @@ func transformerReshapeParseCLI(
|
|||
|
||||
*pargi = argi
|
||||
if !doConstruct { // All transformers must do this for main command-line parsing
|
||||
return nil
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
transformer, err := NewTransformerReshape(
|
||||
|
|
@ -212,11 +220,10 @@ func transformerReshapeParseCLI(
|
|||
splitOutValueFieldName,
|
||||
)
|
||||
if err != nil {
|
||||
fmt.Fprintf(os.Stderr, "mlr: %v\n", err)
|
||||
os.Exit(1)
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return transformer
|
||||
return transformer, nil
|
||||
}
|
||||
|
||||
type TransformerReshape struct {
|
||||
|
|
|
|||
|
|
@ -39,7 +39,7 @@ func transformerSampleParseCLI(
|
|||
args []string,
|
||||
_ *cli.TOptions,
|
||||
doConstruct bool, // false for first pass of CLI-parse, true for second pass
|
||||
) RecordTransformer {
|
||||
) (RecordTransformer, error) {
|
||||
|
||||
// Skip the verb name from the current spot in the mlr command line
|
||||
argi := *pargi
|
||||
|
|
@ -49,6 +49,7 @@ func transformerSampleParseCLI(
|
|||
sampleCount := int64(-1)
|
||||
var groupByFieldNames []string = nil
|
||||
|
||||
var err error
|
||||
for argi < argc /* variable increment: 1 or 2 depending on flag */ {
|
||||
opt := args[argi]
|
||||
if !strings.HasPrefix(opt, "-") {
|
||||
|
|
@ -61,28 +62,32 @@ func transformerSampleParseCLI(
|
|||
|
||||
if opt == "-h" || opt == "--help" {
|
||||
transformerSampleUsage(os.Stdout)
|
||||
os.Exit(0)
|
||||
return nil, cli.ErrHelpRequested
|
||||
|
||||
} else if opt == "-k" {
|
||||
sampleCount = cli.VerbGetIntArgOrDie(verb, opt, args, &argi, argc)
|
||||
sampleCount, err = cli.VerbGetIntArg(verb, opt, args, &argi, argc)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
} else if opt == "-g" {
|
||||
groupByFieldNames = cli.VerbGetStringArrayArgOrDie(verb, opt, args, &argi, argc)
|
||||
groupByFieldNames, err = cli.VerbGetStringArrayArg(verb, opt, args, &argi, argc)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
} else {
|
||||
transformerSampleUsage(os.Stderr)
|
||||
os.Exit(1)
|
||||
return nil, cli.VerbErrorf(verb, "option \"%s\" not recognized", opt)
|
||||
}
|
||||
}
|
||||
|
||||
if sampleCount < 0 {
|
||||
transformerSampleUsage(os.Stderr)
|
||||
os.Exit(1)
|
||||
return nil, cli.VerbErrorf(verb, "sample count must be non-negative")
|
||||
}
|
||||
|
||||
*pargi = argi
|
||||
if !doConstruct { // All transformers must do this for main command-line parsing
|
||||
return nil
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
transformer, err := NewTransformerSample(
|
||||
|
|
@ -90,11 +95,10 @@ func transformerSampleParseCLI(
|
|||
groupByFieldNames,
|
||||
)
|
||||
if err != nil {
|
||||
fmt.Fprintf(os.Stderr, "mlr: %v\n", err)
|
||||
os.Exit(1)
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return transformer
|
||||
return transformer, nil
|
||||
}
|
||||
|
||||
type sampleBucketType struct {
|
||||
|
|
|
|||
|
|
@ -43,7 +43,7 @@ func transformerSec2GMTParseCLI(
|
|||
args []string,
|
||||
_ *cli.TOptions,
|
||||
doConstruct bool, // false for first pass of CLI-parse, true for second pass
|
||||
) RecordTransformer {
|
||||
) (RecordTransformer, error) {
|
||||
|
||||
// Skip the verb name from the current spot in the mlr command line
|
||||
argi := *pargi
|
||||
|
|
@ -64,7 +64,7 @@ func transformerSec2GMTParseCLI(
|
|||
|
||||
if opt == "-h" || opt == "--help" {
|
||||
transformerSec2GMTUsage(os.Stdout)
|
||||
os.Exit(0)
|
||||
return nil, cli.ErrHelpRequested
|
||||
|
||||
} else if opt == "-1" {
|
||||
numDecimalPlaces = 1
|
||||
|
|
@ -93,21 +93,19 @@ func transformerSec2GMTParseCLI(
|
|||
preDivide = 1.0e9
|
||||
|
||||
} else {
|
||||
transformerSec2GMTUsage(os.Stderr)
|
||||
os.Exit(1)
|
||||
return nil, cli.VerbErrorf(verbNameSec2GMT, "option \"%s\" not recognized", opt)
|
||||
}
|
||||
}
|
||||
|
||||
if argi >= argc {
|
||||
transformerSec2GMTUsage(os.Stderr)
|
||||
os.Exit(1)
|
||||
return nil, cli.VerbErrorf(verbNameSec2GMT, "field names required")
|
||||
}
|
||||
fieldNames := args[argi]
|
||||
argi++
|
||||
|
||||
*pargi = argi
|
||||
if !doConstruct { // All transformers must do this for main command-line parsing
|
||||
return nil
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
transformer, err := NewTransformerSec2GMT(
|
||||
|
|
@ -116,11 +114,10 @@ func transformerSec2GMTParseCLI(
|
|||
numDecimalPlaces,
|
||||
)
|
||||
if err != nil {
|
||||
fmt.Fprintf(os.Stderr, "mlr: %v\n", err)
|
||||
os.Exit(1)
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return transformer
|
||||
return transformer, nil
|
||||
}
|
||||
|
||||
type TransformerSec2GMT struct {
|
||||
|
|
|
|||
|
|
@ -37,7 +37,7 @@ func transformerSec2GMTDateParseCLI(
|
|||
args []string,
|
||||
_ *cli.TOptions,
|
||||
doConstruct bool, // false for first pass of CLI-parse, true for second pass
|
||||
) RecordTransformer {
|
||||
) (RecordTransformer, error) {
|
||||
|
||||
// Skip the verb name from the current spot in the mlr command line
|
||||
argi := *pargi
|
||||
|
|
@ -55,34 +55,31 @@ func transformerSec2GMTDateParseCLI(
|
|||
|
||||
if opt == "-h" || opt == "--help" {
|
||||
transformerSec2GMTDateUsage(os.Stdout)
|
||||
os.Exit(0)
|
||||
return nil, cli.ErrHelpRequested
|
||||
|
||||
}
|
||||
transformerSec2GMTDateUsage(os.Stderr)
|
||||
os.Exit(1)
|
||||
return nil, cli.VerbErrorf(verbNameSec2GMTDate, "option \"%s\" not recognized", opt)
|
||||
}
|
||||
|
||||
if argi >= argc {
|
||||
transformerSec2GMTDateUsage(os.Stderr)
|
||||
os.Exit(1)
|
||||
return nil, cli.VerbErrorf(verbNameSec2GMTDate, "field names required")
|
||||
}
|
||||
fieldNames := args[argi]
|
||||
argi++
|
||||
|
||||
*pargi = argi
|
||||
if !doConstruct { // All transformers must do this for main command-line parsing
|
||||
return nil
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
transformer, err := NewTransformerSec2GMTDate(
|
||||
fieldNames,
|
||||
)
|
||||
if err != nil {
|
||||
fmt.Fprintf(os.Stderr, "mlr: %v\n", err)
|
||||
os.Exit(1)
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return transformer
|
||||
return transformer, nil
|
||||
}
|
||||
|
||||
type TransformerSec2GMTDate struct {
|
||||
|
|
|
|||
|
|
@ -46,7 +46,7 @@ func transformerSeqgenParseCLI(
|
|||
args []string,
|
||||
_ *cli.TOptions,
|
||||
doConstruct bool, // false for first pass of CLI-parse, true for second pass
|
||||
) RecordTransformer {
|
||||
) (RecordTransformer, error) {
|
||||
|
||||
// Skip the verb name from the current spot in the mlr command line
|
||||
argi := *pargi
|
||||
|
|
@ -58,6 +58,7 @@ func transformerSeqgenParseCLI(
|
|||
stopString := "100"
|
||||
stepString := "1"
|
||||
|
||||
var err error
|
||||
for argi < argc /* variable increment: 1 or 2 depending on flag */ {
|
||||
opt := args[argi]
|
||||
if !strings.HasPrefix(opt, "-") {
|
||||
|
|
@ -70,29 +71,40 @@ func transformerSeqgenParseCLI(
|
|||
|
||||
if opt == "-h" || opt == "--help" {
|
||||
transformerSeqgenUsage(os.Stdout)
|
||||
os.Exit(0)
|
||||
return nil, cli.ErrHelpRequested
|
||||
|
||||
} else if opt == "-f" {
|
||||
fieldName = cli.VerbGetStringArgOrDie(verb, opt, args, &argi, argc)
|
||||
fieldName, err = cli.VerbGetStringArg(verb, opt, args, &argi, argc)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
} else if opt == "--start" {
|
||||
startString = cli.VerbGetStringArgOrDie(verb, opt, args, &argi, argc)
|
||||
startString, err = cli.VerbGetStringArg(verb, opt, args, &argi, argc)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
} else if opt == "--stop" {
|
||||
stopString = cli.VerbGetStringArgOrDie(verb, opt, args, &argi, argc)
|
||||
stopString, err = cli.VerbGetStringArg(verb, opt, args, &argi, argc)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
} else if opt == "--step" {
|
||||
stepString = cli.VerbGetStringArgOrDie(verb, opt, args, &argi, argc)
|
||||
stepString, err = cli.VerbGetStringArg(verb, opt, args, &argi, argc)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
} else {
|
||||
transformerSeqgenUsage(os.Stderr)
|
||||
os.Exit(1)
|
||||
return nil, cli.VerbErrorf(verb, "option \"%s\" not recognized", opt)
|
||||
}
|
||||
}
|
||||
|
||||
*pargi = argi
|
||||
if !doConstruct { // All transformers must do this for main command-line parsing
|
||||
return nil
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
transformer, err := NewTransformerSeqgen(
|
||||
|
|
@ -102,11 +114,10 @@ func transformerSeqgenParseCLI(
|
|||
stepString,
|
||||
)
|
||||
if err != nil {
|
||||
fmt.Fprintf(os.Stderr, "mlr: %v\n", err)
|
||||
os.Exit(1)
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return transformer
|
||||
return transformer, nil
|
||||
}
|
||||
|
||||
type TransformerSeqgen struct {
|
||||
|
|
|
|||
|
|
@ -37,7 +37,7 @@ func transformerShuffleParseCLI(
|
|||
args []string,
|
||||
_ *cli.TOptions,
|
||||
doConstruct bool, // false for first pass of CLI-parse, true for second pass
|
||||
) RecordTransformer {
|
||||
) (RecordTransformer, error) {
|
||||
|
||||
// Skip the verb name from the current spot in the mlr command line
|
||||
argi := *pargi
|
||||
|
|
@ -55,25 +55,23 @@ func transformerShuffleParseCLI(
|
|||
|
||||
if opt == "-h" || opt == "--help" {
|
||||
transformerShuffleUsage(os.Stdout)
|
||||
os.Exit(0)
|
||||
return nil, cli.ErrHelpRequested
|
||||
|
||||
}
|
||||
transformerShuffleUsage(os.Stderr)
|
||||
os.Exit(1)
|
||||
return nil, cli.VerbErrorf(verbNameShuffle, "option \"%s\" not recognized", opt)
|
||||
}
|
||||
|
||||
*pargi = argi
|
||||
if !doConstruct { // All transformers must do this for main command-line parsing
|
||||
return nil
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
transformer, err := NewTransformerShuffle()
|
||||
if err != nil {
|
||||
fmt.Fprintf(os.Stderr, "mlr: %v\n", err)
|
||||
os.Exit(1)
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return transformer
|
||||
return transformer, nil
|
||||
}
|
||||
|
||||
type TransformerShuffle struct {
|
||||
|
|
|
|||
|
|
@ -34,7 +34,7 @@ func transformerSkipTrivialRecordsParseCLI(
|
|||
args []string,
|
||||
_ *cli.TOptions,
|
||||
doConstruct bool, // false for first pass of CLI-parse, true for second pass
|
||||
) RecordTransformer {
|
||||
) (RecordTransformer, error) {
|
||||
|
||||
// Skip the verb name from the current spot in the mlr command line
|
||||
argi := *pargi
|
||||
|
|
@ -52,25 +52,23 @@ func transformerSkipTrivialRecordsParseCLI(
|
|||
|
||||
if opt == "-h" || opt == "--help" {
|
||||
transformerSkipTrivialRecordsUsage(os.Stdout)
|
||||
os.Exit(0)
|
||||
return nil, cli.ErrHelpRequested
|
||||
|
||||
}
|
||||
transformerSkipTrivialRecordsUsage(os.Stderr)
|
||||
os.Exit(1)
|
||||
return nil, cli.VerbErrorf(verbNameSkipTrivialRecords, "option \"%s\" not recognized", opt)
|
||||
}
|
||||
|
||||
*pargi = argi
|
||||
if !doConstruct { // All transformers must do this for main command-line parsing
|
||||
return nil
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
transformer, err := NewTransformerSkipTrivialRecords()
|
||||
if err != nil {
|
||||
fmt.Fprintf(os.Stderr, "mlr: %v\n", err)
|
||||
os.Exit(1)
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return transformer
|
||||
return transformer, nil
|
||||
}
|
||||
|
||||
type TransformerSkipTrivialRecords struct {
|
||||
|
|
|
|||
|
|
@ -95,7 +95,7 @@ func transformerSortParseCLI(
|
|||
args []string,
|
||||
_ *cli.TOptions,
|
||||
doConstruct bool, // false for first pass of CLI-parse, true for second pass
|
||||
) RecordTransformer {
|
||||
) (RecordTransformer, error) {
|
||||
|
||||
// Skip the verb name from the current spot in the mlr command line
|
||||
argi := *pargi
|
||||
|
|
@ -118,10 +118,13 @@ func transformerSortParseCLI(
|
|||
|
||||
if opt == "-h" || opt == "--help" {
|
||||
transformerSortUsage(os.Stdout)
|
||||
os.Exit(0)
|
||||
return nil, cli.ErrHelpRequested
|
||||
|
||||
} else if opt == "-f" {
|
||||
subList := cli.VerbGetStringArrayArgOrDie(verb, opt, args, &argi, argc)
|
||||
subList, err := cli.VerbGetStringArrayArg(verb, opt, args, &argi, argc)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
for _, item := range subList {
|
||||
groupByFieldNames = append(groupByFieldNames, item)
|
||||
comparatorFuncs = append(comparatorFuncs, mlrval.LexicalAscendingComparator)
|
||||
|
|
@ -131,16 +134,24 @@ func transformerSortParseCLI(
|
|||
// See comments over "-n" -- similar hack.
|
||||
if args[argi] == "-r" {
|
||||
// Treat like "-cr"
|
||||
cli.VerbCheckArgCount(verb, args[argi], args, argi, argc, 1)
|
||||
if err := cli.VerbCheckArgCount(verb, args[argi], args, argi, argc, 1); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
argi++
|
||||
subList := cli.VerbGetStringArrayArgOrDie(verb, "-nr", args, &argi, argc)
|
||||
subList, err := cli.VerbGetStringArrayArg(verb, "-nr", args, &argi, argc)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
for _, item := range subList {
|
||||
groupByFieldNames = append(groupByFieldNames, item)
|
||||
comparatorFuncs = append(comparatorFuncs, mlrval.CaseFoldDescendingComparator)
|
||||
}
|
||||
} else {
|
||||
|
||||
subList := cli.VerbGetStringArrayArgOrDie(verb, opt, args, &argi, argc)
|
||||
subList, err := cli.VerbGetStringArrayArg(verb, opt, args, &argi, argc)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
for _, item := range subList {
|
||||
groupByFieldNames = append(groupByFieldNames, item)
|
||||
comparatorFuncs = append(comparatorFuncs, mlrval.CaseFoldAscendingComparator)
|
||||
|
|
@ -149,18 +160,28 @@ func transformerSortParseCLI(
|
|||
|
||||
} else if opt == "-t" {
|
||||
// See comments over "-n" -- similar hack.
|
||||
cli.VerbCheckArgCount(verb, opt, args, argi, argc, 1)
|
||||
if err := cli.VerbCheckArgCount(verb, opt, args, argi, argc, 1); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if args[argi] == "-r" {
|
||||
// Treat like "-tr"
|
||||
cli.VerbCheckArgCount(verb, args[argi], args, argi, argc, 1)
|
||||
if err := cli.VerbCheckArgCount(verb, args[argi], args, argi, argc, 1); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
argi++
|
||||
subList := cli.VerbGetStringArrayArgOrDie(verb, "-tr", args, &argi, argc)
|
||||
subList, err := cli.VerbGetStringArrayArg(verb, "-tr", args, &argi, argc)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
for _, item := range subList {
|
||||
groupByFieldNames = append(groupByFieldNames, item)
|
||||
comparatorFuncs = append(comparatorFuncs, mlrval.NaturalAscendingComparator)
|
||||
}
|
||||
} else {
|
||||
subList := cli.VerbGetStringArrayArgOrDie(verb, opt, args, &argi, argc)
|
||||
subList, err := cli.VerbGetStringArrayArg(verb, opt, args, &argi, argc)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
for _, item := range subList {
|
||||
groupByFieldNames = append(groupByFieldNames, item)
|
||||
comparatorFuncs = append(comparatorFuncs, mlrval.NaturalDescendingComparator)
|
||||
|
|
@ -169,18 +190,28 @@ func transformerSortParseCLI(
|
|||
|
||||
} else if opt == "-r" {
|
||||
// See comments over "-n" -- similar hack.
|
||||
cli.VerbCheckArgCount(verb, opt, args, argi, argc, 1)
|
||||
if err := cli.VerbCheckArgCount(verb, opt, args, argi, argc, 1); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if args[argi] == "-t" {
|
||||
// Treat like "-rt" which is same as "-tr"
|
||||
cli.VerbCheckArgCount(verb, args[argi], args, argi, argc, 1)
|
||||
if err := cli.VerbCheckArgCount(verb, args[argi], args, argi, argc, 1); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
argi++
|
||||
subList := cli.VerbGetStringArrayArgOrDie(verb, "-tr", args, &argi, argc)
|
||||
subList, err := cli.VerbGetStringArrayArg(verb, "-tr", args, &argi, argc)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
for _, item := range subList {
|
||||
groupByFieldNames = append(groupByFieldNames, item)
|
||||
comparatorFuncs = append(comparatorFuncs, mlrval.NaturalAscendingComparator)
|
||||
}
|
||||
} else {
|
||||
subList := cli.VerbGetStringArrayArgOrDie(verb, opt, args, &argi, argc)
|
||||
subList, err := cli.VerbGetStringArrayArg(verb, opt, args, &argi, argc)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
for _, item := range subList {
|
||||
groupByFieldNames = append(groupByFieldNames, item)
|
||||
comparatorFuncs = append(comparatorFuncs, mlrval.LexicalDescendingComparator)
|
||||
|
|
@ -210,12 +241,17 @@ func transformerSortParseCLI(
|
|||
// 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".
|
||||
cli.VerbCheckArgCount(verb, opt, args, argi, argc, 1)
|
||||
if err := cli.VerbCheckArgCount(verb, opt, args, argi, argc, 1); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if args[argi] == "-f" {
|
||||
// Treat like "-nf"
|
||||
argi++
|
||||
subList := cli.VerbGetStringArrayArgOrDie(verb, "-nf", args, &argi, argc)
|
||||
subList, err := cli.VerbGetStringArrayArg(verb, "-nf", args, &argi, argc)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
for _, item := range subList {
|
||||
groupByFieldNames = append(groupByFieldNames, item)
|
||||
comparatorFuncs = append(comparatorFuncs, mlrval.NumericAscendingComparator)
|
||||
|
|
@ -224,7 +260,10 @@ func transformerSortParseCLI(
|
|||
} else if args[argi] == "-r" {
|
||||
// Treat like "-nr"
|
||||
argi++
|
||||
subList := cli.VerbGetStringArrayArgOrDie(verb, "-nr", args, &argi, argc)
|
||||
subList, err := cli.VerbGetStringArrayArg(verb, "-nr", args, &argi, argc)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
for _, item := range subList {
|
||||
groupByFieldNames = append(groupByFieldNames, item)
|
||||
comparatorFuncs = append(comparatorFuncs, mlrval.NumericDescendingComparator)
|
||||
|
|
@ -232,7 +271,10 @@ func transformerSortParseCLI(
|
|||
|
||||
} else {
|
||||
// Treat like "-n"
|
||||
subList := cli.VerbGetStringArrayArgOrDie(verb, opt, args, &argi, argc)
|
||||
subList, err := cli.VerbGetStringArrayArg(verb, opt, args, &argi, argc)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
for _, item := range subList {
|
||||
groupByFieldNames = append(groupByFieldNames, item)
|
||||
comparatorFuncs = append(comparatorFuncs, mlrval.NumericAscendingComparator)
|
||||
|
|
@ -240,14 +282,20 @@ func transformerSortParseCLI(
|
|||
}
|
||||
|
||||
} else if opt == "-nf" {
|
||||
subList := cli.VerbGetStringArrayArgOrDie(verb, opt, args, &argi, argc)
|
||||
subList, err := cli.VerbGetStringArrayArg(verb, opt, args, &argi, argc)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
for _, item := range subList {
|
||||
groupByFieldNames = append(groupByFieldNames, item)
|
||||
comparatorFuncs = append(comparatorFuncs, mlrval.NumericAscendingComparator)
|
||||
}
|
||||
|
||||
} else if opt == "-nr" {
|
||||
subList := cli.VerbGetStringArrayArgOrDie(verb, opt, args, &argi, argc)
|
||||
subList, err := cli.VerbGetStringArrayArg(verb, opt, args, &argi, argc)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
for _, item := range subList {
|
||||
groupByFieldNames = append(groupByFieldNames, item)
|
||||
comparatorFuncs = append(comparatorFuncs, mlrval.NumericDescendingComparator)
|
||||
|
|
@ -257,19 +305,17 @@ func transformerSortParseCLI(
|
|||
doMoveToHead = true
|
||||
|
||||
} else {
|
||||
transformerSortUsage(os.Stderr)
|
||||
os.Exit(1)
|
||||
return nil, cli.VerbErrorf(verb, "option \"%s\" not recognized", opt)
|
||||
}
|
||||
}
|
||||
|
||||
if len(groupByFieldNames) == 0 {
|
||||
transformerSortUsage(os.Stderr)
|
||||
os.Exit(1)
|
||||
return nil, cli.VerbErrorf(verb, "-f sort fields required")
|
||||
}
|
||||
|
||||
*pargi = argi
|
||||
if !doConstruct { // All transformers must do this for main command-line parsing
|
||||
return nil
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
transformer, err := NewTransformerSort(
|
||||
|
|
@ -278,11 +324,10 @@ func transformerSortParseCLI(
|
|||
doMoveToHead,
|
||||
)
|
||||
if err != nil {
|
||||
fmt.Fprintf(os.Stderr, "mlr: %v\n", err)
|
||||
os.Exit(1)
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return transformer
|
||||
return transformer, nil
|
||||
}
|
||||
|
||||
// Example:
|
||||
|
|
|
|||
|
|
@ -34,7 +34,7 @@ func transformerSortWithinRecordsParseCLI(
|
|||
args []string,
|
||||
_ *cli.TOptions,
|
||||
doConstruct bool, // false for first pass of CLI-parse, true for second pass
|
||||
) RecordTransformer {
|
||||
) (RecordTransformer, error) {
|
||||
|
||||
// Skip the verb name from the current spot in the mlr command line
|
||||
argi := *pargi
|
||||
|
|
@ -53,14 +53,13 @@ func transformerSortWithinRecordsParseCLI(
|
|||
|
||||
if opt == "-h" || opt == "--help" {
|
||||
transformerSortWithinRecordsUsage(os.Stdout)
|
||||
os.Exit(0)
|
||||
return nil, cli.ErrHelpRequested
|
||||
|
||||
} else if opt == "-r" {
|
||||
doRecurse = true
|
||||
|
||||
} else {
|
||||
transformerSortWithinRecordsUsage(os.Stderr)
|
||||
os.Exit(1)
|
||||
return nil, cli.VerbErrorf(verbNameSortWithinRecords, "option \"%s\" not recognized", opt)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -69,16 +68,15 @@ func transformerSortWithinRecordsParseCLI(
|
|||
|
||||
*pargi = argi
|
||||
if !doConstruct { // All transformers must do this for main command-line parsing
|
||||
return nil
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
transformer, err := NewTransformerSortWithinRecords(doRecurse)
|
||||
if err != nil {
|
||||
fmt.Fprintf(os.Stderr, "mlr: %v\n", err)
|
||||
os.Exit(1)
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return transformer
|
||||
return transformer, nil
|
||||
}
|
||||
|
||||
type TransformerSortWithinRecords struct {
|
||||
|
|
|
|||
|
|
@ -46,7 +46,7 @@ func transformerSparsifyParseCLI(
|
|||
args []string,
|
||||
_ *cli.TOptions,
|
||||
doConstruct bool, // false for first pass of CLI-parse, true for second pass
|
||||
) RecordTransformer {
|
||||
) (RecordTransformer, error) {
|
||||
|
||||
// Skip the verb name from the current spot in the mlr command line
|
||||
argi := *pargi
|
||||
|
|
@ -56,6 +56,7 @@ func transformerSparsifyParseCLI(
|
|||
fillerString := ""
|
||||
var specifiedFieldNames []string = nil
|
||||
|
||||
var err error
|
||||
for argi < argc /* variable increment: 1 or 2 depending on flag */ {
|
||||
opt := args[argi]
|
||||
if !strings.HasPrefix(opt, "-") {
|
||||
|
|
@ -68,23 +69,28 @@ func transformerSparsifyParseCLI(
|
|||
|
||||
if opt == "-h" || opt == "--help" {
|
||||
transformerSparsifyUsage(os.Stdout)
|
||||
os.Exit(0)
|
||||
return nil, cli.ErrHelpRequested
|
||||
|
||||
} else if opt == "-s" {
|
||||
fillerString = cli.VerbGetStringArgOrDie(verb, opt, args, &argi, argc)
|
||||
fillerString, err = cli.VerbGetStringArg(verb, opt, args, &argi, argc)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
} else if opt == "-f" {
|
||||
specifiedFieldNames = cli.VerbGetStringArrayArgOrDie(verb, opt, args, &argi, argc)
|
||||
specifiedFieldNames, err = cli.VerbGetStringArrayArg(verb, opt, args, &argi, argc)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
} else {
|
||||
transformerSparsifyUsage(os.Stderr)
|
||||
os.Exit(1)
|
||||
return nil, cli.VerbErrorf(verb, "option \"%s\" not recognized", opt)
|
||||
}
|
||||
}
|
||||
|
||||
*pargi = argi
|
||||
if !doConstruct { // All transformers must do this for main command-line parsing
|
||||
return nil
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
transformer, err := NewTransformerSparsify(
|
||||
|
|
@ -92,11 +98,10 @@ func transformerSparsifyParseCLI(
|
|||
specifiedFieldNames,
|
||||
)
|
||||
if err != nil {
|
||||
fmt.Fprintf(os.Stderr, "mlr: %v\n", err)
|
||||
os.Exit(1)
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return transformer
|
||||
return transformer, nil
|
||||
}
|
||||
|
||||
type TransformerSparsify struct {
|
||||
|
|
|
|||
|
|
@ -80,7 +80,7 @@ func transformerSplitParseCLI(
|
|||
args []string,
|
||||
mainOptions *cli.TOptions,
|
||||
doConstruct bool, // false for first pass of CLI-parse, true for second pass
|
||||
) RecordTransformer {
|
||||
) (RecordTransformer, error) {
|
||||
|
||||
// Skip the verb name from the current spot in the mlr command line
|
||||
argi := *pargi
|
||||
|
|
@ -107,6 +107,7 @@ func transformerSplitParseCLI(
|
|||
}
|
||||
|
||||
// Parse local flags.
|
||||
var err error
|
||||
for argi < argc /* variable increment: 1 or 2 depending on flag */ {
|
||||
opt := args[argi]
|
||||
if !strings.HasPrefix(opt, "-") {
|
||||
|
|
@ -119,28 +120,46 @@ func transformerSplitParseCLI(
|
|||
|
||||
if opt == "-h" || opt == "--help" {
|
||||
transformerSplitUsage(os.Stdout)
|
||||
os.Exit(0)
|
||||
return nil, cli.ErrHelpRequested
|
||||
|
||||
} else if opt == "-n" {
|
||||
n = cli.VerbGetIntArgOrDie(verb, opt, args, &argi, argc)
|
||||
n, err = cli.VerbGetIntArg(verb, opt, args, &argi, argc)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
doSize = true
|
||||
|
||||
} else if opt == "-m" {
|
||||
n = cli.VerbGetIntArgOrDie(verb, opt, args, &argi, argc)
|
||||
n, err = cli.VerbGetIntArg(verb, opt, args, &argi, argc)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
doMod = true
|
||||
|
||||
} else if opt == "-g" {
|
||||
groupByFieldNames = cli.VerbGetStringArrayArgOrDie(verb, opt, args, &argi, argc)
|
||||
groupByFieldNames, err = cli.VerbGetStringArrayArg(verb, opt, args, &argi, argc)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
} else if opt == "--prefix" {
|
||||
outputFileNamePrefix = cli.VerbGetStringArgOrDie(verb, opt, args, &argi, argc)
|
||||
outputFileNamePrefix, err = cli.VerbGetStringArg(verb, opt, args, &argi, argc)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
} else if opt == "--suffix" {
|
||||
outputFileNameSuffix = cli.VerbGetStringArgOrDie(verb, opt, args, &argi, argc)
|
||||
outputFileNameSuffix, err = cli.VerbGetStringArg(verb, opt, args, &argi, argc)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
haveOutputFileNameSuffix = true
|
||||
|
||||
} else if opt == "--folder" {
|
||||
outputFolder = cli.VerbGetStringArgOrDie(verb, opt, args, &argi, argc)
|
||||
outputFolder, err = cli.VerbGetStringArg(verb, opt, args, &argi, argc)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
} else if opt == "-a" {
|
||||
doAppend = true
|
||||
|
|
@ -152,7 +171,10 @@ func transformerSplitParseCLI(
|
|||
escapeFileNameCharacters = false
|
||||
|
||||
} else if opt == "-j" {
|
||||
fileNamePartJoiner = cli.VerbGetStringArgOrDie(verb, opt, args, &argi, argc)
|
||||
fileNamePartJoiner, err = cli.VerbGetStringArg(verb, opt, args, &argi, argc)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
} else {
|
||||
// This is inelegant. For error-proofing we advance argi already in our
|
||||
|
|
@ -164,20 +186,17 @@ func transformerSplitParseCLI(
|
|||
// Nothing else to handle here.
|
||||
argi = largi
|
||||
} else {
|
||||
transformerSplitUsage(os.Stderr)
|
||||
os.Exit(1)
|
||||
return nil, cli.VerbErrorf(verb, "output format not recognized")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
doGroup := groupByFieldNames != nil
|
||||
if !doMod && !doSize && !doGroup {
|
||||
fmt.Fprintf(os.Stderr, "mlr %s: At least one of -m, -n, or -g is required.\n", verb)
|
||||
os.Exit(1)
|
||||
return nil, cli.VerbErrorf(verb, "-n, -g, or -s is required")
|
||||
}
|
||||
if (doMod && doSize) || (doMod && doGroup) || (doSize && doGroup) {
|
||||
fmt.Fprintf(os.Stderr, "mlr %s: Only one of -m, -n, or -g is required.\n", verb)
|
||||
os.Exit(1)
|
||||
return nil, cli.VerbErrorf(verb, "-n, -g, and -s are mutually exclusive")
|
||||
}
|
||||
|
||||
cli.FinalizeWriterOptions(&localOptions.WriterOptions)
|
||||
|
|
@ -187,7 +206,7 @@ func transformerSplitParseCLI(
|
|||
|
||||
*pargi = argi
|
||||
if !doConstruct { // All transformers must do this for main command-line parsing
|
||||
return nil
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
transformer, err := NewTransformerSplit(
|
||||
|
|
@ -209,7 +228,7 @@ func transformerSplitParseCLI(
|
|||
os.Exit(1)
|
||||
}
|
||||
|
||||
return transformer
|
||||
return transformer, nil
|
||||
}
|
||||
|
||||
type TransformerSplit struct {
|
||||
|
|
@ -310,7 +329,7 @@ func (tr *TransformerSplit) splitModUngrouped(
|
|||
|
||||
err := tr.outputHandlerManager.WriteRecordAndContext(inrecAndContext, filename)
|
||||
if err != nil {
|
||||
fmt.Fprintf(os.Stderr, "mlr: file-write error: %v\n", err)
|
||||
fmt.Fprintf(os.Stderr, "mlr: %v\n", err)
|
||||
os.Exit(1)
|
||||
}
|
||||
|
||||
|
|
@ -346,7 +365,7 @@ func (tr *TransformerSplit) splitSizeUngrouped(
|
|||
if tr.outputHandler != nil {
|
||||
err = tr.outputHandler.Close()
|
||||
if err != nil {
|
||||
fmt.Fprintf(os.Stderr, "mlr: file-close error: %v\n", err)
|
||||
fmt.Fprintf(os.Stderr, "mlr: %v\n", err)
|
||||
os.Exit(1)
|
||||
}
|
||||
}
|
||||
|
|
@ -358,7 +377,7 @@ func (tr *TransformerSplit) splitSizeUngrouped(
|
|||
tr.doAppend,
|
||||
)
|
||||
if err != nil {
|
||||
fmt.Fprintf(os.Stderr, "mlr: file-open error: %v\n", err)
|
||||
fmt.Fprintf(os.Stderr, "mlr: %v\n", err)
|
||||
os.Exit(1)
|
||||
}
|
||||
|
||||
|
|
@ -367,7 +386,7 @@ func (tr *TransformerSplit) splitSizeUngrouped(
|
|||
|
||||
err = tr.outputHandler.WriteRecordAndContext(inrecAndContext)
|
||||
if err != nil {
|
||||
fmt.Fprintf(os.Stderr, "mlr: file-write error: %v\n", err)
|
||||
fmt.Fprintf(os.Stderr, "mlr: %v\n", err)
|
||||
os.Exit(1)
|
||||
}
|
||||
|
||||
|
|
@ -383,7 +402,7 @@ func (tr *TransformerSplit) splitSizeUngrouped(
|
|||
if tr.outputHandler != nil {
|
||||
err := tr.outputHandler.Close()
|
||||
if err != nil {
|
||||
fmt.Fprintf(os.Stderr, "mlr: file-close error: %v\n", err)
|
||||
fmt.Fprintf(os.Stderr, "mlr: %v\n", err)
|
||||
os.Exit(1)
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -92,7 +92,7 @@ func transformerStats1ParseCLI(
|
|||
args []string,
|
||||
_ *cli.TOptions,
|
||||
doConstruct bool, // false for first pass of CLI-parse, true for second pass
|
||||
) RecordTransformer {
|
||||
) (RecordTransformer, error) {
|
||||
|
||||
// Skip the verb name from the current spot in the mlr command line
|
||||
argi := *pargi
|
||||
|
|
@ -111,6 +111,7 @@ func transformerStats1ParseCLI(
|
|||
doInterpolatedPercentiles := false
|
||||
doIterativeStats := false
|
||||
|
||||
var err error
|
||||
for argi < argc /* variable increment: 1 or 2 depending on flag */ {
|
||||
opt := args[argi]
|
||||
if !strings.HasPrefix(opt, "-") {
|
||||
|
|
@ -123,30 +124,51 @@ func transformerStats1ParseCLI(
|
|||
|
||||
if opt == "-h" || opt == "--help" {
|
||||
transformerStats1Usage(os.Stdout)
|
||||
os.Exit(0)
|
||||
return nil, cli.ErrHelpRequested
|
||||
|
||||
} else if opt == "-a" {
|
||||
accumulatorNameList = cli.VerbGetStringArrayArgOrDie(verb, opt, args, &argi, argc)
|
||||
accumulatorNameList, err = cli.VerbGetStringArrayArg(verb, opt, args, &argi, argc)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
} else if opt == "-f" {
|
||||
valueFieldNameList = cli.VerbGetStringArrayArgOrDie(verb, opt, args, &argi, argc)
|
||||
valueFieldNameList, err = cli.VerbGetStringArrayArg(verb, opt, args, &argi, argc)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
} else if opt == "-g" {
|
||||
groupByFieldNameList = cli.VerbGetStringArrayArgOrDie(verb, opt, args, &argi, argc)
|
||||
groupByFieldNameList, err = cli.VerbGetStringArrayArg(verb, opt, args, &argi, argc)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
} else if opt == "--fr" {
|
||||
valueFieldNameList = cli.VerbGetStringArrayArgOrDie(verb, opt, args, &argi, argc)
|
||||
valueFieldNameList, err = cli.VerbGetStringArrayArg(verb, opt, args, &argi, argc)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
doRegexValueFieldNames = true
|
||||
|
||||
} else if opt == "--fx" {
|
||||
valueFieldNameList = cli.VerbGetStringArrayArgOrDie(verb, opt, args, &argi, argc)
|
||||
valueFieldNameList, err = cli.VerbGetStringArrayArg(verb, opt, args, &argi, argc)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
doRegexValueFieldNames = true
|
||||
invertRegexValueFieldNames = true
|
||||
} else if opt == "--gr" {
|
||||
groupByFieldNameList = cli.VerbGetStringArrayArgOrDie(verb, opt, args, &argi, argc)
|
||||
groupByFieldNameList, err = cli.VerbGetStringArrayArg(verb, opt, args, &argi, argc)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
doRegexGroupByFieldNames = true
|
||||
} else if opt == "--gx" {
|
||||
groupByFieldNameList = cli.VerbGetStringArrayArgOrDie(verb, opt, args, &argi, argc)
|
||||
groupByFieldNameList, err = cli.VerbGetStringArrayArg(verb, opt, args, &argi, argc)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
doRegexGroupByFieldNames = true
|
||||
invertRegexGroupByFieldNames = true
|
||||
|
||||
|
|
@ -154,7 +176,10 @@ func transformerStats1ParseCLI(
|
|||
doRegexValueFieldNames = true
|
||||
doRegexGroupByFieldNames = true
|
||||
invertRegexValueFieldNames = true
|
||||
valueFieldNameList = cli.VerbGetStringArrayArgOrDie(verb, opt, args, &argi, argc)
|
||||
valueFieldNameList, err = cli.VerbGetStringArrayArg(verb, opt, args, &argi, argc)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
groupByFieldNameList = lib.CopyStringArray(valueFieldNameList)
|
||||
|
||||
} else if opt == "-i" {
|
||||
|
|
@ -170,26 +195,21 @@ func transformerStats1ParseCLI(
|
|||
// No-op pass-through for backward compatibility with Miller 5
|
||||
|
||||
} else {
|
||||
transformerStats1Usage(os.Stderr)
|
||||
os.Exit(1)
|
||||
return nil, cli.VerbErrorf(verbNameStats1, "option \"%s\" not recognized", opt)
|
||||
}
|
||||
}
|
||||
|
||||
// TODO: libify for use across verbs.
|
||||
if len(accumulatorNameList) == 0 {
|
||||
fmt.Fprintf(os.Stderr, "%s %s: -a option is required.\n", "mlr", verbNameStats1)
|
||||
fmt.Fprintf(os.Stderr, "Please see %s %s --help for more information.\n", "mlr", verbNameStats1)
|
||||
os.Exit(1)
|
||||
return nil, cli.VerbErrorf(verbNameStats1, "-a option is required")
|
||||
}
|
||||
if len(valueFieldNameList) == 0 {
|
||||
fmt.Fprintf(os.Stderr, "%s %s: -f option is required.\n", "mlr", verbNameStats1)
|
||||
fmt.Fprintf(os.Stderr, "Please see %s %s --help for more information.\n", "mlr", verbNameStats1)
|
||||
os.Exit(1)
|
||||
return nil, cli.VerbErrorf(verbNameStats1, "-f option is required")
|
||||
}
|
||||
|
||||
*pargi = argi
|
||||
if !doConstruct { // All transformers must do this for main command-line parsing
|
||||
return nil
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
transformer, err := NewTransformerStats1(
|
||||
|
|
@ -206,11 +226,10 @@ func transformerStats1ParseCLI(
|
|||
doIterativeStats,
|
||||
)
|
||||
if err != nil {
|
||||
fmt.Fprintf(os.Stderr, "mlr stats1: %v\n", err)
|
||||
os.Exit(1)
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return transformer
|
||||
return transformer, nil
|
||||
}
|
||||
|
||||
type TransformerStats1 struct {
|
||||
|
|
@ -309,7 +328,7 @@ func NewTransformerStats1(
|
|||
) (*TransformerStats1, error) {
|
||||
for _, name := range accumulatorNameList {
|
||||
if !utils.ValidateStats1AccumulatorName(name) {
|
||||
return nil, fmt.Errorf(`accumulator "%s" not found`, name)
|
||||
return nil, fmt.Errorf(`mlr stats1: accumulator "%s" not found`, name)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -62,15 +62,13 @@ func transformerStats2ParseCLI(
|
|||
args []string,
|
||||
_ *cli.TOptions,
|
||||
doConstruct bool, // false for first pass of CLI-parse, true for second pass
|
||||
) RecordTransformer {
|
||||
) (RecordTransformer, error) {
|
||||
|
||||
// Skip the verb name from the current spot in the mlr command line
|
||||
argi := *pargi
|
||||
verb := args[argi]
|
||||
argi++
|
||||
|
||||
argv0 := "mlr"
|
||||
|
||||
var accumulatorNameList []string = nil
|
||||
var valueFieldNameList []string = nil
|
||||
groupByFieldNameList := []string{}
|
||||
|
|
@ -78,6 +76,7 @@ func transformerStats2ParseCLI(
|
|||
doIterativeStats := false
|
||||
doHoldAndFit := false
|
||||
|
||||
var err error
|
||||
for argi < argc /* variable increment: 1 or 2 depending on flag */ {
|
||||
opt := args[argi]
|
||||
if !strings.HasPrefix(opt, "-") {
|
||||
|
|
@ -90,16 +89,25 @@ func transformerStats2ParseCLI(
|
|||
|
||||
if opt == "-h" || opt == "--help" {
|
||||
transformerStats2Usage(os.Stdout)
|
||||
os.Exit(0)
|
||||
return nil, cli.ErrHelpRequested
|
||||
|
||||
} else if opt == "-a" {
|
||||
accumulatorNameList = cli.VerbGetStringArrayArgOrDie(verb, opt, args, &argi, argc)
|
||||
accumulatorNameList, err = cli.VerbGetStringArrayArg(verb, opt, args, &argi, argc)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
} else if opt == "-f" {
|
||||
valueFieldNameList = cli.VerbGetStringArrayArgOrDie(verb, opt, args, &argi, argc)
|
||||
valueFieldNameList, err = cli.VerbGetStringArrayArg(verb, opt, args, &argi, argc)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
} else if opt == "-g" {
|
||||
groupByFieldNameList = cli.VerbGetStringArrayArgOrDie(verb, opt, args, &argi, argc)
|
||||
groupByFieldNameList, err = cli.VerbGetStringArrayArg(verb, opt, args, &argi, argc)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
} else if opt == "-v" {
|
||||
doVerbose = true
|
||||
|
|
@ -120,34 +128,26 @@ func transformerStats2ParseCLI(
|
|||
// for all applicable stats2 accumulators (i.e. none of them).
|
||||
|
||||
} else {
|
||||
transformerStats2Usage(os.Stderr)
|
||||
os.Exit(1)
|
||||
return nil, cli.VerbErrorf(verb, "option \"%s\" not recognized", opt)
|
||||
}
|
||||
}
|
||||
|
||||
if doIterativeStats && doHoldAndFit {
|
||||
transformerStats2Usage(os.Stderr)
|
||||
os.Exit(1)
|
||||
return nil, cli.VerbErrorf(verb, "cannot combine -I and -H")
|
||||
}
|
||||
if accumulatorNameList == nil {
|
||||
fmt.Fprintf(os.Stderr, "%s %s: -a option is required.\n", argv0, verb)
|
||||
fmt.Fprintf(os.Stderr, "Please see %s %s --help for more information.\n", argv0, verb)
|
||||
os.Exit(1)
|
||||
return nil, cli.VerbErrorf(verb, "-a option is required")
|
||||
}
|
||||
if valueFieldNameList == nil {
|
||||
fmt.Fprintf(os.Stderr, "%s %s: -f option is required.\n", argv0, verb)
|
||||
fmt.Fprintf(os.Stderr, "Please see %s %s --help for more information.\n", argv0, verb)
|
||||
os.Exit(1)
|
||||
return nil, cli.VerbErrorf(verb, "-f option is required")
|
||||
}
|
||||
if len(valueFieldNameList)%2 != 0 {
|
||||
fmt.Fprintf(os.Stderr, "%s %s: argument to -f must have even number of fields.\n", argv0, verb)
|
||||
fmt.Fprintf(os.Stderr, "Please see %s %s --help for more information.\n", argv0, verb)
|
||||
os.Exit(1)
|
||||
return nil, cli.VerbErrorf(verb, "argument to -f must have even number of fields")
|
||||
}
|
||||
|
||||
*pargi = argi
|
||||
if !doConstruct { // All transformers must do this for main command-line parsing
|
||||
return nil
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
transformer, err := NewTransformerStats2(
|
||||
|
|
@ -159,11 +159,10 @@ func transformerStats2ParseCLI(
|
|||
doHoldAndFit,
|
||||
)
|
||||
if err != nil {
|
||||
fmt.Fprintf(os.Stderr, "mlr: %v\n", err)
|
||||
os.Exit(1)
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return transformer
|
||||
return transformer, nil
|
||||
}
|
||||
|
||||
type TransformerStats2 struct {
|
||||
|
|
@ -348,9 +347,7 @@ func (tr *TransformerStats2) ingest(
|
|||
tr.doVerbose,
|
||||
)
|
||||
if accumulator == nil {
|
||||
fmt.Fprintf(os.Stderr, "%s %s: accumulator \"%s\" not found.\n",
|
||||
"mlr", verbNameStats2, accumulatorName,
|
||||
)
|
||||
fmt.Fprintf(os.Stderr, "mlr stats2: accumulator creation failed\n")
|
||||
os.Exit(1)
|
||||
}
|
||||
valueFieldsToAccumulator.Put(accumulatorName, accumulator)
|
||||
|
|
|
|||
|
|
@ -143,7 +143,7 @@ func transformerStepParseCLI(
|
|||
args []string,
|
||||
_ *cli.TOptions,
|
||||
doConstruct bool, // false for first pass of CLI-parse, true for second pass
|
||||
) RecordTransformer {
|
||||
) (RecordTransformer, error) {
|
||||
|
||||
// Skip the verb name from the current spot in the mlr command line
|
||||
argi := *pargi
|
||||
|
|
@ -168,51 +168,67 @@ func transformerStepParseCLI(
|
|||
|
||||
if opt == "-h" || opt == "--help" {
|
||||
transformerStepUsage(os.Stdout)
|
||||
os.Exit(0)
|
||||
return nil, cli.ErrHelpRequested
|
||||
|
||||
} else if opt == "-a" {
|
||||
// Let them do '-a delta -a rsum' or '-a delta,rsum'
|
||||
stepperNames := cli.VerbGetStringArrayArgOrDie(verb, opt, args, &argi, argc)
|
||||
stepperNames, err := cli.VerbGetStringArrayArg(verb, opt, args, &argi, argc)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
for _, stepperName := range stepperNames {
|
||||
stepperInput := stepperInputFromName(stepperName)
|
||||
if stepperInput == nil {
|
||||
fmt.Fprintf(os.Stderr, "mlr %s: stepper \"%s\" not found.\n",
|
||||
verbNameStep, stepperName)
|
||||
os.Exit(1)
|
||||
return nil, cli.VerbErrorf(verb, "stepper \"%s\" not found", stepperName)
|
||||
}
|
||||
stepperInputs = append(stepperInputs, stepperInput)
|
||||
}
|
||||
|
||||
} else if opt == "-f" {
|
||||
// Let them do '-f x -f y' or '-f x,y'
|
||||
valueFieldNames = append(valueFieldNames, cli.VerbGetStringArrayArgOrDie(verb, opt, args, &argi, argc)...)
|
||||
arr, err := cli.VerbGetStringArrayArg(verb, opt, args, &argi, argc)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
valueFieldNames = append(valueFieldNames, arr...)
|
||||
|
||||
} else if opt == "-g" {
|
||||
// Let them do '-g a -g b' or '-g a,b'
|
||||
groupByFieldNames = append(groupByFieldNames, cli.VerbGetStringArrayArgOrDie(verb, opt, args, &argi, argc)...)
|
||||
arr, err := cli.VerbGetStringArrayArg(verb, opt, args, &argi, argc)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
groupByFieldNames = append(groupByFieldNames, arr...)
|
||||
|
||||
} else if opt == "-d" {
|
||||
// Let them do '-d 0.8 -d 0.9' or '-d 0.8,0.9'
|
||||
stringAlphas = append(stringAlphas, cli.VerbGetStringArrayArgOrDie(verb, opt, args, &argi, argc)...)
|
||||
arr, err := cli.VerbGetStringArrayArg(verb, opt, args, &argi, argc)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
stringAlphas = append(stringAlphas, arr...)
|
||||
|
||||
} else if opt == "-o" {
|
||||
// Let them do '-o fast -o slow' or '-o fast,slow'
|
||||
ewmaSuffixes = append(ewmaSuffixes, cli.VerbGetStringArrayArgOrDie(verb, opt, args, &argi, argc)...)
|
||||
arr, err := cli.VerbGetStringArrayArg(verb, opt, args, &argi, argc)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
ewmaSuffixes = append(ewmaSuffixes, arr...)
|
||||
|
||||
} else if opt == "-F" {
|
||||
// As of Miller 6 this happens automatically, but the flag is accepted
|
||||
// as a no-op for backward compatibility with Miller 5 and below.
|
||||
|
||||
} else {
|
||||
transformerStepUsage(os.Stderr)
|
||||
os.Exit(1)
|
||||
return nil, cli.VerbErrorf(verb, "option \"%s\" not recognized", opt)
|
||||
}
|
||||
}
|
||||
|
||||
*pargi = argi
|
||||
if !doConstruct { // All transformers must do this for main command-line parsing
|
||||
return nil
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
transformer, err := NewTransformerStep(
|
||||
|
|
@ -223,11 +239,10 @@ func transformerStepParseCLI(
|
|||
ewmaSuffixes,
|
||||
)
|
||||
if err != nil {
|
||||
fmt.Fprintf(os.Stderr, "mlr: %v\n", err)
|
||||
os.Exit(1)
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return transformer
|
||||
return transformer, nil
|
||||
}
|
||||
|
||||
// This is the "stepper log" referred to in comments at the top of this file.
|
||||
|
|
@ -436,8 +451,7 @@ func (tr *TransformerStep) handleRecord(
|
|||
tr.ewmaSuffixes,
|
||||
)
|
||||
if stepper == nil {
|
||||
fmt.Fprintf(os.Stderr, "mlr %s: stepper \"%s\" not found.\n",
|
||||
verbNameStep, stepperInput.name)
|
||||
fmt.Fprintf(os.Stderr, "mlr step: stepper allocation failed\n")
|
||||
os.Exit(1)
|
||||
}
|
||||
accFieldToAccState[stepperInput.name] = stepper
|
||||
|
|
|
|||
|
|
@ -97,7 +97,7 @@ func transformerSubParseCLI(
|
|||
args []string,
|
||||
opts *cli.TOptions,
|
||||
doConstruct bool, // false for first pass of CLI-parse, true for second pass
|
||||
) RecordTransformer {
|
||||
) (RecordTransformer, error) {
|
||||
return transformerSubsParseCLI(pargi, argc, args, opts, doConstruct, transformerSubUsage, NewTransformerSub)
|
||||
}
|
||||
|
||||
|
|
@ -107,7 +107,7 @@ func transformerGsubParseCLI(
|
|||
args []string,
|
||||
opts *cli.TOptions,
|
||||
doConstruct bool, // false for first pass of CLI-parse, true for second pass
|
||||
) RecordTransformer {
|
||||
) (RecordTransformer, error) {
|
||||
return transformerSubsParseCLI(pargi, argc, args, opts, doConstruct, transformerGsubUsage, NewTransformerGsub)
|
||||
}
|
||||
|
||||
|
|
@ -117,7 +117,7 @@ func transformerSsubParseCLI(
|
|||
args []string,
|
||||
opts *cli.TOptions,
|
||||
doConstruct bool, // false for first pass of CLI-parse, true for second pass
|
||||
) RecordTransformer {
|
||||
) (RecordTransformer, error) {
|
||||
return transformerSubsParseCLI(pargi, argc, args, opts, doConstruct, transformerSsubUsage, NewTransformerSsub)
|
||||
}
|
||||
|
||||
|
|
@ -130,7 +130,7 @@ func transformerSubsParseCLI(
|
|||
doConstruct bool, // false for first pass of CLI-parse, true for second pass
|
||||
usageFunc TransformerUsageFunc,
|
||||
constructorFunc subConstructorFunc,
|
||||
) RecordTransformer {
|
||||
) (RecordTransformer, error) {
|
||||
|
||||
// Skip the verb name from the current spot in the mlr command line
|
||||
argi := *pargi
|
||||
|
|
@ -144,6 +144,7 @@ func transformerSubsParseCLI(
|
|||
var oldText string
|
||||
var newText string
|
||||
|
||||
var err error
|
||||
for argi < argc /* variable increment: 1 or 2 depending on flag */ {
|
||||
opt := args[argi]
|
||||
if !strings.HasPrefix(opt, "-") {
|
||||
|
|
@ -167,7 +168,10 @@ func transformerSubsParseCLI(
|
|||
doRegexes = true
|
||||
|
||||
} else if opt == "-f" {
|
||||
fieldNames = cli.VerbGetStringArrayArgOrDie(verb, opt, args, &argi, argc)
|
||||
fieldNames, err = cli.VerbGetStringArrayArg(verb, opt, args, &argi, argc)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
doAllFieldNames = false
|
||||
} else {
|
||||
usageFunc(os.Stderr)
|
||||
|
|
@ -192,7 +196,7 @@ func transformerSubsParseCLI(
|
|||
|
||||
*pargi = argi
|
||||
if !doConstruct { // All transformers must do this for main command-line parsing
|
||||
return nil
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
transformer, err := constructorFunc(
|
||||
|
|
@ -203,11 +207,10 @@ func transformerSubsParseCLI(
|
|||
newText,
|
||||
)
|
||||
if err != nil {
|
||||
fmt.Fprintf(os.Stderr, "mlr: %v\n", err)
|
||||
os.Exit(1)
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return transformer
|
||||
return transformer, nil
|
||||
}
|
||||
|
||||
type TransformerSubs struct {
|
||||
|
|
@ -273,8 +276,7 @@ func NewTransformerSubs(
|
|||
// Handles "a.*b"i Miller case-insensitive-regex specification
|
||||
regex, err := lib.CompileMillerRegex(regexString)
|
||||
if err != nil {
|
||||
fmt.Fprintf(os.Stderr, "%s %s: cannot compile regex [%s]\n", "mlr", verbNameCut, regexString)
|
||||
os.Exit(1)
|
||||
return nil, cli.VerbErrorf("sub", "invalid regex \"%s\": %w", regexString, err)
|
||||
}
|
||||
tr.regexes[i] = regex
|
||||
}
|
||||
|
|
|
|||
|
|
@ -114,7 +114,7 @@ func transformerSummaryParseCLI(
|
|||
args []string,
|
||||
_ *cli.TOptions,
|
||||
doConstruct bool, // false for first pass of CLI-parse, true for second pass
|
||||
) RecordTransformer {
|
||||
) (RecordTransformer, error) {
|
||||
|
||||
// Skip the verb name from the current spot in the mlr command line
|
||||
argi := *pargi
|
||||
|
|
@ -135,6 +135,7 @@ func transformerSummaryParseCLI(
|
|||
|
||||
transposeOutput := false
|
||||
|
||||
var err error
|
||||
for argi < argc /* variable increment: 1 or 2 depending on flag */ {
|
||||
opt := args[argi]
|
||||
if !strings.HasPrefix(opt, "-") {
|
||||
|
|
@ -147,30 +148,30 @@ func transformerSummaryParseCLI(
|
|||
|
||||
if opt == "-h" || opt == "--help" {
|
||||
transformerSummaryUsage(os.Stdout)
|
||||
os.Exit(0)
|
||||
return nil, cli.ErrHelpRequested
|
||||
|
||||
} else if opt == "--all" {
|
||||
summarizerNames = allSummarizerNamesList
|
||||
|
||||
} else if opt == "-a" {
|
||||
summarizerNames = cli.VerbGetStringArrayArgOrDie(verb, opt, args, &argi, argc)
|
||||
summarizerNames, err = cli.VerbGetStringArrayArg(verb, opt, args, &argi, argc)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
for _, summarizerName := range summarizerNames {
|
||||
if !allSummarizerNamesSet[summarizerName] {
|
||||
fmt.Fprintf(os.Stderr, "mlr %s: unrecognized summarizer name %s\n",
|
||||
verb, summarizerName,
|
||||
)
|
||||
os.Exit(1)
|
||||
return nil, cli.VerbErrorf(verb, "summarizer \"%s\" not found", summarizerName)
|
||||
}
|
||||
}
|
||||
|
||||
} else if opt == "-x" {
|
||||
excludeSummarizerNames := cli.VerbGetStringArrayArgOrDie(verb, opt, args, &argi, argc)
|
||||
excludeSummarizerNames, err := cli.VerbGetStringArrayArg(verb, opt, args, &argi, argc)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
for _, excludeSummarizerName := range excludeSummarizerNames {
|
||||
if !allSummarizerNamesSet[excludeSummarizerName] {
|
||||
fmt.Fprintf(os.Stderr, "mlr %s: unrecognized Summarizer name %s\n",
|
||||
verb, excludeSummarizerName,
|
||||
)
|
||||
os.Exit(1)
|
||||
return nil, cli.VerbErrorf(verb, "exclude summarizer \"%s\" not found", excludeSummarizerName)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -190,23 +191,21 @@ func transformerSummaryParseCLI(
|
|||
transposeOutput = true
|
||||
|
||||
} else {
|
||||
transformerSummaryUsage(os.Stderr)
|
||||
os.Exit(1)
|
||||
return nil, cli.VerbErrorf(verb, "option \"%s\" not recognized", opt)
|
||||
}
|
||||
}
|
||||
|
||||
*pargi = argi
|
||||
if !doConstruct { // All transformers must do this for main command-line parsing
|
||||
return nil
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
transformer, err := NewTransformerSummary(summarizerNames, transposeOutput)
|
||||
if err != nil {
|
||||
fmt.Fprintf(os.Stderr, "mlr: %v\n", err)
|
||||
os.Exit(1)
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return transformer
|
||||
return transformer, nil
|
||||
}
|
||||
|
||||
type tFieldSummary struct {
|
||||
|
|
|
|||
|
|
@ -39,7 +39,7 @@ func transformerSurvParseCLI(
|
|||
args []string,
|
||||
_ *cli.TOptions,
|
||||
doConstruct bool,
|
||||
) RecordTransformer {
|
||||
) (RecordTransformer, error) {
|
||||
argi := *pargi
|
||||
verb := args[argi]
|
||||
argi++
|
||||
|
|
@ -53,19 +53,17 @@ func transformerSurvParseCLI(
|
|||
}
|
||||
if opt == "-h" || opt == "--help" {
|
||||
transformerSurvUsage(os.Stdout)
|
||||
os.Exit(0)
|
||||
return nil, cli.ErrHelpRequested
|
||||
} else if opt == "-d" {
|
||||
if argi+1 >= argc {
|
||||
fmt.Fprintf(os.Stderr, "mlr %s: %s requires an argument\n", verb, opt)
|
||||
os.Exit(1)
|
||||
return nil, cli.VerbErrorf(verb, "-d requires an argument")
|
||||
}
|
||||
argi++
|
||||
durationField = args[argi]
|
||||
argi++
|
||||
} else if opt == "-s" {
|
||||
if argi+1 >= argc {
|
||||
fmt.Fprintf(os.Stderr, "mlr %s: %s requires an argument\n", verb, opt)
|
||||
os.Exit(1)
|
||||
return nil, cli.VerbErrorf(verb, "-s requires an argument")
|
||||
}
|
||||
argi++
|
||||
statusField = args[argi]
|
||||
|
|
@ -76,17 +74,13 @@ func transformerSurvParseCLI(
|
|||
}
|
||||
*pargi = argi
|
||||
if !doConstruct {
|
||||
return nil
|
||||
return nil, nil
|
||||
}
|
||||
if durationField == "" {
|
||||
fmt.Fprintf(os.Stderr, "mlr %s: -d option is required.\n", verbNameSurv)
|
||||
fmt.Fprintf(os.Stderr, "Please see 'mlr %s --help' for more information.\n", verbNameSurv)
|
||||
os.Exit(1)
|
||||
return nil, fmt.Errorf("mlr %s: -d option is required", verb)
|
||||
}
|
||||
if statusField == "" {
|
||||
fmt.Fprintf(os.Stderr, "mlr %s: -s option is required.\n", verbNameSurv)
|
||||
fmt.Fprintf(os.Stderr, "Please see 'mlr %s --help' for more information.\n", verbNameSurv)
|
||||
os.Exit(1)
|
||||
return nil, fmt.Errorf("mlr %s: -s option is required", verb)
|
||||
}
|
||||
return NewTransformerSurv(durationField, statusField)
|
||||
}
|
||||
|
|
@ -100,13 +94,13 @@ type TransformerSurv struct {
|
|||
}
|
||||
|
||||
// NewTransformerSurv constructs a new surv transformer.
|
||||
func NewTransformerSurv(durationField, statusField string) RecordTransformer {
|
||||
func NewTransformerSurv(durationField, statusField string) (*TransformerSurv, error) {
|
||||
return &TransformerSurv{
|
||||
durationField: durationField,
|
||||
statusField: statusField,
|
||||
times: []float64{},
|
||||
events: []bool{},
|
||||
}
|
||||
}, nil
|
||||
}
|
||||
|
||||
// Transform processes each record or emits results at end-of-stream.
|
||||
|
|
@ -121,14 +115,14 @@ func (tr *TransformerSurv) Transform(
|
|||
rec := inrecAndContext.Record
|
||||
mvDur := rec.Get(tr.durationField)
|
||||
if mvDur == nil {
|
||||
fmt.Fprintf(os.Stderr, "mlr surv: duration field '%s' not found\n", tr.durationField)
|
||||
os.Exit(1)
|
||||
// Skip records missing the duration field
|
||||
return
|
||||
}
|
||||
duration := mvDur.GetNumericToFloatValueOrDie()
|
||||
mvStat := rec.Get(tr.statusField)
|
||||
if mvStat == nil {
|
||||
fmt.Fprintf(os.Stderr, "mlr surv: status field '%s' not found\n", tr.statusField)
|
||||
os.Exit(1)
|
||||
// Skip records missing the status field
|
||||
return
|
||||
}
|
||||
status := mvStat.GetNumericToFloatValueOrDie() != 0
|
||||
tr.times = append(tr.times, duration)
|
||||
|
|
|
|||
|
|
@ -33,7 +33,7 @@ func transformerTacParseCLI(
|
|||
args []string,
|
||||
_ *cli.TOptions,
|
||||
doConstruct bool, // false for first pass of CLI-parse, true for second pass
|
||||
) RecordTransformer {
|
||||
) (RecordTransformer, error) {
|
||||
|
||||
// Skip the verb name from the current spot in the mlr command line
|
||||
argi := *pargi
|
||||
|
|
@ -51,25 +51,23 @@ func transformerTacParseCLI(
|
|||
|
||||
if opt == "-h" || opt == "--help" {
|
||||
transformerTacUsage(os.Stdout)
|
||||
os.Exit(0)
|
||||
return nil, cli.ErrHelpRequested
|
||||
|
||||
}
|
||||
transformerTacUsage(os.Stderr)
|
||||
os.Exit(1)
|
||||
return nil, cli.VerbErrorf(verbNameTac, "option \"%s\" not recognized", opt)
|
||||
}
|
||||
|
||||
*pargi = argi
|
||||
if !doConstruct { // All transformers must do this for main command-line parsing
|
||||
return nil
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
transformer, err := NewTransformerTac()
|
||||
if err != nil {
|
||||
fmt.Fprintf(os.Stderr, "mlr: %v\n", err)
|
||||
os.Exit(1)
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return transformer
|
||||
return transformer, nil
|
||||
}
|
||||
|
||||
type TransformerTac struct {
|
||||
|
|
|
|||
|
|
@ -37,7 +37,7 @@ func transformerTailParseCLI(
|
|||
args []string,
|
||||
_ *cli.TOptions,
|
||||
doConstruct bool, // false for first pass of CLI-parse, true for second pass
|
||||
) RecordTransformer {
|
||||
) (RecordTransformer, error) {
|
||||
|
||||
// Skip the verb name from the current spot in the mlr command line
|
||||
argi := *pargi
|
||||
|
|
@ -59,10 +59,14 @@ func transformerTailParseCLI(
|
|||
|
||||
if opt == "-h" || opt == "--help" {
|
||||
transformerTailUsage(os.Stdout)
|
||||
os.Exit(0)
|
||||
return nil, cli.ErrHelpRequested
|
||||
|
||||
} else if opt == "-n" {
|
||||
tailCount = cli.VerbGetIntArgOrDie(verb, opt, args, &argi, argc)
|
||||
n, err := cli.VerbGetIntArg(verb, opt, args, &argi, argc)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
tailCount = n
|
||||
|
||||
// This is a bit of a hack. In our Getoptify routine we preprocess
|
||||
// the command line sending '-xyz' to '-x -y -z', but leaving
|
||||
|
|
@ -75,17 +79,21 @@ func transformerTailParseCLI(
|
|||
}
|
||||
|
||||
} else if opt == "-g" {
|
||||
groupByFieldNames = cli.VerbGetStringArrayArgOrDie(verb, opt, args, &argi, argc)
|
||||
names, err := cli.VerbGetStringArrayArg(verb, opt, args, &argi, argc)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
groupByFieldNames = names
|
||||
|
||||
} else {
|
||||
transformerTailUsage(os.Stderr)
|
||||
os.Exit(1)
|
||||
return nil, fmt.Errorf("%s %s: option \"%s\" not recognized", "mlr", verb, opt)
|
||||
}
|
||||
}
|
||||
|
||||
*pargi = argi
|
||||
if !doConstruct { // All transformers must do this for main command-line parsing
|
||||
return nil
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
transformer, err := NewTransformerTail(
|
||||
|
|
@ -93,11 +101,10 @@ func transformerTailParseCLI(
|
|||
groupByFieldNames,
|
||||
)
|
||||
if err != nil {
|
||||
fmt.Fprintf(os.Stderr, "mlr: %v\n", err)
|
||||
os.Exit(1)
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return transformer
|
||||
return transformer, nil
|
||||
}
|
||||
|
||||
type TransformerTail struct {
|
||||
|
|
|
|||
|
|
@ -42,7 +42,7 @@ func transformerTeeParseCLI(
|
|||
args []string,
|
||||
mainOptions *cli.TOptions,
|
||||
doConstruct bool, // false for first pass of CLI-parse, true for second pass
|
||||
) RecordTransformer {
|
||||
) (RecordTransformer, error) {
|
||||
|
||||
// Skip the verb name from the current spot in the mlr command line
|
||||
argi := *pargi
|
||||
|
|
@ -72,7 +72,7 @@ func transformerTeeParseCLI(
|
|||
|
||||
if opt == "-h" || opt == "--help" {
|
||||
transformerTeeUsage(os.Stdout)
|
||||
os.Exit(0)
|
||||
return nil, cli.ErrHelpRequested
|
||||
|
||||
} else if opt == "-a" {
|
||||
appending = true
|
||||
|
|
@ -92,7 +92,6 @@ func transformerTeeParseCLI(
|
|||
// Nothing else to handle here.
|
||||
argi = largi
|
||||
} else {
|
||||
transformerTeeUsage(os.Stderr)
|
||||
os.Exit(1)
|
||||
}
|
||||
}
|
||||
|
|
@ -102,15 +101,14 @@ func transformerTeeParseCLI(
|
|||
|
||||
// Get the filename/command from the command line, after the flags
|
||||
if argi >= argc {
|
||||
transformerTeeUsage(os.Stderr)
|
||||
os.Exit(1)
|
||||
return nil, cli.VerbErrorf(verbNameTee, "filename or command required")
|
||||
}
|
||||
filenameOrCommand = args[argi]
|
||||
argi++
|
||||
|
||||
*pargi = argi
|
||||
if !doConstruct { // All transformers must do this for main command-line parsing
|
||||
return nil
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
transformer, err := NewTransformerTee(
|
||||
|
|
@ -124,7 +122,7 @@ func transformerTeeParseCLI(
|
|||
os.Exit(1)
|
||||
}
|
||||
|
||||
return transformer
|
||||
return transformer, nil
|
||||
}
|
||||
|
||||
type TransformerTee struct {
|
||||
|
|
@ -195,7 +193,6 @@ func (tr *TransformerTee) Transform(
|
|||
"%s: error writing to tee \"%s\":\n",
|
||||
"mlr", tr.filenameOrCommandForDisplay,
|
||||
)
|
||||
fmt.Fprintf(os.Stderr, "mlr: %v\n", err)
|
||||
os.Exit(1)
|
||||
}
|
||||
|
||||
|
|
@ -208,7 +205,6 @@ func (tr *TransformerTee) Transform(
|
|||
"%s: error closing tee \"%s\":\n",
|
||||
"mlr", tr.filenameOrCommandForDisplay,
|
||||
)
|
||||
fmt.Fprintf(os.Stderr, "mlr: %v\n", err)
|
||||
os.Exit(1)
|
||||
}
|
||||
*outputRecordsAndContexts = append(*outputRecordsAndContexts, inrecAndContext)
|
||||
|
|
|
|||
|
|
@ -44,7 +44,7 @@ func transformerTemplateParseCLI(
|
|||
args []string,
|
||||
_ *cli.TOptions,
|
||||
doConstruct bool, // false for first pass of CLI-parse, true for second pass
|
||||
) RecordTransformer {
|
||||
) (RecordTransformer, error) {
|
||||
|
||||
// Skip the verb name from the current spot in the mlr command line
|
||||
argi := *pargi
|
||||
|
|
@ -54,6 +54,7 @@ func transformerTemplateParseCLI(
|
|||
var fieldNames []string = nil
|
||||
fillWith := ""
|
||||
|
||||
var err error
|
||||
for argi < argc /* variable increment: 1 or 2 depending on flag */ {
|
||||
opt := args[argi]
|
||||
if !strings.HasPrefix(opt, "-") {
|
||||
|
|
@ -66,37 +67,43 @@ func transformerTemplateParseCLI(
|
|||
|
||||
if opt == "-h" || opt == "--help" {
|
||||
transformerTemplateUsage(os.Stdout)
|
||||
os.Exit(0)
|
||||
return nil, cli.ErrHelpRequested
|
||||
|
||||
} else if opt == "-f" {
|
||||
fieldNames = cli.VerbGetStringArrayArgOrDie(verb, opt, args, &argi, argc)
|
||||
fieldNames, err = cli.VerbGetStringArrayArg(verb, opt, args, &argi, argc)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
} else if opt == "-t" {
|
||||
templateFileName := cli.VerbGetStringArgOrDie(verb, opt, args, &argi, argc)
|
||||
templateFileName, err := cli.VerbGetStringArg(verb, opt, args, &argi, argc)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
temp, err := lib.ReadCSVHeader(templateFileName)
|
||||
if err != nil {
|
||||
fmt.Println(err)
|
||||
os.Exit(1)
|
||||
return nil, fmt.Errorf("mlr %s: cannot read template file: %w", verb, err)
|
||||
}
|
||||
fieldNames = temp
|
||||
|
||||
} else if opt == "--fill-with" {
|
||||
fillWith = cli.VerbGetStringArgOrDie(verb, opt, args, &argi, argc)
|
||||
fillWith, err = cli.VerbGetStringArg(verb, opt, args, &argi, argc)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
} else {
|
||||
transformerTemplateUsage(os.Stderr)
|
||||
os.Exit(1)
|
||||
return nil, cli.VerbErrorf(verb, "option \"%s\" not recognized", opt)
|
||||
}
|
||||
}
|
||||
|
||||
if fieldNames == nil {
|
||||
transformerTemplateUsage(os.Stderr)
|
||||
os.Exit(1)
|
||||
return nil, cli.VerbErrorf(verb, "-f or -t is required")
|
||||
}
|
||||
|
||||
*pargi = argi
|
||||
if !doConstruct { // All transformers must do this for main command-line parsing
|
||||
return nil
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
transformer, err := NewTransformerTemplate(
|
||||
|
|
@ -104,11 +111,10 @@ func transformerTemplateParseCLI(
|
|||
fillWith,
|
||||
)
|
||||
if err != nil {
|
||||
fmt.Fprintf(os.Stderr, "mlr: %v\n", err)
|
||||
os.Exit(1)
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return transformer
|
||||
return transformer, nil
|
||||
}
|
||||
|
||||
type TransformerTemplate struct {
|
||||
|
|
|
|||
|
|
@ -52,7 +52,7 @@ func transformerTopParseCLI(
|
|||
args []string,
|
||||
_ *cli.TOptions,
|
||||
doConstruct bool, // false for first pass of CLI-parse, true for second pass
|
||||
) RecordTransformer {
|
||||
) (RecordTransformer, error) {
|
||||
|
||||
// Skip the verb name from the current spot in the mlr command line
|
||||
argi := *pargi
|
||||
|
|
@ -67,6 +67,7 @@ func transformerTopParseCLI(
|
|||
doMax := true
|
||||
outputFieldName := verbTopDefaultOutputFieldName
|
||||
|
||||
var err error
|
||||
for argi < argc /* variable increment: 1 or 2 depending on flag */ {
|
||||
opt := args[argi]
|
||||
if !strings.HasPrefix(opt, "-") {
|
||||
|
|
@ -79,14 +80,23 @@ func transformerTopParseCLI(
|
|||
|
||||
if opt == "-h" || opt == "--help" {
|
||||
transformerTopUsage(os.Stdout)
|
||||
os.Exit(0)
|
||||
return nil, cli.ErrHelpRequested
|
||||
|
||||
} else if opt == "-n" {
|
||||
topCount = cli.VerbGetIntArgOrDie(verb, opt, args, &argi, argc)
|
||||
topCount, err = cli.VerbGetIntArg(verb, opt, args, &argi, argc)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
} else if opt == "-f" {
|
||||
valueFieldNames = cli.VerbGetStringArrayArgOrDie(verb, opt, args, &argi, argc)
|
||||
valueFieldNames, err = cli.VerbGetStringArrayArg(verb, opt, args, &argi, argc)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
} else if opt == "-g" {
|
||||
groupByFieldNames = cli.VerbGetStringArrayArgOrDie(verb, opt, args, &argi, argc)
|
||||
groupByFieldNames, err = cli.VerbGetStringArrayArg(verb, opt, args, &argi, argc)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
} else if opt == "-a" {
|
||||
showFullRecords = true
|
||||
} else if opt == "--max" {
|
||||
|
|
@ -96,26 +106,26 @@ func transformerTopParseCLI(
|
|||
} else if opt == "-F" {
|
||||
// Ignored in Miller 6; allowed for command-line backward compatibility
|
||||
} else if opt == "-o" {
|
||||
outputFieldName = cli.VerbGetStringArgOrDie(verb, opt, args, &argi, argc)
|
||||
outputFieldName, err = cli.VerbGetStringArg(verb, opt, args, &argi, argc)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
} else {
|
||||
transformerTopUsage(os.Stderr)
|
||||
os.Exit(1)
|
||||
return nil, cli.VerbErrorf(verb, "option \"%s\" not recognized", opt)
|
||||
}
|
||||
}
|
||||
|
||||
if valueFieldNames == nil {
|
||||
transformerTopUsage(os.Stderr)
|
||||
os.Exit(1)
|
||||
return nil, cli.VerbErrorf(verb, "-f field names required")
|
||||
}
|
||||
if len(valueFieldNames) > 1 && showFullRecords {
|
||||
transformerTopUsage(os.Stderr)
|
||||
os.Exit(1)
|
||||
return nil, cli.VerbErrorf(verb, "-a (full records) incompatible with multiple -f fields")
|
||||
}
|
||||
|
||||
*pargi = argi
|
||||
if !doConstruct { // All transformers must do this for main command-line parsing
|
||||
return nil
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
transformer, _ := NewTransformerTop(
|
||||
|
|
@ -127,7 +137,7 @@ func transformerTopParseCLI(
|
|||
outputFieldName,
|
||||
)
|
||||
|
||||
return transformer
|
||||
return transformer, nil
|
||||
}
|
||||
|
||||
type TransformerTop struct {
|
||||
|
|
|
|||
|
|
@ -39,7 +39,7 @@ func transformerUnflattenParseCLI(
|
|||
args []string,
|
||||
options *cli.TOptions,
|
||||
doConstruct bool, // false for first pass of CLI-parse, true for second pass
|
||||
) RecordTransformer {
|
||||
) (RecordTransformer, error) {
|
||||
|
||||
// Skip the verb name from the current spot in the mlr command line
|
||||
argi := *pargi
|
||||
|
|
@ -49,6 +49,7 @@ func transformerUnflattenParseCLI(
|
|||
oFlatSep := "" // means take it from the record context
|
||||
var fieldNames []string = nil
|
||||
|
||||
var err error
|
||||
for argi < argc /* variable increment: 1 or 2 depending on flag */ {
|
||||
opt := args[argi]
|
||||
if !strings.HasPrefix(opt, "-") {
|
||||
|
|
@ -61,23 +62,28 @@ func transformerUnflattenParseCLI(
|
|||
|
||||
if opt == "-h" || opt == "--help" {
|
||||
transformerUnflattenUsage(os.Stdout)
|
||||
os.Exit(0)
|
||||
return nil, cli.ErrHelpRequested
|
||||
|
||||
} else if opt == "-s" {
|
||||
oFlatSep = cli.VerbGetStringArgOrDie(verb, opt, args, &argi, argc)
|
||||
oFlatSep, err = cli.VerbGetStringArg(verb, opt, args, &argi, argc)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
} else if opt == "-f" {
|
||||
fieldNames = cli.VerbGetStringArrayArgOrDie(verb, opt, args, &argi, argc)
|
||||
fieldNames, err = cli.VerbGetStringArrayArg(verb, opt, args, &argi, argc)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
} else {
|
||||
transformerUnflattenUsage(os.Stderr)
|
||||
os.Exit(1)
|
||||
return nil, cli.VerbErrorf(verb, "option \"%s\" not recognized", opt)
|
||||
}
|
||||
}
|
||||
|
||||
*pargi = argi
|
||||
if !doConstruct { // All transformers must do this for main command-line parsing
|
||||
return nil
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
transformer, err := NewTransformerUnflatten(
|
||||
|
|
@ -86,11 +92,10 @@ func transformerUnflattenParseCLI(
|
|||
fieldNames,
|
||||
)
|
||||
if err != nil {
|
||||
fmt.Fprintf(os.Stderr, "mlr: %v\n", err)
|
||||
os.Exit(1)
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return transformer
|
||||
return transformer, nil
|
||||
}
|
||||
|
||||
type TransformerUnflatten struct {
|
||||
|
|
|
|||
|
|
@ -57,7 +57,7 @@ func transformerCountDistinctParseCLI(
|
|||
args []string,
|
||||
_ *cli.TOptions,
|
||||
doConstruct bool, // false for first pass of CLI-parse, true for second pass
|
||||
) RecordTransformer {
|
||||
) (RecordTransformer, error) {
|
||||
|
||||
// Skip the verb name from the current spot in the mlr command line
|
||||
argi := *pargi
|
||||
|
|
@ -71,6 +71,7 @@ func transformerCountDistinctParseCLI(
|
|||
outputFieldName := uniqDefaultOutputFieldName
|
||||
doLashed := true
|
||||
|
||||
var err error
|
||||
for argi < argc /* variable increment: 1 or 2 depending on flag */ {
|
||||
opt := args[argi]
|
||||
if !strings.HasPrefix(opt, "-") {
|
||||
|
|
@ -83,37 +84,43 @@ func transformerCountDistinctParseCLI(
|
|||
|
||||
if opt == "-h" || opt == "--help" {
|
||||
transformerCountDistinctUsage(os.Stdout)
|
||||
os.Exit(0)
|
||||
return nil, cli.ErrHelpRequested
|
||||
|
||||
} else if opt == "-g" || opt == "-f" {
|
||||
fieldNames = cli.VerbGetStringArrayArgOrDie(verb, opt, args, &argi, argc)
|
||||
fieldNames, err = cli.VerbGetStringArrayArg(verb, opt, args, &argi, argc)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
} else if opt == "-x" {
|
||||
fieldNames = cli.VerbGetStringArrayArgOrDie(verb, opt, args, &argi, argc)
|
||||
fieldNames, err = cli.VerbGetStringArrayArg(verb, opt, args, &argi, argc)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
invertFieldNames = true
|
||||
|
||||
} else if opt == "-n" {
|
||||
showNumDistinctOnly = true
|
||||
|
||||
} else if opt == "-o" {
|
||||
outputFieldName = cli.VerbGetStringArgOrDie(verb, opt, args, &argi, argc)
|
||||
outputFieldName, err = cli.VerbGetStringArg(verb, opt, args, &argi, argc)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
} else if opt == "-u" {
|
||||
doLashed = false
|
||||
|
||||
} else {
|
||||
transformerCountDistinctUsage(os.Stderr)
|
||||
os.Exit(1)
|
||||
return nil, cli.VerbErrorf(verb, "option \"%s\" not recognized", opt)
|
||||
}
|
||||
}
|
||||
|
||||
if fieldNames == nil {
|
||||
transformerCountDistinctUsage(os.Stderr)
|
||||
os.Exit(1)
|
||||
return nil, cli.VerbErrorf(verb, "-g or -x field names required")
|
||||
}
|
||||
if !doLashed && showNumDistinctOnly {
|
||||
transformerCountDistinctUsage(os.Stderr)
|
||||
os.Exit(1)
|
||||
return nil, cli.VerbErrorf(verb, "-n requires -a (uniqify entire records)")
|
||||
}
|
||||
|
||||
showCounts := true
|
||||
|
|
@ -121,7 +128,7 @@ func transformerCountDistinctParseCLI(
|
|||
|
||||
*pargi = argi
|
||||
if !doConstruct { // All transformers must do this for main command-line parsing
|
||||
return nil
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
transformer, err := NewTransformerUniq(
|
||||
|
|
@ -134,11 +141,10 @@ func transformerCountDistinctParseCLI(
|
|||
uniqifyEntireRecords,
|
||||
)
|
||||
if err != nil {
|
||||
fmt.Fprintf(os.Stderr, "mlr: %v\n", err)
|
||||
os.Exit(1)
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return transformer
|
||||
return transformer, nil
|
||||
}
|
||||
|
||||
func transformerUniqUsage(
|
||||
|
|
@ -168,7 +174,7 @@ func transformerUniqParseCLI(
|
|||
args []string,
|
||||
_ *cli.TOptions,
|
||||
doConstruct bool, // false for first pass of CLI-parse, true for second pass
|
||||
) RecordTransformer {
|
||||
) (RecordTransformer, error) {
|
||||
|
||||
// Skip the verb name from the current spot in the mlr command line
|
||||
argi := *pargi
|
||||
|
|
@ -183,6 +189,7 @@ func transformerUniqParseCLI(
|
|||
outputFieldName := uniqDefaultOutputFieldName
|
||||
uniqifyEntireRecords := false
|
||||
|
||||
var err error
|
||||
for argi < argc /* variable increment: 1 or 2 depending on flag */ {
|
||||
opt := args[argi]
|
||||
if !strings.HasPrefix(opt, "-") {
|
||||
|
|
@ -195,13 +202,19 @@ func transformerUniqParseCLI(
|
|||
|
||||
if opt == "-h" || opt == "--help" {
|
||||
transformerUniqUsage(os.Stdout)
|
||||
os.Exit(0)
|
||||
return nil, cli.ErrHelpRequested
|
||||
|
||||
} else if opt == "-g" || opt == "-f" {
|
||||
fieldNames = cli.VerbGetStringArrayArgOrDie(verb, opt, args, &argi, argc)
|
||||
fieldNames, err = cli.VerbGetStringArrayArg(verb, opt, args, &argi, argc)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
} else if opt == "-x" {
|
||||
fieldNames = cli.VerbGetStringArrayArgOrDie(verb, opt, args, &argi, argc)
|
||||
fieldNames, err = cli.VerbGetStringArrayArg(verb, opt, args, &argi, argc)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
invertFieldNames = true
|
||||
|
||||
} else if opt == "-c" {
|
||||
|
|
@ -211,30 +224,29 @@ func transformerUniqParseCLI(
|
|||
showNumDistinctOnly = true
|
||||
|
||||
} else if opt == "-o" {
|
||||
outputFieldName = cli.VerbGetStringArgOrDie(verb, opt, args, &argi, argc)
|
||||
outputFieldName, err = cli.VerbGetStringArg(verb, opt, args, &argi, argc)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
} else if opt == "-a" {
|
||||
uniqifyEntireRecords = true
|
||||
|
||||
} else {
|
||||
transformerUniqUsage(os.Stderr)
|
||||
os.Exit(1)
|
||||
return nil, cli.VerbErrorf(verb, "option \"%s\" not recognized", opt)
|
||||
}
|
||||
}
|
||||
|
||||
if uniqifyEntireRecords {
|
||||
if fieldNames != nil {
|
||||
transformerUniqUsage(os.Stderr)
|
||||
os.Exit(1)
|
||||
return nil, cli.VerbErrorf(verb, "-a (uniqify entire records) is incompatible with -g/-x")
|
||||
}
|
||||
if showCounts && showNumDistinctOnly {
|
||||
transformerUniqUsage(os.Stderr)
|
||||
os.Exit(1)
|
||||
return nil, cli.VerbErrorf(verb, "-c and -n are mutually exclusive with -a")
|
||||
}
|
||||
} else {
|
||||
if fieldNames == nil {
|
||||
transformerUniqUsage(os.Stderr)
|
||||
os.Exit(1)
|
||||
return nil, cli.VerbErrorf(verb, "-g or -x field names required")
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -242,7 +254,7 @@ func transformerUniqParseCLI(
|
|||
|
||||
*pargi = argi
|
||||
if !doConstruct { // All transformers must do this for main command-line parsing
|
||||
return nil
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
transformer, _ := NewTransformerUniq(
|
||||
|
|
@ -255,7 +267,7 @@ func transformerUniqParseCLI(
|
|||
uniqifyEntireRecords,
|
||||
)
|
||||
|
||||
return transformer
|
||||
return transformer, nil
|
||||
}
|
||||
|
||||
type TransformerUniq struct {
|
||||
|
|
|
|||
|
|
@ -37,7 +37,7 @@ func transformerUnspaceParseCLI(
|
|||
args []string,
|
||||
_ *cli.TOptions,
|
||||
doConstruct bool, // false for first pass of CLI-parse, true for second pass
|
||||
) RecordTransformer {
|
||||
) (RecordTransformer, error) {
|
||||
|
||||
// Skip the verb name from the current spot in the mlr command line
|
||||
argi := *pargi
|
||||
|
|
@ -47,6 +47,7 @@ func transformerUnspaceParseCLI(
|
|||
filler := "_"
|
||||
which := "keys_and_values"
|
||||
|
||||
var err error
|
||||
for argi < argc /* variable increment: 1 or 2 depending on flag */ {
|
||||
opt := args[argi]
|
||||
if !strings.HasPrefix(opt, "-") {
|
||||
|
|
@ -59,10 +60,13 @@ func transformerUnspaceParseCLI(
|
|||
|
||||
if opt == "-h" || opt == "--help" {
|
||||
transformerUnspaceUsage(os.Stdout)
|
||||
os.Exit(0)
|
||||
return nil, cli.ErrHelpRequested
|
||||
|
||||
} else if opt == "-f" {
|
||||
filler = cli.VerbGetStringArgOrDie(verb, opt, args, &argi, argc)
|
||||
filler, err = cli.VerbGetStringArg(verb, opt, args, &argi, argc)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
} else if opt == "-k" {
|
||||
which = "keys_only"
|
||||
|
|
@ -71,23 +75,21 @@ func transformerUnspaceParseCLI(
|
|||
which = "values_only"
|
||||
|
||||
} else {
|
||||
transformerUnspaceUsage(os.Stderr)
|
||||
os.Exit(1)
|
||||
return nil, cli.VerbErrorf(verb, "option \"%s\" not recognized", opt)
|
||||
}
|
||||
}
|
||||
|
||||
*pargi = argi
|
||||
if !doConstruct { // All transformers must do this for main command-line parsing
|
||||
return nil
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
transformer, err := NewTransformerUnspace(filler, which)
|
||||
if err != nil {
|
||||
fmt.Fprintf(os.Stderr, "mlr: %v\n", err)
|
||||
os.Exit(1)
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return transformer
|
||||
return transformer, nil
|
||||
}
|
||||
|
||||
type TransformerUnspace struct {
|
||||
|
|
|
|||
|
|
@ -50,7 +50,7 @@ func transformerUnsparsifyParseCLI(
|
|||
args []string,
|
||||
_ *cli.TOptions,
|
||||
doConstruct bool, // false for first pass of CLI-parse, true for second pass
|
||||
) RecordTransformer {
|
||||
) (RecordTransformer, error) {
|
||||
|
||||
// Skip the verb name from the current spot in the mlr command line
|
||||
argi := *pargi
|
||||
|
|
@ -60,6 +60,7 @@ func transformerUnsparsifyParseCLI(
|
|||
fillerString := ""
|
||||
var specifiedFieldNames []string = nil
|
||||
|
||||
var err error
|
||||
for argi < argc /* variable increment: 1 or 2 depending on flag */ {
|
||||
opt := args[argi]
|
||||
if !strings.HasPrefix(opt, "-") {
|
||||
|
|
@ -72,23 +73,28 @@ func transformerUnsparsifyParseCLI(
|
|||
|
||||
if opt == "-h" || opt == "--help" {
|
||||
transformerUnsparsifyUsage(os.Stdout)
|
||||
os.Exit(0)
|
||||
return nil, cli.ErrHelpRequested
|
||||
|
||||
} else if opt == "--fill-with" {
|
||||
fillerString = cli.VerbGetStringArgOrDie(verb, opt, args, &argi, argc)
|
||||
fillerString, err = cli.VerbGetStringArg(verb, opt, args, &argi, argc)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
} else if opt == "-f" {
|
||||
specifiedFieldNames = cli.VerbGetStringArrayArgOrDie(verb, opt, args, &argi, argc)
|
||||
specifiedFieldNames, err = cli.VerbGetStringArrayArg(verb, opt, args, &argi, argc)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
} else {
|
||||
transformerUnsparsifyUsage(os.Stderr)
|
||||
os.Exit(1)
|
||||
return nil, cli.VerbErrorf(verb, "option \"%s\" not recognized", opt)
|
||||
}
|
||||
}
|
||||
|
||||
*pargi = argi
|
||||
if !doConstruct { // All transformers must do this for main command-line parsing
|
||||
return nil
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
transformer, err := NewTransformerUnsparsify(
|
||||
|
|
@ -96,11 +102,10 @@ func transformerUnsparsifyParseCLI(
|
|||
specifiedFieldNames,
|
||||
)
|
||||
if err != nil {
|
||||
fmt.Fprintf(os.Stderr, "mlr: %v\n", err)
|
||||
os.Exit(1)
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return transformer
|
||||
return transformer, nil
|
||||
}
|
||||
|
||||
type TransformerUnsparsify struct {
|
||||
|
|
|
|||
|
|
@ -36,7 +36,7 @@ func transformerUTF8ToLatin1ParseCLI(
|
|||
args []string,
|
||||
_ *cli.TOptions,
|
||||
doConstruct bool, // false for first pass of CLI-parse, true for second pass
|
||||
) RecordTransformer {
|
||||
) (RecordTransformer, error) {
|
||||
|
||||
// Skip the verb name from the current spot in the mlr command line
|
||||
argi := *pargi
|
||||
|
|
@ -54,25 +54,23 @@ func transformerUTF8ToLatin1ParseCLI(
|
|||
|
||||
if opt == "-h" || opt == "--help" {
|
||||
transformerUTF8ToLatin1Usage(os.Stdout)
|
||||
os.Exit(0)
|
||||
return nil, cli.ErrHelpRequested
|
||||
|
||||
}
|
||||
transformerUTF8ToLatin1Usage(os.Stderr)
|
||||
os.Exit(1)
|
||||
return nil, cli.VerbErrorf(verbNameUTF8ToLatin1, "option \"%s\" not recognized", opt)
|
||||
}
|
||||
|
||||
*pargi = argi
|
||||
if !doConstruct { // All transformers must do this for main command-line parsing
|
||||
return nil
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
transformer, err := NewTransformerUTF8ToLatin1()
|
||||
if err != nil {
|
||||
fmt.Fprintf(os.Stderr, "mlr: %v\n", err)
|
||||
os.Exit(1)
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return transformer
|
||||
return transformer, nil
|
||||
}
|
||||
|
||||
type TransformerUTF8ToLatin1 struct {
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue