Documentation
¶
Overview ¶
Package mains contains functions for implementing a command-line utility or a service.
Index ¶
- Constants
- func BaseOptionData(program string, yaml ...YamlOption) (optionData []pflags.OptionData)
- func MinimalRecovery(errp *error)
- type ArgumentSpec
- type BaseOptionsType
- type Executable
- func (x *Executable) AddError(err error)
- func (x *Executable) ConfigureLog() (ex1 *Executable)
- func (x *Executable) EarlyPanic(errp ...*error)
- func (x *Executable) EndErrors()
- func (x *Executable) Init() (ex2 *Executable)
- func (x *Executable) LongErrors(isLongErrors bool, isErrorLocation bool) *Executable
- func (x *Executable) PrintBannerAndParseOptions(optionsList []pflags.OptionData) (ex1 *Executable)
- func (x *Executable) Recover(errp ...*error)
- func (x *Executable) SetStatusCode(statusCode *int)
- type Keystrokes
- type SilentType
- type YamlOption
Constants ¶
const ( // as second argument to [BaseOptionData], indicates that yaml options -yamlFile -yamlKey should not be present YamlNo YamlOption = false // indicates silent: no banner. Must be first option on command-line ‘-silent’ SilentString = "-" + silentOption // name of version option Version = "version" )
const ( // if [Executable.OKtext] is assigned NoOK there ir no successful message on app exit NoOK = "-" // displays error location for errors printed without stack trace // - second argument to [Executable.LongErrors] OutputErrorLocationTrue = true // error location is not appended to errors printed without stack trace // - second argument to [Executable.LongErrors] NoErrorLocationTrue = false // always output error stack traces // - first argument to [Executable.LongErrors] AlwaysStackTrace = true // stack traces are not output for errors // - stack traces are printed for panic // - first argument to [Executable.LongErrors] NoStackTrace = false )
const ( // NoArguments besides switches, zero trailing arguments is allowed NoArguments = 1 << iota // OneArgument besides switches, exactly one trailing arguments is allowed OneArgument // ManyArguments besides switches, one or more trailing arguments is allowed ManyArguments )
Variables ¶
This section is empty.
Functions ¶
func BaseOptionData ¶
func BaseOptionData(program string, yaml ...YamlOption) (optionData []pflags.OptionData)
BaseOptionData returns basic options for mains
- program: used to generate help text
- yaml: YamlNo means no yaml options
- -verbose -debug -silent -version
- if yaml == YamlYes: -yamlFile -yamlKey
func MinimalRecovery ¶ added in v0.4.130
func MinimalRecovery(errp *error)
MinimalRecovery handles error process exit for the main function
- purpose is to avoid a silent zero status-code exit on error and to print exactly when the process exited
- panics are not recovered
- on success: *errp == nil:
- – a timestamped success message is printed to stderr
- — the function returns
- on error: *errp != nil:
- — if error is caused by panic, error is printed with stack trace
- — other errors are printed as a one-liner with code-location
- — os.Exit is invoked with status code 1
Usage:
main() { var err error defer mains.MinimalRecovery(&err)
Types ¶
type ArgumentSpec ¶
type ArgumentSpec uint32
ArgumentSpec bitfield for 0, 1, many arguments following command-line switches
type BaseOptionsType ¶
type BaseOptionsType = struct {
YamlFile, YamlKey, Verbosity string
Debug, Silent, Version, DoYaml bool
}
BaseOptionsType is the type that holds mains’ effective option values
- -yamlFile -yamlKey -verbose -debug -silent -version -no-yaml
var BaseOptions BaseOptionsType
BaseOptions is the value that holds mains’ effective option values
- -yamlFile -yamlKey -verbose -debug -silent -version -no-yaml
type Executable ¶
type Executable struct { Program string // “gonet” Version string // “0.0.1” Comment string // [ banner text after program and version] “options parsing” changes in last version Description string // [Description part of usage] “configures firewall and routing” Copyright string // “© 2020…” License string // “ISC License” OKtext string // “Completed successfully” ArgumentsUsage string // usage help text for arguments after options Arguments ArgumentSpec // eg. mains.NoArguments Launch time.Time // process start time LaunchString string // Launch as printable rfc 3339 time string Host string // short hostname, ie. no dots “mymac” ArgCount int // number of post-options strings during parse Arg string // if one post-options string and that is allowed, this is the string Args []string // any post-options strings if allowed // errors are printed with stack traces, associated values and errors // - panics are always printed long // - if errors long or more than 1 error, the first error is repeated last as a one-liner IsLongErrors bool // adds a code location to errors if not IsLongErrors IsErrorLocation bool // contains filtered or unexported fields }
Executable constant strings that describes an executable advisable static values include Program Version Comment Description Copyright License Arguments like:
var ex = mains.Executable{ Program: "getip", Version: "0.0.1", Comment: "first version", Description: "finds ip address for hostname", Copyright: "© 2020-present Harald Rudell <harald.rudell@gmail.com> (http://www.haraldrudell.com)", License: "All rights reserved", Arguments: mains.NoArguments | mains.OneArgument, }
func (*Executable) AddError ¶ added in v0.4.178
func (x *Executable) AddError(err error)
AddError extended with immediate printing of first error
- if err is the first error, it is immediately printed
- subsequent errors are appended to x.err
- err nil: ignored
func (*Executable) ConfigureLog ¶
func (x *Executable) ConfigureLog() (ex1 *Executable)
ConfigureLog configures the default log such as parl.Log parl.Out parl.D for silent, debug and regExp. Settings come from BaseOptions.Silent and BaseOptions.Debug.
ConfigureLog supports functional chaining like:
exe.Init(). … ConfigureLog(). ApplyYaml(…)
func (*Executable) EarlyPanic ¶ added in v0.4.173
func (x *Executable) EarlyPanic(errp ...*error)
EarlyPanic is a deferred function that recovers panic prior to all other deferred functions
- EarlyPanic ensures that a panic is displayed immediately and that the panic is stored as the first occurring error
- the first deferred function should be Executable.Recover
- the last deferred function should be Executable.EarlyPanic
- EarlyPanic avoids confusion from other deferred functions quietly hanging or storing a first error that is actually subsequent to the panic
func (*Executable) EndErrors ¶ added in v0.4.178
func (x *Executable) EndErrors()
a subt making Executable implement parl.ErrorSink
func (*Executable) Init ¶
func (x *Executable) Init() (ex2 *Executable)
Init initializes a created mains.Executable value
- the value should have relevant fields populates such as exeuctable name and more
- — Program Version Comment Copyright License Arguments
- populates launch time and sets silence if first os.Args argument is “-silent.”
- Init supports function chaining like:
typical code:
ex.Init(). PrintBannerAndParseOptions(optionData). LongErrors(options.Debug, options.Verbosity != ""). ConfigureLog() applyYaml(options.YamlFile, options.YamlKey, applyYaml, optionData) …
func (*Executable) LongErrors ¶
func (x *Executable) LongErrors(isLongErrors bool, isErrorLocation bool) *Executable
LongErrors sets if errors are printed with stack trace and values. LongErrors supports functional chaining:
exe.Init(). … LongErrors(options.Debug, options.Verbosity != ""). ConfigureLog()…
isLongErrors prints full stack traces, related errors and error data in string lists and string maps.
isErrorLocation appends the innermost location to the error message when isLongErrors is not set:
error-message at error116.(*csTypeName).FuncName-chainstring_test.go:26
func (*Executable) PrintBannerAndParseOptions ¶
func (x *Executable) PrintBannerAndParseOptions(optionsList []pflags.OptionData) (ex1 *Executable)
PrintBannerAndParseOptions prints greeting like:
parl 0.1.0 parlca https server/client udp server
It then parses options described by []OptionData stroing the values at OptionData.P. If options fail to parse, a proper message is printed to stderr and the process exits with status code 2. PrintBannerAndParseOptions supports functional chaining like:
exe.Init(). PrintBannerAndParseOptions(…). LongErrors(…
Options and yaml is configured likeso:
var options = &struct { noStdin bool *mains.BaseOptionsType }{BaseOptionsType: &mains.BaseOptions} var optionData = append(mains.BaseOptionData(exe.Program, mains.YamlYes), []mains.OptionData{ {P: &options.noStdin, Name: "no-stdin", Value: false, Usage: "Service: do not use standard input", Y: mains.NewYamlValue(&y, &y.NoStdin)}, }...) type YamlData struct { NoStdin bool // nostdin: true } var y YamlData
func (*Executable) Recover ¶
func (x *Executable) Recover(errp ...*error)
Recover terminates the process, typically invoked as the first deferred function in main.main
- errp: optional pointer that may point to a non-nil error
- Recover does not return, instead it invokes os.Exit
- Recover recovers any ongoing panic using recover()
- successful exit is:
- — no ongoing panic
- — no non-nil errors pointed to by errp
- — no errors previously stored by Executable.AddError or Executable.EarlyPanic
- — no non-zero status code previously stored by Executable.SetStatusCode
- on successful exit, a timestamped success message is printed followed by exit status zero:
- — “gtee completed successfully at 240524 17:26:50-07”
- on failure exit:
- — non-panic errors are printed as one-liners with code location
- — panics are printed with stack trace and error chain
- — the last printed line is a timestamped exit message:
- — “240524 21:32:08-07 gtee: exit status 1”
- — exit status code is any non-zero status code provided to Executable.SetStatusCode or 1
Usage:
func main() { var err error defer Recover(&err) …
func (*Executable) SetStatusCode ¶ added in v0.4.179
func (x *Executable) SetStatusCode(statusCode *int)
SetStatusCode allos to set the status code to use on exit
- deferrable, thread-safe
type Keystrokes ¶
type Keystrokes struct {
// contains filtered or unexported fields
}
Keystrokes reads line-wise from standard input
- os.File.Read from os.Stdin cannot be aborted because Stdin cannot be closed
- therefore, on process exit or Keystrokes.CloseNow, keystrokesThread thread is left blocked in Read
- —
- -verbose='mains...Keystrokes|mains.keystrokesThread' “github.com/haraldrudell/parl/mains.(*Keystrokes)”
- this object is released on process exit. Remaining items due to stdin cannot be closed are:
- the stdin unbound channel
- optional addError
- those items along with [KeyStrokesThread] and [StdinReader] are released on process exit or next keypress
func NewKeystrokes ¶ added in v0.4.130
func NewKeystrokes(fieldp ...*Keystrokes) (keystrokes *Keystrokes)
NewKeystrokes returns an object reading lines from standard input
- Keystrokes.Launch launches a thread reading from os.Stdin
- Keystrokes.StringSource provides a channel sending strings on each return key-press
- Keystrokes.CloseNow closes the channel discarding buffered characters
- Ch also closes on Stdin closing or thread runtime error
Usage:
var err error … var keystrokes = NewKeystrokes() defer keystrokes.Launch().CloseNow(&err) for line := range keystrokes.Ch() {
func (*Keystrokes) CloseNow ¶ added in v0.4.130
func (k *Keystrokes) CloseNow(errp *error)
CloseNow closes the string-sending channel discarding any pending characters
func (*Keystrokes) Launch ¶ added in v0.4.130
func (k *Keystrokes) Launch(errorSink parl.ErrorSink1, silent ...SilentType) (keystrokes *Keystrokes)
Launch starts reading stdin for keystrokes
- can only be invoked once per process or panic
- supports functional chaining
- silent SilentClose does not echo anything on os.Stdin closing
- addError if present receives errors from os.Stdin.Read
func (*Keystrokes) StringSource ¶ added in v0.4.180
func (k *Keystrokes) StringSource() (stringSource parl.ClosableSource1[string])
StringSource returns a possibly closing unbound slice sending lines from the keyboard on each return press
- closing-channel wait mechanic
- Ch sends strings with return character removed
- the channel closes upon:
- — Keystrokes.CloseNow or
- — os.Stdin closing or
- — thread runtime error
type SilentType ¶ added in v0.4.191
type SilentType bool
optional flag for no stdin-cose echo SilentClose
const ( // do not echo to standard error on [os.Stdin] closing // optional argument to [Keystrokes.Launch] SilentClose SilentType = true )