Golang Configuration tool that support YAML, JSON, TOML, Shell Environment

Configor

Golang Configuration tool that support YAML, JSON, TOML, Shell Environment (Supports Go 1.10+)

wercker status

Usage

package main

import (
	"fmt"
	"github.com/jinzhu/configor"
)

var Config = struct {
	APPName string `default:"app name"`

	DB struct {
		Name     string
		User     string `default:"root"`
		Password string `required:"true" env:"DBPassword"`
		Port     uint   `default:"3306"`
	}

	Contacts []struct {
		Name  string
		Email string `required:"true"`
	}
}{}

func main() {
	configor.Load(&Config, "config.yml")
	fmt.Printf("config: %#v", Config)
}

With configuration file config.yml:

appname: test

db:
    name:     test
    user:     test
    password: test
    port:     1234

contacts:
- name: i test
  email: [email protected]

Debug Mode & Verbose Mode

Debug/Verbose mode is helpful when debuging your application, debug mode will let you know how configor loaded your configurations, like from which file, shell env, verbose mode will tell you even more, like those shell environments configor tried to load.

// Enable debug mode or set env `CONFIGOR_DEBUG_MODE` to true when running your application
configor.New(&configor.Config{Debug: true}).Load(&Config, "config.json")

// Enable verbose mode or set env `CONFIGOR_VERBOSE_MODE` to true when running your application
configor.New(&configor.Config{Verbose: true}).Load(&Config, "config.json")

Auto Reload Mode

Configor can auto reload configuration based on time

// auto reload configuration every second
configor.New(&configor.Config{AutoReload: true}).Load(&Config, "config.json")

// auto reload configuration every minute
configor.New(&configor.Config{AutoReload: true, AutoReloadInterval: time.Minute}).Load(&Config, "config.json")

Auto Reload Callback

configor.New(&configor.Config{AutoReload: true, AutoReloadCallback: func(config interface{}) {
    fmt.Printf("%v changed", config)
}}).Load(&Config, "config.json")

Advanced Usage

  • Load mutiple configurations
// Earlier configurations have higher priority
configor.Load(&Config, "application.yml", "database.json")
  • Return error on unmatched keys

Return an error on finding keys in the config file that do not match any fields in the config struct. In the example below, an error will be returned if config.toml contains keys that do not match any fields in the ConfigStruct struct. If ErrorOnUnmatchedKeys is not set, it defaults to false.

Note that for json files, setting ErrorOnUnmatchedKeys to true will have an effect only if using go 1.10 or later.

err := configor.New(&configor.Config{ErrorOnUnmatchedKeys: true}).Load(&ConfigStruct, "config.toml")
  • Load configuration by environment

Use CONFIGOR_ENV to set environment, if CONFIGOR_ENV not set, environment will be development by default, and it will be test when running tests with go test

// config.go
configor.Load(&Config, "config.json")

$ go run config.go
// Will load `config.json`, `config.development.json` if it exists
// `config.development.json` will overwrite `config.json`'s configuration
// You could use this to share same configuration across different environments

$ CONFIGOR_ENV=production go run config.go
// Will load `config.json`, `config.production.json` if it exists
// `config.production.json` will overwrite `config.json`'s configuration

$ go test
// Will load `config.json`, `config.test.json` if it exists
// `config.test.json` will overwrite `config.json`'s configuration

$ CONFIGOR_ENV=production go test
// Will load `config.json`, `config.production.json` if it exists
// `config.production.json` will overwrite `config.json`'s configuration
// Set environment by config
configor.New(&configor.Config{Environment: "production"}).Load(&Config, "config.json")
  • Example Configuration
// config.go
configor.Load(&Config, "config.yml")

$ go run config.go
// Will load `config.example.yml` automatically if `config.yml` not found and print warning message
  • Load From Shell Environment
$ CONFIGOR_APPNAME="hello world" CONFIGOR_DB_NAME="hello world" go run config.go
// Load configuration from shell environment, it's name is {{prefix}}_FieldName
// You could overwrite the prefix with environment CONFIGOR_ENV_PREFIX, for example:
$ CONFIGOR_ENV_PREFIX="WEB" WEB_APPNAME="hello world" WEB_DB_NAME="hello world" go run config.go

