Golang library with POSIX-compliant command-line UI (CLI) and Hierarchical-configuration. Better substitute for stdlib flag.

cmdr

Build Status Go GitHub tag (latest SemVer) GoDoc FOSSA Status go.dev Go Report Card codecov Coverage Status Mentioned in Awesome Go

cmdr is a POSIX-compliant, command-line UI (CLI) library in Golang. It is a getopt-like parser of command-line options, be compatible with the getopt_long command line UI, which is an extension of the syntax recommended by POSIX.

We made many enhancements beyond the standard library flag.

There is a full Options Store (configurations) for your hierarchical configuration dataset too.

The .netCore version Cmdr.Core is available now. And, a cxx version cmdr-cxx is comming soon.

ee99d078e2f7

To review the image frames, go surfing at https://github.com/hedzr/cmdr/issues/1#issuecomment-567779978

Table of Contents

Youtube - 李宗盛2013最新單曲 山丘 官方完整版音檔 / Jonathan Lee - Hill CHT + ENU

Import

The better choice is importing with go-modules enabled:

import "github.com/hedzr/cmdr"

See our extras:

News

  • docs (WIP):

  • v1.7.42

    • routine maintenance
  • v1.7.41

    • fixed: flags after tail-args might not be recognized. NOTE: in app cmd1 cmd2 --a file1 file2 --c, --c might be ignored.
    • updated: log+logex
  • v1.7.40

    • update log/logex to fix the wrong caller skips for logrus
  • v1.7.39

    • update log/logex to fix the wrong caller skips for zap/sugar, and ensure debug mode work
  • v1.7.38

    • improved the usage line in help screen
  • v1.7.37

    • added WithAlterLocations(...)
    • broken: LoadConfigFiles returns 3 values now
  • v1.7.36

    • fixed GetSectionFrom() now work for []interface{}. such as:
      inform:
       - name: xx
         url: xx
       - name: yy
         url: yy
    • print error detail while loading and merging child config file failed
  • v1.7.35

    • update deps with log/logex fixed
  • v1.7.33

    • added project-level files
    • update deps
  • v1.7.32

    • added WithWarnForUnknownCommand
    • fixed bugs
  • v1.7.31

    • added alternative config file and folder: $CURRDIR/.<appname>.yml & $CURRDIR/.<appname>/*.yml - Using WithSearchAlterConfigFiles(true)
    • configurable auto-sub-folder-name conf.d: WithConfigSubDirAutoName(string)
  • v1.7.30

    • added docker hub image for examples/fluent
  • v1.7.29

    • added docker image for examples/fluent
    • added cmdr.InDockerEnv
    • small fixes
  • v1.7.28

    • added cmdr.NewLoggerConfigWith for better smoothing transfer cmdr internal status to log/logex.
    • added cmdr.InDevelopingTime
    • better output in PassThruChar(--) detected
    • doc and added SetTraceMode/SetDebugMode
  • v1.7.27

    • added: WithHelpScreenHooks, GetRemainArgs, ...
    • improved: WithPagerEnabled, InTesting, ...
    • fixed: missed initializing for logger-level in Option Store sometimes.
    • tests
  • v1.7.25

    • New feature: loading command definition from config file
    • fixed bugs
  • v1.7.23

    • A new feature: the builtin pluggable cmdr-addon/plugin. make build && bin/fluent --help && bin/fluent dx
    • added: WithPluginLocations(locations...), WithExtensionsLocations(locations...)
  • v1.7.21

  • v1.7.11

    • update: new log.Logger instance in log.GetLogger
    • fixed: ReadPassword in windows
  • v1.7.10

    • fixed: too much empty lines in help screen
  • v1.7.9

    • right align multi-lines desc string in help screen
    • added new envvars: HELP, NO_COLOR (HELP=1 app some sub cmd == app some sub cmd --help)
  • v1.7.8

    • tabStop in help screen will be autosize now
    • deprecated at next minor release (v1.8+): WithHelpTabStop()
    • deprecated at next minor release (v1.8+): plugins/daemon
    • BREAK: some two methods in the interface Painter has been changed.
  • v1.7.7

    • update deps to improve logging supports
    • deprecated: WithLogex(), as its replacement, WithLogx() has a better generic logging interface (hedzr/log.Logger)
  • v1.7.6:

    • using hedzr/log and remove other logging dependencies.
    • added WithLogx(logger): integrating with your logger (via log.Logger interface)
  • v1.7.5:

    • move some helper function to tool sub-package
  • For more information to refer to CHANGELOG

Features

Features.md

Old README.md: README.old.md

About the Docker build

Here is a docker build for cmdr/examples/fluent so that you can run it without go building or downloading the release files:

# from Docker Hub:
$ docker run -it --rm hedzr/cmdr-fluent
$ docker run -it --rm hedzr/cmdr-fluent --help

# from Github Packages (please following the guide of GitHub Packages Site):
$ docker run -it --rm docker.pkg.github.com/hedzr/cmdr/cmdr-fluent
$ docker run -it --rm docker.pkg.github.com/hedzr/cmdr/cmdr-fluent --help

For Developer

For Developer

Examples

  1. short
    simple codes with structured data style.

  2. demo
    normal demo with external config files.

  3. wget-demo
    partial-covered for GNU wget.

  4. fluent
    demostrates how to define your command-ui with the fluent api style.

  5. ffmain

    a demo to show you how to migrate from go flag smoothly.

  6. cmdr-http2
    http2 server with daemon supports, graceful shutdown

  7. awesome-tool
    awesome-tool is a cli app that fetch the repo stars and generate a markdown summary, accordingly with most of awesome-xxx list in github (such as awesome-go).

See Also the examples index: Examples.md (zh-cn TODO: Examples.zh-cn.md)

Uses

Contrib

Feel free to issue me bug reports and fixes. Many thanks to all contributors.

Thanks to JODL

JODL (JetBrains OpenSource Development License) is good:

goland jetbrains

License

MIT

FOSSA Status

Owner
hz
#devops #agile #golang #kotlin #dotnetcore #modern-cxx #android #flutter #shell
hz
Comments
  • 双引号的问题

    双引号的问题

    
    const (
    	versionName = "0.0.1"
    	appName     = "cmdrtest"
    )
    
    func buildRootCmd() (rootCmd *cmdr.RootCommand) {
    
    	root := cmdr.Root(appName, versionName)
    
    	root.NewFlag(cmdr.OptFlagTypeString).
    		Titles("o", "output-file").
    		Description("output file", "").
    		DefaultValue("", "").
    		OnSet(func(keyPath string, value interface{}) {
    			fmt.Println(keyPath)
    			os.Exit(0)
    			return
    		})
    
    	rootCmd = root.RootCommand()
    
    	return
    }
    
    func main() {
    
    	rootCmd := buildRootCmd()
    	if err := cmdr.Exec(rootCmd,
    		cmdr.WithBuiltinCommands(false, false, false, false, false),
    	); err != nil {
    		panic(err)
    	}
    }
    

    编译完如果 cmdrtest -o "" 就会 panic

    panic: runtime error: index out of range [0] with length 0
    
    goroutine 1 [running]:
    github.com/hedzr/cmdr.(*ptpkg).preprocessPkg(0xc0002c6000, 0xc00002a0c0, 0x3, 0x4, 0x0, 0x5)
            $GOPATH/pkg/mod/github.com/hedzr/[email protected]/ptpkg.go:170 +0x33a
    github.com/hedzr/cmdr.(*ptpkg).processTypeString(0xc0002c6000, 0xc00002a0c0, 0x3, 0x4, 0xffffffffffffffff, 0xc0000220d1)
            $GOPATH/pkg/mod/github.com/hedzr/[email protected]/ptpkg.go:280 +0x6e
    github.com/hedzr/cmdr.(*ptpkg).tryExtractingValue(0xc0002c6000, 0xc00002a0c0, 0x3, 0x4, 0xc0002784e8, 0x9e509f)
            $GOPATH/pkg/mod/github.com/hedzr/[email protected]/ptpkg.go:100 +0x112
    github.com/hedzr/cmdr.(*ExecWorker).flagsMatched(0xc0002b8120, 0xc0002c6000, 0xc0002981c0, 0xc00002a0c0, 0x3, 0x4, 0x9c8ede, 0xc0002c6000, 0xc0002c6028)
            $GOPATH/pkg/mod/github.com/hedzr/[email protected]/exec_match.go:133 +0x5f
    github.com/hedzr/cmdr.(*ExecWorker).flagsMatching(0xc0002b8120, 0xc0002c6000, 0xc0002981c0, 0xc00022be48, 0xc00002a0c0, 0x3, 0x4, 0x0, 0x0, 0x0)
            $GOPATH/pkg/mod/github.com/hedzr/[email protected]/exec_match.go:99 +0x3ce
    github.com/hedzr/cmdr.(*ExecWorker).xxTestCmd(0xc0002b8120, 0xc0002c6000, 0xc00022be48, 0xc0002981c0, 0xc00002a0c0, 0x3, 0x4, 0x0, 0x1, 0xc000134060)
            $GOPATH/pkg/mod/github.com/hedzr/[email protected]/exec.go:244 +0x15c
    github.com/hedzr/cmdr.(*ExecWorker).InternalExecFor(0xc0002b8120, 0xc0002981c0, 0xc00002a0c0, 0x3, 0x4, 0x0, 0x0)
            $GOPATH/pkg/mod/github.com/hedzr/[email protected]/exec.go:194 +0x2da
    github.com/hedzr/cmdr.Exec(0xc0002981c0, 0xc00022bf38, 0x1, 0x1, 0x43e6c1, 0x1081ec0)
            $GOPATH/pkg/mod/github.com/hedzr/[email protected]/exec.go:88 +0x9e
    main.main()
    
    

    单引号的话就没问题~

  • Add license scan report and status

    Add license scan report and status

    Your FOSSA integration was successful! Attached in this PR is a badge and license report to track scan status in your README.

    Below are docs for integrating FOSSA license checks into your CI:

  • ToggleGroup & flag.Args()

    ToggleGroup & flag.Args()

    Hi, Maybe I'm missing what the feature ToggleGroup is but I thought that by setting a values like this would make the values mutually exclusive

                    {
                            BaseOpt: cmdr.BaseOpt{
                                    Short:       "L",
                                    Full:        "list",
                                    Description: "list command",
                                    Group:       cStartup,
                            },
                            DefaultValue: false,
                            ToggleGroup:  "target",
                    },
                    {
                            BaseOpt: cmdr.BaseOpt{
                                    Short:       "G",
                                    Full:        "grain",
                                    Description: "grain command",
                                    Group:       cStartup,
                            },
                            DefaultValue: false,
                            ToggleGroup:  "target",
                    },
    

    but I can run both commands and I don't get an error.

    Also, I would have wanted to have the option to get the remaining args that were not parsed just as in the official flag package.

  • 禁用 help 之后

    禁用 help 之后

    谢谢你的作品,很棒的库,流式调用链相当舒服,使用中遇到了一个疑问:

    const (
    	versionName = "0.0.1"
    	appName     = "cmdrtest"
    )
    
    func buildRootCmd() (rootCmd *cmdr.RootCommand) {
    
    	root := cmdr.Root(appName, versionName)
    
    	// root.NewSubCommand().
    	// 	Titles("h", "help").
    	// 	Description("show help screen", "").
    	// 	Action(func(cmd *cmdr.Command, args []string) (err error) {
    	// 		fmt.Println("this is help text")
    	// 		os.Exit(0)
    	// 		return
    	// 	})
    
    	// root.NewFlag(cmdr.OptFlagTypeBool).
    	// 	Titles("h", "help").
    	// 	Description("show help screen", "").
    	// 	DefaultValue(false, "").
    	// 	OnSet(func(keyPath string, value interface{}) {
    	// 		fmt.Println("this is help text")
    	// 		os.Exit(0)
    	// 		return
    	// 	})
    
    	rootCmd = root.RootCommand()
    
    	return
    }
    func main() {
    
    	// To disable internal commands and flags, uncomment the following codes
    	cmdr.EnableVersionCommands = false
    	cmdr.EnableVerboseCommands = false
    	cmdr.EnableHelpCommands = false
    	cmdr.EnableGenerateCommands = false
    	cmdr.EnableCmdrCommands = false
    
    	rootCmd := buildRootCmd()
    	if err := cmdr.Exec(rootCmd); err != nil {
    		panic(err)
    	}
    }
    

    这个时候 -h 或者 --help 似乎是无效的 (Unknown flag: -h)

    但是直接运行会默认输出 usage,最后一行仍然会是:

    Type '-h' or '--help' to get command help screen.

    如果想要实现它,用 NewSubCommand 的话会不能带 - 符号,就和最后一行的输出相矛盾了。此时该用 NewFlag(cmdr.OptFlagTypeBool)OnSet 吗?但总感觉它应该是 Command 范畴,因为可能需要实现 go help build 这种效果

  • Gallery

    Gallery

    wget-demo app

    image

    demo app

    image

    man page

    # generate man pages to `./man1`
    mkdir man1 && bin/demo gen man
    # move them to system location:
    mv ./man1/* /usr/local/man/man1/
    # And, query them via `man 1 demo` or `man 1 demo server`:
    man demo-generate
    

    And: image

Substitute environment variables from command line for template driven configuration files.
Substitute  environment variables from command line for template driven configuration files.

Substitute Variables (subvars) is a small utility which provides a way to render any Go templates from command line recognizing the object being passed in and drawing attributes from the object to create wanted text. It is very useful for template driven configuration files.

Jun 3, 2022
Drop-in replacement for Go's flag package, implementing POSIX/GNU-style --flags.

Description pflag is a drop-in replacement for Go's flag package, implementing POSIX/GNU-style --flags. pflag is compatible with the GNU extensions to

Dec 30, 2022
Go binding configuration and command flag made easy✨✨
Go binding configuration and command flag made easy✨✨

✨ Binding configuration and command flag made easy! ✨ You can use multiple keys tag to simplify the look like this (supported feature**): // single ta

Sep 18, 2022
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
CONTRIBUTIONS ONLY: A Go (golang) command line and flag parser

CONTRIBUTIONS ONLY What does this mean? I do not have time to fix issues myself. The only way fixes or new features will be added is by people submitt

Dec 29, 2022
A collection of CLI argument types for the Go `flag` package.

flagvar A collection of CLI argument types for the flag package. import "github.com/sgreben/flagvar" Or just copy & paste what you need. It's public d

Sep 26, 2022
A golang library for building interactive prompts with full support for windows and posix terminals.
A golang library for building interactive prompts with full support for windows and posix terminals.

Survey A library for building interactive prompts on terminals supporting ANSI escape sequences. package main import ( "fmt" "github.com/Alec

Jan 6, 2023
hierarchical progress bars in terminal on steroids
hierarchical progress bars in terminal on steroids

Echelon - hierarchical progress in terminals Cross-platform library to organize logs in a hierarchical structure. Here is an example how it looks for

Nov 26, 2022
The standard library flag package with its missing features

cmd Package cmd is a minimalistic library that enables easy sub commands with the standard flag library. This library extends the standard library fla

Oct 4, 2022
A command line tool that builds and (re)starts your web application everytime you save a Go or template fileA command line tool that builds and (re)starts your web application everytime you save a Go or template file

# Fresh Fresh is a command line tool that builds and (re)starts your web application everytime you save a Go or template file. If the web framework yo

Nov 22, 2021
Utility CLI to convert Spring Boot Yaml configuration into external configuration

boot-config-export Utility CLI to convert Spring Boot Yaml configuration into external configuration (as environment variables). The variables are tra

Nov 17, 2021
Argparse for golang. Just because `flag` sucks

Golang argparse Let's be honest -- Go's standard command line arguments parser flag terribly sucks. It cannot come anywhere close to the Python's argp

Dec 28, 2022
A simple posix shell created in golang

Fox-Shell Description Fox-Shell is a simple posix shell builded with golang Features - chdir works perfectly - mkdir works, but need bug fix To-Do Li

Dec 13, 2021
An open-source GitLab command line tool bringing GitLab's cool features to your command line
An open-source GitLab command line tool bringing GitLab's cool features to your command line

GLab is an open source GitLab CLI tool bringing GitLab to your terminal next to where you are already working with git and your code without switching

Dec 30, 2022
A command line tool to prompt for a value to be included in another command line.

readval is a command line tool which is designed for one specific purpose—to prompt for a value to be included in another command line. readval prints

Dec 22, 2021
git-xargs is a command-line tool (CLI) for making updates across multiple Github repositories with a single command.
git-xargs is a command-line tool (CLI) for making updates across multiple Github repositories with a single command.

Table of contents Introduction Reference Contributing Introduction Overview git-xargs is a command-line tool (CLI) for making updates across multiple

Dec 31, 2022
git-xargs is a command-line tool (CLI) for making updates across multiple GitHub repositories with a single command
git-xargs is a command-line tool (CLI) for making updates across multiple GitHub repositories with a single command

git-xargs is a command-line tool (CLI) for making updates across multiple GitHub repositories with a single command. You give git-xargs:

Feb 5, 2022
A simple library to build golang command line (cli / cmd)apps

A simple library to build golang command line (cli / cmd)apps

Jan 11, 2022
Watcher - A simple command line app to watch files in a directory for changes and run a command when files change!

Watcher - Develop your programs easily Watcher watches all the files present in the directory it is run from of the directory that is specified while

Mar 27, 2022