cmd

package
v0.9.1 Latest Latest
Warning

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

Go to latest
Published: Apr 30, 2019 License: ISC Imports: 28 Imported by: 0

README

config

It is deceptively small but this library provides a neat and concise syntax for declaration of a configuration data structure and application definition.

In the cmd/ folder is an example of a declaration of the struct and a function that binds a struct containing pointers to the values into the generated map of configuration values.

These are the various facilities that this design pattern provides:

  1. Declaration is short and neat and readable and self explanatory
  2. Produced data structure can be converted to json and decoded from a json configuration file which includes useful information for a human editor in the form of the constraints and usage text that apply from the declarattion
  3. Produced structure contains initialisers, getters and setters that validate all input.
  4. Declaration of a set of commands that are processed via a set intersection operation to find the most precedent that run with the configuration pre-parsed.

If it was needed the structure can have mutex locks for concurrent read/write by chaining unlock/lock into the initial validator and accessors, and chain onto a channel notifying of changes in the configuration that can alter runtime parameters, triggering a reinitialisation or so.

In its current form it makes specifying configuration just two functions that mostly explain themselves, and provide a human readable structured document matching the specification, to be written and read in a configuration file.

Initially it was to just be configuration but it made more sense to link it with the launchers. These also construct the same way so in theory later can be hot configured by adding a controller server.

Documentation

Index

Constants

This section is empty.

Variables

View Source
var Log = cl.NewSubSystem("cmd/config", ll.DEFAULT)

Log is the logger for node

