Skip to content
master
Switch branches/tags
Code

Latest commit

 

Git stats

Files

Permalink
Failed to load latest commit information.
Type
Name
Latest commit message
Commit time
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

CircleCI GoDoc

twist

Cascade and integrate config struct from various setting files, envrironments, and command-line arguments

Supporting configuration types:

  • toml file
  • yaml file
  • json file
  • ini file
  • environment variables
  • command-line arguments
  • default values

Installation

$ go get -u github.com/ysugimoto/twist

Or install via package manager which you're using like dep, go mod, etc...

Getting Started

Define your configuration strcut and call Mix() function with cascading configurations.

Here is toml file example:

# /path/to/setting.toml

host = "localhost"
port = 8000

[service]
name = "My Service"
description = "This is my favorite service"

Then this package can use as following:

package main

import (
  "log"

  "github.com/ysugimoto/twist"
)

type MyConfig struct {
  Host string `toml:"host"`
  Port int    `toml:"port"`

  Service struct{
    Name        string `toml:"name"`
    Description string `toml:"description"`
  } `toml:"service"` // <- need this
}

func main() {
  var config MyConfig
  if err := twist.Mix(&config, twist.WithToml("/path/to/setting.toml")); err != nil {
    log.Fatal(err)
  }
  log.Println(config.Host)                // => localhost
  log.Println(config.Port)                // => 8000
  log.Println(config.Service.Name)        // => My Service
  log.Println(config.Service.Description) // => This is my favorite service
}

Merging configuration from various kind of files and defaults

This package can support kinds of config files (eg. yaml and json and env). To merge from some configurations, call Mix() with some of WithXXX options and make sure put tag in your struct field which you want to assign:

package main

import (
  "log"
  "os"

  "github.com/ysugimoto/twist"
)

type MyConfig struct {
  Host string `toml:"host"` // will be used from toml file
  Port int    `yaml:"port"` // will be used from yaml file

  Service struct{
    Name        string `default:"My Service"`          // set as default
    Description string `default:"My Favorite Service"` // set as default
  } `toml:"service" yaml:"service"` // <- need if you want to assign from multiple files

  Secret string `env:"SECRET"`      // will be used from envrironment variable
}

func main() {
  var config MyConfig
  if err := twist.Mix(
    &config,
    twist.WithToml("/path/to/setting.toml"),
    twist.WithToml("/path/to/setting.yaml"),
    twist.WithEnv(),
  ); err != nil {
    log.Fatal(err)
  }
  log.Println(config.Host)                // => host in toml file
  log.Println(config.Port)                // => port in yaml file 
  log.Println(config.Service.Name)        // => My Service as default
  log.Println(config.Service.Description) // => My Favorite Service as default
  log.Println(config.Secret)              // => value of os.Getenv("SECRET")
}

Of course you'll confuse when cascading from different file types, so usually you can use from same file of partial configurations and integrate it, and secret values (like accessToken, etc) should be assigned from envrironment variables:

# /path/to/server.json
{
  "host": "localhost",
  "port": 8000
}

# /path/to/service.json
{
  "service": {
    "name": "My Service",
    "description": "My Favorite Service"
  }
}

Then cascading is:

package main

import (
  "log"

  "github.com/ysugimoto/twist"
)

type MyConfig struct {
  Host string `json:"host"`
  Port int    `json:"port"`

  Service struct{
    Name        string `json:"name"`
    Description string `json:"description"`
  } `json:"service"`

  Secret  string `env:"SECRET"`    // will be used from envrironment variable
  Verbose string `cli:"v,verbose"` // will be used from command-line arguments
}

func main() {
  var config MyConfig
  if err := twist.Mix(
    &config,
    twist.WithToml("/path/to/server.json"),  // will set only Host and Port
    twist.WithToml("/path/to/service.json"), // will set only Service.Name and Service.Description
    twist.WithEnv(),
    twist.WithCli(os.Args[1:]),
  ); err != nil {
    log.Fatal(err)
  }
  log.Println(config.Host)                // => host value in server.json
  log.Println(config.Port)                // => port value in server.json
  log.Println(config.Service.Name)        // => name value in service.json
  log.Println(config.Service.Description) // => description value in service.json
  log.Println(config.Secret)              // => value of os.Getenv("SECRET")
}

Correspond Struct Tags

type Config struct {
  TomlValue    string `toml:"value"`     // for toml mapping
  YamlValue    string `yaml:"value"`     // for yaml mapping
  JsonValue    string `json:"value"`     // for json mapping
  IniValue     string `ini:"value"`      // for ini mapping
  EnvValue     string `env:"ENV_NAME"`   // for env mapping
  CliValue     string `cli:"short,long"` // for cli mapping
  DefaultValue string `default:"value"`  // set as default value
}

toml, yaml, json and ini are used following packages:

  • github.com/BurntSushi/toml
  • github.com/go-yaml/yaml
  • github.com/go-ini/ini
  • encoding/json

env and cli is package defined.

Author

Yoshiaki Sugimoto

License

MIT

PR is welcome :-)

About

Cascade and integrate config struct from various setting files and environment.

Topics

Resources

License

Releases

No releases published

Packages

No packages published

Languages