Permits a Go application to implement subcommands support similar to what is supported by the 'go' tool.

subcommands golang library

This package permits a Go application to implement subcommands support similar to what is supported by the 'go' tool.

The library is designed so that the test cases can run concurrently. Using global flags variables is discouraged to keep your program testable concurrently.

The intended command is found via heuristic search;

  • exact match
  • unique prefix, e.g. lo will run longcommand as long as there's no command with the same prefix.
  • case insensitivity; for those weird enough to use Upper Cased Commands.
  • levenshtein distance; where longcmmand or longcmomand will properly trigger longcommand.

PkgGoDev Coverage Status

Examples

  • See sample-simple for a barebone sample skeleton usable as-is.
  • See sample-complex for a complex sample using advanced features.
  • See module subcommands/subcommandstest for tools to help testing an application using subcommands. One of the main benefit is t.Parallel() just works, because subcommands help wrapping global variables.
Owner
M-A
Mostly write state machines. My GitHub contribution graph is a lie: that's what automation is all about, right?
M-A
Comments
  • Add first-class support for documented environment variables.

    Add first-class support for documented environment variables.

    This allows applications to declare, document, and add default values for environment variables that they're sensitive too.

    Includes support for the recently-added "advanced" feature to allow documentation of esoteric environment variables without cluttering the help output.

  • Add the concept of

    Add the concept of "advanced" commands.

    This allows a program to define many subcommands, but have them omitted from the default help view, to keep the high-level subcommands directly visible to the user.

  • Allow GetFlags to return nil.

    Allow GetFlags to return nil.

    This allows individual subcommands to indicate that they would like to take full control of the 'args' parsing. This is useful for when 'flag' is insufficiently groovy, or when writing wrapper programs where some or even none of the flags need to be interpreted by the wrapper itself (e.g. merely passed through to the target program).

    Without this, invocations such as prog subcommand -flag will fail because -flag would be interpreted as an 'unknown flag'.

  • Data race is detected at flag.Usage modification

    Data race is detected at flag.Usage modification

    When running tests in parallel, sometimes race detector (go test -race) fails at the following line. https://github.com/maruel/subcommands/blob/4b22346b79dd1f53c945985bb1243cc141f70aa7/subcommands.go#L334

    Example: https://logs.chromium.org/logs/infra/buildbucket/cr-buildbucket.appspot.com/8856422888007344336/+/u/go_test_-race/stdout#L6231_51

  • Subcommands should have first-class support for errors

    Subcommands should have first-class support for errors

    Currently, the CommandRun.Run method returns an int. I suspect this is because the original design wanted commands to decide their exit code, but it causes some unfortunate boilerplate: most commands will end up with an error value, and have to manually print it out and decide some code to return, adding a few lines on every return statement.

    Some people mitigate some awkwardness by introducing a helper function to call, which translates an error into an int (and prints non-nil errors), but that has other awkwardness in that you have to remember to use that in every return statement in every command's top-level Run method.

    Instead of a helper function that you have to call, I recently introduced a wrapper type in my project which allows commands to implement a Run method which returns an error, and then does the error check and translation to integer code in one place. (It also fixes the lack of context.) It works for my project, but ideally this convenience would be pushed into this library too for everyone to share.

    I would suggest instead to have the Run method return an error instead of an int; I suspect most commands would be content with exiting with 0 on a nil error, and a 1 on an arbitrary error. For those (few) commands which want to control their exit code, we can introduce an extra type like:

    type ExitCode struct {
       Err error
       Code int
    }
    

    Directly changing the CommandRun function would be a breaking change, and I'm not sure how amenable people are to that. (With Go modules, it should be slightly easier to avoid breaking people? I think...) But an obvious second choice would be to deprecate the old type and make a new one which returns an error (and, ideally, takes a context too to solve https://github.com/maruel/subcommands/issues/4).

  • Subcommands should have first-class support for Context.

    Subcommands should have first-class support for Context.

    Currently, this package is completely Context-unaware. Context is, however, the sort of thing the top-level main method may want to establish or control from outside the scope of the subcommand (e.g., for signal-based cancellation, factory installation, etc.).

    Some solutions, such as https://godoc.org/github.com/luci/luci-go/common/cli, operate by bolting this support onto subcommands. This results in some pretty wonky code, weird inversions, and the creation (or discarding) of multiple Context.

    A better solution would be to have subcommands.Run accept a Context and forward it to its CommandRun.

  • proposal: read arguments from a file

    proposal: read arguments from a file

    Proposal:

    Add DefaultApplication.AllowArgsInFIle or something like that (name suggestions are welcome). If true

    • extra text is printed in usage that subcommand and its arguments can be passed through a file
    • if first argument starts with @, treat the rest of the argument as a path to the file that contains command line arguments. There must be no other arguments besides @file.

    This is needed on Windows where the command line length limit is low.

    @maruel @vadimsht

Fully featured Go (golang) command line option parser with built-in auto-completion support.

