File: verb_utils.go

package info (click to toggle)
miller 6.17.0-1
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid
  • size: 88,244 kB
  • sloc: ruby: 162; sh: 120; makefile: 87; python: 46
file content (83 lines) | stat: -rw-r--r-- 3,091 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
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"
	"strconv"

	"github.com/johnkerl/miller/v6/pkg/lib"
)

// 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 {
		return fmt.Errorf("%s %s: option \"%s\" missing argument(s)", "mlr", verb, opt)
	}
	return nil
}

// 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, nil
}

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

// 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, err := VerbGetStringArg(verb, opt, args, pargi, argc)
	if err != nil {
		return 0, err
	}
	retval, err := strconv.ParseInt(stringArg, 10, 64)
	if err != nil {
		return 0, fmt.Errorf("%s %s: could not scan flag \"%s\" argument \"%s\" as int",
			"mlr", verb, flag, stringArg)
	}
	return retval, nil
}

// 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, err := VerbGetStringArg(verb, opt, args, pargi, argc)
	if err != nil {
		return 0, err
	}
	retval, err := strconv.ParseFloat(stringArg, 64)
	if err != nil {
		return 0, fmt.Errorf("%s %s: could not scan flag \"%s\" argument \"%s\" as float",
			"mlr", verb, flag, stringArg)
	}
	return retval, nil
}