Browse Source

Updated docs

Stephen Starkey 1 year ago
parent
commit
5cb745023e
1 changed files with 135 additions and 118 deletions
  1. 135
    118
      docs/index.html

+ 135
- 118
docs/index.html View File

@@ -2865,8 +2865,111 @@ net.brehaut.ClojureTools = (function (SH) {
2865 2865
     build_tree: build_tree
2866 2866
   };
2867 2867
 })(SyntaxHighlighter);
2868
-</script><title>coreagile/defenv -- Marginalia</title></head><body><table><tr><td class="docs"><div class="header"><h1 class="project-name"><a href="https://defenv.calmabiding.me/">coreagile/defenv</a></h1><h2 class="project-version">1.0.3</h2><br /><p>A simple library for managing environment variables in Clojure</p>
2869
-</div><div class="dependencies"><h3>dependencies</h3><table><tr><td class="dep-name">org.clojure/clojure</td><td class="dotted"><hr /></td><td class="dep-version">1.9.0</td></tr><tr><td class="dep-name">slingshot</td><td class="dotted"><hr /></td><td class="dep-version">0.12.2</td></tr></table></div></td><td class="codes" style="text-align: center; vertical-align: middle;color: #666;padding-right:20px"><br /><br /><br />(this space intentionally left almost blank)</td></tr><tr><td class="docs"><div class="toc"><a name="toc"><h3>namespaces</h3></a><ul><li><a href="#defenv.core">defenv.core</a></li><li><a href="#defenv.usage">defenv.usage</a></li><li><a href="#defenv.docs">defenv.docs</a></li></ul></div></td><td class="codes">&nbsp;</td></tr><tr><td class="docs"><div class="docs-header"><a class="anchor" href="#defenv.core" name="defenv.core"><h1 class="project-name">defenv.core</h1><a class="toc-link" href="#toc">toc</a></a></div></td><td class="codes" /></tr><tr><td class="docs"><h1>Welcome to defenv</h1>
2868
+</script><title>coreagile/defenv -- Marginalia</title></head><body><table><tr><td class="docs"><div class="header"><h1 class="project-name"><a href="https://defenv.calmabiding.me/">coreagile/defenv</a></h1><h2 class="project-version">1.0.4</h2><br /><p>A simple library for managing environment variables in Clojure</p>
2869
+</div><div class="dependencies"><h3>dependencies</h3><table><tr><td class="dep-name">org.clojure/clojure</td><td class="dotted"><hr /></td><td class="dep-version">1.10.1</td></tr><tr><td class="dep-name">slingshot</td><td class="dotted"><hr /></td><td class="dep-version">0.12.2</td></tr></table></div></td><td class="codes" style="text-align: center; vertical-align: middle;color: #666;padding-right:20px"><br /><br /><br />(this space intentionally left almost blank)</td></tr><tr><td class="docs"><div class="toc"><a name="toc"><h3>namespaces</h3></a><ul><li><a href="#defenv.usage">defenv.usage</a></li><li><a href="#defenv.docs">defenv.docs</a></li><li><a href="#defenv.core">defenv.core</a></li></ul></div></td><td class="codes">&nbsp;</td></tr><tr><td class="docs"><div class="docs-header"><a class="anchor" href="#defenv.usage" name="defenv.usage"><h1 class="project-name">defenv.usage</h1><a class="toc-link" href="#toc">toc</a></a></div></td><td class="codes" /></tr><tr><td class="docs"><h1>Usage example</h1>
2870
+</td><td class="codes"></td></tr><tr><td class="docs">
2871
+</td><td class="codes"><pre class="brush: clojure">(ns defenv.usage
2872
+  (:require [clojure.string :as str]
2873
+            [defenv.core :as env]
2874
+            [slingshot.slingshot :refer [try+]]
2875
+            [taoensso.timbre :as log])
2876
+  (:gen-class)
2877
+  (:import (clojure.lang ExceptionInfo)))</pre></td></tr><tr><td class="docs"><h2>Environment variables</h2>
2878
+</td><td class="codes"></td></tr><tr><td class="docs">
2879
+</td><td class="codes"><pre class="brush: clojure">(def sensible-default &quot;A Sensible Default™&quot;)</pre></td></tr><tr><td class="docs"><h3>Global Bindings</h3>
2880
+</td><td class="codes"></td></tr><tr><td class="docs"><p>An environment variable with a default value.</p>
2881
+</td><td class="codes"><pre class="brush: clojure">(env/defenv testing
2882
+  &quot;DEFENV_TESTING&quot; :default sensible-default)</pre></td></tr><tr><td class="docs"><p>Shows you what happens when something is missing.</p>
2883
+</td><td class="codes"><pre class="brush: clojure">(env/defenv missing
2884
+  &quot;DEFENV_MISSING&quot;)</pre></td></tr><tr><td class="docs">
2885
+</td><td class="codes"><pre class="brush: clojure">(env/defenv missing-no-docs &quot;DEFENV_MISSING_NO_DOCS&quot;)</pre></td></tr><tr><td class="docs"><p>Shows how values can be converted to keywords.</p>
2886
+</td><td class="codes"><pre class="brush: clojure">(env/defenv some-keyword
2887
+  &quot;DEFENV_KEYWORD&quot; :default &quot;test&quot; :tfn keyword)</pre></td></tr><tr><td class="docs"><p>Shows what happens when you mask a var.</p>
2888
+</td><td class="codes"><pre class="brush: clojure">(env/defenv secret-thing
2889
+  &quot;DEFENV_SECRET&quot; :default &quot;oops&quot; :masked? true)</pre></td></tr><tr><td class="docs"><p>A truly optional value.</p>
2890
+</td><td class="codes"><pre class="brush: clojure">(env/defenv truly-optional
2891
+  &quot;DEFENV_OPT&quot; :tfn env/parse-int :optional? true)</pre></td></tr><tr><td class="docs">
2892
+</td><td class="codes"><pre class="brush: clojure">(defn parse-broken [x]
2893
+  (throw (ExceptionInfo. (str &quot;I refuse to parse: &quot; x) {})))</pre></td></tr><tr><td class="docs"><p>Something secret that can't be parsed.</p>
2894
+</td><td class="codes"><pre class="brush: clojure">(env/defenv secret-parse-error
2895
+  &quot;DEFENV_UNPARSEABLE_SECRET&quot;
2896
+  :tfn parse-broken :default &quot;secret&quot; :masked? true)</pre></td></tr><tr><td class="docs"><p>Something that can't be parsed.</p>
2897
+</td><td class="codes"><pre class="brush: clojure">(env/defenv parse-error  &quot;DEFENV_UNPARSEABLE&quot;
2898
+  :tfn parse-broken :default &quot;broken&quot;)</pre></td></tr><tr><td class="docs"><h3>Local Map</h3>
2899
+</td><td class="codes"></td></tr><tr><td class="docs">
2900
+</td><td class="codes"><pre class="brush: clojure">(def env-map-spec {:testing {:env-name &quot;DEFENV_TESTING&quot;
2901
+                             :default sensible-default}
2902
+                   :log-level {:env-name &quot;LOG_LEVEL&quot; :doc &quot;Global log level.&quot;
2903
+                               :tfn keyword :default &quot;info&quot;}
2904
+                   :should-log? {:env-name &quot;SHOULD_LOG&quot;
2905
+                                 :doc &quot;Should I log? A boolean.&quot;
2906
+                                 :tfn env/parse-bool :default &quot;false&quot;}
2907
+                   :optional {:env-name &quot;DEFENV_OPT&quot; :optional? true
2908
+                              :doc &quot;A truly optional value.&quot;}})
2909
+(def env-map (env/env-&gt;map env-map-spec))</pre></td></tr><tr><td class="docs">
2910
+</td><td class="codes"><pre class="brush: clojure">(defmacro handle-exception [&amp; body]
2911
+  `(try+
2912
+     (printf &quot;this should die: %s%n&quot; ~@body)
2913
+     (catch [:type :defenv.core/missing-env] {missing# :missing}
2914
+       (println &quot;Exception msg:&quot; (.getMessage (:throwable ~'&amp;throw-context)))
2915
+       (println &quot;Variables missing:&quot; (str/join &quot;, &quot; missing#)))))</pre></td></tr><tr><td class="docs"><p>A very simple example of how to use the library. Just run <code>lein usage</code>.</p>
2916
+</td><td class="codes"><pre class="brush: clojure">(defn -main
2917
+  [&amp; _]
2918
+  (println &quot;* Display usage without trying to access a variable *&quot;)
2919
+  (env/on-load! (fn [_] (println &quot;** Global Bindings On-Load **&quot;)))
2920
+  (env/on-load! (partial env/print-usage println &quot;Environment On-Load&quot;))
2921
+  (env/on-load! (fn [_] (println &quot;*****************************&quot;)))
2922
+  (println &quot;We should see 2 dumps of the same global environment:&quot;)
2923
+  (env/display-env nil println)
2924
+  (println &quot;\n** Local Map **&quot;)
2925
+  (println env-map)
2926
+  (env/display-env env-map-spec)
2927
+  (println &quot;\n** Single values **&quot;)
2928
+  (println (env/one &quot;PATH&quot;))
2929
+  (handle-exception (env/one &quot;MISSING_SECRET&quot; :masked? true :tfn env/parse-int))
2930
+  (println &quot;\n* Error Handling *&quot;)
2931
+  (env/set-error-print-enabled! true)
2932
+  (env/set-err-print-fn! #(log/error %))
2933
+  (printf &quot;Exception Printing: %s%n&quot; @testing)
2934
+  (handle-exception @missing))</pre></td></tr><tr><td class="spacer docs">&nbsp;</td><td class="codes" /></tr><tr><td class="docs"><div class="docs-header"><a class="anchor" href="#defenv.docs" name="defenv.docs"><h1 class="project-name">defenv.docs</h1><a class="toc-link" href="#toc">toc</a></a></div></td><td class="codes" /></tr><tr><td class="docs">
2935
+</td><td class="codes"><pre class="brush: clojure">(ns defenv.docs
2936
+  (:require [defenv.core :as env]
2937
+            [hiccup.core :as h]))</pre></td></tr><tr><td class="docs"><h1>Documentation Generation</h1>
2938
+</td><td class="codes"></td></tr><tr><td class="docs">
2939
+</td><td class="codes"><pre class="brush: clojure">(defn- env-var-&gt;html [{:keys [env-name default optional? masked? doc]}]
2940
+  [[:dd env-name]
2941
+   [:dt
2942
+    (when (or default optional? masked?)
2943
+      [:ul
2944
+       (when default
2945
+         [:li {:class &quot;default-value&quot;} &quot;Default: &quot;
2946
+          [:span default]])
2947
+       (when optional? [:li {:class &quot;optional&quot;} &quot;optional&quot;])
2948
+       (when masked? [:li {:class &quot;masked&quot;} &quot;masked&quot;])])
2949
+    [:span {:class &quot;doc&quot;} (or doc [:i &quot;No documentation found&quot;])]]])</pre></td></tr><tr><td class="docs">
2950
+</td><td class="codes"><pre class="brush: clojure">(defn- env-&gt;html [header]
2951
+  (h/html
2952
+    [:html
2953
+     [:head
2954
+      [:link {:type &quot;text/css&quot; :href &quot;defenv.css&quot; :rel &quot;stylesheet&quot;}]]
2955
+     [:body
2956
+      [:h1 header]
2957
+      (-&gt;&gt; env-var-&gt;html
2958
+           env/extract-global-spec
2959
+           (reduce concat)
2960
+           (concat [:dl])
2961
+           (into []))]]))</pre></td></tr><tr><td class="docs"><p>Save the current global environment as an HTML file. The <code>header</code> will be
2962
+  emitted as an <code>h1</code> element at the top of the file. The <code>file-name</code> is where
2963
+  the contents will be saved.</p>
2964
+</td><td class="codes"><pre class="brush: clojure">(defn save-html
2965
+  [header file-name]
2966
+  (spit file-name (env-&gt;html header)))</pre></td></tr><tr><td class="docs">
2967
+</td><td class="codes"><pre class="brush: clojure">(defn- example-usage []
2968
+  (load-file &quot;src/defenv/usage.clj&quot;)
2969
+  (save-html &quot;defenv environment specification&quot; &quot;test.html&quot;))</pre></td></tr><tr><td class="docs">
2970
+</td><td class="codes"><pre class="brush: clojure">(comment
2971
+  (example-usage)
2972
+  )</pre></td></tr><tr><td class="spacer docs">&nbsp;</td><td class="codes" /></tr><tr><td class="docs"><div class="docs-header"><a class="anchor" href="#defenv.core" name="defenv.core"><h1 class="project-name">defenv.core</h1><a class="toc-link" href="#toc">toc</a></a></div></td><td class="codes" /></tr><tr><td class="docs"><h1>Welcome to defenv</h1>
2870 2973
 
2871 2974
 <p>This library attempts to simplify the management of environment variables.
2872 2975
 Put simply, it's <code>System/getenv</code> on steroids.</p>
@@ -2881,7 +2984,8 @@ doesn't throw exceptions when loading namespaces (a huge pet peeve!).</p>
2881 2984
   (:require [clojure.pprint :refer :all]
2882 2985
             [clojure.repl :as repl]
2883 2986
             [clojure.set :refer :all]
2884
-            [slingshot.slingshot :refer [throw+]]))</pre></td></tr><tr><td class="docs">
2987
+            [slingshot.slingshot :refer [throw+]]
2988
+            [clojure.string :as str]))</pre></td></tr><tr><td class="docs">
2885 2989
 </td><td class="codes"><pre class="brush: clojure">(defn- env
2886 2990
   [env-name default-value]
2887 2991
   (let [val (System/getenv env-name)] (if-not val default-value val)))</pre></td></tr><tr><td class="docs"><h2>Transformation convenience functions</h2>
@@ -2896,11 +3000,11 @@ doesn't throw exceptions when loading namespaces (a huge pet peeve!).</p>
2896 3000
 </td><td class="codes"><pre class="brush: clojure">(defn parse-boolean
2897 3001
   {:deprecated &quot;0.0.6&quot;} [s] (parse-bool s))</pre></td></tr><tr><td class="docs"><h2>On-the-fly documentation</h2>
2898 3002
 </td><td class="codes"></td></tr><tr><td class="docs"><h3>Generation</h3>
2899
-</td><td class="codes"><pre class="brush: clojure">(def ^:private displays {::missing &quot;*REQUIRED*&quot;
2900
-                         ::masked &quot;--MASKED--&quot;
3003
+</td><td class="codes"><pre class="brush: clojure">(def ^:private displays {::missing     &quot;*REQUIRED*&quot;
3004
+                         ::masked      &quot;--MASKED--&quot;
2901 3005
                          ::parse-error &quot;*PARSE ERROR*&quot;})</pre></td></tr><tr><td class="docs">
2902 3006
 </td><td class="codes"><pre class="brush: clojure">(defn- get-var-status [{:keys [env-name v default masked? optional?]
2903
-                        :as doc-map}]
3007
+                        :as   doc-map}]
2904 3008
   (let [e-val (env env-name default)]
2905 3009
     (-&gt; doc-map
2906 3010
         (assoc :value
@@ -2946,21 +3050,23 @@ doesn't throw exceptions when loading namespaces (a huge pet peeve!).</p>
2946 3050
                           false)))
2947 3051
              (map :name))]
2948 3052
     (when (seq missing-vals)
2949
-      (when @print-usage? (print-usage @epfn missing display-spec))
2950
-      (throw+ {:type ::missing-env :missing missing-vals} missing))))</pre></td></tr><tr><td class="docs"><h2>Core functionality</h2>
3053
+      (let [missing-msg
3054
+            (format &quot;%s: %s&quot; missing (str/join &quot;, &quot; missing-vals))]
3055
+        (when @print-usage? (print-usage @epfn missing display-spec))
3056
+        (throw+ {:type ::missing-env :missing missing-vals} missing-msg)))))</pre></td></tr><tr><td class="docs"><h2>Core functionality</h2>
2951 3057
 </td><td class="codes"></td></tr><tr><td class="docs"><h3>Retrieving environment variable values</h3>
2952 3058
 </td><td class="codes"></td></tr><tr><td class="docs">
2953 3059
 </td><td class="codes"><pre class="brush: clojure">(defn- parse-env [env-name {:keys [default tfn optional?] :as params}]
2954 3060
   (let [has-param? (partial contains? params)
2955 3061
         env-args [env-name]
2956 3062
         base-value (env env-name default)]
2957
-    {:tfn (if (and (not (nil? base-value))
2958
-                   (has-param? :tfn)) tfn
2959
-                                      identity)
2960
-     :env-args (if (or optional? (has-param? :default))
2961
-                 (conj env-args default) env-args)
3063
+    {:tfn               (if (and (not (nil? base-value))
3064
+                                 (has-param? :tfn)) tfn
3065
+                                                    identity)
3066
+     :env-args          (if (or optional? (has-param? :default))
3067
+                          (conj env-args default) env-args)
2962 3068
      :params-to-display (assoc params :env-name env-name)
2963
-     :base-value base-value}))</pre></td></tr><tr><td class="docs">
3069
+     :base-value        base-value}))</pre></td></tr><tr><td class="docs">
2964 3070
 </td><td class="codes"><pre class="brush: clojure">(defn- pretty-demunge
2965 3071
   [fn-object]
2966 3072
   (let [demunged (repl/demunge (str fn-object))
@@ -3083,16 +3189,26 @@ missing.</p>
3083 3189
     `(do (add-to-global-defined-spec! ~env-name ~params)
3084 3190
          (def ^:dynamic ~b (delay (get-global-env ~env-name))))))</pre></td></tr><tr><td class="docs"><h2>Displaying environment information to your users</h2>
