|
@@ -69,7 +69,7 @@
|
69
|
69
|
See `defenv.tfn-spec` for examples."
|
70
|
70
|
([s] (parse-map {} s))
|
71
|
71
|
([{:keys [default-key key-fn] :or {default-key "default"
|
72
|
|
- key-fn identity}} s]
|
|
72
|
+ key-fn identity}} s]
|
73
|
73
|
(if (re-find #"=" s)
|
74
|
74
|
(let [kvs (str/split s #",")]
|
75
|
75
|
(reduce (fn [m s]
|
|
@@ -84,12 +84,12 @@
|
84
|
84
|
;; ## On-the-fly documentation
|
85
|
85
|
|
86
|
86
|
;; ### Generation
|
87
|
|
-(def ^:private displays {::missing "*REQUIRED*"
|
88
|
|
- ::masked "--MASKED--"
|
|
87
|
+(def ^:private displays {::missing "*REQUIRED*"
|
|
88
|
+ ::masked "--MASKED--"
|
89
|
89
|
::parse-error "*PARSE ERROR*"})
|
90
|
90
|
|
91
|
91
|
(defn- get-var-status [{:keys [env-name v default masked? optional?]
|
92
|
|
- :as doc-map}]
|
|
92
|
+ :as doc-map}]
|
93
|
93
|
(let [e-val (env env-name default)]
|
94
|
94
|
(-> doc-map
|
95
|
95
|
(assoc :value
|
|
@@ -179,13 +179,13 @@
|
179
|
179
|
(let [has-param? (partial contains? params)
|
180
|
180
|
env-args [env-name]
|
181
|
181
|
base-value (env env-name default)]
|
182
|
|
- {:tfn (if (and (not (nil? base-value))
|
183
|
|
- (has-param? :tfn)) tfn
|
184
|
|
- identity)
|
185
|
|
- :env-args (if (or optional? (has-param? :default))
|
186
|
|
- (conj env-args default) env-args)
|
|
182
|
+ {:tfn (if (and (not (nil? base-value))
|
|
183
|
+ (has-param? :tfn)) tfn
|
|
184
|
+ identity)
|
|
185
|
+ :env-args (if (or optional? (has-param? :default))
|
|
186
|
+ (conj env-args default) env-args)
|
187
|
187
|
:params-to-display (assoc params :env-name env-name)
|
188
|
|
- :base-value base-value}))
|
|
188
|
+ :base-value base-value}))
|
189
|
189
|
|
190
|
190
|
(defn- pretty-demunge
|
191
|
191
|
[fn-object]
|
|
@@ -203,8 +203,11 @@
|
203
|
203
|
(if masked? "--ERROR MASKED--" (.getMessage e))))
|
204
|
204
|
::parse-error)))
|
205
|
205
|
|
206
|
|
-(defn- overlay-env [m k {:keys [optional? masked? env-name env] :as params}]
|
207
|
|
- (let [env-name (or env-name env)
|
|
206
|
+(defn- overlay-env [m k raw-params]
|
|
207
|
+ (let [{:keys [optional? masked? env-name env] :as params}
|
|
208
|
+ (merge {:masked? true} raw-params)
|
|
209
|
+
|
|
210
|
+ env-name (or env-name env)
|
208
|
211
|
{:keys [tfn params-to-display base-value]} (parse-env env-name params)
|
209
|
212
|
v (try-tfn env-name masked? tfn base-value)]
|
210
|
213
|
(-> m
|
|
@@ -265,8 +268,8 @@ by `defenv `that is required but missing."
|
265
|
268
|
(when (empty? @global-parsed-env)
|
266
|
269
|
(let [{:keys [env-map display-spec]} (get-env-info @global-defined-spec)]
|
267
|
270
|
(dosync
|
268
|
|
- (ref-set global-parsed-env env-map)
|
269
|
|
- (ref-set global-display-spec display-spec))
|
|
271
|
+ (ref-set global-parsed-env env-map)
|
|
272
|
+ (ref-set global-display-spec display-spec))
|
270
|
273
|
(doall (map #(% @global-display-spec) @on-load-handlers)))))
|
271
|
274
|
|
272
|
275
|
(defn on-load! [f] (swap! on-load-handlers conj f))
|
|
@@ -281,9 +284,9 @@ by `defenv `that is required but missing."
|
281
|
284
|
"Used primarily by `defenv` to retrieve the global environment state. "
|
282
|
285
|
[env-name]
|
283
|
286
|
(guarantee-global!
|
284
|
|
- (if ((set (keys @global-parsed-env)) env-name)
|
285
|
|
- (get @global-parsed-env env-name)
|
286
|
|
- (throw-usage-if-missing @global-display-spec))))
|
|
287
|
+ (if ((set (keys @global-parsed-env)) env-name)
|
|
288
|
+ (get @global-parsed-env env-name)
|
|
289
|
+ (throw-usage-if-missing @global-display-spec))))
|
287
|
290
|
|
288
|
291
|
(defn add-to-global-defined-spec!
|
289
|
292
|
"Used primarily by `defenv` to add to the global environment state. "
|
|
@@ -325,8 +328,8 @@ missing."
|
325
|
328
|
remaining
|
326
|
329
|
(when env-or-fk (concat [env-or-fk] remaining)))
|
327
|
330
|
(apply hash-map)
|
328
|
|
- (add-doc doc-present? doc-or-env))
|
329
|
|
- params (assoc params :env-name env-name)]
|
|
331
|
+ (add-doc doc-present? doc-or-env)
|
|
332
|
+ (merge {:env-name env-name}))]
|
330
|
333
|
`(do (add-to-global-defined-spec! ~env-name ~params)
|
331
|
334
|
(def ~(vary-meta b assoc :dynamic true)
|
332
|
335
|
(delay (get-global-env ~env-name))))))
|
|
@@ -348,28 +351,28 @@ missing."
|
348
|
351
|
|
349
|
352
|
;; A recipe for doing your own display of environment information
|
350
|
353
|
(comment
|
351
|
|
- (let [test-spec {:stuff {:env-name "STUFF" :default "bits" :doc "fun"}
|
352
|
|
-
|
353
|
|
- :answer
|
354
|
|
- {:env-name "ANSWER"
|
355
|
|
- :default "42"
|
356
|
|
- :tfn parse-int
|
357
|
|
- :doc "ultimate"}
|
358
|
|
-
|
359
|
|
- :path {:env-name "PATH"
|
360
|
|
- :tfn (fn [v] (str/split v #"[:;]"))
|
361
|
|
- :masked? true
|
362
|
|
- :doc "System path!"}}]
|
363
|
|
-
|
364
|
|
- (println "\nInternal use:")
|
365
|
|
- (->> test-spec env->map clojure.pprint/pprint)
|
366
|
|
- (println "\nExternal view:")
|
367
|
|
- (-> test-spec
|
368
|
|
- display-spec
|
369
|
|
- display-spec->docs
|
370
|
|
- doc-table
|
371
|
|
- println))
|
372
|
|
- )
|
|
354
|
+ (let [test-spec {:stuff {:env-name "STUFF" :default "bits" :doc "fun"}
|
|
355
|
+
|
|
356
|
+ :answer
|
|
357
|
+ {:env-name "ANSWER"
|
|
358
|
+ :default "42"
|
|
359
|
+ :tfn parse-int
|
|
360
|
+ :doc "ultimate"}
|
|
361
|
+
|
|
362
|
+ :path {:env-name "PATH"
|
|
363
|
+ :tfn (fn [v] (str/split v #"[:;]"))
|
|
364
|
+ :masked? true
|
|
365
|
+ :doc "System path!"}}]
|
|
366
|
+
|
|
367
|
+ (println "\nInternal use:")
|
|
368
|
+ (->> test-spec env->map clojure.pprint/pprint)
|
|
369
|
+ (println "\nExternal view:")
|
|
370
|
+ (-> test-spec
|
|
371
|
+ display-spec
|
|
372
|
+ display-spec->docs
|
|
373
|
+ doc-table
|
|
374
|
+ println))
|
|
375
|
+ )
|
373
|
376
|
|
374
|
377
|
(defn display-env
|
375
|
378
|
"Display the current environment to users in a friendly manner. If you call
|
|
@@ -399,5 +402,5 @@ missing."
|
399
|
402
|
(defn reset-defined-env!
|
400
|
403
|
[]
|
401
|
404
|
(with-new-parsed-env!
|
402
|
|
- (alter global-display-spec empty)
|
403
|
|
- (alter global-defined-spec empty)))
|
|
405
|
+ (alter global-display-spec empty)
|
|
406
|
+ (alter global-defined-spec empty)))
|