GithubHelp home page GithubHelp logo

cjrd / cli Goto Github PK

View Code? Open in Web Editor NEW

This project forked from mkideal/cli

0.0 2.0 0.0 4.92 MB

CLI - A package for building command line app with go

License: MIT License

Go 98.93% Shell 1.07%

cli's Introduction

Command line interface

License Travis branch Coverage Status Go Report Card GoDoc

Screenshot

screenshot2

Key features

  • Lightweight and easy to use.
  • Defines flag by tag, e.g. flag name(short or/and long), description, default value, password, prompt and so on.
  • Type safety.
  • Output looks very nice.
  • Supports custom Validator.
  • Supports slice and map as a flag.
  • Supports any type as a flag field which implements cli.Decoder interface.
  • Supports any type as a flag field which uses FlagParser.
  • Suggestions for command.(e.g. hl => help, "veron" => "version").
  • Supports default value for flag, even expression about env variable(e.g. dft:"$HOME/dev").
  • Supports editor like git commit command.(See example 21 and 22)

Getting started

package main

import (
	"github.com/mkideal/cli"
)

type argT struct {
	cli.Helper
	Name string `cli:"name" usage:"your name" dft:"world"`
	Age  uint8  `cli:"a,age" usage:"your age" dft:"100"`
}

func main() {
	cli.Run(&argT{}, func(ctx *cli.Context) error {
		argv := ctx.Argv().(*argT)
		ctx.String("Hello, %s! Your age is %d?\n", argv.Name, argv.Age)
		return nil
	})
}

Type these in terminal

$> go build -o hello
$> ./hello
Hello, world! Your age is 100?
$> ./hello --name=clipher -a 9
Hello, clipher! Your age is 9?
$> ./hello -h

Try

$> ./hello -a 256

API documentation

See godoc

Examples

See _examples, example_*test.go files or sites listed below:

Projects which uses CLI

  • onepw - A lightweight tool for managing passwords
  • rqlite CLI - A command line tool for connecting to a rqlited node

Argument object of cli

Supported tags in argument object of cli:

  • cli - supports short format and long format, e,g, -p, --port
  • pw - similar to cli, but used to input password
  • edit - input from editor(like git commit)
  • usage - description of flag
  • dft - default value, supports constant value, env variable, and even expression
  • prompt - prompt string
  • parser - builtin parsers: json, jsonfile, supports custom parsers.
  • name - placeholder for flag
  • sep - string for seperate key/value pair of map(default =).

Supported types of flag

  • All basic types: int,uint,...,float32,float64,string,bool
  • Slice of basic type: []int, []uint, []string,...
  • Map of basic type: map[uint]int, map[string]string,...
  • Any type which implments cli.Decoder
  • Any type which uses correct parser(json,jsonfile, or your registered parser)

AutoHelper

// AutoHelper represents interface for showing help information automaticly
AutoHelper interface {
	AutoHelp() bool
}

If your argT implments AutoHelper, it will show help if argT.AutoHelp return true.

For example:

package main

import "github.com/mkideal/cli"

type argT struct {
	Help bool `cli:"h,help" usage:"show help"`
}

func (argv *argT) AutoHelp() bool {
	return argv.Help
}

func main() {
	cli.Run(&argT{}, func(ctx *cli.Context) error {
		return nil
	})
}

Build and run:

go build -o app
./app -h

This will print help information.

For convenience, builtin type cli.Helper implements cli.AutoHelper.

So, you just need to inherit it!

type argT struct {
	cli.Helper
}

Validator - validate argument

// Validator validates flag before running command
type Validator interface {
	Validate(*Context) error
}

Context.IsSet

Determin whether the flag is set

Hooks

  • OnRootPrepareError - Function of root command which should be invoked if occur error while prepare period
  • OnBefore - Function which should be invoked before Fn
  • OnRootBefore - Function of root command which should be invoked before Fn
  • OnRootAfter - Function of root command which should be invoked after Fn
  • OnAfter - Function which should be invoked after Fn

Invoked sequence: OnRootPrepareError => OnBefore => OnRootBefore => Fn => OnRootAfter => OnAfter

Don't invoke any hook function if NoHook property of command is true, e.g.

var helpCmd = &cli.Command{
	Name: "help",
	Desc: "balabala...",
	NoHook: true,
	Fn: func(ctx *cli.Context) error { ... },
}

Command tree

// Tree creates a CommandTree
func Tree(cmd *Command, forest ...*CommandTree) *CommandTree

// Root registers forest for root and return root
func Root(root *Command, forest ...*CommandTree) *Command
func log(ctx *cli.Context) error {
	ctx.String("path: `%s`\n", ctx.Path())
	return nil
}
var (
	cmd1  = &cli.Command{Name: "cmd1", Fn: log}
	cmd11 = &cli.Command{Name: "cmd11", Fn: log}
	cmd12 = &cli.Command{Name: "cmd12", Fn: log}

	cmd2   = &cli.Command{Name: "cmd2", Fn: log}
	cmd21  = &cli.Command{Name: "cmd21", Fn: log}
	cmd22  = &cli.Command{Name: "cmd22", Fn: log}
	cmd221 = &cli.Command{Name: "cmd221", Fn: log}
	cmd222 = &cli.Command{Name: "cmd222", Fn: log}
	cmd223 = &cli.Command{Name: "cmd223", Fn: log}
)

root := cli.Root(
	&cli.Command{Name: "tree"},
	cli.Tree(cmd1,
		cli.Tree(cmd11),
		cli.Tree(cmd12),
	),
	cli.Tree(cmd2,
		cli.Tree(cmd21),
		cli.Tree(cmd22,
			cli.Tree(cmd221),
			cli.Tree(cmd222),
			cli.Tree(cmd223),
		),
	),
)

HTTP router

Context implements ServeHTTP method.

func (ctx *Context) ServeHTTP(w http.ResponseWriter, r *http.Request)

Command has two http properties: HTTPMethods and HTTPRouters.

HTTPRouters []string
HTTPMethods []string

Each command have one default router: slashes-separated router path of command. e.g. $app sub1 sub11 has default router /sub1/sub11. The HTTPRouters property will add some new extra routers, it would'nt replace the default router. The HTTPMethods is a string array. It will handle any method if HTTPMethods is empty.

var help = &cli.Command{
	Name:        "help",
	Desc:        "display help",
	CanSubRoute: true,
	HTTPRouters: []string{"/v1/help", "/v2/help"},
	HTTPMethods: []string{"GET", "POST"},

	Fn: cli.HelpCommandFn,
}

NOTE: Must call root command's RegisterHTTP method if you want to use custom HTTPRouters

...
if err := ctx.Command().Root().RegisterHTTP(ctx); err != nil {
	return err
}
return http.ListenAndServe(addr, ctx.Command().Root())
...

cli's People

Contributors

mkideal avatar wangshijin avatar

Watchers

 avatar  avatar

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.