{"id":48986737,"url":"https://github.com/7ched7/gocli","last_synced_at":"2026-04-18T13:03:46.377Z","repository":{"id":337014542,"uuid":"1150507781","full_name":"7ched7/gocli","owner":"7ched7","description":"lightweight CLI framework for Go","archived":false,"fork":false,"pushed_at":"2026-04-13T04:32:28.000Z","size":152,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":0,"default_branch":"main","last_synced_at":"2026-04-13T06:24:17.535Z","etag":null,"topics":["cli","cli-framework","cli-parser","go"],"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/7ched7.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,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2026-02-05T11:09:00.000Z","updated_at":"2026-03-09T14:13:09.000Z","dependencies_parsed_at":null,"dependency_job_id":null,"html_url":"https://github.com/7ched7/gocli","commit_stats":null,"previous_names":["7ched7/gocli"],"tags_count":7,"template":false,"template_full_name":null,"purl":"pkg:github/7ched7/gocli","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/7ched7%2Fgocli","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/7ched7%2Fgocli/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/7ched7%2Fgocli/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/7ched7%2Fgocli/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/7ched7","download_url":"https://codeload.github.com/7ched7/gocli/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/7ched7%2Fgocli/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":31969773,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-04-18T00:39:45.007Z","status":"online","status_checked_at":"2026-04-18T02:00:07.018Z","response_time":103,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"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","cli-framework","cli-parser","go"],"created_at":"2026-04-18T13:03:43.015Z","updated_at":"2026-04-18T13:03:46.360Z","avatar_url":"https://github.com/7ched7.png","language":"Go","readme":"![License: MIT](https://img.shields.io/badge/license-MIT-blue)\n![Test Status](https://github.com/7ched7/gocli/actions/workflows/test.yml/badge.svg)\n\n# gocli 🦦\nA lightweight, dependency-free CLI framework for Go. \n\n## Overview\n**gocli** provides a fluent interface that allows you to define commands, subcommands, and flags in a single, readable format, unlike standard flag parsing. It handles help menu generation, alias mapping, argument validation, error handling, and many other things right out of the box, allowing you to focus on your business logic.\n\n## Installation\n```bash\ngo get github.com/7ched7/gocli@latest\n```\n\n## Quick Start\n```go \npackage main\n\nimport (\n\t\"os\"\n\n\t\"github.com/7ched7/gocli\"\n)\n\nfunc main() {\n\t// Create a new App instance\n\tapp := gocli.NewApp(\"mycli\").WithVersion(\"0.1.0\")\n\n\tnameFlag := gocli.NewStringFlag(\"name\", \"Guest\").WithAlias(\"n\")\n\n\tapp.\n\t\tAddGlobalFlag(nameFlag).\n\t\tWithMinArg(1).\n\t\tWithMaxArg(1).\n\t\tWithAction(func(ctx *gocli.Context) error {\n\t\t\tname := ctx.String(\"name\")\n\t\t\tmessage := ctx.Args()[0]\n\n\t\t\treturn gocli.Exitf(0, \"Hey %s! %s\", name, message)\n\t\t})\n\n\tos.Exit(app.Run())\n}\n```\n\n**Execution Example**\n```console\n$ mycli -nJohn \"How are you?\"\nHey John! How are you?\n```\n\n## Features\n### Commands \u0026 Subcommands\nThis framework lets you define standalone commands and organize them hierarchically using subcommands.\n\nTo create a new command, you can simply use the `NewCommand` method provided by the API. \n```go\nserverCmd := gocli.NewCommand(\"server\")\n```\n\nOnce defined, register the command by passing it to the `AddCommand` method of the app instance.\n```go\napp.AddCommand(serverCmd)\n```\n\nIf your project requires nested commands, you can register the command directly within a parent command using the `AddSubcommand` method.\n```go\nstartCmd := gocli.NewCommand(\"start\").\n\tWithAction(func(ctx *gocli.Context) error {\n\t\tfmt.Println(\"Server is up and running!\")\n\t\treturn nil\n\t})\n\nserverCmd.AddSubcommand(startCmd)\n```\n\nIf you don't want to mess around with variables, simply call the `NewCommand` method directly inside the `AddCommand` method. This is the another way also.\n```go\napp.AddCommand(gocli.NewCommand(\"server\"))\n```\n\n**Execution Example**\n```console\n$ mycli server start \nServer is up and running!\n```\n\n### Flags\nFlags are created using type-specific helper methods and then registered on a command using the `AddFlag` method.\n```go\nipFlag := gocli.NewStringFlag(\"ip\", \"\")\nstartCmd.AddFlag(ipFlag)\n```\n\nYou can also add flags globally. Simply pass the flag to the `AddGlobalFlag` method of the app instance. No matter which command you run, the global flags will always be available. \n```go\nverboseFlag := gocli.NewBoolFlag(\"verbose\", false)\napp.AddGlobalFlag(verboseFlag)\n```\n\nIn this framework, flags are accessed in two main ways:\n- [Variable Binding](#variable-binding) - bind the variable to the flag\n- [Dynamic Access via Context](#dynamic-access-via-context) - access the flag at runtime\n\n#### Variable Binding\nWith variable binding, the flag value is automatically stored in a predefined variable. This is useful when you want simple and direct access to the value.\n```go\nvar ip string = \"127.0.0.1\"\n\nipFlag := gocli.NewStringFlagVar(\"ip\", \u0026ip).WithAlias(\"i\")\n\nstartCmd.AddFlag(ipFlag).\n\tWithAction(func(ctx *gocli.Context) error {\n\t\tfmt.Printf(\"IP address: %s\\n\", ip) // Direct access\n\t\treturn nil\n\t})\n```\n\n#### Dynamic Access via Context\nAnother approach is to retrieve the flag value from the **Context** during execution. This is more flexible than binding approach and can be used when multiple flags are involved.\n```go\nportFlag := gocli.NewIntFlag(\"port\", 0).WithAlias(\"p\")\n\nstartCmd.AddFlag(portFlag).\n\tWithAction(func(ctx *gocli.Context) error {\n\t\tport := ctx.Int(\"port\") // Get flag value from context\n\t\tfmt.Printf(\"IP address: %s\\n\", ip)\n\t\tfmt.Printf(\"Port: %d\\n\", port)\n\t\treturn nil\n\t})\n```\n\n**Execution Example**\n```console\n$ mycli server start -i 127.0.0.1 -p 8000\nIP address: 127.0.0.1\nPort: 8000\n```\n\n### Custom Validator\nFlags may need to be validated to ensure they meet specific conditions. In such cases, you can use the `WithValidator` method on the flag to validate the flag value just before the action is triggered.\n```go\nportFlag.WithValidator(func(ctx *gocli.Context, value int) error {\n\tif value \u003c 1 || value \u003e 65535 {\n\t\treturn fmt.Errorf(\"invalid port number: %d\", value)\n\t}\n\treturn nil\n})\n```\n\n**Execution Example**\n```console\n$ mycli server start -i 127.0.0.1 -p 80000\ninvalid port number: 80000\n```\n\nThe **Context** allows you to write more complex controls by providing access to other flag values.\n```go\nip := ctx.String(\"ip\")\n\nif ip == \"127.0.0.1\" \u0026\u0026 value == 8080 {\n\treturn fmt.Errorf(\"port already in use: %s:%d\", ip, value)\n}\n```\n\n**Execution Example**\n```console\n$ mycli server start -i 127.0.0.1 -p 8080\nport already in use: 127.0.0.1:8080\n```\n\n### Custom Types\nThis framework doesn’t support every type out of the box. Instead, it lets you define and integrate custom types by implementing the **FlagValue** interface, which closely mirrors Go’s standard [flag.Value](https://pkg.go.dev/flag#Value).\n\nThe first step is to wrap your desired data type within a struct. This struct acts as a container that the framework will interact with during the flag lifecycle.\n```go\ntype IP struct {\n\tvalue net.IP\n}\n```\n\nThe `Set(string)` method is the core of your custom type. The framework calls this method whenever it encounters your flag in the CLI. It is responsible for converting the raw string input into your internal data type.\n```go\nfunc (i *IP) Set(value string) error {\n\tif ip := net.ParseIP(value); ip != nil {\n\t\ti.value = ip\n\t\treturn nil\n\t}\n\treturn fmt.Errorf(\"invalid IP address: %s\", value)\n}\n```\n\nTo retrieve the processed data back, you need to implement the `Get()` method. This returns the underlying value as **any** type.\n```go\nfunc (i *IP) Get() any { \n\treturn i.value \n}\n```\n\nThe `String()` method is implemented to satisfy the [Stringer](https://go.dev/tour/methods/17) interface. It represents either the current value or a hint about the expected format.\n```go\nfunc (i *IP) String() string { \n\treturn i.value.String() \n}\n```\n\nOnce your struct satisfies the **FlagValue** interface, you can integrate it into the flag using the `NewCustomFlagVar` method provided by the API. Simply create a typed variable and bind it.\n```go\nvar ip IP\nipFlag := gocli.NewCustomFlagVar(\"ip\", \u0026ip).WithAlias(\"i\")\n```\n\n**Execution Example**\n```console\n$ mycli server start -i 256.168.1.1\ninvalid IP address: 256.168.1.1\n```\n\n### Configurations\nThis framework offers a flexible configuration system that allows you to customize core behaviors.\n\n#### Customizing Default Flags\nBy default, framework comes with standard flags like **--help** and **--version**. You are free to customize them to better suit your own style and needs.\n```go\nconf := gocli.DefaultAppConfig()\n\n// Override the version flag alias (e.g., using -V instead of -v)\nconf.VersionFlag = gocli.DefaultVersionFlag().WithAlias(\"V\")\n\napp.WithConfig(conf)\n```\n\n**Execution Example**\n```console\n$ mycli -V\nmycli version 0.1.0\n```\n\n#### Customizing System Messages\nOne of the core features of the framework is the ability to override default system messages. Using `CustomMessages`, you can provide a more user-friendly output.\t \n\nSimply define a **MessagesMap** and assign a custom function to the specific message type you want to override.\n```go\nconf.CustomMessages = gocli.MessagesMap{\n\tgocli.MsgUnknownCommand: func(msgCtx gocli.MessageContext) error {\n\t\treturn fmt.Errorf(\"invalid command\")\n\t},\n}\n```\n\n**Execution Example**\n```console\n$ mycli servr\ninvalid command\n```\n\nFor more advanced scenarios, the **MessageContext** gives you access to detailed runtime state. This makes it possible to generate dynamic messages.\n```go\nunkCommand := msgCtx.Msg().Data()[\"command\"] // Access the entered invalid command\ncommands := msgCtx.App().Commands() // All registered commands in app instance\n\nvar sb strings.Builder\n\nsb.WriteString(\"invalid command: \")\nsb.WriteString(unkCommand)\nsb.WriteString(\"\\navailable commands:\\n\")\n\nfor _, cmd := range commands {\n\tsb.WriteString(\"- \")\n\tsb.WriteString(cmd.Name())\n\tsb.WriteString(\"\\n\")\n}\n\nreturn fmt.Errorf(sb.String())\n```\n\n**Execution Example**\n```console\n$ mycli servr\ninvalid command: servr\navailable commands:\n- server\n```\n\nSee the [documentation](https://pkg.go.dev/github.com/7ched7/gocli) for more information.\n","funding_links":[],"categories":[],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2F7ched7%2Fgocli","html_url":"https://awesome.ecosyste.ms/projects/github.com%2F7ched7%2Fgocli","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2F7ched7%2Fgocli/lists"}