{"id":21331551,"url":"https://github.com/lukechampine/flagg","last_synced_at":"2025-07-12T10:30:49.318Z","repository":{"id":57497118,"uuid":"102310361","full_name":"lukechampine/flagg","owner":"lukechampine","description":"Barebones subcommand handling","archived":false,"fork":false,"pushed_at":"2019-06-02T18:44:54.000Z","size":20,"stargazers_count":57,"open_issues_count":0,"forks_count":3,"subscribers_count":4,"default_branch":"master","last_synced_at":"2024-10-21T09:15:25.135Z","etag":null,"topics":["cli","flags"],"latest_commit_sha":null,"homepage":null,"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/lukechampine.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-09-04T02:27:59.000Z","updated_at":"2024-04-05T23:13:57.000Z","dependencies_parsed_at":"2022-09-03T23:20:33.791Z","dependency_job_id":null,"html_url":"https://github.com/lukechampine/flagg","commit_stats":null,"previous_names":[],"tags_count":3,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/lukechampine%2Fflagg","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/lukechampine%2Fflagg/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/lukechampine%2Fflagg/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/lukechampine%2Fflagg/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/lukechampine","download_url":"https://codeload.github.com/lukechampine/flagg/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":225814913,"owners_count":17528295,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","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","flags"],"created_at":"2024-11-21T22:42:16.693Z","updated_at":"2024-11-21T22:42:17.275Z","avatar_url":"https://github.com/lukechampine.png","language":"Go","readme":"flagg\n-----\n\n[![GoDoc](https://godoc.org/lukechampine.com/flagg?status.svg)](https://godoc.org/lukechampine.com/flagg)\n[![Go Report Card](http://goreportcard.com/badge/lukechampine.com/flagg)](https://goreportcard.com/report/lukechampine.com/flagg)\n\n```\ngo get lukechampine.com/flagg\n```\n\n`flagg` is a tiny package that makes it easier to build CLI apps that use\nsubcommands. I built it because the stdlib `flag` package is too low-level,\nbut popular alternatives like `spf13/cobra` are full-fledged frameworks with\ntoo many bells and whistles for my liking. `flagg` is 67 lines of code and\nimports only stdlib packages.\n\n`flagg` is designed around the stdlib `*flag.FlagSet` type. You represent each\nsubcommand in your app with a `*flag.FlagSet`, and arrange them into a hierarchy\nwith `flagg.Tree`. Then just call `flagg.Parse` to parse the subcommand selected\nby `os.Args`.\n\n## Example\n\n```go\n// commands are just *flag.FlagSets\nvar rootCmd *flag.FlagSet = flagg.Root\nrootCmd.Usage = flagg.SimpleUsage(rootCmd, \"An example program\")\nverbose := rootCmd.Bool(\"v\", false, \"display verbose output\")\n\n// flagg.New constructs a *flag.FlagSet with the given name and usage\n// description\nfooCmd := flagg.New(\"foo\", \"The foo subcommand\")\nbars := fooCmd.Int(\"bars\", 0, \"number of bars to foo\")\nquuxCmd := flagg.New(\"quux\", \"The quux subcommand\")\n\n// construct the command hierarchy\ntree := flagg.Tree{\n\tCmd: rootCmd,\n\tSub: []flagg.Tree{\n\t\t{Cmd: fooCmd},\n\t\t{Cmd: quuxCmd},\n\t},\n}\n\n// Parse the command hierarchy. cmd is the selected command, e.g. if\n// os.Args = []string{\"./example\", \"quux\"}, then cmd == quuxCmd.\ncmd := flagg.Parse(tree)\n\n// again, cmd is just a *flag.FlagSet, so Args() returns the arguments of the\n// selected command.\nargs := cmd.Args()\n\n// use a switch to identify the cmd that was selected\nswitch cmd {\ncase fooCmd:\n\tfmt.Printf(\"fooing %v bars\\n\", *bars)\ncase quuxCmd:\n\tfmt.Println(\"quux!\", args)\n}\n```\n","funding_links":[],"categories":[],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Flukechampine%2Fflagg","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Flukechampine%2Fflagg","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Flukechampine%2Fflagg/lists"}