Skip to content

Commit

Permalink
Merge pull request #4 from zpatrick/cleanup
Browse files Browse the repository at this point in the history
remove extra directory, cleanup readme
  • Loading branch information
Zack Patrick authored Feb 27, 2024
2 parents 19e9028 + 1fe3a70 commit c0e954a
Show file tree
Hide file tree
Showing 14 changed files with 42 additions and 149 deletions.
44 changes: 22 additions & 22 deletions .github/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,11 @@
[![Go Doc](https://godoc.org/github.com/zpatrick/cfg?status.svg)](https://godoc.org/github.com/zpatrick/cfg)
[![Build Status](https://github.com/zpatrick/cfg/actions/workflows/go.yaml/badge.svg?branch=main)](https://github.com/zpatrick/cfg/actions/workflows/go.yaml?query=branch%3Amain)

This package is designed to house a common set of configuration-related features & patterns for teams working with microservice applications. These designs include:
This package is designed to house a common set of configuration-related features & patterns for Golang services. This include:

- Support for multiple sources of configuration.
- Providing default values and validation logic for specific settings.
- Support access patterns which encourage decoupling configuration logic from the rest of the application.
- Package API which encourages high cohesion and low coupling with the rest of the application.

## Usage

Expand All @@ -20,8 +20,8 @@ import (
"time"

"github.com/zpatrick/cfg"
"github.com/zpatrick/cfg/providers/envvar"
"github.com/zpatrick/cfg/providers/yaml"
"github.com/zpatrick/cfg/envvar"
"github.com/zpatrick/cfg/ini"
)

type Config struct {
Expand All @@ -32,7 +32,7 @@ type Config struct {
}

func LoadConfig(ctx context.Context, path string) (*Config, error) {
yamlFile, err := yaml.New(path)
iniFile, err := ini.Load(path)
if err != nil {
return nil, err
}
Expand All @@ -55,7 +55,7 @@ func LoadConfig(ctx context.Context, path string) (*Config, error) {
Default: cfg.Addr(8080),
Provider: cfg.MultiProvider {
envvar.Newf("APP_SERVER_PORT", strconv.Atoi),
yamlFile.Int("server", "port"),
iniFile.Int("server", "port"),
},
},
"server timeout": cfg.Schema[time.Duration]{
Expand All @@ -64,7 +64,7 @@ func LoadConfig(ctx context.Context, path string) (*Config, error) {
Validator: cfg.Between(time.Second, time.Minute*5),
Provider: cfg.MultiProvider {
envvar.Newf("APP_SERVER_TIMEOUT", time.ParseDuration),
yamlFile.Duration("server", "timeout"),
iniFile.Duration("server", "timeout"),
},
},
}); err != nil {
Expand All @@ -82,8 +82,8 @@ func LoadConfig(ctx context.Context, path string) (*Config, error) {
- [Flags](https://pkg.go.dev/github.com/zpatrick/cfg#Flag)
- [INI Files](https://pkg.go.dev/github.com/zpatrick/cfg#INIFile)
- [TOML Files](https://pkg.go.dev/github.com/zpatrick/cfg#TOMLFile)
- [YAML Files](https://pkg.go.dev/github.com/zpatrick/cfg#YAMLFile)

Please see the [Godoc](https://pkg.go.dev/github.com/zpatrick/cfg#example-YAML) example for YAML files.

# Validation
A setting may specify a [Validator](https://pkg.go.dev/github.com/zpatrick/cfg#Validator) which will check whether or not a provided value is valid.
Expand All @@ -97,6 +97,20 @@ The built in validators are:

# Advanced

## Custom Validation
A custom Validator must satisfy the [Validator](https://pkg.go.dev/github.com/zpatrick/cfg#Validator) interface.
The simplest way to achieve this is by using the [ValidatorFunc](https://pkg.go.dev/github.com/zpatrick/cfg#ValidatorFunc) type.

```go
cfg.Setting[string]{
Default: cfg.Addr("name@email.com"),
Validator: cfg.ValidatorFunc(func(addr string) error {
_, err := mail.ParseAddr(addr)
return err
}),
}
```

## Custom Providers

```go
Expand Down Expand Up @@ -134,17 +148,3 @@ func LoadConfig() (*Config, error) {
...
}
```

## Custom Validation
A custom Validator must satisfy the [Validator](https://pkg.go.dev/github.com/zpatrick/cfg#Validator) interface.
The simplest way to achieve this is by using the [ValidatorFunc](https://pkg.go.dev/github.com/zpatrick/cfg#ValidatorFunc) type.

```go
cfg.Setting[string]{
Default: cfg.Addr("name@email.com"),
Validator: cfg.ValidatorFunc(func(addr string) error {
_, err := mail.ParseAddr(addr)
return err
}),
}
```
File renamed without changes.
2 changes: 1 addition & 1 deletion providers/envvar/envvar_test.go → envvar/envvar_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ import (
"testing"

"github.com/zpatrick/cfg"
"github.com/zpatrick/cfg/providers/envvar"
"github.com/zpatrick/cfg/envvar"
"github.com/zpatrick/testx/assert"
)

Expand Down
File renamed without changes.
2 changes: 1 addition & 1 deletion providers/flags/flags_test.go → flags/flags_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ import (
"testing"

"github.com/zpatrick/cfg"
"github.com/zpatrick/cfg/providers/flags"
"github.com/zpatrick/cfg/flags"
"github.com/zpatrick/testx/assert"
)

Expand Down
4 changes: 2 additions & 2 deletions providers/ini/example_test.go → ini/example_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,8 @@ import (
"time"

"github.com/zpatrick/cfg"
"github.com/zpatrick/cfg/ini"
"github.com/zpatrick/cfg/internal"
"github.com/zpatrick/cfg/providers/ini"
)

type Config struct {
Expand All @@ -32,7 +32,7 @@ addr = "localhost"
}
defer os.Remove(path)

iniFile, err := ini.New(path)
iniFile, err := ini.Load(path)
if err != nil {
panic(err)
}
Expand Down
9 changes: 7 additions & 2 deletions providers/ini/ini.go → ini/ini.go
Original file line number Diff line number Diff line change
Expand Up @@ -16,8 +16,8 @@ type Provider struct {
f *ini.File
}

// New returns a Provider which loads values from the parsed ini file at the given path.
func New(path string) (*Provider, error) {
// Load reads and parses the ini file at the given path.
func Load(path string) (*Provider, error) {
data, err := os.ReadFile(path)
if err != nil {
return nil, err
Expand All @@ -31,6 +31,11 @@ func New(path string) (*Provider, error) {
return &Provider{f: f}, nil
}

// New returns a Provider which loads values from f.
func New(f *ini.File) (*Provider, error) {
return &Provider{f: f}, nil
}

// String returns a string configuration value at the given section and key.
func (p *Provider) String(section, key string) cfg.Provider[string] {
return Provide(p, section, key, func(k *ini.Key) (string, error) { return k.String(), nil })
Expand Down
4 changes: 2 additions & 2 deletions providers/ini/ini_test.go → ini/ini_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,8 @@ import (
"time"

"github.com/zpatrick/cfg"
"github.com/zpatrick/cfg/ini"
"github.com/zpatrick/cfg/internal"
"github.com/zpatrick/cfg/providers/ini"
"github.com/zpatrick/testx/assert"
)

Expand All @@ -27,7 +27,7 @@ timeout = "5s"
assert.NilError(t, err)
t.Cleanup(func() { os.Remove(path) })

f, err := ini.New(path)
f, err := ini.Load(path)
assert.NilError(t, err)

internal.AssertProvides(t, f.String("", "root"), "hello")
Expand Down
4 changes: 2 additions & 2 deletions internal/testing.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ package internal
import (
"bytes"
"context"
"io/ioutil"
"os"
"testing"

"github.com/zpatrick/cfg"
Expand All @@ -13,7 +13,7 @@ import (
// WriteTempFile creates a new temporary file under dir with the contents of data.
// The file name is returned.
func WriteTempFile(dir, data string) (string, error) {
file, err := ioutil.TempFile(dir, "config.yaml")
file, err := os.CreateTemp(dir, "config.yaml")
if err != nil {
return "", nil
}
Expand Down
2 changes: 1 addition & 1 deletion provider_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ import (

"github.com/pkg/errors"
"github.com/zpatrick/cfg"
"github.com/zpatrick/cfg/providers/envvar"
"github.com/zpatrick/cfg/envvar"
"github.com/zpatrick/testx/assert"
)

Expand Down
112 changes: 0 additions & 112 deletions providers/generic/generic.go

This file was deleted.

2 changes: 1 addition & 1 deletion providers/toml/example_test.go → toml/example_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ import (

"github.com/zpatrick/cfg"
"github.com/zpatrick/cfg/internal"
"github.com/zpatrick/cfg/providers/toml"
"github.com/zpatrick/cfg/toml"
)

type Config struct {
Expand Down
4 changes: 2 additions & 2 deletions providers/toml/toml.go → toml/toml.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ import (

"github.com/pelletier/go-toml"
"github.com/zpatrick/cfg"
"github.com/zpatrick/cfg/providers/generic"
"github.com/zpatrick/cfg/internal"
)

type Provider struct {
Expand Down Expand Up @@ -68,7 +68,7 @@ func Provide[T any](p *Provider, keys ...string) cfg.Provider[T] {
val := p.tree.GetPath(keys)
v, ok := val.(T)
if !ok {
return out, generic.NewUnexpectedTypeError(out, val)
return out, internal.NewUnexpectedTypeError(out, val)
}

return v, nil
Expand Down
2 changes: 1 addition & 1 deletion providers/toml/toml_test.go → toml/toml_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ import (

"github.com/zpatrick/cfg"
"github.com/zpatrick/cfg/internal"
"github.com/zpatrick/cfg/providers/toml"
"github.com/zpatrick/cfg/toml"
"github.com/zpatrick/testx/assert"
)

Expand Down

0 comments on commit c0e954a

Please sign in to comment.