View Source
var NetParams = map[string]*nine.Params{
	"mainnet":    &nine.MainNetParams,
	"testnet":    &nine.TestNet3Params,
	"simnet":     &nine.SimNetParams,
	"regtestnet": &nine.RegressionNetParams,
}
View Source
var Networks = []string{"mainnet", "testnet", "simnet", "regtestnet"}
View Source
var Valid = struct {
	File, Dir, Port, Bool, Int, Tag, Tags, Algo, Float, Duration, Net,
	Level func(*Row, interface{}) bool
}{
	File: func(r *Row, in interface{}) bool {
		var s *string
		switch I := in.(type) {
		case string:
			s = &I
		case *string:
			s = I
		default:
			return false
		}
		if len(*s) > 0 {
			ss := CleanAndExpandPath(*s, *datadir)
			if r != nil {
				r.String = fmt.Sprint(ss)
				if r.Value == nil {
					r.Value = NewIface()
				}
				r.Value.Put(ss)
				r.App.SaveConfig()
				return true
			} else {
				return false
			}
		}
		return false
	},
	Dir: func(r *Row, in interface{}) bool {
		var s *string
		switch I := in.(type) {
		case string:
			s = &I
		case *string:
			s = I
		default:
			return false
		}
		if len(*s) > 0 {
			ss := CleanAndExpandPath(*s, *datadir)
			if r != nil {
				r.String = fmt.Sprint(ss)
				if r.Value == nil {
					r.Value = NewIface()
				}
				r.Value.Put(ss)
				r.App.SaveConfig()
				return true
			} else {
				return false
			}
		}
		return false
	},
	Port: func(r *Row, in interface{}) bool {
		var s string
		var ii int
		isString := false
		switch I := in.(type) {
		case string:
			s = I
			isString = true
		case *string:
			s = *I
			isString = true
		case int:
			ii = I
		case *int:
			ii = *I
		default:
			return false
		}
		if isString {
			n, e := strconv.Atoi(s)
			if e != nil {
				return false
			}
			ii = n
		}
		if ii < 1025 || ii > 65535 {
			return false
		}
		if r != nil {
			r.Value.Put(ii)
			r.String = fmt.Sprint(ii)
			r.App.SaveConfig()
		}
		return true
	},
	Bool: func(r *Row, in interface{}) bool {
		var sb string
		var b bool
		switch I := in.(type) {
		case string:
			sb = I
			if strings.ToUpper(sb) == "TRUE" {
				b = true
				goto boolout
			}
			if strings.ToUpper(sb) == "FALSE" {
				b = false
				goto boolout
			}
		case *string:
			sb = *I
			if strings.ToUpper(sb) == "TRUE" {
				b = true
				goto boolout
			}
			if strings.ToUpper(sb) == "FALSE" {
				b = false
				goto boolout
			}
		case bool:
			b = I
		case *bool:
			b = *I
		default:
			return false
		}
	boolout:
		if r != nil {
			r.String = fmt.Sprint(b)
			r.Value.Put(b)
			r.App.SaveConfig()
		}
		return true
	},
	Int: func(r *Row, in interface{}) bool {
		var s string
		var ii int
		isString := false
		switch I := in.(type) {
		case string:
			s = I
			isString = true
		case *string:
			s = *I
			isString = true
		case int:
			ii = I
		case *int:
			ii = *I
		default:
			return false
		}
		if isString {
			n, e := strconv.Atoi(s)
			if e != nil {
				return false
			}
			ii = n
		}
		if r != nil {
			r.String = fmt.Sprint(ii)

			r.Value.Put(ii)
			r.App.SaveConfig()
		}
		return true
	},
	Tag: func(r *Row, in interface{}) bool {
		var s string
		switch I := in.(type) {
		case string:
			s = I
		case *string:
			s = *I
		default:
			return false
		}
		s = strings.TrimSpace(s)
		if len(s) < 1 {
			return false
		}
		if r != nil {
			r.Value.Put(s)
			r.String = fmt.Sprint(s)
			r.App.SaveConfig()
		}
		return true
	},
	Tags: func(r *Row, in interface{}) bool {
		var s []string
		existing, ok := r.Value.Get().([]string)
		if !ok {
			existing = []string{}
		}
		switch I := in.(type) {
		case string:
			s = append(s, I)
		case *string:
			s = append(s, *I)
		case []string:
			s = I
		case *[]string:
			s = *I
		case []interface{}:
			for _, x := range I {
				so, ok := x.(string)
				if ok {
					s = append(s, so)
				}
			}
		case nil:
			return false
		default:
			fmt.Println("invalid type", in, reflect.TypeOf(in))
			return false
		}
		for _, sse := range s {
			existing = append(existing, sse)
		}
		if r != nil {

			tmpMap := make(map[string]struct{})
			for _, x := range existing {
				tmpMap[x] = struct{}{}
			}
			existing = []string{}
			for i := range tmpMap {
				existing = append(existing, i)
			}
			sort.Strings(existing)
			r.Value.Put(existing)
			r.String = fmt.Sprint(existing)
			r.App.SaveConfig()
		}
		return true
	},
	Algo: func(r *Row, in interface{}) bool {
		var s string
		switch I := in.(type) {
		case string:
			s = I
		case *string:
			s = *I
		default:
			return false
		}
		var o string
		options := getAlgoOptions()
		for _, x := range options {
			if s == x {
				o = s
			}
		}
		if o == "" {
			rnd := "random"
			o = rnd
		}
		if r != nil {
			r.String = fmt.Sprint(o)
			r.Value.Put(o)
			r.App.SaveConfig()
		}
		return true
	},
	Float: func(r *Row, in interface{}) bool {
		var s string
		var f float64
		isString := false
		switch I := in.(type) {
		case string:
			s = I
			isString = true
		case *string:
			s = *I
			isString = true
		case float64:
			f = I
		case *float64:
			f = *I
		default:
			return false
		}
		if isString {
			ff, e := strconv.ParseFloat(s, 64)
			if e != nil {
				return false
			}
			f = ff
		}
		if r != nil {
			r.Value.Put(f)
			r.String = fmt.Sprint(f)
			r.App.SaveConfig()
		}
		return true
	},
	Duration: func(r *Row, in interface{}) bool {
		var s string
		var t time.Duration
		isString := false
		switch I := in.(type) {
		case string:
			s = I
			isString = true
		case *string:
			s = *I
			isString = true
		case time.Duration:
			t = I
		case *time.Duration:
			t = *I
		default:
			return false
		}
		if isString {
			dd, e := time.ParseDuration(s)
			if e != nil {
				return false
			}
			t = dd
		}
		if r != nil {
			r.String = fmt.Sprint(t)
			r.Value.Put(t)
			r.App.SaveConfig()
		}
		return true
	},
	Net: func(r *Row, in interface{}) bool {
		var sn string
		switch I := in.(type) {
		case string:
			sn = I
		case *string:
			sn = *I
		default:
			return false
		}
		found := false
		for _, x := range Networks {
			if x == sn {
				found = true
				*nine.ActiveNetParams = *NetParams[x]
			}
		}
		if r != nil && found {
			r.String = fmt.Sprint(sn)
			r.Value.Put(sn)
			r.App.SaveConfig()
		}
		return found
	},
	Level: func(r *Row, in interface{}) bool {
		var sl string
		switch I := in.(type) {
		case string:
			sl = I
		case *string:
			sl = *I
		default:
			return false
		}
		found := false
		for x := range cl.Levels {
			if x == sl {
				found = true
			}
		}
		if r != nil && found {
			r.String = fmt.Sprint(sl)
			r.Value.Put(sl)
			r.App.SaveConfig()
		}
		return found
	},
}

