Initial commit
This commit is contained in:
commit
a57ab31b71
9
LICENSE.md
Normal file
9
LICENSE.md
Normal file
|
@ -0,0 +1,9 @@
|
||||||
|
# MIT License
|
||||||
|
|
||||||
|
Copyright 2020 Noah Petherbridge
|
||||||
|
|
||||||
|
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
|
||||||
|
|
||||||
|
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
|
||||||
|
|
||||||
|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
80
README.md
Normal file
80
README.md
Normal file
|
@ -0,0 +1,80 @@
|
||||||
|
# YamlSettings for Go
|
||||||
|
|
||||||
|
This is a config file manager for Go, inspired by Python
|
||||||
|
[yamlsettings](https://github.com/KyleJamesWalker/yamlsettings).
|
||||||
|
|
||||||
|
## Example
|
||||||
|
|
||||||
|
Your Go code:
|
||||||
|
|
||||||
|
```go
|
||||||
|
import "git.kirsle.net/go/yamlsettings"
|
||||||
|
|
||||||
|
// Typedef for your config object.
|
||||||
|
type Config struct {
|
||||||
|
Database struct {
|
||||||
|
Host string `yaml:"host"`
|
||||||
|
Port string `yaml:"port"`
|
||||||
|
User string `yaml:"user"`
|
||||||
|
Password string `yaml:"passwd"`
|
||||||
|
} `yaml:"database"`
|
||||||
|
|
||||||
|
Redis struct {
|
||||||
|
Host string `yaml:"redis_host"`
|
||||||
|
Port int `yaml:"redis_port"`
|
||||||
|
} `yaml:"redis"`
|
||||||
|
|
||||||
|
Debug bool `yaml:"DEBUG"`
|
||||||
|
SecretKey string `yaml:"SECRET_KEY"`
|
||||||
|
}
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
// Marshal your app config from the defaults + settings files.
|
||||||
|
// Only the defaults.yml should exist on disk; the settings.yml is
|
||||||
|
// optional and will be ignored if not found.
|
||||||
|
var setting Config
|
||||||
|
err := yamlsettings.LoadFiles(
|
||||||
|
"defaults.yml", "settings.yml",
|
||||||
|
&setting,
|
||||||
|
)
|
||||||
|
if err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
fmt.Printf("Redis host: %s\n", settings.Redis.Host)
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
Your defaults.yml file can be committed to version control. It uses sensible
|
||||||
|
defaults and has dummy text in place of passwords and needed configuration:
|
||||||
|
|
||||||
|
```yaml
|
||||||
|
---
|
||||||
|
database:
|
||||||
|
host: "localhost"
|
||||||
|
port: 5432
|
||||||
|
user: "postgres"
|
||||||
|
passwd: "postgres"
|
||||||
|
redis:
|
||||||
|
host: "localhost"
|
||||||
|
port: 6379
|
||||||
|
DEBUG: false
|
||||||
|
SECRET_KEY: "!! CHANGE ME !!"
|
||||||
|
```
|
||||||
|
|
||||||
|
The settings.yml file can override values from the defaults file. This
|
||||||
|
file goes in your `.gitignore` to avoid accidentally committing secrets
|
||||||
|
to version control!
|
||||||
|
|
||||||
|
```yaml
|
||||||
|
---
|
||||||
|
database:
|
||||||
|
host: "pgprod.example.com"
|
||||||
|
user: "pgprod_admin"
|
||||||
|
passwd: "big secret long password"
|
||||||
|
SECRET_KEY: "fd09s0sfv0dhgf098sasd"
|
||||||
|
```
|
||||||
|
|
||||||
|
## License
|
||||||
|
|
||||||
|
MIT. © 2020 Noah Petherbridge.
|
23
example/defaults.yml
Normal file
23
example/defaults.yml
Normal file
|
@ -0,0 +1,23 @@
|
||||||
|
---
|
||||||
|
# Program Defaults, do not edit this file!!!
|
||||||
|
# All values should be overridden in the following ways:
|
||||||
|
# 1. In the 'settings.yaml' file.
|
||||||
|
# 2. With environment variables. Example myproj.databases.primary_sql.user can
|
||||||
|
# be overridden with MYPROJ_DATABASES_PRIMARY_SQL_USER.:
|
||||||
|
databases:
|
||||||
|
extra_setting: "not specified"
|
||||||
|
primary_sql:
|
||||||
|
user: my_user
|
||||||
|
passwd: password_here
|
||||||
|
host: db-bouncer-01.postgres.com:5432
|
||||||
|
db: postgres
|
||||||
|
compress: true
|
||||||
|
engine: postgresql2
|
||||||
|
redis:
|
||||||
|
redis_host: 127.0.0.1
|
||||||
|
redis_port: 6379
|
||||||
|
app_config:
|
||||||
|
DEBUG: false
|
||||||
|
SECRET_KEY: hard key to guess and keep values secret
|
||||||
|
debug_sql: false
|
||||||
|
debug_profiler: false
|
54
example/main.go
Normal file
54
example/main.go
Normal file
|
@ -0,0 +1,54 @@
|
||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"encoding/json"
|
||||||
|
"fmt"
|
||||||
|
|
||||||
|
"git.kirsle.net/go/yamlsettings"
|
||||||
|
)
|
||||||
|
|
||||||
|
type MyProj struct {
|
||||||
|
Databases struct {
|
||||||
|
PrimarySQL struct {
|
||||||
|
User string `yaml:"user"`
|
||||||
|
Passwd string `yaml:"passwd"`
|
||||||
|
Host string `yaml:"host"`
|
||||||
|
DB string `yaml:"db"`
|
||||||
|
Compress bool `yaml:"compress"`
|
||||||
|
Engine string `yaml:"engine"`
|
||||||
|
} `yaml:"primary_sql"`
|
||||||
|
|
||||||
|
Redis struct {
|
||||||
|
Host string `yaml:"redis_host"`
|
||||||
|
Port int `yaml:"redis_port"`
|
||||||
|
} `yaml:"redis"`
|
||||||
|
} `yaml:"databases"`
|
||||||
|
|
||||||
|
AppConfig struct {
|
||||||
|
Debug bool `yaml:"DEBUG"`
|
||||||
|
SecretKey string `yaml:"SECRET_KEY"`
|
||||||
|
} `yaml:"app_config"`
|
||||||
|
|
||||||
|
DebugSQL bool `yaml:"debug_sql"`
|
||||||
|
DebugProfiler bool `yaml:"debug_profiler"`
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c MyProj) String() string {
|
||||||
|
output, _ := json.MarshalIndent(c, "", "\t")
|
||||||
|
return string(output)
|
||||||
|
}
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
var config MyProj
|
||||||
|
err := yamlsettings.LoadFiles(
|
||||||
|
"defaults.yml",
|
||||||
|
"settings.yml2",
|
||||||
|
&config,
|
||||||
|
)
|
||||||
|
if err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Print out the final settings to terminal as JSON.
|
||||||
|
fmt.Println(config)
|
||||||
|
}
|
11
example/settings.yml
Normal file
11
example/settings.yml
Normal file
|
@ -0,0 +1,11 @@
|
||||||
|
---
|
||||||
|
databases:
|
||||||
|
primary_sql:
|
||||||
|
user: root
|
||||||
|
passwd: god
|
||||||
|
redis:
|
||||||
|
redis_host: redis.example.com
|
||||||
|
app_config:
|
||||||
|
DEBUG: true
|
||||||
|
SECRET_KEY: sdfasjksdfASFAS23423f@#$%!$#VR@%UQ%
|
||||||
|
debug_sql: true
|
5
go.mod
Normal file
5
go.mod
Normal file
|
@ -0,0 +1,5 @@
|
||||||
|
module git.kirsle.net/go/yamlsettings
|
||||||
|
|
||||||
|
go 1.14
|
||||||
|
|
||||||
|
require gopkg.in/yaml.v2 v2.3.0
|
3
go.sum
Normal file
3
go.sum
Normal file
|
@ -0,0 +1,3 @@
|
||||||
|
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||||
|
gopkg.in/yaml.v2 v2.3.0 h1:clyUAQHOM3G0M3f5vQj7LuJrETvjVot3Z5el9nffUtU=
|
||||||
|
gopkg.in/yaml.v2 v2.3.0/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
50
yamlsettings.go
Normal file
50
yamlsettings.go
Normal file
|
@ -0,0 +1,50 @@
|
||||||
|
package yamlsettings
|
||||||
|
|
||||||
|
import (
|
||||||
|
"io"
|
||||||
|
"os"
|
||||||
|
|
||||||
|
"gopkg.in/yaml.v2"
|
||||||
|
)
|
||||||
|
|
||||||
|
// LoadFiles marshals your app settings from the default.yml overridden
|
||||||
|
// by the settings.yml file.
|
||||||
|
func LoadFiles(defaultsFile, settingsFile string, v interface{}) error {
|
||||||
|
// Read the defaults file.
|
||||||
|
if err := LoadFile(defaultsFile, v); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
// Read the settings.yml. It's OK if it doesn't exist.
|
||||||
|
if err := LoadFile(settingsFile, v); err != nil && !os.IsNotExist(err) {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// LoadFile opens and marshals YAML settings from a single config file.
|
||||||
|
func LoadFile(filename string, v interface{}) error {
|
||||||
|
fh, err := os.Open(filename)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
dec := yaml.NewDecoder(fh)
|
||||||
|
return dec.Decode(v)
|
||||||
|
}
|
||||||
|
|
||||||
|
// LoadReaders marshals your app settings from the defaults and settings
|
||||||
|
// readers, so you can feed in YAML data from sources other than files
|
||||||
|
// on disk.
|
||||||
|
func LoadReaders(defaults, settings io.Reader, v interface{}) error {
|
||||||
|
if defaults != nil {
|
||||||
|
if err := yaml.NewDecoder(defaults).Decode(v); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if settings != nil {
|
||||||
|
return yaml.NewDecoder(settings).Decode(v)
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
84
yamlsettings_test.go
Normal file
84
yamlsettings_test.go
Normal file
|
@ -0,0 +1,84 @@
|
||||||
|
package yamlsettings_test
|
||||||
|
|
||||||
|
import (
|
||||||
|
"bytes"
|
||||||
|
"fmt"
|
||||||
|
"testing"
|
||||||
|
|
||||||
|
"git.kirsle.net/go/yamlsettings"
|
||||||
|
)
|
||||||
|
|
||||||
|
func TestLoadReaders(t *testing.T) {
|
||||||
|
type Settings struct {
|
||||||
|
Databases struct {
|
||||||
|
PrimarySQL struct {
|
||||||
|
User string `yaml:"user"`
|
||||||
|
Passwd string `yaml:"passwd"`
|
||||||
|
Host string `yaml:"host"`
|
||||||
|
DB string `yaml:"db"`
|
||||||
|
Compress bool `yaml:"compress"`
|
||||||
|
Engine string `yaml:"engine"`
|
||||||
|
} `yaml:"primary_sql"`
|
||||||
|
|
||||||
|
Redis struct {
|
||||||
|
Host string `yaml:"redis_host"`
|
||||||
|
Port int `yaml:"redis_port"`
|
||||||
|
} `yaml:"redis"`
|
||||||
|
} `yaml:"databases"`
|
||||||
|
|
||||||
|
AppConfig struct {
|
||||||
|
Debug bool `yaml:"DEBUG"`
|
||||||
|
SecretKey string `yaml:"SECRET_KEY"`
|
||||||
|
} `yaml:"app_config"`
|
||||||
|
|
||||||
|
DebugSQL bool `yaml:"debug_sql"`
|
||||||
|
DebugProfiler bool `yaml:"debug_profiler"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// The defaults.yml file you can commit to version control,
|
||||||
|
// it's used as the template config that contains all options,
|
||||||
|
// has sensible defaults where possible or "CHANGE_ME" where not.
|
||||||
|
var (
|
||||||
|
defaultsYaml = bytes.NewBuffer([]byte(`---
|
||||||
|
# Program Defaults, do not edit this file!!!
|
||||||
|
# All values should be overridden in the settings.yml file.
|
||||||
|
databases:
|
||||||
|
primary_sql:
|
||||||
|
user: my_user
|
||||||
|
passwd: password_here
|
||||||
|
host: db-bouncer-01.postgres.com:5432
|
||||||
|
db: postgres
|
||||||
|
compress: true
|
||||||
|
engine: postgresql2
|
||||||
|
redis:
|
||||||
|
redis_host: 127.0.0.1
|
||||||
|
redis_port: 6379
|
||||||
|
app_config:
|
||||||
|
DEBUG: false
|
||||||
|
SECRET_KEY: hard key to guess and keep values secret
|
||||||
|
debug_sql: false
|
||||||
|
debug_profiler: false`))
|
||||||
|
settingsYaml = bytes.NewBuffer([]byte(`---
|
||||||
|
databases:
|
||||||
|
primary_sql:
|
||||||
|
user: root
|
||||||
|
passwd: god
|
||||||
|
redis:
|
||||||
|
redis_host: redis.service.com
|
||||||
|
app_config:
|
||||||
|
DEBUG: true
|
||||||
|
SECRET_KEY: sdfasjksdfASFAS23423f@#$%!$#VR@%UQ%
|
||||||
|
debug_sql: true`))
|
||||||
|
)
|
||||||
|
|
||||||
|
// Load the defaults and the optional settings file.
|
||||||
|
// yamlsettings.LoadFiles("defaults.yml", "settings.yml", &config)
|
||||||
|
var config Settings
|
||||||
|
yamlsettings.LoadReaders(defaultsYaml, settingsYaml, &config)
|
||||||
|
fmt.Printf("Redis host: %s\n", config.Databases.Redis.Host)
|
||||||
|
fmt.Printf("Secret: %s\n", config.AppConfig.SecretKey)
|
||||||
|
|
||||||
|
// Load from yaml files on disk.
|
||||||
|
yamlsettings.LoadFiles("example/defaults.yml", "example/settings.yml", &config)
|
||||||
|
fmt.Printf("Redis host: %s\n", config.Databases.Redis.Host)
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user