Help us shape the future of Go! Take the 2026 Go Developer Survey

cobra-util

module
v0.0.5 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Sep 26, 2026 License: MIT

README

cobra-util

License Go Reference

cobra-util is a Go library for spf13/cobra. It is the cobra counterpart of urfave-cli-v3-util.

  • cobrautil: The entry point of the process, and environment variable sources for flags
  • helpall: Output the help message of all commands
  • vcmd: Version Command
  • jsonschema: Output the JSON Schema of the configuration file
  • docs: Output the embedded documents for coding agents
  • keyring/ghtoken: Manage a GitHub Access token by keyring

How To Use

Example

cobrautil.Main runs the CLI, logs the error it returns, and exits with its exit code. cobrautil.Command wires the root command to the process environment and adds --version, the version command, and the hidden help-all command.

func main() {
	cobrautil.Main("hello", "1.0.0", run)
}

func run(ctx context.Context, logger *slogutil.Logger, env *cobrautil.Env) error {
	cmd := cobrautil.Command(env, &cobra.Command{
		Use:   "hello",
		Short: "A new cli application",
	}, &cobrautil.Options{
		SHA: "abc123",
	})
	cmd.AddCommand(/* ... */)
	return cmd.ExecuteContext(ctx)
}
Environment variables

urfave/cli lets a flag fall back to environment variables with cli.EnvVars, which pflag has no equivalent of. cobrautil.Envs binds environment variables to a flag, and cobrautil.Command applies them in the root command's PersistentPreRunE.

cmd.Flags().String("token", "", "GitHub Access token")
cobrautil.Envs(cmd.Flags(), "token", "HELLO_GITHUB_TOKEN", "GITHUB_TOKEN")

The value comes from the command line first, then from the environment variables in the order they were bound, then from the flag's default. The names are appended to the flag's usage as [$HELLO_GITHUB_TOKEN] [$GITHUB_TOKEN], so the help says where else the value can come from.

Note that cobra runs only the closest PersistentPreRunE in the chain, so a command that sets one of its own must call cobrautil.ApplyEnvs itself.

JSON Schema

jsonschema.With adds the json-schema command, which outputs the JSON Schema of the configuration file so that editors such as VSCode can complete the configuration file and warn about invalid settings. The schema is passed as bytes, so embed the schema the CLI generates with go:embed and it always describes the configuration the running version accepts.

With adds the command to the command it is given and returns it, so it can wrap cobrautil.Command.

//go:embed json-schema/hello.json
var schema []byte

cmd := jsonschema.With(cobrautil.Command(env, rootCmd, opts), schema)

It takes the name of the program from the command it adds to, which is what the example in the help says. Use jsonschema.New instead to name the program yourself, or to add the command somewhere other than the root.

cmd.AddCommand(jsonschema.New(&jsonschema.Command{
	Schema: schema,
	Name:   "hello",
}))
$ hello json-schema > hello.json
Documents for coding agents

docs.With adds the docs command, which lists and outputs the documents embedded in the binary. Coding agents read them before answering questions about the CLI or troubleshooting its errors, so they always see the documents of the version that is running rather than whatever a web search turns up.

The documents are Markdown files with a YAML frontmatter holding their description, embedded with go:embed.

---
description: How to install hello. Use to pick an installation method and to verify the binary.
---

# Install
//go:embed docs/*.md
var docsFS embed.FS

sub, err := fs.Sub(docsFS, "docs")
if err != nil {
	return err
}
cmd := docs.With(cobrautil.Command(env, rootCmd, opts), sub)

docs list outputs the name and the description of every document as JSON, and docs show <name> outputs one of them. A name that doesn't exist is reported with the names that do, so an agent that guessed wrong recovers without listing the documents again. Documents in subdirectories are served too, named by their path, such as docs show codes/001, so documentation grouped in directories doesn't have to be flattened.

$ hello docs list
{
  "results": [
    {
      "name": "install",
      "description": "How to install hello. Use to pick an installation method and to verify the binary."
    }
  ],
  "help": "Run `hello docs show <name>` to see the details of each document."
}

$ hello docs show install

Use docs.New instead of docs.With to name the program yourself, or to add the command somewhere other than the root.

docsCmd := &docs.Command{
	FS:   sub,
	Name: "hello",
}
cmd.AddCommand(docs.New(docsCmd))

An agent only learns that these documents exist if a command it runs says so, so log Command.Hint from the commands it is likely to run. Log it to stderr rather than stdout, so that it doesn't break scripts that parse the output, and at the info level so that a lower log level silences it.

logger.Info(docsCmd.Hint())

Directories

Path Synopsis
cmd
hello command
Package main is an example CLI built with cobra-util.
Package main is an example CLI built with cobra-util.
Package cobrautil provides the pieces every CLI of ours needs on top of spf13/cobra: the process entry point, the wiring of a root command to that entry point, and environment variable sources for flags.
Package cobrautil provides the pieces every CLI of ours needs on top of spf13/cobra: the process entry point, the wiring of a root command to that entry point, and environment variable sources for flags.
Package docs implements the docs command of CLIs built with spf13/cobra, which lists and outputs the documents embedded in the binary so that a coding agent can read them before answering questions about the CLI or troubleshooting its errors.
Package docs implements the docs command of CLIs built with spf13/cobra, which lists and outputs the documents embedded in the binary so that a coding agent can read them before answering questions about the CLI or troubleshooting its errors.
Package helpall implements the help-all command of CLIs built with spf13/cobra, which writes the help of every command as Markdown so that it can be put into the documentation.
Package helpall implements the help-all command of CLIs built with spf13/cobra, which writes the help of every command as Markdown so that it can be put into the documentation.
Package jsonschema implements the json-schema command of CLIs built with spf13/cobra, which outputs the JSON Schema of the configuration file so that editors such as VSCode can complete the configuration file and warn about invalid settings.
Package jsonschema implements the json-schema command of CLIs built with spf13/cobra, which outputs the JSON Schema of the configuration file so that editors such as VSCode can complete the configuration file and warn about invalid settings.
keyring
ghtoken
Package ghtoken implements the commands managing a GitHub Access token in the keyring of the operating system, and the oauth2 token source reading it back.
Package ghtoken implements the commands managing a GitHub Access token in the keyring of the operating system, and the oauth2 token source reading it back.
Package vcmd implements the version command of CLIs built with spf13/cobra.
Package vcmd implements the version command of CLIs built with spf13/cobra.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL