Movatterモバイル変換


[0]ホーム

URL:


serpent

packagemodule
v0.10.0Latest Latest
Warning

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

Go to latest
Published: Nov 18, 2024 License:CC0-1.0Imports:39Imported by:31

Details

Repository

github.com/coder/serpent

Links

README

serpent

Go Reference

serpent is a Go CLI configuration framework based oncobra and used bycoder/coder.It's designed for large-scale CLIs with dozens of commands and hundredsof options. If you're building a small, self-contained tool, go withcobra.

help example

When compared to cobra, serpent strives for:

  • Better default help output inspired by the Go toolchain
  • Greater flexibility in accepting options that span across multiple sources
  • Composition via middleware
  • Testability (e.g. OS Stdout and Stderr is only available to commands explicitly)

Basic Usage

Seeexample/echo:

package mainimport ("os""strings""github.com/coder/serpent")func main() {var upper boolcmd := serpent.Command{Use:   "echo <text>",Short: "Prints the given text to the console.",Options: serpent.OptionSet{{Name:        "upper",Value:       serpent.BoolOf(&upper),Flag:        "upper",Description: "Prints the text in upper case.",},},Handler: func(inv *serpent.Invocation) error {if len(inv.Args) == 0 {inv.Stderr.Write([]byte("error: missing text\n"))os.Exit(1)}text := inv.Args[0]if upper {text = strings.ToUpper(text)}inv.Stdout.Write([]byte(text))return nil},}err := cmd.Invoke().WithOS().Run()if err != nil {panic(err)}}

Design

This Design section assumes you have a good understanding of howcobra works.

Options

Serpent is designed for high-configurability. To us, that means providingmany ways to configure the same value (env, YAML, flags, etc.) and keepingthe code clean and testable as you scale the number of options.

Serpent'sOption type looks like:

