• Stars
    star
    246
  • Rank 164,726 (Top 4 %)
  • Language
    Go
  • License
    MIT License
  • Created about 10 years ago
  • Updated over 6 years ago

Reviews

There are no reviews yet. Be the first to send feedback to the community and the maintainers!

Repository Details

A go-lang library to help build self documenting command line applications.

odin godoc Build Status Coverage Status Gitter

A note to readers:
I did my best to make this readme as comprehensive as possible but I strongly suggest reading the godocs detailed information on the internals of odin.


Installation | Usage | Examples | Contributing | In the Wild

odin

A go-lang library to help build self documenting command line applications.

odin currently supports:

  • Required Parameters
  • Typed Flag/Option Parsing
  • Flag Aliasing
  • SubCommand DSL for creating complex CLI utils

Installation

get the package with:

go get github.com/jwaldrip/odin/cli

import it with:

import "github.com/jwaldrip/odin/cli"

or using a a package manager like Goop:

# Goopfile
github.com/jwaldrip/odin #v1.4.0

Usage

Creating a new CLI | Flags | Required Parameters | Freeform Parameters | Sub Commands | Self Documentation

Creating a new CLI

cli.New(version string, description string, fn func(), params...)

Flags

Flags are optional parameters that can be specifed when running the command.

$ cmd --flag=value -g

Defining

Flags support a number of different types and can be defined by using a basic definition or pointer definition.

Basic Definitions are in the format of:

DefineTypeFlag(name string, defaultValue typedValue, usage string)

Pointer Definitions are in the format of:

var ptr TYPE
DefineTypeFlagVar(ptr, name string, defaultValue typedValue, usage string)

Supported Value Types

Value Type Basic Definition Method Pointer Defintion Method
bool DefineBoolFlag DefineBoolFlagVar
float64 DefineFloat64Flag DefineFloat64FlagVar
int DefineIntFlag DefineIntFlagVar
int64 DefineInt64Flag DefineInt64FlagVar
string DefineStringFlag DefineStringFlagVar
time.Duration DefineDurationFlag DefineDurationFlagVar
uint DefineUintFlag DefineUintFlagVar
uint64 DefineUint64Flag DefineUint64FlagVar

Flags also support aliases: aliases are always defined as a rune to limit them to one character.

AliasFlag(alias rune, flagName string)

Example

package main

import (
	"fmt"

	"github.com/jwaldrip/odin/cli"
)

// CLI is the odin CLI
var app = cli.New("0.0.1", "my cli", func(c cli.Command){
	if c.Flag("gopher").Get() == true {
		fmt.Println("IS JUST GOPHERTASTIC!!!")
	} else {
		fmt.Println("Is pretty dandy")
	}
})

func init(){
	app.DefineBoolFlag("gopher", false, "is it gophertastic?")
	app.AliasFlag('g', "gopher")
}

func main(){
	app.Start()
}
$ mycli
Is pretty dandy

$ mycli --gopher
IS JUST GOPHERTASTIC!!!

$ mycli -g
IS JUST GOPHERTASTIC!!!

Required Parameters

Defining

Commands can specify parameters that they require in the order they are passed. All parameter arguments are treated as string values.

They can be defined at CLI creation...

cli.New(version string, description string, fn func(Command), params ...string)

or at a later time...

app.DefineParams(params ...string)

Accessing

Parameters can be accessed invidually...

	cmd.Param(name string) Value

or as a ValueMap where the name is the string key of the map.

	cmd.Params() ValueMap

Freeform Parameters

Free form parameters are any parameters that remain after all parsing has completed.

To access them you can call them by their order...

cmd.Arg(0) Value

or just by getting them all as a slice

cmd.Args() ValueList

Sub Commands

Sub commands can be defined in order to create chainable, complex command line utlilities.

Defining

Sub commands have all the same defintion methods as the root level command, with one caveat; they have a Parent() method that can be used to fetch parameters and flags from further up the command chain.

mycli.DefineSubCommand(name string, description string, fn func(Command), params ...string)

Accessing Params + Flags

You would access the sub-command's flags and params just as you would a normal root level CLI.

cmd.Param("name")
cmd.Flag("name")

To access a parent commands just call:

cmd.Parent().Param("name")
cmd.Parent().Flag("name")

Flag Inheritence

In addition to accesing the parent params via the Parent() you can instruct a sub command to inherit a flag from its parent.

example:

package main

import (
   "fmt"
	"github.com/jwaldrip/odin"
)

var app = cli.New("0.0.1", "sample command", func(Command){})

func init(){
	app.DefineStringFlag("user", "", "the user")
	subcmd := app.DefineSubCommand("action", "perform an action", func(c cli.Command){
		fmt.Println("the user is:", c.Flag("user"))
		fmt.Println("the action is:", c.Param("actionName"))
	})
	subcmd.DefineParams("actionName")
	subcmd.InheritFlag("user")
}

func main(){
	app.Start()
}
$ mycmd --user=jason action hello
the user is: jason
the action is: hello

Output

Helpers

Output is possible directly on the CLI and is prefered over using fmt. Available commands map to their fmt counterparts.

