(ns beherbergung.config.state "Wrapping yogthos/config with defstate allows overwriting the config at runtime and checking it at startup against a spec" (:require [clojure.spec.alpha :as s] [mount.core :refer [defstate args]] [config.core] [clojure.string])) (s/def ::frontend-base-url string?) (s/def ::frontend-backend-base-url string?) (s/def ::port number?) ;; the webserver port (s/def ::verbose boolean?) (s/def ::validate-output boolean?) ;; should specialist ensure type correctness (s/def ::db-inmemory boolean?) ;; we run unit tests in an in-memory instance, otherwise the default db would be looked (s/def ::db-dir string?) ;; ignored when ::db-inmemory (s/def ::db-seed string?) ;; an edn-file to be used for seeding (s/def ::db-export-prefix (s/nilable string?)) ;; path where during startup an export should be written (s/def ::db-validate boolean?) (s/def ::admin-passphrase (s/nilable string?)) ;; allows setting up ngo logins and encrypted downloads of db exports (s/def ::admin-gpg-id string?) (s/def ::import-file (s/nilable string?)) (s/def ::mail-host string?) (s/def ::mail-user string?) (s/def ::mail-pass string?) (s/def ::mail-port number?) (s/def ::mail-from (s/nilable string?)) (s/def ::env (s/keys :req-un [::frontend-base-url ::frontend-backend-base-url ::port ::verbose ::validate-output ::db-inmemory ::db-dir ::db-seed ::db-export-prefix ::db-validate ::admin-passphrase ::admin-gpg-id ::import-file ;::mail-host ::mail-user ::mail-pass ::mail-port ::mail-from ])) (defn strip-secrets [env] (assoc env :mail-pass "*" :admin-passphrase "*")) (defn filter-defined [keys-spec m] (let [req-un (last (s/form keys-spec)) unnamespaced-keys (map #(-> (clojure.string/replace % (if-let [n (namespace %)] (str n "/") "") "") (clojure.string/replace ":" "") keyword) req-un)] (select-keys m (into [] unnamespaced-keys)))) (defstate env :start (let [env (->> (merge (config.core/load-env) (args)) ;; allows: (mount/start-with-args {…}) (filter-defined ::env)) config-errors (s/explain-data ::env env)] (when (:verbose env) (println (strip-secrets env))) (assert (not config-errors) (with-out-str (s/explain-out config-errors))) env))