goptions

package module
v0.0.0-...-58cddc2 Latest Latest
Warning

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

Go to latest
Published: Jun 30, 2018 License: BSD-3-Clause Imports: 15 Imported by: 117

README

goptions implements a flexible parser for command line options.

Key targets were the support for both long and short flag versions, mutually exclusive flags, and verbs. Flags and their corresponding variables are defined by the tags in a (possibly anonymous) struct.

Example

package main

import (
	"github.com/voxelbrain/goptions"
	"os"
	"time"
)

func main() {
	options := struct {
		Servers  []string      `goptions:"-s, --server, obligatory, description='Servers to connect to'"`
		Password string        `goptions:"-p, --password, description='Don\\'t prompt for password'"`
		Timeout  time.Duration `goptions:"-t, --timeout, description='Connection timeout in seconds'"`
		Help     goptions.Help `goptions:"-h, --help, description='Show this help'"`

		goptions.Verbs
		Execute struct {
			Command string   `goptions:"--command, mutexgroup='input', description='Command to exectute', obligatory"`
			Script  *os.File `goptions:"--script, mutexgroup='input', description='Script to exectute', rdonly"`
		} `goptions:"execute"`
		Delete struct {
			Path  string `goptions:"-n, --name, obligatory, description='Name of the entity to be deleted'"`
			Force bool   `goptions:"-f, --force, description='Force removal'"`
		} `goptions:"delete"`
	}{ // Default values goes here
		Timeout: 10 * time.Second,
	}
	goptions.ParseAndFail(&options)
}
$ go run examples/readme_example.go --help
Usage: a.out [global options] <verb> [verb options]

Global options:
        -s, --server   Servers to connect to (*)
        -p, --password Don't prompt for password
        -t, --timeout  Connection timeout in seconds (default: 10s)
        -h, --help     Show this help

Verbs:
    delete:
        -n, --name     Name of the entity to be deleted (*)
        -f, --force    Force removal
    execute:
            --command  Command to exectute (*)
            --script   Script to exectute

Quick Reference

goptions

Each field of your struct can be tagged with a goptions

    FieldName type `goptions:"-S, --long, options..."`

Where the short options (-S) are declared with a single dash and long options (--long) are declared with two dashes. Either or both may be declared.

After the short/long option names are one or more of the following:

Global Options
  • description='...'
  • obligatory
  • mutexgroup='GROUP_NAME'
os.File specific
  • create
  • append
  • rdonly
  • wronly
  • rdwr
  • excl
  • sync
  • trunc
  • perm=0777

Supported Types

  • bool
  • string
  • float64
  • float32
  • int
  • int64
  • int32
  • goptions.Help
  • *os.File
  • *net.TCPAddr
  • *url.URL
  • time.Duration

Version 2.5.11

Documentation

Overview

package goptions implements a flexible parser for command line options.

Key targets were the support for both long and short flag versions, mutually exclusive flags, and verbs. Flags and their corresponding variables are defined by the tags in a (possibly anonymous) struct.

var options struct {
	Name string `goptions:"-n, --name"`
	Force bool `goptions:"-f, --force"`
	Verbosity int `goptions:"-v, --verbose"`
}

Short flags can be combined (e.g. `-nfv`). Long flags take their value after a separating space. The equals notation (`--long-flag=value`) is NOT supported right now.

Every member of the struct which is supposed to catch a command line value has to have a "goptions" tag. The contains the short and long flag names for this member but can additionally specify any of these options below.

obligatory        - Flag must be specified. Otherwise an error will be returned
                    when Parse() is called.
description='...' - Set the description for this particular flag. Will be
                    used by the HelpFunc.
mutexgroup='...'  - Add this flag to a MutexGroup. Only one flag of the
                    ones sharing a MutexGroup can be set. Otherwise an error
                    will be returned when Parse() is called. If one flag in a
                    MutexGroup is `obligatory` one flag of the group must be
                    specified. A flag can be in multiple MutexGroups at once.

Depending on the type of the struct member, additional options might become available:

Type: *os.File
    The given string is interpreted as a path to a file. If the string is "-"
    os.Stdin or os.Stdout will be used. os.Stdin will be returned, if the
    `rdonly` flag was set. os.Stdout will be returned, if `wronly` was set.
Available options:
    Any combination of create, append, rdonly, wronly, rdwr,
    excl, sync, trunc and perm can be specified and correspond directly with
    the combination of the homonymous flags in the os package.