method description
ErrPrint(a ...interface{}) Prints to the err output.
ErrPrintf(format string, a ...interface{}) Prints formatted to the err output.
ErrPrintln(a ...interface{}) Prints a line to the err output.
Print(a ...interface{}) Prints to the std output.
Printf(format string, a ...interface{}) Prints formatted to the std output.
Println(a ...interface{}) Prints a line to the std output.
package main

import "github.com/jwaldrip/odin/cli"

app := cli.New("1.0.0", "my app", func(c cli.Command){
  c.Println("hello world")
  c.ErrPrintln("There was an error")
} 

Custom Output

Any io.Writer can be used as an output

outbuffer := bytes.NewBufferString("")
errbuffer := bytes.NewBufferString("")
app.SetStdOut(outbuffer)
app.SetStdErr(errbuffer)

Self Documentation

Usage

Documentation is auto generated for all commands (main and sub). By Default a help flag --help and alias -h are defined on each command (unless overridden) to display usage to the end user.

Auto generated documentation for ./examples/greet-with:

$ greet-with -h
Usage:
  greet-with [options...] <greeting> <command> [arg...]

a simple tool to greet with

Options:
  -c, --color="blue"  # color the output (red, blue, green)
  -h, --help          # show help and exit
  -l, --loudly        # say loudly
  -v, --version       # show version and exit

Commands:
  to     greet a person

Version

By Default a version flag --version and alias -v are defined on the main command (unless overridden), which will display the version specified when creating a new CLI.

Version for ./examples/greet-with:

$ greet-with -v
greet-with 1.0.0

Examples

Example CLIs can be found in ./examples

In the wild

Here are some tools using Odin in the wild. Have your own you would like to plug? Submit a pull request!

Todo

  • Bash Completion
  • Zsh Completion
  • CLI Bootstrapping
  • Param Inheritence

Contributing

See CONTRIBUTING for details on how to contribute.

More Repositories

1

admiral.cr

A robust DSL for writing command line interfaces written in Crystal.
Crystal
134
star
2

terraform-coreos-user-data

CoreOS cloud config generation via Terraform variables
HCL
46
star
3

promise.cr

A Promise Implementation in Crystal
Crystal
32
star
4

git-get

Git clone that clones into a common path
Go
15
star
5

shell-table.cr

Crystal
10
star
6

mime-types-cr

MIME Types for Crystal :: A port of the Ruby MIME::Types library
Crystal
10
star
7

flatrack

A static site generator with a little sprinkle of ruby magic
Ruby
9
star
8

react-infinite-pane

Responsive infinite scroll pane for React
JavaScript
6
star
9

dotfiles

Jason Waldrip's Dev Environment
Makefile
6
star
10

crystal-sf2017

Crystal
6
star
11

stripe_rails

Ruby
5
star
12

tint

Go
3
star
13

http_cache_handler

Crystal
3
star
14

jasonwaldrip.com

My Little Website
CSS
3
star
15

graphql.cr

An implementation of GraphQL for Crystal
Crystal
3
star
16

of

A simple gem to give you n number of objects.
Ruby
3
star
17

workman

Define and run parallel workers in go
Go
2
star
18

navigable_hash

Ruby
2
star
19

modloc

Find the source location of a given module or class
Ruby
2
star
20

memory_model

A familar model construct that lives only when your app is running (Great for RSpec!)
Ruby
2
star
21

libgraphql-cr

Crystal
2
star
22

delegated_presenter

DelegatedPresenter, More info on rubydoc.info:
Ruby
1
star
23

docker-ruby-app

Shell
1
star
24

docker-mysql

Shell
1
star
25

docker-rails-app

Shell
1
star
26

docker-mariadb

Shell
1
star
27

faxfinder-override

CSS
1
star
28

docker-base

Shell
1
star
29

relay-vote

A voting app in relay.
JavaScript
1
star
30

docker-node

Shell
1
star
31

docker-host

Ruby
1
star
32

jwaldrip.github.com

1
star
33

def_cache

Ruby
1
star
34

docker-rbenv

Shell
1
star
35

node-docker-example

JavaScript
1
star
36

docker-docker

Shell
1
star
37

all_the_badges

Ruby
1
star
38

modernize-hashes

Ruby
1
star
39

carly-paige

JavaScript
1
star
40

docker-railsdev

A feature full rails development environment.
1
star
41

concerned_inheritance

Ruby
1
star
42

git-cleanremote

Clean up your remote repos
Ruby
1
star
43

pollr

Ruby
1
star
44

12f-elasticsearch

12 Factor Configurable Elasticsearch
Makefile
1
star
45

sinful-proxy

A Simple Proxy Written in Sinatra
Ruby
1
star
46

haml-flatrack

Ruby
1
star
47

homebrew-on-tap

Ruby
1
star
48

slim-flatrack

Slim for flatrack
1
star
49

12f-vault

Shell
1
star
50

keep-em-up

Ruby
1
star
51

tar.cr

Tape archives (tar) are a file format for storing a sequence of files that can be read and written in a streaming manner. This package aims to cover most variations of the format, including those produced by GNU and BSD tar tools.
Crystal
1
star