cli

package module
v1.0.12 Latest Latest
Warning

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

Go to latest
Published: Jan 24, 2019 License: MIT Imports: 3 Imported by: 3

README

cli

Simple library for parsing commands, and flags from the command line in Go.

Quickstart

This is a simple library that makes parsing commands, flags, arguments from the command line easier to do in Go. Here's what it looks like:

package main

import (
    "fmt"
    "os"

    "github.com/andrewpillar/cli"
)

func main() {
    c := cli.New()

    c.Main(func(c cli.Command) {
        fmt.Println("Say something"!)
    })

    helloCmd := c.Command("hello", func(c cli.Command) {
        cnt, err := c.Flags.GetInt("count")

        if err != nil {
            fmt.Fprintf(os.Stderr, "%s\n", err)
            os.Exit(1)
        }

        for i := 0; i < cnt; i++ {
            fmt.Println("Hello " + c.Args.Get(0))
        }
    })

    helloCmd.AddFlag(&cli.Flag{
        Name:     "count",
        Short:    "-c",
        Long:     "--count",
        Argument: true,
        Default:  1,
    })

    if err := c.Run(os.Args[1:]); err != nil {
        fmt.Fprintf(os.Stderr, "%s\n", err)
        os.Exit(1)
    }
}

And here is what the above program will produce once it has been built, and run:

$ say hello world --count=5
Hello world
Hello world
Hello world
Hello world
Hello world

You can start using the library by installing it with go get:

go get github.com/andrewpillar/cli

Writing Commands

This library can allow you to define a single main command, or multiple commands throughout. Each command which is created with this library can also have sub-commands.

Every command defined will take a call-back for executing that command. This call-back will receive the command which is being executed as its only parameter.

Main Command

The main command for the program can be defined with the Main method. This is the default command that will be executed if no other command is specified.

c.Main(func(c cli.Command) {
    fmt.Println("Say something!")
})
$ say
Say something!
Commands

Commands can be defined with a name, and a call-back with the Command method. This can allow for command line program to have multiple commands throughout.

c.Command("hello", func(c cli.Command) {
    fmt.Println("Hello!")
})
Sub-commands

Each command created with the library can have further sub-commands. The Command method will return a pointer to the newly created cli.Command type. This type has a method called Command which can allow for commands to be defined on the command itself.

cmd := c.Command("remote", func(c cli.Command) {
    fmt.Println("Doing something with a remote")
})

cmd.Command("add", func(c cli.Command) {
    fmt.Println("Adding a remote")
})
Flags

Command line flags can either be added to individual commands, or to the entire command line program itself. This is done by calling the AddFlag method and passing a pointer to the cli.Flag type.

helloCmd := c.Command("hello", func(c cli.Command) {
    cnt, err := c.Flags.GetInt("count")

    if err != nil {
        fmt.Fprintf(os.Stderr, "%s\n", err)
        os.Exit(1)
    }

    for i := 0; i < cnt; i++ {
        fmt.Println("Hello " + c.Args.Get(0))
    }
})

helloCmd.AddFlag(&cli.Flag{
    Name:     "count",
    Short:    "-c",
    Long:     "--count",
    Argument: true,
    Default:  1,
})

In the above example we added the count flag to the hello command in our program. We specified the short, and long flags for this flag, -c, and --count respectively, and stated that this flag takes an argument with a default value of 1.

If this flag is passed to the hello command and given no argument, or not passed to the command at all, then the default value of 1 will be returned when we retrieve the flag's value from the command.

There are multiple ways of retrieving a flag's value, since its value can be of varying types. Listed below are the different getter methods for accessing a flag's value:

  • GetInt
  • GetIn32
  • GetIn64
  • GetString
  • GetSlice

The GetSlice getter is a utility getter that wraps GetString, and takes an additional parameter for the delimiter on which to split the string.

c.Command("hello", func(c cli.Command) {
    names := c.Flags.GetSlice("names", ",")
})

For flags which do not take values, and merely serve as boolean flags then the IsSet method should be used for determining whether the flag was passed to the command.

c.Command("hello", func(c cli.Command) {
    if c.Flags.IsSet("help") {
        fmt.Println("Say hello")
        return
    }
})

Should a non-existent flag try and be accessed then the default zero-value for the type trying to be retrieved will be returned.

Global flags can be declared on the program itself. These will be added to every command which is created.

c := cli.New()

c.AddFlag(&cli.Flag{
    Name: "help",
    Long: "--help",
})

Handlers can also be set on flags. A flag handler will be passed the flag, and the command which had that flag passed to it. Setting the Exclusive property on the given cli.Flag type to true will prevent the command which passed the flag from running. This is useful if you want to display usage information for that command via a --help flag without having the command itself be run.

c := cli.New()

