@@ -0,0 +1,82 @@
|
||||
(ns net.deertopia.doerg.config
|
||||
(:require [clojure.spec.alpha :as s]
|
||||
[babashka.fs :as fs]
|
||||
[aero.core :as aero]
|
||||
[clojure.java.io :as io]))
|
||||
|
||||
(s/def ::config
|
||||
(s/keys :req [::ibm-plex-web
|
||||
::latex
|
||||
::dvisvgm
|
||||
::doerg-temml-worker
|
||||
::doerg-parser
|
||||
::state-directory
|
||||
::org-roam-db-path]))
|
||||
|
||||
(s/def ::directory
|
||||
(s/conformer #(fs/file %)))
|
||||
|
||||
(s/def ::file
|
||||
(s/conformer #(-> % fs/expand-home fs/file)))
|
||||
|
||||
(s/def ::executable
|
||||
(s/conformer
|
||||
;; I'd love to use `fs/which` here, but it's fairly problematic to
|
||||
;; check `fs/executable?` at… build time (which `fs/which` does)?
|
||||
;; Wait… what? Do I know how Clojure compilation works?
|
||||
#(or #_(some-> % fs/expand-home fs/which fs/file)
|
||||
(some-> % fs/expand-home fs/file)
|
||||
::s/invalid)))
|
||||
|
||||
(s/def ::ibm-plex-web ::directory)
|
||||
|
||||
(s/def ::latex ::executable)
|
||||
|
||||
(s/def ::dvisvgm ::executable)
|
||||
|
||||
(s/def ::doerg-temml-worker ::executable)
|
||||
|
||||
(s/def ::doerg-parser ::executable)
|
||||
|
||||
(s/def ::state-directory ::file)
|
||||
(s/def ::org-roam-db-path ::file)
|
||||
|
||||
(defmethod aero/reader 'xdg-data-dir
|
||||
[_opts tag value]
|
||||
"Aero tag to search for a directory on $XDG_DATA_DIRS."
|
||||
(some #(let [x (fs/path % value)]
|
||||
(and (fs/exists? x) x))
|
||||
(fs/split-paths (System/getenv "XDG_DATA_DIRS"))))
|
||||
|
||||
(defmethod aero/reader 'file
|
||||
[{:keys [source]} tag value]
|
||||
"Aero tag to reference a `java.io.File` relative to the config
|
||||
file."
|
||||
(-> (aero/relative-resolver source value)
|
||||
fs/file))
|
||||
|
||||
(defn read-config [files & {:as opts}]
|
||||
(let [r (->> files
|
||||
(filter identity)
|
||||
(map #(aero/read-config % opts))
|
||||
(apply merge))
|
||||
conformed (s/conform ::config r)]
|
||||
(if-not (s/invalid? conformed)
|
||||
conformed
|
||||
(throw (ex-info "Failed to conform config"
|
||||
(s/explain-data ::config r))))))
|
||||
|
||||
(defn load-config! [var spec files & {:as opts}]
|
||||
(alter-var-root var (constantly (read-config files opts))))
|
||||
|
||||
(def sources
|
||||
[;; Default config.
|
||||
(io/resource "net/deertopia/doerg/default-config.edn")
|
||||
;; Defaults set at build time, if any.
|
||||
(io/resource "net/deertopia/doerg/extra-config.edn")
|
||||
;; Config set at runtime.
|
||||
(System/getenv "DOERG_CONFIG")])
|
||||
|
||||
(def default (read-config sources))
|
||||
|
||||
(def ^:dynamic *cfg* default)
|
||||
Reference in New Issue
Block a user