cli

package
v6.13.0 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Oct 5, 2024 License: BSD-2-Clause Imports: 13 Imported by: 0

README

Datatypes for parsing the Miller command line, and the flags table.

  • pkg/climain is the flag-parsing logic for supporting Miller's command-line interface. When you type something like mlr --icsv --ojson put '$sum = $a + $b' then filter '$sum > 1000' myfile.csv, it's the CLI parser which makes it possible for Miller to construct a CSV record-reader, a transformer chain of put then filter, and a JSON record-writer.
  • pkg/cli contains datatypes and the flags table for the CLI-parser, which was split out to avoid a Go package-import cycle.

Documentation

Overview

Package cli contains the flags table and associated datatypes for parsing the Miller command line.

Index

Constants

View Source
const ASCII_ESC = "\\x1b"
View Source
const ASCII_ETX = "\\x03"
View Source
const ASCII_FS = "\\x1c"
View Source
const ASCII_GS = "\\x1d"
View Source
const ASCII_NULL = "\\x00"
View Source
const ASCII_RS = "\\x1e"
View Source
const ASCII_SOH = "\\x01"
View Source
const ASCII_STX = "\\x02"
View Source
const ASCII_US = "\\x1f"
View Source
const ASV_FS = "\\x1f"
View Source
const ASV_FS_FOR_HELP = "\\x1f"
View Source
const ASV_RS = "\\x1e"
View Source
const ASV_RS_FOR_HELP = "\\x1e"
View Source
const COLON = ":"
View Source
const COMMA = ","
View Source
const CR = "\\r"
View Source
const CRCR = "\\r\\r"
View Source
const CRLF = "\\r\\n"
View Source
const CRLFCRLF = "\\r\\n\\r\\n"
View Source
const DEFAULT_COMMENT_STRING = "#"
View Source
const DEFAULT_GEN_FIELD_NAME = "i"
View Source
const DEFAULT_GEN_START_AS_STRING = "1"
View Source
const DEFAULT_GEN_STEP_AS_STRING = "1"
View Source
const DEFAULT_GEN_STOP_AS_STRING = "100"
View Source
const DEFAULT_JSON_FLATTEN_SEPARATOR = "."
View Source
const DEFAULT_RECORDS_PER_BATCH = 500
View Source
const EQUALS = "="
View Source
const LF = "\\n"
View Source
const LFLF = "\\n\\n"
View Source
const NEWLINE = "\\n"
View Source
const PIPE = "|"
View Source
const SEMICOLON = ";"
View Source
const SLASH = "/"
View Source
const SPACE = " "
View Source
const SPACES_REGEX = "( )+"
View Source
const TAB = "\\t"
View Source
const TABS_REGEX = "(\\t)+"
View Source
const USV_FS = "\\xe2\\x90\\x9f"
View Source
const USV_FS_FOR_HELP = "U+241F (UTF-8 \\xe2\\x90\\x9f)"
View Source
const USV_RS = "\\xe2\\x90\\x9e"
View Source
const USV_RS_FOR_HELP = "U+241E (UTF-8 \\xe2\\x90\\x9e)"
View Source
const WHITESPACE_REGEX = "([ \\t])+"

Variables

View Source
var CSVTSVOnlyFlagSection = FlagSection{
	// contains filtered or unexported fields
}
View Source
var CommentsInDataFlagSection = FlagSection{
	// contains filtered or unexported fields
}
View Source
var CompressedDataFlagSection = FlagSection{
	// contains filtered or unexported fields
}
View Source
var FLAG_TABLE = FlagTable{
	// contains filtered or unexported fields
}

================================================================

