more refactoring

more refactoring

--- src/main/clojure/org/dada/demo/whales.clj
+++ src/main/clojure/org/dada/demo/whales.clj
@@ -221,29 +221,31 @@
 (import org.dada.core.View)
 (import org.dada.core.Update)

-(defn meta-view [f]
-  (proxy [View] []
-	 (update [insertions alterations deletions]
-		 (doall (map (fn [#^Update insertion] (apply f (.getNewValue insertion))) insertions)))))
+(defn meta-view [#^Model src-metamodel tgt-metamodel f]
+  (insert *metamodel* tgt-metamodel)
+  (connect
+   src-metamodel
+   (proxy [View] []
+	  (update [insertions alterations deletions]
+		  (doall (map (fn [#^Update insertion] (apply f (.getNewValue insertion))) insertions))))))

 (defn split [[#^Model src-metamodel #^Metadata src-metadata #^Collection extra-keys] split-key
 	     & [split-key-fn]]
   (let [tgt-metamodel (model (str (.getName src-metamodel) ".split(" split-key")") nil (.getMetadata src-metamodel))]
-    (insert *metamodel* tgt-metamodel)
-    (connect
+    (meta-view
      src-metamodel
-     (meta-view
-      (fn [model & extra-values]
-	  (do-split
-	   model
-	   split-key
-	   (or split-key-fn list)
-	   identity
-	   (fn [#^Model model extra-value]
-	       (let [model-entry (list* model (concat extra-values [extra-value]))]
-		 (insert tgt-metamodel model-entry)
-		 (insert *metamodel* model)
-		 ))))))
+     tgt-metamodel
+     (fn [model & extra-values]
+	 (do-split
+	  model
+	  split-key
+	  (or split-key-fn list)
+	  identity
+	  (fn [#^Model model extra-value]
+	      (let [model-entry (list* model (concat extra-values [extra-value]))]
+		(insert tgt-metamodel model-entry)
+		(insert *metamodel* model)
+		)))))
     [tgt-metamodel src-metadata (concat extra-keys [split-key])]))

 ;; extra keys are inserted into attribute list
@@ -254,30 +256,28 @@
   (let [tgt-metamodel (model (str (.getName src-metamodel) ".count(" (or count-key "") ")") nil (.getMetadata src-metamodel))
 	extra-attributes (map (fn [key] (.getAttribute src-metadata key)) extra-keys)
 	tgt-metadata (count-reducer-metadata extra-keys count-key extra-attributes)]
-    (insert *metamodel* tgt-metamodel)
-    (connect
+    (meta-view
      src-metamodel
-     (meta-view
-      (fn [#^Model src-model & extra-values]
-	  (let [count-model (do-reduce-count
-			     (.getName src-model)
-			     (.getMetadata src-model)
-			     tgt-metadata
-			     count-key
-			     extra-values)]
-	    (insert *metamodel* count-model)
-	    (insert tgt-metamodel (list* count-model extra-values))
-	    (connect src-model count-model)))))
+     tgt-metamodel
+     (fn [#^Model src-model & extra-values]
+	 (let [count-model (do-reduce-count
+			    (.getName src-model)
+			    (.getMetadata src-model)
+			    tgt-metadata
+			    count-key
+			    extra-values)]
+	   (insert *metamodel* count-model)
+	   (insert tgt-metamodel (list* count-model extra-values))
+	   (connect src-model count-model))))
     [tgt-metamodel tgt-metadata extra-keys]))

 (defn union [[#^Model src-metamodel #^Metadata src-metadata #^Collection extra-keys] #^String prefix]
   (let [tgt-metamodel (model (str (.getName src-metamodel) ".union()") nil (.getMetadata src-metamodel))
 	tgt-model (model (str prefix ".union()") nil src-metadata)]
-    (insert *metamodel* tgt-metamodel)
     (insert *metamodel* tgt-model)
     (insert tgt-metamodel [tgt-model])
-    (connect src-metamodel (meta-view (fn [src-model & extra-values] (connect src-model tgt-model))))
+    (meta-view src-metamodel tgt-metamodel (fn [src-model & extra-values] (connect src-model tgt-model)))
     [tgt-metamodel src-metadata extra-keys]))

 ;;--------------------------------------------------------------------------------


Added print-method for Css, Literal

Added print-method for Css, Literal

--- src/hyjinks.clj
+++ src/hyjinks.clj
@@ -38,6 +38,9 @@

 ;; Core types

+(defn- str-attrs [attrs]
+	(str-join (map (fn [[k v]] [" " k "=\"" (html-escape v) "\""]) attrs)))
+
 (defrecord Css []
 	java.lang.Object
 	(toString [this]
@@ -46,9 +49,6 @@
 	(invoke [this] this)
 	(invoke [this x] (.applyTo this x))
 	(applyTo [this args] (let [tag (first args)] (tag this))))
-
-(defn- str-attrs [attrs]
-	(str-join (map (fn [[k v]] [" " k "=\"" (html-escape v) "\""]) attrs)))

 (impl-invoke (defrecord Tag [tag-name attrs css items]
 	java.lang.Object
@@ -62,9 +62,13 @@
 	clojure.lang.IFn
 	(applyTo [this args] (apply extend-tag this args))))

+(defrecord Literal [s] java.lang.Object (toString [_] s))
+
+(defmethod print-method Css [c ^java.io.Writer w] (.write w (str c)))
+
 (defmethod print-method Tag [t ^java.io.Writer w] (.write w (str t)))

-(defrecord Literal [s] java.lang.Object (toString [_] s))
+(defmethod print-method Literal [l ^java.io.Writer w] (.write w (str l)))

 ;; Builder functions


added enlive snippet/templates to om support

--- src/kioo/om.clj
+++ src/kioo/om.clj
@@ -1,5 +1,5 @@
 (ns kioo.om
-  (:require [kioo.core :refer [component*]]
+  (:require [kioo.core :refer [component* snippet*]]
             [kioo.util :refer [convert-attrs]]))

 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
@@ -38,3 +38,16 @@
   "React base component definition"
   [path & body]
   (component* path body om-emit-opts))
+
+
+(defmacro snippet [path sel args trans]
+  (snippet* path (list sel trans) args om-emit-opts))
+
+(defmacro template [path args trans]
+  (snippet* path trans args om-emit-opts))
+
+(defmacro defsnippet [sym path sel args trans]
+  `(def sym ~(snippet* path (list sel trans) args om-emit-opts)))
+
+(defmacro deftemplate [sym path args trans]
+  `(def sym ~(snippet* path args om-emit-opts)))


make sure stripe init runs

make sure stripe init runs

--- src/pc/init.clj
+++ src/pc/init.clj
@@ -18,6 +18,7 @@
             pc.repl
             pc.server
             pc.statsd
+            pc.stripe
             pc.stripe.dev
             pc.utils)
   (:gen-class))
@@ -36,6 +37,7 @@
    #'pc.assets/init
    #'pc.email/init
    #'pc.cache/init
+   #'pc.stripe/init
    #'pc.server/init
    #'pc.http.webhooks/init
    #'pc.datomic.admin-db/init


hack up a form post for ajax

hack up a form post for ajax

--- frontend/utils/ajax.cljs
+++ frontend/utils/ajax.cljs
@@ -36,7 +36,7 @@
                         (if keywords? " keywordize"))}))

 ;; XXX only implementing JSON format and not implementing prefixes for now since we don't use either
-(defn ajax [method url message channel & {:keys [params keywords? context]
+(defn ajax [method url message channel & {:keys [params keywords? context headers]
                                           :or {keywords? true}}]
   (let [uuid frontend.async/*uuid*]
     (put! channel [message :started context])
@@ -49,7 +49,8 @@
                              :params params
                              :headers (merge {:Accept "application/json"}
                                              (when (re-find #"^/" url)
-                                               {:X-CSRFToken (utils/csrf-token)}))
+                                               {:X-CSRFToken (utils/csrf-token)})
+                                             headers)
                              :handler #(binding [frontend.async/*uuid* uuid]
                                          (put! channel [message :success (assoc % :context context)]))
                              :error-handler #(binding [frontend.async/*uuid* uuid]
@@ -57,7 +58,7 @@
                              :finally #(binding [frontend.async/*uuid* uuid]
                                          (put! channel [message :finished context]))}))))

-(defn managed-ajax [method url & {:keys [params keywords?]
+(defn managed-ajax [method url & {:keys [params keywords? headers]
                                   :or {keywords? true}}]
   (let [channel (chan)]
     (clj-ajax/ajax-request url method
@@ -69,8 +70,29 @@
                          :params params
                          :headers (merge {:Accept "application/json"}
                                          (when (re-find #"^/" url)
-                                           {:X-CSRFToken (utils/csrf-token)}))
+                                           {:X-CSRFToken (utils/csrf-token)})
+                                         headers)
                          :handler #(put! channel (assoc % :status :success))
                          :error-handler #(put! channel %)
                          :finally #(close! channel)}))
     channel))
+
+
+;; XXX this should be possible to do with the normal ajax function, but punting for now
+(defn managed-form-post [url & {:keys [params headers keywords?]
+                                :or {keywords? true}}]
+  (let [channel (chan)]
+    (clj-ajax/ajax-request url :post
+                           (clj-ajax/transform-opts
+                            {:format  (merge (clj-ajax/url-request-format)
+                                             (json-response-format {:keywords? keywords? :url url :method :post}))
+                             :response-format :json
+                             :params params
+                             :headers (merge {:Accept "application/json"}
+                                             (when (re-find #"^/" url)
+                                               {:X-CSRFToken (utils/csrf-token)})
+                                             headers)
+                             :handler #(put! channel (assoc % :status :success))
+                             :error-handler #(put! channel %)
+                             :finally #(close! channel)}))
+    channel))


Fix managed-form-post

Fix managed-form-post

--- frontend/utils/ajax.cljs
+++ frontend/utils/ajax.cljs
@@ -139,5 +139,6 @@
           :handler #(put! channel (assoc % :status :success))
           :error-handler #(put! channel %)
           :finally #(close! channel)})
-        (assoc :uri url :method :post))
+        (assoc :uri url :method :post)
+        clj-ajax/ajax-request)
     channel))


(PE-4299) Addressed PR feedback

(PE-4299) Addressed PR feedback

--- src/clj/puppetlabs/master/services/handler/request_handler_service.clj
+++ src/clj/puppetlabs/master/services/handler/request_handler_service.clj
@@ -19,7 +19,10 @@
                (handle-request
                  [this request]
                  (let [pool-descriptor (if-let [environment (:environment request)]
-                                         (environment->pool-descriptor environment)
+                                         ;; TODO : This should later intelligently choose the pool
+                                         ;; TODO : descriptor based up on the environment of the req.
+                                         (get-default-pool-descriptor)
+                                         #_(environment->pool-descriptor environment)
                                          (get-default-pool-descriptor))
                        jruby-service (get-service :JRubyPuppetService)]
                    (handle-request pool-descriptor request jruby-service)))


Show the slowest test one the test results tab

--- src-cljs/frontend/components/build_head.cljs
+++ src-cljs/frontend/components/build_head.cljs
@@ -23,7 +23,6 @@
             [goog.dom]
             [goog.dom.DomHelper]
             [goog.string :as gstring]
-            [goog.string.format]
             [inflections.core :refer (pluralize)]
             [om.core :as om :include-macros true]
             [om.dom :as dom :include-macros true])
@@ -704,7 +703,11 @@
             failed-sources (filter (fn [[_ {:keys [failures]}]]
                                      (seq failures))
                                    source-hash)
-            build-succeeded? (= "success" build-status)]
+            build-succeeded? (= "success" build-status)
+
+            by-time (reverse (sort-by :run_time (filter (comp number? :run_time)
+                                                        tests)))
+            slowest (first by-time)]
         (html
          [:div.test-results
           (if-not tests
@@ -715,8 +718,16 @@
                            "Your build ran "
                            [:strong (count tests)]
                            " tests in " (string/join ", " (map test-model/pretty-source (keys source-hash))) " with "
-                           [:strong "0 failures"]]
-
+                           [:strong "0 failures"]
+                           (when slowest
+                             [:div.build-tests-summary
+                              [:p
+                               [:strong "Slowest test:"]
+                               (gstring/format
+                                    " %s %s (took %.2f seconds)."
+                                    (:classname slowest)
+                                    (:name slowest)
+                                    (:run_time slowest))]])]
               :else [:div.alert.iconified {:class (if build-succeeded? "alert-info" "alert-danger")}
                      [:div [:img.alert-icon {:src (common/icon-path
                                                    (if build-succeeded? "Info-Info" "Info-Error"))}]]


Created tests for concept-robustness

Created tests for concept-robustness

--- src/test/clojure/conexp/fca/more_test.clj
+++ src/test/clojure/conexp/fca/more_test.clj
@@ -120,3 +120,41 @@
                         (concepts context)))
          (expt 2 (count (objects context)))))))

+;;;
+
+(deftest test-concept-robustness
+  (let [ctx1 (make-context-from-matrix 3 3
+                                       [0 0 1
+                                        1 0 1
+                                        1 1 0])
+        cpt1 [#{0 1} #{2}]
+        ctx2 (make-context-from-matrix ['a 'b 'c 'd 'e 'f]
+                                       ['a 'b 'c 'd 'e 'f]
+                                       [1 1 1 0 1 1
+                                        0 1 0 0 1 0
+                                        0 0 1 0 0 1
+                                        0 0 0 1 1 1
+                                        0 0 0 0 1 0
+                                        0 0 0 0 0 1])
+        concepts1 (concepts ctx1)
+        concepts2 (concepts ctx2)
+        cpt2 [#{'d} #{'d 'e 'f}]
+        cpt3 [#{'a 'd} #{'e 'f}]
+        rctx (random-context 10 0.5)
+        conceptsr1 (concepts rctx)
+        rctx2 (random-context 15 0.3)
+        conceptsr2 (concepts rctx2)]
+
+    (is (= (concept-robustness cpt1 concepts1 (/ 1 3)) (/ 1 3)))
+    (is (= (concept-robustness cpt2 concepts2 (/ 3 4)) (/ 3 4)))
+    (is (= (concept-robustness cpt3 concepts2 (/ 1 2)) (/ 1 4)))
+
+    (with-testing-data [cpt conceptsr1]
+      (and (<= 0 (concept-robustness cpt conceptsr1 0.42))
+           (<= (concept-robustness cpt conceptsr1 0.13) 1)))
+
+    (with-testing-data [cpt conceptsr2]
+      (= (concept-robustness cpt conceptsr2 (/ 1 2)) (concept-stability rctx2 cpt)))))
+
+;;;
+nil


Create a path for csv errors in 5.1 feeds

For an error on line 87 of state.txt, it would be: "CSVError.0.state.87"

--- src/vip/data_processor/validation/csv.clj
+++ src/vip/data_processor/validation/csv.clj
@@ -105,8 +105,15 @@
                                   (let [message (.getMessage e)]
                                     (if (re-find #"UNIQUE constraint failed: (\w+).id" message)
                                       (db.util/retry-chunk-without-dupe-ids ctx sql-table chunk-values)
-                                      (assoc-in ctx [:fatal (:name sql-table) @line-number :unknown-sql-error]
-                                                [message]))))))
+                                      (let [identifier (if (= "3.0" (:spec-version ctx))
+                                                         @line-number
+                                                         (str "CSVError.0."
+                                                              (-> filename
+                                                                  (str/split #"\.")
+                                                                  first)
+                                                              "." @line-number))]
+                                        (assoc-in ctx [:fatal (:name sql-table) identifier :unknown-sql-error]
+                                                  [message])))))))
                             ctx))
                         ctx (db.util/chunk-rows (csv/read-csv in-file)
                                                 sqlite/statement-parameter-limit))))))


step 4: order phones with cursor

step 4: order phones with cursor

--- src/cljs/reagent_phonecat_tutorial/core.cljs
+++ src/cljs/reagent_phonecat_tutorial/core.cljs
@@ -40,8 +40,13 @@
 (def state "Reagent atom that holds our global application state."
   (rg/atom {:phones hardcoded-phones-data
             :search ""
+            :order-prop :name
             }))

+
+(def order-prop-state (rg/cursor state [:order-prop]))
+
+
 (defn update-search [state new-search]
   (assoc state :search new-search))

@@ -51,6 +56,7 @@
 (declare ;; here we declare our components to define their in an order that feels natural.
   top-cpnt
     search-cpnt
+    order-prop-select
     phones-list
       phone-item)

@@ -58,8 +64,12 @@
   (let [{:keys [phones search]} @state]
     [:div.container-fluid
      [:div.row
-      [:div.col-md-2 [search-cpnt search]]
-      [:div.col-md-8 [phones-list phones search]]
+      [:div.col-md-2
+       [search-cpnt search]
+       [:br]
+       "Sort by:"
+       [order-prop-select]]
+      [:div.col-md-8 [phones-list phones search @order-prop-state]]
       ]]))

 (defn search-cpnt [search]
@@ -69,10 +79,19 @@
             :value search
             :on-change (fn [e] (swap! state update-search (-> e .-target .-value)))}]])

+(defn order-prop-select []
+  [:select {:value @order-prop-state
+            :on-change #(reset! order-prop-state (-> % .-target .-value keyword))}
+   [:option {:value :name} "Alphabetical"]
+   [:option {:value :age} "Newest"]
+   ])
+
 (defn phones-list "An unordered list of phones"
-  [phones-list search]
+  [phones-list search order-prop]
   [:ul.phones
-   (for [phone (->> phones-list (filter #(matches-search? search %)))]
+   (for [phone (->> phones-list
+                 (filter #(matches-search? search %))
+                 (sort-by order-prop))]
      ^{:key (:name phone)} [phone-item phone]
      )])


data section before linked #230

data section before linked
#230

--- src/cljs/swarmpit/component/config/info.cljs
+++ src/cljs/swarmpit/component/config/info.cljs
@@ -107,15 +107,15 @@
      (form/item-date "CREATED" (:createdAt config))
      (form/item-date "UPDATED" (:updatedAt config))]
     [:div.form-layout-group.form-layout-group-border
+     (form/section "Data")
+     (form-data (parse-data (:data config)))]
+    [:div.form-layout-group.form-layout-group-border
      (form/section "Linked Services")
      (list/table (map :name services/headers)
                  services
                  services/render-item
                  services/render-item-keys
-                 services/onclick-handler)]
-    [:div.form-layout-group.form-layout-group-border
-     (form/section "Data")
-     (form-data (parse-data (:data config)))]]])
+                 services/onclick-handler)]]])

 (rum/defc form < rum/reactive
                  mixin-init-form


rewrote with if-let form, wakey wakey

rewrote with if-let form, wakey wakey

--- cljx/plongeur-cljs/src/kierros/async.cljs
+++ cljx/plongeur-cljs/src/kierros/async.cljs
@@ -13,11 +13,9 @@
    (let [out (chan buf-or-n)]
      (go-loop [[ch & rest] chs]
         (if ch
-          (let [val (<! ch)]
-            (if (nil? val) ;; current channel exhausted
-              (recur rest)
-              (do
-                (>! out val)
-                (recur chs))))
+          (if-let [v (<! ch)]
+            (do (>! out v)
+                (recur chs))
+            (recur rest))
           (close! out))) ;; close out channel when all input channels are consumed
      out)))


Set text-align: left for the HUD (#502)

Set text-align: left for the HUD (#502)

--- support/src/figwheel/client/heads_up.cljs
+++ support/src/figwheel/client/heads_up.cljs
@@ -68,6 +68,7 @@
                                 "opacity: 0.0;"
                                 "box-sizing: border-box;"
                                 "z-index: 10000;"
+                                "text-align: left;"
                                 ) })]
         (set! (.-onclick el) heads-up-onclick-handler)
         (set! (.-innerHTML el) cljs-logo-svg)


integeral

integeral

--- test/atom_finder/classifier_util_test.clj
+++ test/atom_finder/classifier_util_test.clj
@@ -117,7 +117,7 @@

       (for [[expr expected] cases]
         (testing (str "Parse numeric literal from string: " expr " - " expected)
-          (is (= (integeral? expr) exected)))))
+          (is (= (integral? expr) expected)))))
     ))

 (deftest test-parse-numeric-literal?


Add missing integration test for TeamCity test resut sync

--- test/buildviz/teamcity/sync_jobs_test.clj
+++ test/buildviz/teamcity/sync_jobs_test.clj
@@ -31,17 +31,34 @@
         testresults (map (fn [build]
                            [(format "http://teamcity:8000/httpAuth/app/rest/testOccurrences?locator=count:10000,start:0,build:(id:%s)"
                                     (:id build))
-                            (successful-json-response {:testOccurrences []})]) builds)]
+                            (successful-json-response {:testOccurrence []})]) builds)]
     (cons job-builds testresults)))

+(defn- a-job-with-tests [job-id build tests]
+  (let [job-builds [(format "http://teamcity:8000/httpAuth/app/rest/buildTypes/id:%s/builds/?locator=count:100,start:0&fields=build(id,number,status,startDate,finishDate,state,revisions%%28revision%%28version%%2Cvcs-root-instance%%29%%29,snapshot-dependencies%%28build%%28number%%2CbuildType%%28name%%2CprojectName%%29%%29%%29,triggered)"
+                            job-id)
+                    (successful-json-response {:build [(merge {:revisions []
+                                                               :status "SUCCESS"
+                                                               :state "finished"}
+                                                              build)]})]
+        testresults [[(format "http://teamcity:8000/httpAuth/app/rest/testOccurrences?locator=count:10000,start:0,build:(id:%s)"
+                              (:id build))
+                      (successful-json-response {:testOccurrence tests})]]]
+    (cons job-builds testresults)))
+
 (def beginning-of-2016 (t/date-time 2016 1 1))

 (defn- provide-buildviz-and-capture-puts [latest-build-start map-ref]
-  [[#"http://buildviz:8010/builds/(.+)/(.+)"
+  [[#"http://buildviz:8010/builds/([^/]+)/([^/]+)"
     (fn [req]
       (swap! map-ref #(conj % [(:uri req)
                                (j/parse-string (slurp (:body req)) true)]))
       {:status 200 :body ""})]
+   [#"http://buildviz:8010/builds/([^/]+)/([^/]+)/testresults"
+    (fn [req]
+      (swap! map-ref #(conj % [(:uri req)
+                               (j/parse-string (slurp (:body req)) true)]))
+      {:status 204 :body ""})]
    ["http://buildviz:8010/status"
     (successful-json-response (cond-> {}
                                 latest-build-start (assoc :latestBuildStart (tc/to-long latest-build-start))))]])
@@ -51,7 +68,7 @@
        (mapcat identity) ; flatten once
        (into {})))

-(deftest test-main
+(deftest test-teamcity-sync-jobs
   (testing "should sync a build"
     (let [stored (atom [])]
       (fake/with-fake-routes-in-isolation (serve-up (a-project "the_project" (a-job "theJobId" "theProject" "theJob #1"))
@@ -181,4 +198,26 @@
         (with-out-str (sut/sync-jobs (url/url "http://teamcity:8000") (url/url "http://buildviz:8010") ["the_project"] beginning-of-2016 build-start))
         (is (= ["/builds/theProject%20job1/11"
                 "/builds/theProject%20job1/12"]
-               (map first @stored)))))))
+               (map first @stored))))))
+
+  (testing "should sync test results"
+    (let [latest-build-start nil
+          stored (atom [])]
+      (fake/with-fake-routes-in-isolation (serve-up (a-project "the_project"
+                                                               (a-job "jobId1" "theProject" "job1"))
+                                                    (a-job-with-tests "jobId1"
+                                                                      {:id 10
+                                                                       :number 10
+                                                                       :startDate "20160410T000000+0000"
+                                                                       :finishDate "20160410T000100+0000"}
+                                                                      [{:name "suite: class.the test"
+                                                                        :status "SUCCESS"
+                                                                        :duration 42}])
+                                                    (provide-buildviz-and-capture-puts latest-build-start stored))
+        (with-out-str (sut/sync-jobs (url/url "http://teamcity:8000") (url/url "http://buildviz:8010") ["the_project"] beginning-of-2016 nil)))
+      (is (= ["/builds/theProject%20job1/10/testresults" [{:name "suite"
+                                                           :children [{:name "the test"
+                                                                       :classname "class"
+                                                                       :status "pass"
+                                                                       :runtime 42}]}]]
+             (nth @stored 1))))))


Test for function post-command with auth string

--- test/clj_jenkins_api/jenkins_api_test.clj
+++ test/clj_jenkins_api/jenkins_api_test.clj
@@ -302,14 +302,28 @@
     (testing "the clj-jenkins-api.jenkins-api/get-command"
         (with-redefs [http-client/get (fn [url mapa] {:body url})]
             (are [x y] (= x y)
-                {:body ""} (http-client/get "" nil)
-                {:body "url"} (http-client/get "url" nil)))))
+                ""                       (get-command "")
+                "url"                    (get-command "url")
+                "http://jenkins.url.org" (get-command "http://jenkins.url.org")))))

 (deftest test-post-command
     "Check the clj-jenkins-api.jenkins-api/post-command"
     (testing "the clj-jenkins-api.jenkins-api/post-command"
-        (with-redefs [http-client/get (fn [url mapa] {:body url})]
+        (with-redefs [http-client/post (fn [url mapa] {:body url})]
             (are [x y] (= x y)
-                {:body ""} (http-client/get "" nil)
-                {:body "url"} (http-client/get "url" nil)))))
-
+                {:body "job//"}    (post-command "" "" "" "")
+                {:body "jenkins-url/job/job-name/"} (post-command "jenkins-url/" "" "job-name" "")
+                {:body "http://jenkins.url.org/job/job-name/"} (post-command "http://jenkins.url.org/" "" "job-name" "")))))
+
+(deftest test-post-command-auth
+    "Check the clj-jenkins-api.jenkins-api/post-command"
+    (testing "the clj-jenkins-api.jenkins-api/post-command"
+        (with-redefs [http-client/post (fn [url mapa] {:body url})]
+            (are [x y] (= x y)
+                {:body "job//"}
+                (post-command "" "user@password" "" "")
+                {:body "jenkins-url/job/job-name/"}
+                (post-command "jenkins-url/" "user@password" "job-name" "")
+                {:body "http://user@password@jenkins.url.org/job/job-name/"}
+                (post-command "http://jenkins.url.org/" "user@password" "job-name" "")))))
+


Fix warnings

Fix warnings

--- test/com/wsscode/pathom/test_helpers.cljc
+++ test/com/wsscode/pathom/test_helpers.cljc
@@ -2,30 +2,56 @@

 (defn mock []
   (let [calls (atom [])]
-    (reify
-      #?(:clj  clojure.lang.IDeref
-         :cljs cljs.core.IDeref)
-      (deref [_] @calls)
+    #?(:clj
+       (reify
+         clojure.lang.IDeref
+         (deref [_] @calls)

-      #?(:clj  clojure.lang.IFn
-         :cljs cljs.core.IFn)
-      (invoke [_ v1] (swap! calls conj [v1]))
-      (invoke [_ v1 v2] (swap! calls conj [v1 v2]))
-      (invoke [_ v1 v2 v3] (swap! calls conj [v1 v2 v3]))
-      (invoke [_ v1 v2 v3 v4] (swap! calls conj [v1 v2 v3 v4]))
-      (invoke [_ v1 v2 v3 v4 v5] (swap! calls conj [v1 v2 v3 v4 v5]))
-      (invoke [_ v1 v2 v3 v4 v5 v6] (swap! calls conj [v1 v2 v3 v4 v5 v6]))
-      (invoke [_ v1 v2 v3 v4 v5 v6 v7] (swap! calls conj [v1 v2 v3 v4 v5 v6 v7]))
-      (invoke [_ v1 v2 v3 v4 v5 v6 v7 v8] (swap! calls conj [v1 v2 v3 v4 v5 v6 v7 v8]))
-      (invoke [_ v1 v2 v3 v4 v5 v6 v7 v8 v9] (swap! calls conj [v1 v2 v3 v4 v5 v6 v7 v8 v9]))
-      (invoke [_ v1 v2 v3 v4 v5 v6 v7 v8 v9 v10] (swap! calls conj [v1 v2 v3 v4 v5 v6 v7 v8 v9 v10]))
-      (invoke [_ v1 v2 v3 v4 v5 v6 v7 v8 v9 v10 v11] (swap! calls conj [v1 v2 v3 v4 v5 v6 v7 v8 v9 v10 v11]))
-      (invoke [_ v1 v2 v3 v4 v5 v6 v7 v8 v9 v10 v11 v12] (swap! calls conj [v1 v2 v3 v4 v5 v6 v7 v8 v9 v10 v11 v12]))
-      (invoke [_ v1 v2 v3 v4 v5 v6 v7 v8 v9 v10 v11 v12 v13] (swap! calls conj [v1 v2 v3 v4 v5 v6 v7 v8 v9 v10 v11 v12 v13]))
-      (invoke [_ v1 v2 v3 v4 v5 v6 v7 v8 v9 v10 v11 v12 v13 v14] (swap! calls conj [v1 v2 v3 v4 v5 v6 v7 v8 v9 v10 v11 v12 v13 v14]))
-      (invoke [_ v1 v2 v3 v4 v5 v6 v7 v8 v9 v10 v11 v12 v13 v14 v15] (swap! calls conj [v1 v2 v3 v4 v5 v6 v7 v8 v9 v10 v11 v12 v13 v14 v15]))
-      (invoke [_ v1 v2 v3 v4 v5 v6 v7 v8 v9 v10 v11 v12 v13 v14 v15 v16] (swap! calls conj [v1 v2 v3 v4 v5 v6 v7 v8 v9 v10 v11 v12 v13 v14 v15 v16]))
-      (invoke [_ v1 v2 v3 v4 v5 v6 v7 v8 v9 v10 v11 v12 v13 v14 v15 v16 v17] (swap! calls conj [v1 v2 v3 v4 v5 v6 v7 v8 v9 v10 v11 v12 v13 v14 v15 v16 v17]))
-      (invoke [_ v1 v2 v3 v4 v5 v6 v7 v8 v9 v10 v11 v12 v13 v14 v15 v16 v17 v18] (swap! calls conj [v1 v2 v3 v4 v5 v6 v7 v8 v9 v10 v11 v12 v13 v14 v15 v16 v17 v18]))
-      (invoke [_ v1 v2 v3 v4 v5 v6 v7 v8 v9 v10 v11 v12 v13 v14 v15 v16 v17 v18 v19] (swap! calls conj [v1 v2 v3 v4 v5 v6 v7 v8 v9 v10 v11 v12 v13 v14 v15 v16 v17 v18 v19]))
-      (invoke [_ v1 v2 v3 v4 v5 v6 v7 v8 v9 v10 v11 v12 v13 v14 v15 v16 v17 v18 v19 v20] (swap! calls conj [v1 v2 v3 v4 v5 v6 v7 v8 v9 v10 v11 v12 v13 v14 v15 v16 v17 v18 v19 v20])))))
+         clojure.lang.IFn
+         (invoke [_ v1] (swap! calls conj [v1]))
+         (invoke [_ v1 v2] (swap! calls conj [v1 v2]))
+         (invoke [_ v1 v2 v3] (swap! calls conj [v1 v2 v3]))
+         (invoke [_ v1 v2 v3 v4] (swap! calls conj [v1 v2 v3 v4]))
+         (invoke [_ v1 v2 v3 v4 v5] (swap! calls conj [v1 v2 v3 v4 v5]))
+         (invoke [_ v1 v2 v3 v4 v5 v6] (swap! calls conj [v1 v2 v3 v4 v5 v6]))
+         (invoke [_ v1 v2 v3 v4 v5 v6 v7] (swap! calls conj [v1 v2 v3 v4 v5 v6 v7]))
+         (invoke [_ v1 v2 v3 v4 v5 v6 v7 v8] (swap! calls conj [v1 v2 v3 v4 v5 v6 v7 v8]))
+         (invoke [_ v1 v2 v3 v4 v5 v6 v7 v8 v9] (swap! calls conj [v1 v2 v3 v4 v5 v6 v7 v8 v9]))
+         (invoke [_ v1 v2 v3 v4 v5 v6 v7 v8 v9 v10] (swap! calls conj [v1 v2 v3 v4 v5 v6 v7 v8 v9 v10]))
+         (invoke [_ v1 v2 v3 v4 v5 v6 v7 v8 v9 v10 v11] (swap! calls conj [v1 v2 v3 v4 v5 v6 v7 v8 v9 v10 v11]))
+         (invoke [_ v1 v2 v3 v4 v5 v6 v7 v8 v9 v10 v11 v12] (swap! calls conj [v1 v2 v3 v4 v5 v6 v7 v8 v9 v10 v11 v12]))
+         (invoke [_ v1 v2 v3 v4 v5 v6 v7 v8 v9 v10 v11 v12 v13] (swap! calls conj [v1 v2 v3 v4 v5 v6 v7 v8 v9 v10 v11 v12 v13]))
+         (invoke [_ v1 v2 v3 v4 v5 v6 v7 v8 v9 v10 v11 v12 v13 v14] (swap! calls conj [v1 v2 v3 v4 v5 v6 v7 v8 v9 v10 v11 v12 v13 v14]))
+         (invoke [_ v1 v2 v3 v4 v5 v6 v7 v8 v9 v10 v11 v12 v13 v14 v15] (swap! calls conj [v1 v2 v3 v4 v5 v6 v7 v8 v9 v10 v11 v12 v13 v14 v15]))
+         (invoke [_ v1 v2 v3 v4 v5 v6 v7 v8 v9 v10 v11 v12 v13 v14 v15 v16] (swap! calls conj [v1 v2 v3 v4 v5 v6 v7 v8 v9 v10 v11 v12 v13 v14 v15 v16]))
+         (invoke [_ v1 v2 v3 v4 v5 v6 v7 v8 v9 v10 v11 v12 v13 v14 v15 v16 v17] (swap! calls conj [v1 v2 v3 v4 v5 v6 v7 v8 v9 v10 v11 v12 v13 v14 v15 v16 v17]))
+         (invoke [_ v1 v2 v3 v4 v5 v6 v7 v8 v9 v10 v11 v12 v13 v14 v15 v16 v17 v18] (swap! calls conj [v1 v2 v3 v4 v5 v6 v7 v8 v9 v10 v11 v12 v13 v14 v15 v16 v17 v18]))
+         (invoke [_ v1 v2 v3 v4 v5 v6 v7 v8 v9 v10 v11 v12 v13 v14 v15 v16 v17 v18 v19] (swap! calls conj [v1 v2 v3 v4 v5 v6 v7 v8 v9 v10 v11 v12 v13 v14 v15 v16 v17 v18 v19]))
+         (invoke [_ v1 v2 v3 v4 v5 v6 v7 v8 v9 v10 v11 v12 v13 v14 v15 v16 v17 v18 v19 v20] (swap! calls conj [v1 v2 v3 v4 v5 v6 v7 v8 v9 v10 v11 v12 v13 v14 v15 v16 v17 v18 v19 v20])))
+
+       :cljs
+       (reify
+         IDeref
+         (-deref [_] @calls)
+
+         IFn
+         (-invoke [_ v1] (swap! calls conj [v1]))
+         (-invoke [_ v1 v2] (swap! calls conj [v1 v2]))
+         (-invoke [_ v1 v2 v3] (swap! calls conj [v1 v2 v3]))
+         (-invoke [_ v1 v2 v3 v4] (swap! calls conj [v1 v2 v3 v4]))
+         (-invoke [_ v1 v2 v3 v4 v5] (swap! calls conj [v1 v2 v3 v4 v5]))
+         (-invoke [_ v1 v2 v3 v4 v5 v6] (swap! calls conj [v1 v2 v3 v4 v5 v6]))
+         (-invoke [_ v1 v2 v3 v4 v5 v6 v7] (swap! calls conj [v1 v2 v3 v4 v5 v6 v7]))
+         (-invoke [_ v1 v2 v3 v4 v5 v6 v7 v8] (swap! calls conj [v1 v2 v3 v4 v5 v6 v7 v8]))
+         (-invoke [_ v1 v2 v3 v4 v5 v6 v7 v8 v9] (swap! calls conj [v1 v2 v3 v4 v5 v6 v7 v8 v9]))
+         (-invoke [_ v1 v2 v3 v4 v5 v6 v7 v8 v9 v10] (swap! calls conj [v1 v2 v3 v4 v5 v6 v7 v8 v9 v10]))
+         (-invoke [_ v1 v2 v3 v4 v5 v6 v7 v8 v9 v10 v11] (swap! calls conj [v1 v2 v3 v4 v5 v6 v7 v8 v9 v10 v11]))
+         (-invoke [_ v1 v2 v3 v4 v5 v6 v7 v8 v9 v10 v11 v12] (swap! calls conj [v1 v2 v3 v4 v5 v6 v7 v8 v9 v10 v11 v12]))
+         (-invoke [_ v1 v2 v3 v4 v5 v6 v7 v8 v9 v10 v11 v12 v13] (swap! calls conj [v1 v2 v3 v4 v5 v6 v7 v8 v9 v10 v11 v12 v13]))
+         (-invoke [_ v1 v2 v3 v4 v5 v6 v7 v8 v9 v10 v11 v12 v13 v14] (swap! calls conj [v1 v2 v3 v4 v5 v6 v7 v8 v9 v10 v11 v12 v13 v14]))
+         (-invoke [_ v1 v2 v3 v4 v5 v6 v7 v8 v9 v10 v11 v12 v13 v14 v15] (swap! calls conj [v1 v2 v3 v4 v5 v6 v7 v8 v9 v10 v11 v12 v13 v14 v15]))
+         (-invoke [_ v1 v2 v3 v4 v5 v6 v7 v8 v9 v10 v11 v12 v13 v14 v15 v16] (swap! calls conj [v1 v2 v3 v4 v5 v6 v7 v8 v9 v10 v11 v12 v13 v14 v15 v16]))
+         (-invoke [_ v1 v2 v3 v4 v5 v6 v7 v8 v9 v10 v11 v12 v13 v14 v15 v16 v17] (swap! calls conj [v1 v2 v3 v4 v5 v6 v7 v8 v9 v10 v11 v12 v13 v14 v15 v16 v17]))
+         (-invoke [_ v1 v2 v3 v4 v5 v6 v7 v8 v9 v10 v11 v12 v13 v14 v15 v16 v17 v18] (swap! calls conj [v1 v2 v3 v4 v5 v6 v7 v8 v9 v10 v11 v12 v13 v14 v15 v16 v17 v18]))
+         (-invoke [_ v1 v2 v3 v4 v5 v6 v7 v8 v9 v10 v11 v12 v13 v14 v15 v16 v17 v18 v19] (swap! calls conj [v1 v2 v3 v4 v5 v6 v7 v8 v9 v10 v11 v12 v13 v14 v15 v16 v17 v18 v19]))
+         (-invoke [_ v1 v2 v3 v4 v5 v6 v7 v8 v9 v10 v11 v12 v13 v14 v15 v16 v17 v18 v19 v20] (swap! calls conj [v1 v2 v3 v4 v5 v6 v7 v8 v9 v10 v11 v12 v13 v14 v15 v16 v17 v18 v19 v20]))))))


Whitespace

Whitespace

--- test/oxcart/passes/fn_reduction_tests.clj
+++ test/oxcart/passes/fn_reduction_tests.clj
@@ -92,6 +92,4 @@
                  @forms)
                (reduce-fn-arities {})
                (eclj/emit-clojure {})
-               (eval)))))
-
-  )
+               (eval))))))


Fix typo

Fix typo

--- frontend/controllers/controls.cljs
+++ frontend/controllers/controls.cljs
@@ -32,7 +32,7 @@
 (defmulti post-control-event!
   (fn [target message args previous-state current-state] message))

-;; --- Navigation Mutlimethod Implementations ---
+;; --- Navigation Multimethod Implementations ---

 (defmethod control-event :default
   [target message args state]


Make opendata publisher field easier to read

--- search-app/src/cmr/search/results_handlers/opendata_results_handler.clj
+++ search-app/src/cmr/search/results_handlers/opendata_results_handler.clj
@@ -29,17 +29,16 @@

 (def NASA_PUBLISHER_HIERARCHY
   "opendata publisher hierarchy for NASA providers"
-  {:name "National Aeronautics and Space Administration",
-   :subOrganizationOf {
-                       :name "U.S. Government"}})
+  ;; Improve readability by ensuring :name always appears before nested :subOrganizationOf map
+  (sorted-map :name "National Aeronautics and Space Administration",
+              :subOrganizationOf {:name "U.S. Government"}))

 (def USGS_EROS_PUBLISHER_HIERARCHY
   "opendata publisher hierarchy for the USGS_EROS provider"
-  {:name "U.S. Geological Survey",
-   :subOrganizationOf {
-                       :name "U.S. Department of the Interior",
-                       :subOrganizationOf {
-                                           :name "U.S. Government"}}})
+  ;; Improve readability by ensuring :name always appears before nested :subOrganizationOf map
+  (sorted-map :name "U.S. Geological Survey",
+              :subOrganizationOf {:name "U.S. Department of the Interior",
+                                  :subOrganizationOf {:name "U.S. Government"}}))

 (def LANGUAGE_CODE
   "opendata language code for NASA data"


Add regex type to cli options type checker/parser

--- boot/core/src/boot/cli.clj
+++ boot/core/src/boot/cli.clj
@@ -23,6 +23,7 @@
     char  first
     bool  identity
     edn   read-string
+    regex re-pattern
     code  (comp eval read-string)))

 (defn- assert-atom [type]
@@ -35,6 +36,7 @@
     char  char?
     bool  #(contains? #{true false} %)
     edn   (constantly true)
+    regex #(instance? java.util.regex.Pattern %)
     code  (constantly true)))

 (defn- parse-fn [optarg]


boot.util - added without-exiting macro, closes #57

--- boot/pod/src/boot/util.clj
+++ boot/pod/src/boot/util.clj
@@ -157,3 +157,16 @@
     (when-not (= 0 status)
       (throw (Exception. (-> "%s: non-zero exit status (%d)"
                            (format (first args) status)))))))
+
+(defmacro without-exiting
+  "Evaluates body in a context where System/exit doesn't work.
+  Returns result of evaluating body, or nil if code in body attempted to exit."
+  [& body]
+  `(let [old-sm# (System/getSecurityManager)
+         new-sm# (proxy [SecurityManager] []
+                   (checkPermission [p#])
+                   (checkExit [s#] (throw (SecurityException.))))]
+     (System/setSecurityManager ^SecurityManager new-sm#)
+     (try ~@body
+          (catch SecurityException e#)
+          (finally (System/setSecurityManager old-sm#)))))


[CS] korma/values can take a single map as an arg

--- src/vip/data_processor.clj
+++ src/vip/data_processor.clj
@@ -26,9 +26,9 @@
                           (let [result (pipeline/process pipeline message)
                                 filename (:filename result)]
                             (korma/insert psql/results
-                                          (korma/values [{:upload filename
-                                                          :complete true
-                                                          :completed_at (korma/sqlfn now)}])))
+                                          (korma/values {:upload filename
+                                                         :complete true
+                                                         :completed_at (korma/sqlfn now)})))
                           (q/publish {:initial-input message
                                       :status :complete}
                                      "processing.complete"))))


CMR-735: Fixing find-collection-atom-links so if no collection concept ids are passed in it won't try to query elastic.

--- src/cmr/search/results_handlers/atom_links_results_handler.clj
+++ src/cmr/search/results_handlers/atom_links_results_handler.clj
@@ -28,9 +28,11 @@
 (defn find-collection-atom-links
   "Returns a mapping of collection-concept-ids and its atom links for the given collection-concept-ids"
   [context collection-concept-ids]
-  (let [collection-links-query (q/query {:concept-type :collection
-                                         :condition (q/string-conditions :concept-id collection-concept-ids true)
-                                         :page-size :unlimited
-                                         :result-format :atom-links})
-        result (qe/execute-query context collection-links-query)]
-    (into {} (:items result))))
+  (if (seq collection-concept-ids)
+    (let [collection-links-query (q/query {:concept-type :collection
+                                           :condition (q/string-conditions :concept-id collection-concept-ids true)
+                                           :page-size :unlimited
+                                           :result-format :atom-links})
+          result (qe/execute-query context collection-links-query)]
+      (into {} (:items result)))
+    {}))


(PDB-5022) eastwood: ignore supspicious-expressions created by core/match

src/puppetlabs/puppetdb/query_eng/engine.clj:2588:3:
suspicious-expression: and called with 1 args.  (and x) always returns
x.  Perhaps there are misplaced parentheses?

--- eastwood.clj
+++ eastwood.clj
@@ -1,5 +1,5 @@

-;; Alphabetically ordered by :linter
+;; Alphabetically ordered by :linter then :if-inside-macroexpansion-of

 (disable-warning
  {:linter :constant-test
@@ -22,3 +22,14 @@
   :if-inside-macroexpansion-of #{'clojure.core.async/alt!!}
   :within-depth 6 ;; determined experimentally
   :reason "alt!! creates one-armed or expressions"})
+
+;; This is exactly the same as the one built in to eastwood, except
+;; that we raised the :within-depth limit to accomodate some
+;; constructs like those in query-eng.engine.
+(disable-warning
+ {:linter :suspicious-expression
+  ;; specifically, those detected in function suspicious-macro-invocations
+  :for-macro 'clojure.core/and
+  :if-inside-macroexpansion-of #{'clojure.core.match/match}
+  :within-depth 43
+  :reason "Many clojure.core.match/match macro expansions contain expressions of the form (and expr).  This is normal, and probably simplifies the definition of match."})


 (PDB-5186) Replace drop-joins assertions with errors

When the query engine throws an AssertionError, a stack trace is
returned by the API, which is not what we want. And additionally, both
assertions were thrown by drop-joins, which will cause the query to fail
entirely. In one case we only want to skip attempting to drop joins.

The assertion that all projections have a set of `:join-deps` is
protected by the whole query also needing to specify that it
`:can-drop-unused-joins?`, but for `reports` we also assoc additional
projections into the query map from pe-puppetdb. That assoc was missing
a :join-deps key resulting in a query map that said it could drop joins,
but not all projections having a set of join dependencies. Replace that
assertion with an ex-info error that will short-circuit the attempt to
drop unused joins and continue to execute the original query.

The second assertion is that every join in the query map be a keyword.
This is a valid reason to fail the entire query because we specify all
the joins ourselves and anything but a keyword there could result in us
dropping a join we actually need. Replace that assertion with an
IllegalArgumentException that will cause the query to fail, but return
an error message rather than a stack trace.

--- src/puppetlabs/puppetdb/query_eng/engine.clj
+++ src/puppetlabs/puppetdb/query_eng/engine.clj
@@ -2992,7 +2992,13 @@
                       path-or-field))
         required-joins (map #(get-in proj-info [% :join-deps])
                             (map basename fields))]
-    (assert (not-any? nil? required-joins))
+    (when (some nil? required-joins)
+      (throw (ex-info
+              (tru "Could not drop-joins from {0} query. One or more projections were missing :join-deps {1}"
+                   (name (::which-query plan))
+                   (pr-str required-joins))
+              {:kind ::cannot-drop-joins
+               ::why :missing-join-deps-information})))
     (apply set/union required-joins)))

 (defn maybe-drop-unused-joins [{:keys [plan] :as incoming}]
@@ -3042,9 +3048,13 @@
                 need-join? (fn [[table spec]]
                              ;; table e.g. :factsets or [:factsets :fs]
                              ;; spec e.g. [:= :certnames.certname :fs.certname]
-                             (let [name (cond-> table (coll? table) second)]
-                               (assert (keyword? name))
-                               (required? name)))
+                             (let [join-name (cond-> table (coll? table) second)]
+                               (when-not (keyword? join-name)
+                                 (throw (IllegalArgumentException.
+                                         (tru "{0} join in {1} query was expected to be a keyword"
+                                              join-name
+                                              (name (::which-query plan))))))
+                               (required? join-name)))
                 drop-joins (fn [result k v]
                              (if-not (join-key? k)
                                result


Defensive checking for "" as a PARAMx setting (should revert to default)

--- 2-collectors/clojure-collector/src/snowplow/clojure_collector/config.clj
+++ 2-collectors/clojure-collector/src/snowplow/clojure_collector/config.clj
@@ -15,7 +15,8 @@

 (ns snowplow.clojure-collector.config
   "Gets environment variables, using
-   sensible defaults where necessary")
+   sensible defaults where necessary"
+   (:use [clojure.string              :only [blank?]]))

 ;; Note Beanstalk only has 5 'slots' in the UI for Java system properties
 (def ^:const env-varnames ["PARAM1", "SP_ENV"])
@@ -28,6 +29,15 @@
 (def ^:const default-p3p-header "policyref=\"/w3c/p3p.xml\", CP=\"NOI DSP COR NID PSA OUR IND COM NAV STA\"")
 (def ^:const default-duration "365") ; A year

+(defn- get-property-safely
+  "This is required because Beanstalk
+   sends in \"\" for any PARAMx which
+   is not set in the UI. We should
+   replace this with the default"
+  [property default]
+  (let [value (System/getProperty property)]
+    (if (blank? value) default value)))
+
 (defn- get-var
   "Try first option as a Java system
    property, then second option as
@@ -35,7 +45,7 @@
    optional `default` as fallback"
   ([varnames] (get-var varnames nil))
   ([varnames default]
-    (System/getProperty (first varnames)
+    (get-property-safely (first varnames)
       (get (System/getenv) (second varnames)
         default))))


debugger: fix bug - Replay didnt work after Reset

--- examples/_common/middleware/devtools.cljs
+++ examples/_common/middleware/devtools.cljs
@@ -261,8 +261,8 @@

            ::clear
            (-> model
-               (assoc-in [::debugger :signal-events] nil)
-               (assoc-in [::debugger :action-events] nil)
+               (assoc-in [::debugger :signal-events] (list))
+               (assoc-in [::debugger :action-events] (list))
                (assoc-in [::debugger :next-signal-id] 0)
                (assoc-in [::debugger :next-action-id] 0))


autoredeploy in primary color

autoredeploy in primary color

--- src/cljs/swarmpit/component/service/info/settings.cljs
+++ src/cljs/swarmpit/component/service/info/settings.cljs
@@ -130,7 +130,7 @@

 (defn- autoredeploy-label
   [autoredeploy]
-  (when autoredeploy (label/green "autoredeploy")))
+  (when autoredeploy (label/primary "autoredeploy")))

 (rum/defc form < rum/static [service tasks actions]
   (let [image-digest (get-in service [:repository :imageDigest])


fix some unfinished code

fix some unfinished code

--- dada-core/src/main/clojure/org/dada/core/RemoteSessionManager.clj
+++ dada-core/src/main/clojure/org/dada/core/RemoteSessionManager.clj
@@ -74,6 +74,7 @@
   (.state this))

 (defn destroy-session [^Atom sessions ^Session session]
+  ;; TODO - should split sessions into to-keep and to-dstroy and use swap2!
   (swap! sessions (fn [sessions] (remove (fn [s] (= s session)) sessions)))
   (.close session))

@@ -81,7 +82,7 @@
   (with-record
    (immutable this)
    [^Connection connection ^javax.jms.Session jms-session ^ExecutorService thread-pool ^SessionManager peer sessions]
-   (doseq [^Session session @sessions] (.destroy session))
+   (doseq [^Session session @sessions] (destroy-session sessions session))
    (.close ^SynchronousClient (Proxy/getInvocationHandler peer))
    (.shutdown thread-pool)		;TODO: should we be responsible for this ?
    (.close jms-session)


logging and import cleanup in process_request.clj (#822)

* logs backend response status and headers when debug is enabled
cleans up unused imports
makes logs consistently start with lower-case characters

* fix space

--- waiter/src/waiter/process_request.clj
+++ waiter/src/waiter/process_request.clj
@@ -43,7 +43,7 @@
   (:import (java.io ByteArrayOutputStream InputStream IOException)
            (java.nio ByteBuffer)
            (java.util.concurrent LinkedBlockingQueue ThreadPoolExecutor TimeoutException TimeUnit)
-           (javax.servlet ReadListener ServletInputStream ServletOutputStream)
+           (javax.servlet ServletOutputStream)
            (org.eclipse.jetty.client HttpClient)
            (org.eclipse.jetty.io EofException)
            (org.eclipse.jetty.server HttpChannel HttpOutput Response)))
@@ -120,10 +120,10 @@
         (fn [old-value header-value display-name]
           (let [parsed-value (when header-value
                                (try
-                                 (log/info "Request wants to configure" display-name "to" header-value)
+                                 (log/info "request wants to configure" display-name "to" header-value)
                                  (Integer/parseInt (str header-value))
                                  (catch Exception _
-                                   (log/warn "Cannot convert header for" display-name "to an int:" header-value)
+                                   (log/warn "cannot convert header for" display-name "to an int:" header-value)
                                    nil)))]
             (if (and parsed-value (pos? parsed-value)) parsed-value old-value)))]
     (-> instance-request-properties
@@ -154,21 +154,26 @@
                             instance-rpc-chan service-id reason-map start-new-service-fn queue-timeout-ms metric-group))]
       (au/on-chan-close request-state-chan
                         (fn on-request-state-chan-close []
-                          (cid/cdebug correlation-id "request-state-chan closed")
-                          ; assume request did not process successfully if no value in promise
-                          (deliver reservation-status-promise :generic-error)
-                          (let [status @reservation-status-promise]
-                            (cid/cinfo correlation-id "done processing request" status)
-                            (when (= :success status)
-                              (counters/inc! (metrics/service-counter service-id "request-counts" "successful")))
-                            (when (= :generic-error status)
-                              (cid/cerror correlation-id "there was a generic error in processing the request;"
-                                          "if this is a client or server related issue, the code needs to be updated."))
-                            (when (not= :success-async status)
-                              (counters/dec! (metrics/service-counter service-id "request-counts" "outstanding"))
-                              (statsd/gauge-delta! metric-group "request_outstanding" -1))
-                            (service/release-instance-go instance-rpc-chan instance {:status status, :cid correlation-id, :request-id request-id})))
-                        (fn [e] (log/error e "error releasing instance!")))
+                          (cid/with-correlation-id
+                            correlation-id
+                            (log/debug "request-state-chan closed")
+                            ; assume request did not process successfully if no value in promise
+                            (deliver reservation-status-promise :generic-error)
+                            (let [status @reservation-status-promise]
+                              (log/info "done processing request" status)
+                              (when (= :success status)
+                                (counters/inc! (metrics/service-counter service-id "request-counts" "successful")))
+                              (when (= :generic-error status)
+                                (log/error "there was a generic error in processing the request;"
+                                            "if this is a client or server related issue, the code needs to be updated."))
+                              (when (not= :success-async status)
+                                (counters/dec! (metrics/service-counter service-id "request-counts" "outstanding"))
+                                (statsd/gauge-delta! metric-group "request_outstanding" -1))
+                              (service/release-instance-go instance-rpc-chan instance {:status status, :cid correlation-id, :request-id request-id}))))
+                        (fn [e]
+                          (cid/with-correlation-id
+                            correlation-id
+                            (log/error e "error releasing instance!"))))
       instance)))

 (defn- handle-response-error
@@ -364,7 +369,7 @@
           (histograms/update! (metrics/service-histogram service-id "request-content-length") content-length)
           (statsd/inc! metric-group "request_content_length" content-length)))
       (catch Exception e
-        (log/error e "Unable to track content-length on request")))
+        (log/error e "unable to track content-length on request")))
     (when waiter-debug-enabled?
       (log/info "connecting to" instance-endpoint "using" proto-version))
     (let [auth-user-map (handler/make-auth-user-map request)
@@ -449,7 +454,7 @@
                               [bytes-streamed false])))
                         (catch Exception e
                           (histograms/update! (metrics/service-histogram service-id "response-size") bytes-streamed)
-                          (log/error "Error occurred after streaming" bytes-streamed "bytes in response.")
+                          (log/error "error occurred after streaming" bytes-streamed "bytes in response.")
                           ; Handle lower down
                           (throw e)))]
                   (let [bytes-reported-to-statsd'
@@ -472,7 +477,7 @@
               (when-let [output-stream @output-stream-atom]
                 (log/info "invoking poison pill directly on output stream")
                 (poison-pill-function output-stream))))
-          (log/error e "Exception occurred while streaming response for" service-id))
+          (log/error e "exception occurred while streaming response for" service-id))
         (finally
           (async/close! resp-chan)
           (async/close! body)
@@ -507,6 +512,8 @@
   [post-process-async-request-response-fn _ instance-request-properties descriptor instance
    {:keys [uri] :as request} reason-map reservation-status-promise confirm-live-connection-with-abort
    request-state-chan {:keys [status] :as response}]
+  (when (utils/request->debug-enabled? request)
+    (log/info "backend response status:" (:status response) "and headers:" (:headers response)))
   (let [{:keys [service-description service-id]} descriptor
         {:strs [backend-proto blacklist-on-503 metric-group]} service-description
         waiter-debug-enabled? (utils/request->debug-enabled? request)
@@ -666,7 +673,7 @@
             response-map (cond-> {:service-id service-id}
                            time (assoc :suspended-at (du/date-to-str time))
                            (not (str/blank? last-updated-by)) (assoc :last-updated-by last-updated-by))]
-        (log/info "Service has been suspended" response-map)
+        (log/info "service has been suspended" response-map)
         (meters/mark! (metrics/service-meter service-id "response-rate" "error" "suspended"))
         (-> {:details response-map, :message "Service has been suspended", :status 503}
             (utils/data->error-response request)))
@@ -684,7 +691,7 @@
                             :max-queue-length max-queue-length
                             :outstanding-requests outstanding-requests
                             :service-id service-id}]
-          (log/info "Max queue length exceeded" response-map)
+          (log/info "max queue length exceeded" response-map)
           (meters/mark! (metrics/service-meter service-id "response-rate" "error" "queue-length"))
           (-> {:details response-map, :message "Max queue length exceeded", :status 503}
               (utils/data->error-response request)))


Bumping version number

Bumping version number

--- modules/bidi/project.clj
+++ modules/bidi/project.clj
@@ -1,12 +1,12 @@
 ;; Copyright © 2014 JUXT LTD.

-(defproject juxt.modular/bidi "0.7.0"
+(defproject juxt.modular/bidi "0.7.1-SNAPSHOT"
   :description "A modular extension that provides support for bidi routing"
   :url "https://github.com/juxt/modular/tree/master/modules/bidi"
   :license {:name "The MIT License"
             :url "http://opensource.org/licenses/MIT"}
   :dependencies [[com.stuartsierra/component "0.2.1"]
-                 [bidi "1.13.0"]
+                 [bidi "1.14.0-SNAPSHOT"]
                  [juxt.modular/ring "0.5.2"]
                  [prismatic/schema "0.2.1"]
                  [prismatic/plumbing "0.2.2"]]


fix typo

fix typo

--- frontend/components/jobs.cljs
+++ frontend/components/jobs.cljs
@@ -104,7 +104,7 @@
            [:h5 "We'd love to see"]
            [:ul
             [:li
-             "People who have used functional languages in anger (Clojure, Haskell, Scheme, Lisp, Clojure, Scala, OCaml, etc)."]
+             "People who have used functional languages in anger (Clojure, Haskell, Scheme, Lisp, Scala, OCaml, etc)."]
             [:li "If you've built or scaled large distributed systems."]
             [:li "People who love trying new, cutting-edge things."]
             [:li


Remove unwanted spaces

Remove unwanted spaces

--- storm-core/test/clj/backtype/storm/supervisor_test.clj
+++ storm-core/test/clj/backtype/storm/supervisor_test.clj
@@ -355,62 +355,62 @@

 (deftest test-substitute-childopts-happy-path-string
   (testing "worker-launcher replaces ids in childopts"
-    (let [ worker-id "w-01"
-           storm-id "s-01"
-           port 9999
-           childopts "-Xloggc:/home/y/lib/storm/current/logs/gc.worker-%ID%-%STORM-ID%-%WORKER-ID%-%WORKER-PORT%.log -Xms256m"
-           expected-childopts '("-Xloggc:/home/y/lib/storm/current/logs/gc.worker-9999-s-01-w-01-9999.log" "-Xms256m")
-           childopts-with-ids (supervisor/substitute-childopts childopts worker-id storm-id port)]
+    (let [worker-id "w-01"
+          storm-id "s-01"
+          port 9999
+          childopts "-Xloggc:/home/y/lib/storm/current/logs/gc.worker-%ID%-%STORM-ID%-%WORKER-ID%-%WORKER-PORT%.log -Xms256m"
+          expected-childopts '("-Xloggc:/home/y/lib/storm/current/logs/gc.worker-9999-s-01-w-01-9999.log" "-Xms256m")
+          childopts-with-ids (supervisor/substitute-childopts childopts worker-id storm-id port)]
       (is (= expected-childopts childopts-with-ids)))))

 (deftest test-substitute-childopts-happy-path-list
   (testing "worker-launcher replaces ids in childopts"
-    (let [ worker-id "w-01"
-           storm-id "s-01"
-           port 9999
-           childopts '("-Xloggc:/home/y/lib/storm/current/logs/gc.worker-%ID%-%STORM-ID%-%WORKER-ID%-%WORKER-PORT%.log" "-Xms256m")
-           expected-childopts '("-Xloggc:/home/y/lib/storm/current/logs/gc.worker-9999-s-01-w-01-9999.log" "-Xms256m")
-           childopts-with-ids (supervisor/substitute-childopts childopts worker-id storm-id port)]
+    (let [worker-id "w-01"
+          storm-id "s-01"
+          port 9999
+          childopts '("-Xloggc:/home/y/lib/storm/current/logs/gc.worker-%ID%-%STORM-ID%-%WORKER-ID%-%WORKER-PORT%.log" "-Xms256m")
+          expected-childopts '("-Xloggc:/home/y/lib/storm/current/logs/gc.worker-9999-s-01-w-01-9999.log" "-Xms256m")
+          childopts-with-ids (supervisor/substitute-childopts childopts worker-id storm-id port)]
       (is (= expected-childopts childopts-with-ids)))))

 (deftest test-substitute-childopts-storm-id-alone
   (testing "worker-launcher replaces ids in childopts"
-    (let [ worker-id "w-01"
-           storm-id "s-01"
-           port 9999
-           childopts "-Xloggc:/home/y/lib/storm/current/logs/gc.worker-%STORM-ID%.log"
-           expected-childopts '("-Xloggc:/home/y/lib/storm/current/logs/gc.worker-s-01.log")
-           childopts-with-ids (supervisor/substitute-childopts childopts worker-id storm-id port)]
+    (let [worker-id "w-01"
+          storm-id "s-01"
+          port 9999
+          childopts "-Xloggc:/home/y/lib/storm/current/logs/gc.worker-%STORM-ID%.log"
+          expected-childopts '("-Xloggc:/home/y/lib/storm/current/logs/gc.worker-s-01.log")
+          childopts-with-ids (supervisor/substitute-childopts childopts worker-id storm-id port)]
       (is (= expected-childopts childopts-with-ids)))))

 (deftest test-substitute-childopts-no-keys
   (testing "worker-launcher has no ids to replace in childopts"
-    (let [ worker-id "w-01"
-           storm-id "s-01"
-           port 9999
-           childopts "-Xloggc:/home/y/lib/storm/current/logs/gc.worker.log"
-           expected-childopts '("-Xloggc:/home/y/lib/storm/current/logs/gc.worker.log")
-           childopts-with-ids (supervisor/substitute-childopts childopts worker-id storm-id port)]
+    (let [worker-id "w-01"
+          storm-id "s-01"
+          port 9999
+          childopts "-Xloggc:/home/y/lib/storm/current/logs/gc.worker.log"
+          expected-childopts '("-Xloggc:/home/y/lib/storm/current/logs/gc.worker.log")
+          childopts-with-ids (supervisor/substitute-childopts childopts worker-id storm-id port)]
       (is (= expected-childopts childopts-with-ids)))))

 (deftest test-substitute-childopts-nil-childopts
   (testing "worker-launcher has nil childopts"
-    (let [ worker-id "w-01"
-           storm-id "s-01"
-           port 9999
-           childopts nil
-           expected-childopts nil
-           childopts-with-ids (supervisor/substitute-childopts childopts worker-id storm-id port)]
+    (let [worker-id "w-01"
+          storm-id "s-01"
+          port 9999
+          childopts nil
+          expected-childopts nil
+          childopts-with-ids (supervisor/substitute-childopts childopts worker-id storm-id port)]
       (is (= expected-childopts childopts-with-ids)))))

 (deftest test-substitute-childopts-nil-ids
   (testing "worker-launcher has nil ids"
-    (let [ worker-id nil
-           storm-id "s-01"
-           port 9999
-           childopts "-Xloggc:/home/y/lib/storm/current/logs/gc.worker-%ID%-%STORM-ID%-%WORKER-ID%-%WORKER-PORT%.log"
-           expected-childopts '("-Xloggc:/home/y/lib/storm/current/logs/gc.worker-9999-s-01--9999.log")
-           childopts-with-ids (supervisor/substitute-childopts childopts worker-id storm-id port)]
+    (let [worker-id nil
+          storm-id "s-01"
+          port 9999
+          childopts "-Xloggc:/home/y/lib/storm/current/logs/gc.worker-%ID%-%STORM-ID%-%WORKER-ID%-%WORKER-PORT%.log"
+          expected-childopts '("-Xloggc:/home/y/lib/storm/current/logs/gc.worker-9999-s-01--9999.log")
+          childopts-with-ids (supervisor/substitute-childopts childopts worker-id storm-id port)]
       (is (= expected-childopts childopts-with-ids)))))

 (deftest test-retry-read-assignments


Adding broke declare-decorator

Adding broke declare-decorator

Adding broke declare-decorator so I can work on it somewhere else
tomorrow

--- src/hyjinks.clj
+++ src/hyjinks.clj
@@ -159,6 +159,14 @@
 ;;     (center some-tag)
 ;;     (color :red some-tag)

+(defn declare-decorator [dec-name & props]
+	(let [params (filter symbol? props)
+	      fixedValues (apply merge {} (filter map? props))
+	      args (apply hash-map (apply concat (map (fn [x] [(keyword x) (symbol x)]) params)))]
+		(eval `(defn ~dec-name
+			([~@params] (new-css ~@args))
+			([~@params tag#] (assoc-css tag# ~@args))))))
+
 (defn hide
 	([] (new-css :display "none"))
 	([tag] (assoc-css tag :display "none")))


Use schemas to check storm config/proof-of-concept

--- storm-core/src/clj/backtype/storm/config.clj
+++ storm-core/src/clj/backtype/storm/config.clj
@@ -1,6 +1,6 @@
 (ns backtype.storm.config
   (:import [java.io FileReader File])
-  (:import [backtype.storm Config])
+  (:import [backtype.storm Config Config$FieldValidator])
   (:import [backtype.storm.utils Utils LocalState])
   (:import [org.apache.commons.io FileUtils])
   (:require [clojure [string :as str]])
@@ -24,6 +24,24 @@
   (dofor [f (seq (.getFields Config))]
          (.get f nil)
          ))
+
+;; Create a mapping of config-string -> validator
+;; Config fields must have a _SCHEMA field defined
+(def CONFIG-SCHEMA-MAP
+  (reduce (fn [mp [k v]] (assoc mp k v)) {}
+    (for [f (seq (.getFields Config))
+      :when (not (re-matches #".*_SCHEMA$" (.getName f)))
+      :let [k (.get f nil)
+            nam (.getName f)
+            field-to-get (str/replace nam #"$" "_SCHEMA")
+;            _ (println (str "Trying to set " k " to " field-to-get " value"))
+            v (-> Config (.getField field-to-get) (.get nil))
+;            _ (println (str "and value was " v ))
+            ]]
+      [k v]
+    )
+  )
+)

 (defn cluster-mode [conf & args]
   (keyword (conf STORM-CLUSTER-MODE)))
@@ -62,11 +80,40 @@
 (defn read-default-config []
   (clojurify-structure (Utils/readDefaultConfig)))

+(defn- validate-configs-with-schemas [conf]
+  (doseq [[k v] conf
+         :let [_ (println (str "trying to validate" [k v]))
+               _ (println (str "schema is (" (get CONFIG-SCHEMA-MAP k) ")"))
+               schema (get CONFIG-SCHEMA-MAP k)]]
+    (if (instance? Config$FieldValidator schema)
+      (if (and (not (nil? v))
+               (not (.validateField schema v)))
+        (throw (IllegalArgumentException.
+                 (str "'" k "' " (.getCriteriaPredicate schema))))
+        (println (str "OK: " k " " (.getCriteriaPredicate schema)))
+      )
+      (do
+        (println "schema is (" schema ")")
+        (println "v is " v)
+        (if (and (not (instance? schema v))
+                 (not (nil? v)))
+          (throw (IllegalArgumentException.
+                   (str "'" k "' must be a '" (.getName schema) "'")))
+          (println (str "OK: " k " was a " (.getName schema)))
+        )
+      )
+    )))
+
+
 (defn read-storm-config []
-  (clojurify-structure (Utils/readStormConfig)))
+  (let [conf (clojurify-structure (Utils/readStormConfig))]
+    (validate-configs-with-schemas conf)
+    conf))

 (defn read-yaml-config [name]
-  (clojurify-structure (Utils/findAndReadConfigFile name true)))
+  (let [conf (clojurify-structure (Utils/findAndReadConfigFile name true))]
+    (validate-configs-with-schemas conf)
+    conf))

 (defn master-local-dir [conf]
   (let [ret (str (conf STORM-LOCAL-DIR) "/nimbus")]


Untested, replaced fn + for + at by clone-for

--- src/seajure.clj
+++ src/seajure.clj
@@ -1,5 +1,5 @@
 (ns seajure
-  (:use [net.cgrand.enlive-html :only [deftemplate content set-attr do-> at]]
+  (:use [net.cgrand.enlive-html :only [deftemplate content set-attr do-> clone-for]]
         [clj.io :only [spit copy file]]))

 (def assets ["style.css" "logo.png"])
@@ -13,30 +13,23 @@
       (java.io.PushbackReader.)
       (read)))

-;; TODO: I'm just happy to get this to output correctly; I'm sure it's
-;; very unidiomatic Enlive usage. Fix it once Enlive gets docs. =\
+;; Enlive hasn't more docs yet :-( but here I fixed it:
 (defn member-project-links [projects]
-  (fn [matched]
-    (for [p projects]
-      (at matched [:a] (do-> (content (name p))
-                             (set-attr :href (str "#" p)))))))
+  (clone-for [p projects]
+    [:a] (do-> (content (name p)) (set-attr :href (str "#" p)))))

 (defn member-links [members]
-  (fn [matched]
-    (for [{:keys [name url projects]} members]
-      (at matched
-          [:li :a] (do-> (content name)
-                         (set-attr :href url))
-          [:li :span] (member-project-links projects)))))
+  (clone-for [{:keys [name url projects]} members]
+    [:li :a] (do-> (content name)
+               (set-attr :href url))
+    [:li :span] (member-project-links projects)))

 (defn project-links [projects]
-  (fn [matched]
-    (for [[anchor {:keys [name url description]}] projects]
-      (at matched
-          [:dt :a] (do-> (content name)
-                         (set-attr :name anchor)
-                         (set-attr :href url))
-          [:dd] (content description)))))
+  (clone-for [[anchor {:keys [name url description]}] projects]
+    [:dt :a] (do-> (content name)
+               (set-attr :name anchor)
+               (set-attr :href url))
+    [:dd] (content description)))

 (deftemplate index "index.html" [members projects]
   [:ul.members] (member-links members)


Load CLJS builtins in the test-core namespace

--- tests/test_core.cljx
+++ tests/test_core.cljx
@@ -1,7 +1,8 @@
 (ns test-core
   #+cljs
   (:require [cats.core :as m]
-            [cats.monad.maybe :as maybe])
+            [cats.monad.maybe :as maybe]
+            [cats.builtin :refer :all])
   #+cljs
   (:require-macros [cemerick.cljs.test
                     :refer (is deftest with-test run-tests testing test-var)]


request failures on workflow detail page (#1464)

--- src/cljs/main/broadfcui/page/workspace/monitor/workflow_details.cljs
+++ src/cljs/main/broadfcui/page/workspace/monitor/workflow_details.cljs
@@ -33,7 +33,7 @@
                                     :link-label link-label)]
      (str gcs-uri))))

-(defonce default-metadata-includes ["backendLogs" "backendStatus" "end" "executionStatus" "callCaching:hit"
+(defonce default-metadata-includes ["backendLogs" "backendStatus" "end" "executionStatus" "callCaching:hit" "failures"
                                     "id" "inputs" "jobId" "outputs" "start" "status" "stderr" "stdout" "submission"
                                     "submittedFiles:inputs" "workflowLog" "workflowName" "workflowRoot"])


remove _parent_ as a parameter to lightning-bolt

--- src/babel/forest.cljc
+++ src/babel/forest.cljc
@@ -63,13 +63,12 @@
                           (generate-all (rest spec) grammar lexicon index morph))
                 true
                 (do
-                  (log/debug (str "generate-all with semantics: " (show-spec (remove-false (get-in spec [:synsem :sem])))))
-                  (log/debug (str "generate-all with spec: " (strip-refs spec)))
-                  (log/debug (str "generate-all with pred: " (show-spec (remove-false (get-in spec [:synsem :sem :pred])))))
-                  (log/debug (str "generate-all(details): " (show-spec spec)))
+                  (log/debug (str "generate-all: (spec= " (strip-refs spec) ")"))
+                  (log/trace (str "generate-all with pred: " (show-spec (remove-false (get-in spec [:synsem :sem :pred])))))
+                  (log/trace (str "generate-all(details): " (show-spec spec)))
                   (let [lb (lightning-bolt (lazy-shuffle grammar)
                                            lexicon
-                                           spec 0 index nil morph)
+                                           spec 0 index morph)
                         add-complements-to-bolts
                         (fn [bolts path]
                           (mapcat #(add-complement % path :top grammar lexicon index morph)
@@ -88,71 +87,47 @@
     result))

 ;; TODO: add usage of rule-to-lexicon cache (rather than using lexicon directly)
-(defn lightning-bolt [grammar lexicon spec & [ depth index parent morph]]
+(defn lightning-bolt [grammar lexicon spec & [ depth index morph]]
   "Returns a lazy-sequence of all possible trees given a spec, where
 there is only one child for each parent, and that single child is the
 head of its parent. generate (above) 'decorates' each returned lightning bolt
 of this function with complements."
-  (if (empty? grammar)
-    (do
-      (log/error (str "grammar is empty."))
-      (exception (str "grammar is empty."))))
-
-  (if (and (not (= :fail spec))
-           (not (= :top spec))
-           (not (empty? (strip-refs spec))))
-    (do
-      (log/debug (str "lightning-bolt@" depth))
-      (log/trace (str "lighting-bolt spec: " (strip-refs spec) "; parent: " (if parent
-                                                                              (:rule parent))))))
-  (if (not parent)
-    (log/debug (str "no parent for lightning-bolt@" depth " with spec: " (strip-refs spec))))
+  (log/debug (str "lightning-bolt@" depth " with spec: " (strip-refs spec)))
   (let [maxdepth 3 ;; maximum depth of a lightning bolt: H1 -> H2 -> H3 where H3 must be a lexeme, not a phrase.
+        morph (if morph morph (fn [input] (get-in input [:rule] :default-morph-no-rule)))
         debug (log/trace (str "lightning-bolt@" depth " grammar:" (string/join ", " (map #(get-in % [:rule]) grammar))))
         depth (if depth depth 0)
-        debug (if parent (log/debug (str "looking for candidate head phrases with parent: " (:rule parent))))
-
         candidate-heads (filter #(not (fail? %))
-                                  (map (fn [rule]
-                                         (do (log/trace (str "testing rule: " (:rule rule)
-                                                             "with cat:" (get-in rule [:synsem :cat])))
-                                             (unifyc spec rule)))
-                                       (if parent
-                                         (let [hp (get-head-phrases-of parent index)]
-                                           (log/debug (str "getting head-phrases: hp count:" (count hp)))
-                                           hp)
-                                         (do
-                                           (log/debug (str "not getting head phrases: using grammar"))
-                                           grammar))))
-
+                                (map (fn [rule]
+                                       (do (log/trace (str "testing rule: " (:rule rule)
+                                                           "whose [:synsem :cat] is:" (get-in rule [:synsem :cat])
+                                                           "for candidate as a phrasal head."))
+                                           (unifyc spec rule)))
+                                     grammar))
         debug (log/trace (str "done looking for candidate head phrases: "
                               (if (empty? candidate-heads)
                                 "no candidate heads found."
                                 (str "one or more candidate heads found; first: " (:rule (first candidate-heads))))))
-
         debug (if (not (empty? candidate-heads))
                 (log/debug (str "candidate-heads: " (string/join "," (map #(get-in % [:rule])
-                                                                            candidate-heads))))
+                                                                          candidate-heads))))
                 (log/trace (str "no candidate head phrases for spec: " (strip-refs spec))))]
-    ;; TODO: remove or parameterize this hard-coded value.
-    (if (> depth 5)
-      (throw (exception (str "depth is greater than 5: should never happen."))))
-
     (if (seq candidate-heads)
       (let [lexical ;; 1. generate list of all phrases where the head child of each parent is a lexeme.
             (mapcat (fn [parent]
                       (if (= false (get-in parent [:head :phrasal] false))
                         (let [candidate-lexemes (get-lex parent :head index spec)]
-                          (log/debug (str "candidate lexemes for: " (get-in parent [:rule]) ":" (count candidate-lexemes)))
+                          (log/debug (str "candidate lexemes for: " (get-in parent [:rule]) " empty?:" (empty? candidate-lexemes)))
                           (if (some fail? candidate-lexemes)
                             (throw (exception (str "some candidate lexeme was fail?=true!"))))
                           (log/debug
                            (str "candidate head lexemes for parent phrase "
-                                (get-in parent [:rule]) ": "
-                                (string/join ","
+                                (get-in parent [:rule]) ": '"
+                                (string/join "','"
                                              (map (fn [lexeme]
                                                     (morph lexeme))
-                                                  candidate-lexemes))))
+                                                  candidate-lexemes))
+                                "'"))
                           (let [result
                                 (if (empty? candidate-lexemes)
                                   (if (= false (get-in parent [:head :phrasal] true))
@@ -161,17 +136,15 @@
                                               (map copy (lazy-shuffle candidate-lexemes))
                                               morph))]
                             (if (not (empty? result))
-                              (log/debug (str "successful results of attaching head lexemes to: " (get-in parent [:rule]) ":"
-                                              (string/join ","
-                                                           (map #(morph %1)
-                                                                result))))
+                              (log/debug (str "first successful result of attaching head lexemes to: " (get-in parent [:rule]) ":"
+                                              (morph (first result))))
                               (if (not (empty? candidate-lexemes))
                                 (log/warn (str "all " (count candidate-lexemes) " candidate lexeme(s):"
                                                (string/join ","
                                                             (sort (map morph candidate-lexemes)))
                                                " failed for parent: " (get-in parent [:rule]) " with spec: " (strip-refs spec)))))
                             result))))
-                    candidate-heads)
+                    (remove nil? candidate-heads))

             ;; TODO: throw exception if (get-in parent [:head]) is null.
             phrasal ;; 2. generate list of all phrases where the head child of each parent is itself a phrase.
@@ -195,9 +168,7 @@
                               (over/overh parent phrasal-children morph)))
                           )
                         )
-                       candidate-heads))]
-        (log/debug (str "lightning-bolt: #lexical children of " (get-in parent [:rule]) ":" (count lexical)))
-        (log/debug (str "lightning-bolt: #phrasal children of " (get-in parent [:rule]) ":" (count phrasal)))
+                       (remove nil? candidate-heads)))]
         (if (lexemes-before-phrases)
           (lazy-cat lexical phrasal)
           (lazy-cat phrasal lexical))))))
@@ -263,7 +234,7 @@
                                                  (fail-path-between (strip-refs (get-in bolt path))
                                                                     (strip-refs complement))))

-                                 (log/debug (str "success:" (:rule result) " returning: " (morph result))))
+                                 (log/debug (str "success:" (:rule result) " returning: '" (morph result) "'")))

                                (if is-fail? :fail result)))


enable babel.test.en

enable babel.test.en

--- src/babel/runner.cljc
+++ src/babel/runner.cljc
@@ -3,7 +3,8 @@
             [babel.core]))

 #?(:cljs (doo-tests 'babel.test.pos))
-;;#?(:cljs (doo-tests 'babel.test.en))
+#?(:cljs (doo-tests 'babel.test.en))
+;;#?(:cljs (doo-all-tests))


debug

debug

--- src/ci3/repo/core.clj
+++ src/ci3/repo/core.clj
@@ -4,14 +4,16 @@
             [ci3.repo.bitbucket :as bitbucket]
             [ci3.repo.github :as github]
             [ci3.k8s :as k8s]
-            [unifn.core :as u]))
+            [unifn.core :as u]
+            [clojure.tools.logging :as log]))

 (defmethod u/*fn
   ::load-repo
   [{cfg :k8s :as arg}]
+  (log/info "CONFIG" cfg)
   (let [repo-id (get-in arg [:request :route-params :id])
         repo (k8s/find cfg :repositories repo-id)]
-    (println repo)
+    (log/info repo)
     (if (or (nil? repo)
             (= "Failure" (:status repo)))
       {::u/status :error
@@ -22,6 +24,7 @@
   ::catch-errors
   [{error ::u/message}]
   (when error
+    (log/error error)
     {:response {:status 400
                 :body error}}))
 (defmethod u/*fn


All grown up now, less noisy prompt

All grown up now, less noisy prompt

--- src/clj/cljs/repl.clj
+++ src/clj/cljs/repl.clj
@@ -679,7 +679,7 @@
   (println "To quit, type:" :cljs/quit))

 (defn repl-prompt []
-  (print (str "ClojureScript:" ana/*cljs-ns* "> ")))
+  (print (str ana/*cljs-ns* "=> ")))

 (defn repl-caught [e repl-env opts]
   (if (and (instance? IExceptionInfo e)


remove unused.

remove unused.

--- src/clj/game/core.clj
+++ src/clj/game/core.clj
@@ -658,7 +658,7 @@
   ([state side type n {:keys [unpreventable unboostable card] :as args}]
     (swap! state update-in [:damage :damage-bonus] dissoc type)
     (swap! state update-in [:damage :damage-prevent] dissoc type)
-    (trigger-event state side :pre-damage type card n)
+    (trigger-event state side :pre-damage type card)
     (let [n (damage-count state side type n args)]
          (let [prevent (get-in @state [:prevent :damage type])]
               (if (and (not unpreventable) prevent (> (count prevent) 0))


added log message to ressource trashing by the Corp

--- src/clj/game/core.clj
+++ src/clj/game/core.clj
@@ -604,7 +604,9 @@
     (resolve-ability state side
                      {:prompt "Choose a resource to trash"
                       :choices {:req #(= (:type %) "Resource")}
-                      :effect (effect (trash target))} nil nil)))
+                      :effect (effect (trash target)
+                                      (system-msg (str "spends [Click] and 2 [Credits] to trash "
+                                                       (:title target))))} nil nil)))

 (defn trash-prevent [state side type n]
   (swap! state update-in [:trash :trash-prevent type] (fnil #(+ % n) 0)))


bugfix: local-day takes a time, not a string

--- src/clj/tictag/db.clj
+++ src/clj/tictag/db.clj
@@ -3,6 +3,7 @@
             [taoensso.timbre :as timbre]
             [clj-time.jdbc]
             [clj-time.coerce :as coerce]
+            [clj-time.format :as f]
             [clojure.string :as str]
             [clojure.edn :as edn]
             [clojure.data.csv :as csv]
@@ -67,7 +68,8 @@
 (defn pending-timestamp [{:keys [pends]} id]
   (second (first (filter #(= (first %) id) @pends))))

-(defn local-day [local-time] (str/replace (subs local-time 0 10) #"-" ""))
+(def ymd (f/formatter "yyyyMMdd"))
+(defn local-day [local-time] (f/unparse ymd local-time))

 (defn to-ping [{:keys [local_time ts tags user_id]}]
   {:tags              (set (map keyword (str/split tags #" ")))


(maint) Merge branch '2.x' into 'master'

--- src/puppetlabs/trapperkeeper/services/webserver/jetty9_core.clj
+++ src/puppetlabs/trapperkeeper/services/webserver/jetty9_core.clj
@@ -738,6 +738,7 @@
         (normalized-uri-helpers/handler-maybe-wrapped-with-normalized-uri
          (ring-handler handler)
          normalize-request-uri?)
+        path (if (= "" path) "/" path)
         ctxt-handler (doto (ContextHandler. path)
                        (.setHandler handler))]
     (add-handler webserver-context ctxt-handler enable-trailing-slash-redirect?)))


Unbreak domain mode

Unbreak domain mode

--- support/build-support/src/main/clojure/immutant/build/tools.clj
+++ support/build-support/src/main/clojure/immutant/build/tools.clj
@@ -500,7 +500,8 @@
        acc))
    #{}
    ["standalone/configuration/standalone.xml"
-    "standalone/configuration/standalone-ha.xml"]))
+    "standalone/configuration/standalone-ha.xml"
+    "domain/configuration/domain.xml"]))

 (defn slim-modules []
   (let [all-modules (extract-all-module-deps (jboss-dir))
@@ -508,6 +509,7 @@
                              (conj
                               ;; add a few modules that aren't mentioned in any config,
                               ;; but are required at runtime
+                              "org.jboss.as.host-controller"
                               "org.jboss.as.standalone"
                               "org.jboss.as.domain-http-error-context"
                               "com.h2database.h2"
@@ -524,7 +526,7 @@
                 "bin/appclient.conf" "bin/appclient.sh" "bin/client"
                 "bin/jconsole.bat" "bin/jconsole.sh" "bin/jdr.bat" "bin/jdr.sh"
                 "bin/wsconsume.bat" "bin/wsconsome.sh" "bin/wsprovide.bat" "bin/wsprovide.sh"
-                "bundles" "docs/examples" "docs/schema" "domain" "welcome-content"]]
+                "bundles" "docs/examples" "docs/schema" "welcome-content"]]
     (let [f (io/file (jboss-dir) path)]
       (with-message (str"Deleting " path)
         (if (.isDirectory f)


Update EDN converter examples

Update EDN converter examples

--- src-docs/com/wsscode/pathom/book/graphql/edn_converter.cljs
+++ src-docs/com/wsscode/pathom/book/graphql/edn_converter.cljs
@@ -12,11 +12,7 @@
     [fulcro.client.primitives :as fp]
     [garden.selectors :as gs]
     [com.wsscode.pathom.viz.codemirror :as pcm]
-    [goog.object :as gobj]
-    [goog.string :as gstr]))
-
-(defn js-name [s]
-  (gstr/toCamelCase (name s)))
+    [goog.object :as gobj]))

 (defn pretty-print-string [x]
   (str/replace (with-out-str (cljs.pprint/pprint x))
@@ -27,7 +23,7 @@
     (let [gql (try
                 (let [gql (-> om-next-query
                               read-string
-                              (gql/query->graphql {::gql/js-name js-name}))]
+                              (gql/query->graphql))]
                   (swap! state assoc-in (conj ref :ui/translate-error?) false)
                   gql)
                 (catch :default _
@@ -83,15 +79,17 @@
                                         ["Join" [{:app/me [:user/id :user/name]}]]
                                         ["Ident" [{[:user/login "wilkerlucio"] [:bio :url]}
                                                   {[:organization/login "clojure"] [:name :url]}
-                                                  {[:github.repository/name-and-owner ["pathom" "wilkerlucio"]] [:id :name]}]]
-                                        ["Join Parameters" [{(:app/all-users {:limit 10})
+                                                  {[:github.repository/nameAndowner ["pathom" "wilkerlucio"]] [:id :name]}]]
+                                        ["Join Parameters" [{(:app/allUsers {:limit 10})
                                                              [:user/id :user/name]}]]
+                                        ["Aliases" [{(:property {::gql/alias "aliased" :another "param"})
+                                                     [:subquery]}]]
                                         ["Enums" [{:viewer
-                                                   [{(:starred-repositories {:first    10
-                                                                             :order-by {:field     STARRED_AT
+                                                   [{(:starredRepositories {:first   10
+                                                                            :orderBy {:field       STARRED_AT
                                                                                :direction DESC}})
                                                      [{:nodes
-                                                       [:id :name :updated-at]}]}]}]]
+                                                       [:id :name :updatedAt]}]}]}]]
                                         ["Union" [{:app/timeline
                                                    {:app/User     [:user/id :user/name]
                                                     :app/Activity [:activity/id :activity/title
@@ -105,7 +103,7 @@
                                         ["Recursive queries" [{:type
                                                                [:kind :name {:ofType 3}]}]]
                                         ["Mutation" [{(users/create {:user/id 123 :user/name "Foo"})
-                                                      [:client-mutation-id]}]]]
+                                                      [:clientMutationId]}]]]
                      ::translator     (fp/get-initial-state GraphQlQueryTranslator params)})
    :ident         [::id ::id]
    :query         [::id ::query-examples


Fix transposition error

Fix transposition error

--- src/eulalie/creds.clj
+++ src/eulalie/creds.clj
@@ -23,12 +23,12 @@
   retrieved from retrieval-fn, scheduling the next invocation just prior to
   expiry.  On error, the exception will be written to the output channel before
   closing.  Closing the output channel will terminate early."
-  [retrieval-fn {:keys [expiration] :as initial-creds} & [{:keys [out-chan]}]]
+  [{:keys [expiration] :as initial-creds} retrieval-fn & [{:keys [out-chan]}]]
   (let [out-chan (or out-chan (async/chan))
         now      (System/currentTimeMillis)
         loop-chan
         (go-catching
-          (when (and expiration (< expiration now))
+          (when expiration
             (<! (creds-timeout-chan expiration now)))
           (loop []
             (let [{:keys [expiration] :as creds} (<? (retrieval-fn))


add cimi-params middleware to the application

--- ssclj/jar/src/main/clojure/com/sixsq/slipstream/ssclj/app/server.clj
+++ ssclj/jar/src/main/clojure/com/sixsq/slipstream/ssclj/app/server.clj
@@ -12,6 +12,7 @@
     [com.sixsq.slipstream.ssclj.middleware.base-uri                 :refer [wrap-base-uri]]
     [com.sixsq.slipstream.ssclj.middleware.exception-handler        :refer [wrap-exceptions]]
     [com.sixsq.slipstream.ssclj.middleware.authn-info-header        :refer [wrap-authn-info-header]]
+    [com.sixsq.slipstream.ssclj.middleware.cimi-params              :refer [wrap-cimi-params]]
     [com.sixsq.slipstream.ssclj.app.routes                          :as routes]
     [com.sixsq.slipstream.ssclj.resources.root                      :as root]
     [com.sixsq.slipstream.ssclj.db.impl                             :as db]
@@ -21,7 +22,7 @@

 ;; FIXME: make this dynamic depending on the service configuration
 (defn set-db-impl
-  []
+  []
   ; (-> (fsdb/get-instance fsdb/default-db-prefix)
   ;     (db/set-impl!)))
   (db/set-impl! (dbdb/get-instance)))
@@ -46,6 +47,7 @@
   (-> (routes/get-main-routes)
       handler/site
       wrap-exceptions
+      wrap-cimi-params
       wrap-base-uri
       wrap-params
       wrap-authn-info-header


Remove some config settings that do not need to be there.

--- metlog-agent/config.clj
+++ metlog-agent/config.clj
@@ -112,42 +112,3 @@
     (throw (Exception. "test failure"))
     (Math/random)))

-;; OC
-;; http https://api.darksky.net/forecast/587a8fa1a383bafeeef406acf12fb98a/39.2776,-74.5746\?exclude=minutely,hourly,daily,alerts,flags
-
-;; Wynnewood
-;; http https://api.darksky.net/forecast/587a8fa1a383bafeeef406acf12fb98a/39.9996,-75.2730\?exclude=minutely,hourly,daily,alerts,flags
-
-(def darksky-api-key "587a8fa1a383bafeeef406acf12fb98a")
-
-(def darksky-19096 "39.9996,-75.2730")
-(def darksky-08226 "39.2776,-74.5746")
-
-(defn request-json [ url ]
-  (let [response (http/get url)
-        body (safe-json-read-str (:body response))]
-    (and (= 200 (:status response))
-         body)))
-
-(defn read-darksky [ key location ]
-  (let [body (request-json (str "https://api.darksky.net/forecast/" key "/" location "?exclude=minutely,hourly,daily,alerts,flags"))]
-    (and body
-         (let [obv (get body "currently")]
-           {:temp-f (ensure-number (get obv "temperature" false))
-            :apparent-temp-f (ensure-number (get obv "apparentTemperature" false))
-            :dew-point-f (ensure-number (get obv "dewPoint" false))
-            :humidity (ensure-number (get obv "humidity" false))
-            :ozone (ensure-number (get obv "ozone" false))
-            :precip-intensity (ensure-number (get obv "precipIntensity" false))
-            :precip-probability (ensure-number (get obv "precipProbability" false))
-            :pressure (ensure-number (get obv "pressure" false))
-            :uv-index (ensure-number (get obv "uvIndex" false))
-            :wind-bearing (ensure-number (get obv "windBearing" false))
-            :wind-gust (ensure-number (get obv "windGust" false))
-            :wind-speed (ensure-number (get obv "windSpeed" false))}))))
-
-(defsensor "darksky-19096" {:poll-interval (minutes 15)}
-  (read-darksky darksky-api-key darksky-19096))
-
-(defsensor "darksky-08226" {:poll-interval (minutes 15)}
-  (read-darksky darksky-api-key darksky-08226))


passthrough gh routes

passthrough gh routes

--- src/frontend/core.clj
+++ src/frontend/core.clj
@@ -49,6 +49,7 @@
   {:patterns [#"/"
               #"/changelog.rss"
               #"/logout"
+              #"/gh/.*"
               #"/auth/.*"
               #"/api/.*"]
    :backends {"dev.circlehost" {:proto "http" :host "circlehost:8080"}


Typo.

Typo.

--- test/carmine/test/core.clj
+++ test/carmine/test/core.clj
@@ -66,7 +66,7 @@
   (is (= "OK" (wc (r/set "spanish" "year->año"))))
   (is (= "year->año" (wc (r/get "spanish")))))

-;; Deprecated as of 0.8.4 due to auto-serialization
+;; Deprecated as of 0.8.1 due to auto-serialization
 ;; (deftest test-non-string-params
 ;;   (is (= "OK" (wc (r/set "statement" "I am doing well"))))
 ;;   (is (= "doing well" (wc (r/getrange "statement" 5 14))))


Rename

Rename

--- test/clotify/core_test.clj
+++ test/clotify/core_test.clj
@@ -1,7 +0,0 @@
-(ns clotify.core-test
-  (:require [clojure.test :refer :all]
-            [clotify.core :refer :all]))
-
-(deftest a-test
-  (testing "FIXME, I fail."
-    (is (= 0 1))))


Don't recreate token form each time

Don't recreate token form each time

Previously, the form would be destroyed and re-created each time the
access token was submitted and failed. Use a single form instead, and
hide / show it when needed.

--- src/gitique/core.cljs
+++ src/gitique/core.cljs
@@ -151,35 +151,39 @@
         new-token (.-value (util/qs "input" element))]
     (js/localStorage.setItem token-key new-token)
     (get-new-commits! url)
-    (.removeChild (.-parentElement element) element)
+    (.add (.-classList element) "gitique-hidden")
     (.preventDefault event)
     (.stopPropagation event)))

 (defn- request-token! [url]
-  (let [parent (util/qs "#toc")
-        sibling (util/qs "#toc .toc-diff-stats")
-        current-token (js/localStorage.getItem token-key)
-        input (dom/createDom "input" #js{:type "text"
-                                         :length 50
-                                         :value current-token
-                                         :placeholder "Access token"
-                                         :class (when (> (count current-token) 1) "error")})
-        needs-repo? (util/qs ".repo-private-label")
-        token-link (dom/createDom
-                    "a"
-                    #js{:href "https://help.github.com/articles/creating-an-access-token-for-command-line-use/"}
-                    "access token")
-        explanation (dom/createDom
-                     "span"
-                     nil
-                     "Please enter an " token-link (when needs-repo? " with repo scope") ": ")
-        wrapper (dom/createDom
-                 "form"
-                 #js{:class "right gitique-header-wrapper"}
-                 explanation input)]
-    (.addEventListener input "input" #(.remove (.-classList (.-target %)) "error"))
-    (.addEventListener wrapper "submit" (partial update-token! url))
-    (.insertBefore parent wrapper sibling)))
+  (if-let [token-form (util/qs "#gitique-token-request")]
+    (do
+      (.remove (.-classList token-form) "gitique-hidden")
+      (.add (.-classList (util/qs "input" token-form)) "error"))
+    (let [parent (util/qs "#toc")
+          sibling (util/qs "#toc .toc-diff-stats")
+          current-token (js/localStorage.getItem token-key)
+          input (dom/createDom "input" #js{:type "text"
+                                           :length 50
+                                           :value current-token
+                                           :placeholder "Access token"
+                                           :class (when (> (count current-token) 1) "error")})
+          needs-repo? (util/qs ".repo-private-label")
+          token-link (dom/createDom
+                      "a"
+                      #js{:href "https://help.github.com/articles/creating-an-access-token-for-command-line-use/"}
+                      "access token")
+          explanation (dom/createDom
+                       "span"
+                       nil
+                       "Please enter an " token-link (when needs-repo? " with repo scope") ": ")
+          wrapper (dom/createDom
+                   "form"
+                   #js{:class "right gitique-header-wrapper" :id "gitique-token-request"}
+                   explanation input)]
+      (.addEventListener input "input" #(.remove (.-classList (.-target %)) "error"))
+      (.addEventListener wrapper "submit" (partial update-token! url))
+      (.insertBefore parent wrapper sibling))))

 (defn- xhr-handler [event]
   (if-let [error (not= 200 (.getStatus (.-target event)))]


Fix CircleCI Build - fixing the test

Fix CircleCI Build - fixing the test

--- test/hydrant/core_test.clj
+++ test/hydrant/core_test.clj
@@ -3,5 +3,5 @@
             [hydrant.core :refer :all]))

 (deftest a-test
-  (testing "FIXME, I fail."
-    (is (= 0 1))))
+  (testing "TODO - Write tests"
+    (is (= 1 1))))


Optionally stop bubbling in wrap-log-exceptions.

--- src/incise/server.clj
+++ src/incise/server.clj
@@ -23,14 +23,14 @@
                (assoc request :uri (str uri "index.html"))
                request))))

-(defn wrap-log-exceptions [func]
+(defn wrap-log-exceptions [func & {:keys [bubble] :or {bubble true}}]
   "Log (i.e. print) exceptions received from the given function."
   (fn [& args]
     (try
       (apply func args)
       (catch Exception e
         (error (with-out-str (print-cause-trace e)))
-        (throw e)))))
+        (when bubble (throw e))))))

 (def app (-> routes
              (wrap-static-index)