Type: *net.TCPAddr
    The given string is interpreted as a tcp address. It is passed to
    net.ResolvTCPAddr() with "tcp" as the network type identifier.

Type: *net/url.URL
    The given string is parsed by net/url.Parse()

Type: time.Duration
    The given string is parsed by time.ParseDuration()

If a member is a slice type, multiple definitions of the flags are possible. For each specification the underlying type will be used.

var options struct {
    Servers []string `goptions:"-s, --server, description='Servers to connect to'"`
}{}

goptions also has support for verbs. Each verb accepts its own set of flags which take exactly the same tag format as global options. For an usage example of verbs see the PrintHelp() example.

Index

Examples

Constants

View Source
const (
	VERSION = "2.5.11"
)

Variables

View Source
var (
	ErrHelpRequest = errors.New("Request for Help")
)

Functions

func DefaultHelpFunc

func DefaultHelpFunc(w io.Writer, fs *FlagSet)

DefaultHelpFunc is a HelpFunc which renders the default help template and pipes the output through a text/tabwriter.Writer before flushing it to the output.

func Parse

func Parse(v interface{}) error

Parse parses the command-line flags from os.Args[1:].

func ParseAndFail

func ParseAndFail(v interface{})

ParseAndFail is a convenience function to parse os.Args[1:] and print the help if an error occurs. This should cover 90% of this library's applications.

func PrintHelp

func PrintHelp()

PrintHelp renders the default help to os.Stderr.

func StartsWithLowercase

func StartsWithLowercase(s string) bool

Types

type Flag

type Flag struct {
	Short        string
	Long         string
	MutexGroups  []string
	Description  string
	Obligatory   bool
	WasSpecified bool

	DefaultValue interface{}
	// contains filtered or unexported fields
}

Flag represents a single flag of a FlagSet.

func (*Flag) Handles

func (f *Flag) Handles(arg string) bool

func (*Flag) IsMulti

func (f *Flag) IsMulti() bool

IsMulti returns true if the flag can be specified multiple times.

func (*Flag) Name

func (f *Flag) Name() string

Return the name of the flag preceding the right amount of dashes. The long name is preferred. If no name has been specified, "<unspecified>" will be returned.

func (*Flag) NeedsExtraValue

func (f *Flag) NeedsExtraValue() bool

NeedsExtraValue returns true if the flag expects a separate value.

func (*Flag) Parse

func (f *Flag) Parse(args []string) ([]string, error)

type FlagSet

type FlagSet struct {
	// This HelpFunc will be called when PrintHelp() is called.
	HelpFunc
	// Name of the program. Might be used by HelpFunc.
	Name string

	// Global option flags
	Flags []*Flag
	// Verbs and corresponding FlagSets
	Verbs map[string]*FlagSet
	// contains filtered or unexported fields
}

A FlagSet represents one set of flags which belong to one particular program. A FlagSet is also used to represent a subset of flags belonging to one verb.

func NewFlagSet

func NewFlagSet(name string, v interface{}) *FlagSet

NewFlagSet returns a new FlagSet containing all the flags which result from parsing the tags of the struct. Said struct as to be passed to the function as a pointer. If a tag line is erroneous, NewFlagSet() panics as this is considered a compile time error rather than a runtme error.

func (*FlagSet) FlagByName

func (fs *FlagSet) FlagByName(fname string) *Flag

func (*FlagSet) MutexGroups

func (fs *FlagSet) MutexGroups() map[string]MutexGroup

MutexGroups returns a map of Flag lists which contain mutually exclusive flags.

func (*FlagSet) Parse

func (fs *FlagSet) Parse(args []string) (err error)

Parse takes the command line arguments and sets the corresponding values in the FlagSet's struct.

func (*FlagSet) ParseAndFail

func (fs *FlagSet) ParseAndFail(w io.Writer, args []string)

func (*FlagSet) PrintHelp

func (fs *FlagSet) PrintHelp(w io.Writer)

Prints the FlagSet's help to the given writer.

Example
options := struct {
	Server   string        `goptions:"-s, --server, obligatory, description='Server to connect to'"`
	Password string        `goptions:"-p, --password, description='Don\\'t prompt for password'"`
	Timeout  time.Duration `goptions:"-t, --timeout, description='Connection timeout in seconds'"`
	Help     Help          `goptions:"-h, --help, description='Show this help'"`

	Verbs
	Execute struct {
		Command string   `goptions:"--command, mutexgroup='input', description='Command to exectute', obligatory"`
		Script  *os.File `goptions:"--script, mutexgroup='input', description='Script to exectute', rdonly"`
	} `goptions:"execute"`
	Delete struct {
		Path  string `goptions:"-n, --name, obligatory, description='Name of the entity to be deleted'"`
		Force bool   `goptions:"-f, --force, description='Force removal'"`
	} `goptions:"delete"`
}{ // Default values goes here
	Timeout: 10 * time.Second,
}

