83 lines
2.3 KiB
Clojure
83 lines
2.3 KiB
Clojure
(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)
|