{"id":16540946,"url":"https://github.com/itzg/go-flagsfiller","last_synced_at":"2025-05-16T16:09:16.867Z","repository":{"id":38323243,"uuid":"222013767","full_name":"itzg/go-flagsfiller","owner":"itzg","description":"Bring your own struct and make Go's flag package pleasant to use","archived":false,"fork":false,"pushed_at":"2025-03-15T15:15:51.000Z","size":88,"stargazers_count":32,"open_issues_count":3,"forks_count":9,"subscribers_count":2,"default_branch":"master","last_synced_at":"2025-04-12T15:57:11.928Z","etag":null,"topics":[],"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/itzg.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE.txt","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":"2019-11-15T22:31:39.000Z","updated_at":"2025-03-15T15:15:53.000Z","dependencies_parsed_at":"2023-01-30T05:01:16.657Z","dependency_job_id":"afc80269-7e32-404c-8610-4f9df44617c0","html_url":"https://github.com/itzg/go-flagsfiller","commit_stats":null,"previous_names":[],"tags_count":22,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/itzg%2Fgo-flagsfiller","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/itzg%2Fgo-flagsfiller/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/itzg%2Fgo-flagsfiller/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/itzg%2Fgo-flagsfiller/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/itzg","download_url":"https://codeload.github.com/itzg/go-flagsfiller/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":254564127,"owners_count":22092122,"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":[],"created_at":"2024-10-11T18:53:42.767Z","updated_at":"2025-05-16T16:09:16.848Z","avatar_url":"https://github.com/itzg.png","language":"Go","funding_links":[],"categories":[],"sub_categories":[],"readme":"# go-flagsfiller\n\n[![](https://godoc.org/github.com/itzg/go-flagsfiller?status.svg)](https://godoc.org/github.com/itzg/go-flagsfiller)\n[![](https://img.shields.io/badge/go.dev-module-007D9C)](https://pkg.go.dev/github.com/itzg/go-flagsfiller)\n\nBring your own struct and make Go's flag package pleasant to use.\n\n## Install\n\n```\ngo get github.com/itzg/go-flagsfiller\n```\n\n## Import\n\n```go\nimport \"github.com/itzg/go-flagsfiller\"\n```\n\n## Features\n\n- Populates Go's [flag.FlagSet](https://golang.org/pkg/flag/#FlagSet) from a struct of your choosing\n- By default, field names are converted to flag names using [kebab-case](https://en.wiktionary.org/wiki/kebab_case), but can be configured.\n- Use nested structs where flag name is prefixed by the nesting struct field names\n- Allows defaults to be given via struct tag `default`\n- Falls back to using instance field values as declared default\n- Declare flag usage via struct tag `usage`\n- Can be combined with other modules, such as [google/subcommands](https://github.com/google/subcommands) for sub-command processing. Can also be integrated with [spf13/cobra](https://github.com/spf13/cobra) by using pflag's [AddGoFlagSet](https://godoc.org/github.com/spf13/pflag#FlagSet.AddGoFlagSet)\n- Beyond the standard types supported by flag.FlagSet also includes support for:\n    - `[]string` where repetition of the argument appends to the slice and/or an argument value can contain a comma or newline-separated list of values. For example: `--arg one --arg two,three`\n    - `map[string]string` where each entry is a `key=value` and/or repetition of the arguments adds to the map or multiple entries can be comma or newline-separated in a single argument value. For example: `--arg k1=v1 --arg k2=v2,k3=v3`\n\t- `time.Time` parse via time.Parse(), with tag `layout` specify the layout string, default is \"2006-01-02 15:04:05\"\n\t- `net.IP` parse via net.ParseIP()\n\t- `net.IPNet` parse via net.ParseCIDR()\n\t- `net.HardwareAddr` parse via net.ParseMAC()\n\t- and all types that implement encoding.TextUnmarshaler interface\n- Optionally set flag values from environment variables. Similar to flag names, environment variable names are derived automatically from the field names\n- New types could be supported via user code, via `RegisterSimpleType(ConvertFunc)`, check [time.go](time.go) and [net.go](net.go) to see how it works\n\t- note: in case of a registered type also implements encoding.TextUnmarshaler, then registered type's ConvertFunc is preferred \n\n## Quick example\n\n```go\npackage main\n\nimport (\n\t\"flag\"\n\t\"fmt\"\n\t\"github.com/itzg/go-flagsfiller\"\n\t\"log\"\n\t\"time\"\n)\n\ntype Config struct {\n\tHost         string        `default:\"localhost\" usage:\"The remote host\"`\n\tDebugEnabled bool          `default:\"true\" usage:\"Show debugs\"`\n\tMaxTimeout   time.Duration `default:\"5s\" usage:\"How long to wait\"`\n\tFeature      struct {\n\t\tFaster         bool `usage:\"Go faster\"`\n\t\tLudicrousSpeed bool `usage:\"Go even faster\"`\n\t}\n}\n\nfunc main() {\n\tvar config Config\n    \n    // create a FlagSetFiller\n\tfiller := flagsfiller.New()\n    // fill and map struct fields to flags\n\terr := filler.Fill(flag.CommandLine, \u0026config)\n\tif err != nil {\n\t\tlog.Fatal(err)\n\t}\n\n    // parse command-line like usual\n\tflag.Parse()\n\n\tfmt.Printf(\"Loaded: %+v\\n\", config)\n}\n```\n\nThe following shows an example of the usage provided when passing `--help`:\n```\n  -debug-enabled\n    \tShow debugs (default true)\n  -feature-faster\n    \tGo faster\n  -feature-ludicrous-speed\n    \tGo even faster\n  -host string\n    \tThe remote host (default \"localhost\")\n  -max-timeout duration\n    \tHow long to wait (default 5s)\n```\n\n## Real world example\n\n[saml-auth-proxy](https://github.com/itzg/saml-auth-proxy) shows an end-to-end usage of flagsfiller where the main function fills the flags, maps those to environment variables with [envy](https://github.com/jamiealquiza/envy), and parses the command line:\n\n```go\nfunc main() {\n\tvar serverConfig server.Config\n\n\tfiller := flagsfiller.New()\n\terr := filler.Fill(flag.CommandLine, \u0026serverConfig)\n\tif err != nil {\n\t\tlog.Fatal(err)\n\t}\n\n\tenvy.Parse(\"SAML_PROXY\")\n\tflag.Parse()\n```\n\nwhere `server.Config` is declared as\n\n```go\ntype Config struct {\n\tVersion                 bool              `usage:\"show version and exit\"`\n\tBind                    string            `default:\":8080\" usage:\"host:port to bind for serving HTTP\"`\n\tBaseUrl                 string            `usage:\"External URL of this proxy\"`\n\tBackendUrl              string            `usage:\"URL of the backend being proxied\"`\n\tIdpMetadataUrl          string            `usage:\"URL of the IdP's metadata XML\"`\n\tIdpCaPath               string            `usage:\"Optional path to a CA certificate PEM file for the IdP\"`\n    // ...see https://github.com/itzg/saml-auth-proxy/blob/master/server/server.go for full set\n}\n```\n\n## Using with google/subcommands\n\nFlagsfiller can be used in combination with [google/subcommands](https://github.com/google/subcommands) to fill both global command-line flags and subcommand flags.\n\nFor the global flags, it is best to declare a struct type, such as\n\n```go\ntype GlobalConfig struct {\n\tDebug bool `usage:\"enable debug logging\"`\n}\n```\n\nPrior to calling `Execute` on the subcommands' `Commander`, fill and parse the global flags like normal:\n\n```go\nfunc main() {\n    //... register subcommands here\n\n\tvar globalConfig GlobalConfig\n\n\terr := flagsfiller.Parse(\u0026globalConfig)\n\tif err != nil {\n\t\tlog.Fatal(err)\n\t}\n\n    //... execute subcommands but pass global config\n\tos.Exit(int(subcommands.Execute(context.Background(), \u0026globalConfig)))\n}\n```\n\nEach of your subcommand struct types should contain the flag fields to fill and parse, such as:\n\n```go\ntype connectCmd struct {\n\tHost string `usage:\"the hostname of the server\" env:\"GITHUB_TOKEN\"`\n\tPort int `usage:\"the port of the server\" default:\"8080\"`\n}\n```\n\nYour implementation of `SetFlags` will use flagsfiller to fill the definition of the subcommand's flagset, such as:\n\n```go\nfunc (c *connectCmd) SetFlags(f *flag.FlagSet) {\n\tfiller := flagsfiller.New()\n\terr := filler.Fill(f, c)\n\tif err != nil {\n\t\tlog.Fatal(err)\n\t}\n}\n```\n\nFinally, your subcommand's `Execute` function can accept the global config passed from the main `Execute` call and access its own fields populated from the subcommand flags:\n\n```go\nfunc (c *loadFromGitCmd) Execute(ctx context.Context, f *flag.FlagSet, args ...interface{}) subcommands.ExitStatus {\n\tglobalConfig := args[0].(*GlobalConfig)\n    if globalConfig.Debug {\n        //... enable debug logs\n    }\n\n    // ...operate on subcommand flags, such as\n    conn, err := net.Dial(\"tcp\", fmt.Sprintf(\"%s:%d\", c.Host, c.Port))\n}\n```\n## More information\n\n[Refer to the GoDocs](https://godoc.org/github.com/itzg/go-flagsfiller) for more information about this module.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fitzg%2Fgo-flagsfiller","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fitzg%2Fgo-flagsfiller","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fitzg%2Fgo-flagsfiller/lists"}