{"id":13411207,"url":"https://github.com/omeid/uconfig","last_synced_at":"2026-01-06T00:55:45.609Z","repository":{"id":21403607,"uuid":"90923273","full_name":"omeid/uconfig","owner":"omeid","description":"Lightweight, zero-dependency, and extendable configuration management library for Go","archived":false,"fork":false,"pushed_at":"2024-04-23T03:02:11.000Z","size":127,"stargazers_count":70,"open_issues_count":1,"forks_count":9,"subscribers_count":4,"default_branch":"master","last_synced_at":"2024-07-31T20:45:11.724Z","etag":null,"topics":["config","flags","golang","kubernetes"],"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/omeid.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":"2017-05-11T01:21:44.000Z","updated_at":"2024-02-19T12:25:46.000Z","dependencies_parsed_at":"2024-04-04T05:22:40.896Z","dependency_job_id":"a7ba198f-b0be-48fe-bf65-6c6a0ab03281","html_url":"https://github.com/omeid/uconfig","commit_stats":null,"previous_names":[],"tags_count":8,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/omeid%2Fuconfig","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/omeid%2Fuconfig/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/omeid%2Fuconfig/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/omeid%2Fuconfig/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/omeid","download_url":"https://codeload.github.com/omeid/uconfig/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":243610890,"owners_count":20319046,"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":["config","flags","golang","kubernetes"],"created_at":"2024-07-30T20:01:12.155Z","updated_at":"2026-01-06T00:55:45.598Z","avatar_url":"https://github.com/omeid.png","language":"Go","readme":"# uConfig [![GoDoc](https://img.shields.io/badge/godoc-reference-blue.svg?style=flat-square)](https://godoc.org/github.com/omeid/uconfig) [![Build Status](https://app.travis-ci.com/omeid/uconfig.svg?branch=master)](https://app.travis-ci.com/omeid/uconfig) [![Go Report Card](https://goreportcard.com/badge/github.com/omeid/uconfig)](https://goreportcard.com/report/github.com/omeid/uconfig) [![Coverage](https://gocover.io/_badge/github.com/omeid/uconfig?update)](https://gocover.io/github.com/omeid/uconfig)\n\n\nLightweight, zero-dependency, and extendable configuration management.\n\nuConfig is extremely light and extendable configuration management library with zero dependencies. Every aspect of configuration is provided through a _plugin_, which means you can have any combination of flags, environment variables, defaults, secret providers, Kubernetes Downward API, and any combination of configuration files and formats including json, toml, cue, or just about anything you want, and only what you want, through plugins.\n\n\nTo use uConfig, you simply define the configuration struct for your services and application, and uConfig does all the heavy-lifting. It just works.\n\n## Example Configuration:\n\n```go\npackage database\n// Config holds the database configurations.\ntype Config struct {\n  Address  string `default:\"localhost\"`\n  Port     string `default:\"28015\"`\n  Database string `default:\"my-project\"`\n}\n```\n\n```go\npackage redis\n// Config describes the requirement for redis client.\ntype Config struct {\n  Address  string        `default:\"redis-master\"`\n  Port     string        `default:\"6379\"`\n  Password string        `secret:\"\"`\n  DB       int           `default:\"0\"`\n  Expire   time.Duration `default:\"5s\"`\n}\n```\n\n```go\npackage main\n\nimport (\n\t\"encoding/json\"\n\t\"fmt\"\n\t\"os\"\n\n\t\"github.com/omeid/uconfig\"\n\n\t\"github.com/omeid/uconfig/examples/sample/database\"\n\t\"github.com/omeid/uconfig/examples/sample/redis\"\n)\n\n\n// Config is our application config.\ntype Config struct {\n\t// yes you can have slices.\n\tHosts []string `default:\"localhost,localhost.local\" usage:\"the ip or domains to bind to\"`\n\n\tRedis    redis.Config\n\tDatabase database.Config\n\n\t// the flags plugin allows capturing a single Command after the flags.\n\t// so you can run myprogram -flag=value -s -blah=bleh stop|start|stop and so on.\n\tMode string `default:\"start\" flag:\",command\" usage:\"run|start|stop\"`\n}\n\nvar files = uconfig.Files{\n\t{Path: \"/etc/demo-app/config.json\", Unmarshal: json.Unmarshal, Optional: true},\n\t{Path: \"config.json\", Unmarshal: json.Unmarshal, Optional: true},\n\t// or short form {\"config.json\", json.Unmarshal, true},\n\t// And, of course, you can of course add as many files\n\t// as you want, and they will be applied\n\t// in the given order.\n}\n\nvar conf = uconfig.Classic[Config](files)\n\nfunc main() {\n\tconf := conf.Run()\n\t// use conf as you please.\n\t// let's pretty print it as JSON for example:\n\tconfigAsJson, err := json.MarshalIndent(conf, \"\", \" \")\n\tif err != nil {\n\t\tfmt.Println(err)\n\t\tos.Exit(1)\n\t}\n\n\tfmt.Print(string(configAsJson))\n}\n```\n\nNow lets run our program:\n\n```sh\n$ go run main.go -h\nUsage:\n    main [flags] [command]\n\nConfigurations:\nFIELD                FLAG                  ENV                 DEFAULT                      USAGE\n-----                -----                 -----               -------                      -----\nHosts                -hosts                HOSTS               localhost,localhost.local    the ip or domains to bind to\nRedis.Address        -redis-address        REDIS_ADDRESS       redis-master                 \nRedis.Port           -redis-port           REDIS_PORT          6379                         \nRedis.Password       -redis-password       REDIS_PASSWORD                                   \nRedis.DB             -redis-db             REDIS_DB            0                            \nRedis.Expire         -redis-expire         REDIS_EXPIRE        5s                           \nDatabase.Address     -database-address     DATABASE_ADDRESS    localhost                    \nDatabase.Port        -database-port        SERVICE_PORT        28015                        \nDatabase.Database    -database-database    DB                  my-project                   \nMode                 [command]             MODE                start                        run|start|stop\n\nConfiguration Files:\n    /etc/demo-app/config.json\n    config.json\n\n```\n```sh\n$ go run main.go \n```\n```json\n{\n \"Hosts\": [\n  \"localhost\",\n  \"localhost.local\"\n ],\n \"Redis\": {\n  \"Address\": \"redis-master\",\n  \"Port\": \"6379\",\n  \"Password\": \"\",\n  \"DB\": 0,\n  \"Expire\": 5000000000\n },\n \"Database\": {\n  \"Address\": \"localhost\",\n  \"Port\": \"28015\",\n  \"Database\": \"my-project\"\n },\n \"Mode\": \"start\"\n}\n\n```\n\nuConfig supports all basic types, time.Duration, slices, and any other type through `encoding.TextUnmarshaler` interface.\nSee the _[flat view](https://godoc.org/github.com/omeid/uconfig/flat)_ package for details.\n\n## Custom names:\n\nSometimes you might want to use a different env var, or flag name for backwards compatibility or other reasons, you have two options.\n\n1. uconfig tag\n\nYou can change the name of a field as seen by `uconfig`.\n\nPlease note that this flag only works for walker plugins (flags, env, anything flat) and for Visitor plugins (file, stream, et al) you will need to use encoder specific tags like `json:\"field_name\"` and so on.\n\n\n2. Plugin specific tags\n\nMost plugins support controlling the field name as seen by that specific plugin. For example `env:\"DB_NAME\"`.\n\n\nFor both type of tags, you can prefix them with `.` to rename the field only at the struct level.\nSee the `Service.Port` and `DB_NAME` examples below.\n\n```go\npackage database\n\n// Config holds the database configurations.\ntype Database struct {\n  Address  string `default:\"localhost\"`\n  Port     string `default:\"28015\" uconfig:\".Service.Port\"` // field level rename.\n  Database string `default:\"my-project\" env:\"DB_NAME\" flag:\"main-db-name\"` // plugin specific rename.\n}\n```\n\n\n```go\npackage main\n\n// Config is our application config.\ntype Config struct {\n\n  // yes you can have slices.\n  Hosts    []string `default:\"localhost,localhost.local\"`\n\n  Redis    redis.Config\n  Database database.Config\n}\n```\n\n\nWhich should give you the following settings:\n\n```sh\n$ go run main.go -h\nUsage:\n    main [flags] [command]\n\nConfigurations:\nFIELD                  FLAG                    ENV                    DEFAULT                      USAGE\n-----                  -----                   -----                  -------                      -----\nHosts                  -hosts                  HOSTS                  localhost,localhost.local    the ip or domains to bind to\nRedis.Address          -redis-address          REDIS_ADDRESS          redis-master                 \nRedis.Port             -redis-port             REDIS_PORT             6379                         \nRedis.Password         -redis-password         REDIS_PASSWORD                                      \nRedis.DB               -redis-db               REDIS_DB               0                            \nRedis.Expire           -redis-expire           REDIS_EXPIRE           5s                           \nDatabase.Address       -database-address       DATABASE_ADDRESS       localhost                    \nDatabase.Database      -main-db-db             DB_NAME                my-project\nDatabase.Service.Port  -database-service-port  DATABASE_SERVICE_PORT  28015\n```\n\n\nFor file based plugins, you will need to use the appropriate tags as used by your encoder of choice. For example:\n\n```go\npackage users\n\n// Config holds the database configurations.\ntype Config struct {\n  Host string `json:\"bind_addr\"`\n}\n```\n\n## Secrets Plugin\n[![GoDoc](https://img.shields.io/badge/godoc-reference-blue.svg?style=flat-square)](https://godoc.org/github.com/omeid/uconfig/plugins/secret)\n\nThe secret provider allows you to grab the value of a config from anywhere you want. You simply need to implement the `func(name string) (value string)` function and pass it to the secrets plugin.\n\nUnlike most other plugins, secret requires explicit `secret:\"\"` tag, this is because only specific config values like passwords and api keys come from a secret provider, compared to the rest of the config which can be set in various ways.\n\n```go\npackage main\n\nimport (\n    \"encoding/json\"\n    \"fmt\"\n\n    \"github.com/omeid/uconfig\"\n    \"github.com/omeid/uconfig/plugins/secret\"\n\n    \"github.com/omeid/uconfig/examples/secrets/secretsource\"\n)\n\n// Creds is an example of a config struct that uses secret values.\ntype Creds struct {\n    // by default, secret plugin will generate a name that is identical\n    // to env plugin, SCREAM_SNAKE_CASE, so in this case it will be\n    // APIKEY however, following the standard uConfig nesting rules\n    // in Config struct below, it becomes CREDS_APIKEY.\n    APIKey string `secret:\"\"`\n    // or you can provide your own name, which will not be impacted\n    // by nesting or the field name.\n    APIToken string `secret:\"API_TOKEN\"`\n}\n\ntype Config struct {\n    Creds Creds\n}\n\nvar secrets = secret.New(func(name string) (string, error) {\n    // you're free to grab the secret based on the name from wherever\n    // you please, aws secrets-manager, hashicorp vault, or wherever.\n    value, ok := secretsource.Get(name)\n    if !ok {\n        return \"\", secret.ErrSecretNotFound\n    }\n\n    return value, nil\n})\n\nfunc main() {\n    // then you can use the secretPlugin with uConfig like any other plugin.\n    // Lucky, uconfig.Classic allows passing more plugins, which means\n    // you can simply do the following for flags, envs, files, and secrets!\n    conf := uconfig.Classic[Config](nil, secrets).Run()\n\n    fmt.Printf(\"we got an API Key: %s\\n\", conf.Creds.APIKey)\n}\n```\n\n\n## Tests\n\nFor tests, you may consider the `Must` function to set the defaults, like so\n```go\npackage something\n\nimport (\n  \"testing\"\n\n  \"github.com/omeid/uconfig\"\n  \"github.com/omeid/uconfig/defaults\"\n)\n\nfunc TestSomething(t *testing.T) error {\n\n  // It will panic on error\n    conf := uconfig.Must[Conf](defaults.New())\n\n  // Use your conf as you please.\n}\n\n```\n\nSee the Classic source for how to compose plugins.\nFor more details, see the [godoc](https://godoc.org/github.com/omeid/uconfig).\n\n## Extending uConfig:\n\nuConfig provides a plugin mechanism for adding new sources of configuration.\nThere are two kind of plugins, Walkers and Visitors.\n\nTo implement your own, see the examples.\n\n\n### Visitors\n\nVisitors get a _[flat view](https://godoc.org/github.com/omeid/uconfig/flat)_ of the configuration struct, which is a flat view of the structs regardless of nesting level, for more details see the [flat](https://godoc.org/github.com/omeid/uconfig/flat) package documentation.\n\nPlugins that load the configurations from flat structures (e.g flags, environment variables, default tags) are good candidates for this type of plugin.\nSee [env plugin](plugins/env/env.go) for an example.\n\n### Walkers\n\nWalkers are used for configuration plugins that take the whole config struct and unmarshal the underlying content into the config struct.\nPlugins that load the configuration from files are good candidates for this.\n\nSee [file plugin](plugins/file/file.go) for an example.\n","funding_links":[],"categories":["Configuration","配置","Uncategorized"],"sub_categories":["Standard CLI","Advanced Console UIs","标准CLI"],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fomeid%2Fuconfig","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fomeid%2Fuconfig","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fomeid%2Fuconfig/lists"}