kubo

package module
v0.2.0 Latest Latest
Warning

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

Go to latest
Published: Jul 30, 2018 License: GPL-3.0 Imports: 5 Imported by: 1

README

Kubo

GoDoc GoReportCard TravisCI

Lightweight package to write command line apps in Go.

Aims

To be (and remain) as lightweight as possible, while still providing sufficient features to build rich command line applications. Also to be easy to understand and use.

Installation

Use vgo get to download the package.

$ vgo get github.com/ravernkoh/kubo

Usage

Basic

The most basic app has just one command, with no arguments and no flags.

app := kubo.NewApp(&kubo.Command{
    Name: "basic",
    Description: "a basic hello world app",
    Run: func(ctx *kubo.Context) error {
        // Prints 'hello, world!'
        fmt.Fprintln(ctx.Stdout(), "hello, world!")
    },
})

Run then runs the app and returns an error which should be handled (usually by simply printing it out).

// Blocks until the command is completed
if err := app.Run(); err != nil {
    fmt.Printf("error: %v\n", err)
}

In this case, the app simply prints "hello, world!" (more will be explained on the context later).

$ basic
hello, world!
Commands

The building block of a command line app is a command. Flags, arguments and child commands can all be defined on a command.

kubo.Command{
    Name: "commands",
    Description: "a random command",
    Run: func(ctx *kubo.Context) error {
        // Prints 'random'
        fmt.Fprintln(ctx.Stdout(), "random")
    },
}

The Run function is the function that will be called if the raw arguments are successfully parsed by the app. Usually, code will be written in this function.

Flags

Defining flags on a command is easy.

kubo.Command{
    Name: "flags",
    Description: "a command with flags",
    // Defines the flags for this command
    Flags: []kubo.Flag{
        {
            Name: "one",
            Description: "the first flag",
        },
        {
            Name: "two",
            Description: "the second flag",
        },
    },
}

The code above defines two flags, called one and two, which will be available for use with the command.

$ flags --one value1 --two value2

Flags can have aliases, which defines alternate names for them.

kubo.Flag{
    Name: "one",
    Description: "the first flag",
    Aliases: []string{"o"},
}

For single letter flags, only a single dash needs to be used.

$ flags -o value1 --two value2

Flags also have a field called Bool. If this is set to true, then no value needs to be passed to them.

kubo.Flag{
    Name: "two",
    Description: "the second flag",
    Bool: true,
}

The resulting value would be "true" if the flag is set and "false" if the flag is not set.

Note that once Bool is set, no value should be passed to the flag, as the parser will not try to parse for the flag value.

$ flags -o value1 --two
Arguments

Defining arguments on a command is also easy.

kubo.Command{
    Name: "arguments",
    Description: "a command with arguments",
    // Defines the arguments for this command
    Arguments: []kubo.Argument{
        {
            Name: "one",
        },
        {
            Name: "two",
        },
    },
}

The code above defines two arguments, one and two. The order in which you define the arguments matters. This is because arguments are parsed by their positions and not by their names.

$ arguments value1 value2

This will result in one having the value "value1" and two having the value "value2".

Arguments can also have a field of Multiple, which causes the argument to collect multiple values.

kubo.Argument{
    Name: "two",
    Multiple: true,
}

Note that only the last argument can have Multiple set.

$ arguments value1 value2 value3 value4

This will result in two having the value ["value2", "value3", "value4"].

Contexts

The context passed in the run function is used to get the arguments and flags that were parsed from the raw arguments.

kubo.Command{
    Name: "contexts",
    Description: "a command with arguments and flags",
    Arguments: []kubo.Argument{
        {Name: "argument"},
    },
    Flags: []kubo.Flag{
        {Name: "flag"},
    },
    Run: func(ctx *kubo.Context) error {
        // Gets the argument called 'argument'
        argument, err := ctx.Argument("argument")
        if err != nil {
            return err
        }

        // Gets the flag called 'flag'
        flag, err := ctx.Flag("flag")
        if err != nil {
            return err
        }

        fmt.Fprintf(ctx.Stdout(), "argument: %s, flag: %s\n", argument, flag)
    },
}

The context also contains the methods for Stdin and Stdout, which should be used to read from and write to the console. They can be configured in the app itself (which will pass these values to the context).

// Default values
app.Stdin = os.Stdin
app.Stdout = os.Stdout

When getting arguments and flags from the context, sometimes their values need to be converted to other types. For that purpose, the kuboutil package can be used.

// Gets the argument called 'argument' and converts it to an int
argument, err := kuboutil.Int(ctx.Argument("argument"))
if err != nil {
    return err
}

These conversion utilities automatically propogate the error from the Argument method.

Child commands

Commands can have child commands.