go-getoptions Go option parser inspired on the flexibility of Perl’s GetOpt::Long. Table of Contents Quick overview Examples Simple script Program wit

Dec 14, 2022
Idiomatic Go input parsing with subcommands, positional values, and flags at any position. No required project or package layout and no external dependencies.
Idiomatic Go input parsing with subcommands, positional values, and flags at any position. No required project or package layout and no external dependencies.

Sensible and fast command-line flag parsing with excellent support for subcommands and positional values. Flags can be at any position. Flaggy has no

Jan 1, 2023
CLI subcommands for Go

command command is a tiny package that helps you to add cli subcommands to your Go program with no effort, and prints a pretty guide if needed. Usage:

Jul 13, 2021
A simple way for CLI command to have many subcommands

subcommands This is a modified fork of google/subcommands that uses lucasepe/pflag Subcommands is a Go package that implements a simple way for a sing

Oct 12, 2021
Build for all gccgo-supported platforms by default, disable those which you don't want (bagop with CGo support).

bagccgop Build for all gccgo-supported platforms by default, disable those which you don't want (bagop with CGo support). Overview bagccgop is a simpl

Nov 9, 2022
others implement usefuls stuff in their free time. I implement an eventstore framework

Eventstore eventstore is a library where I try out new stuff related to an eventstore as a single point of truth. At the moment I'm writing this it's

Nov 10, 2022
Example instrumentation of Golang Application with OpenTelemetry with supported configurations to export to Sentry.
Example instrumentation of Golang Application with OpenTelemetry with supported configurations to export to Sentry.

Sentry + Opentelemetry Go Example Requirements To run this example, you will need a kubernetes cluster. This example has been tried and tested on Mini

Oct 27, 2022
This application shows how to use the websocket package to implement a simple web chat application.

Chat Example This application shows how to use the websocket package to implement a simple web chat application. Running the example The example requi

Nov 14, 2021
A simple database application that I was asked to implement as part of a job application process

This is a simple database application that I was asked to implement as part of a job application process. They told me I could choose any languages an

Nov 24, 2021
ide-gen is a tool for development workspace prepare automation by automatic VCS repositories discovery and clone and project generation for supported IDEs.

ide-gen is a tool for development workspace prepare automation by automatic VCS repositories discovery and clone and project generation for supported IDEs.

May 8, 2022
go-fastdfs 是一个简单的分布式文件系统(私有云存储),具有无中心、高性能,高可靠,免维护等优点,支持断点续传,分块上传,小文件合并,自动同步,自动修复。Go-fastdfs is a simple distributed file system (private cloud storage), with no center, high performance, high reliability, maintenance free and other advantages, support breakpoint continuation, block upload, small file merge, automatic synchronization, automatic repair.(similar fastdfs).
go-fastdfs 是一个简单的分布式文件系统(私有云存储),具有无中心、高性能,高可靠,免维护等优点,支持断点续传,分块上传,小文件合并,自动同步,自动修复。Go-fastdfs is a simple distributed file system (private cloud storage), with no center, high performance, high reliability, maintenance free and other advantages, support breakpoint continuation, block upload, small file merge, automatic synchronization, automatic repair.(similar fastdfs).

中文 English 愿景:为用户提供最简单、可靠、高效的分布式文件系统。 go-fastdfs是一个基于http协议的分布式文件系统,它基于大道至简的设计理念,一切从简设计,使得它的运维及扩展变得更加简单,它具有高性能、高可靠、无中心、免维护等优点。 大家担心的是这么简单的文件系统,靠不靠谱,可不

Jan 8, 2023
A bytecode-based virtual machine to implement scripting/filtering support in your golang project.

eval-filter Implementation Scripting Facilities Types Built-In Functions Conditionals Loops Functions Case/Switch Use Cases Security Denial of service

Dec 30, 2022
A bytecode-based virtual machine to implement scripting/filtering support in your golang project.

eval-filter Implementation Scripting Facilities Types Built-In Functions Conditionals Loops Functions Case/Switch Use Cases Security Denial of service

Jan 8, 2023
Govalid is a data validation library that can validate most data types supported by golang

Govalid is a data validation library that can validate most data types supported by golang. Custom validators can be used where the supplied ones are not enough.

Apr 22, 2022
More effective network communication, two-way calling, notify and broadcast supported.

ARPC - More Effective Network Communication Contents ARPC - More Effective Network Communication Contents Features Performance Header Layout Installat

Dec 22, 2022
IPIP.net officially supported IP database ipdb format parsing library

IPIP.net officially supported IP database ipdb format parsing library

Dec 27, 2022
Microservice Boilerplate for Golang with gRPC and RESTful API. Multiple database and client supported
Microservice Boilerplate for Golang with gRPC and RESTful API. Multiple database and client supported

Go Microservice Starter A boilerplate for flexible Go microservice. Table of contents Features Installation Todo List Folder Structures Features: Mult

Jul 28, 2022