yagap

package module
v0.0.0-...-eea9d14 Latest Latest
Warning

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

Go to latest
Published: Jan 20, 2026 License: AGPL-3.0 Imports: 4 Imported by: 0

README

yagap

Yet another Go argument parser

Why?

The basic argument parsing mechamisms in Go include package flag. It's pretty good, but maybe not good enough for your needs.

Neither mine.

The beauty of Go is that you can extend its library in a way that makes it easy for anyone interested to use it. Notable examples include go-flags and argparse. Don't get me wrong: they're both great, but they have some annoyances, and that's why I created yagap. It was inspired (but not based) on these libraries, and also on Python argparse.

Installation

Just run go get -u codeberg.org/taflaj/yagap on your application directory. Pretty simple, isn't it?

But you already knew that…

Usage

The below are the steps necessary to use the parser.

Initialization

To initialize it, use parser := yagap.NewParser(progname, description), where progname and description are strings that will be shown when presenting your program's help.

Configuration

Two methods allow for parser configuration, both returning a reference to the parser object. This way, methods can be concatenated. For example, you could do something like parser.SetEpilog().AddOption() and so forth.

The first one is parser.SetEpilog(epilog), where epilog (a string) contains the message to be printed at the end of the help text. This is entirely optional.

The second one is parser.AddOption(option), where option is a reference to a yagap.OptionObject, which in turn defines each argument option.

Argument option

To define an argument option, you can use option := yagap.NewOption(). Just like above, the methods described below return a reference to the argument option itself, thus allowing you to concatenate the method calls and, as a result, configuring all option aspects in a single line of code.

Method Parameters Description
SetShort(s) s string Character following the - on the command line to denote a short form argument.
SetLong(s) s string String following -- on the command line to define a long form argument.
SetDescription(s) s string String describing the argument.
SetRequired() By default, all arguments are optional on the command line. This method requires the user to use the argument. If it's not used, the program will exit with an error message.
SetMultiple() By default, each argument can only be used once. This methods allows the user to use the argument more than once, for example to increase a given property of the program.
SetFlag() By default, all arguments require an additional parameter to be entered. This method defines the argument as a flag. The default value is false; using it switches the value to true.
SetDefault(s) s string Defines the default value of an argument, in case the user doesn't use it on the command line. This can't be used with flags because they already have a default value: false.

Here's an example to show how to enable -h and --help as arguments:

help := yagap.NewOption().
  SetShort("h").
  SetLong("help").
  SetDescription("Print this message").
  SetFlag()

This isn't really necessary, though, as yagap.NewParser automatically does it for you. You can, however, customize it using the SetDescription and SetMultiple methods. Just be careful what you're doing, and keep in mind that there's no way to disable it.

Execution

The user launches the program specifying a number of arguments on the command line. Single character arguments can be entered following a -, jointly or independently. For example, if a, b, and c are valid arguments, the user can enter them as -a -b -c or -abc. Long arguments are entered individually following a --, as in --help. Entering -- with no arguments stops parsing immediately; all remaining arguments are passed as entered, regardless of being preceded by - or --.

To capture the arguments, use values, err := parser.Parse(), which is a convenience method. Alternatively you could use values, err := parser.ParseArgs(os.Args[1:]). The first returned value is a slice of strings with all arguments that were not subject to parsing. The second one indicates any errors that took place during parsing, or nil otherwise.

Obtaining results

These methods are available directly on the Option object:

Method Results Description
GetShort() string Character following the - on the command line to denote a short form argument.
GetLong() string String following -- on the command line to define a long form argument.
GetCount() int Number of times the argument was specified on the command line.
IsSet() bool Indicates whether the flag was specified on the command line.
GetValue() string, error A convenience method to return the value specified for the given argument.
GetValues() []string All values assigned to a given argument.

These methods are available on the Parser object:

Method Parameters Results Description
GetAll() []*OptionObject References to all argument options defined on the program.
GetHelpOption() *OptionObject Reference to the help Option.
GetValuesFromShort(s) string []string All values assigned to the short form argument.
GetValuesFromLong(s) string []string All values assigned to the long form argument.
PrintUsage() int, error Prints the usage text. You may want to add fmt.Println() right afterwards.
GetUsage() string The usage text, in case you want to present it in another way.

A practical example

This program accepts -d or --debug to enable debugging mode, -c or --config to specify an alternate configuration file, and obviously -h or --help for help.