parent := &kubo.Command{
    Name: "parent",
}

child := &kubo.Command{
    Name: "child",
}

// Makes 'child' a child of the 'parent' command
parent.Add(child)

These child commands can be called by passing in their name.

$ parent child

Child commands can have flags, arguments, and even child commands of their own!

parent := &kubo.Command{
    Name: "parent",
}

child := &kubo.Command{
    Name: "child",
}

grandchild := &kubo.Command{
    Name: "grandchild",
}

// Makes 'grandchild' a child of the 'child' command
child.Add(grandchild)

// Makes 'child' a child of the 'parent' command
parent.Add(child)

They can then be called by passing in their names.

$ parent child grandchild
Help command

A help command can be generated for each command.

complex := &kubo.Command{
    Name: "complex",
    Description: "some complex command",
}

// Makes 'help' a child command of the 'complex' command
complex.Add(complex.Help())

The help command can be called using help.

$ complex help

Examples

More examples can be found in the _examples folder.

Alternatives

Of course, there are other more notable packages for building command line apps (Forgive me if I missed yours out).

Kubo was built as some practice for me and also to contribute to open source software!

License

This project is licensed under the GNU Public License 3.0.

Author

Documentation

Overview

Package kubo is a lightweight package to write command line apps in Go.

Basic

The most basic app has just one command, with no arguments and no flags.

 app := kubo.NewApp(&kubo.Command{
	Name: "basic",
	Description: "a basic hello world app",
	Run: func(ctx *kubo.Context) error {
		// Prints 'hello, world!'
		fmt.Fprintln(ctx.Stdout(), "hello, world!")
	},
 })

Run then runs the app and returns an error which should be handled (usually by simply printing it out).

// Blocks until the command is completed
if err := app.Run(); err != nil {
	fmt.Printf("error: %v\n", err)
}

In this case, the app simply prints `"hello, world!"` (more will be explained on the context later).

$ basic
hello, world!

Commands

The building block of a command line app is a command. Flags, arguments and child commands can all be defined on a command.

kubo.Command{
	Name: "commands",
	Description: "a random command",
	Run: func(ctx *kubo.Context) error {
		// Prints 'random'
		fmt.Fprintln(ctx.Stdout(), "random")
   	},
}

The `Run` function is the function that will be called if the raw arguments are successfully parsed by the app. Usually, code will be written in this function.

Flags

Defining flags on a command is easy.

kubo.Command{
	Name: "flags",
	Description: "a command with flags",
	// Defines the flags for this command
	Flags: []kubo.Flag{
		{
			Name: "one",
 			Description: "the first flag",
		},
 		{
 			Name: "two",
			Description: "the second flag",
		},
	},
}

The code above defines two flags, called `one` and `two`, which will be available for use with the command.

$ flags --one value1 --two value2

Flags can have aliases, which defines alternate names for them.

kubo.Flag{
	Name: "one",
	Description: "the first flag",
	Aliases: []string{"o"},
}

For single letter flags, only a single dash needs to be used.

$ flags -o value1 --two value2

Flags also have a field called `Bool`. If this is set to true, then no value needs to be passed to them.

kubo.Flag{
	Name: "two",
	Description: "the second flag",
	Bool: true,
}

The resulting value would be `"true"` if the flag is set and `"false"` if the flag is not set.

*Note that once `Bool` is set, no value* should *be passed to the flag, as the parser will not try to parse for the flag value.*

$ flags -o value1 --two

Arguments

Defining arguments on a command is also easy.

kubo.Command{
	Name: "arguments",
	Description: "a command with arguments",
	// Defines the arguments for this command
	Arguments: []kubo.Argument{
		{
 			Name: "one",
		},
		{
 			Name: "two",
		},
	},
}

The code above defines two arguments, `one` and `two`. The order in which you define the arguments matters. This is because arguments are parsed by their positions and not by their names.

$ arguments value1 value2

This will result in `one` having the value `"value1"` and `two` having the value `"value2"`.

Arguments can also have a field of `Multiple`, which causes the argument to collect multiple values.

kubo.Argument{
	Name: "two",
	Multiple: true,
}

*Note that only the last argument can have `Multiple` set.*

$ arguments value1 value2 value3 value4

This will result in `two` having the value `["value2", "value3", "value4"]`.

Contexts

The context passed in the run function is used to get the arguments and flags that were parsed from the raw arguments.

kubo.Command{
	Name: "contexts",
	Description: "a command with arguments and flags",
	Arguments: []kubo.Argument{
		{Name: "argument"},
	},
	Flags: []kubo.Flag{
		{Name: "flag"},
	},
	Run: func(ctx *kubo.Context) error {
		// Gets the argument called 'argument'
		argument, err := ctx.Argument("argument")
		if err != nil {
 			return err
		}

		// Gets the flag called 'flag'
		flag, err := ctx.Flag("flag")
		if err != nil {
			return err
		}

		fmt.Fprintf(ctx.Stdout(), "argument: %s, flag: %s\n", argument, flag)
	},
}

