cflag

package module
v0.4.0 Latest Latest
Warning

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

Go to latest
Published: Feb 6, 2024 License: MIT Imports: 8 Imported by: 0

README

cflag

cflag adds command functionality to pflag by making use of pflag's FlagSet and its parsing capabilities. Commands can have subcommands, enabling deep command structures with independent flags. The API is leaned on flag.

Unlike pflag, cflag is not a drop-in replacement for flag or pflag.

Installation

cflag is available using the standard go get command.

Install by running:

go get github.com/forside/cflag

Run tests by running:

go test github.com/forside/cflag

Usage

Imports
import (
    flag "github.com/spf13/pflag"
    "github.com/forside/cflag"
)
Parsing base application flags

To parse application arguments without commands, define a FlagSet, register flags and parse the arguments using cflag.

flags := flag.NewFlagSet("", flag.ExitOnError)
paramVersion = flags.BoolP("version", "v", false, "Display the application version.")

cflag.Parse(os.Args, flags)
fmt.Printf("version flag: %t\n", *paramVersion)
Parsing a command with flags

To add a command with a new set of flags, define a FlagSet, register a command with the set and parse the arguments using cflag. When no flags are required for the application or a command, supply nil instead of a FlagSet.

flagsFoo := flag.NewFlagSet("", flag.ExitOnError)
paramFooTest1 := flagsFoo.Int("test1", 1, "Test 1.")
cmdFoo := cflag.Cmd("foo", flagsFoo)

cflag.Parse(os.Args, nil)
fmt.Printf("foo command supplied: %t\n", cmdFoo.IsActive())
fmt.Printf("test1 flag: %d\n", *paramFooTest1)
Parsing subcommands

To add a subcommand to another command, register it to the command instead of to cflag directly.

cmdFoo := cflag.Cmd("foo", nil)
flagsFooBar := flag.NewFlagSet("", flag.ExitOnError)
paramFooBarTest2 := flagsFoo.Int("test2", 2, "Test 2.")
cmdFooBar := cmdFoo.Cmd("bar", flagsFooBar)

cflag.Parse(os.Args, nil)
fmt.Printf("foo command supplied: %t\n", cmdFoo.IsActive())
fmt.Printf("foo/bar command supplied: %t\n", cmdFooBar.IsActive())
fmt.Printf("test2 flag: %d\n", *paramFooBarTest2)
Full example
package main

import (
    "fmt"
    "github.com/forside/cflag"
    flag "github.com/spf13/pflag"
    "os"
)

func main() {
    // Define top-level flags.
    flags := cflag.NewFlagSet("", flag.ExitOnError)
    flags.SortFlags = false
    paramVersion := flags.BoolP("version", "v", false, "Display the application version.")

    // Define foo command.
    flagsFoo := cflag.NewFlagSet("", flag.ExitOnError)
    flagsFoo.SortFlags = false
    paramFooTest1 := flagsFoo.Int("test1", 1, "Test 1.")
    cmdFoo, _ := cflag.Cmd("foo", "Foo command.", flagsFoo)

    // Define foo/bar command.
    flagsFooBar := cflag.NewFlagSet("", flag.ExitOnError)
    paramFooBarTest2 := flagsFooBar.Int("test2", 2, "Test 2.")
    flagsFooBar.SortFlags = false
    cmdFooBar, _ := cmdFoo.Cmd("bar", "Bar command", flagsFooBar)

    // Parse arguments and print values.
    cflag.Parse(os.Args, flags)
    fmt.Printf("version flag: %t\n", *paramVersion)
    fmt.Printf("foo command supplied: %t\n", cmdFoo.IsActive())
    fmt.Printf("foo/bar command supplied: %t\n", cmdFooBar.IsActive())
    fmt.Printf("test1 flag: %d\n", *paramFooTest1)
    fmt.Printf("test2 flag: %d\n", *paramFooBarTest2)
}
$ go build
$ ./main -v foo --test1 11 bar --test2 12
version flag: true
foo command supplied: true
foo/bar command supplied: true
test1 flag: 11
test2 flag: 12

For more examples check cflag_test.go.

Using callbacks

To automatically execute a function for an active command, callbacks can be defined. The last active command in a command chain and its FlagSet is passed to the callback. When a callback is defined for a parent command but not for its subcommands, the callback of the parent command is executed and the subcommand and its FlagSet is passed to it.

cb := func(command *cflag.Command, flags *flag.FlagSet) {
    // Print flag.
    paramTest, _ := flags.GetInt("test")
    fmt.Printf("Test: %t %d\n", flags.Changed("test"), paramTest)
}

// Define flags.
flags := clag.NewFlagSet("", flag.ExitOnError)
flags.SortFlags = false
_ = flags.Int("test", 0, "Test.")

// Set global command callback.
cflag.SetCallback(cb)

// Run cflag parser.
cflag.Parse(args, flags)

