All Projects → segmentio → Conf

segmentio / Conf

Licence: mit
Go package for loading program configuration from multiple sources.

Programming Languages

go
31211 projects - #10 most used programming language
golang
3204 projects

Projects that are alternatives of or similar to Conf

Andhow
Strongly typed, validated, easy to use Java configuration
Stars: ✭ 17 (-75.71%)
Mutual labels:  command-line, configuration, command-line-parser
Env
Simple lib to parse environment variables to structs
Stars: ✭ 2,164 (+2991.43%)
Mutual labels:  environment-variables, environment, configuration
Phpdotenv
Loads environment variables from `.env` to `getenv()`, `$_ENV` and `$_SERVER` automagically.
Stars: ✭ 11,648 (+16540%)
Mutual labels:  environment, configuration, environment-variables
Fig
A minimalist Go configuration library
Stars: ✭ 142 (+102.86%)
Mutual labels:  environment, environment-variables, configuration
Aconfig
Simple, useful and opinionated config loader.
Stars: ✭ 187 (+167.14%)
Mutual labels:  command-line, environment-variables, configuration
Environ Config
Python Application Configuration With Environment Variables
Stars: ✭ 210 (+200%)
Mutual labels:  environment, environment-variables, configuration
Konfig
Simple config properties API for Kotlin
Stars: ✭ 249 (+255.71%)
Mutual labels:  environment-variables, configuration, command-line-parser
dart environment config
Environment specific config generator for Dart and Flutter applications during CI/CD builds
Stars: ✭ 87 (+24.29%)
Mutual labels:  environment, configuration, environment-variables
ngx-env
Easily inject environment variables into your Angular applications
Stars: ✭ 73 (+4.29%)
Mutual labels:  environment, configuration, environment-variables
Common Env
🔑 The only configuration library you will ever need
Stars: ✭ 67 (-4.29%)
Mutual labels:  environment, configuration
envkeygo
EnvKey's official Go client library
Stars: ✭ 36 (-48.57%)
Mutual labels:  configuration, environment-variables
envconfig-rs
Build a config structure from environment variables in Rust without boilerplate
Stars: ✭ 135 (+92.86%)
Mutual labels:  environment, configuration
environment
🌳 Environment variable configuration for Node.js made easy.
Stars: ✭ 12 (-82.86%)
Mutual labels:  environment, configuration
envy
Use envy to manage environment variables with your OS keychain
Stars: ✭ 23 (-67.14%)
Mutual labels:  environment, environment-variables
Variable Injector
Continuous Integration Tool for Swift Projects
Stars: ✭ 63 (-10%)
Mutual labels:  environment, environment-variables
envkey-ruby
EnvKey's official Ruby client library
Stars: ✭ 24 (-65.71%)
Mutual labels:  configuration, environment-variables
Confex
Useful helper to read and use application configuration from environment variables.
Stars: ✭ 272 (+288.57%)
Mutual labels:  environment-variables, configuration
Caporal.js
A full-featured framework for building command line applications (cli) with node.js
Stars: ✭ 3,279 (+4584.29%)
Mutual labels:  command-line, command-line-parser
angular-environment
AngularJS Environment Plugin
Stars: ✭ 78 (+11.43%)
Mutual labels:  environment, environment-variables
Picocli
Picocli is a modern framework for building powerful, user-friendly, GraalVM-enabled command line apps with ease. It supports colors, autocompletion, subcommands, and more. In 1 source file so apps can include as source & avoid adding a dependency. Written in Java, usable from Groovy, Kotlin, Scala, etc.
Stars: ✭ 3,286 (+4594.29%)
Mutual labels:  command-line, command-line-parser

conf CircleCI Go Report Card GoDoc

Go package for loading program configuration from multiple sources.

Motivations

Loading program configurations is usually done by parsing the arguments passed to the command line, and in this case the standard library offers a good support with the flag package.
However, there are times where the standard is just too limiting, for example when the program needs to load configuration from other sources (like a file, or the environment variables).
The conf package was built to address these issues, here were the goals:

  • Loading the configuration has to be type-safe, there were other packages available that were covering the same use-cases but they often required doing type assertions on the configuration values which is always an opportunity to get the program to panic.

  • Keeping the API minimal, while the flag package offered the type safety we needed it is also very verbose to setup. With conf, only a single function call is needed to setup and load the entire program configuration.

  • Supporting richer syntaxes, because program configurations are often generated dynamically, the conf package accepts YAML values as input to all configuration values. It also has support for sub-commands on the command line, which is a common approach used by CLI tools.

  • Supporting multiple sources, because passing values through the command line is not always the best appraoch, programs may need to receive their configuration from files, environment variables, secret stores, or other network locations.

