Skip to content

Commit

Permalink
Merge branch 'main' into new-parser
Browse files Browse the repository at this point in the history
Signed-off-by: Oleg Kovalov <oleg@hey.com>
  • Loading branch information
cristaloleg committed Dec 26, 2023
2 parents 1e0dc4d + 3a81b29 commit ed1d40b
Show file tree
Hide file tree
Showing 11 changed files with 198 additions and 160 deletions.
17 changes: 12 additions & 5 deletions .github/dependabot.yml
Original file line number Diff line number Diff line change
@@ -1,11 +1,18 @@
version: 2
updates:
- package-ecosystem: gomod
- package-ecosystem: "gomod"
commit-message:
prefix: "deps:"
directory: "/"
schedule:
interval: daily
- package-ecosystem: github-actions
interval: "weekly"
day: "sunday"
time: "09:00"
- package-ecosystem: "github-actions"
commit-message:
prefix: "ci:"
directory: "/"
schedule:
interval: daily

interval: "weekly"
day: "sunday"
time: "09:00"
18 changes: 6 additions & 12 deletions .github/workflows/build.yml
Original file line number Diff line number Diff line change
Expand Up @@ -4,20 +4,14 @@ on:
push:
branches: [main]
pull_request:
workflow_dispatch:
inputs:
tag:
description: 'Tag to create'
required: true
default: 'v0.0.0'
branches: [main]
schedule:
- cron: '0 0 * * 0' # run "At 00:00 on Sunday"

# See https://github.com/cristalhq/.github/.github/workflows
jobs:
build:
uses: cristalhq/.github/.github/workflows/build.yml@main
uses: cristalhq/.github/.github/workflows/build.yml@v0.7.0

release:
if: github.event_name == 'workflow_dispatch'
uses: cristalhq/.github/.github/workflows/release.yml@main
with:
tag: ${{ github.event.input.tag }}
vuln:
uses: cristalhq/.github/.github/workflows/vuln.yml@v0.7.0
14 changes: 4 additions & 10 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,15 +2,13 @@

[![build-img]][build-url]
[![pkg-img]][pkg-url]
[![reportcard-img]][reportcard-url]
[![coverage-img]][coverage-url]
[![version-img]][version-url]

Simple, useful and opinionated config loader.

## Rationale

There are many solutions regarding configuration loading in Go. I was looking for a simple loader that is as easy to use and understand as possible. The goal was to load config from 4 places: defaults (in the code), files, environment variables, command-line flags. This library works with all of this sources.
There are many solutions regarding configuration loading in Go. I was looking for a simple loader that is as easy to use and understand as possible. The goal was to load config from 4 places: defaults (in the code), files, environment variables, command-line flags. This library works with all of these sources.

## Features

Expand Down Expand Up @@ -39,8 +37,8 @@ go get github.com/cristalhq/aconfig
type MyConfig struct {
Port int `default:"1111" usage:"just give a number"`
Auth struct {
User string `default:"def-user"`
Pass string `default:"def-pass"`
User string `required:"true"`
Pass string `required:"true"`
}
Pass string `default:"" env:"SECRET" flag:"sec_ret"`
}
Expand Down Expand Up @@ -74,7 +72,7 @@ if err := loader.Load(); err != nil {
// 1. defaults set in structure tags (see MyConfig defenition)
// 2. loaded from files `file.json` if not `ouch.yaml` will be used
// 3. from corresponding environment variables with the prefix `APP_`
// 4. command-line flags with the prefix `app.` if they are
// 4. command-line flags with the prefix `app.` if they are
```

Also see examples: [examples_test.go](https://github.com/cristalhq/aconfig/blob/master/example_test.go).
Expand All @@ -93,9 +91,5 @@ See [these docs][pkg-url].
[build-url]: https://github.com/cristalhq/aconfig/actions
[pkg-img]: https://pkg.go.dev/badge/cristalhq/aconfig
[pkg-url]: https://pkg.go.dev/github.com/cristalhq/aconfig
[reportcard-img]: https://goreportcard.com/badge/cristalhq/aconfig
[reportcard-url]: https://goreportcard.com/report/cristalhq/aconfig
[coverage-img]: https://codecov.io/gh/cristalhq/aconfig/branch/master/graph/badge.svg
[coverage-url]: https://codecov.io/gh/cristalhq/aconfig
[version-img]: https://img.shields.io/github/v/release/cristalhq/aconfig
[version-url]: https://github.com/cristalhq/aconfig/releases
23 changes: 14 additions & 9 deletions aconfig.go
Original file line number Diff line number Diff line change
Expand Up @@ -286,15 +286,20 @@ func (l *Loader) loadSources() error {
}

func (l *Loader) checkRequired() error {
missedFields := []string{}
for _, field := range l.fields {
if field.isSet {
continue
}
if field.isRequired || l.config.AllFieldRequired {
return fmt.Errorf("field %s is required but not set", field.name)
missedFields = append(missedFields, field.name)
}
}
return nil

if len(missedFields) == 0 {
return nil
}
return fmt.Errorf("fields required but not set: %s", strings.Join(missedFields, ","))
}

func (l *Loader) loadDefaults() error {
Expand Down Expand Up @@ -381,8 +386,8 @@ func (l *Loader) loadFile(file string) error {
}

if !l.config.AllowUnknownFields {
for env, value := range actualFields {
return fmt.Errorf("unknown field in file %q: %s=%v (see AllowUnknownFields config param)", file, env, value)
for env := range actualFields {
return fmt.Errorf("unknown field in file %q: %s (see AllowUnknownFields config param)", file, env)
}
}
return nil
Expand Down Expand Up @@ -437,9 +442,9 @@ func (l *Loader) postEnvCheck(values map[string]interface{}, dupls map[string]st
for name := range dupls {
delete(values, name)
}
for env, value := range values {
for env := range values {
if strings.HasPrefix(env, l.config.EnvPrefix) {
return fmt.Errorf("unknown environment var %s=%v (see AllowUnknownEnvs config param)", env, value)
return fmt.Errorf("unknown environment var %s (see AllowUnknownEnvs config param)", env)
}
}
return nil
Expand Down Expand Up @@ -475,15 +480,15 @@ func (l *Loader) postFlagCheck(values map[string]interface{}, dupls map[string]s
for name := range dupls {
delete(values, name)
}
for flag, value := range values {
for flag := range values {
if strings.HasPrefix(flag, l.config.FlagPrefix) {
return fmt.Errorf("unknown flag %s=%v (see AllowUnknownFlags config param)", flag, value)
return fmt.Errorf("unknown flag %s (see AllowUnknownFlags config param)", flag)
}
}
return nil
}

// TODO(cristaloleg): revisit
// TODO(cristaloleg): revisit.
func (l *Loader) setField(field *fieldData, name string, values map[string]interface{}, dupls map[string]struct{}) error {
if !l.config.AllowDuplicates {
if _, ok := dupls[name]; ok {
Expand Down

0 comments on commit ed1d40b

Please sign in to comment.