Giter Club home page Giter Club logo

fig's People

Contributors

arieltorti avatar joshkaplinsky avatar jparise avatar kkyr avatar rsjethani avatar wneessen avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar

fig's Issues

feat: being able to add env name for a specific field

Hello and thanks for your great package.
I have a specific use case in which env var is using another names which is different with the name generated by the fig for that field.

Can we add a new feature to achieve this.

Something like this:

type Config struct {
    Field int `fig:"field" env:"DIFFERENT_KEY"`	
}

This way, the config is loaded from a file using the current approach. But if the DIFFERENT_KEY env is set, its value will be used for this field.

Feature request: custom type unmarshalling

First of all, I love fig. It's such a versatile tool, thanks for this!

I was wondering if there would be a posibility to add config parsing/unmarshaling for custom types, like encode/json allows to provide a UnmarshalJSON() method. This would help i. e. with custom "enums" type that are set up via iota.

Here is an example:
Let's say I have a custom type ListenerType and I pre-define 3 types via const:

// ListenerType is an enumeration wrapper for the different listener types
type ListenerType uint

const (
        ListenerUnix ListenerType = iota
        ListenerTCP
        ListenerTLS
)

In my config struct, I would then define my config setting with the corresponding ListenerType and a default value:

// Config holds all the global configuration settings that are parsed by fig
type Config struct {
        // Server holds server specific configuration values
        Server struct {
                PIDFile      string               `fig:"pid_file" default:"/var/run/app.pid"`
                ListenerType ListenerType `fig:"listener_type" default:"unix"`
        }
}

By default this would of course not work, as the default or provided setting in the config file would be a string, not an uint. But here comes my request into play. fig defines an interface like this:

type Unmarshaler interface {
        UnmarshalType(string) error
}

and checks if the corresponding type provides a method that satisfies this interface. For my example it could look like this:

func (l *ListenerType) UnmarshalType(v string) error {
        switch strings.ToLower(v) {
        case "unix":
                *l = ListenerUnix
        case "tcp":
                *l = ListenerTCP
        case "tls":
                *l = ListenerTLS
        default:
                return fmt.Errorf("unknown listener type: %s", v)
        }
        return nil
}

This way, I can keep my iota type but fill the values via fig with the actual string values instead of the user having to provide "0", "1" or "2".

Hope this makes sense and is something you would consider adding.

Make it possible to use only environment variables (with no config file)

Currently, environment variables can't be used as a full replacement for a config file, only in addition to one. If no config file exists, I think it should just use the defaults from the struct, check environment variables if UseEnv is set, and then return an error if required stuff is not set (e.g. port: required validation failed (using only environment as no config file could be found)).

Feature request: auto create config file if not found

I am writing an app that looks for a config.yaml in

  • ".",
  • "/etc/myapp",
  • "/home/user/myapp",
  • "$HOME/.config/myapp,

What I wish to add is an option to auto-create file on the initial startup. Of course, I can make it on my own before fig.Load() but it will duplicate the code in the package (like methods findCfgFiles). Besides that, since I store all config properties under fig annotations it will be simple and more convenient.

Do you mind adding that kind of feature? I can open the PR soon

Add an option to explicitly set which config file to use

It would be nice to have an option/function to explicitly load the config file that was provided by user.
The idea is to have smth like:

package main

var configFile = flag.String("config", "app.yaml", "Config file to use") // so it may have the value like `/usr/local/etc/name_by_user.yaml`

func main() {
    flag.Parse()
    err := fig.Load(&cfg, fig.File(*configFile))
}

In the current implementation it wouldn't work because fig will search for the file in the current directory (.) only by default. But it also can check for the file existence using only given path:

func (f *fig) findCfgFile() (path string, err error) {
	for _, dir := range f.dirs {
		path = filepath.Join(dir, f.filename)
		if fileExists(path) {
			return
		}
	}
        if path = f.filename; fileExists(path) {
            return
        }
	return "", fmt.Errorf("%s: %w", f.filename, ErrFileNotFound)
}

validate a values of map

I use fig to initialize a map of structs.
The fields in the struct have a "required" validation tag. However, fig does not enforce this validation.
E.g.

type Config struct {
Elements map[string]Element fig:"chartConfigs" validate:"required"
}

type Element struct {
Name string fig:"name" validate:"required"
}

