Logo

0x3d.Site

is designed for aggregating information.
Welcome
check repository here

nfigure - per-library configuration

GoDoc unit tests report card codecov

Install:

go get github.com/muir/nfigure

Nfigure is a reflective configuration library. It supports:

  • Describing what to configure using struct tags
  • Configuration from: multiple configuration file formats, and multiple files
  • Configuration from: environment variables
  • Configuration from: the command line
  • Posix-style and Go-style command line parsing
  • Support for subcommands when parsing command lines
  • Multi-stage binding to allow independently-developed libraries to express their configruration needs ahead of program startup
  • Custom type support using reflectutils.RegisterStringSetter().
  • Filling all normal Go types, array, slices, maps, and time.Duration
  • Ability to export flag-based configuration requests to the "flag" module (useful for libraries)

While nfigure has lots of flexibility and many features, using it should be simple.

Example: In a library, in-house or published for others to use

It can pre-register configuration at the library level, before program startup. This allows library-specific configuration to be handled at the library-level rather than pushed to a central main.

type myLibraryConfig struct {
	Field1	string	  `env="FIELD1" flag:"field1" default:"f1" help:"Field1 controls the first field"`
	Field2	int	  `config:"mylibrary.field2"` 
	Field3	[]string  `flag:"field3"`
}

type MyLibrary struct {
	config	myLibraryConfig
}

func createMyLibrary(nreg *nfigure.Registry) *MyLibrary {
	lib := MyLibrary{}
	nreg.Request(&lib.config,
		nfigure.Prefix("myLibrary"),
		nfigure.ConfigFileFrom(`env="MYLIBRARY_CONFIG_FILE" flag:"mylibrary-config"`),
	)
	_ = nreg.Configure()
	return &lib
}

Example: At the program level

This is an example using nserve. Where this gets interesting is if multiple binaries are built from the same source, the set of libraires can exist in a list and only the ones that are needed for particular executables will have their configuration evaluated.

type programLevelConfig struct {
	Field1	string `env="field1" default:"F1"`
	Field4	float64	`flag:"field4" default:"3.9"`
}

func createMyApp(myLibrary *mylibrary.MyLibrary, nreg *nfigure.Registery) error {
	// start servers, do not return until time to shut down
	var config programLevelConfig
	nreg.Request(&config, "main")
	_ = nreg.Configure()
}

func main() {
	app, _ := nserve.CreateApp("myApp", 
		nfigure.NewRegistryFactory(),
		createMyLibrary, 
		createMyApp)
	_ = app.Do(nserve.Start)
	_ = app.Do(nserve.Stop)
}

Supported tags

Assuming a command line parser was bound, the follwing tags are supported:

  • nfigure: the meta tag, used to control filler interactions
  • default: a filler that provides a literal value
  • env: fill values from environment variables
  • config: fill values from configuration files
  • flag: fill values from the command line (Go style or Posix style)
  • help: per-item help text for command line Usage

Environment variables

Usage:

  • env:"VARNAME" specifies that a value can or should be loaded from an environment variable

Command line parsing

Both Go-style and Posix-style command line parsing is supported. In addition to the base features, counters are supported. Filling maps, arrays, and slices is supported.

  • flag:"name" specifies the name of the command line flag to fill a value.
  • flag:"name n" specifies a single letter alternative
  • flag:"name,split=comma for array values, specifies that strings will be split on comma, flag can only be given once
  • flag:"name,explode=true for array values, specifies that the flag can be given multiple times and is not split
  • flag:"name,counter for numberic values, counts the number of times the flag is used, flag cannot take argument
  • flag:"name,map=explode,split=equal for maps, support -name a=b -name b=c
  • flag:"name,map=prefix for maps, support --namex=a --nameb=c

Posix-style

When using Posix-style flags (PosixFlagHandler()), flags whose names are only a single rune can be combined on the command line:

--debug 
-d
--verbose
-v
-dv (debug and verbose)

For boolean values, negation is "--no-":

--no-verbose

Best Practices

Best Practices for existing libraries

Libraries that are already published and using the standard "flag" package can be refactored to use nfigure. If they register themselves with flag during init, then that behavior should be retained:

package mylibrary 

