mains

package
v0.2.2 Latest Latest
Warning

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

Go to latest
Published: Mar 28, 2022 License: ISC Imports: 21 Imported by: 2

Documentation

Overview

Package mains contains functions for implementing a service or command-line utility

Index

Constants

View Source
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
)
View Source
const (
	SilentString = "-" + silentOption
)

Variables

This section is empty.

Functions

func Abs

func Abs(dir string) (out string)

Abs ensures a file system path is fully qualified. Abs is single-return-value and panics on troubles

func ExecDir

func ExecDir() (dir string)

ExecDir gets abolute path to directory where executable is located

func FindFile

func FindFile(filename0, program string) (out string, bytes []byte)

FindFile locates and read the yaml file

func GetStringSliceValue

func GetStringSliceValue(p *[]string, value []string) (v flag.Value)

GetStringSliceValue initializes

func GetTopLevelKey

func GetTopLevelKey(topKey string) (key string)

GetTopLevelKey gets the top level key to use

func Keystrokes

func Keystrokes(ctx ev.Callee)

Keystrokes emits keystroke events

func ParentDir

func ParentDir() (dir string)

ParentDir gets absolute path of executable parent directory

func Timer

func Timer(ctx ev.Callee)

Timer displays a second counter and help on long-running invocations

func UserHomeDir

func UserHomeDir() (dir string)

UserHomeDir gets file system path of user’s home directory

Types

type ArgumentSpec

type ArgumentSpec uint32

ArgumentSpec bitfield for 0, 1, many arguments following command-line switches

type BaseOptionsType

type BaseOptionsType = struct {
	YamlFile  string
	YamlKey   string
	Verbosity string
	Debug     bool
	Silent    bool
}
var BaseOptions BaseOptionsType

type Executable

type Executable struct {
	Program        string // gonet
	Version        string // 0.0.1
	Comment        string // [ banner text after program and version] options parsing (about this version)
	Description    string // [Description part of usage] configures firewall and routing
	Copyright      string // © 2020…
	License        string // ISC License
	ArgumentsUsage string
	Arguments      ArgumentSpec // eg. NoArguments
	// fields below popualted by .Init()
	Launch       time.Time
	LaunchString string
	Host         string // short hostname, ie. no dots

	ArgCount        int
	Arg             string
	Args            []string
	IsLongErrors    bool
	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 exe = 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) AddErr

func (ex *Executable) AddErr(err error) (x *Executable)

AddErr extended with immediate printing of first error

func (*Executable) ApplyYaml

func (ex *Executable) ApplyYaml(yamlFile, yamlKey string, thunk UnmarshalThunk, om []OptionData)

ApplyYaml adds options read from a yaml file.

File: The filename searched comes from Executable.Program or the yamlFile argument. If yamlFile is set exactly this file is read. If yamlFile is not set, A search is executed in the directories ~/apps .. and /etc. The filename searched is [program]-[hostname].yaml and [program].yaml.

Content: If the file does not eixst, no action is taken. If the file is empty, no action is taken.

The top entry in the yaml file is expected to be a dictionary of dictionaries. The key searched for in the top level dictionary is the yamlKey argument or “options” if not set.

thunk needs to in otuside of the library for typoing reasons and is implemented similar to the below. y is the variable receiving parsed yaml data. The om list is then svcaned for its Y pointers to copy yaml settings to options.

func applyYaml(bytes []byte, unmarshal mains.UnmarshalFunc, yamlDictionaryKey string) (hasData bool, err error) {
  yamlContentObject := map[string]*YamlData{} // need map[string] because yaml top level is dictionary
  if err = unmarshal(bytes, &yamlContentObject); err != nil {
    return
  }
  yamlDataPointer := yamlContentObject[yamlDictionaryKey] // pick out the options dictionary value
  if hasData = yamlDataPointer != nil; !hasData {
    return
  }
  y = *yamlDataPointer
  return
}

func (*Executable) ConfigureLog

func (ex *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) Exit

func (ex *Executable) Exit()

Exit terminate from mains.err: exit 0 or echo to stderr and status code 1

func (*Executable) Init

func (ex *Executable) Init() *Executable

Init populate launch time and sets silence if first argument is “-silent.” Init supports function chaining like:

exe.Init().
  PrintBannerAndParseOptions(optionData).
  LongErrors(options.Debug, options.Verbosity != "").
  ConfigureLog().
  ApplyYaml(options.YamlFile, options.YamlKey, applyYaml, optionData)
  …

func (*Executable) LongErrors

func (ex *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 (ex *Executable) PrintBannerAndParseOptions(om []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) PrintErr

func (ex *Executable) PrintErr(err error)

PrintErr prints an error

func (*Executable) Recover

func (ex *Executable) Recover()

Recover function to be used in main.main:

func main() {
  defer Recover()
  …

On panic, the function prints to stderr: "Unhandled panic invoked exe.Recover: stack:" followed by a stack trace. It then adds an error to mains.Executable and terminates the process with status code 1

type InputLine

type InputLine string

type OptionData

type OptionData struct {
	P     interface{}
	Name  string
	Value interface{}
	Usage string
	Y     *YamlValue // pointer to data value from yaml
}

OptionData contain options data for the flag package

func BaseOptionData

func BaseOptionData(program string, yaml YamlOption) (od []OptionData)

func (*OptionData) AddOption

func (om *OptionData) AddOption()

AddOption executes flag.BoolVar and such on the options map

func (*OptionData) ApplyYaml

func (om *OptionData) ApplyYaml() (err error)

type Status

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

Status handles printing of status to stdout

func GetStatus

func GetStatus() (stat *Status)

GetStatus gets instance of status printer

func (*Status) Clear

func (stat *Status) Clear()

Clear remove previously printed status

func (*Status) Print

func (stat *Status) Print(s string)

Print status information

type StringSliceValue

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

StringSliceValue manages a string-slice value for flag.Var

func (*StringSliceValue) Set

func (v *StringSliceValue) Set(s string) (err error)

Set updates the string slice

func (StringSliceValue) String

func (v StringSliceValue) String() (s string)

type UnmarshalFunc

type UnmarshalFunc func(in []byte, out interface{}) (err error) // yaml.Unmarshal

type UnmarshalThunk

type UnmarshalThunk func(bytes []byte, unmarshal UnmarshalFunc, yamlKey string) (hasDate bool, err error)

type YamlOption

type YamlOption bool
const (
	YamlNo  YamlOption = false
	YamlYes YamlOption = true
)

type YamlValue

type YamlValue struct {
	Name    string
	Pointer interface{}
}

func NewYamlValue

func NewYamlValue(instancePointer interface{}, fieldPointer interface{}) (yv *YamlValue)

Jump to

Keyboard shortcuts

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