Mcli - A mininal and very powerful cli library for Go

mcli

GoDoc Go Report Card Issues GitHub release MIT License

mcli is a minimal but powerful cli library for Go. m stands for minimal and magic.

It is extremely easy to use, it makes you like writing cli programs in Go. The idea is borrowed from https://github.com/shafreeck/cortana.

Features

  1. Extremely easy to use, dead simple buf powerful API to define commands, flags and arguments.
  2. Add arbitrary level sub-command with single line code.
  3. Define your command flags and arguments inside the command processor using a simple struct tag.
  4. Set default value for flags and arguments.
  5. Read environment variables for flags and arguments.
  6. Set default value for flags and arguments.
  7. Work with slice, map out of box (of course the bool, (u)int, (u)int16, (u)int32, (u)int64, float, duration, string types are also supported).
  8. Automatic help for commands, flags and arguments.
  9. Mark commands, flags as hidden, hidden commands and flags won't be showed in help, except that when a special flag "--mcli-show-hidden" is provided.
  10. Mark flags, arguments as required, it reports error when not given.
  11. Mark flags as deprecated.
  12. Automatic suggestions like git.
  13. Compatible with the standard library's flag.FlagSet.

Usage

Work in main function:

func main() {
    var args struct {
        Name string `cli:"-n, --name, Who do you want to say to" default:"tom"`

        // This argument is required.
        Text string `cli:"#R, text, The 'message' you want to send"`
    }
    mcli.Parse(&args)
    fmt.Printf("Say to %s: %s\n", args.Name, args.Text)
}
$ go run say.go
argument is required but not given: text
USAGE:
  tt [flags] <text>

FLAGS:
  -n, --name string    Who do you want to say to (default "tom")

ARGUMENTS:
  text message (REQUIRED)    The message you want to send

exit status 2

$ go run say.go hello
Say to tom: hello

Use with sub-commands:

func main() {
    mcli.Add("cmd1", runCmd1, "An awesome command cmd1")

    mcli.AddGroup("cmd2", "This is a command group called cmd2")
    mcli.Add("cmd2 sub1", runCmd2Sub1, "Do something with cmd2 sub1")
    mcli.Add("cmd2 sub2", runCmd2Sub2, "Brief description about cmd2 sub2")

    // A sub-command can also be registered without registering the group.
    mcli.Add("group3 sub1 subsub1", runGroup3Sub1Subsub1, "Blah blah Blah")

    // This is a hidden command, it won't be showed in help,
    // except that when flag "--mcli-show-hidden" is given.
    mcli.AddHiden("secret-cmd", secretCmd, "An secret command won't be showed in help")

    mcli.Run()
}

func runCmd1() {
    var args struct {
        Branch    string `cli:"-b, --branch, Select another branch by passing in the branch name"`
        Commit    bool   `cli:"-c, --commit, Open the last commit"`
        NoBrowser bool   `cli:"-n, --no-browser, Print destination URL instead of opening the browser"`
        Projects  bool   `cli:"-p, --projects, Open repository projects"`
        Repo      string `cli:"-R, --repo, Select another repository using the '[HOST/]OWNER/REPO' format"`
        Settings  bool   `cli:"-s, --settings, Open repository settings"`
        Wiki      bool   `cli:"-w, --wiki, Open repository wiki"`

        Location  string `cli:"location, A browser location can be specified using arguments in the following format:\n- by number for issue or pull request, e.g. \"123\"; or\n- by path for opening folders and files, e.g. \"cmd/gh/main.go\""`
    }
	mcli.Parse(&args)

    // Do something
}

type Cmd2CommonArgs struct {
    Repo string `cli:"-R, --repo, Select another repository using the '[HOST/]OWNER/REPO' format"`
}

func runCmd2Sub1() {
    // Note that the flag/argument description can be seperated either
    // by a comma or spaces, and can be mixed.
    var args struct {
        Body     string `cli:"-b, --body        Supply a body. Will prompt for one otherwise."`
        BodyFile string `cli:"-F, --body-file   Read body text from 'file' (use \"-\" to read from standard input)"`
        Editor   bool   `cli:"-e, --editor,     Add body using editor"`
        Web      bool   `cli:"-w, --web,        Add body in browser"`
        CommonIssueArgs
    }
    mcli.Parse(&args)

    // Do something
}