See TestCallback in cflag_test.go.

Using cflag without global values

cflag can be used standalone without using global values. While parsing the arguments, a command expects its name to be either empty or equal args[0]. This means the name of the top-level command must be either empty or args[0].

// Define top-level flags.
flags := NewFlagSet("", flag.ExitOnError)
flags.SortFlags = false
paramTest := flags.Int("test", 0, "Test.")

// Create top-level command with empty name.
cmd := NewCommand("", "Test.", flags)

// Parse arguments and print values.
cmd.Parse(os.Args)
fmt.Printf("Test: %t %d\n", flags.Changed("test"), *paramTest)

See TestStandalone in cflag_test.go.

Help page

cflag automatically generates help pages for all commands. It can be accessed by supplying -h, --help to a command. To add a description to your command, use SetDescription().

// Define top-level flags.
flags := cflag.NewFlagSet("", flag.ExitOnError)
flags.SortFlags = false
paramVersion := flags.BoolP("version", "v", false, "Display the application version.")

// Define foo command.
flagsFoo := cflag.NewFlagSet("", flag.ExitOnError)
flagsFoo.SortFlags = false
paramFooTest1 := flagsFoo.Int("test1", 1, "Test 1.")
cmdFoo, _ := cflag.Cmd("foo", "Foo command.", flagsFoo)

// Parse arguments.
cflag.SetDescription("cflag test application.")
cflag.Parse(os.Args, flags)
$ ./main -h
cflag test application.
Commands:
  foo   Foo command.
Flags:
  -v, --version   Display the application version.
  -h, --help      Display help.
$ ./main foo -h
Foo command.
Flags:
      --test1 int   Test 1. (default 1)
  -h, --help        Display help.

See TestHelp, TestHidden and TestDeprecated in cflag_test.go for more options.

Development

Clone the repository and run go build to build the module or go test to run the integrated tests.

Documentation

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

func Active added in v0.2.0

func Active(name string) bool

Active searches for a registered command by its name and reports its activation state. See IsActive.

func AddCommand

func AddCommand(command *Command) error

AddCommand adds command to the global register. When a command with the same name already exists, the operation is cancelled and an error is returned.

func CommandUsage added in v0.2.0

func CommandUsage() string

CommandUsage returns a string containing the usage information for the application and all commands, including the application description if defined.

func CommandUsages

func CommandUsages() string

CommandUsages returns a string containing the usage information for all commands defined for the application.

func CommandUsagesWrapped added in v0.3.0

func CommandUsagesWrapped(cols int) string

CommandUsagesWrapped returns a string containing the usage information for all subcommands defined for this command. Wrapped to cols columns (0 for no wrapping).

func FlagUsages added in v0.2.0

func FlagUsages() string

FlagUsages returns a string containing the usage information for all flags defined for this command.

func GetDescription added in v0.2.0

func GetDescription() string

GetDescription returns the application description if set. See SetDescription.

func IsActive

func IsActive() bool

IsActive reports whether the global command is active, i.e. Parse has been called.

func NewFlagSet added in v0.2.0

func NewFlagSet(name string, errorHandling flag.ErrorHandling) *flag.FlagSet

NewFlagSet creates a flag.FlagSet with ParseErrorsWhitelist.UnknownFlags enabled, which is required to process subcommands.

func Parse

func Parse(arguments []string, flags *flag.FlagSet)

Parse parses the application command line arguments respecting the defined global command structure. Arguments for each command are parsed using pflag. The first argument is expected to be the application path. Use flag.NewFlagSet to create the flag.FlagSet for parsing top-level application flags.

func Reset

func Reset()

Reset resets the global command register.

func SetCallback added in v0.4.0

func SetCallback(callback CommandCallback)

SetCallback sets the global function which is executed at the end of the parsing process, when no callback is defined for the active command. The last active command (with or without a callback defined) is passed to the callback.

func SetDescription

func SetDescription(description string)

SetDescription defines a long description that is displayed on the generated help page. See CommandUsages.

func SetOutput added in v0.2.0

func SetOutput(output io.Writer)

SetOutput sets the destination for usage and error messages. If output is nil, os.Stderr is used.

func SetUsageFunc added in v0.4.0

func SetUsageFunc(usageFunc UsageFunc)

SetUsageFunc sets the function which prints the command usage when the --help flag is recognized during parsing. By default, it prints the output of CommandUsage which is roughly equivalent to fmt.Printf("%s\n%s\nCommands:\n%sFlags:\n%s", c.GetUsage(), c.GetDescription(), c.CommandUsages(), c.FlagUsages())

Types

type Command

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

A Command represents a (sub)command with a set of defined flags.

func Cmd

func Cmd(name string, usage string, flags *flag.FlagSet) (*Command, error)

Cmd creates and adds a new command to the global register. When the command is added successfully, the Command value is returned. Else nil and an error is returned.

func Lookup added in v0.2.0

func Lookup(name string) *Command