The context also contains the methods for `Stdin` and `Stdout`, which *should* be used to read from and write to the console. They can be configured in the app itself (which will pass these values to the context).

// Default values
app.Stdin = os.Stdin
app.Stdout = os.Stdout

When getting arguments and flags from the context, sometimes their values need to be converted to other types. For that purpose, the `kuboutil` package can be used.

// Gets the argument called 'argument' and converts it to an int
argument, err := kuboutil.Int(ctx.Argument("argument"))
if err != nil {
	return err
}

These conversion utilities automatically propagate the error from the `Argument` method.

Child commands

Commands can have child commands.

parent := &kubo.Command{
	Name: "parent",
}

child := &kubo.Command{
	Name: "child",
}

// Makes 'child' a child of the 'parent' command
parent.Add(child)

These child commands can be called by passing in their name.

$ parent child

Child commands can have flags, arguments, and even child commands of their own!

parent := &kubo.Command{
	Name: "parent",
}

child := &kubo.Command{
	Name: "child",
}

grandchild := &kubo.Command{
	Name: "grandchild",
}

// Makes 'grandchild' a child of the 'child' command
child.Add(grandchild)

// Makes 'child' a child of the 'parent' command
parent.Add(child)

They can then be called by passing in their names.

$ parent child grandchild

Help command

A help command can be generated for each command.

complex := &kubo.Command{
	Name: "complex",
	Description: "some complex command",
}

// Makes 'help' a child command of the 'complex' command
complex.Add(complex.Help())

The help command can be called using `help`.

$ complex help

Index

Constants

This section is empty.

Variables

View Source
var TabSize = 8

TabSize is the number of spaces a tab occupies.

Functions

This section is empty.

Types

type App

type App struct {
	Root *Command // root command

	Stdin  io.Reader // default is os.Stdin
	Stdout io.Writer // default is os.Stdout
}

App represents a command line app.

func NewApp

func NewApp(root *Command) *App

NewApp creates a new app with the given root command.

func (*App) Run

func (a *App) Run(args []string) error

Run runs the app with the given arguments.

type Argument

type Argument struct {
	Name string

	// Multiple is whether this argument collects multiple arguments.
	//
	// This is typically used to support a dynamic number of arguments (e.g.
	// 'command <argument1> <argument2> <arguments...>'). It should only
	// be used at the end of the argument list.
	Multiple bool
}

Argument represents an argument for a command.

type Command

type Command struct {
	Name        string
	Aliases     []string
	Description string

	Arguments []Argument // should be in order
	Flags     []Flag

	// Run runs the command.
	//
	// Any error returned is propogated and returned to the main Run function
	// of the app.
	//
	// When reading from and printing to the console, Stdin and Stdout from
	// the context is used.
	Run func(*Context) error
	// contains filtered or unexported fields
}

Command represents a command or a subcommand.

func (*Command) Add

func (cmd *Command) Add(child *Command)

Add adds a child command.

func (*Command) Help

func (cmd *Command) Help() *Command

Help returns a generated help command which prints usage details on run.

func (*Command) Usage

func (cmd *Command) Usage() string

Usage returns the usage details.

type Context

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

Context represents the runtime context of a command.

func (*Context) Argument

func (ctx *Context) Argument(name string) (string, error)

Argument returns the argument with the given name and an error if it doesn't exist.

func (*Context) ArgumentMultiple

func (ctx *Context) ArgumentMultiple(name string) ([]string, error)

ArgumentMultiple returns the argument with the given name as a collected argument and an error if it doesn't exist.

func (*Context) Flag

func (ctx *Context) Flag(name string) (string, error)

Flag returns the argument with the given name and an error if it doesn't exist.

func (*Context) Stdin

func (ctx *Context) Stdin() io.Reader

Stdin returns the stdin defined in the app.

func (*Context) Stdout

func (ctx *Context) Stdout() io.Writer

Stdout returns the stdout defined in the app.

type Flag

type Flag struct {
	Name        string
	Aliases     []string
	Description string

	// Bool is whether this flag has a value or not.
	//
	// If this is set, this flag will be used as a boolean flag (e.g.
	// 'command --flag'), which means it does not need a value after it.
	Bool bool
}

Flag represents a flag for a command.

Directories

Path Synopsis
_examples
Package kuboutil provides type conversion utilities for flags.
Package kuboutil provides type conversion utilities for flags.

Jump to

Keyboard shortcuts

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