type Option struct {Name stringFlag stringEnv stringDefault stringValue pflag.Value// ...}

And is used by eachCommand whenpassed as an array to theOptions field.

More coming...

This README is a stub for now. We'll better explain the design and usageofserpent in the future.

Documentation

Overview

Package serpent offers an all-in-one solution for a highly configurable CLIapplication. Within Coder, we use it for all of our subcommands, whichdemands more functionality than cobra/viber offers.

The Command interface is loosely based on the chi middleware pattern andhttp.Handler/HandlerFunc.

Index

Constants

View Source
const CompletionModeEnv = "COMPLETION_MODE"

CompletionModeEnv is a special environment variable that isset when the command is being run in completion mode.

Variables

View Source
var DiscardValue discardValue

DiscardValue does nothing but implements the pflag.Value interface.It's useful in cases where you want to accept an option, but access theunderlying value directly instead of through the Option methods.

Functions

funcDefaultCompletionHandleradded inv0.8.0

func DefaultCompletionHandler(inv *Invocation) []string

DefaultCompletionHandler is a handler that prints all the subcommands, orall the options that haven't been exhaustively set, if the current wordstarts with a dash.

Types

typeAnnotations

type Annotations map[string]string

Annotations is an arbitrary key-mapping used to extend the Option and Command types.Its methods won't panic if the map is nil.

func (Annotations)Get

func (aAnnotations) Get(keystring) (string,bool)

Get retrieves a key from the map, returning false if the key is not foundor the map is nil.

func (Annotations)IsSet

func (aAnnotations) IsSet(keystring)bool

IsSet returns true if the key is set in the annotations map.

func (Annotations)Mark

func (aAnnotations) Mark(keystring, valuestring)Annotations

Mark sets a value on the annotations map, creating oneif it doesn't exist. Mark does not mutate the original andreturns a copy. It is suitable for chaining.

typeBool

type Boolbool

funcBoolOf

func BoolOf(b *bool) *Bool

func (*Bool)NoOptDefValue

func (*Bool) NoOptDefValue()string

func (*Bool)Set

func (b *Bool) Set(sstring)error

func (Bool)String

func (bBool) String()string

func (Bool)Type

func (Bool) Type()string

func (Bool)Value

func (bBool) Value()bool

typeCommandadded inv0.5.0

type Command struct {// Parent is the direct parent of the command.//// It is set automatically when an invokation runs.Parent *Command// Children is a list of direct descendants.Children []*Command// Use is provided in form "command [flags] [args...]".Usestring// Aliases is a list of alternative names for the command.Aliases []string// Short is a one-line description of the command.Shortstring// Hidden determines whether the command should be hidden from help.Hiddenbool// Deprecated indicates whether this command is deprecated.// If empty, the command is not deprecated.// If set, the value is used as the deprecation message.Deprecatedstring `json:"deprecated,omitempty"`// RawArgs determines whether the command should receive unparsed arguments.// No flags are parsed when set, and the command is responsible for parsing// its own flags.RawArgsbool// Long is a detailed description of the command,// presented on its help page. It may contain examples.LongstringOptionsOptionSetAnnotationsAnnotations// Middleware is called before the Handler.// Use Chain() to combine multiple middlewares.MiddlewareMiddlewareFuncHandlerHandlerFuncHelpHandlerHandlerFunc// CompletionHandler is called when the command is run in completion// mode. If nil, only the default completion handler is used.//// Flag and option parsing is best-effort in this mode, so even if an Option// is "required" it may not be set.CompletionHandlerCompletionHandlerFunc}

Command describes an executable command.

func (*Command)AddSubcommandsadded inv0.5.0

func (c *Command) AddSubcommands(cmds ...*Command)

AddSubcommands adds the given subcommands, setting theirParent field automatically.

func (*Command)FullNameadded inv0.5.0

func (c *Command) FullName()string

FullName returns the full invocation name of the command,as seen on the command line.

func (*Command)FullOptionsadded inv0.5.0

func (c *Command) FullOptions()OptionSet

FullOptions returns the options of the command and its parents.

func (*Command)FullUsageadded inv0.5.0

func (c *Command) FullUsage()string

FullName returns usage of the command, precededby the usage of its parents.

func (*Command)Invokeadded inv0.5.0

func (c *Command) Invoke(args ...string) *Invocation

Invoke creates a new invocation of the command, withstdio discarded.

The returned invocation is not live until Run() is called.

func (*Command)Nameadded inv0.5.0

func (c *Command) Name()string

Name returns the first word in the Use string.

func (*Command)Walkadded inv0.5.0

func (c *Command) Walk(fn func(*Command))

Walk calls fn for the command and all its children.

typeCompletionHandlerFuncadded inv0.8.0

type CompletionHandlerFunc func(i *Invocation) []string

typeDuration

type Durationtime.Duration

funcDurationOf

func DurationOf(d *time.Duration) *Duration

func (*Duration)MarshalYAML

func (d *Duration) MarshalYAML() (interface{},error)

func (*Duration)Set

func (d *Duration) Set(vstring)error

func (*Duration)String

func (d *Duration) String()string

func (Duration)Type

func (Duration) Type()string

func (*Duration)UnmarshalYAML

func (d *Duration) UnmarshalYAML(n *yaml.Node)error

func (*Duration)Value

func (d *Duration) Value()time.Duration

typeEnum

type Enum struct {Choices []stringValue   *string}

funcEnumOf

func EnumOf(v *string, choices ...string) *Enum

func (*Enum)MarshalYAMLadded inv0.6.0

func (e *Enum) MarshalYAML() (interface{},error)

func (*Enum)Set

func (e *Enum) Set(vstring)error

func (*Enum)String

func (e *Enum) String()string

func (*Enum)Type

func (e *Enum) Type()string

func (*Enum)UnmarshalYAMLadded inv0.6.0

func (e *Enum) UnmarshalYAML(n *yaml.Node)error

typeEnumArrayadded inv0.8.0

type EnumArray struct {Choices []stringValue   *[]string}

funcEnumArrayOfadded inv0.8.0

func EnumArrayOf(v *[]string, choices ...string) *EnumArray

func (*EnumArray)Appendadded inv0.8.0

func (e *EnumArray) Append(sstring)error

func (*EnumArray)GetSliceadded inv0.8.0

func (e *EnumArray) GetSlice() []string

func (*EnumArray)Replaceadded inv0.8.0

func (e *EnumArray) Replace(ss []string)error

func (*EnumArray)Setadded inv0.8.0

func (e *EnumArray) Set(vstring)error

func (*EnumArray)Stringadded inv0.8.0

func (e *EnumArray) String()string

func (*EnumArray)Typeadded inv0.8.0

func (e *EnumArray) Type()string

typeEnvVar

type EnvVar struct {NamestringValuestring}

Var represents a single environment variable of formNAME=VALUE.

typeEnviron

type Environ []EnvVar

funcParseEnviron

func ParseEnviron(environ []string, prefixstring)Environ

ParseEnviron returns all environment variables starting withprefix without said prefix.

func (Environ)Get

func (eEnviron) Get(namestring)string

func (Environ)Lookup

func (eEnviron) Lookup(namestring) (string,bool)

func (*Environ)Set

func (e *Environ) Set(name, valuestring)

func (Environ)ToOS

func (eEnviron) ToOS() []string

typeFloat64added inv0.8.0

type Float64float64

funcFloat64Ofadded inv0.8.0

func Float64Of(f *float64) *Float64

func (*Float64)Setadded inv0.8.0

func (f *Float64) Set(sstring)error

func (Float64)Stringadded inv0.8.0

func (fFloat64) String()string

func (Float64)Typeadded inv0.8.0

func (Float64) Type()string

func (Float64)Valueadded inv0.8.0

func (fFloat64) Value()float64

typeGroup

type Group struct {Parent      *Group `json:"parent,omitempty"`Namestring `json:"name,omitempty"`YAMLstring `json:"yaml,omitempty"`Descriptionstring `json:"description,omitempty"`}

Group describes a hierarchy of groups that an option or command belongs to.

func (*Group)Ancestry

func (g *Group) Ancestry() []Group

Ancestry returns the group and all of its parents, in order.

func (*Group)FullName

func (g *Group) FullName()string

typeHandlerFunc

type HandlerFunc func(i *Invocation)error

HandlerFunc handles an Invocation of a command.

funcDefaultHelpFnadded inv0.8.0

func DefaultHelpFn()HandlerFunc

DefaultHelpFn returns a function that generates usage (help)output for a given command.

typeHostPort

type HostPort struct {HoststringPortstring}

HostPort is a host:port pair.

func (*HostPort)MarshalJSON

func (hp *HostPort) MarshalJSON() ([]byte,error)

func (*HostPort)MarshalYAML

func (hp *HostPort) MarshalYAML() (interface{},error)

func (*HostPort)Set

func (hp *HostPort) Set(vstring)error

func (*HostPort)String

func (hp *HostPort) String()string

func (*HostPort)Type

func (*HostPort) Type()string

func (*HostPort)UnmarshalJSON

func (hp *HostPort) UnmarshalJSON(b []byte)error

func (*HostPort)UnmarshalYAML

func (hp *HostPort) UnmarshalYAML(n *yaml.Node)error

typeInt64

type Int64int64

funcInt64Of

func Int64Of(i *int64) *Int64

func (*Int64)Set

func (i *Int64) Set(sstring)error

func (Int64)String

func (iInt64) String()string

func (Int64)Type

func (Int64) Type()string

func (Int64)Value

func (iInt64) Value()int64

typeInvocation

type Invocation struct {Command *Command// Args is reduced into the remaining arguments after parsing flags// during Run.Args []string// Environ is a list of environment variables. Use EnvsWithPrefix to parse// os.Environ.EnvironEnvironStdoutio.WriterStderrio.WriterStdinio.Reader// DeprecatedLoggerslog.Logger// DeprecatedNetNet// contains filtered or unexported fields}

Invocation represents an instance of a command being executed.

func (*Invocation)Context

func (inv *Invocation) Context()context.Context

func (*Invocation)CurWordsadded inv0.8.0

func (inv *Invocation) CurWords() (prevstring, curstring)

func (*Invocation)IsCompletionModeadded inv0.8.0

func (inv *Invocation) IsCompletionMode()bool

IsCompletionMode returns true if the command is being run in completion mode.

func (*Invocation)ParsedFlags

func (inv *Invocation) ParsedFlags() *pflag.FlagSet

func (*Invocation)Run

func (inv *Invocation) Run() (errerror)

Run executes the command.If two command share a flag name, the first command wins.

func (*Invocation)SignalNotifyContext

func (inv *Invocation) SignalNotifyContext(parentcontext.Context, signals ...os.Signal) (ctxcontext.Context, stopcontext.CancelFunc)

SignalNotifyContext is equivalent to signal.NotifyContext, but supports being overridden intests.

func (*Invocation)WithContext

func (inv *Invocation) WithContext(ctxcontext.Context) *Invocation

WithContext returns a copy of the Invocation with the given context.

func (*Invocation)WithOS

func (inv *Invocation) WithOS() *Invocation

WithOS returns the invocation as a main package, filling in the invocation's unsetfields with OS defaults.

func (*Invocation)WithTestParsedFlags

func (inv *Invocation) WithTestParsedFlags(_testing.TB,parsedFlags *pflag.FlagSet,) *Invocation

func (*Invocation)WithTestSignalNotifyContext

func (inv *Invocation) WithTestSignalNotifyContext(_testing.TB,f func(parentcontext.Context, signals ...os.Signal) (ctxcontext.Context, stopcontext.CancelFunc),) *Invocation

WithTestSignalNotifyContext allows overriding the default implementation of SignalNotifyContext.This should only be used in testing.

typeMiddlewareFunc

type MiddlewareFunc func(nextHandlerFunc)HandlerFunc

MiddlewareFunc returns the next handler in the chain,or nil if there are no more.

funcChain

Chain returns a Handler that first calls middleware in order.

funcRequireNArgs

func RequireNArgs(wantint)MiddlewareFunc

funcRequireRangeArgs

func RequireRangeArgs(start, endint)MiddlewareFunc

RequireRangeArgs returns a Middleware that requires the number of argumentsto be between start and end (inclusive). If end is -1, then the number ofarguments must be at least start.

typeNet

type Net interface {// Listen has the same semantics as `net.Listen` but also supports `udp`Listen(network, addressstring) (net.Listener,error)}

Net abstracts CLI commands interacting with the operating system networking.

At present, it covers opening local listening sockets, since doing thisin testing is a challenge without flakes, since it's hard to pick a port weknow a priori will be free.

typeNoOptDefValuer

type NoOptDefValuer interface {NoOptDefValue()string}

NoOptDefValuer describes behavior when nooption is passed into the flag.

This is useful for boolean or otherwise binary flags.

typeOption

type Option struct {Namestring `json:"name,omitempty"`Descriptionstring `json:"description,omitempty"`// Required means this value must be set by some means. It requires// `ValueSource != ValueSourceNone`// If `Default` is set, then `Required` is ignored.Requiredbool `json:"required,omitempty"`// Flag is the long name of the flag used to configure this option. If unset,// flag configuring is disabled.Flagstring `json:"flag,omitempty"`// FlagShorthand is the one-character shorthand for the flag. If unset, no// shorthand is used.FlagShorthandstring `json:"flag_shorthand,omitempty"`// Env is the environment variable used to configure this option. If unset,// environment configuring is disabled.Envstring `json:"env,omitempty"`// YAML is the YAML key used to configure this option. If unset, YAML// configuring is disabled.YAMLstring `json:"yaml,omitempty"`// Default is parsed into Value if set.Defaultstring `json:"default,omitempty"`// Value includes the types listed in values.go.Valuepflag.Value `json:"value,omitempty"`// Annotations enable extensions to serpent higher up in the stack. It's useful for// help formatting and documentation generation.AnnotationsAnnotations `json:"annotations,omitempty"`// Group is a group hierarchy that helps organize this option in help, configs// and other documentation.Group *Group `json:"group,omitempty"`// UseInstead is a list of options that should be used instead of this one.// The field is used to generate a deprecation warning.UseInstead []Option `json:"use_instead,omitempty"`Hiddenbool `json:"hidden,omitempty"`ValueSourceValueSource `json:"value_source,omitempty"`CompletionHandlerCompletionHandlerFunc `json:"-"`}

Option is a configuration option for a CLI application.

func (*Option)UnmarshalJSON

func (o *Option) UnmarshalJSON(data []byte)error

func (Option)YAMLPath

func (oOption) YAMLPath()string

typeOptionSet

type OptionSet []Option

OptionSet is a group of options that can be applied to a command.

func (*OptionSet)Add

func (optSet *OptionSet) Add(opts ...Option)

Add adds the given Options to the OptionSet.

func (OptionSet)ByFlagadded inv0.8.0

func (optSetOptionSet) ByFlag(flagstring) *Option

func (OptionSet)ByName

func (optSetOptionSet) ByName(namestring) *Option

ByName returns the Option with the given name, or nil if no such optionexists.

func (OptionSet)Filter

func (optSetOptionSet) Filter(filter func(optOption)bool)OptionSet

Filter will only return options that match the given filter. (return true)

func (*OptionSet)FlagSet

func (optSet *OptionSet) FlagSet() *pflag.FlagSet

FlagSet returns a pflag.FlagSet for the OptionSet.

func (*OptionSet)MarshalYAML

func (optSet *OptionSet) MarshalYAML() (any,error)

MarshalYAML converts the option set to a YAML node, that can beconverted into bytes via yaml.Marshal.

The node is returned to enable post-processing higher up inthe stack.

It is isomorphic with FromYAML.

func (*OptionSet)ParseEnv

func (optSet *OptionSet) ParseEnv(vs []EnvVar)error

ParseEnv parses the given environment variables into the OptionSet.Use EnvsWithPrefix to filter out prefixes.

func (*OptionSet)SetDefaults

func (optSet *OptionSet) SetDefaults()error

SetDefaults sets the default values for each Option, skipping valuesthat already have a value source.

func (*OptionSet)UnmarshalJSON

func (optSet *OptionSet) UnmarshalJSON(data []byte)error

UnmarshalJSON implements json.Unmarshaler for OptionSets. Options have aninterface Value type that cannot handle unmarshalling because the types cannotbe inferred. Since it is a slice, instantiating the Options first does nothelp.

However, we typically do instantiate the slice to have the correct types.So this unmarshaller will attempt to find the named option in the existingset, if it cannot, the value is discarded. If the option exists, the valueis unmarshalled into the existing option, and replaces the existing option.

The value is discarded if it's type cannot be inferred. This behavior justfeels "safer", although it should never happen if the correct option setis passed in. The situation where this could occur is if a client and serverare on different versions with different options.

func (*OptionSet)UnmarshalYAML

func (optSet *OptionSet) UnmarshalYAML(rootNode *yaml.Node)error

UnmarshalYAML converts the given YAML node into the option set.It is isomorphic with ToYAML.

typeRegexp

type Regexpregexp.Regexp

func (*Regexp)MarshalJSON

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

func (*Regexp)MarshalYAML

func (r *Regexp) MarshalYAML() (interface{},error)

func (*Regexp)Set

func (r *Regexp) Set(vstring)error

func (Regexp)String

func (rRegexp) String()string

func (Regexp)Type

func (Regexp) Type()string

func (*Regexp)UnmarshalJSON

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

func (*Regexp)UnmarshalYAML

func (r *Regexp) UnmarshalYAML(n *yaml.Node)error

func (*Regexp)Value

func (r *Regexp) Value() *regexp.Regexp

typeRunCommandError

type RunCommandError struct {Cmd *CommandErrerror}

func (*RunCommandError)Error

func (e *RunCommandError) Error()string

func (*RunCommandError)Unwrap

func (e *RunCommandError) Unwrap()error

typeString

type Stringstring

funcStringOf

func StringOf(s *string) *String

func (*String)NoOptDefValue

func (*String) NoOptDefValue()string

func (*String)Set

func (s *String) Set(vstring)error

func (String)String

func (sString) String()string

func (String)Type

func (String) Type()string

func (String)Value

func (sString) Value()string

typeStringArray

type StringArray []string

StringArray is a slice of strings that implements pflag.Value and pflag.SliceValue.

funcStringArrayOf

func StringArrayOf(ss *[]string) *StringArray

func (*StringArray)Append

func (s *StringArray) Append(vstring)error

func (*StringArray)GetSlice

func (s *StringArray) GetSlice() []string

func (*StringArray)Replace

func (s *StringArray) Replace(vals []string)error

func (*StringArray)Set

func (s *StringArray) Set(vstring)error

func (StringArray)String

func (sStringArray) String()string

func (StringArray)Type

func (StringArray) Type()string

func (StringArray)Value

func (sStringArray) Value() []string

typeStruct

type Struct[Tany] struct {Value T}

Struct is a special value type that encodes an arbitrary struct.It implements the flag.Value interface, but in general these values shouldonly be accepted via config for ergonomics.

The string encoding type is YAML.

func (*Struct[T])MarshalJSON

func (s *Struct[T]) MarshalJSON() ([]byte,error)

nolint:revive

func (*Struct[T])MarshalYAML

func (s *Struct[T]) MarshalYAML() (interface{},error)

nolint:revive

func (*Struct[T])Set

func (s *Struct[T]) Set(vstring)error

func (*Struct[T])String

func (s *Struct[T]) String()string

func (*Struct[T])Type

func (s *Struct[T]) Type()string

func (*Struct[T])UnmarshalJSON

func (s *Struct[T]) UnmarshalJSON(b []byte)error

nolint:revive

func (*Struct[T])UnmarshalYAML

func (s *Struct[T]) UnmarshalYAML(n *yaml.Node)error

nolint:revive

typeURL

type URLurl.URL

funcURLOf

func URLOf(u *url.URL) *URL

func (*URL)MarshalJSON

func (u *URL) MarshalJSON() ([]byte,error)

func (*URL)MarshalYAML

func (u *URL) MarshalYAML() (interface{},error)

func (*URL)Set

func (u *URL) Set(vstring)error

func (*URL)String

func (u *URL) String()string

func (*URL)Type

func (*URL) Type()string

func (*URL)UnmarshalJSON

func (u *URL) UnmarshalJSON(b []byte)error

func (*URL)UnmarshalYAML

func (u *URL) UnmarshalYAML(n *yaml.Node)error

func (*URL)Value

func (u *URL) Value() *url.URL

typeUnknownSubcommandErroradded inv0.8.0

type UnknownSubcommandError struct {Args []string}

func (*UnknownSubcommandError)Erroradded inv0.8.0

typeValidator

type Validator[Tpflag.Value] struct {Value T// contains filtered or unexported fields}

Validator is a wrapper around a pflag.Value that allows for validationof the value after or before it has been set.

funcValidate

func Validate[Tpflag.Value](opt T, validate func(value T)error) *Validator[T]

func (*Validator[T])MarshalJSON

func (i *Validator[T]) MarshalJSON() ([]byte,error)

func (*Validator[T])MarshalYAML

func (i *Validator[T]) MarshalYAML() (interface{},error)

func (*Validator[T])Set

func (i *Validator[T]) Set(inputstring)error

func (*Validator[T])String

func (i *Validator[T]) String()string

func (*Validator[T])Type

func (i *Validator[T]) Type()string

func (*Validator[T])Underlying

func (i *Validator[T]) Underlying()pflag.Value

func (*Validator[T])UnmarshalJSON

func (i *Validator[T]) UnmarshalJSON(b []byte)error

func (*Validator[T])UnmarshalYAML

func (i *Validator[T]) UnmarshalYAML(n *yaml.Node)error

typeValueSource

type ValueSourcestring
const (ValueSourceNoneValueSource = ""ValueSourceFlagValueSource = "flag"ValueSourceEnvValueSource = "env"ValueSourceYAMLValueSource = "yaml"ValueSourceDefaultValueSource = "default")

typeYAMLConfigPath

type YAMLConfigPathstring

YAMLConfigPath is a special value type that encodes a path to a YAMLconfiguration file where options are read from.

func (*YAMLConfigPath)Set

func (p *YAMLConfigPath) Set(vstring)error

func (*YAMLConfigPath)String

func (p *YAMLConfigPath) String()string

func (*YAMLConfigPath)Type

func (*YAMLConfigPath) Type()string

Source Files

View all Source files

Directories

PathSynopsis
example

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f orF : Jump to
y orY : Canonical URL
go.dev uses cookies from Google to deliver and enhance the quality of its services and to analyze traffic.Learn more.

[8]ページ先頭

©2009-2025 Movatter.jp