c.AddFlag(&cli.Flag{
    Name:      "help",
    Long:      "--help",
    Exclusive: true,
    Handler:   func(f cli.Flag, c cli.Command) {
        fmt.Println("usage for " + c.Name)
    },
})
Arguments

Command line arguments can be retrieved by accessing the Args property on the given command, and calling the Get method passing through the index of the argument you want to get.

c.Command("hello", func(c cli.Command) {
    fmt.Println("Hello " + c.Args.Get(0))
})

The Args property can also be looped through.

c.Command("hello", func(c cli.Command) {
    for _, a := range c.Args {
        fmt.Println("Hello " + a)
    }
})

Documentation

Overview

Simple library for building CLI applications in Go.

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

This section is empty.

Types

type Cli

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

func New

func New() *Cli

New creates a new Cli struct for attaching commands, and flags to. There is no limit to how many of these you can create.

func (*Cli) AddFlag

func (c *Cli) AddFlag(f *Flag)

AddFlag takes a pointer to a Flag struct, and adds it to the Cli struct marking it as global. This flag will be passed down to every subsequent command added to the Cli struct.

func (*Cli) Command

func (c *Cli) Command(name string, handler commandHandler) *Command

Command creates a new command for the Cli struct based on the name, and handler given. A pointer to the newly created Command is returned. The name of the command is typically what the user would type in to have the command run.

func (*Cli) Main

func (c *Cli) Main(handler commandHandler) *Command

Main specifies the main command to run should no initial command be found upon the first run of the application. This only takes a command handler.

func (*Cli) NilHandler

func (c *Cli) NilHandler(handler commandHandler)

NilHandler specifies a handler to be used for commands which do not have a handler on them. This is useful if you have mulitple sub-commands that perform actions, but whose parent command does not.

func (*Cli) Run

func (c *Cli) Run(args_ []string) error

Run takes the slice of strings, and parses them as commands and flags.

type Command

type Command struct {

	// The pointer to the command's parent if it is a sub-command. Otherwise
	// set to nil.
	Parent *Command

	// Name specifies the string the user inputs to execute the command. For
	// sub-commands this will not be the full string including the parent's
	// name, just the sub-command name itself.
	Name string

	// Args specifies the slice of arguments that are passed to the command.
	Args args

	// Flags specifies the flags that were set on the command.
	Flags flags

	// Commands specifies any sub-commands that the current command might have.
	Commands commands

	// Handler specifies the handler to call when the command is executed.
	Handler commandHandler
	// contains filtered or unexported fields
}

func (*Command) AddFlag

func (c *Command) AddFlag(f *Flag)

AddFlag takes a pointer to a Flag struct, and adds it to the Cli struct. Similar to the AddFlag method on the Cli struct, only the flags are contained to the Command struct itself, and not passed down to the sub-commands.

func (*Command) Command

func (c *Command) Command(name string, handler commandHandler) *Command

Command creates a new command for the Command struct based on the nane, and handler given. Similar to the Command method on the Cli struct, only this creates a sub-command.

func (Command) FullName

func (c Command) FullName() string

FullName returns the full name of the current command. If the command is a sub command then the string returned will be a concatenation of the command and all ancestors.

For example given the command,

theme ls

then the FullName would be,

theme-ls

func (Command) Run

func (c Command) Run(nilHandler commandHandler) error

Run executes the command, and takes a nilHandler. The nilHandler is only used as an attempted fall-back if the command does not have a handler by default.

type Flag

type Flag struct {

	// Name specifies the name of the flag. This should be a string, and will
	// be what is used to access the flag when passed to the command's handler.
	Name string

	// Short specifies the short version of a flag, for example '-h'.
	Short string

	// Long specifies the long version of a flag, for example '--help'.
	Long string

	// Argument specifies whether or not the flag takes an argument.
	Argument bool

	// If the flag takes an argument then the Value property will be set during
	// parsing of the input arguments.
	Value string

	// Default specifies the default value the flag should be if no value is
	// given to the flag. This is an interface, and before accessing the flag's
	// value you should know what it's expected type should be.
	Default interface{}

	// Exclusive specifies whether or not a flag with a handler should be
	// exclusive in its execution. Setting this to true means that no command
	// will be executed if an exclusive flag, with a handler has been set on
	// that command, and passed to that command.
	//
	// For example, the '--help' flag could be considered an exclusive flag.
	// When passed to a command you do not want the command itself to be
	// executed along with the '--help' flag.
	Exclusive bool

	// Handler specifies the handler for the flag should a flag be given to
	// a command. This handler will be passed the flag itself, and the command
	// on which the flag was passed.
	Handler flagHandler
	// contains filtered or unexported fields
}

func (Flag) Matches

func (f Flag) Matches(arg string) bool

Matches determins if the given argument matches against the current flag, based on the short, and long values of the current flag.

Jump to

Keyboard shortcuts

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