See example_test for a more sophisticated example which mimics Github's cli command gh.

Tag syntax

Struct tag is a powerful feature in Go, mcli uses struct tag to define flags and argumens.

  • tag cli defines the name and description for flags and arguments
  • tag default optionally provides a default value to a flag or argument
  • tag env tells Parse to lookup environment variables when user doesn't provide a value

The syntax is

/* cli tag, only Name is required.
 * Short name and long name are both optional, but at least one must be given.
 * See below for details about Modifiers.
 * e.g.
 * - `cli:"-c, Open the last commit"`
 * - `cli:"#R, -b, --branch, Select another branch by passing in the branch name"`
 * - `cli:"--an-obvious-flag-dont-need-description"`
 */
CliTag           <-  ( Modifiers ',' Space? )? Name ( ( ',' | Space ) Description )?
Modifiers        <-  '#' [DHR]+
Name             <-  ( ShortName LongName? ) | LongName
Description      <-  ( ![\r\n] . )*

/* default value tag, optional.
 * e.g.
 * - `default:"1.5s"` // duration
 * - `default:"true"` // bool
 */
DefaultValueTag  <-  ( ![\r\n] . )*

/* env tag, optional.
 * Multiple environment names can be specified.
 * e.g.
 * - `env:"SOME_ENV"`
 * - `env:"ANOTHER_ENV_1, ANOTHER_ENV_2"`
 */
EnvTag           <-  ( EnvName ',' Space? )* EnvName

Modifiers

Modifier represents an option to a flag, it sets the flag to be deprecated, hidden, or required. In a cli tag, modifiers appears as the first segment, starting with a # character.

Fow now the following modifiers are available:

  • D - marks a flag or argument as deprecated, "DEPRECATED" will be showed in help
  • R - marks a flag or argument as required, "REQUIRED" will be showed in help
  • H - marks a flag as hidden, see below for more about hidden flags

Hidden flags won't be showed in help, except that when a special flag "--mcli-show-hidden" is provided.

Modifier H shall not be used for an argument, else it panics. An argument must be showed in help to tell user how to use the program correctly.

Some modifiers cannot be used together, else it panics, e.g.

  • H & R - a required flag must be showed in help to tell user to set it
  • D & R - a required flag must not be deprecated, it does not make sense and make user confusing

Compatibility with package flag

Parse returns a *flag.FlagSet if success, all defined flags are available with the flag set, including both short and long names.

Note that there is a little difference with flag package, while the flag package requires command line flags must present before arguments, and arguments can be accessed using flag.Arg(i), this library doesn't require that, the order that user pass flags and arguments doesn't matter. Arguments should be defined in the struct given to Parse, command line arguments will be set to the struct. As a bonus, you can use slice and map arguments, it just works.

When command line arguments are given before flags, calling FlagSet.Arg(i) won't get the expected arguments.

Performance

Well, definitely command line parsing won't be your hot path, performance is not a main consideration for this library, we always want simpler API and better usage instruction for end-users. (This does not mean the library has poor performance.)

Similar Resources

TScli - a very simple terminal-based client for TSWeb online judge

TScli TScli - a very simple terminal-based client for TSWeb online judge. It supports submitting problems and receiving feedback on them. Installation

Oct 24, 2021

Syno-cli - Synology unofficial API CLI and library

Synology CLI Unofficial wrapper over Synology API in Go. Focus on administrative

Jan 6, 2023

A fast and powerful alternative to grep

sift A fast and powerful open source alternative to grep. Features sift has a slightly different focus than most other grep alternatives. Code search,

Jan 3, 2023

🚀 Platform providing a powerful and fast public script parsing API dedicated to the Skript community.

SkriptMC-Parser is currently a prototype in the early stages of development of a system that allows the Skript community to test their scripts via a public API for potential errors or warnings. This is a quick and easy way to check your scripts without having to set up a Spigot server on your environment.

Mar 3, 2022

CLI to run a docker image with R. CLI built using cobra library in go.