func main() {
	parser := yagap.NewParser("myprog", "Just for testing").SetEpilog("And nothing else")
	debug := yagap.NewOption().
		SetShort("d").
		SetLong("debug").
		SetDescription("Enable debugging mode").
		SetFlag()
	parser.AddOption(debug.(*yagap.OptionObject))
	config := yagap.NewOption().
		SetShort("c").
		SetLong("config").
		SetDescription("Configuration file").
		SetDefault("config.cfg")
	parser.AddOption(config.(*yagap.OptionObject))
	args, err := parser.Parse()
	if err != nil {
		fmt.Println(err)
		os.Exit(1)
	}
	if parser.GetHelpOption().IsSet() {
		parser.PrintUsage()
		fmt.Println()
	} else {
		filename, _ := config.GetValue()
		fmt.Printf("Debugging mode: %t\nUsing configuration file %s\nAdditional arguments: %v\n", debug.IsSet(), filename, args)
	}
}
Sample runs
$ example
Debugging mode: false
Using configuration file config.cfg
Additional arguments: []
$ example --help
Just for testing
Usage: myprog <arguments>
Arguments:
  -h  --help    Print this message
  -d  --debug   Enable debugging mode
  -c  --config  Configuration file
  --            Stop parsing (all further arguments are passed through)
And nothing else
$ example --debug -c test.cfg Hello world
Debugging mode: true
Using configuration file test.cfg
Additional arguments: [Hello world]

Future improvements

I definitely need to refactor ParseArgs. In its current shape and form, it's overly complicated.

I usually like to stop the program once help is presented. Today, it's in the hands of the developer to force an exit if -h or --help are entered. I may want to add a method to stop parsing once the user asks for help.

Talking about help, I should show the default value for any arguments that have it defined.

One thing that could be useful (which I also saw elsewhere) is to have a callback function for when selected arguments are entered.

I can't think of anything else at the moment. Once you start using it (with my heartful thanks), you might come up with an idea or too; please share them with me. Thank you for your support!

Documentation

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

This section is empty.

Types

type Option

type Option interface {
	GetShort() string
	SetShort(string) Option
	GetLong() string
	SetLong(string) Option
	SetRequired() Option
	SetDescription(string) Option
	SetMultiple() Option
	SetDefault(string) Option
	GetValues() []string
	GetValue() (string, error)
	IsSet() bool

	SetFlag() Option
	GetCount() int
	// contains filtered or unexported methods
}

func NewOption

func NewOption() Option

type OptionObject

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

func (*OptionObject) GetCount

func (o *OptionObject) GetCount() int

func (*OptionObject) GetLong

func (o *OptionObject) GetLong() string

func (*OptionObject) GetShort

func (o *OptionObject) GetShort() string

func (*OptionObject) GetValue

func (o *OptionObject) GetValue() (string, error)

func (*OptionObject) GetValues

func (o *OptionObject) GetValues() []string

func (*OptionObject) IsSet

func (o *OptionObject) IsSet() bool

func (*OptionObject) SetDefault

func (o *OptionObject) SetDefault(value string) Option

func (*OptionObject) SetDescription

func (o *OptionObject) SetDescription(description string) Option

func (*OptionObject) SetFlag

func (o *OptionObject) SetFlag() Option

func (*OptionObject) SetLong

func (o *OptionObject) SetLong(long string) Option

func (*OptionObject) SetMultiple

func (o *OptionObject) SetMultiple() Option

func (*OptionObject) SetRequired

func (o *OptionObject) SetRequired() Option

func (*OptionObject) SetShort

func (o *OptionObject) SetShort(short string) Option

type Parser

type Parser interface {
	SetEpilog(string) Parser
	AddOption(o *OptionObject) Parser
	GetHelpOption() *OptionObject
	GetAll() []*OptionObject
	GetValuesFromShort(string) []string
	GetValuesFromLong(string) []string
	Parse() ([]string, error)
	ParseArgs([]string) ([]string, error)
	GetUsage() string
	PrintUsage() (int, error)
}

type ParserObject

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

func NewParser

func NewParser(program string, description string) *ParserObject

func (*ParserObject) AddOption

func (po *ParserObject) AddOption(o *OptionObject) Parser

func (*ParserObject) GetAll

func (po *ParserObject) GetAll() []*OptionObject

func (*ParserObject) GetHelpOption

func (po *ParserObject) GetHelpOption() *OptionObject

func (*ParserObject) GetUsage

func (po *ParserObject) GetUsage() string

func (*ParserObject) GetValuesFromLong

func (po *ParserObject) GetValuesFromLong(long string) []string

func (*ParserObject) GetValuesFromShort

func (po *ParserObject) GetValuesFromShort(short string) []string

func (*ParserObject) Parse

func (po *ParserObject) Parse() ([]string, error)

func (*ParserObject) ParseArgs

func (po *ParserObject) ParseArgs(args []string) ([]string, error)

func (*ParserObject) PrintUsage

func (po *ParserObject) PrintUsage() (int, error)

func (*ParserObject) SetEpilog

func (po *ParserObject) SetEpilog(epilog string) Parser

Jump to

Keyboard shortcuts

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