View Source
var FileFormatFlagSection = FlagSection{
	// contains filtered or unexported fields
}
View Source
var FlattenUnflattenFlagSection = FlagSection{
	// contains filtered or unexported fields
}
View Source
var FormatConversionKeystrokeSaverFlagSection = FlagSection{
	// contains filtered or unexported fields
}
View Source
var JSONOnlyFlagSection = FlagSection{
	// contains filtered or unexported fields
}
View Source
var LegacyFlagSection = FlagSection{
	// contains filtered or unexported fields
}
View Source
var MiscFlagSection = FlagSection{
	// contains filtered or unexported fields
}
View Source
var OutputColorizationFlagSection = FlagSection{
	// contains filtered or unexported fields
}
View Source
var PPRINTOnlyFlagSection = FlagSection{
	// contains filtered or unexported fields
}
View Source
var ProfilingFlagSection = FlagSection{
	// contains filtered or unexported fields
}
View Source
var SEPARATOR_NAMES_TO_VALUES = map[string]string{
	"ascii_esc":  ASCII_ESC,
	"ascii_etx":  ASCII_ETX,
	"ascii_fs":   ASCII_FS,
	"ascii_gs":   ASCII_GS,
	"ascii_null": ASCII_NULL,
	"ascii_rs":   ASCII_RS,
	"ascii_soh":  ASCII_SOH,
	"ascii_stx":  ASCII_STX,
	"ascii_us":   ASCII_US,
	"asv_fs":     ASV_FS,
	"asv_rs":     ASV_RS,
	"colon":      COLON,
	"comma":      COMMA,
	"cr":         CR,
	"crcr":       CRCR,
	"crlf":       CRLF,
	"crlfcrlf":   CRLFCRLF,
	"equals":     EQUALS,
	"lf":         LF,
	"lflf":       LFLF,
	"newline":    NEWLINE,
	"pipe":       PIPE,
	"semicolon":  SEMICOLON,
	"slash":      SLASH,
	"space":      SPACE,
	"tab":        TAB,
	"usv_fs":     USV_FS,
	"usv_rs":     USV_RS,
}
View Source
var SEPARATOR_REGEX_NAMES_TO_VALUES = map[string]string{
	"spaces":     SPACES_REGEX,
	"tabs":       TABS_REGEX,
	"whitespace": WHITESPACE_REGEX,
}
View Source
var SeparatorFlagSection = FlagSection{
	// contains filtered or unexported fields
}

Functions

func CSVTSVOnlyPrintInfo

func CSVTSVOnlyPrintInfo()

func CheckArgCount

func CheckArgCount(args []string, argi int, argc int, n int)

CheckArgCount is for flags with values, e.g. ["-n" "10"], while we're looking at the "-n": this let us see if the "10" slot exists.

func CommentsInDataPrintInfo

func CommentsInDataPrintInfo()

func CompressedDataPrintInfo

func CompressedDataPrintInfo()

func DecideFinalFlatten

func DecideFinalFlatten(writerOptions *TWriterOptions) bool

func DecideFinalUnflatten

func DecideFinalUnflatten(
	options *TOptions,
	verbSequences [][]string,
) bool

func FileFormatPrintInfo

func FileFormatPrintInfo()

func FinalizeReaderOptions

func FinalizeReaderOptions(readerOptions *TReaderOptions) error

FinalizeReaderOptions does a few things.

  • If a file format was specified but one or more separators were not, a default specific to that file format is applied.
  • Computing regexes for IPS and IFS, and unbackslashing IRS. This is because the '\n' at the command line which is Go "\\n" (a backslash and an n) needs to become the single newline character, and likewise for "\t", etc.
  • IFS/IPS can have escapes like "\x1f" which aren't valid regex literals so we unhex them. For example, from "\x1f" -- the four bytes '\', 'x', '1', 'f' -- to the single byte with hex code 0x1f.

func FinalizeWriterOptions

func FinalizeWriterOptions(writerOptions *TWriterOptions) error

FinalizeWriterOptions unbackslashes OPS, OFS, and ORS. This is because because the '\n' at the command line which is Go "\\n" (a backslash and an n) needs to become the single newline character., and likewise for "\t", etc.