CLI  to run a docker image with R. CLI built using cobra library in go.

BlueBeak Installation Guide Task 1: Building the CLI The directory structure looks like Fastest process: 1)cd into bbtools 2)cd into bbtools/bin 3)I h

Dec 20, 2021

`tmax` is a powerful tool to help you get terminal cmd directly.

`tmax`  is a powerful tool to help you get terminal cmd directly.

The positioning of tmax is a command line tool with a little artificial intelligence. If you frequently deal with the terminal daily, tmax will greatly improve your work efficiency.

Oct 15, 2022

Building powerful interactive prompts in Go, inspired by python-prompt-toolkit.

Building powerful interactive prompts in Go, inspired by python-prompt-toolkit.

go-prompt A library for building powerful interactive prompts inspired by python-prompt-toolkit, making it easier to build cross-platform command line

Jan 3, 2023

A powerful little TUI framework 🏗

A powerful little TUI framework 🏗

Bubble Tea The fun, functional and stateful way to build terminal apps. A Go framework based on The Elm Architecture. Bubble Tea is well-suited for si

Dec 27, 2022

A lightweight but powerful OCR tool.

A lightweight but powerful OCR tool.

这个项目是什么? LOCR(Lightweight OCR)是一款轻量级的文字识别工具, 结合第三方截图工具, 可以快速的对图片文字进行识别。 为什么有这个项目 在日常学习的工作中, 难免会遇到一些文字的复制粘贴任务。但由于一些限制,我们无法复制想要的文字,只能一个字一个字的敲出来。而随着近几年OC

Nov 1, 2022
Related tags
Go-Suit is a very very wacky version of a bash terminal but in go, however with a little twitst

Go-Suit Go-Suit is a very very wacky version of a bash terminal but in go, however with a little twitst languages -> Go-Lang packages Third Party -> g

May 19, 2022
A very simple note-taking CLI you can use from the terminal that uses a SQLite DB to persist, and query, notes.

Note Logger Summary A very simple note-taking CLI you can use from the terminal that uses a SQLite DB to persist, and query, notes. Building/Installin

Apr 14, 2022
A very basic cli keyring tool to use accross various OS.

A very basic cli keyring tool to use accross various OS.

Dec 14, 2022
A powerful modern CLI and SHELL
A powerful modern CLI and SHELL

Grumble - A powerful modern CLI and SHELL There are a handful of powerful go CLI libraries available (spf13/cobra, urfave/cli). However sometimes an i

Dec 30, 2021
A powerful cli tool to implement gin annotation ⭐
A powerful cli tool to implement gin annotation ⭐

gin-annotation A powerful cli tool to implement gin annotation Chinese Document Features Using code generating technology by operating golang AST Rout

Mar 24, 2022
Powerful CLI written in GO to generate projects in various technologies
Powerful CLI written in GO to generate projects in various technologies

Barca CLI is a project generator written in GO and its purpose is to build and configure HTTP servers, web proxy, SPA/PWA, Blog and custom landing page. It's easy, fast and productive.

Aug 26, 2022
A very simple library for interactively selecting an option on a terminal
A very simple library for interactively selecting an option on a terminal

go-choice A very simple library for interactively selecting an option on a terminal Usage package main import ( "fmt" "github.com/TwiN/go-ch

Dec 30, 2021
Sloc, Cloc and Code: scc is a very fast accurate code counter with complexity calculations and COCOMO estimates written in pure Go
Sloc, Cloc and Code: scc is a very fast accurate code counter with complexity calculations and COCOMO estimates written in pure Go

Sloc Cloc and Code (scc) A tool similar to cloc, sloccount and tokei. For counting physical the lines of code, blank lines, comment lines, and physica

Jan 8, 2023
Flag is a simple but powerful command line option parsing library for Go support infinite level subcommand

Flag Flag is a simple but powerful commandline flag parsing library for Go. Documentation Documentation can be found at Godoc Supported features bool

Sep 26, 2022
A very simple command line tool for downloading YouTube videos.

GoTube Overview This repository contains a single-file implementation of YouTube video downloader written in Go. It does not require any third-party p

Dec 20, 2022