var cfg Config
fig.Load(&cfg)

Add a strict parsing alternative which disallows unknown fields

It would be nice to have something akin to json.DisallowUnknownFields and yaml.UnmarshalStrict to catch configuration invalid configurations earlier and make them an error.

I propose to add a new flag fig.UseStrict, when set fig.Load will return an error upon encountering unknown (i.e: extra) fields.

For example. given:

---
log_level: debug
host: "0.0.0.0"
type Config struct {
	Host string `fig:"host"`
	LogLevel string `fig:"logLevel"`
}

var cfg Server
fig.Load(&cfg, UseStrict()) // Returns error because the key `log_level` is unknown

Allow for multiple possible file names

Hi,

I would like it, if it would be possible to search for different file names (same as dirs).
ex allow ./config.json ./config.yaml and ./config.toml

Thanks for the nice work.

fig should be more customizable via hooks

fig uses the very powerful mapstructure under the hood just like viper. But unlike viper or uconfig it does not expose some sort of hook/middleware mechanism so that user defined logic can be executed as part of loading config

Introducing such a behavior might break backwards compatibility but it would be worth it in the long run.

Fields of type time.Duration should fail when the input is an integer

The duration parser provided by the standard library fails when it's input doesn't include a time unit. As expected, fig also fails in such a case, but it doesn't when the input is not wrapped in quotes because it's interpreted as an integer and not a string.

For example, given:

// config.yaml
timeout: 1
// main.go
package main

import (
	"fmt"
	"log"
	"time"

	"github.com/kkyr/fig"
)

type Config struct {
	Timeout time.Duration `fig:"timeout" validate:"required"`
}

func main() {
	var cfg Config
	if err := fig.Load(&cfg); err != nil {
		log.Fatal(err)
	}

	fmt.Printf("%+v\n", cfg)
}

I would expect it to fail because timeout: 1 doesn't have a time unit, instead the config is parsed without errors and the set value is 1ns.

Maybe this could be fixed by adding a check of Int (and maybe float?) values in StringToTimeDurationHookFunc, although I may be missing some other cases.

Setting config value to "zero" in file takes default value

I really enjoy fig for my configuration, because it is simpler than other solutions, but I found a problem with it that is more than a nuance.

Imagine you have a config value set like below, and then in the config file you want to set it to 0: log_level: 0

LogLevel    int    `fig:"log_level" default:"1"` // -1:trace 0: debug, 1: info, 2: warn, 3: error, 4: fatal, 5: panic

The default value will be used, I assume because at the point it looks if it is set, it thinks it is not because it is set to the "zero" value of the type

Default bool items not being set correctly when not present in config

Howdy,

According to the documentation:

A default key in the field tag makes fig fill the field with the value specified when the field is not otherwise set.

Given the following config.yaml:

itemone:
  enabled: false

With the following program:

package main

import (
    "fmt"
    "github.com/kkyr/fig"
)

type Config struct {
    ItemOne  ItemOne   `default:{}`
    ItemTwo  ItemTwo   `default:{}`

}

type ItemOne struct {
    Enabled     bool    `fig:"enabled" default:true`
}

type ItemTwo struct {
    Enabled     bool    `fig:"enabled" default:true`
}

func main() {
    var conf Config
    err := fig.Load(&conf)
    if err != nil {
        panic(err)
    }

    fmt.Printf("Config %+v", conf)
}

What was expected:
Field ItemTwo.Enabled would be set to boolean true.

What actually happened:
Field ItemTwo.Enabled is set to boolean false:

Config {ItemOne:{Enabled:false} ItemTwo:{Enabled:false}}

I've slimmed down an existing program to this most basic PoC to rule out other code in my application being a problem, though my usage is perhaps still incorrect.

Feature request: Updating configuration files

It would be nice to have an API to create/update a configuration file, keeping constraints in mind.

The call would be something like:

// do something with the settings' attributes
// ....
// Update the configuration file and check the constraints
fig.Update(&cfg, fig.File("settings.json"), fig.Dir("/app/conf"))

Value from environment

Thank you for the library. It is something I've been planning to write myself. But I'd still hope for one more feature. Especially for projects packaged as docker images. Could you support some sort of environment variable interpolation syntax? Like ${FOOBAR} being read from the environment variable FOOBAR?

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.