conf

package module
v0.0.7 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Mar 22, 2024 License: MIT Imports: 10 Imported by: 2

README

conf - a configuration parsing lib for Go

Description: A Go library for parsing environment variables (and any other source) and setting corresponding flags. It is heavily inspired by Go's std flag package in its design.

Why

Why another package for parsing the environment? Currently, most popular environment parsing libraries depend on struct tags to map the environment to a structure and provide options like flag requirement or default values when absent.

With conf and the use of Go Generics, we can now have a type-safe API that doesn't depend on struct tags and can take advantage of strong typing.

Let's contrast davidmdm/conf with a popular environment parsing library github.com/kelseyhightower/envconfig:

The envconfig approach is convenient but very sensitive to typos, and the defaults need to be encoded in their string format, which can be error-prone.

package main

import (
    "time"
    "github.com/kelseyhightower/envconfig"
)

type Config struct {
    DatabaseURL string        `envconfig:"DATABASE_URL" required:"true"`
    Timeout     time.Duration `envconfig:"TIMEMOUT" default:"5m"`
}

func main() {
    var cfg Config
    envconfig.Process("", &cfg)
}

On the other hand, davidmdm/conf does not suffer from these problems. It also has the added benefit of being programmatic instead of static. If we need, environment variable names and options could be determined at runtime instead of statically typed into a struct definition.

package main

import (
    "time"
    "github.com/davidmdm/conf"
)

type Config struct {
    DatabaseURL string
    Timeout     time.Duration
}

func main() {
    var cfg Config
    conf.Var(conf.Environ, &cfg.DatabaseURL, "DATABASE_URL", conf.Required[string](true))
    conf.Var(conf.Environ, &cfg.Timeout, "TIMEOUT", conf.Default[time.Duration](5 * time.Minute))

    conf.Environ.MustParse()
}

Overview

This Go package provides a flexible and extensible configuration parser that allows you to easily manage configuration settings in your Go applications. The parser supports environment variables, command line arguments, and file system-based configuration, making it adaptable to various deployment scenarios.

Installation

go get -u github.com/davidmdm/conf

Features

Environment Variables: Retrieve configuration values from environment variables with the ability to set default values and mark certain configurations as required.

Command Line Arguments: Easily map command line flags to configuration variables, supporting case-insensitivity and automatic conversion of underscores to dashes.

File System Configuration: Load configuration settings from files in the file system, providing a convenient way to manage configuration files.

Multiple Sources: Combine any of the above sources or your own custom functions to lookup strings.

Usage

Creating a Parser

To get started, create a configuration parser using the MakeParser function:

import "github.com/davidmdm/conf"

// Create a configuration parser with optional lookup functions. By default if no lookup funcs are provided
// the parser will use os.Lookupenv
parser := conf.MakeParser()

You can provide one or more lookup functions to the MakeParser function, which will be used to retrieve configuration values.

Define your configuration variables using the Var function:

var (
    yourStringVar string
    yourIntVar    int
)

conf.Var(parser, &yourStringVar, "YOUR_STRING_VAR", conf.Options[string]{Required: true})
conf.Var(parser, &yourIntVar, "YOUR_INT_VAR", conf.Options[int]{Required: false, DefaultValue: 42})

// In this example, YOUR_STRING_VAR is a required string variable, and YOUR_INT_VAR is an optional integer variable with a default value of 42.
Parsing Configuration

Parse the configuration using the Parse or MustParse methods:

if err := parser.Parse(); err != nil {
// Handle configuration parsing errors
}

// Alternatively, use MustParse to panic on errors
parser.MustParse()

Configuring Lookup Functions

Environment Variables

The package provides a default parser for environment variables conf.Environ. You can create one yourself:

environ := conf.MakeParser(os.Lookupenv)
Command Line Arguments

Create a lookup function for command line arguments:


var (
    path string
    max  int
)

args := conf.MakeParser(conf.CommandLineArgs())

conf.Var(args, "path", &path)
conf.Var(args, "max", &max)

args.MustParse()
File System Configuration

Create a lookup function for file system-based configuration:

var (
    secret string
)

fs := conf.MakeParser(conf.FileSystem(conf.FileSystemOptions{Base: "/path/to/config/files"}))
conf.Var(fs, "secret.txt", &secret)

fs.MustParse()
User provided lookups

When creating a parser any number of lookup functions can be provided. For example you could read key/value pairs from maps, from a redis instance or any other key/value store.

Let's implement a Redis integration that isn't provided by conf:


var redisURL string
conf.Var(conf.Environ, "REDIS_URL", &redisURL, config.Required[string](true))

config.Environ.MustParse()

// Skipping error handling for example's sake
opt, _ := redis.ParseURL(redisURL)

client := redis.NewClient(opt)

rdb := conf.MakeParser(func(key string) (string, bool) {
    value, err := rdb.Get(ctx, key)
    if err != nil {
        if err == redis.Nil {
            return "", false
        }
        panic(err) // panics in lookup functions are recovered during parsing and presented as normal errors from Parse().
    }
    return value, true
})

conf.Var(rdb, ...)

rdb.MustParse()
Multi Source Lookups

You can pass more than one lookup function when creating a parser. It will look search each source in turn and attempt to use the first value it finds.

// First Lookup command line args, then fallback to os.Lookupenv
sources := conf.MakeParser(conf.CommandLineArgs(), os.Lookupenv)

var max int

// Note that commandline args automatically lower-cases and converts underscores to dashes before performing a lookup. This allows it to play nicely os.Lookupenv and allow you to override environment variables via command line args.
conf.Var(sources, &max, "MAX") // Can be configured via --max flag or MAX environment variable
sources.MustParse()

License

This project is licensed under the MIT License - see the LICENSE file for details

Documentation

Index

Constants

This section is empty.

Variables

Functions

func Var

func Var[T any](parser Parser, p *T, name string, opts ...Option[T])

Types

type FileSystemOptions

type FileSystemOptions struct {
	Base string
}

type LookupFunc

type LookupFunc func(string) (string, bool)

func CommandLineArgs

func CommandLineArgs(args ...string) LookupFunc

CommandLineArgs returns a lookup function that will search the provided args for flags. Since we often want our EnvironmentVariable name declarations to be reusable for command line args the lookup is case-insensitive and all underscores are changes to dashes. For example, a variable mapped to DATABASE_URL can be found using the --database-url flag when working with CommandLineArgs.

func FileSystem

func FileSystem(opts FileSystemOptions) LookupFunc

type Option added in v0.0.2

type Option[T any] func(*options)

func Default added in v0.0.2

func Default[T any](value T) Option[T]

func NonEmpty added in v0.0.5

func NonEmpty[T any](value bool) Option[T]

func Required added in v0.0.2

func Required[T any](value bool) Option[T]

func SkipEmpty added in v0.0.7

func SkipEmpty[T any](value bool) Option[T]

type Parser

type Parser struct {
	// contains filtered or unexported fields
}

func MakeParser

func MakeParser(funcs ...LookupFunc) Parser

func (Parser) MustParse

func (parser Parser) MustParse()

MustParse is like Parse but panics if an error occurs

func (Parser) Parse

func (parser Parser) Parse() error

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL