{"id":42044615,"url":"https://github.com/subchen/go-cli","last_synced_at":"2026-01-26T06:06:35.674Z","repository":{"id":57487682,"uuid":"91143496","full_name":"subchen/go-cli","owner":"subchen","description":"A full-featured and easy to use command-line package","archived":false,"fork":false,"pushed_at":"2021-01-02T11:46:58.000Z","size":60,"stargazers_count":13,"open_issues_count":1,"forks_count":3,"subscribers_count":4,"default_branch":"master","last_synced_at":"2025-08-13T22:29:29.698Z","etag":null,"topics":["cli","command","command-line","flag","getopt","golang"],"latest_commit_sha":null,"homepage":"","language":"Go","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"apache-2.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/subchen.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2017-05-13T02:21:16.000Z","updated_at":"2023-06-05T16:55:53.000Z","dependencies_parsed_at":"2022-08-29T11:21:36.460Z","dependency_job_id":null,"html_url":"https://github.com/subchen/go-cli","commit_stats":null,"previous_names":[],"tags_count":19,"template":false,"template_full_name":null,"purl":"pkg:github/subchen/go-cli","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/subchen%2Fgo-cli","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/subchen%2Fgo-cli/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/subchen%2Fgo-cli/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/subchen%2Fgo-cli/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/subchen","download_url":"https://codeload.github.com/subchen/go-cli/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/subchen%2Fgo-cli/sbom","scorecard":{"id":856695,"data":{"date":"2025-08-11","repo":{"name":"github.com/subchen/go-cli","commit":"e60b8d5b463b05c60cd352ff1de3a05383e48dd6"},"scorecard":{"version":"v5.2.1-40-gf6ed084d","commit":"f6ed084d17c9236477efd66e5b258b9d4cc7b389"},"score":3,"checks":[{"name":"Dangerous-Workflow","score":-1,"reason":"no workflows found","details":null,"documentation":{"short":"Determines if the project's GitHub Action workflows avoid dangerous patterns.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#dangerous-workflow"}},{"name":"Packaging","score":-1,"reason":"packaging workflow not detected","details":["Warn: no GitHub/GitLab publishing workflow detected."],"documentation":{"short":"Determines if the project is published as a package that others can easily download, install, easily update, and uninstall.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#packaging"}},{"name":"Code-Review","score":0,"reason":"Found 2/27 approved changesets -- score normalized to 0","details":null,"documentation":{"short":"Determines if the project requires human code review before pull requests (aka merge requests) are merged.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#code-review"}},{"name":"Token-Permissions","score":-1,"reason":"No tokens found","details":null,"documentation":{"short":"Determines if the project's workflows follow the principle of least privilege.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#token-permissions"}},{"name":"Maintained","score":0,"reason":"0 commit(s) and 0 issue activity found in the last 90 days -- score normalized to 0","details":null,"documentation":{"short":"Determines if the project is \"actively maintained\".","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#maintained"}},{"name":"Binary-Artifacts","score":10,"reason":"no binaries found in the repo","details":null,"documentation":{"short":"Determines if the project has generated executable (binary) artifacts in the source repository.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#binary-artifacts"}},{"name":"Pinned-Dependencies","score":-1,"reason":"no dependencies found","details":null,"documentation":{"short":"Determines if the project has declared and pinned the dependencies of its build process.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#pinned-dependencies"}},{"name":"CII-Best-Practices","score":0,"reason":"no effort to earn an OpenSSF best practices badge detected","details":null,"documentation":{"short":"Determines if the project has an OpenSSF (formerly CII) Best Practices Badge.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#cii-best-practices"}},{"name":"Fuzzing","score":0,"reason":"project is not fuzzed","details":["Warn: no fuzzer integrations found"],"documentation":{"short":"Determines if the project uses fuzzing.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#fuzzing"}},{"name":"License","score":10,"reason":"license file detected","details":["Info: project has a license file: LICENSE:0","Info: FSF or OSI recognized license: Apache License 2.0: LICENSE:0"],"documentation":{"short":"Determines if the project has defined a license.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#license"}},{"name":"Signed-Releases","score":-1,"reason":"no releases found","details":null,"documentation":{"short":"Determines if the project cryptographically signs release artifacts.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#signed-releases"}},{"name":"Branch-Protection","score":0,"reason":"branch protection not enabled on development/release branches","details":["Warn: branch protection not enabled for branch 'master'"],"documentation":{"short":"Determines if the default and release branches are protected with GitHub's branch protection settings.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#branch-protection"}},{"name":"Security-Policy","score":0,"reason":"security policy file not detected","details":["Warn: no security policy file detected","Warn: no security file to analyze","Warn: no security file to analyze","Warn: no security file to analyze"],"documentation":{"short":"Determines if the project has published a security policy.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#security-policy"}},{"name":"SAST","score":0,"reason":"SAST tool is not run on all commits -- score normalized to 0","details":["Warn: 0 commits out of 5 are checked with a SAST tool"],"documentation":{"short":"Determines if the project uses static code analysis.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#sast"}},{"name":"Vulnerabilities","score":10,"reason":"0 existing vulnerabilities detected","details":null,"documentation":{"short":"Determines if the project has open, known unfixed vulnerabilities.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#vulnerabilities"}}]},"last_synced_at":"2025-08-24T00:02:14.643Z","repository_id":57487682,"created_at":"2025-08-24T00:02:14.643Z","updated_at":"2025-08-24T00:02:14.643Z"},"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":28768074,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-01-26T03:54:34.369Z","status":"ssl_error","status_checked_at":"2026-01-26T03:54:33.031Z","response_time":59,"last_error":"SSL_connect returned=1 errno=0 peeraddr=140.82.121.5:443 state=error: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["cli","command","command-line","flag","getopt","golang"],"created_at":"2026-01-26T06:06:35.611Z","updated_at":"2026-01-26T06:06:35.657Z","avatar_url":"https://github.com/subchen.png","language":"Go","funding_links":[],"categories":[],"sub_categories":[],"readme":"# go-cli\n\n[![GoDoc](https://godoc.org/github.com/subchen/go-cli?status.svg)](https://godoc.org/github.com/subchen/go-cli)\n[![Build Status](https://travis-ci.org/subchen/go-cli.svg?branch=master)](https://travis-ci.org/subchen/go-cli)\n[![Coverage Status](https://coveralls.io/repos/github/subchen/go-cli/badge.svg?branch=master)](https://coveralls.io/github/subchen/go-cli?branch=master)\n[![Go Report Card](https://goreportcard.com/badge/github.com/subchen/go-cli)](https://goreportcard.com/report/github.com/subchen/go-cli)\n[![Release](https://img.shields.io/github/release/subchen/go-cli.svg)](https://github.com/subchen/go-cli/releases/latest)\n[![License](http://img.shields.io/badge/License-Apache_2-red.svg?style=flat)](http://www.apache.org/licenses/LICENSE-2.0)\n\n`go-cli` is a package to build a CLI application. Support command/sub-commands.\n\n\nSome applications are built using `go-cli` including:\n\n- [frep](https://github.com/subchen/frep)\n- [mknovel](https://github.com/subchen/mknovel)\n- [ovfenv-installer](https://github.com/subchen/ovfenv-installer)\n- [publish-toolset](https://github.com/subchen/publish-toolset)\n\n\n**Table of Contents**\n\n- [Installation](#overview)\n- [Syntax for Command Line](#syntax-for-command-line)\n- [Getting Started](#getting-started)\n  * [Arguments](#arguments)\n  * [Flags](#flags)\n    + [Bool flag](#bool-flag)\n    + [Value bind](#value-bind)\n    + [Short, Long, Alias Names](#short-long-alias-names)\n    + [Placeholder](#placeholder)\n    + [Default Value](#default-value)\n    + [NoOptDefVal](#nooptdefval)\n    + [Hidden flags](#hidden-flags)\n  * [Commands](#commands)\n- [Generate Help](#generate-help)\n  * [Customize help](#customize-help)\n- [Generate Version](#generate-version)\n  * [Customize version](#customize-version)\n- [Error Handler](#error-handler)\n  * [OnCommandNotFound](#oncommandnotfound)\n  * [OnActionPanic](#onactionpanic)\n- [Contributing](#contributing)\n- [License](#license)\n\n\n## Installation\n\n`go-cli` is available using the standard go get command.\n\nTo install `go-cli`, simply run:\n\n```bash\ngo get github.com/subchen/go-cli/v3\n```\n\n## Syntax for Command Line\n\n```\n// Long option\n--flag    // boolean flags, or flags with no option default values\n--flag x  // only on flags without a default value\n--flag=x\n\n// Short option\n-x        // boolean flags\n-x 123\n-x=123\n-x123     // value is 123\n\n// value wrapped by quote\n-x=\"123\"\n-x='123'\n\n// unordered in flags and arguments\narg1 -x 123 arg2 --test arg3 arg4\n\n// stops parsing after the terminator `--`\n-x 123 -- arg1 --not-a-flag arg3 arg4\n```\n\n\n## Getting Started\n\nA simple CLI application:\n\n```go\npackage main\n\nimport (\n    \"fmt\"\n    \"os\"\n    \"github.com/subchen/go-cli/v3\"\n)\n\nfunc main() {\n    app := cli.NewApp()\n    app.Name = \"hello\"\n    app.Version = \"1.0.0\"\n    app.Usage = \"a hello world application.\"\n    app.Action = func(c *cli.Context) {\n        fmt.Println(\"Hello World!\")\n    }\n    app.Run(os.Args)\n}\n```\n\nBuild and run our new CLI application\n\n```bash\n$ go build\n$ ./hello\nHello World!\n```\n\n`go-cli` also generates neat help text\n\n```bash\n$ ./hello --help\nNAME:\n    hello - a hello world application.\n\nUSAGE:\n    hello [options] [arguments...]\n\nVERSION:\n    1.0.0\n\nOPTIONS:\n    --help     print this help\n    --version  print version information\n```\n\n### Arguments\n\nYou can lookup arguments by calling the `Args` function on `cli.Context`, e.g.:\n\n```go\napp := cli.NewApp()\n\napp.Action = func(c *cli.Context) {\n    name := c.Args()[0]\n    fmt.Printf(\"Hello %v\\n\", name)\n}\n\napp.Run(os.Args)\n```\n\n### Flags\n\nSetting and querying flags is simple.\n\n\n```go\napp := cli.NewApp()\n\napp.Flags = []*cli.Flag {\n    {\n        Name: \"name\",\n        Usage: \"a name of user\",\n    },\n}\n\napp.Action = func(c *cli.Context) {\n    name := c.GetString(\"name\")\n    fmt.Printf(\"Hello %v\\n\", name)\n}\n\napp.Run(os.Args)\n```\n\n#### Bool flag\n\nA bool flag can has a optional inline bool value.\n\n```go\n\u0026cli.Flag{\n    Name: \"verbose\",\n    Usage: \"output verbose information\",\n    IsBool: true,\n},\n```\n\nThe parsed arguments likes:\n\n```\n// valid\n--verbose\n--verbose=true\n--verbose=false\n\n// invalid\n--verbose false\n```\n\nbool flag accepts `1,t,true,yes,on` as true, `0,f,false,no,off` as false.\n\n#### Value bind\n\nYou can bind a variable for a `Flag.Value`, which will be set after parsed.\n\n```go\nvar name string\n\napp := cli.NewApp()\n\napp.Flags = []*cli.Flag {\n    {\n        Name: \"name\",\n        Usage: \"a name of user\",\n        Value: \u0026name,\n    },\n}\n\napp.Action = func(c *cli.Context) {\n    fmt.Printf(\"Hello %v\\n\", name)\n}\n\napp.Run(os.Args)\n```\n\n`Flag.Value` can accept a `cli.Value` interface or a pointer of base type.\n\n- **base type:**\n    - `*string`\n    - `*bool`\n    - `*int`, `*int8`, `*int16`, `*int32`, `*int64`\n    - `*uint`, `*uint8`, `*uint16`, `*uint32`, `*uint64`\n    - `*float32`, `*float64`\n    - `*time.Time`, `*time.Duration`, `*time.Location`\n    - `*net.IP`, `*net.IPMask`, `*net.IPNet`\n    - `*url.URL`\n\n- **slice of base type:**\n    - `*[]string`\n    - `*[]int`, `*[]uint`, `*[]float64`\n    - `*[]net.IP`, `*[]net.IPNet`\n    - `*[]url.URL`\n\n- **cli.Value:**\n    ```go\n    type Value interface {\n        String() string\n        Set(string) error\n    }\n    ```\n\n\u003e Note: If you set `*bool` as `Flag.Value`, the `Flag.IsBool` will be automatically `true`.\n\n\n#### Short, Long, Alias Names\n\nYou can set multiply name in a flag, a short name, a long name, or multiple alias names.\n\n```go\n\u0026cli.Flag{\n    Name: \"o, output, output-dir\",\n    Usage: \"A directory for output\",\n}\n```\n\nThen, results in help output like:\n\n```\n-o, --output, --output-dir value   A directory for output\n```\n\n#### Placeholder\n\nSometimes it's useful to specify a flag's value within the usage string itself.\n\nFor example this:\n\n```go\n\u0026cli.Flag{\n    Name: \"o, output\",\n    Usage: \"A directory for output\",\n    Placeholder: \"DIR\",\n}\n```\n\nThen, results in help output like:\n\n```\n-o DIR, --output DIR   A directory for output\n```\n\n#### Default Value\n\n```go\n\u0026cli.Flag{\n    Name: \"o, output\",\n    Usage: \"A directory for output\",\n    DefValue: \"/tmp/\",\n}\n```\n\nYou also can set a default value got from the Environment\n\n```go\n\u0026cli.Flag{\n    Name: \"o, output\",\n    Usage: \"A directory for output\",\n    EnvVar: \"APP_OUTPUT_DIR\",\n}\n```\n\nThe `EnvVar` may also be given as a comma-delimited \"cascade\", \nwhere the first environment variable that resolves is used as the default.\n\n```go\nEnvVar: \"APP_OUTPUT,APP_OUTPUT_DIR\",\n```\n\n#### NoOptDefVal\n\nIf a flag has a `NoOptDefVal` and the flag is set on the command line without an option\nthe flag will be set to the `NoOptDefVal`.\n\nFor example given:\n\n```go\n\u0026cli.Flag{\n    Name: \"flagname\",\n    DefValue: \"123\",\n    NoOptDefVal: \"456\",\n    Value: \u0026val\n}\n```\n\nWould result in something like\n\n| Parsed Arguments | Resulting Value |\n| -------------    | -------------   |\n| --flagname=000   | val=000         |\n| --flagname       | val=456         |\n| [nothing]        | val=123         |\n\n#### Hidden flags\n\nIt is possible to mark a flag as hidden, meaning it will still function as normal, \nhowever will not show up in usage/help text.\n\n```go\n\u0026cli.Flag{\n    Name: \"secretFlag\",\n    Hidden: true,\n}\n```\n\n### Commands\n\nCommands can be defined for a more git-like command line app.\n\n```go\npackage main\n\nimport (\n    \"fmt\"\n    \"os\"\n    \"strings\"\n    \"github.com/subchen/go-cli/v3\"\n)\n\nfunc main() {\n    app := cli.NewApp()\n    app.Name = \"git\"\n    app.Commands = []*cli.Command{\n        {\n            Name:   \"add\",\n            Usage:  \"Add file contents to the index\",\n            Action: func(c *cli.Context) {\n                fmt.Println(\"added files: \", strings.Join(c.Args(), \", \"))\n            },\n        },\n        {\n            // alias name\n            Name:   \"commit, co\",\n            Usage:  \"Record changes to the repository\",\n            Flags:  []*cli.Flag {\n                {\n                    Name: \"m, message\",\n                    Usage: \"commit message\",\n                },\n            },\n            Hidden: false,\n            Action: func(c *cli.Context) {\n                fmt.Println(\"commit message: \", c.GetString(\"m\"))\n            },\n        },\n    }\n\n    app.SeeAlso = `https://github.com/subchen/go-cli\nhttps://github.com/subchen/go-cli/wiki`\n\n    app.Run(os.Args)\n}\n```\n\nAlso, you can use sub-commands in a command.\n\n## Generate Help\n\nThe default help flag (`--help`) is defined in `cli.App` and `cli.Command`.\n\n### Customize help\n\nAll of the help text generation may be customized.\nA help template is exposed as variable `cli.HelpTemplate`, that can be override.\n\n```go\n// Append copyright\ncli.HelpTemplate = cli.HelpTemplate + \"@2017 Your company, Inc.\\n\\n\"\n```\n\nOr, you can rewrite a help using customized func.\n\n```go\napp := cli.NewApp()\n\napp.ShowHelp = func(c *cli.HelpContext) {\n    fmt.Println(\"this is my help generated.\")\n}\n\napp.Run(os.Args)\n```\n\n## Generate Version\n\nThe default version flag (`--version`) is defined in `cli.App`.\n\n```go\napp := cli.NewApp()\napp.Name = \"hello\"\napp.Version = \"1.0.0\"\napp.BuildInfo = \u0026cli.BuildInfo{\n    GitBranch:   \"master\",\n    GitCommit:   \"320279c1a9a6537cdfd1e526063f6a748bb1fec3\",\n    GitRevCount: \"1234\",\n    Timestamp:   \"Sat May 13 19:53:08 UTC 2017\",\n}\napp.Run(os.Args)\n```\n\nThen, `./hello --version` results like:\n\n```bash\nName:       hello\nVersion:    1.0.0\nPatches:    1234\nGit branch: master\nGit commit: 320279c1a9a6537cdfd1e526063f6a748bb1fec3\nBuilt:      Sat May 13 19:53:08 UTC 2017\nGo version: go1.8.1\nOS/Arch:    darwin/amd64\n```\n\n### Customize version\n\nYou can rewrite version output using customized func.\n\n```go\napp := cli.NewApp()\n\napp.ShowVersion = func(app *App) {\n    fmt.Println(\"Version: \", app.Version)\n}\n\napp.Run(os.Args)\n```\n\n## Error Handler\n\n### OnCommandNotFound\n\n`go-cli` provides `OnCommandNotFound` func to handle an error if command/sub-command is not found.\n\n```go\napp := cli.NewApp()\napp.Flags = ...\napp.Commands = ...\n\napp.OnCommandNotFound = func(c *cli.Context, command string) {\n    c.ShowError(fmt.Errorf(\"Command not found: %s\", command))\n}\n\napp.Run(os.Args)\n```\n\n### OnActionPanic\n\n`go-cli` provides `OnActionPanic` func to handle an error if panic in action.\n\n```go\napp := cli.NewApp()\napp.Flags = ...\napp.Commands = ...\n\napp.OnActionPanic = func(c *cli.Context, err error) {\n    os.Stderr.WriteString(fmt.Sprintf(\"fatal: %v\\n\", err))\n}\n\napp.Run(os.Args)\n```\n\n\u003e Notes: `go-cli` will only output error message without golang error stacks if app.OnActionPanic is nil.\n\n## Contributing\n\n- Fork it\n- Create your feature branch (git checkout -b my-new-feature)\n- Commit your changes (git commit -am 'Add some feature')\n- Push to the branch (git push origin my-new-feature)\n- Create new Pull Request\n\n\n## License\n\nApache 2.0 license. See [LICENSE](https://github.com/subchen/go-cli/blob/master/LICENSE)\n\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fsubchen%2Fgo-cli","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fsubchen%2Fgo-cli","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fsubchen%2Fgo-cli/lists"}