Skip to content

Instantly share code, notes, and snippets.

@crimeminister
Created May 2, 2017 19:14
Show Gist options
  • Save crimeminister/e9ac993cb9d0ba65f6a113351421b4cc to your computer and use it in GitHub Desktop.
Save crimeminister/e9ac993cb9d0ba65f6a113351421b4cc to your computer and use it in GitHub Desktop.
Load config using cprop and merge with configuration taken from CLI
;; This is the snippet of code I use to merge CLI options with config loaded using cprop.
;; Do you have any interest in a PR that adds a (from-cli) function to cprop.sources, or
;; is that a non-goal?
;; To override the default values stored in the config.edn
;; configuration file using environment variables, note that double
;; underscore ("__") is used to represent nesting, e.g. FOO__BAR is
;; merged into the combined config map as {:foo {:bar …}}. To override
;; configuration values from the command line double hyphen ("--") is
;; used to representing nesting instead, e.g. --foo--bar is merged
;; into the config map as {:foo {:bar …}}.
(defn hyphenated-kw->nested-map
"Turn a map entry into a map where double hyphens are used to denote
nesting in the result. The namespace of the key is preserved.
E.g. :foo => {:foo …}
:foo-bar => {:foo-bar …}
:foo--bar => {:foo {:bar …}}
:xxx/foo--bar => #:xxx{:foo #:xxx{:bar …}}"
[[kw value]]
{:pre [(keyword? kw)]}
(let [kw-ns (namespace kw)
kw-name (name kw)
kw-parts (string/split kw-name #"--")
kw-path (mapv #(keyword kw-ns %) kw-parts)]
(assoc-in {} kw-path value)))
(defn make-nested-options
""
[options]
(into {} (map hyphenated-kw->nested-map options)))
(defn load-config
"Load configuration from all available sources. Takes the argument
seqence given on the command line and the CLI parser configuration."
[cli-args cli-opts]
{:pre [(or (nil? cli-args) (seq? cli-args))]}
(let [{:keys [options]} (cli/parse-opts cli-args cli-opts)
;; Replace keys having 2 hyphens by nested maps.
nested-options (make-nested-options options)
config (cprop/load-config :merge [(cprops/from-system-props)
(cprops/from-resource "config.edn")
(cprops/from-env)
nested-options])]
config))
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment