Skip to content
Snippets Groups Projects

Compare revisions

Changes are shown as if the source revision was being merged into the target revision. Learn more about comparing revisions.

Source

Select target project
No results found
Select Git revision

Target

Select target project
  • oss/libraries/go/application/configuration
1 result
Select Git revision
Show changes
Commits on Source (6)
<a name="v1.4.0"></a>
## [v1.4.0] - 2022-10-05
### Bug Fixes
- fix settings must be exported
### Changes
- chore add license file
<a name="v1.3.0"></a> <a name="v1.3.0"></a>
## [v1.3.0] - 2022-09-18 ## [v1.3.0] - 2022-09-18
### Code Refactoring ### Code Refactoring
...@@ -26,6 +35,7 @@ ...@@ -26,6 +35,7 @@
<a name="v1.0.0"></a> <a name="v1.0.0"></a>
## v1.0.0 - 2022-09-18 ## v1.0.0 - 2022-09-18
[v1.4.0]: https://gitlab.schukai.com/oss/libraries/go/application/configuration/compare/v1.3.0...v1.4.0
[v1.3.0]: https://gitlab.schukai.com/oss/libraries/go/application/configuration/compare/v1.2.0...v1.3.0 [v1.3.0]: https://gitlab.schukai.com/oss/libraries/go/application/configuration/compare/v1.2.0...v1.3.0
[v1.2.0]: https://gitlab.schukai.com/oss/libraries/go/application/configuration/compare/v1.1.0...v1.2.0 [v1.2.0]: https://gitlab.schukai.com/oss/libraries/go/application/configuration/compare/v1.1.0...v1.2.0
[v1.1.0]: https://gitlab.schukai.com/oss/libraries/go/application/configuration/compare/v1.0.1...v1.1.0 [v1.1.0]: https://gitlab.schukai.com/oss/libraries/go/application/configuration/compare/v1.0.1...v1.1.0
......
This diff is collapsed.
## Configuration ## Configuration
## What do this library? ## What does this library?
This library provides a simple way to load configuration from different sources. This library provides a simple way to load configuration from different sources.
......
...@@ -4,9 +4,9 @@ import "github.com/imdario/mergo" ...@@ -4,9 +4,9 @@ import "github.com/imdario/mergo"
// NewSetting creates a new configuration setting // NewSetting creates a new configuration setting
// with the given defaults. // with the given defaults.
func New[C any](defaults C) *setting[C] { func New[C any](defaults C) *Settings[C] {
s := &setting[C]{} s := &Settings[C]{}
s.initDefaults() s.initDefaults()
if err := mergo.Merge(&defaults, s.config); err != nil { if err := mergo.Merge(&defaults, s.config); err != nil {
...@@ -28,7 +28,7 @@ func New[C any](defaults C) *setting[C] { ...@@ -28,7 +28,7 @@ func New[C any](defaults C) *setting[C] {
// Set the mnemonic // Set the mnemonic
// The mnemonic is used to identify the configuration in the configuration file // The mnemonic is used to identify the configuration in the configuration file
func (s *setting[C]) SetMnemonic(mnemonic string) *setting[C] { func (s *Settings[C]) SetMnemonic(mnemonic string) *Settings[C] {
if mnemonic == "" { if mnemonic == "" {
s.errors = append(s.errors, MnemonicEmptyError) s.errors = append(s.errors, MnemonicEmptyError)
} else { } else {
...@@ -38,6 +38,6 @@ func (s *setting[C]) SetMnemonic(mnemonic string) *setting[C] { ...@@ -38,6 +38,6 @@ func (s *setting[C]) SetMnemonic(mnemonic string) *setting[C] {
} }
// Config() returns the configuration // Config() returns the configuration
func (s *setting[C]) Config() C { func (s *Settings[C]) Config() C {
return s.config return s.config
} }
...@@ -10,19 +10,19 @@ type ChangeEvent struct { ...@@ -10,19 +10,19 @@ type ChangeEvent struct {
type EventHook func(event ChangeEvent) type EventHook func(event ChangeEvent)
func (s *setting[C]) OnChange(hook EventHook) *setting[C] { func (s *Settings[C]) OnChange(hook EventHook) *Settings[C] {
s.hooks.change = append(s.hooks.change, hook) s.hooks.change = append(s.hooks.change, hook)
return s return s
} }
func (s *setting[C]) notifyChangeHooks(changelog diff.Changelog) *setting[C] { func (s *Settings[C]) notifyChangeHooks(changelog diff.Changelog) *Settings[C] {
for _, h := range s.hooks.change { for _, h := range s.hooks.change {
h(ChangeEvent{Changlog: changelog}) h(ChangeEvent{Changlog: changelog})
} }
return s return s
} }
func (s *setting[C]) setConfigInternal(config C, lock bool) *setting[C] { func (s *Settings[C]) setConfigInternal(config C, lock bool) *Settings[C] {
var ( var (
changelog diff.Changelog changelog diff.Changelog
...@@ -68,6 +68,6 @@ func (s *setting[C]) setConfigInternal(config C, lock bool) *setting[C] { ...@@ -68,6 +68,6 @@ func (s *setting[C]) setConfigInternal(config C, lock bool) *setting[C] {
return s return s
} }
func (s *setting[C]) SetConfig(config C) *setting[C] { func (s *Settings[C]) SetConfig(config C) *Settings[C] {
return s.setConfigInternal(config, true) return s.setConfigInternal(config, true)
} }
...@@ -6,7 +6,7 @@ import ( ...@@ -6,7 +6,7 @@ import (
"strconv" "strconv"
) )
func (s *setting[C]) InitFromEnv(prefix string) *setting[C] { func (s *Settings[C]) InitFromEnv(prefix string) *Settings[C] {
s.Lock() s.Lock()
defer s.Unlock() defer s.Unlock()
......
...@@ -7,18 +7,18 @@ import ( ...@@ -7,18 +7,18 @@ import (
// ResetError is used to reset the error to nil // ResetError is used to reset the error to nil
// After calling this function, the call HasErrors() will return false // After calling this function, the call HasErrors() will return false
func (s *setting[C]) ResetErrors() *setting[C] { func (s *Settings[C]) ResetErrors() *Settings[C] {
s.errors = []error{} s.errors = []error{}
return s return s
} }
// Check if the setting contains errors // Check if the setting contains errors
func (s *setting[C]) HasErrors() bool { func (s *Settings[C]) HasErrors() bool {
return len(s.errors) > 0 return len(s.errors) > 0
} }
// Get all errors // Get all errors
func (s *setting[C]) Errors() []error { func (s *Settings[C]) Errors() []error {
return s.errors return s.errors
} }
......
...@@ -10,24 +10,24 @@ import ( ...@@ -10,24 +10,24 @@ import (
"gopkg.in/yaml.v3" "gopkg.in/yaml.v3"
) )
func (s *setting[C]) Export() *setting[C] { func (s *Settings[C]) Export() *Settings[C] {
return s return s
} }
func (s *setting[C]) writeJson(writer io.Writer) error { func (s *Settings[C]) writeJson(writer io.Writer) error {
encoder := json.NewEncoder(writer) encoder := json.NewEncoder(writer)
return encoder.Encode(s.config) return encoder.Encode(s.config)
} }
func (s *setting[C]) writeYaml(writer io.Writer) error { func (s *Settings[C]) writeYaml(writer io.Writer) error {
encoder := yaml.NewEncoder(writer) encoder := yaml.NewEncoder(writer)
return encoder.Encode(s.config) return encoder.Encode(s.config)
} }
func (s *setting[C]) writeToml(writer io.Writer) error { func (s *Settings[C]) writeToml(writer io.Writer) error {
encoder := toml.NewEncoder(writer) encoder := toml.NewEncoder(writer)
return encoder.Encode(s.config) return encoder.Encode(s.config)
} }
func (s *setting[C]) writeProperties(writer io.Writer) error { func (s *Settings[C]) writeProperties(writer io.Writer) error {
m, errors := getMapForProperties[C](s.config) m, errors := getMapForProperties[C](s.config)
...@@ -44,7 +44,7 @@ func (s *setting[C]) writeProperties(writer io.Writer) error { ...@@ -44,7 +44,7 @@ func (s *setting[C]) writeProperties(writer io.Writer) error {
} }
func (s *setting[C]) WriteFile(fn string, format Format) *setting[C] { func (s *Settings[C]) WriteFile(fn string, format Format) *Settings[C] {
var err error var err error
...@@ -66,7 +66,7 @@ func (s *setting[C]) WriteFile(fn string, format Format) *setting[C] { ...@@ -66,7 +66,7 @@ func (s *setting[C]) WriteFile(fn string, format Format) *setting[C] {
} }
func (s *setting[C]) Write(writer io.Writer, format Format) *setting[C] { func (s *Settings[C]) Write(writer io.Writer, format Format) *Settings[C] {
var err error var err error
......
...@@ -21,7 +21,7 @@ type fileBackend struct { ...@@ -21,7 +21,7 @@ type fileBackend struct {
} }
// AddFiles adds a file to the list of files to import // AddFiles adds a file to the list of files to import
func (s *setting[C]) AddFile(file string, format Format) *setting[C] { func (s *Settings[C]) AddFile(file string, format Format) *Settings[C] {
s.files.files = append(s.files.files, files{file, format}) s.files.files = append(s.files.files, files{file, format})
return s return s
} }
...@@ -33,12 +33,12 @@ func initFileBackend(files *fileBackend) { ...@@ -33,12 +33,12 @@ func initFileBackend(files *fileBackend) {
} }
// Path returns the configuration directory // Path returns the configuration directory
func (s *setting[C]) Directories() []string { func (s *Settings[C]) Directories() []string {
return s.files.directories return s.files.directories
} }
// AddPath adds a directory to the configuration directory // AddPath adds a directory to the configuration directory
func (s *setting[C]) AddDirectory(d string) *setting[C] { func (s *Settings[C]) AddDirectory(d string) *Settings[C] {
s.Lock() s.Lock()
defer s.Unlock() defer s.Unlock()
s.files.directories = append(s.files.directories, d) s.files.directories = append(s.files.directories, d)
...@@ -46,7 +46,7 @@ func (s *setting[C]) AddDirectory(d string) *setting[C] { ...@@ -46,7 +46,7 @@ func (s *setting[C]) AddDirectory(d string) *setting[C] {
return s return s
} }
func (s *setting[C]) sanitizeDirectories() { func (s *Settings[C]) sanitizeDirectories() {
wd, err := os.Getwd() wd, err := os.Getwd()
if err != nil { if err != nil {
...@@ -76,7 +76,7 @@ func (s *setting[C]) sanitizeDirectories() { ...@@ -76,7 +76,7 @@ func (s *setting[C]) sanitizeDirectories() {
} }
// Set all configuration directories // Set all configuration directories
func (s *setting[C]) SetDirectories(d []string) *setting[C] { func (s *Settings[C]) SetDirectories(d []string) *Settings[C] {
s.Lock() s.Lock()
defer s.Unlock() defer s.Unlock()
...@@ -86,7 +86,7 @@ func (s *setting[C]) SetDirectories(d []string) *setting[C] { ...@@ -86,7 +86,7 @@ func (s *setting[C]) SetDirectories(d []string) *setting[C] {
} }
// Add the current working directory to the configuration directory // Add the current working directory to the configuration directory
func (s *setting[C]) AddWorkingDirectory() *setting[C] { func (s *Settings[C]) AddWorkingDirectory() *Settings[C] {
s.Lock() s.Lock()
defer s.Unlock() defer s.Unlock()
...@@ -101,7 +101,7 @@ func (s *setting[C]) AddWorkingDirectory() *setting[C] { ...@@ -101,7 +101,7 @@ func (s *setting[C]) AddWorkingDirectory() *setting[C] {
} }
// Add the Unix etc directory to the configuration directory // Add the Unix etc directory to the configuration directory
func (s *setting[C]) AddEtcDirectory() *setting[C] { func (s *Settings[C]) AddEtcDirectory() *Settings[C] {
s.Lock() s.Lock()
defer s.Unlock() defer s.Unlock()
...@@ -125,7 +125,7 @@ func (s *setting[C]) AddEtcDirectory() *setting[C] { ...@@ -125,7 +125,7 @@ func (s *setting[C]) AddEtcDirectory() *setting[C] {
// Add the user configuration directory to the configuration directory // Add the user configuration directory to the configuration directory
// The mnemonic must be set for this function // The mnemonic must be set for this function
func (s *setting[C]) AddUserConfigDirectory() *setting[C] { func (s *Settings[C]) AddUserConfigDirectory() *Settings[C] {
if s.mnemonic == "" { if s.mnemonic == "" {
s.errors = append(s.errors, MnemonicEmptyError) s.errors = append(s.errors, MnemonicEmptyError)
...@@ -149,14 +149,14 @@ func (s *setting[C]) AddUserConfigDirectory() *setting[C] { ...@@ -149,14 +149,14 @@ func (s *setting[C]) AddUserConfigDirectory() *setting[C] {
// Add the current working directory, the user configuration directory // Add the current working directory, the user configuration directory
// and the Unix etc directory to the configuration directory // and the Unix etc directory to the configuration directory
func (s *setting[C]) SetDefaultDirectories() *setting[C] { func (s *Settings[C]) SetDefaultDirectories() *Settings[C] {
s.AddWorkingDirectory(). s.AddWorkingDirectory().
AddUserConfigDirectory(). AddUserConfigDirectory().
AddEtcDirectory() AddEtcDirectory()
return s return s
} }
func (s *setting[C]) SetFileFormat(format Format) *setting[C] { func (s *Settings[C]) SetFileFormat(format Format) *Settings[C] {
if slices.Contains(availableFormats, format) { if slices.Contains(availableFormats, format) {
s.files.format = format s.files.format = format
...@@ -168,7 +168,7 @@ func (s *setting[C]) SetFileFormat(format Format) *setting[C] { ...@@ -168,7 +168,7 @@ func (s *setting[C]) SetFileFormat(format Format) *setting[C] {
} }
// Set the file name without extension // Set the file name without extension
func (s *setting[C]) SetFileName(name string) *setting[C] { func (s *Settings[C]) SetFileName(name string) *Settings[C] {
if name == "" { if name == "" {
s.errors = append(s.errors, FileNameEmptyError) s.errors = append(s.errors, FileNameEmptyError)
...@@ -179,7 +179,7 @@ func (s *setting[C]) SetFileName(name string) *setting[C] { ...@@ -179,7 +179,7 @@ func (s *setting[C]) SetFileName(name string) *setting[C] {
return s return s
} }
func (s *setting[C]) SetFilesystem(f fs.FS) *setting[C] { func (s *Settings[C]) SetFilesystem(f fs.FS) *Settings[C] {
s.files.fs = f s.files.fs = f
return s return s
} }
...@@ -6,9 +6,9 @@ import ( ...@@ -6,9 +6,9 @@ import (
"strconv" "strconv"
) )
// AddFileFromFlags adds a file to the configuration // AddFileFromFlagSet adds a file to the configuration
// The file is read from the flag specified by the name // The file is read from the flag specified by the name
func (s *setting[C]) AddFileFromFlagSet(flagset *flag.FlagSet, name string, format Format) *setting[C] { func (s *Settings[C]) AddFileFromFlagSet(flagset *flag.FlagSet, name string, format Format) *Settings[C] {
flag := flagset.Lookup(name) flag := flagset.Lookup(name)
if flag == nil { if flag == nil {
...@@ -25,8 +25,8 @@ func (s *setting[C]) AddFileFromFlagSet(flagset *flag.FlagSet, name string, form ...@@ -25,8 +25,8 @@ func (s *setting[C]) AddFileFromFlagSet(flagset *flag.FlagSet, name string, form
return s.AddFile(path, format) return s.AddFile(path, format)
} }
// InitFromFlags initializes the configuration from the command line flags. // InitFromFlagSet initializes the configuration from the command line flags.
func (s *setting[C]) InitFromFlagSet(flagset *flag.FlagSet) *setting[C] { func (s *Settings[C]) InitFromFlagSet(flagset *flag.FlagSet) *Settings[C] {
s.Lock() s.Lock()
defer s.Unlock() defer s.Unlock()
......
...@@ -9,7 +9,7 @@ import ( ...@@ -9,7 +9,7 @@ import (
// ContextKey is the key used to store the configuration in the request context // ContextKey is the key used to store the configuration in the request context
// This is used by the middleware // This is used by the middleware
func (s *setting[C]) Middleware(next http.Handler) http.Handler { func (s *Settings[C]) Middleware(next http.Handler) http.Handler {
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
ctx := r.Context() ctx := r.Context()
ctx = context.WithValue(ctx, contextKey, s.config) ctx = context.WithValue(ctx, contextKey, s.config)
...@@ -19,7 +19,7 @@ func (s *setting[C]) Middleware(next http.Handler) http.Handler { ...@@ -19,7 +19,7 @@ func (s *setting[C]) Middleware(next http.Handler) http.Handler {
} }
// serveGet handles GET requests // serveGet handles GET requests
func (s *setting[C]) serveGet(w http.ResponseWriter, r *http.Request) { func (s *Settings[C]) serveGet(w http.ResponseWriter, r *http.Request) {
n := negotiation.New(r.Header) n := negotiation.New(r.Header)
m := n.Type("application/json", "text/json", "application/yaml", "text/yaml", "application/toml", "text/toml", "application/properties", "text/properties", "text/x-java-properties", "text/x-properties") m := n.Type("application/json", "text/json", "application/yaml", "text/yaml", "application/toml", "text/toml", "application/properties", "text/properties", "text/x-java-properties", "text/x-properties")
...@@ -56,7 +56,7 @@ func (s *setting[C]) serveGet(w http.ResponseWriter, r *http.Request) { ...@@ -56,7 +56,7 @@ func (s *setting[C]) serveGet(w http.ResponseWriter, r *http.Request) {
} }
func (s *setting[C]) servePost(w http.ResponseWriter, r *http.Request) { func (s *Settings[C]) servePost(w http.ResponseWriter, r *http.Request) {
n := negotiation.New(r.Header) n := negotiation.New(r.Header)
m := n.ContentType("application/json", "text/json", "application/yaml", "text/yaml", "application/toml", "text/toml", "application/properties", "text/properties", "text/x-java-properties", "text/x-properties") m := n.ContentType("application/json", "text/json", "application/yaml", "text/yaml", "application/toml", "text/toml", "application/properties", "text/properties", "text/x-java-properties", "text/x-properties")
...@@ -93,7 +93,7 @@ func (s *setting[C]) servePost(w http.ResponseWriter, r *http.Request) { ...@@ -93,7 +93,7 @@ func (s *setting[C]) servePost(w http.ResponseWriter, r *http.Request) {
} }
// ServeHTTP implements the http.Handler interface // ServeHTTP implements the http.Handler interface
func (s *setting[C]) ServeHTTP(w http.ResponseWriter, r *http.Request) { func (s *Settings[C]) ServeHTTP(w http.ResponseWriter, r *http.Request) {
switch r.Method { switch r.Method {
case http.MethodGet: case http.MethodGet:
......
...@@ -42,7 +42,7 @@ func importProperties[C any](config *C, reader io.Reader) error { ...@@ -42,7 +42,7 @@ func importProperties[C any](config *C, reader io.Reader) error {
} }
func (s *setting[C]) importStream(r reader) { func (s *Settings[C]) importStream(r reader) {
var c C var c C
var err error var err error
...@@ -73,17 +73,17 @@ func (s *setting[C]) importStream(r reader) { ...@@ -73,17 +73,17 @@ func (s *setting[C]) importStream(r reader) {
} }
} }
func (s *setting[C]) importStreams() { func (s *Settings[C]) importStreams() {
for _, r := range s.stream.readers { for _, r := range s.stream.readers {
s.importStream(r) s.importStream(r)
} }
} }
func (s *setting[C]) importFiles() { func (s *Settings[C]) importFiles() {
s.fileWatch.Lock() s.fileWatch.Lock()
defer s.fileWatch.Unlock() defer s.fileWatch.Unlock()
// new files may have been added // new files may have been added
s.fileWatch.watchList = make(map[string]string) s.fileWatch.watchList = make(map[string]string)
...@@ -120,7 +120,7 @@ func (s *setting[C]) importFiles() { ...@@ -120,7 +120,7 @@ func (s *setting[C]) importFiles() {
} }
func (s *setting[C]) Import() *setting[C] { func (s *Settings[C]) Import() *Settings[C] {
s.Lock() s.Lock()
defer s.Unlock() defer s.Unlock()
......
{"version":"1.3.0"} {"version":"1.4.0"}
...@@ -15,7 +15,7 @@ type fileWatch struct { ...@@ -15,7 +15,7 @@ type fileWatch struct {
onWatch bool onWatch bool
} }
type setting[C any] struct { type Settings[C any] struct {
files fileBackend files fileBackend
stream streamBackend stream streamBackend
config C config C
...@@ -30,7 +30,7 @@ type setting[C any] struct { ...@@ -30,7 +30,7 @@ type setting[C any] struct {
fileWatch fileWatch fileWatch fileWatch
} }
func (s *setting[C]) initDefaults() *setting[C] { func (s *Settings[C]) initDefaults() *Settings[C] {
err := runOnTags(&s.config, []string{"default"}, func(v string, field reflect.Value) { err := runOnTags(&s.config, []string{"default"}, func(v string, field reflect.Value) {
......
...@@ -20,20 +20,20 @@ type streamBackend struct { ...@@ -20,20 +20,20 @@ type streamBackend struct {
//type StreamOption struct { //type StreamOption struct {
//} //}
//func (s *setting[C]) AddStream(stream io.ReadWriter, format Format) *setting[C] { //func (s *Settings[C]) AddStream(stream io.ReadWriter, format Format) *Settings[C] {
// return s. // return s.
// AddReader(stream, format) // AddReader(stream, format)
// //AddWriter(stream, format) // //AddWriter(stream, format)
//} //}
func (s *setting[C]) AddReader(r io.Reader, format Format) *setting[C] { func (s *Settings[C]) AddReader(r io.Reader, format Format) *Settings[C] {
s.Lock() s.Lock()
defer s.Unlock() defer s.Unlock()
s.stream.readers = append(s.stream.readers, reader{format, r}) s.stream.readers = append(s.stream.readers, reader{format, r})
return s return s
} }
//func (s *setting[C]) AddWriter(w io.Writer, format Format) *setting[C] { //func (s *Settings[C]) AddWriter(w io.Writer, format Format) *Settings[C] {
// s.Lock() // s.Lock()
// defer s.Unlock() // defer s.Unlock()
// s.stream.writers = append(s.stream.writers, writer{format, w}) // s.stream.writers = append(s.stream.writers, writer{format, w})
......
...@@ -4,7 +4,7 @@ import ( ...@@ -4,7 +4,7 @@ import (
"github.com/fsnotify/fsnotify" "github.com/fsnotify/fsnotify"
) )
func (s *setting[C]) initWatch() *setting[C] { func (s *Settings[C]) initWatch() *Settings[C] {
var err error var err error
...@@ -23,7 +23,7 @@ func (s *setting[C]) initWatch() *setting[C] { ...@@ -23,7 +23,7 @@ func (s *setting[C]) initWatch() *setting[C] {
} }
func (s *setting[C]) StopWatching() *setting[C] { func (s *Settings[C]) StopWatching() *Settings[C] {
s.fileWatch.Lock() s.fileWatch.Lock()
defer s.fileWatch.Unlock() defer s.fileWatch.Unlock()
...@@ -44,7 +44,7 @@ func (s *setting[C]) StopWatching() *setting[C] { ...@@ -44,7 +44,7 @@ func (s *setting[C]) StopWatching() *setting[C] {
} }
// Watch the given file for changes // Watch the given file for changes
func (s *setting[C]) Watch() *setting[C] { func (s *Settings[C]) Watch() *Settings[C] {
s.fileWatch.Lock() s.fileWatch.Lock()
defer s.fileWatch.Unlock() defer s.fileWatch.Unlock()
......