config

package module
v1.0.0 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Oct 24, 2024 License: Apache-2.0 Imports: 15 Imported by: 0

README

Config

config is a simple golang library and designed to read configurations from JSON, Yaml files, environment variables and command line. config depends on go-yaml to analyze Yaml file and uses built-in golang library to handle JSON file.

Installation

  1. Install Yaml library first:
go get gopkg.in/yaml.v3
  1. Install config library:
go get github.com/eschao/config

Usage

I. Define configuration name in structure tags

Like JSON, Yaml, config uses tags to define configurations:

Tag Example Function
json Host string json:"host" Maps Host to a JSON field: host
yaml Host string yaml:"host" Maps Host to a Yaml field: host
env Host string env:"HOST" Maps Host to a Environment variable: HOST
cli Host string cli:"host database host" Maps Host to a command line argument: -host or --host
default Port int default:"8080" Defines the port with default value: 8080
separator Path string json:"path" separator:";" Separator is used to split string to a slice
usage Usage string usage:"host address" Usage description
1. Data types

config supports the following golang data types:

  • bool
  • string
  • int8, int16, int, int32, int64
  • uint8, uint16, uint, uint32, uint64
  • float32, float64
  • slice type. e.g: []string, []int ...
2. Defines default values

Using default keyword in structure tags to define default value:

type Log struct {
    Path  string `default:"/var/logs"`
    Level string `default:"debug"`
}
3. Defines configuration name for JSON

Like parsing JSON object, using json keyword to define configuration name:

  type Database struct {
    Host     string `json:"host"`
    Port     int    `json:"port"`
    Username string `default:"admin" json:"username"`
    Password string `default:"admin" json:"password"`
    Log      Log    `json:"log"`
  }

Corresponding JSON file:

 {
   "host": "test.db.hostname",
   "port": 8080,
   "username": "admin",
   "password": "admin",
   "log": {
     "path": "/var/logs/db",
     "level": "debug"
   }
 }
4. Defines configuration name for Yaml

Like parsing Yaml object, using yaml keyword to define configuration name

  type Database struct {
    Host     string `yaml:"host"`
    Port     int    `yaml:"port"`
    Username string `default:"admin" yaml:"username"`
    Password string `default:"admin" yaml:"password"`
    Log      Log    `yaml:"log"`
  }

Corresponding Yaml file:

  host: test.db.hostname
  port: 8080
  username: admin
  password: admin
  log:
    path: /var/logs/db
    level: debug
5. Defines configuration name for Environment variable

Using env keyword to define configuration name

  type Database struct {
    Host     string `env:"DB_HOST"`
    Port     int    `env:"DB_PORT"`
    Username string `default:"admin" env:"DB_USER"`
    Password string `default:"admin" env:"DB_PASSWORD"`
    Log      Log    `env:"DB_LOG_"`
  }

Corresponding Environment variables:

 export DB_HOST=test.db.hostname
 export DB_PORT=8080
 export DB_USER=admin
 export DB_PASSWORD=admin
 export DB_LOG_PATH=/var/logs/db
 export DB_LOG_LEVEL=debug

Since the Log is a structure and nested in Database structure, the tag of Log and tags of its structure members will be combined to be an unique environment variable, for example: Path will be mapped to environment var: DB_LOG_PATH. But if the Log has no tag definition, only tags of its structure members will be used, that means the Path will be mapped to PATH.

6. Defines configuration name for Command line

Using cli keyword to define configuration name:

  type Database struct {
    Host     string `cli:"host" usage:"database host name"`
    Port     int    `cli:"port" usage:"database port"`
    Username string `cli:"username" default:"admin" usage:"database username"`
    Password string `cli:"password" default:"admin" usage:"database password"`
    Log      Log    `cli:"log" usage:"database log configurations"`
  }

For cli definition, the string is command line argument, and the usage tag are the command line usage and will be outputted when printing usage.

Corresponding command line:

  ./main --host test.db.hostname --port 8080 --username admin --password admin --log-path /var/logs/db --log-level debug