3085 3191
 </td><td class="codes"></td></tr><tr><td class="docs">
3086
-</td><td class="codes"><pre class="brush: clojure">(defn- display-env-internal [display-spec]
3087
-  (print-usage println &quot;Environment&quot; display-spec))</pre></td></tr><tr><td class="docs"><p>Display the current environment to users in a friendly manner. If you call
3192
+</td><td class="codes"><pre class="brush: clojure">(defn- display-env-internal [display-spec display-fn]
3193
+  (print-usage display-fn &quot;Environment&quot; display-spec))</pre></td></tr><tr><td class="docs"><p>Display the current environment to users in a friendly manner. If you call
3088 3194
   this function without an <code>env-spec</code>, we will print the result of documentation
3089 3195
   from all the <code>defenv</code> calls that have been executed in all the referred
3090 3196
   namespaces. Otherwise, it will be based on the spec given. This is the same
3091 3197
   format as you would send to <code>env-&gt;map</code>.</p>
3198
+
3199
+<p>  Also, in case you want to send your own function (instead of println), you
3200
+  can call the 2-argument alternative. <code>out-fn</code> will be executed with a string
3201
+  representation of the given environment. If <code>env-spec</code> is nil, we will use
3202
+  the global environment (modified using <code>defenv</code>).</p>
3092 3203
 </td><td class="codes"><pre class="brush: clojure">(defn display-env
3093
-  ([] (guarantee-global! (display-env-internal @global-display-spec)))
3204
+  ([]
3205
+   (display-env nil println))
3094 3206
   ([env-spec]
3095
-   (display-env-internal (:display-spec (get-env-info env-spec)))))</pre></td></tr><tr><td class="docs"><p>Extract the global environment config as a list of maps</p>
3207
+   (display-env env-spec println))
3208
+  ([env-spec out-fn]
3209
+   (if env-spec
3210
+     (display-env-internal (:display-spec (get-env-info env-spec)) out-fn)
3211
+     (guarantee-global! (display-env-internal @global-display-spec out-fn)))))</pre></td></tr><tr><td class="docs"><p>Extract the global environment config as a list of maps</p>
3096 3212
 </td><td class="codes"><pre class="brush: clojure">(defn extract-global-spec
3097 3213
   [f]
3098 3214
   (guarantee-global! (map (comp f second) @global-defined-spec)))</pre></td></tr><tr><td class="docs"><h2>Test fixtures</h2>