Basic Usage

A program using the conf package needs to declare a struct which is passed to conf.Load to populate the fields with the configuration that was made available at runtime through a configuration file, environment variables or the program arguments.

Each field of the structure may declare a conf tag which sets the name of the property, and a help tag to provide a help message for the configuration.

The conf package will automatically understand the structure of the program configuration based on the struct it receives, as well as generating the program usage and help messages if the -h or -help options are passed (or an error is detected).

The conf.Load function adds support for a -config-file option on the program arguments which accepts the path to a file that the configuration may be loaded from as well.

Here's an example of how a program would typically use the package:

package main

import (
    "fmt"

    "github.com/segmentio/conf"
)

func main() {
    var config struct {
        Message string `conf:"m" help:"A message to print."`
    }

    // Load the configuration, either from a config file, the environment or the program arguments.
    conf.Load(&config)

    fmt.Println(config.Message)
}
$ go run ./example.go -m 'Hello World!'
Hello World!

Environment Variables

By default, conf will look for environment variables before loading command-line configuration flags with one important caveat: environment variables are prefixed with the program name. For example, given a program named "foobar":

func main() {
	config := struct {
		Name string `conf:"name"`
	}{
		Name: "default",
	}
	conf.Load(&config)
	fmt.Println("Hello", config.Name)
}

The following will be output:

$ ./foobar                                    // "Hello default"
$ FOOBAR_NAME=world ./foobar                  // "Hello world"
$ FOOBAR_NAME=world ./foobar --name neighbor  // "Hello neighbor"
$ MAIN_NAME=world go run main.go              // "Hello world"

If you want to hard-code the prefix to guarantee immutability or just to customize it, you can supply a custom loader config:

loader := conf.Loader{
	Name: "my-service",
	Args: os.Args[1:],
	Sources: []conf.Source{
		conf.NewEnvSource("MY_SVC", os.Environ()...),
	},
}
conf.LoadWith(&config, loader)

Advanced Usage

While the conf.Load function is good enough for common use cases, programs sometimes need to customize the default behavior.
A program may then use the conf.LoadWith function, which accepts a conf.Loader as second argument to gain more control over how the configuration is loaded.

Here's the conf.Loader definition:

package conf

type Loader struct {
     Name     string    // program name
     Usage    string    // program usage
     Args     []string  // list of arguments
     Commands []Command // list of commands
     Sources  []Source  // list of sources to load configuration from.
}

The conf.Load function is actually just a wrapper around conf.LoadWith that passes a default loader. The default loader gets the program name from the first program argument, supports no sub-commands, and has two custom sources setup to potentially load its configuration from a configuration file or the environment variables.

Here's an example showing how to configure a CLI tool that supports a couple of sub-commands:

package main

import (
    "fmt"

    "github.com/segmentio/conf"
)

func main() {
    // If nil is passed instead of a configuration struct no arguments are
    // parsed, only the command is extracted.
    cmd, args := conf.LoadWith(nil, conf.Loader{
        Name:     "example",
        Args:     os.Args[1:],
        Commands: []conf.Command{
            {"print", "Print the message passed to -m"},
            {"version", "Show the program version"},
        },
    })

    switch cmd {
    case "print":
        var config struct{
            Message string `conf:"m" help:"A message to print."`
        }

        conf.LoadWith(&config, conf.Loader{
            Name: "example print",
            Args: args,
        })

        fmt.Println(config.Message)

    case "version":
        fmt.Println("1.2.3")
    }
}
$ go run ./example.go version
1.2.3
$ go run ./example.go print -m 'Hello World!'
Hello World!

Custom Sources

We mentionned the conf.Loader type supported setting custom sources that the program configuration can be loaded from. Here's the the conf.Source interface definition:

package conf

type Source interface {
    Load(dst Map)
}

The source has a single method which receives a conf.Map value which is an itermediate representation of the configuration struct that was received by the loader.
The package uses this type internally as well for loading configuration values from the program arguments, it can be seen as a reflective representiong of the original value which exposes an API that is more convenient to use that having a raw reflect.Value.

One of the advantages of the conf.Map type is that it implements the objconv.ValueDecoder interface and therefore can be used directly to load configurations from a serialized format (like JSON for example).

Validation

Last but not least, the conf package also supports automatic validation of the fields in the configuration struct. This happens after the values were loaded and is based on gopkg.in/validator.v2.

This step could have been done outside the package however it is both convenient and useful to have all configuration errors treated the same way (getting the usage and help message shown when something is wrong).

Note that the project description data, including the texts, logos, images, and/or trademarks, for each open source project belongs to its rightful owner. If you wish to add or remove any projects, please contact us at [email protected].