func FlattenUnflattenPrintInfo

func FlattenUnflattenPrintInfo()

func FormatConversionKeystrokeSaverPrintInfo

func FormatConversionKeystrokeSaverPrintInfo()

func JSONOnlyPrintInfo

func JSONOnlyPrintInfo()

func LegacyFlagInfoPrint

func LegacyFlagInfoPrint()

func ListSeparatorAliasesForOnlineHelp

func ListSeparatorAliasesForOnlineHelp()

func ListSeparatorRegexAliasesForOnlineHelp

func ListSeparatorRegexAliasesForOnlineHelp()

func MiscPrintInfo

func MiscPrintInfo()

func NoOpParse1

func NoOpParse1(args []string, argc int, pargi *int, options *TOptions)

NoOpParse1 is a helper function for flags which take no argument and are backward-compatibility no-ops.

func OutputColorizationPrintInfo

func OutputColorizationPrintInfo()

func PPRINTOnlyPrintInfo

func PPRINTOnlyPrintInfo()

func ProfilingPrintInfo

func ProfilingPrintInfo()

func SeparatorFromArg

func SeparatorFromArg(name string) string

SeparatorFromArg is for letting people do things like `--ifs pipe` rather than `--ifs '|'`.

func SeparatorPrintInfo

func SeparatorPrintInfo()

func SeparatorRegexFromArg

func SeparatorRegexFromArg(name string) string

SeparatorRegexFromArg is for letting people do things like `--ifs-regex whitespace` rather than `--ifs '([ \t])+'`.

func VerbCheckArgCount

func VerbCheckArgCount(verb string, opt string, args []string, argi int, argc int, n int)

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 VerbGetFloatArgOrDie

func VerbGetFloatArgOrDie(verb string, opt string, args []string, pargi *int, argc int) float64

E.g. with ["-n", "10.3"], makes sure there is something in the "10.3" position, scans it as float, and returns it.

func VerbGetIntArgOrDie

func VerbGetIntArgOrDie(verb string, opt string, args []string, pargi *int, argc int) int64

E.g. with ["-n", "10"], makes sure there is something in the "10" position, scans it as int, and returns it.

func VerbGetStringArgOrDie

func VerbGetStringArgOrDie(verb string, opt string, args []string, pargi *int, argc int) string

E.g. with ["-f", "a,b,c"], makes sure there is something in the "a,b,c" position, and returns it.

func VerbGetStringArrayArgOrDie

func VerbGetStringArrayArgOrDie(verb string, opt string, args []string, pargi *int, argc int) []string

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.

Types

type Flag

type Flag struct {
	// contains filtered or unexported fields
}

Flag is a container for all runtime as well as documentation information for a flag.

func (*Flag) GetHeadline

func (flag *Flag) GetHeadline() string

GetHeadline puts together the flag name, any altNames, and any argument spec into a single string for the left column of online help / manpage content. Given flag named `--foo`, altName `-f`, and argument spec `{bar}`, the headline is `--foo or -f {bar}`. This is the bit which is highlighted in on-line help; its length is also used for alignment decisions in the on-line help and the manapge.

func (*Flag) GetHelpOneLine

func (flag *Flag) GetHelpOneLine() string

Gets the help string all on one line (just in case anyone typed it in using multiline string-literal backtick notation in Go). This is suitable for webdoc use where we create all one line, and the browser dynamically line-wraps as the user resizes the window.

func (*Flag) Matches

func (flag *Flag) Matches(input string) bool

Matches is like Owns but is for substring matching, for on-line help with approximate match on flag name.

func (*Flag) NilCheck

func (flag *Flag) NilCheck()

See comments above FlagTable's NilCheck method.

func (*Flag) Owns

func (flag *Flag) Owns(input string) bool

Owns determines whether this object handles a command-line flag such as "--foo". This is used for command-line parsing, as well as for on-line help with exact match on flag name.