Valid is a collection of validator functions for the different types used in a configuration. These functions optionally can accept a *Row and with this they assign the validated, parsed value into the Value slot.

Functions

func BackgroundColor

func BackgroundColor() tcell.Color

func CleanAndExpandPath

func CleanAndExpandPath(path, datadir string) string

CleanAndExpandPath expands environment variables and leading ~ in the passed path, cleans the result, and returns it.

func Conf

func Conf(args []string, tokens Tokens, app *App) int

func Copy

func Copy(args []string, tokens Tokens, app *App) int

func Create

func Create(args []string, tokens Tokens, app *App) int

func Ctl

func Ctl(args []string, tokens Tokens, app *App) int

func DimColor

func DimColor() tcell.Color

func EnsureDir

func EnsureDir(fileName string) bool

EnsureDir checks a file could be written to a path, creates the directories as needed

func FileExists

func FileExists(filePath string) bool

FileExists reports whether the named file or directory exists.

func GUI

func GUI(args []string, tokens Tokens, app *App) int

func GenAddr

func GenAddr(name string, port int) func(r *Row, in interface{}) bool

GenAddr returns a validator with a set default port assumed if one is not present

func GenAddrs

func GenAddrs(name string, port int) func(r *Row, in interface{}) bool

GenAddrs returns a validator with a set default port assumed if one is not present

func GenCA

func GenCA(args []string, tokens Tokens, app *App) int

func GenCerts

func GenCerts(args []string, tokens Tokens, app *App) int

func Help

func Help(args []string, tokens Tokens, app *App) int

func List

func List(args []string, tokens Tokens, app *App) int

func MainColor

func MainColor() tcell.Color

func MakeConfig

func MakeConfig(c *App) (out *nine.Config)

func MinUint32

func MinUint32(a, b uint32) uint32

MinUint32 is a helper function to return the minimum of two uint32s. This avoids a math import and the need to cast to floats.

func Mine

func Mine(args []string, tokens Tokens, app *App) int

func New

func New(args []string, tokens Tokens, app *App) int

func Node

func Node(args []string, tokens Tokens, app *App) int

func NormalizeAddress

func NormalizeAddress(addr, defaultPort string) string

NormalizeAddress returns addr with the passed default port appended if there is not already a port specified.

func NormalizeAddresses

func NormalizeAddresses(addrs []string, defaultPort string) []string

NormalizeAddresses returns a new slice with all the passed peer addresses normalized with the given default port, and all duplicates removed.

func PrelightColor

func PrelightColor() tcell.Color

func RemoveDuplicateAddresses

func RemoveDuplicateAddresses(addrs []string) []string

RemoveDuplicateAddresses returns a new slice with all duplicate entries in addrs removed.

func Run

func Run(args []string, tokens Tokens, app *App) int

func Shell

func Shell(args []string, tokens Tokens, app *App) int

func Test

func Test(args []string, tokens Tokens, app *App) int

func TestHandler

func TestHandler(args []string, tokens Tokens, app *App) int

func TextColor

func TextColor() tcell.Color

func UseLogger

func UseLogger(
	logger *cl.SubSystem)

UseLogger uses a specified Logger to output package logging info. This should be used in preference to SetLogWriter if the caller is also using log.