Lookup searches for a registered command by its name. If no matching command is found, nil is returned.

func NewCommand

func NewCommand(name string, usage string, flags *flag.FlagSet) *Command

NewCommand creates a new Command object for use with AddCommand. A top-level command must have an empty name. Use flag.NewFlagSet to create the flag.FlagSet.

func (*Command) Active added in v0.2.0

func (c *Command) Active(name string) bool

Active searches for a registered subcommand by its name and reports its activation state. See IsActive.

func (*Command) AddCommand

func (c *Command) AddCommand(command *Command) error

AddCommand adds command as a subcommand. When a command with the same name already exists, the operation is cancelled and an error is returned.

func (*Command) Cmd

func (c *Command) Cmd(name string, usage string, flags *flag.FlagSet) (*Command, error)

Cmd creates a new command and adds it as a subcommand. When the command is added successfully, the Command value is returned. Else nil and an error is returned.

func (*Command) CommandUsage added in v0.2.0

func (c *Command) CommandUsage() string

CommandUsage returns a string containing the usage information for this command and all subcommands, including the description for this command if defined.

func (*Command) CommandUsages

func (c *Command) CommandUsages() string

CommandUsages returns a string containing the usage information for all subcommands defined for this command.

func (*Command) CommandUsagesWrapped added in v0.3.0

func (c *Command) CommandUsagesWrapped(cols int) string

CommandUsagesWrapped returns a string containing the usage information for all subcommands defined for this command. Wrapped to cols columns (0 for no wrapping).

func (*Command) FlagUsages added in v0.2.0

func (c *Command) FlagUsages() string

FlagUsages returns a string containing the usage information for all flags defined for this command.

func (*Command) FlagUsagesWrapped added in v0.3.0

func (c *Command) FlagUsagesWrapped(cols int) string

FlagUsagesWrapped returns a string containing the usage information for all flags defined for this command. Wrapped to cols columns (0 for no wrapping).

func (*Command) GetDescription added in v0.2.0

func (c *Command) GetDescription() string

GetDescription returns the command description if set. See Command.SetDescription.

func (*Command) GetName added in v0.2.0

func (c *Command) GetName() string

GetName returns the command name.

func (*Command) GetUsage added in v0.2.0

func (c *Command) GetUsage() string

GetUsage returns the command usage.

func (*Command) IsActive

func (c *Command) IsActive() bool

IsActive reports whether the command is active, i.e. it was supplied to the command line when calling Parse.

func (*Command) IsDeprecated added in v0.2.0

func (c *Command) IsDeprecated() bool

IsDeprecated reports whether the command is marked as deprecated, i.e. it is not listed in help and usage messages and a warning is displayed on its help message.

func (*Command) IsHidden added in v0.2.0

func (c *Command) IsHidden() bool

IsHidden reports whether the command is marked as hidden, i.e. it is not listed in help and usage messages.

func (*Command) Lookup added in v0.2.0

func (c *Command) Lookup(name string) *Command

Lookup searches for a registered subcommand by its name. If no matching command is found, nil is returned.

func (*Command) MarkDeprecated added in v0.2.0

func (c *Command) MarkDeprecated()

MarkDeprecated indicates that the command is deprecated. It will continue to function but will not show up in help or usage messages.

func (*Command) MarkHidden added in v0.2.0

func (c *Command) MarkHidden()

MarkHidden sets the command to 'hidden'. It will continue to function but will not show up in help or usage messages.

func (*Command) Parse

func (c *Command) Parse(arguments []string)

Parse parses the command line arguments respecting the defined command structure. Arguments for each command are parsed using pflag.

func (*Command) SetCallback added in v0.4.0

func (c *Command) SetCallback(callback CommandCallback)

SetCallback sets the function which is executed when the command is the last active command with a callback defined at the end of the parsing process. The last active command (with or without a callback defined) is passed to the callback.

func (*Command) SetDescription

func (c *Command) SetDescription(description string)

SetDescription defines a long description that is displayed on the generated help page. See CommandUsages.

func (*Command) SetOutput added in v0.2.0

func (c *Command) SetOutput(output io.Writer)

SetOutput sets the destination for usage and error messages. If output is nil, os.Stderr is used.

func (*Command) SetUsageFunc added in v0.4.0

func (c *Command) SetUsageFunc(usageFunc UsageFunc)

SetUsageFunc sets the function which prints the command usage when the --help flag is recognized during parsing. By default, it prints the output of CommandUsage which is roughly equivalent to fmt.Printf("%s\n%s\nCommands:\n%sFlags:\n%s", c.GetUsage(), c.GetDescription(), c.CommandUsages(), c.FlagUsages())

type CommandCallback added in v0.4.0

type CommandCallback func(command *Command, flags *flag.FlagSet)

type UsageFunc added in v0.4.0

type UsageFunc func(command *Command)

Jump to

Keyboard shortcuts

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