func (*Flag) ShowHelp

func (flag *Flag) ShowHelp()

type FlagParser

type FlagParser func(
	args []string,
	argc int,
	pargi *int,
	options *TOptions,
)

FlagParser is a function which takes a flag such as `--foo`.

  • It should assume that a flag.Owns method has already been invoked to be sure that this function is indeed the right one to call for `--foo`.
  • The FlagParser function is responsible for advancing *pargi by 1 (if `--foo`) or 2 (if `--foo bar`), checking to see if argc is long enough in the latter case, and mutating the options struct.
  • Successful handling of the flag is indicated by this function making a non-zero increment of *pargi.

type FlagSection

type FlagSection struct {
	// contains filtered or unexported fields
}

FlagSection holds all the flags in a given cateogory, where these categories exist for documentation purposes.

The name should be right-cased for webdocs. For on-line help and manpage use, it will get fully uppercased.

The infoPrinter provides summary/overview for all flags in the section, for on-line help / webdocs.

func (*FlagSection) GetDowndashSectionName

func (fs *FlagSection) GetDowndashSectionName() string

Map "CSV-only flags" to "csv-only-flags" etc. for the benefit of per-section help in `mlr help topics`.

func (*FlagSection) ListFlags

func (fs *FlagSection) ListFlags()

ListFlags exposes some of the flags-table structure, so Ruby autogen scripts for on-line help and webdocs can traverse the structure with looping inside their own code.

func (*FlagSection) NilCheck

func (fs *FlagSection) NilCheck()

See comments above FlagTable's NilCheck method.

func (*FlagSection) PrintInfo

func (fs *FlagSection) PrintInfo()

PrintInfo exposes some of the flags-table structure, so Ruby autogen scripts for on-line help and webdocs can traverse the structure with looping inside their own code.

func (*FlagSection) ShowHelpForFlags

func (fs *FlagSection) ShowHelpForFlags()

ShowHelpForFlags prints all-in-one on-line help, nominally for `mlr help flags`.

func (*FlagSection) Sort

func (fs *FlagSection) Sort()

Sort organizes the flags in the section alphabetically, to make on-line help easier to read. This is done from func-init context so on-line help will always be easy to navigate.

type FlagTable

type FlagTable struct {
	// contains filtered or unexported fields
}

FlagTable holds all the flags for Miller, organized into sections.

func (*FlagTable) GetDowndashSectionNames

func (ft *FlagTable) GetDowndashSectionNames() []string

Map "CSV-only flags" to "csv-only-flags" etc. for the benefit of per-section help in `mlr help topics`.

func (*FlagTable) ListFlagSections

func (ft *FlagTable) ListFlagSections()

ListFlagSections exposes some of the flags-table structure, so Ruby autogen scripts for on-line help and webdocs can traverse the structure with looping inside their own code.

func (*FlagTable) ListFlagsForSection

func (ft *FlagTable) ListFlagsForSection(sectionName string) bool

ListFlagsForSection exposes some of the flags-table structure, so Ruby autogen scripts for on-line help and webdocs can traverse the structure with looping inside their own code.

func (*FlagTable) NilCheck

func (ft *FlagTable) NilCheck()

NilCheck checks to see if any flag/section is missing help info. This arises since in Go you needn't specify all struct initializers, so for example a Flag struct-initializer which doesn't say `help: "..."` will have empty help string. This nil-checking doesn't need to be done on every Miller invocation, but rather, only at build time. The `mlr help` terminal has an entrypoint wherein a regression-test case can do `mlr help nil-check` and make this function exits cleanly.

func (*FlagTable) Parse

func (ft *FlagTable) Parse(
	args []string,
	argc int,
	pargi *int,
	options *TOptions,
) bool

Parse is for parsing a flag on the command line. Given say `--foo`, if a Flag object is found which owns the flag, and if its parser accepts it (e.g. `bar` is present and spelt correctly if the flag-parser expects `--foo bar`) then the return value is true, else false.