func Wallet

func Wallet(args []string, tokens Tokens, app *App) int

Types

type App

type App struct {
	Name     string
	Tagline  string
	About    string
	Version  func() string
	Default  func(ctx *App) int
	Cats     Cats
	Commands Commands
	Config   *nine.Config
}

func NewApp

func NewApp(name string, g ...AppGenerator) (out *App)

func (*App) MarshalJSON

func (r *App) MarshalJSON() ([]byte, error)

func (*App) Parse

func (app *App) Parse(args []string) int

func (*App) ParseCLI

func (app *App) ParseCLI(args []string) (cmd *Command, tokens Tokens)

func (*App) SaveConfig

func (app *App) SaveConfig()

func (*App) UnmarshalJSON

func (r *App) UnmarshalJSON(data []byte) error

type AppGenerator

type AppGenerator func(ctx *App)

func About

func About(ver string) AppGenerator

func Cmd

func Cmd(name string, g ...CommandGenerator) AppGenerator

func DefaultRunner

func DefaultRunner(fn func(ctx *App) int) AppGenerator

func Group

func Group(name string, g ...CatGenerator) AppGenerator

func Tagline

func Tagline(ver string) AppGenerator

func Version

func Version(ver string) AppGenerator

type AppGenerators

type AppGenerators []AppGenerator

func (*AppGenerators) RunAll

func (r *AppGenerators) RunAll(app *App)

type Cat

type Cat map[string]*Row

func (Cat) GetSortedKeys

func (r Cat) GetSortedKeys() (out []string)

type CatGenerator

type CatGenerator func(ctx *Cat)

func Addr

func Addr(name string, defPort int, g ...RowGenerator) CatGenerator

func Addrs

func Addrs(name string, defPort int, g ...RowGenerator) CatGenerator

func Algo

func Algo(name string, g ...RowGenerator) CatGenerator

func Dir

func Dir(name string, g ...RowGenerator) CatGenerator

func Duration

func Duration(name string, g ...RowGenerator) CatGenerator

func Enable

func Enable(name string, g ...RowGenerator) CatGenerator

func Enabled

func Enabled(name string, g ...RowGenerator) CatGenerator

func File

func File(name string, g ...RowGenerator) CatGenerator

func Float

func Float(name string, g ...RowGenerator) CatGenerator

func Int

func Int(name string, g ...RowGenerator) CatGenerator

func Level

func Level(g ...RowGenerator) CatGenerator

func Net

func Net(name string, g ...RowGenerator) CatGenerator

func Port

func Port(name string, g ...RowGenerator) CatGenerator

func Tag

func Tag(name string, g ...RowGenerator) CatGenerator

func Tags

func Tags(name string, g ...RowGenerator) CatGenerator

type CatGenerators

type CatGenerators []CatGenerator

func (*CatGenerators) RunAll

func (r *CatGenerators) RunAll(cat Cat)

type CatJSON

type CatJSON map[string]Line

func (*CatJSON) GetSortedKeys

func (r *CatJSON) GetSortedKeys() (out []string)

GetSortedKeys returns the keys of a map in alphabetical order

type Cats

type Cats map[string]Cat

func (*Cats) Bool

func (r *Cats) Bool(cat, item string) (out *bool)

Bool returns the pointer to a value in the category map

func (*Cats) Duration

func (r *Cats) Duration(cat, item string) (out *time.Duration)

Duration returns the pointer to a value in the category map

func (*Cats) Float

func (r *Cats) Float(cat, item string) (out *float64)

Float returns the pointer to a value in the category map

func (*Cats) GetSortedKeys

func (r *Cats) GetSortedKeys() (out []string)

func (*Cats) Int

func (r *Cats) Int(cat, item string) (out *int)

Int returns the pointer to a value in the category map

func (*Cats) Map

func (r *Cats) Map(cat, item string) (out *nine.Mapstringstring)

Map returns the pointer to a value in the category map

func (*Cats) Str

func (r *Cats) Str(cat, item string) (out *string)

Str returns the pointer to a value in the category map

func (*Cats) Tags

func (r *Cats) Tags(cat, item string) (out *[]string)

Tags returns the pointer to a value in the category map

