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>
## [v1.3.0] - 2022-09-18
### Code Refactoring
......@@ -26,6 +35,7 @@
<a name="v1.0.0"></a>
## 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.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
......
This diff is collapsed.
## Configuration
## What do this library?
## What does this library?
This library provides a simple way to load configuration from different sources.
......
......@@ -4,9 +4,9 @@ import "github.com/imdario/mergo"
// NewSetting creates a new configuration setting
// 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()
if err := mergo.Merge(&defaults, s.config); err != nil {
......@@ -28,7 +28,7 @@ func New[C any](defaults C) *setting[C] {
// Set the mnemonic
// 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 == "" {
s.errors = append(s.errors, MnemonicEmptyError)
} else {
......@@ -38,6 +38,6 @@ func (s *setting[C]) SetMnemonic(mnemonic string) *setting[C] {
}
// Config() returns the configuration
func (s *setting[C]) Config() C {
func (s *Settings[C]) Config() C {
return s.config
}
......@@ -10,19 +10,19 @@ type ChangeEvent struct {
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)
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 {
h(ChangeEvent{Changlog: changelog})
}
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 (
changelog diff.Changelog
......@@ -68,6 +68,6 @@ func (s *setting[C]) setConfigInternal(config C, lock bool) *setting[C] {
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)
}
......@@ -6,7 +6,7 @@ import (
"strconv"
)
func (s *setting[C]) InitFromEnv(prefix string) *setting[C] {
func (s *Settings[C]) InitFromEnv(prefix string) *Settings[C] {
s.Lock()
defer s.Unlock()
......
......@@ -7,18 +7,18 @@ import (
// ResetError is used to reset the error to nil
// 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{}
return s
}
// Check if the setting contains errors
func (s *setting[C]) HasErrors() bool {
func (s *Settings[C]) HasErrors() bool {
return len(s.errors) > 0
}
// Get all errors
func (s *setting[C]) Errors() []error {
func (s *Settings[C]) Errors() []error {
return s.errors
}
......
......@@ -10,24 +10,24 @@ import (
"gopkg.in/yaml.v3"
)
func (s *setting[C]) Export() *setting[C] {
func (s *Settings[C]) Export() *Settings[C] {
return s
}
func (s *setting[C]) writeJson(writer io.Writer) error {
func (s *Settings[C]) writeJson(writer io.Writer) error {
encoder := json.NewEncoder(writer)
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)
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)
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)
......@@ -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
......@@ -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
......
......@@ -21,7 +21,7 @@ type fileBackend struct {
}
// 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})
return s
}
......@@ -33,12 +33,12 @@ func initFileBackend(files *fileBackend) {
}
// Path returns the configuration directory
func (s *setting[C]) Directories() []string {
func (s *Settings[C]) Directories() []string {
return s.files.directories
}
// 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()
defer s.Unlock()
s.files.directories = append(s.files.directories, d)
......@@ -46,7 +46,7 @@ func (s *setting[C]) AddDirectory(d string) *setting[C] {
return s
}
func (s *setting[C]) sanitizeDirectories() {
func (s *Settings[C]) sanitizeDirectories() {
wd, err := os.Getwd()
if err != nil {
......@@ -76,7 +76,7 @@ func (s *setting[C]) sanitizeDirectories() {
}
// Set all configuration directories
func (s *setting[C]) SetDirectories(d []string) *setting[C] {
func (s *Settings[C]) SetDirectories(d []string) *Settings[C] {
s.Lock()
defer s.Unlock()
......@@ -86,7 +86,7 @@ func (s *setting[C]) SetDirectories(d []string) *setting[C] {
}
// 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()
defer s.Unlock()
......@@ -101,7 +101,7 @@ func (s *setting[C]) AddWorkingDirectory() *setting[C] {
}
// 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()
defer s.Unlock()
......@@ -125,7 +125,7 @@ func (s *setting[C]) AddEtcDirectory() *setting[C] {
// Add the user configuration directory to the configuration directory
// 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 == "" {
s.errors = append(s.errors, MnemonicEmptyError)
......@@ -149,14 +149,14 @@ func (s *setting[C]) AddUserConfigDirectory() *setting[C] {
// Add the current working directory, the user 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().
AddUserConfigDirectory().
AddEtcDirectory()
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) {
s.files.format = format
......@@ -168,7 +168,7 @@ func (s *setting[C]) SetFileFormat(format Format) *setting[C] {
}
// 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 == "" {
s.errors = append(s.errors, FileNameEmptyError)
......@@ -179,7 +179,7 @@ func (s *setting[C]) SetFileName(name string) *setting[C] {
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
return s
}
......@@ -6,9 +6,9 @@ import (
"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
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)
if flag == nil {
......@@ -25,8 +25,8 @@ func (s *setting[C]) AddFileFromFlagSet(flagset *flag.FlagSet, name string, form
return s.AddFile(path, format)
}
// InitFromFlags initializes the configuration from the command line flags.
func (s *setting[C]) InitFromFlagSet(flagset *flag.FlagSet) *setting[C] {
// InitFromFlagSet initializes the configuration from the command line flags.
func (s *Settings[C]) InitFromFlagSet(flagset *flag.FlagSet) *Settings[C] {
s.Lock()
defer s.Unlock()
......
......@@ -9,7 +9,7 @@ import (
// ContextKey is the key used to store the configuration in the request context
// 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) {
ctx := r.Context()
ctx = context.WithValue(ctx, contextKey, s.config)
......@@ -19,7 +19,7 @@ func (s *setting[C]) Middleware(next http.Handler) http.Handler {
}
// 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)
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) {
}
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)
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) {
}
// 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 {
case http.MethodGet:
......
......@@ -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 err error
......@@ -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 {
s.importStream(r)
}
}
func (s *setting[C]) importFiles() {
func (s *Settings[C]) importFiles() {
s.fileWatch.Lock()
defer s.fileWatch.Unlock()
// new files may have been added
s.fileWatch.watchList = make(map[string]string)
......@@ -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()
defer s.Unlock()
......
{"version":"1.3.0"}
{"version":"1.4.0"}
......@@ -15,7 +15,7 @@ type fileWatch struct {
onWatch bool
}
type setting[C any] struct {
type Settings[C any] struct {
files fileBackend
stream streamBackend
config C
......@@ -30,7 +30,7 @@ type setting[C any] struct {
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) {
......
......@@ -20,20 +20,20 @@ type streamBackend 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.
// AddReader(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()
defer s.Unlock()
s.stream.readers = append(s.stream.readers, reader{format, r})
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()
// defer s.Unlock()
// s.stream.writers = append(s.stream.writers, writer{format, w})
......
......@@ -4,7 +4,7 @@ import (
"github.com/fsnotify/fsnotify"
)
func (s *setting[C]) initWatch() *setting[C] {
func (s *Settings[C]) initWatch() *Settings[C] {
var err error
......@@ -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()
defer s.fileWatch.Unlock()
......@@ -44,7 +44,7 @@ func (s *setting[C]) StopWatching() *setting[C] {
}
// Watch the given file for changes
func (s *setting[C]) Watch() *setting[C] {
func (s *Settings[C]) Watch() *Settings[C] {
s.fileWatch.Lock()
defer s.fileWatch.Unlock()
......