import (
	"flag"
	"github.com/muir/nfigure"
)

type MyConfig struct {
	MyField string `flag:"myfield"`
}
var myConfig MyConfig

sub init() {
	err := nfigure.ExportToFlagSet(flag.CommandLine, "flag", &myConfig)
	if err != nil {
		panic(err.Error())
	}
}

In a program that is using nfigure, MyConfig can be explicitly imported:

registery.Request(&mylibrary.MyConfig)

However, if there are other libraries that only support "flag" and they're being imported:

GoFlagHandler(nfigure.ImportFlagSet(flag.CommandLine))

Then MyConfig should not also be explicity imported since that would end up with the flags being defined twice.

Best practices for new libraries

New libraries should use nfigure to handle their configruation needs. The suggested way to do this is to have a New function that takes a registry as arguments.

Separate New() and Start() so that configuation can happen after New() but before Start().

Users of your library can use NewWithRegistry() if they're using nfigure. For other users, they can fill MyConfig by hand or use "flag" to populate the configuration

Library writer boilerplate

import "github.com/muir/nfigure"

func NewWithRegistry(registry *nfigure.Registry) MySelf {
	var config Config
	registry.Request(&config)
	...
}

func NewWithConfig(config *Config) MySelf {
	...
}

func (m MySelf) Start() {
	...
}

Library user not using nfigure boilerplate:

import (
	"flag"
	"library"
	"github.com/muir/nfigure"
)

func main() {
	var libConfig library.Config
	nfigure.MustExportToFlagSet(flag.CommandLine, "flag", &libConfig)
	lib := library.NewWithConfig(libConfig) // config is not used yet
	flag.Parse()
	lib.Start() // call to Start must be after config is filled in
}

Library user using nfigure boilerplate:

import (
	"flag"
	"library"
	"github.com/muir/nfigure"
)

func main() {
	registry := nfigure.NewRegistry(WithFiller("flag", GoFlagHandler()))
	lib := registry.NewWithRegistry(registry)
	registry.Configure()
	lib.Start()
}

Best practices for program writers

Use nfigure everywhere! Be careful not to combine ImportFlagSet with registry.Request() of the same models that are ExportToFlagSet()ed in library inits.

Separate library creation from library starting. Allow configuration to be deferred until until library start.

Golang
Golang
Golang, or Go, is a statically typed programming language developed by Google. It’s known for its simplicity, performance, and support for concurrent programming. Go is widely used in cloud computing, server-side applications, and microservices.
GitHub - goyek/goyek: Task automation Go library
GitHub - goyek/goyek: Task automation Go library
gommon/color at master · labstack/gommon
gommon/color at master · labstack/gommon
GitHub - blevesearch/bleve: A modern text/numeric/geo-spatial/vector indexing library for go
GitHub - blevesearch/bleve: A modern text/numeric/geo-spatial/vector indexing library for go
GitHub - schollz/progressbar: A really basic thread-safe progress bar for Golang applications
GitHub - schollz/progressbar: A really basic thread-safe progress bar for Golang applications
GitHub - free/concurrent-writer: Highly concurrent drop-in replacement for bufio.Writer
GitHub - free/concurrent-writer: Highly concurrent drop-in replacement for bufio.Writer
GitHub - mattn/go-colorable
GitHub - mattn/go-colorable
GitHub - StudioSol/set: A simple Set data structure implementation in Go (Golang) using LinkedHashMap.
GitHub - StudioSol/set: A simple Set data structure implementation in Go (Golang) using LinkedHashMap.
GitHub - essentialkaos/branca: Authenticated encrypted API tokens (IETF XChaCha20-Poly1305 AEAD) for Golang
GitHub - essentialkaos/branca: Authenticated encrypted API tokens (IETF XChaCha20-Poly1305 AEAD) for Golang
Cloud Native Computing Foundation
Cloud Native Computing Foundation
GitHub - sakirsensoy/genv: Genv is a library for Go (golang) that makes it easy to read and use environment variables in your projects. It also allows environment variables to be loaded from the .env file.
GitHub - sakirsensoy/genv: Genv is a library for Go (golang) that makes it easy to read and use environment variables in your projects. It also allows environment variables to be loaded from the .env file.
GitHub - heetch/confita: Load configuration in cascade from multiple backends into a struct
GitHub - heetch/confita: Load configuration in cascade from multiple backends into a struct
GitHub - brianvoe/sjwt: Simple JWT Golang
GitHub - brianvoe/sjwt: Simple JWT Golang
GitHub - subpop/go-ini: Go package that encodes and decodes INI-files
GitHub - subpop/go-ini: Go package that encodes and decodes INI-files
GitHub - DylanMeeus/GoAudio: Go tools for audio processing & creation 🎶
GitHub - DylanMeeus/GoAudio: Go tools for audio processing & creation 🎶
GitHub - daviddengcn/go-colortext: Change the color of console text.
GitHub - daviddengcn/go-colortext: Change the color of console text.
GitHub - andOTP/andOTP: [Unmaintained] Open source two-factor authentication for Android
GitHub - andOTP/andOTP: [Unmaintained] Open source two-factor authentication for Android
GitHub - alfiankan/crab-config-files-templating: Dynamic configuration file templating tool for kubernetes manifest or general configuration files
GitHub - alfiankan/crab-config-files-templating: Dynamic configuration file templating tool for kubernetes manifest or general configuration files
GitHub - viney-shih/go-cache: A flexible multi-layer Go caching library to deal with in-memory and shared cache by adopting Cache-Aside pattern.
GitHub - viney-shih/go-cache: A flexible multi-layer Go caching library to deal with in-memory and shared cache by adopting Cache-Aside pattern.
GitHub - TreyBastian/colourize: An ANSI colour terminal package for Go
GitHub - TreyBastian/colourize: An ANSI colour terminal package for Go
GitHub - Evertras/bubble-table: A customizable, interactive table component for the Bubble Tea framework
GitHub - Evertras/bubble-table: A customizable, interactive table component for the Bubble Tea framework
GitHub - deatil/go-array: A Go package that read or set data from map, slice or json
GitHub - deatil/go-array: A Go package that read or set data from map, slice or json
GitHub - cometbft/cometbft: CometBFT (fork of Tendermint Core): A distributed, Byzantine fault-tolerant, deterministic state machine replication engine
GitHub - cometbft/cometbft: CometBFT (fork of Tendermint Core): A distributed, Byzantine fault-tolerant, deterministic state machine replication engine
GitHub - icza/session: Go session management for web servers (including support for Google App Engine - GAE).
GitHub - icza/session: Go session management for web servers (including support for Google App Engine - GAE).
GitHub - cristalhq/jwt: Safe, simple and fast JSON Web Tokens for Go
GitHub - cristalhq/jwt: Safe, simple and fast JSON Web Tokens for Go
GitHub - lrita/cmap: a thread-safe concurrent map for go
GitHub - lrita/cmap: a thread-safe concurrent map for go
GitHub - wzshiming/ctc: Console Text Colors - The non-invasive cross-platform terminal color library does not need to modify the Print method
GitHub - wzshiming/ctc: Console Text Colors - The non-invasive cross-platform terminal color library does not need to modify the Print method
GitHub - goradd/maps: map library using Go generics that offers a standard interface, go routine synchronization, and sorting
GitHub - goradd/maps: map library using Go generics that offers a standard interface, go routine synchronization, and sorting
GitHub - alfiankan/teleterm: Telegram Bot Exec Terminal Command
GitHub - alfiankan/teleterm: Telegram Bot Exec Terminal Command
GitHub - JeremyLoy/config: 12 factor configuration as a typesafe struct in as little as two function calls
GitHub - JeremyLoy/config: 12 factor configuration as a typesafe struct in as little as two function calls
GitHub - goraz/onion: Layer based configuration for golang
GitHub - goraz/onion: Layer based configuration for golang
Golang
More on Golang

Programming Tips & Tricks

Code smarter, not harder—insider tips and tricks for developers.

Error Solutions

Turn frustration into progress—fix errors faster than ever.

Shortcuts

The art of speed—shortcuts to supercharge your workflow.
  1. Collections 😎
  2. Frequently Asked Question's 🤯

Tools

available to use.

Made with ❤️

to provide resources in various ares.