This is a handy bit of code I've written more than once. I thought I'd throw it in here so I can refer back to it later. Basically, it lets you read a config file to produce a Clojure map. The config files themselves can contain one or more forms, each of which can be either a map or a list. Maps are simply merged. Lists correspond to invocations of extension points, which in turn produces a map, which is merged along with everything else.
Consider the following files:
names.edn
{:first-name "Craig"
:middle-name "Bert"}
;; Comments are ignored - cool!
{:last-name "Andera"
:middle-name "Alan"} ; Later entries override earlier ones
addresses.edn
{:real-world {:city "Fairfax" :state "VA"}
:email "craig@craigandera.org"}
craig.edn
(include "names.edn")
(include "addresses.edn")
{:favorites {:colors [:red :black]}}
Calling (read-config "/path/to/craig.edn")
would produce the following map:
{:first-name "Craig"
:last-name "Andera"
:middle-name "Alan"}
:real-world {:city "Fairfax" :state "VA"}
:email "craig@craigandera.org"
:favorites {:colors [:red :black]}}
Note that you can use relative or absolute pathnames in the (include ...
calls, and they'll be resolved relative to the file they appear in