@@ -3101,106 +3217,7 @@ missing.</p>
3101 3217
   []
3102 3218
   (with-new-parsed-env!
3103 3219
     (alter global-display-spec empty)
3104
-    (alter global-defined-spec empty)))</pre></td></tr><tr><td class="spacer docs">&nbsp;</td><td class="codes" /></tr><tr><td class="docs"><div class="docs-header"><a class="anchor" href="#defenv.usage" name="defenv.usage"><h1 class="project-name">defenv.usage</h1><a class="toc-link" href="#toc">toc</a></a></div></td><td class="codes" /></tr><tr><td class="docs"><h1>Usage example</h1>
3105
-</td><td class="codes"></td></tr><tr><td class="docs">
3106
-</td><td class="codes"><pre class="brush: clojure">(ns defenv.usage
3107
-  (:require [clojure.string :as str]
3108
-            [defenv.core :as env]
3109
-            [slingshot.slingshot :refer [try+]]
3110
-            [taoensso.timbre :as log])
3111
-  (:gen-class)
3112
-  (:import (clojure.lang ExceptionInfo)))</pre></td></tr><tr><td class="docs"><h2>Environment variables</h2>
3113
-</td><td class="codes"></td></tr><tr><td class="docs">
3114
-</td><td class="codes"><pre class="brush: clojure">(def sensible-default &quot;A Sensible Default™&quot;)</pre></td></tr><tr><td class="docs"><h3>Global Bindings</h3>
3115
-</td><td class="codes"></td></tr><tr><td class="docs"><p>An environment variable with a default value.</p>
3116
-</td><td class="codes"><pre class="brush: clojure">(env/defenv testing
3117
-  &quot;DEFENV_TESTING&quot; :default sensible-default)</pre></td></tr><tr><td class="docs"><p>Shows you what happens when something is missing.</p>
3118
-</td><td class="codes"><pre class="brush: clojure">(env/defenv missing
3119
-  &quot;DEFENV_MISSING&quot;)</pre></td></tr><tr><td class="docs">
3120
-</td><td class="codes"><pre class="brush: clojure">(env/defenv missing-no-docs &quot;DEFENV_MISSING_NO_DOCS&quot;)</pre></td></tr><tr><td class="docs"><p>Shows how values can be converted to keywords.</p>
3121
-</td><td class="codes"><pre class="brush: clojure">(env/defenv some-keyword
3122
-  &quot;DEFENV_KEYWORD&quot; :default &quot;test&quot; :tfn keyword)</pre></td></tr><tr><td class="docs"><p>Shows what happens when you mask a var.</p>
3123
-</td><td class="codes"><pre class="brush: clojure">(env/defenv secret-thing
3124
-  &quot;DEFENV_SECRET&quot; :default &quot;oops&quot; :masked? true)</pre></td></tr><tr><td class="docs"><p>A truly optional value.</p>
3125
-</td><td class="codes"><pre class="brush: clojure">(env/defenv truly-optional
3126
-  &quot;DEFENV_OPT&quot; :tfn env/parse-int :optional? true)</pre></td></tr><tr><td class="docs">
3127
-</td><td class="codes"><pre class="brush: clojure">(defn parse-broken [x]
3128
-  (throw (ExceptionInfo. (str &quot;I refuse to parse: &quot; x) {})))</pre></td></tr><tr><td class="docs"><p>Something secret that can't be parsed.</p>
3129
-</td><td class="codes"><pre class="brush: clojure">(env/defenv secret-parse-error
3130
-  &quot;DEFENV_UNPARSEABLE_SECRET&quot;
3131
-  :tfn parse-broken :default &quot;secret&quot; :masked? true)</pre></td></tr><tr><td class="docs"><p>Something that can't be parsed.</p>
3132
-</td><td class="codes"><pre class="brush: clojure">(env/defenv parse-error  &quot;DEFENV_UNPARSEABLE&quot;
3133
-  :tfn parse-broken :default &quot;broken&quot;)</pre></td></tr><tr><td class="docs"><h3>Local Map</h3>
3134
-</td><td class="codes"></td></tr><tr><td class="docs">
3135
-</td><td class="codes"><pre class="brush: clojure">(def env-map-spec {:testing {:env-name &quot;DEFENV_TESTING&quot;
3136
-                             :default sensible-default}
3137
-                   :log-level {:env-name &quot;LOG_LEVEL&quot; :doc &quot;Global log level.&quot;
3138
-                               :tfn keyword :default &quot;info&quot;}
3139
-                   :should-log? {:env-name &quot;SHOULD_LOG&quot;
3140
-                                 :doc &quot;Should I log? A boolean.&quot;
3141
-                                 :tfn env/parse-bool :default &quot;false&quot;}
3142
-                   :optional {:env-name &quot;DEFENV_OPT&quot; :optional? true
3143
-                              :doc &quot;A truly optional value.&quot;}})
3144
-(def env-map (env/env-&gt;map env-map-spec))</pre></td></tr><tr><td class="docs">
3145
-</td><td class="codes"><pre class="brush: clojure">(defmacro handle-exception [&amp; body]
3146
-  `(try+
3147
-     (printf &quot;this should die: %s%n&quot; ~@body)
3148
-     (catch [:type :defenv.core/missing-env] {missing# :missing}
3149
-       (println &quot;Missing:&quot; (str/join &quot;, &quot; missing#)))))</pre></td></tr><tr><td class="docs"><p>A very simple example of how to use the library. Just run <code>lein usage</code>.</p>
3150
-</td><td class="codes"><pre class="brush: clojure">(defn -main
3151
-  [&amp; _]
3152
-  (println &quot;* Display usage without trying to access a variable *&quot;)
3153
-  (env/on-load! (fn [_] (println &quot;** Global Bindings On-Load **&quot;)))
3154
-  (env/on-load! (partial env/print-usage println &quot;Environment&quot;))
3155
-  (println &quot;\n** Local Map **&quot;)
3156
-  (println env-map)
3157
-  (env/display-env env-map-spec)
3158
-  (println &quot;\n** Single values **&quot;)
3159
-  (println (env/one &quot;PATH&quot;))
3160
-  (handle-exception (env/one &quot;MISSING_SECRET&quot; :masked? true :tfn env/parse-int))
3161
-  (println &quot;\n* Error Handling *&quot;)
3162
-  (env/set-error-print-enabled! true)
3163
-  (env/set-err-print-fn! #(log/error %))
3164
-  (printf &quot;Exception Printing: %s%n&quot; @testing)
3165
-  (handle-exception @missing))</pre></td></tr><tr><td class="spacer docs">&nbsp;</td><td class="codes" /></tr><tr><td class="docs"><div class="docs-header"><a class="anchor" href="#defenv.docs" name="defenv.docs"><h1 class="project-name">defenv.docs</h1><a class="toc-link" href="#toc">toc</a></a></div></td><td class="codes" /></tr><tr><td class="docs">
3166
-</td><td class="codes"><pre class="brush: clojure">(ns defenv.docs
3167
-  (:require [defenv.core :as env]
3168
-            [hiccup.core :as h]))</pre></td></tr><tr><td class="docs"><h1>Documentation Generation</h1>
3169
-</td><td class="codes"></td></tr><tr><td class="docs">
3170
-</td><td class="codes"><pre class="brush: clojure">(defn- env-var-&gt;html [{:keys [env-name default optional? masked? doc]}]
3171
-  [[:dd env-name]
3172
-   [:dt
3173
-    (when (or default optional? masked?)
3174
-      [:ul
3175
-       (when default
3176
-         [:li {:class &quot;default-value&quot;} &quot;Default: &quot;
3177
-          [:span default]])
3178
-       (when optional? [:li {:class &quot;optional&quot;} &quot;optional&quot;])
3179
-       (when masked? [:li {:class &quot;masked&quot;} &quot;masked&quot;])])
3180
-    [:span {:class &quot;doc&quot;} (or doc [:i &quot;No documentation found&quot;])]]])</pre></td></tr><tr><td class="docs">
3181
-</td><td class="codes"><pre class="brush: clojure">(defn- env-&gt;html [header]
3182
-  (h/html
3183
-    [:html
3184
-     [:head
3185
-      [:link {:type &quot;text/css&quot; :href &quot;defenv.css&quot; :rel &quot;stylesheet&quot;}]]
3186
-     [:body
3187
-      [:h1 header]
3188
-      (-&gt;&gt; env-var-&gt;html
3189
-           env/extract-global-spec
3190
-           (reduce concat)
3191
-           (concat [:dl])
3192
-           (into []))]]))</pre></td></tr><tr><td class="docs"><p>Save the current global environment as an HTML file. The <code>header</code> will be
3193
-  emitted as an <code>h1</code> element at the top of the file. The <code>file-name</code> is where
3194
-  the contents will be saved.</p>
3195
-</td><td class="codes"><pre class="brush: clojure">(defn save-html
3196
-  [header file-name]
3197
-  (spit file-name (env-&gt;html header)))</pre></td></tr><tr><td class="docs">
3198
-</td><td class="codes"><pre class="brush: clojure">(defn- example-usage []
3199
-  (load-file &quot;src/defenv/usage.clj&quot;)
3200
-  (save-html &quot;defenv environment specification&quot; &quot;test.html&quot;))</pre></td></tr><tr><td class="docs">
3201
-</td><td class="codes"><pre class="brush: clojure">(comment
3202
-  (example-usage)
3203
-  )</pre></td></tr><tr><td class="spacer docs">&nbsp;</td><td class="codes" /></tr></table><div class="footer">Generated by <a href="https://github.com/gdeer81/marginalia">Marginalia</a>.&nbsp;&nbsp;Syntax highlighting provided by Alex Gorbatchev's <a href="http://alexgorbatchev.com/SyntaxHighlighter/">SyntaxHighlighter</a><div id="floating-toc"><ul><li class="floating-toc-li" id="floating-toc_defenv.core">defenv.core</li><li class="floating-toc-li" id="floating-toc_defenv.usage">defenv.usage</li><li class="floating-toc-li" id="floating-toc_defenv.docs">defenv.docs</li></ul></div></div><script type="text/javascript">SyntaxHighlighter.defaults['gutter'] = false;
3220
+    (alter global-defined-spec empty)))</pre></td></tr><tr><td class="spacer docs">&nbsp;</td><td class="codes" /></tr></table><div class="footer">Generated by <a href="https://github.com/gdeer81/marginalia">Marginalia</a>.&nbsp;&nbsp;Syntax highlighting provided by Alex Gorbatchev's <a href="http://alexgorbatchev.com/SyntaxHighlighter/">SyntaxHighlighter</a><div id="floating-toc"><ul><li class="floating-toc-li" id="floating-toc_defenv.usage">defenv.usage</li><li class="floating-toc-li" id="floating-toc_defenv.docs">defenv.docs</li><li class="floating-toc-li" id="floating-toc_defenv.core">defenv.core</li></ul></div></div><script type="text/javascript">SyntaxHighlighter.defaults['gutter'] = false;
3204 3221
 SyntaxHighlighter.all();
3205 3222
 
3206 3223
 // hackity hack