or

  ./main --host=test.db.hostname --port=8080 --username=admin --password=admin --log-path=/var/logs/db --log-level=debug
7. Defines configuration name as a slice type

Using separator to split string as a slice:

  type Log struct {
    Levels []string `env:"LEVELS" cli:"levels" separator:";" usage:"log levels"`
  }

If the separator is not given, its default is :, The separator only works on env and cli tags.

  logConfig := Log{}
  // export LEVELS=debug;error;info
  config.ParseEnv(&logConfig)
  // logConfig[0] == debug
  // logConfig[1] == error
  // logConfig[2] == info
II. Parses configurations
1. Parses default values

When default values are defined in tags, calls config.ParseDefault(interface{}) to assign them to given structure instance BEFORE parsing any other configuration types:

  logConfig := Log{}
  config.ParseDefault(&logConfig)

Note: Other parsing functions don't set structure instance with default values whatever if the configuration value is provided or not

2. Parses from Environment variables
  dbConfig := Database{}
  config.ParseEnv(&dbConfig)
3. Parses from Command line
  dbConfig := Database{}
  config.ParseCli(&dbConfig)
4. Parses from default configuration files

Calls ParseConfigFile(interface{}, string) to parse given configuration file:

  dbConfig := Database{}
  config.ParseConfigFile(&dbConfig, "config.json")

If the configuration file is not given, the default configuration files: config.json and config.yaml will be located under the same folder with fixed searching order.

The config.json will always be located first, if it doesn't exist, then checks
config.yaml. If all of them are not found, parsing will fail.

  dbConfig := Database{}
  config.ParseConfigFile(&dbConfig, "")
4. Parses from configuration file specified by command line

Calls ParseConfig(interface{}, string) to parse the configuration file given by command line. The second parameter is a command line argument which is used to specify config file:

  dbConfig := Database{}
  config.ParseConfig(&dbConfig, "c")

Run application like:

  ./main -c config.json

ParseConfig() will analyze command line arguments and get configure file: config.json from argument -c

III. Multi-Configurations

You can define all supported configuration tags in a structure and call corresponding functions in your desired order to parse.

Examples:

  type Log struct {
    Path   string `cli:"path"   default:"/var/logs"   env:"PATH"   json:"path"   usage:"log path"   yaml:"path"`
    Levels string `cli:"levels" default:"debug;error" env:"LEVELS" json:"levels" usage:"log levels" yaml:"levels"`
  }
  
  type Database struct {
    Host     string `cli:"host" env:"DB_HOST" json:"host" usage:"database host name" yaml:"host"`
    Port     int    `cli:"port" env:"DB_PORT" json:"port" usage:"database port"      yaml:"port"`
    Username string `cli:"username" default:"admin" env:"DB_USER"   json:"user"   usage:"database username" yaml" user"`
    Password string `cli:"password" default:"admin" env:"DB_PASSWD" json:"passwd" usage:"database password" yaml:"passwd"`
    Log      Log    `cli:"log" env:"DB_LOG_" json:"log" usage:"database log configurations" yaml:"log"`
  }

Then, you can parse as below:

 dbConfig := Database{}
 
 // parse default values
 if err := config.ParseDefault(&dbConfig); err != nil {
   // error handling
 }

 // parse configuration file from command line
 err := config.ParseConfig(&dbConfig, "c")
 
 // parse default configurations
 if err != nil {
   err = config.ParseConfigFile(&dbConfig), "")
 }
 
 // parse environment variables
 if err != nil {
   err = config.ParseEnv(&dbConfig)
 }
 
 // parse command line
 if err != nil {
   err = config.ParseCli(&dbConfig)
 }
 
 // check if all required configurations are set
 ...

You don't need to call all of them. Just invokes parsing function that your need.

License

This project is licensed under the Apache License Version 2.0.

Documentation

Overview

* Copyright (C) 2017 eschao <esc.chao@gmail.com> * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License.

* Copyright (C) 2017 eschao <esc.chao@gmail.com> * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License.

* Copyright (C) 2017 eschao <esc.chao@gmail.com> * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License.