func (*FlagTable) PrintInfoForSection

func (ft *FlagTable) PrintInfoForSection(sectionName string) bool

PrintInfoForSection exposes some of the flags-table structure, so Ruby autogen scripts for on-line help and webdocs can traverse the structure with looping inside their own code.

func (*FlagTable) ShowHeadlineForFlag

func (ft *FlagTable) ShowHeadlineForFlag(flagName string) bool

Given flag named `--foo`, altName `-f`, and argument spec `{bar}`, the headline is `--foo or -f {bar}`. This is the bit which is highlighted in on-line help; its length is also used for alignment decisions in the on-line help and the manapge.

func (*FlagTable) ShowHelp

func (ft *FlagTable) ShowHelp()

ShowHelp prints all-in-one on-line help, nominally for `mlr help flags`.

func (*FlagTable) ShowHelpForFlag

func (ft *FlagTable) ShowHelpForFlag(flagName string) bool

ShowHelpForFlag prints the flag's help-string all on one line. This is for webdoc usage where the browser does dynamic line-wrapping, as the user resizes the browser window.

func (*FlagTable) ShowHelpForFlagApproximateWithName

func (ft *FlagTable) ShowHelpForFlagApproximateWithName(searchString string) bool

ShowHelpForFlagApproximateWithName is like ShowHelpForFlagWithName but allows substring matches. This is for on-line help usage.

func (*FlagTable) ShowHelpForFlagWithName

func (ft *FlagTable) ShowHelpForFlagWithName(flagName string) bool

ShowHelpForFlagWithName prints the flag's name colorized, then flag's help-string all on one line. This is for on-line help usage.

func (*FlagTable) ShowHelpForSection

func (ft *FlagTable) ShowHelpForSection(sectionName string) bool

PrintInfoForSection exposes some of the flags-table structure, so Ruby autogen scripts for on-line help and webdocs can traverse the structure with looping inside their own code.

func (*FlagTable) ShowHelpForSectionViaDowndash

func (ft *FlagTable) ShowHelpForSectionViaDowndash(downdashSectionName string) bool

Sections are named like "CSV-only flags". `mlr help` uses `mlr help csv-only-flags`. The latter is downcased from the former, with spaces replaced by dashes -- hence "downdashed section name". Here we look up flag-section help given a downdashed section name.

func (*FlagTable) Sort

func (ft *FlagTable) Sort()

Sort organizes the sections in the table alphabetically, to make on-line help easier to read. This is done from func-init context so on-line help will always be easy to navigate.

type TCommentHandling

type TCommentHandling int
const (
	CommentsAreData TCommentHandling = iota
	SkipComments
	PassComments
)

type TGeneratorOptions

type TGeneratorOptions struct {
	FieldName     string
	StartAsString string
	StepAsString  string
	StopAsString  string
}

type TOptions

type TOptions struct {
	ReaderOptions TReaderOptions
	WriterOptions TWriterOptions

	// Data files to be operated on: e.g. given 'mlr cat foo.dat bar.dat', this
	// is ["foo.dat", "bar.dat"].
	FileNames []string

	// DSL files to be loaded for every put/filter operation -- like 'put -f'
	// or 'filter -f' but specified up front on the command line, suitable for
	// .mlrrc. Use-case is someone has DSL functions they always want to be
	// defined.
	//
	// Risk of CVE if this is in .mlrrc so --load and --mload are explicitly
	// denied in the .mlrrc reader.
	DSLPreloadFileNames []string

	NRProgressMod int64
	DoInPlace     bool // mlr -I
	NoInput       bool // mlr -n

	HaveRandSeed bool
	RandSeed     int64

	PrintElapsedTime bool // mlr --time
}

----------------------------------------------------------------

func DefaultOptions

func DefaultOptions() *TOptions

