Update simple deps & clean up exclusions

...so that `lein deps` no longer complains about ambiguous versions.


Add tests for CLI

Add tests for CLI

As the CLI options and defaults get more complicated, tests are
needed to preserve their intended (and somewhat ambiguous) behavior

error: pathspec 'plugin/test/clj/test/lein_doo/config.clj' did not match any file(s) known to git

--- plugin/test/clj/test/lein_doo/config.clj
+++ plugin/test/clj/test/lein_doo/config.clj
@@ -0,0 +1,118 @@
+(ns test.lein-doo.config
+  (:require [clojure.test :refer :all]
+            [leiningen.doo :as doo]))
+
+(deftest correct-main
+  (testing "lein-doo can handle three types for main"
+    (letfn [(find-dev [project]
+              (doo/find-by-id (get-in project [:cljsbuild :builds]) "dev"))]
+      (doseq [main '('lein.core "lein.core" lein.core)]
+        (is (= "dev" (-> {:cljsbuild {:builds [{:id "dev"
+                                                :compiler {:main main}}]}}
+                       doo/correct-builds
+                       find-dev
+                       :id)))
+        (is (= "dev" (-> {:cljsbuild {:builds {:dev {:compiler {:main main}}}}}
+                       doo/correct-builds
+                       find-dev
+                       :id)))))))
+
+(defn mode? [arg]
+  (contains? #{"auto" "once"} arg))
+
+(defn parse [args]
+  (let [[js-env build-id & xs] (remove mode? args)]
+    (assert (empty? xs)
+      (str "We couldn't parse " xs " as a mode, only auto or once are supported"))
+    {:alias (keyword (or js-env "default"))
+     :build (or build-id :default)
+     :mode (keyword (or (first (filter mode? args)) "auto"))}))
+
+(defn args->js-envs [{cli-alias :alias} {alias-map :alias}]
+  (doo.core/resolve-alias cli-alias alias-map))
+
+(deftest parse-cli
+  (testing "lein-doo properly parses the cli arguments"
+    (are [args opts] (= opts (parse args))
+         [] {:build :default
+             :alias :default
+             :mode :auto}
+         ["chrome"] {:build :default
+                     :alias :chrome
+                     :mode :auto}
+         ["chrome" "none-test"] {:build "none-test"
+                                 :alias :chrome
+                                 :mode :auto}
+         ["chrome" "once"] {:build :default
+                            :alias :chrome
+                            :mode :once}
+         ["chrome" "none-test" "once"] {:build "none-test"
+                                        :alias :chrome
+                                        :mode :once})
+    (are [args] (is (thrown? java.lang.AssertionError (parse args)))
+         ["chrome" "none-test" "autoo"]
+         ["chrome" "none-test" "auto" "advanced-test"])))
+
+(deftest parse-js-envs
+  (testing "We can get the js-envs from the cli"
+    (let [opts {:build "test"
+                :alias {:default [:firefox]}}]
+      (are [args js-envs] (= js-envs (args->js-envs (parse args) opts))
+           [] [:firefox]
+           ["chrome"] [:chrome]
+           ["chrome" "none-test"] [:chrome]
+           ["chrome" "once"] [:chrome]
+           ["chrome" "none-test" "once"] [:chrome]))))
+
+(def default-build
+  {:compiler {:optimizations :none
+              :output-to "out/doo-testable.js"}})
+
+(defn args->build [{cli-build :build} builds {opts-build :build}]
+  {:post [(contains? % :source-paths)
+          (not (empty? (:source-paths %)))]}
+  (let [build (if (or (nil? cli-build)
+                      (= :default cli-build))
+                opts-build
+                cli-build)]
+    (if (or (nil? build) (map? build))
+      (merge default-build build)
+      (doo/find-by-id builds build))))
+
+(deftest parse-build
+  (testing "We can get the right build from the cli, opts, and project"
+    (let [builds [{:id "test"
+                   :source-paths ["src" "test"]
+                   :compiler {:optimizations :simple
+                              :output-to "out/testable.js"}}
+                  {:id "advanced"
+                   :source-paths ["src" "test"]
+                   :compiler {:optimizations :advanced
+                              :output-to "out/testable.js"}}]
+          string-opts {:build "test"
+                       :alias {:default [:firefox]}}
+          empty-opts {}
+          map-opts {:build {:source-paths ["src" "test"]
+                            :compiler {:optimizations :whitespace
+                                       :output-to "out/testable.js"}}}]
+      (are [opts args opt-level] (= opt-level (-> (parse args)
+                                                (args->build builds opts)
+                                                :compiler
+                                                :optimizations))
+           string-opts [] :simple
+           string-opts ["chrome"] :simple
+           string-opts ["chrome" "advanced"] :advanced
+           string-opts ["chrome" "once"]  :simple
+           string-opts ["chrome" "test" "once"] :simple
+           map-opts [] :whitespace
+           map-opts ["chrome"] :whitespace
+           map-opts ["chrome" "advanced"] :advanced
+           map-opts ["chrome" "once"]  :whitespace
+           map-opts ["chrome" "test" "once"] :simple
+           empty-opts ["chrome" "advanced"] :advanced
+           empty-opts ["chrome" "test" "once"] :simple)
+      (are [args] (is (thrown? java.lang.AssertionError
+                        (args->build (parse args) builds empty-opts)))
+           []
+           ["chrome"]
+           ["chrome" "once"]))))


no nemesis

no nemesis

remote: Support for password authentication was removed on August 13, 2021.
remote: Please see https://docs.github.com/en/get-started/getting-started-with-git/about-remote-repositories#cloning-with-https-urls for information on currently recommended modes of authentication.
fatal: Authentication failed for 'https://github.com/jchli/jepsen-aurora.git/'


Implemented git server.

Implemented git server.

error: pathspec 'src/clj/darzana/admin/git.clj' did not match any file(s) known to git

--- src/clj/darzana/admin/git.clj
+++ src/clj/darzana/admin/git.clj
@@ -0,0 +1,161 @@
+(ns darzana.admin.git
+  (:use
+    [clj-jgit.internal]
+    [clj-jgit.porcelain]
+    [clj-jgit.querying]
+    [compojure.core :as compojure :only (GET POST PUT ANY defroutes)])
+  (:require
+    [clojure.data.json :as json]
+    [clojure.java.io :as io]
+    [ring.util.response :as response]
+    [ring.util.io :as ring-io]
+    [darzana.workspace :as workspace])
+  (:import
+    [java.io PrintWriter]
+    [org.eclipse.jgit.transport UploadPack ReceivePack PacketLineOut
+      RefAdvertiser$PacketLineOutRefAdvertiser]))
+
+(def config (atom { :upload-pack true
+                    :receive-pack true
+                    :repo-name "darzana-app"}))
+
+;; packet-line handling
+(def pkt-flush "0000")
+
+(defn hdr-nocache [resp]
+  (-> resp
+    (response/header "Expires" "Fri, 01 Jan 1980 00:00:00 GMT")
+    (response/header "Pragma"  "no-cache")
+    (response/header "Cache-Control" "no-cache, max-age=0, must-revalidate")))
+
+(defn hdr-cache-forever [resp]
+  (let [ now (.getTime (new java.util.Date)) ]
+    (-> resp
+      (response/header "Expires" (str now))
+      (response/header "Date"    (str (+ now 31536000)))
+      (response/header "Cache-Control" "public, max-age=31536000"))))
+
+(defn has-access
+  ([request rpc] (has-access request rpc false))
+  ([request rpc check-content-type]
+    (cond
+      (and check-content-type
+        (not= (request :content-type) (str "application/x-git-" rpc "-request"))) false
+      (not (some #{"upload-pack" "receive-pack"} [rpc])) false
+      (= rpc "receive-pack") (@config :receive-pack)
+      (= rpc "upload-pack")  (@config :upload-pack)
+      :else false)))
+
+(defn create-pack [rpc repository]
+  (if (= rpc "upload-pack")
+    (UploadPack. repository)
+    (ReceivePack. repository)))
+
+(defn service-info-refs [service-name]
+  (let [ pack (create-pack service-name (. (workspace/make-repo) getRepository))]
+    (. pack setBiDirectionalPipe false)
+    (-> (response/response
+          (ring-io/piped-input-stream
+            (fn [ostream]
+              (let [ msg (str "# service=git-" service-name "\n")
+                     writer (PrintWriter. ostream)]
+                (. writer print (format "%04x" (+ (count msg) 4)))
+                (. writer print msg)
+                (. writer print pkt-flush)
+                (. writer flush)
+              (. pack sendAdvertisedRefs
+                (RefAdvertiser$PacketLineOutRefAdvertiser. (PacketLineOut. ostream)))))))
+      (response/content-type (str "application/x-git-" service-name "-advertisement"))
+      (hdr-nocache))))
+
+(defn dumb-info-refs []
+  (-> (response/file-response
+        (str (.. (workspace/make-repo) getRepository getDirectory getPath) "/info/refs"))
+    (response/content-type "text/plain")
+    (hdr-nocache)))
+
+(defn get-service-type [request]
+  (if-let [service-type (get-in request [:params :service])]
+    (when (.startsWith service-type "git-")
+      (.substring service-type 4))))
+
+(defn get-info-refs [request]
+  (let [service-name (get-service-type request)]
+    (if (has-access request service-name)
+      (service-info-refs service-name)
+      (dumb-info-refs))))
+
+(defn get-text-file [path]
+  (let [ file (io/file (.. (workspace/make-repo) getRepository getDirectory getPath) path)]
+    (if (.exists file)
+      (-> (response/file-response (.getPath file))
+        (response/content-type "text/plain")
+        (hdr-nocache))
+      (response/not-found "Not Found"))))
+
+(defn get-info-packs []
+  (-> (response/file-response
+        (str (.. (workspace/make-repo) getRepository getDirectory getPath) "/objects/info/packs"))
+    (response/content-type "text/plain; charset=utf-8")
+    (hdr-nocache)))
+
+(defn get-loose-object [path]
+  (-> (response/file-response
+        (str (.. (workspace/make-repo) getRepository getDirectory getPath) "/" path))
+    (response/content-type "application/x-git-loose-object")
+    (hdr-cache-forever)))
+
+(defn get-pack-file [path]
+  (-> (response/file-response
+        (str (.. (workspace/make-repo) getRepository getDirectory getPath) "/" path))
+    (response/content-type "application/x-git-packed-objects")
+    (hdr-cache-forever)))
+
+(defn get-idx-file [path]
+  (-> (response/file-response
+        (str (.. (workspace/make-repo) getRepository getDirectory getPath) "/" path))
+    (response/content-type "application/x-git-packed-objects-toc")
+    (hdr-cache-forever)))
+
+(defn service-upload [request]
+  (let [ pack (create-pack "upload-pack" (. (workspace/make-repo) getRepository))]
+    (. pack setBiDirectionalPipe false)
+    (-> (response/response (ring-io/piped-input-stream
+                             (fn [ostream]
+                               (. pack upload (request :body) ostream nil))))
+      (response/content-type (str "application/x-git-upload-pack-result")))))
+
+(defn service-receive [request]
+  (let [ pack (create-pack "receive-pack" (. (workspace/make-repo) getRepository))]
+    (. pack setBiDirectionalPipe false)
+    (-> (response/response (ring-io/piped-input-stream
+                             (fn [ostream]
+                               (. pack receive (request :body) ostream nil))))
+      (response/content-type (str "application/x-git-receive-pack-result")))))
+
+(defroutes routes
+  (compojure/context (str "/" (@config :repo-name) ".git")  []
+    (GET "/info/refs" {:as request}
+      (get-info-refs request))
+    (POST "/git-upload-pack" {:as request}
+      (service-upload request))
+    (POST "/git-receive-pack" {:as request}
+      (service-receive request))
+    (GET "/HEAD" {params :params}
+      (get-text-file "HEAD"))
+    (GET "/objects/info/alternates" []
+      (get-text-file "objects/info/alternates"))
+    (GET "/objects/info/http-alternates" []
+      (get-text-file "objects/info/http-alternates"))
+    (GET "/objects/info/packs" []
+      (get-info-packs))
+    (GET "/objects/info/*" {params :params}
+      (get-text-file (str "objects/info/" (params :*))))
+    (GET ["/objects/:hash2/:hash38", :hash2 #"[0-9a-f]{2}" :hash38 #"[0-9a-f]{38}"] [hash2 hash38]
+      (get-loose-object (str "objects/" hash2 hash38)))
+    (GET ["/objects/pack/:pack-file", :pack-file #"[0-9a-f]\.(pack|idx)"] [pack-file]
+      (cond
+        (. pack-file endsWith ".pack") (get-pack-file (str "objects/pack/" pack-file))
+        (. pack-file endsWith ".idx")  (get-idx-file  (str "objects/pack/" pack-file))))))
+
+


4clojure:: impl sequs horribilis:: take while predicate coll, maintaining structures

error: pathspec 'src/clojure_learning/tmp7.clj' did not match any file(s) known to git

--- src/clojure_learning/tmp7.clj
+++ src/clojure_learning/tmp7.clj
@@ -0,0 +1,54 @@
+(ns sequs-horribilis
+  (use clojure.repl))
+
+;; Sequs Horribilis
+;; Difficulty:	Medium
+;; Topics:	seqs
+;; Create a function which takes an integer and a nested collection of integers as arguments.
+;; Return a sequence which maintains the nested structure, and which includes all elements
+;; starting from the head whose sum is less than or equal to the input integer.
+;; (=  (__ 10 [1 2 [3 [4 5] 6] 7])
+;;    '(1 2 (3 (4))))
+
+;; =  (__ 9 (range))
+;;    '(0 1 2 3))
+
+;; 1st draft::
+(defn take-until
+  ([bound xs] (take-until bound xs []))
+  ([bound [head & tail] acc]
+    (letfn [(sum-higher-than? [xs bound]
+              (> (apply + (flatten xs)) bound))]
+         (if (sequential? head)
+           (take-until bound head acc)
+           (if (sum-higher-than? (conj acc head) bound)  ;; include current in comparison**
+             acc
+             (recur bound tail (conj acc head)))))))
+
+;; in action:
+(take-until 10 [1 2 [3 [4 5] 6] 7]) ;; [1 2 3 4]
+(take-until 9 (range))              ;; [0 1 2 3]
+
+;; ** the location of the if-predicate higher-than is important, since it includes the current head
+;; in comparison, and while including head, if the conjoined head summed up yields in greather than
+;; the acc is returned WITHOUT head -> [1 2], the next vector-head is ignored
+;; but because we're doing the sequential? comparison first the recursivity takes precedence ->
+;; and the elements are compared by each-number and NOT by conjoining vectors(several items)
+
+;; 2nd draft: persist the nodes-structures of the initial collection/tree
+;; when head resolves into a sequential? -> push on empty node in the accumulator
+;; maintain also the total while going recursively
+(defn take-until
+  ([bound xs] (take-until bound xs [] 0))
+  ([bound [head & tail] acc total]
+    (if (nil? head) acc
+      (if (sequential? head)                        ;; new node -> conjoin to existing and add new node to acc
+        (conj acc (take-until bound head [] total)) ;; reset node & persist total across recursivity
+        (if (> (+ total head) bound)
+          acc
+          (recur bound tail (conj acc head) (+ total head)))))))
+
+;; in action:
+(take-until 10 [1 2 [3 [4 5] 6] 7]) ;; [1 2 3 4]
+(take-until 9 (range))              ;; [0 1 2 3]
+(take-until 30 [1 2 [3 [4 [5 [6 [7 12 13]] 9]] 10] 11]) ;; [1 2 [3 [4 [5 [5 [7]]]]]]


placeholder: sets in Clojure

placeholder: sets in Clojure

fatal: unable to access 'https://github.com/scorphus/sparring.git/': The requested URL returned error: 403


got adding and retrieving users to mongodb working

remote: Support for password authentication was removed on August 13, 2021.
remote: Please see https://docs.github.com/en/get-started/getting-started-with-git/about-remote-repositories#cloning-with-https-urls for information on currently recommended modes of authentication.
fatal: Authentication failed for 'https://github.com/julianjelfs/meeward.git/'


Fix Robin hijacking in uberjar production builds (where run is AOT linked)

remote: Support for password authentication was removed on August 13, 2021.
remote: Please see https://docs.github.com/en/get-started/getting-started-with-git/about-remote-repositories#cloning-with-https-urls for information on currently recommended modes of authentication.
fatal: Authentication failed for 'https://github.com/leif47/immutabledb-experimental.git/'


Improve readability of format-line

Improve readability of format-line

--- src/riemann/xymon.clj
+++ src/riemann/xymon.clj
@@ -6,9 +6,13 @@

 (defn format-line
   "Formats an event "
-  [event]
-  (str "status" (when (and (not= "" (:ttl event)) (not= nil (:ttl event))) (str "+" (:ttl event))) " " (replace (:host event) #"\." ",") "." (replace (:service event) #"(\.| )" "_")" " (:state event) " " (:description event) "\n" )
-  )
+  [{:keys [ttl host service state description]
+    :or {host "" service "" description "" state "unknown"}}]
+  (let [ttl-prefix (if ttl (str "+" ttl) "")
+        host       (s/replace host "." ",")
+        service    (s/replace service #"(\.| )" "_")]
+    (format "status%s %s.%s %s %s\n"
+            ttl-prefix host service state description)))

 (defn send-line
   "Connects to Xymon server, sends line, then closes the connection"


Simple extend function

Simple extend function

remote: Support for password authentication was removed on August 13, 2021.
remote: Please see https://docs.github.com/en/get-started/getting-started-with-git/about-remote-repositories#cloning-with-https-urls for information on currently recommended modes of authentication.
fatal: Authentication failed for 'https://github.com/yokalona/threen.git/'


Added .getArray

Added .getArray

fatal: unable to access 'https://github.com/OttoJursch/sched-system.git/': The requested URL returned error: 403


Changed test-table to testTable

Changed test-table to testTable

remote: Support for password authentication was removed on August 13, 2021.
remote: Please see https://docs.github.com/en/get-started/getting-started-with-git/about-remote-repositories#cloning-with-https-urls for information on currently recommended modes of authentication.
fatal: Authentication failed for 'https://github.com/OttoJursch/sched-system.git/'


Added 04-example-01.clj for the query chapter

remote: Support for password authentication was removed on August 13, 2021.
remote: Please see https://docs.github.com/en/get-started/getting-started-with-git/about-remote-repositories#cloning-with-https-urls for information on currently recommended modes of authentication.
fatal: Authentication failed for 'https://github.com/colophon/clarango.git/'


add queue/channel for ballot reminders

add queue/channel for ballot reminders

remote: Support for password authentication was removed on August 13, 2021.
remote: Please see https://docs.github.com/en/get-started/getting-started-with-git/about-remote-repositories#cloning-with-https-urls for information on currently recommended modes of authentication.
fatal: Authentication failed for 'https://github.com/democracyworks/scheduled-message-works.git/'


whoops, this line is unnecessary

whoops, this line is unnecessary

remote: Support for password authentication was removed on August 13, 2021.
remote: Please see https://docs.github.com/en/get-started/getting-started-with-git/about-remote-repositories#cloning-with-https-urls for information on currently recommended modes of authentication.
fatal: Authentication failed for 'https://github.com/democracyworks/election-mail-works.git/'


Removed obsolete cuke.clj

Removed obsolete cuke.clj

--- clojure/src/main/clj/leiningen/cuke.clj
+++ clojure/src/main/clj/leiningen/cuke.clj
@@ -1,28 +0,0 @@
-(ns leiningen.cuke
-  (:require [leiningen.compile :as lc]
-            [leiningen.core :as c]))
-
-(defn cuke
-  "runs cucumber"
-  [project]
-  ;; basically a reimplimentation of cli.Main that doesn't annoyingly
-  ;; call System/exit
-  (lc/eval-in-project
-   project
-   `(let [~'runtime (cucumber.runtime.Runtime.
-                     (list* ["test/cucumber"])
-                     (cucumber.io.FileResourceLoader.) false)
-          mformatter# (doto (cucumber.formatter.MultiFormatter.)
-                        (.add (.createFormatter
-                               (cucumber.formatter.FormatterFactory.)
-                               "pretty" System/out)))
-          formatter#  (.formatterProxy mformatter#)]
-      (.run ~'runtime
-            (list* ["test/cucumber/features"])
-            (list)
-            formatter#
-            (.reporterProxy mformatter#))
-      (.done formatter#)
-      (println)
-      ~(when-not c/*interactive?*
-         `(System/exit (.exitStatus ~'runtime))))))


WIP.  Basic now working.  More words in Welcome.

error: pathspec 'src/re_com/dropdown.cljs' did not match any file(s) known to git

--- src/re_com/dropdown.cljs
+++ src/re_com/dropdown.cljs
@@ -0,0 +1 @@
+ (ns dropdown)