args := []string{"--help"}
fs := NewFlagSet("goptions", &options)
err := fs.Parse(args)
if err == ErrHelpRequest {
	fs.PrintHelp(os.Stdout)
	return
} else if err != nil {
	fmt.Printf("Failure: %s", err)
}
Output:

Usage: goptions [global options] <verb> [verb options]

Global options:
        -s, --server   Server to connect to (*)
        -p, --password Don't prompt for password
        -t, --timeout  Connection timeout in seconds (default: 10s)
        -h, --help     Show this help

Verbs:
    delete:
        -n, --name     Name of the entity to be deleted (*)
        -f, --force    Force removal
    execute:
            --command  Command to exectute (*)
            --script   Script to exectute

type Help

type Help bool

Help Defines the common help flag. It is handled separately as it will cause Parse() to return ErrHelpRequest.

type HelpFunc

type HelpFunc func(w io.Writer, fs *FlagSet)

HelpFunc is the signature of a function responsible for printing the help.

func NewTemplatedHelpFunc

func NewTemplatedHelpFunc(tpl string) HelpFunc

Generates a new HelpFunc taking a `text/template.Template`-formatted string as an argument. The resulting template will be executed with the FlagSet as its data.

type Marshaler

type Marshaler interface {
	MarshalGoption(s string) error
}

type MutexGroup

type MutexGroup []*Flag

A MutexGroup holds a set of flags which are mutually exclusive and cannot be specified at the same time.

func (MutexGroup) IsObligatory

func (mg MutexGroup) IsObligatory() bool

IsObligatory returns true if exactly one of the flags in the MutexGroup has to be specified

func (MutexGroup) IsValid

func (mg MutexGroup) IsValid() bool

IsValid checks if the flags in the MutexGroup describe a valid state. I.e. At most one has been specified or – if it is an obligatory MutexGroup – exactly one has been specified.

func (MutexGroup) Names

func (mg MutexGroup) Names() []string

Names is a convenience function to return the array of names of the flags in the MutexGroup.

func (MutexGroup) WasSpecified

func (mg MutexGroup) WasSpecified() bool

type Remainder

type Remainder []string

A remainder catches all excessive arguments. If both a verb and the containing options struct have a remainder field, only the latter one will be used.

Example
options := struct {
	Username  string `goptions:"-u, --user, obligatory, description='Name of the user'"`
	Remainder Remainder
}{}

args := []string{"-u", "surma", "some", "more", "args"}
fs := NewFlagSet("goptions", &options)
_ = fs.Parse(args)
// Error handling omitted
fmt.Printf("Remainder: %#v", options.Remainder)
Output:

Remainder: goptions.Remainder{"some", "more", "args"}

type Verbs

type Verbs string

Verbs marks the point in the struct where the verbs start. Its value will be the name of the selected verb.

Example
options := struct {
	ImportantFlag string        `goptions:"-f, --flag, description='Important flag, obligatory'"`
	Password      string        `goptions:"-p, --password, description='Don\\'t prompt for password'"`
	Timeout       time.Duration `goptions:"-t, --timeout, description='Connection timeout in seconds'"`
	Help          Help          `goptions:"-h, --help, description='Show this help'"`

	Verb    Verbs
	Execute struct {
		Command string   `goptions:"--command, mutexgroup='input', description='Command to exectute', obligatory"`
		Script  *os.File `goptions:"--script, mutexgroup='input', description='Script to exectute', rdonly"`
	} `goptions:"execute"`
	Delete struct {
		Path  string `goptions:"-n, --name, obligatory, description='Name of the entity to be deleted'"`
		Force bool   `goptions:"-f, --force, description='Force removal'"`
	} `goptions:"delete"`
}{ // Default values goes here
	Timeout: 10 * time.Second,
}

args := []string{"delete", "-n", "/usr/bin"}
fs := NewFlagSet("goptions", &options)
_ = fs.Parse(args)
// Error handling omitted
fmt.Printf("Selected verb: %s", options.Verb)
Output:

Selected verb: delete

Directories

Path Synopsis

Jump to

Keyboard shortcuts

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