* Copyright (C) 2017 eschao <esc.chao@gmail.com> * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License.

Index

Constants

View Source
const (
	Float32Size = 32
	Float64Size = 64
	Int8Size    = 8
	Int16Size   = 16
	Int32Size   = 32
	Int64Size   = 64
	Uint8Size   = 8
	Uint16Size  = 16
	Uint32Size  = 32
	UintSize    = 32
	Uint64Size  = 64
)
View Source
const (
	DefaultJSONConfig = "config.json"
	DefaultYamlConfig = "config.yaml"
	DefaultPropConfig = "config.properties"
)

Default configuration file

View Source
const (
	JSONConfigType = "json"
	YamlConfigType = "yaml"
	PropConfigType = "properties"
)

Variables

View Source
var ErrInternalError = errors.New("internal error")

Functions

func ParseCli

func ParseCli(out interface{}, name string, args []string) ([]string, error)

ParseCli parses given structure interface and set it with command line input

func ParseConfig

func ParseConfig(out interface{}, configFlag string) error

ParseConfig parses given structure interface and set it with default configuration file. The configFlag is a command line flag to tell where to locate configure file. If the config file doesn't exist, the default config fill will be searched under the same folder with the fixed order: config.json, config.yaml and config.properties

func ParseConfigFile

func ParseConfigFile(out interface{}, configFile string) error

ParseConfigFile parses given structure interface and set its value with the specified configuration file

func ParseDefault

func ParseDefault(i interface{}) error

ParseDefault parses the given structure, extract default value from its tag and set structure with these values. Normally, ParseDefault should be called before any other parsing functions to set default values for structure.

func ParseEnv

func ParseEnv(out interface{}) error

Parse parses given structure interface, extracts environment definitions from its tag and sets structure with defined environment variables

func ParseEnvWith

func ParseEnvWith(out interface{}, prefix string, parser ParseValueEnvFunc) error
type Server struct {
  Server string `env:"SERVER"`
  DB     Database `env:"DB_"`
}

The Server.DB.Host will be mapped to environment variable: DB_HOST which is concatenated from DB tag in Server struct and Host tag in Database struct

func UsageEnv added in v0.3.0

func UsageEnv(out io.Writer, in interface{}) error

UsageEnv prints usage description of config i to out

Types

type Command

type Command struct {
	Name string // Command name

	FlagSet     *flag.FlagSet       // Command arguments
	Usage       string              // Command usage description
	SubCommands map[string]*Command // Sub-commands
	Args        []string            // Rest of args after parsing
	// contains filtered or unexported fields
}

Command defines a command line structure

func NewCLI

func NewCLI(name string) *Command

NewCLI creates a command with given name, the command will use default ErrorHandling: flag.ExitOnError and default usage function: flag.Usage

func NewCliWith added in v0.3.0

func NewCliWith(
	name string, errHandling flag.ErrorHandling, usageHandling UsageFunc,
) *Command

NewCliWith creates a command with given name, error handling and customized usage function

func (*Command) Capture added in v0.6.0

func (c *Command) Capture(args []string) []string

Capture filter config args and return rest args

func (*Command) Init

func (c *Command) Init(in interface{}) error

Init analyzes the given structure interface, extracts cli definitions from its tag and installs command flagset by flag APIs. The interface must be a structure pointer, otherwise will return an error

func (*Command) Parse

func (c *Command) Parse(args []string) error

Parse parses values from command line and save values into given structure. The Init(interface{}) function must be called before parsing

func (*Command) PrintUsage added in v0.3.0

func (c *Command) PrintUsage(w io.Writer) error

PrintUsage prints command description

type ParseValueEnvFunc added in v0.3.0

type ParseValueEnvFunc func(value reflect.Value, prefix string) error

ParseValueEnvFunc func to parse env value

type UsageFunc

type UsageFunc func(*Command) func()

UsageFunc defines a callback function for printing command usage

Directories

Path Synopsis
* Copyright (C) 2017 eschao <esc.chao@gmail.com> * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License.
* Copyright (C) 2017 eschao <esc.chao@gmail.com> * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL