{"id":13410559,"url":"https://github.com/jxskiss/mcli","last_synced_at":"2026-01-23T00:52:16.826Z","repository":{"id":37880967,"uuid":"445050035","full_name":"jxskiss/mcli","owner":"jxskiss","description":"A minimal but powerful cli library for Go","archived":false,"fork":false,"pushed_at":"2024-04-06T02:14:14.000Z","size":265,"stargazers_count":28,"open_issues_count":1,"forks_count":2,"subscribers_count":3,"default_branch":"main","last_synced_at":"2024-07-31T20:43:08.756Z","etag":null,"topics":["awesome","cli","golang"],"latest_commit_sha":null,"homepage":"","language":"Go","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/jxskiss.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2022-01-06T05:20:07.000Z","updated_at":"2024-07-08T09:12:05.000Z","dependencies_parsed_at":"2022-08-19T15:10:43.504Z","dependency_job_id":"f67c3d54-9a4d-4ede-bfea-4bef84109420","html_url":"https://github.com/jxskiss/mcli","commit_stats":null,"previous_names":[],"tags_count":24,"template":false,"template_full_name":null,"purl":"pkg:github/jxskiss/mcli","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jxskiss%2Fmcli","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jxskiss%2Fmcli/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jxskiss%2Fmcli/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jxskiss%2Fmcli/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/jxskiss","download_url":"https://codeload.github.com/jxskiss/mcli/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jxskiss%2Fmcli/sbom","scorecard":{"id":545661,"data":{"date":"2025-08-11","repo":{"name":"github.com/jxskiss/mcli","commit":"9de16894df1e598b17395dfe991cf8a73c279d5f"},"scorecard":{"version":"v5.2.1-40-gf6ed084d","commit":"f6ed084d17c9236477efd66e5b258b9d4cc7b389"},"score":4.3,"checks":[{"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":"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":"Code-Review","score":3,"reason":"Found 4/11 approved changesets -- score normalized to 3","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":"Dangerous-Workflow","score":10,"reason":"no dangerous workflow patterns detected","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":"Token-Permissions","score":0,"reason":"detected GitHub workflow tokens with excessive permissions","details":["Warn: no topLevel permission defined: .github/workflows/go.yml:1","Info: no jobLevel write permissions found"],"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":"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":3,"reason":"dependency not pinned by hash detected -- score normalized to 3","details":["Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/go.yml:18: update your workflow using https://app.stepsecurity.io/secureworkflow/jxskiss/mcli/go.yml/main?enable=pin","Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/go.yml:23: update your workflow using https://app.stepsecurity.io/secureworkflow/jxskiss/mcli/go.yml/main?enable=pin","Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/go.yml:42: update your workflow using https://app.stepsecurity.io/secureworkflow/jxskiss/mcli/go.yml/main?enable=pin","Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/go.yml:47: update your workflow using https://app.stepsecurity.io/secureworkflow/jxskiss/mcli/go.yml/main?enable=pin","Warn: third-party GitHubAction not pinned by hash: .github/workflows/go.yml:53: update your workflow using https://app.stepsecurity.io/secureworkflow/jxskiss/mcli/go.yml/main?enable=pin","Info:   0 out of   4 GitHub-owned GitHubAction dependencies pinned","Info:   0 out of   1 third-party GitHubAction dependencies pinned","Info:   1 out of   1 goCommand dependencies pinned"],"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":"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":"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: MIT License: 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":-1,"reason":"internal error: error during branchesHandler.setup: internal error: githubv4.Query: Resource not accessible by integration","details":null,"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":"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"}},{"name":"SAST","score":0,"reason":"SAST tool is not run on all commits -- score normalized to 0","details":["Warn: 0 commits out of 25 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"}}]},"last_synced_at":"2025-08-20T09:25:39.329Z","repository_id":37880967,"created_at":"2025-08-20T09:25:39.329Z","updated_at":"2025-08-20T09:25:39.329Z"},"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":28676173,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-01-22T20:48:19.482Z","status":"ssl_error","status_checked_at":"2026-01-22T20:48:14.968Z","response_time":144,"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":["awesome","cli","golang"],"created_at":"2024-07-30T20:01:07.680Z","updated_at":"2026-01-23T00:52:16.813Z","avatar_url":"https://github.com/jxskiss.png","language":"Go","readme":"# mcli\n\n[![GoDoc](https://img.shields.io/badge/api-Godoc-blue.svg)][godoc]\n[![Go Report Card](https://goreportcard.com/badge/github.com/jxskiss/mcli)][goreport]\n[![Coverage](https://codecov.io/gh/jxskiss/mcli/branch/main/graph/badge.svg)][codecov]\n[![Issues](https://img.shields.io/github/issues/jxskiss/mcli.svg)][issues]\n[![GitHub release](http://img.shields.io/github/release/jxskiss/mcli.svg)][release]\n[![MIT License](http://img.shields.io/badge/license-MIT-blue.svg)][license]\n\n[godoc]: https://pkg.go.dev/github.com/jxskiss/mcli\n\n[goreport]: https://goreportcard.com/report/github.com/jxskiss/mcli\n\n[codecov]: https://codecov.io/gh/jxskiss/mcli\n\n[issues]: https://github.com/jxskiss/mcli/issues\n\n[release]: https://github.com/jxskiss/mcli/releases\n\n[license]: https://github.com/jxskiss/mcli/blob/master/LICENSE\n\n\n`mcli` is a minimal but powerful cli library for Go.\n`m` stands for minimal and magic.\n\nIt is extremely easy to use, it makes you love writing cli programs in Go.\n\nDisclaimer: the original idea is inspired by [shafreeck/cortana](https://github.com/shafreeck/cortana),\nwhich is licensed under the Apache License 2.0.\n\n## Features\n\n* Easy to use, dead simple yet very powerful API to define commands, flags and arguments.\n* Add arbitrary nested sub-command with single line code.\n* Group subcommands into different categories in help.\n* Define command flags and arguments inside the command processor using struct tag.\n* Define global flags apply to all commands, or share common flags between a group of commands.\n* Read environment variables for flags and arguments.\n* Set default value for flags and arguments.\n* Work with time.Duration, slice, map out of box.\n* Mark commands, flags as hidden, hidden commands and flags won't be showed in help,\n  except that when a special flag `--mcli-show-hidden` is provided.\n* Mark flags, arguments as required, report error when a required flag is not given.\n* Mark flags as deprecated.\n* Automatic suggestions like git.\n* Automatic help generation for commands, flags and arguments.\n* Automatic help flag recognition of `-h`, `--help`, etc.\n* Automatic shell completion, it supports `bash`, `zsh`, `fish`, `powershell` for now.\n* Compatible with the standard library's flag.FlagSet.\n* Optional posix-style single token multiple options command line parsing.\n* Alias command, so you can reorganize commands without breaking them.\n* Flexibility to define your own usage messages.\n* Minimal dependency.\n* Makes you love writing cli programs in Go.\n\n## Usage\n\nUse in main function:\n\n```go\nfunc main() {\n    var args struct {\n        Name string `cli:\"-n, --name, Who do you want to say to\" default:\"tom\"`\n\n        // This argument is required.\n        Text string `cli:\"#R, text, The 'message' you want to send\"`\n\n        // This argument reads environment variable and requires the variable must exist,\n        // it doesn't accept input from command line.\n        APIAccessKey string `cli:\"#ER, The access key to your service provider\" env:\"MY_API_ACCESS_KEY\"`\n    }\n    mcli.Parse(\u0026args)\n    fmt.Printf(\"Say to %s: %s\\n\", args.Name, args.Text)\n}\n```\n\n```shell\n$ go run say.go -h\nUsage:\n  say [flags] \u003ctext\u003e\n\nFlags:\n  -n, --name \u003cstring\u003e    Who do you want to say to\n                         [default: \"tom\"]\n\nArguments:\n  text \u003cmessage\u003e [REQUIRED]    The message you want to send\n\nEnvironment Variables:\n  - MY_API_ACCESS_KEY \u003cstring\u003e [REQUIRED]\n    The access key to your service provider\n\n$ MY_API_ACCESS_KEY=xxxx go run say.go hello\nSay to tom: hello\n```\n\nUse sub-commands:\n\n```go\nfunc main() {\n    mcli.Add(\"cmd1\", runCmd1, \"An awesome command cmd1\")\n\n    mcli.AddGroup(\"cmd2\", \"This is a command group called cmd2\")\n    mcli.Add(\"cmd2 sub1\", runCmd2Sub1, \"Do something with cmd2 sub1\")\n    mcli.Add(\"cmd2 sub2\", runCmd2Sub2, \"Brief description about cmd2 sub2\")\n\n    // A sub-command can also be added without registering the group.\n    mcli.Add(\"group3 sub1 subsub1\", runGroup3Sub1Subsub1, \"Blah blah Blah\")\n\n    // This is a hidden command, it won't be showed in help,\n    // except that when flag \"--mcli-show-hidden\" is given.\n    mcli.AddHidden(\"secret-cmd\", secretCmd, \"An secret command won't be showed in help\")\n\n    // Enable shell auto-completion, see `program completion -h` for help.\n    mcli.AddCompletion()\n\n    mcli.Run()\n}\n\nfunc runCmd1() {\n    var args struct {\n        Branch    string `cli:\"-b, --branch, Select another branch by passing in the branch name\"`\n        Commit    bool   `cli:\"-c, --commit, Open the last commit\"`\n        NoBrowser bool   `cli:\"-n, --no-browser, Print destination URL instead of opening the browser\"`\n        Projects  bool   `cli:\"-p, --projects, Open repository projects\"`\n        Repo      string `cli:\"-R, --repo, Select another repository using the '[HOST/]OWNER/REPO' format\"`\n        Settings  bool   `cli:\"-s, --settings, Open repository settings\"`\n        Wiki      bool   `cli:\"-w, --wiki, Open repository wiki\"`\n\n        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\\\"\"`\n    }\n    mcli.Parse(\u0026args)\n\n    // Do something\n}\n\ntype Cmd2CommonArgs struct {\n    Repo string `cli:\"-R, --repo, Select another repository using the '[HOST/]OWNER/REPO' format\"`\n}\n\nfunc runCmd2Sub1() {\n    // Note that the flag/argument description can be seperated either\n    // by a comma or spaces, and can be mixed.\n    var args struct {\n        Body     string `cli:\"-b, --body        Supply a body. Will prompt for one otherwise.\"`\n        BodyFile string `cli:\"-F, --body-file   Read body text from 'file' (use \\\"-\\\" to read from standard input)\"`\n        Editor   bool   `cli:\"-e, --editor,     Add body using editor\"`\n        Web      bool   `cli:\"-w, --web,        Add body in browser\"`\n\n        // Can embed other structs.\n        Cmd2CommonArgs\n    }\n    mcli.Parse(\u0026args)\n\n    // Do something\n}\n```\n\nAlso, there are some sophisticated examples:\n\n* [github-cli](./examples/github-cli/main.go) mimics Github's cli command `gh`\n* [lego](./examples/lego/main.go) mimics Lego's command `lego`\n\n## API\n\nUse the default App:\n\n- `SetOptions` updates options of the default application.\n- `SetGlobalFlags` sets global flags, global flags are available to all commands.\n- `Add` adds a command.\n- `AddRoot` adds a root command. A root command is executed when no sub command is specified.\n- `AddAlias` adds an alias name for a command.\n- `AddHidden` adds a hidden command.\n- `AddGroup` adds a group explicitly. A group is a common prefix for some commands.\n  It's not required to add group before adding sub commands, but user can use this function\n  to add a description to a group, which will be showed in help.\n- `AddHelp` enables the \"help\" command.\n- `AddCompletion` enables the \"completion\" command to generate autocomplete scripts.\n- `Parse` parses the command line for flags and arguments.\n- `Run` runs the program, it will parse the command line, search for a registered command and run it.\n- `PrintHelp` prints usage doc of the current command to stderr.\n\nCreate a new App instance:\n\n- `NewApp` creates a new cli applcation instance.\n\n### Custom options\n\nApp:\n\n- `App.Options` specifies optional options for an application.\n\nCmdOpt:\n\n- `WithCategory` groups commands into different categories in help.\n- `WithLongDesc` specifies a long description of a command, which will be showed in the command's help.\n- `EnableFlagCompletion` enables flag completion for a command.\n\nParseOpt:\n\n- `WithArgs` tells `Parse` to parse from the given args, instead of parsing from the command line arguments.\n- `WithErrorHandling` tells `Parse` to use the given ErrorHandling.\n  By default, the program exits when an error happens.\n- `WithName` specifies the command name to use when printing usage doc.\n- `DisableGlobalFlags` tells `Parse` to don't parse and print global flags in help.\n- `ReplaceUsage` tells `Parse` to use a custom usage function instead of the default.\n- `WithExamples` specifies examples for a command. Examples will be showed after flags in the help.\n- `WithFooter` adds a footer message after the default help,\n  this option overrides the App's setting `Options.HelpFooter` for this parsing call.\n- `WithArgCompFuncs` specifies functions to suggest flag values and positional arguments programmatically.\n\n## Tag syntax\n\nStruct tag is a powerful feature in Go, `mcli` uses struct tag to define flags and arguments.\n\n* tag `cli` defines the name and description for flags and arguments\n* tag `env` optionally tells Parse to lookup environment variables when user doesn't\n  provide a value on the command line\n* tag `default` optionally provides a default value to a flag or argument,\n  which will be used when the value is not available from both command line and env\n\nThe syntax is\n\n```text\n/* cli tag, only Name is required.\n * Short name and long name are both optional, but at least one must be given.\n * See below for details about modifiers.\n * e.g.\n * - `cli:\"-c, Open the last commit\"`\n * - `cli:\"#R, -b, --branch, Select another branch by passing in the branch name\"`\n * - `cli:\"--an-obvious-flag-dont-need-description\"`\n * - `cli:\"#ER, AWS Secret Access Key\" env:\"AWS_SECRET_ACCESS_KEY\"`\n */\nCliTag       \u003c-  ( Modifiers ',' Space? )? Name ( ( ',' | Space ) Description )?\nModifiers    \u003c-  '#' [DHRE]+\nName         \u003c-  ( ShortName LongName? ) | LongName\nDescription  \u003c-  ( ![\\r\\n] . )*\n\n/* env tag, optional.\n * Multiple environment names can be specified, the first non-empty value takes effect.\n * e.g.\n * - `env:\"SOME_ENV\"`\n * - `env:\"ANOTHER_ENV_1, ANOTHER_ENV_2\"`\n */\nEnvTag  \u003c-  ( EnvName ',' Space? )* EnvName\n\n/* default value tag, optional.\n * e.g.\n * - `default:\"1.5s\"` // duration\n * - `default:\"true\"` // bool\n */\nDefaultValueTag  \u003c-  ( ![\\r\\n] . )*\n```\n\n## Modifiers\n\nModifier represents an option to a flag, it sets the flag to be\ndeprecated, hidden, or required. In a `cli` tag, modifiers appears as\nthe first segment, starting with a `#` character.\n\nFow now the following modifiers are available:\n\n* D - marks a flag or argument as deprecated, \"DEPRECATED\" will be showed in help.\n* R - marks a flag or argument as required, \"REQUIRED\" will be showed in help.\n* H - marks a flag as hidden, see below for more about hidden flags.\n* E - marks an argument read from environment variables, but not command line,\n      environment variables will be showed in a separate section in help.\n\nHidden flags won't be showed in help, except that when a special flag\n\"--mcli-show-hidden\" is provided.\n\nModifier `H` shall not be used for an argument, else it panics.\nAn argument must be showed in help to tell user how to use the program\ncorrectly.\n\nModifier `E` is useful when you want to read an environment variable,\nbut don't want user to provide from command line (e.g. password or other secrets).\nUsing together with `R` also ensures that the env variable must exist.\n\nSome modifiers cannot be used together, else it panics, e.g.\n\n* H \u0026 R - a required flag must appear in help to tell user to set it.\n* D \u0026 R - a required flag must not be deprecated, it does not make sense,\n  but makes user confused.\n\n## Compatibility with package `flag`\n\n`Parse` returns a `*flag.FlagSet` if success, all defined flags are available\nwith the flag set, including both short and long names.\n\nNote that the package `flag` requires command line flags must present before\narguments, this package does not have this requirement.\nPositional arguments can present either before flags or after flags,\neven both before and after flags, in which case, the args will be reordered\nand all arguments can be accessed by calling flagSet.Args() and flagSet.Arg(i).\n\nIf there is slice or map arguments, it will match all following arguments.\n\n## Shell completion\n\n`mcli` supports auto shell completion for `bash`, `zsh`, `fish`, and `powershell`.\nUse `AddCompletion` to enable the feature, run `program help completion [bash|zsh|fish|powershell]`\nfor usage guide.\n\nAlso check `AddCompletion`, `EnableFlagCompletion`, and\n`Options.EnableFlagCompletionForAllCommands` for detail docs about command flag completion.\n\nUser can use `WithArgCompFuncs` to specify functions to suggest flag values and\npositional arguments programmatically, already provided flags and arguments\ncan be accessed in the functions.\n\n## Changelog\n\nSee [CHANGELOG](./CHANGELOG.md) for detailed change history.\n","funding_links":[],"categories":["Command Line","命令行","Build Automation"],"sub_categories":["Standard CLI","标准CLI"],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fjxskiss%2Fmcli","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fjxskiss%2Fmcli","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fjxskiss%2Fmcli/lists"}