// Set prefix by config
configor.New(&configor.Config{ENVPrefix: "WEB"}).Load(&Config, "config.json")
  • Anonymous Struct

Add the anonymous:"true" tag to an anonymous, embedded struct to NOT include the struct name in the environment variable of any contained fields. For example:

type Details struct {
	Description string
}

type Config struct {
	Details `anonymous:"true"`
}

With the anonymous:"true" tag specified, the environment variable for the Description field is CONFIGOR_DESCRIPTION. Without the anonymous:"true"tag specified, then environment variable would include the embedded struct name and be CONFIGOR_DETAILS_DESCRIPTION.

  • With flags
func main() {
	config := flag.String("file", "config.yml", "configuration file")
	flag.StringVar(&Config.APPName, "name", "", "app name")
	flag.StringVar(&Config.DB.Name, "db-name", "", "database name")
	flag.StringVar(&Config.DB.User, "db-user", "root", "database user")
	flag.Parse()

	os.Setenv("CONFIGOR_ENV_PREFIX", "-")
	configor.Load(&Config, *config)
	// configor.Load(&Config) // only load configurations from shell env & flag
}

Contributing

You can help to make the project better, check out http://gorm.io/contribute.html for things you can do.

Author

jinzhu

License

Released under the MIT License

Owner
Comments
  • Bool property with default value works not properly

    Bool property with default value works not properly

    I have a problem with a default value for a boolean property.

    type Config struct {
    	Silent bool `default:"true"`
    }
    

    Yaml:

    silent: false
    

    Result:

    err := configor.Load(conf, *configPath)
    if err != nil {
    	log.Fatal(err)
    }
    log.Println(conf.Silent)
    

    Actual:

    true
    

    Expected:

    false
    
  • Nested YAML issue

    Nested YAML issue

    Hi,

    How to define a type for the following YAML?

    part1:
    - level1:
     - level2:
       -level3:
           key1: value1
           key2: value2
    

    Is the scenario supported in general?

  • Can't parse list/array in YAML

    Can't parse list/array in YAML

    My env is "go version go1.5.3 darwin/amd64" Failed to parse Contacts in example code (result is Contacts:[]struct { Name string; Email string "required:"true"" }(nil)), only primitive type from shell environment is ok.

  • configor.Load(&config,

    configor.Load(&config, "./config.yml") will not return an error if the config file is not found

    Hi there,

    Thank you for this nice library. We did just notice some unexpected behavior:

    The load method will print an error message "Failed to find configuration ./config.yml" but will not return an error. This will cause the program to assume that a configuration was correctly loaded on continue on if no specific additional checks are implemented.

    I think it would be better if the load method would return an error if no config file was found.

  • 无法正常读取yaml文件

    无法正常读取yaml文件

    根据readme中的代码原样拷贝至代码文件,解析时仅得到了默认值,请问可能的原因是什么?

    config: struct { APPName string "default:\"app name\""; DB struct { Name string; User string "default:\"root\""; Password string "required:\"true\" env:\"DBPassword\""; Port uint "default:\"3306\"" }; Contacts []struct { Name string; Email string "required:\"true\"" } }{APPName:"app name", DB:struct { Name string; User string "default:\"root\""; Password string "required:\"true\" env:\"DBPassword\""; Port uint "default:\"3306\"" }{Name:"", User:"root", Password:"", Port:0x0}, Contacts:[]struct { Name string; Email string "required:\"true\"" }(nil)}
    

    config.yml未做改

    APPName: test
    
    DB:
        Name:     test
        User:     test
        Password: test
        Port:     1234
    
    Contacts:
    - Name: i test
      Email: [email protected]
    

    是格式的原因吗?

  • Loading configuration by env stops at struct bool if env is not a bool

    Loading configuration by env stops at struct bool if env is not a bool

    If env name is not a bool (true or false), e.g. 1 or 0, as described in struct, then it stops loading more env.

    export ENVIRONMENT_ID=id export ENVIRONMENT_NAME=name export ENVIRONMENT_REUSE=1 export ENVIRONMENT_GROUP=group

    Environment struct { ID string env:"ENVIRONMENT_ID" Name string env:"ENVIRONMENT_NAME" Reuse bool env:"ENVIRONMENT_REUSE" Group string env:"ENVIRONMENT_GROUP" }

    Debug mode: Loading configuration for struct 's field ID from env ENVIRONMENT_ID... Loading configuration for struct 's field Name from env ENVIRONMENT_NAME... Loading configuration for struct 's field Reuse from env ENVIRONMENT_REUSE... Configuration: ...

  • Fix being unable to override default values

    Fix being unable to override default values

    Problem: if value of a setting specified in a yaml config file equals the zero-value of the target struct's field, the value in the "default" tag could not be overwritten because the field would always be considered to not have been set in the config.

    Fixes #34

    Warning! If setting ANY value in a config file now, it will override the default value, (so even zero-values will override the default). You will just have to leave out a config setting from your yaml config files now if you want to use the default.

  • Document how to use []string with ENV variables

    Document how to use []string with ENV variables

    When the config struct contains a slice, f.e. of strings, the config files allow for using lists and command line arguments allow for repeating arguments.

    How does that work for environment variables?

  • No indication when there are unmatched keys in config file

    No indication when there are unmatched keys in config file

    Hello,

    When loading a config file into a struct, like this: configor.Load(&Config, "config.yml"), there is no indication if there are any keys in config.yml that do not match any field in the Config struct. The Load function will silently load whatever it can and return.

    It would be nice to have the ability to return an error when there are keys in the file that do not match any field in the struct. That will make it easier to catch errors in the config file.

  • Return error on unmatched keys

    Return error on unmatched keys

    Return an error when there are keys in the config file that do not match any fields in the Config struct.

    This behavior will be controlled by a boolean field called ErrorOnUnmatchedKeys in the Configor.Config struct. It will default to false. If set to true, an error will be returned if the config file contains an unmatched key.

    It is supported only for yaml and toml files. Note that I changed it to use yaml.v2 instead of yaml.v1. I can add support for json files once the json library adds support for this.

  • Refactor moved yaml.v2 library back to yaml.v1

    Refactor moved yaml.v2 library back to yaml.v1

    Since the tests still refer to gopkg.in/yaml.v2 was this change intended: https://github.com/jinzhu/configor/commit/0af3f7b50bf927700a30508aafb71ab6aee2089b#diff-7d1c2a3334601b6c1958aae0a594cba8R14

  • Upgrade dependencies, add Go 1.19 as target

    Upgrade dependencies, add Go 1.19 as target

    The gopkg.in/yaml.v2 dependency triggers some security warnings (CVE-2022-28948). As far as I can see there's no feasible attack surface unless the config files are user generated input. However, you never know how this library is being used in the wild.

  • use fsnotify instead of polling for autoreload

    use fsnotify instead of polling for autoreload

    Describe the feature

    configor should reload config when the file changes and not poll it every once in a while.

    Motivation

    Currently, it does polling, if I do it too aggressively it calls my function too often, if not, then my credentials are rotated, but I won't know about it.

    A much nicer API would be to use fsnotify instead. It has good support and it only calls if the file has changed.

    Related Issues

  • Add support for loading into interface fields which have a *struct{} in them

    Add support for loading into interface fields which have a *struct{} in them

    Describe the feature

    Add the ability to load a struct that has an interface element which has a struct assigned to it

    Motivation

    This would support go style polymorphism, where a portion of the configuration is set before Load() is called.

    Consider the following:

    type DatabaseProvider interface {
      GetDatabase() *gorm.DB
    }
    type SqliteDatabase struct {
      File string `env:"SQLITE_DATABASE_FILE"`
      // ...
    }
    func (s *SqliteDatabase) GetDB() *gorm.DB {
      // ...
    }
    type PostgresqlDatabase struct {
      Name string `env:"PSQL_DATABASE_NAME"`
      // ...
    }
    func (p *PostgresqlDatabase) GetDB() *gorm.DB {
      // ...
    }
    type AppConfig struct {
      DatabaseProvider `anonymous:"true"`
    }
    func NewAppConfig() (*AppConfig, error) {
      env := os.GetEnvironment("ENVIRONMENT")
      var appConfig *AppConfig
      switch env {
      case "dev":
        appConfig = &AppConfig{ &SqliteDatabase{} }
      default:
        appConfig = &AppConfig{ &PostgresqlDatabase{} }
      }
      return appConfig, configor.New(&configor.Config{}).Load(appConfig)
    }
    

    Currently configor will not load the underlying database configuration, but there is no reason that it cannot do so since the value of the interface is a struct.

    Related Issues

  • feat: add `envSuffix` tag to use environment variable with prefix

    feat: add `envSuffix` tag to use environment variable with prefix

    Overview

    Make Load() set the value from environment variables specified with envSuffix tag to the struct's field. The new envSuffix tag allows us to specify environment variable name with existing prefix.

Generic templating tool with support of JSON, YAML and TOML data

gotempl Small binary used to generate files from Go Templates and data files. The following formats are supported: JSON YAML TOML Usage usage: gotempl

Jun 15, 2022
Golang library for reading properties from configuration files in JSON and YAML format or from environment variables.

go-config Golang library for reading properties from configuration files in JSON and YAML format or from environment variables. Usage Create config in

Aug 22, 2022
Tmpl - A tool to apply variables from cli, env, JSON/TOML/YAML files to templates

tmpl allows to apply variables from JSON/TOML/YAML files, environment variables or CLI arguments to template files using Golang text/template and functions from the Sprig project.

Nov 14, 2022
Library providing routines to merge and validate JSON, YAML and/or TOML files
Library providing routines to merge and validate JSON, YAML and/or TOML files

CONFLATE Library providing routines to merge and validate JSON, YAML, TOML files and/or structs (godoc) Typical use case: Make your application config

Sep 26, 2022
JSON or YAML configuration wrapper with convenient access methods.

Config Package config provides convenient access methods to configuration stored as JSON or YAML. This is a fork of the original version. This version

Dec 16, 2022
🛠 A configuration library for Go that parses environment variables, JSON files, and reloads automatically on SIGHUP
🛠 A configuration library for Go that parses environment variables, JSON files, and reloads automatically on SIGHUP

config A small configuration library for Go that parses environment variables, JSON files, and reloads automatically on SIGHUP. Example func main() {

Dec 11, 2022
Go-yaml - Yaml parsing Toolkit For Golang

go-yaml 介绍 gopkg.in/yaml.v3 已经是个非常好用的包,但是在实际开发中总有类型转换带来的麻烦,go-yaml只是在它的基础上,简单的一层

Jan 13, 2022
Genv is a library for Go (golang) that makes it easy to read and use environment variables in your projects. It also allows environment variables to be loaded from the .env file.

genv Genv is a library for Go (golang) that makes it easy to read and use environment variables in your projects. It also allows environment variables

Dec 21, 2022
Go-config - Config parser for go that supports environment vars and multiple yaml files

go-multiconfig This package is able to parse yaml config files. It supports gett

Jun 23, 2022
✨Clean and minimalistic environment configuration reader for Golang

Clean Env Minimalistic configuration reader Overview This is a simple configuration reading tool. It just does the following: reads and parses configu

Jan 8, 2023
Golang library for managing configuration data from environment variables

envconfig import "github.com/kelseyhightower/envconfig" Documentation See godoc Usage Set some environment variables: export MYAPP_DEBUG=false export

Dec 26, 2022
It syncronizes the configuration described in a YAML file against your GitHub Organization

It syncronizes the configuration described in a YAML file against your GitHub Organization. Combined with a CI system, it can be used to implement GitOps for GitHub.

Jul 19, 2021
Small library to read your configuration from environment variables

envconfig envconfig is a library which allows you to parse your configuration from environment variables and fill an arbitrary struct. See the example

Nov 3, 2022
goconfig uses a struct as input and populates the fields of this struct with parameters from command line, environment variables and configuration file.

goconfig goconfig uses a struct as input and populates the fields of this struct with parameters from command line, environment variables and configur

Dec 15, 2022
Environment variables configuration package for Go microservices.

gocfg Environment variables configuration package for Go microservices. It helps validate environment variable values and set default values if needed

Dec 30, 2021
YAML support for the Go language.

YAML support for the Go language Introduction The yaml package enables Go programs to comfortably encode and decode YAML values. It was developed with

Jan 8, 2023
YAML support for the Go language
YAML support for the Go language

YAML support for the Go language

Dec 31, 2022
TOML parser for Golang with reflection.

THIS PROJECT IS UNMAINTAINED The last commit to this repo before writing this message occurred over two years ago. While it was never my intention to

Jan 6, 2023