A Babashka library for handling configuration from multiple sources with a unified interface.
- Configuration management from multiple sources:
- Command-line arguments (using docopt)
- YAML configuration files
- Environment variables
- Default values
- Automatic configuration merging with precedence
- Simple and declarative configuration setup
Add to your deps.edn
or bb.edn
:
{:deps {200ok-ch/shell-smith {:git/url "https://github.com/200ok-ch/shell-smith"
:sha "current-sha"}}}
(ns my-app.core
(:require [shell-smith.core :as smith]))
(def usage "
Usage:
app [--port <port>]
app (-h | --help)
Options:
-h --help Show this screen
--port <port> Port number [default: 3000]
")
(def config
(smith/config usage
:name "myapp"))
- Command line arguments
- Environment variables (prefixed with uppercase app name)
- YAML configuration files
- locally:
myapp.yml
- oldschool:
~/.myapp.yml
- newschool:
${XDG_CONFIG_HOME}/myapp/config.yml
- locally:
- Defaults provided by usage string
- Defaults provided by call to
shell-smith.core/config
Create a myapp.yml
in your working directory:
---
port: 8080
Environment variables should be prefixed with the uppercase app name:
MYAPP_PORT=9000
Important: When writing docopt usage strings for shell-smith, avoid using docopt’s standard syntax for defaults. If you use docopt’s default syntax, those defaults will override values from your configuration file(s), which is typically not the desired behavior.
Instead of using docopt’s square bracket syntax for defaults, follow these steps:
- Document defaults informatively: Replace docopt’s square brackets [] with regular parentheses () to show default values in a purely informational manner
- Provide defaults programmatically: Pass your defaults as a separate map to the config function:
(shell-smith.core/config usage :defaults your-defaults-map)
This approach allows shell-smith to properly merge configuration values in the correct precedence order.
tbd.