Not usable until FinalizeReaderOptions and FinalizeWriterOptions are called.

type TReaderOptions

type TReaderOptions struct {
	InputFileFormat  string
	IFS              string
	IPS              string
	IRS              string
	AllowRepeatIFS   bool
	IFSRegex         *regexp.Regexp
	IPSRegex         *regexp.Regexp
	DedupeFieldNames bool

	UseImplicitHeader   bool
	AllowRaggedCSVInput bool
	CSVLazyQuotes       bool
	CSVTrimLeadingSpace bool
	BarredPprintInput   bool

	CommentHandling TCommentHandling
	CommentString   string

	// Fake internal-data-generator 'reader'
	GeneratorOptions TGeneratorOptions

	// For out-of-process handling of compressed data, via popen
	Prepipe string
	// For most things like gunzip we do 'gunzip < filename | mlr ...' if
	// filename is present, else 'gunzip | mlr ...' if reading from stdin.
	// However some commands like 'unzip -qc' are weird so this option lets
	// people give the command and we won't insert the '<'.
	PrepipeIsRaw bool
	// For in-process gunzip/bunzip2/zcat (distinct from prepipe)
	FileInputEncoding lib.TFileInputEncoding

	// TODO: comment
	RecordsPerBatch int64
	// contains filtered or unexported fields
}

func DefaultReaderOptions

func DefaultReaderOptions() TReaderOptions

Not usable until FinalizeReaderOptions is called on it.

type TWriterOptions

type TWriterOptions struct {
	OutputFileFormat string
	ORS              string
	OFS              string
	OPS              string
	FLATSEP          string

	FlushOnEveryRecord bool

	HeaderlessOutput         bool
	BarredPprintOutput       bool
	RightAlignedPPRINTOutput bool
	RightAlignedXTABOutput   bool

	// JSON output: --jlistwrap on, --jvstack on
	// JSON Lines output: --jlistwrap off, --jvstack off
	WrapJSONOutputInOuterList bool // --jlistwrap
	JSONOutputMultiline       bool // --jvstack
	JVQuoteAll                bool // --jvquoteall

	CSVQuoteAll bool // --quote-all

	// When we read things like
	//
	//   x:a=1,x:b=2
	//
	// which is how we write out nested data structures for non-nested formats
	// (all but JSON), the default behavior is to unflatten them back to
	//
	//   {"x": {"a": 1}, {"b": 2}}
	//
	// unless the user explicitly asks to suppress that.
	AutoUnflatten bool

	// The default behavior is to flatten nested data structures like
	//
	//   {"x": {"a": 1}, {"b": 2}}
	//
	// down to
	//
	//   x:a=1,x:b=2
	//
	// which is how we write out nested data structures for non-nested formats
	// (all but JSON) -- unless the user explicitly asks to suppress that.
	AutoFlatten bool

	// Default CSV/TSV:
	//   a=1,b=2,c=3
	//   a=4,b=5
	// leads to
	//   a,b,c
	//   1 2,3
	//   4,5, <-- note trailing empty field
	// and
	//   a=1,b=2,c=3
	//   d=4,e=5
	// leads to
	//   fatal error
	//
	// With this flag:
	//   a=1,b=2,c=3
	//   a=4,b=5
	// leads to
	//   a,b,c
	//   1 2,3
	//
	//   a,b
	//   4,5
	//
	// and
	//   a=1,b=2,c=3
	//   d=4,e=5
	// leads to
	//   a,b,c
	//   1,2,3
	//
	//   d,e
	//   4,5
	NoAutoUnsparsify bool

	// For floating-point numbers: "" means use the Go default.
	FPOFMT string

	// Fatal the process when error data in a given record is about to be output.
	FailOnDataError bool
	// contains filtered or unexported fields
}

----------------------------------------------------------------

func DefaultWriterOptions

func DefaultWriterOptions() TWriterOptions

Not usable until FinalizeWriterOptions is called on it.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL