Use config files in conjunction with claptrap

heads

tip
browse log

clone

read-only
https://hg.sr.ht/~ser/clapconf
read/write
ssh://hg@hg.sr.ht/~ser/clapconf

#Clapconf

logo

clapconf is a utility library (an extension) to claptrap to get (and store) parameters in configuration files.

The project home is here. For help, join #claptrap-lib:matrix.org with a (Matrix client).

Build statusAPI DocumentationGo Report Card

Please file issues in the claptrap todo, and post patches and questions to the claptrap list; please also include #clapconf somewhere in your subjects.

#About

Clapconf will load configuration files from:

  • /etc/<progname>
  • then a file in XDG_CONFIG_HOME, $XDG_CONFIG_HOME/<progname>/config
  • then A supplied path to a file

It will save a configuration to:

  • A supplied path to a file, or
  • A file in XDG_CONFIG_HOME, $XDG_CONFIG_HOME/<progname>/config

Clapconf will never override command-line arguments. Config files are TOML. LoadConfig() is idempotent.

Why? You are using claptrap, and want to easily add config file support.

#Dependencies

Unlike claptrap, clapconf does have dependencies. The TOML de/serialization, in particular, is a non-trivial issue. clapconf is little more than a link between claptrap and a TOML library (with a little magic for finding config files in common places). TOML was chosen because it's a human oriented format with a defined standard and wide usage and. JSON is machine-oriented, and YAML is prone to breakage due to depending on invisible, interchangeable, characters for syntax.

stretchr's testify is used, although that won't affect your binary size.

#Usage

  1. Add ser1.net/clapconf to your imports
  2. Set up your claptrap interface
  3. Call clapconf.LoadConfig("") (or clapconf.Load(), a utility function)
  4. Parse your command line

Steps 3 and 4 are interchangeable.

package main
import "ser1.net/claptrap/v4"
import "ser1.net/clapconf"
func main() {
	myprog := claptrap.Command("myprog", "blah blah blah")
	myprog.Add("--flag", "a bool")
	myprog.Add("--int", "-i", 0, "an int")
	myprog.Add("named", "a positional argument")
  myprog.Parse(nil)        // Parse from os.Args
  clapconf.LoadConfig("")  // Start looking in XDG_CONFIG_HOME
  // The rest of your program here
}

As above, you may call clapconf.LoadConfig() after parsing. This way, you could (e.g.) get the config file name from your user through arguments. clapconf will not overwrite the user's command-line arguments.

As stated, LoadConfig() is idempotent: it can be called any number of times.

#Under the hood

LoadConfig() is overriding the default values, so it's equivalent to changing the defaults specified in the command to defaults provided by user configs.

#Bugs and limitations

Mandatory flags are always required from the user. Whether you consider this a bug or not depends heavily on how you interpret "required." Since clapconf functions by changing the defaults, mandatory args are left unset.

clapconf can not set multiple values from the config file, because claptrap does not support multi-value default values. This is a real issue that will probably require an API change in claptrap to fix.