type CatsJSON

type CatsJSON map[string]CatJSON

func (*CatsJSON) GetSortedKeys

func (r *CatsJSON) GetSortedKeys() (out []string)

type Command

type Command struct {
	Name      string
	Pattern   string
	RE        *regexp.Regexp
	Short     string
	Detail    string
	Opts      Optional
	Precedent Precedent
	Handler   CommandHandler
}

type CommandGenerator

type CommandGenerator func(ctx *Command)

func Detail

func Detail(usage string) CommandGenerator

func Handler

func Handler(hnd func(args []string, tokens Tokens, app *App) int) CommandGenerator

func Opts

func Opts(opts ...string) CommandGenerator

func Pattern

func Pattern(patt string) CommandGenerator

func Precs

func Precs(precs ...string) CommandGenerator

func Short

func Short(usage string) CommandGenerator

type CommandGenerators

type CommandGenerators []CommandGenerator

func (*CommandGenerators) RunAll

func (r *CommandGenerators) RunAll() *Command

type CommandHandler

type CommandHandler func(args []string, tokens Tokens, app *App) int

type Commands

type Commands map[string]*Command

func (*Commands) GetSortedKeys

func (r *Commands) GetSortedKeys() (out []string)

type Iface

type Iface struct {
	Data *interface{}
}

func NewIface

func NewIface() *Iface

func (*Iface) Get

func (i *Iface) Get() interface{}

func (*Iface) Put

func (i *Iface) Put(in interface{}) *Iface

type Line

type Line struct {
	Value   interface{} `json:"value"`
	Default interface{} `json:"default,omitempty"`
	Min     int         `json:"min,omitempty"`
	Max     int         `json:"max,omitempty"`
	Usage   string      `json:"usage"`
}

type Optional

type Optional []string

type Precedent

type Precedent []string

type Row

type Row struct {
	Name     string
	Type     string
	Opts     []string
	Value    *Iface
	Default  *Iface
	Min      *Iface
	Max      *Iface
	Init     func(*Row)
	Get      func() interface{}
	Put      func(interface{}) bool
	Validate func(*Row, interface{}) bool
	String   string
	Usage    string
	App      *App
}

func (*Row) Bool

func (r *Row) Bool() bool

func (*Row) Duration

func (r *Row) Duration() time.Duration

func (*Row) Float

func (r *Row) Float() float64

func (*Row) Int

func (r *Row) Int() int

func (*Row) Tag

func (r *Row) Tag() string

func (*Row) Tags

func (r *Row) Tags() []string

type RowGenerator

type RowGenerator func(ctx *Row)

func Default

func Default(in interface{}) RowGenerator

Default sets the default value for a config item

func Max

func Max(max int) RowGenerator

Max attaches to the validator a test that enforces a maximum

func Min

func Min(min int) RowGenerator

Min attaches to the validator a test that enforces a minimum

func RandomString

func RandomString(n int) RowGenerator

RandomsString generates a random number and converts to base32 for a default random password of some number of characters

func Usage

func Usage(usage string) RowGenerator

Usage populates the usage field for information about a config item

type RowGenerators

type RowGenerators []RowGenerator

func (*RowGenerators) RunAll

func (r *RowGenerators) RunAll(row *Row)

type Token

type Token struct {
	Value string
	Cmd   Command
}

Token is a struct that ties together CLI invocation to the Command it relates to

type Tokens

type Tokens map[string]Token

func (*Tokens) GetSortedKeys

func (r *Tokens) GetSortedKeys() (out []string)

Directories

Path Synopsis
gui
pod is a full-node Parallelcoin implementation written in Go.
pod is a full-node Parallelcoin implementation written in Go.
integration/rpctest
Package rpctest provides a pod-specific RPC testing harness crafting and executing integration tests by driving a `pod` instance via the `RPC` interface.
Package rpctest provides a pod-specific RPC testing harness crafting and executing integration tests by driving a `pod` instance via the `RPC` interface.
mempool
Package mempool provides a policy-enforced pool of unmined bitcoin transactions.
Package mempool provides a policy-enforced pool of unmined bitcoin transactions.
spv

Jump to

Keyboard shortcuts

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