Update unit tests to use newer functions and conventions.

--- src/test/clojure/clara/test_rules.clj
+++ src/test/clojure/clara/test_rules.clj
@@ -1,43 +1,42 @@
 (ns clara.test-rules
-  (:use clojure.test
-        clara.rules
-        clojure.pprint
-        [clara.rules.engine :only [->Token  *trace-transport*]]
-        [clara.rules.compiler :only [to-dnf to-beta-tree]]
-        clara.rules.testfacts)
   (:require [clara.sample-ruleset :as sample]
             [clara.other-ruleset :as other]
+            [clara.rules :refer :all]
+            [clojure.test :refer :all]
+            [clara.rules.testfacts :refer :all]
+            [clara.rules.engine :as eng]
+            [clara.rules.compiler :as com]
+            [clara.rules.dsl :as dsl]
             [clojure.set :as s]
             [clojure.edn :as edn]
             [clojure.walk :as walk]
             schema.test)
-  (import [clara.rules.testfacts Temperature WindSpeed Cold ColdAndWindy LousyWeather First Second Third Fourth]
+  (import [clara.rules.testfacts Temperature WindSpeed Cold
+           ColdAndWindy LousyWeather First Second Third Fourth]
           [java.util TimeZone]))

 (use-fixtures :once schema.test/validate-schemas)

 (deftest test-simple-rule
   (let [rule-output (atom nil)
-        cold-rule (mk-rule [[Temperature (< temperature 20)]]
-                            (reset! rule-output ?__token__) )
-
-        session (-> (mk-rulebase cold-rule)
-                    (mk-session)
+        cold-rule (dsl/parse-rule [[Temperature (< temperature 20)]]
+                                  (reset! rule-output ?__token__))
+
+        session (-> (mk-session [cold-rule])
                     (insert (->Temperature 10 "MCI"))
                     (fire-rules))]

     (is (=
-         (->Token [(->Temperature 10 "MCI")] {})
+         (eng/->Token [(->Temperature 10 "MCI")] {})
          @rule-output))))

 (deftest test-multiple-condition-rule
   (let [rule-output (atom nil)
-        cold-windy-rule (mk-rule [(Temperature (< temperature 20))
-                                   (WindSpeed (> windspeed 25))]
-                                  (reset! rule-output ?__token__))
-
-        session (-> (mk-rulebase cold-windy-rule)
-                    (mk-session)
+        cold-windy-rule (dsl/parse-rule [[Temperature (< temperature 20)]
+                                         [WindSpeed (> windspeed 25)]]
+                                        (reset! rule-output ?__token__))
+
+        session (-> (mk-session [cold-windy-rule])
                     (insert (->WindSpeed 30 "MCI"))
                     (insert (->Temperature 10 "MCI")))]

@@ -51,13 +50,13 @@
   (let [cold-rule-output (atom nil)
         windy-rule-output (atom nil)

-        cold-rule (mk-rule [(Temperature (< temperature 20))]
-                            (reset! cold-rule-output ?__token__))
-
-        windy-rule (mk-rule [(WindSpeed (> windspeed 25))]
-                             (reset! windy-rule-output ?__token__))
-        session (-> (mk-rulebase cold-rule windy-rule)
-                    (mk-session)
+        cold-rule (dsl/parse-rule [[Temperature (< temperature 20)]]
+                                  (reset! cold-rule-output ?__token__))
+
+        windy-rule (dsl/parse-rule [[WindSpeed (> windspeed 25)]]
+                                   (reset! windy-rule-output ?__token__))
+
+        session (-> (mk-session [cold-rule windy-rule])
                     (insert (->WindSpeed 30 "MCI"))
                     (insert (->Temperature 10 "MCI")))]

@@ -65,43 +64,42 @@

     ;; Check rule side effects contin the expected token.
     (is (=
-         (->Token [(->Temperature 10 "MCI")] {})
+         (eng/->Token [(->Temperature 10 "MCI")] {})
          @cold-rule-output))

     (is (=
-         (->Token [(->WindSpeed 30 "MCI")] {})
+         (eng/->Token [(->WindSpeed 30 "MCI")] {})
          @windy-rule-output))))

 (deftest test-multiple-rules-same-fact

   (let [cold-rule-output (atom nil)
         subzero-rule-output (atom nil)
-        cold-rule (mk-rule [(Temperature (< temperature 20))]
-                            (reset! cold-rule-output ?__token__))
-        subzero-rule (mk-rule [(Temperature (< temperature 0))]
-                            (reset! subzero-rule-output ?__token__))
-
-        session (-> (mk-rulebase cold-rule subzero-rule)
-                    (mk-session)
+        cold-rule (dsl/parse-rule [[Temperature (< temperature 20)]]
+                                  (reset! cold-rule-output ?__token__))
+
+        subzero-rule (dsl/parse-rule [[Temperature (< temperature 0)]]
+                                     (reset! subzero-rule-output ?__token__))
+
+        session (-> (mk-session [cold-rule subzero-rule])
                     (insert (->Temperature -10 "MCI")))]

     (fire-rules session)

     (is (=
-         (->Token [(->Temperature -10 "MCI")] {})
+         (eng/->Token [(->Temperature -10 "MCI")] {})
          @cold-rule-output))

     (is (=
-         (->Token [(->Temperature -10 "MCI")] {})
+         (eng/->Token [(->Temperature -10 "MCI")] {})
          @subzero-rule-output))))

 (deftest test-cancelled-activation
   (let [rule-output (atom nil)
-        cold-rule (mk-rule [[Temperature (< temperature 20)]]
-                            (reset! rule-output ?__token__) )
-
-        session (-> (mk-rulebase cold-rule)
-                    (mk-session)
+        cold-rule (dsl/parse-rule [[Temperature (< temperature 20)]]
+                                  (reset! rule-output ?__token__) )
+
+        session (-> (mk-session [cold-rule])
                     (insert (->Temperature 10 "MCI"))
                     (retract (->Temperature 10 "MCI"))
                     (fire-rules))]
@@ -110,11 +108,10 @@

 (deftest test-simple-binding
   (let [rule-output (atom nil)
-        cold-rule (mk-rule [(Temperature (< temperature 20) (== ?t temperature))]
-                            (reset! rule-output ?t) )
-
-        session (-> (mk-rulebase cold-rule)
-                    (mk-session)
+        cold-rule (dsl/parse-rule [[Temperature (< temperature 20) (= ?t temperature)]]
+                                  (reset! rule-output ?t) )
+
+        session (-> (mk-session [cold-rule])
                     (insert (->Temperature 10 "MCI")))]

@@ -123,12 +120,11 @@

 (deftest test-simple-join-binding
   (let [rule-output (atom nil)
-        same-wind-and-temp (mk-rule [(Temperature (== ?t temperature))
-                                      (WindSpeed (== ?t windspeed))]
-                                     (reset! rule-output ?t) )
-
-        session (-> (mk-rulebase same-wind-and-temp)
-                    (mk-session)
+        same-wind-and-temp (dsl/parse-rule [[Temperature (= ?t temperature)]
+                                            [WindSpeed (= ?t windspeed)]]
+                                           (reset! rule-output ?t))
+
+        session (-> (mk-session [same-wind-and-temp])
                     (insert (->Temperature 10  "MCI"))
                     (insert (->WindSpeed 10  "MCI")))]

@@ -137,13 +133,11 @@

 (deftest test-simple-join-binding-nomatch
   (let [rule-output (atom nil)
-        same-wind-and-temp (mk-rule [(Temperature (== ?t temperature))
-                                      (WindSpeed (== ?t windspeed))]
-                                     (reset! rule-output ?t) )
-
-        session (-> (mk-rulebase)
-                    (add-productions same-wind-and-temp)
-                    (mk-session)
+        same-wind-and-temp (dsl/parse-rule [[Temperature (= ?t temperature)]
+                                            [WindSpeed (= ?t windspeed)]]
+                                           (reset! rule-output ?t) )
+
+        session (-> (mk-session [same-wind-and-temp])
                     (insert (->Temperature 10 "MCI"))
                     (insert (->WindSpeed 20 "MCI")))]

@@ -151,10 +145,9 @@
     (is (= nil @rule-output))))

 (deftest test-simple-query
-  (let [cold-query (mk-query [] [(Temperature (< temperature 20) (== ?t temperature))])
-
-        session (-> (mk-rulebase cold-query)
-                    (mk-session)
+  (let [cold-query (dsl/parse-query [] [[Temperature (< temperature 20) (= ?t temperature)]])
+
+        session (-> (mk-session [cold-query])
                     (insert (->Temperature 15 "MCI"))
                     (insert (->Temperature 10 "MCI"))
                     (insert (->Temperature 80 "MCI")))]
@@ -165,24 +158,17 @@
            (set (query session cold-query))))))

 (deftest test-param-query
-  (let [cold-query (mk-query [:?l] [(Temperature (< temperature 50)
-                                                  (== ?t temperature)
-                                                  (== ?l location))])
-
-        session (-> (mk-rulebase cold-query)
-                    (mk-session)
+  (let [cold-query (dsl/parse-query [:?l] [[Temperature (< temperature 50)
+                                     (= ?t temperature)
+                                     (= ?l location)]])
+
+        session (-> (mk-session [cold-query])
                     (insert (->Temperature 15 "MCI"))
                     (insert (->Temperature 20 "MCI")) ; Test multiple items in result.
                     (insert (->Temperature 10 "ORD"))
                     (insert (->Temperature 35 "BOS"))
                     (insert (->Temperature 80 "BOS")))]

-    (comment
-      (println "OLD:")
-      (println (:query-nodes (add-productions (mk-rulebase) cold-query)))
-      (println "NEW:")
-      (println (:query-nodes (mk-rulebase cold-query))))
-
     ;; Query by location.
     (is (= #{{:?l "BOS" :?t 35}}
            (set (query session cold-query :?l "BOS"))))
@@ -194,10 +180,9 @@
            (set (query session cold-query :?l "ORD"))))))

 (deftest test-simple-condition-binding
-  (let [cold-query (mk-query [] [(?t <- Temperature (< temperature 20))])
-
-        session (-> (mk-rulebase cold-query)
-                    (mk-session)
+  (let [cold-query (dsl/parse-query [] [[?t <- Temperature (< temperature 20)]])
+
+        session (-> (mk-session [cold-query])
                     (insert (->Temperature 15 "MCI"))
                     (insert (->Temperature 10 "MCI")))]

@@ -206,10 +191,9 @@
            (set (query session cold-query))))))

 (deftest test-condition-and-value-binding
-  (let [cold-query (mk-query [] [(?t <- Temperature (< temperature 20) (== ?v temperature))])
-
-        session (-> (mk-rulebase cold-query)
-                    (mk-session)
+  (let [cold-query (dsl/parse-query [] [[?t <- Temperature (< temperature 20) (= ?v temperature)]])
+
+        session (-> (mk-session [cold-query])
                     (insert (->Temperature 15 "MCI"))
                     (insert (->Temperature 10 "MCI")))]

@@ -225,10 +209,9 @@
                                           (< (:temperature item) (:temperature value) ))
                                     item
                                     value)))
-        coldest-query (mk-query [] [[?t <- lowest-temp from [Temperature]]])
-
-        session (-> (mk-rulebase coldest-query)
-                    (mk-session)
+        coldest-query (dsl/parse-query [] [[?t <- lowest-temp from [Temperature]]])
+
+        session (-> (mk-session [coldest-query])
                     (insert (->Temperature 15 "MCI"))
                     (insert (->Temperature 10 "MCI"))
                     (insert (->Temperature 80 "MCI")))]
@@ -248,10 +231,9 @@
                   value))))

 (deftest test-defined-accumulator
-  (let [coldest-query (mk-query [] [[?t <- (min-fact :temperature) from [Temperature]]])
-
-        session (-> (mk-rulebase coldest-query)
-                    (mk-session)
+  (let [coldest-query (dsl/parse-query [] [[?t <- (min-fact :temperature) from [Temperature]]])
+
+        session (-> (mk-session [coldest-query])
                     (insert (->Temperature 15 "MCI"))
                     (insert (->Temperature 10 "MCI"))
                     (insert (->Temperature 80 "MCI")))]
@@ -276,10 +258,9 @@

 (deftest test-accumulator-with-result

-  (let [average-temp-query (mk-query [] [[?t <- (average-value :temperature) from [Temperature]]])
-
-        session (-> (mk-rulebase average-temp-query)
-                    (mk-session)
+  (let [average-temp-query (dsl/parse-query [] [[?t <- (average-value :temperature) from [Temperature]]])
+
+        session (-> (mk-session [average-temp-query])
                     (insert (->Temperature 10 "MCI"))
                     (insert (->Temperature 20 "MCI"))
                     (insert (->Temperature 30 "MCI"))
@@ -293,27 +274,27 @@
            (set (query session average-temp-query))))))

 (deftest test-accumulate-with-retract
-  (let [coldest-query (mk-query [] [[?t <- (accumulate
-                                            :initial-value []
-                                            :reduce-fn conj
-                                            :combine-fn concat
-
-                                            ;; Retract by removing the retracted item.
-                                            ;; In general, this would need to remove
-                                            ;; only the first matching item to achieve expected semantics.
-                                            :retract-fn (fn [reduced item]
-                                                          (remove #{item} reduced))
-
-                                            ;; Sort here and return the smallest.
-                                            :convert-return-fn (fn [reduced]
-                                                                 (first
-                                                                  (sort #(< (:temperature %1) (:temperature %2))
-                                                                        reduced))))
-
-                                   :from (Temperature (< temperature 20))]])
-
-        session (-> (mk-rulebase coldest-query)
-                    (mk-session)
+  (let [coldest-query (dsl/parse-query
+                       [] [[?t <- (accumulate
+                                   :initial-value []
+                                   :reduce-fn conj
+                                   :combine-fn concat
+
+                                   ;; Retract by removing the retracted item.
+                                   ;; In general, this would need to remove
+                                   ;; only the first matching item to achieve expected semantics.
+                                   :retract-fn (fn [reduced item]
+                                                 (remove #{item} reduced))
+
+                                   ;; Sort here and return the smallest.
+                                   :convert-return-fn (fn [reduced]
+                                                        (first
+                                                         (sort #(< (:temperature %1) (:temperature %2))
+                                                               reduced))))
+
+                            :from (Temperature (< temperature 20))]])
+
+        session (-> (mk-session [coldest-query])
                     (insert (->Temperature 10 "MCI"))
                     (insert (->Temperature 17 "MCI"))
                     (insert (->Temperature 15 "MCI"))
@@ -328,18 +309,17 @@

 (deftest test-joined-accumulator

-  (let [coldest-query (mk-query []
-                                [(WindSpeed (== ?loc location))
+  (let [coldest-query (dsl/parse-query []
+                                [(WindSpeed (= ?loc location))
                                  [?t <- (accumulate
                                          :reduce-fn (fn [value item]
                                                       (if (or (= value nil)
                                                               (< (:temperature item) (:temperature value) ))
                                                         item
                                                         value)))
-                                  :from (Temperature (== ?loc location))]])
-
-        session (-> (mk-rulebase coldest-query)
-                    (mk-session)
+                                  :from (Temperature (= ?loc location))]])
+
+        session (-> (mk-session [coldest-query])
                     (insert (->Temperature 15 "MCI"))
                     (insert (->Temperature 10 "MCI"))
                     (insert (->Temperature 5 "SFO"))
@@ -357,17 +337,16 @@
     (is (empty? (query session-retracted coldest-query)))))

 (deftest test-bound-accumulator-var
-  (let [coldest-query (mk-query [:?loc]
+  (let [coldest-query (dsl/parse-query [:?loc]
                                 [[?t <- (accumulate
                                          :reduce-fn (fn [value item]
                                                       (if (or (= value nil)
                                                               (< (:temperature item) (:temperature value) ))
                                                         item
                                                         value)))
-                                  :from (Temperature (== ?loc location))]])
-
-        session (-> (mk-rulebase coldest-query)
-                    (mk-session)
+                                  :from [ Temperature (= ?loc location)]]])
+
+        session (-> (mk-session [coldest-query])
                     (insert (->Temperature 15 "MCI"))
                     (insert (->Temperature 10 "MCI"))
                     (insert (->Temperature 5 "SFO")))]
@@ -379,10 +358,9 @@
            (set (query session coldest-query :?loc "SFO"))))))

 (deftest test-simple-negation
-  (let [not-cold-query (mk-query [] [(not (Temperature (< temperature 20)))])
-
-        session (-> (mk-rulebase not-cold-query)
-                    (mk-session))
+  (let [not-cold-query (dsl/parse-query [] [[:not [Temperature (< temperature 20)]]])
+
+        session  (mk-session [not-cold-query])

         session-with-temp (insert session (->Temperature 10 "MCI"))
         session-retracted (retract session-with-temp (->Temperature 10 "MCI"))]
@@ -402,11 +380,10 @@

 (deftest test-negation-with-other-conditions
-  (let [windy-but-not-cold-query (mk-query [] [(WindSpeed (> windspeed 30) (== ?w windspeed))
-                                               (not (Temperature (< temperature 20)))])
-
-        session (-> (mk-rulebase windy-but-not-cold-query)
-                    (mk-session))
+  (let [windy-but-not-cold-query (dsl/parse-query [] [[WindSpeed (> windspeed 30) (= ?w windspeed)]
+                                                      [:not [ Temperature (< temperature 20)]]])
+
+        session  (mk-session [windy-but-not-cold-query])

         ;; Make it windy, so our query should indicate that.
         session (insert session (->WindSpeed 40 "MCI"))
@@ -428,11 +405,11 @@

 (deftest test-negated-conjunction
-  (let [not-cold-and-windy (mk-query [] [(not (and (WindSpeed (> windspeed 30))
-                                                   (Temperature (< temperature 20))))])
-
-        session (-> (mk-rulebase not-cold-and-windy)
-                    (mk-session))
+  (let [not-cold-and-windy (dsl/parse-query [] [[:not [:and
+                                                       [WindSpeed (> windspeed 30)]
+                                                       [Temperature (< temperature 20)]]]])
+
+        session  (mk-session [not-cold-and-windy])

         session-with-data (-> session
                               (insert (->WindSpeed 40 "MCI"))
@@ -446,12 +423,10 @@
     (is (empty? (query session-with-data not-cold-and-windy)))))

 (deftest test-negated-disjunction
-  (let [not-cold-or-windy (mk-query [] [(not (or (WindSpeed (> windspeed 30))
-                                                 (Temperature (< temperature 20))))])
-
-        session (-> (mk-rulebase)
-                    (add-productions not-cold-or-windy)
-                    (mk-session))
+  (let [not-cold-or-windy (dsl/parse-query [] [[:not [:or [WindSpeed (> windspeed 30)]
+                                                          [Temperature (< temperature 20)]]]])
+
+        session  (mk-session [not-cold-or-windy])

         session-with-temp (insert session (->WindSpeed 40 "MCI"))
         session-retracted (retract session-with-temp (->WindSpeed 40 "MCI"))]
@@ -469,12 +444,11 @@

 (deftest test-simple-retraction
-  (let [cold-query (mk-query [] [[Temperature (< temperature 20) (== ?t temperature)]])
+  (let [cold-query (dsl/parse-query [] [[Temperature (< temperature 20) (= ?t temperature)]])

         temp (->Temperature 10 "MCI")

-        session (-> (mk-rulebase cold-query)
-                    (mk-session)
+        session (-> (mk-session [cold-query])
                     (insert temp))]

     ;; Ensure the item is there as expected.
@@ -486,10 +460,9 @@
            (set (query (retract session temp) cold-query))))))

 (deftest test-noop-retraction
-  (let [cold-query (mk-query [] [[Temperature (< temperature 20) (== ?t temperature)]])
-
-        session (-> (mk-rulebase cold-query)
-                    (mk-session)
+  (let [cold-query (dsl/parse-query [] [[Temperature (< temperature 20) (= ?t temperature)]])
+
+        session (-> (mk-session [cold-query])
                     (insert (->Temperature 10 "MCI"))
                     (retract (->Temperature 15 "MCI")))] ; Ensure retracting a non-existant item has no ill effects.

@@ -497,11 +470,10 @@
            (set (query session cold-query))))))

 (deftest test-retraction-of-join
-  (let [same-wind-and-temp (mk-query [] [(Temperature (== ?t temperature))
-                                         (WindSpeed (== ?t windspeed))])
-
-        session (-> (mk-rulebase same-wind-and-temp)
-                    (mk-session)
+  (let [same-wind-and-temp (dsl/parse-query [] [[Temperature (= ?t temperature)]
+                                         (WindSpeed (= ?t windspeed))])
+
+        session (-> (mk-session [same-wind-and-temp])
                     (insert (->Temperature 10 "MCI"))
                     (insert (->WindSpeed 10 "MCI")))]

@@ -518,13 +490,13 @@

 (deftest test-simple-disjunction
-  (let [or-query (mk-query [] [(or (Temperature (< temperature 20) (== ?t temperature))
-                                   (WindSpeed (> windspeed 30) (== ?w windspeed)))])
-
-        rulebase (-> (mk-rulebase or-query))
-
-        cold-session (insert (mk-session rulebase) (->Temperature 15 "MCI"))
-        windy-session (insert (mk-session rulebase) (->WindSpeed 50 "MCI"))  ]
+  (let [or-query (dsl/parse-query [] [[:or [Temperature (< temperature 20) (= ?t temperature)]
+                                           [WindSpeed (> windspeed 30) (= ?w windspeed)]]])
+
+        session (mk-session [or-query])
+
+        cold-session (insert session (->Temperature 15 "MCI"))
+        windy-session (insert session (->WindSpeed 50 "MCI"))  ]

     (is (= #{{:?t 15}}
            (set (query cold-session or-query))))
@@ -536,11 +508,11 @@

   (let [really-cold-or-cold-and-windy
-        (mk-query [] [(or (Temperature (< temperature 0) (== ?t temperature))
-                          (and (Temperature (< temperature 20) (== ?t temperature))
-                               (WindSpeed (> windspeed 30) (== ?w windspeed))))])
-
-        rulebase (mk-rulebase really-cold-or-cold-and-windy)
+        (dsl/parse-query [] [[:or [Temperature (< temperature 0) (= ?t temperature)]
+                                  [:and [Temperature (< temperature 20) (= ?t temperature)]
+                                        [WindSpeed (> windspeed 30) (= ?w windspeed)]]]])
+
+        rulebase [really-cold-or-cold-and-windy]

         cold-session (-> (mk-session rulebase)
                          (insert (->Temperature -10 "MCI")))
@@ -559,16 +531,15 @@

   (let [rule-output (atom nil)
         ;; Insert a new fact and ensure it exists.
-        cold-rule (mk-rule [(Temperature (< temperature 20) (== ?t temperature))]
-                           (insert! (->Cold ?t)) )
-
-        cold-query (mk-query [] [(Cold (== ?c temperature))])
-
-        session (-> (mk-rulebase cold-rule cold-query)
-                       (mk-session)
-                       (insert (->Temperature 10 "MCI"))
-                       (fire-rules))]
-
+        cold-rule (dsl/parse-rule [[Temperature (< temperature 20) (= ?t temperature)]]
+                                  (insert! (->Cold ?t)) )
+
+        cold-query (dsl/parse-query [] [[Cold (= ?c temperature)]])
+
+        session (-> (mk-session [cold-rule cold-query])
+                    (insert (->Temperature 10 "MCI"))
+                    (fire-rules))]
+
     (is (= #{{:?c 10}}
            (set (query session cold-query))))))

@@ -576,13 +547,12 @@
 (deftest test-insert-and-retract
   (let [rule-output (atom nil)
         ;; Insert a new fact and ensure it exists.
-        cold-rule (mk-rule [(Temperature (< temperature 20) (== ?t temperature))]
-                           (insert! (->Cold ?t)) )
-
-        cold-query (mk-query [] [(Cold (== ?c temperature))])
-
-        session (-> (mk-rulebase cold-rule cold-query)
-                    (mk-session)
+        cold-rule (dsl/parse-rule [[Temperature (< temperature 20) (= ?t temperature)]]
+                                  (insert! (->Cold ?t)) )
+
+        cold-query (dsl/parse-query [] [[Cold (= ?c temperature)]])
+
+        session (-> (mk-session [cold-rule cold-query])
                     (insert (->Temperature 10 "MCI"))
                     (fire-rules))]

@@ -599,13 +569,12 @@
 (deftest test-unconditional-insert
   (let [rule-output (atom nil)
         ;; Insert a new fact and ensure it exists.
-        cold-rule (mk-rule [(Temperature (< temperature 20) (== ?t temperature))]
-                           (insert-unconditional! (->Cold ?t)) )
-
-        cold-query (mk-query [] [(Cold (== ?c temperature))])
-
-        session (-> (mk-rulebase cold-rule cold-query)
-                    (mk-session)
+        cold-rule (dsl/parse-rule [[Temperature (< temperature 20) (= ?t temperature)]]
+                                  (insert-unconditional! (->Cold ?t)) )
+
+        cold-query (dsl/parse-query [] [[Cold (= ?c temperature)]])
+
+        session (-> (mk-session [cold-rule cold-query])
                     (insert (->Temperature 10 "MCI"))
                     (fire-rules))]

@@ -623,14 +592,13 @@
 (deftest test-insert-and-retract-multi-input
   (let [rule-output (atom nil)
         ;; Insert a new fact and ensure it exists.
-        cold-rule (mk-rule [(Temperature (< temperature 20) (== ?t temperature))
-                            (WindSpeed (> windspeed 30) (== ?w windspeed))]
+        cold-rule (dsl/parse-rule [[Temperature (< temperature 20) (= ?t temperature)]
+                                   [WindSpeed (> windspeed 30) (= ?w windspeed)]]
                            (insert! (->ColdAndWindy ?t ?w)) )

-        cold-query (mk-query [] [(ColdAndWindy (== ?ct temperature) (== ?cw windspeed))])
-
-        session (-> (mk-rulebase cold-rule cold-query)
-                    (mk-session)
+        cold-query (dsl/parse-query [] [[ColdAndWindy (= ?ct temperature) (= ?cw windspeed)]])
+
+        session (-> (mk-session [cold-rule cold-query])
                     (insert (->Temperature 10 "MCI"))
                     (insert (->WindSpeed 40 "MCI"))
                     (fire-rules))]
@@ -648,18 +616,18 @@

   ;; Test simple condition.
   (is (= {:type Temperature :constraints []}
-         (to-dnf {:type Temperature :constraints []})))
+         (com/to-dnf {:type Temperature :constraints []})))

   ;; Test single-item conjunction removes unnecessary operator.
   (is (=  {:type Temperature :constraints []}
-          (to-dnf [:and {:type Temperature :constraints []}])))
+          (com/to-dnf [:and {:type Temperature :constraints []}])))

   ;; Test multi-item conjunction.
   (is (= [:and
           {:type Temperature :constraints ['(> 2 1)]}
           {:type Temperature :constraints ['(> 3 2)]}
           {:type Temperature :constraints ['(> 4 3)]}]
-         (to-dnf
+         (com/to-dnf
           [:and
            {:type Temperature :constraints ['(> 2 1)]}
            {:type Temperature :constraints ['(> 3 2)]}
@@ -670,7 +638,7 @@
            {:type Temperature :constraints ['(> 2 1)]}
            {:type Temperature :constraints ['(> 3 2)]}
            {:type Temperature :constraints ['(> 4 3)]}]
-         (to-dnf
+         (com/to-dnf
           [:or
            {:type Temperature :constraints ['(> 2 1)]}
            {:type Temperature :constraints ['(> 3 2)]}
@@ -683,7 +651,7 @@
           [:and
            {:type Temperature :constraints ['(> 3 2)]}
            {:type Temperature :constraints ['(> 4 3)]}]]
-         (to-dnf
+         (com/to-dnf
           [:or
            {:type Temperature :constraints ['(> 2 1)]}
            [:and
@@ -698,7 +666,7 @@
           [:and
            {:type Temperature :constraints ['(> 3 2)]}
            {:type Temperature :constraints ['(> 4 3)]}]]
-         (to-dnf
+         (com/to-dnf
           [:and
            [:or
             {:type Temperature :constraints ['(> 2 1)]}
@@ -710,7 +678,7 @@
           [:not {:type Temperature :constraints ['(> 2 1)]}]
           [:not {:type Temperature :constraints ['(> 3 2)]}]
           [:not {:type Temperature :constraints ['(> 4 3)]}]]
-         (to-dnf
+         (com/to-dnf
           [:not
            [:or
             {:type Temperature :constraints ['(> 2 1)]}
@@ -722,7 +690,7 @@
           [:not {:type Temperature :constraints ['(> 2 1)]}]
           [:not {:type Temperature :constraints ['(> 3 2)]}]
           [:not {:type Temperature :constraints ['(> 4 3)]}]]
-         (to-dnf
+         (com/to-dnf
           [:and
            [:not
             [:or
@@ -736,7 +704,7 @@
              {:type Temperature :constraints ['(> 3 2)]}
              {:type Temperature :constraints ['(> 4 3)]}]]

-         (to-dnf
+         (com/to-dnf
           [:and
            [:or
             {:type Temperature :constraints ['(> 2 1)]}
@@ -749,7 +717,7 @@
           [:not {:type Temperature :constraints ['(> 2 1)]}]
           [:not {:type Temperature :constraints ['(> 3 2)]}]
           [:not {:type Temperature :constraints ['(> 4 3)]}]]
-         (to-dnf
+         (com/to-dnf
           [:not
            [:and
             {:type Temperature :constraints ['(> 2 1)]}
@@ -760,7 +728,7 @@
   (is (= [:or
           [:not {:type Temperature :constraints ['(> 2 1)]}]
           [:not {:type Temperature :constraints ['(> 3 2)]}]]
-         (to-dnf
+         (com/to-dnf
           [:or
            [:not {:type Temperature :constraints ['(> 2 1)]}]
            [:not {:type Temperature :constraints ['(> 3 2)]}]])))
@@ -779,7 +747,7 @@
            {:type Temperature :constraints ['(> 4 3)]}
            {:type Temperature :constraints ['(> 5 4)]}
            {:type Temperature :constraints ['(> 6 5)]}]]
-         (to-dnf
+         (com/to-dnf
           [:and
            [:or
             {:type Temperature :constraints ['(> 2 1)]}
@@ -791,30 +759,28 @@
 (def simple-defrule-side-effect (atom nil))

 (defrule test-rule
-  (Temperature (< temperature 20))
+  [Temperature (< temperature 20)]
   =>
   (reset! simple-defrule-side-effect ?__token__))

 (deftest test-simple-defrule
-  (let [session (-> (mk-rulebase test-rule)
-                    (mk-session)
+  (let [session (-> (mk-session [test-rule])
                     (insert (->Temperature 10 "MCI")))]

     (fire-rules session)

     (is (=
-         (->Token [(->Temperature 10 "MCI")] {})
+         (eng/->Token [(->Temperature 10 "MCI")] {})
          @simple-defrule-side-effect))))

 (defquery cold-query
   [:?l]
-  (Temperature (< temperature 50)
-               (== ?t temperature)
-               (== ?l location)))
+  [Temperature (< temperature 50)
+               (= ?t temperature)
+               (= ?l location)])

 (deftest test-defquery
-  (let [session (-> (mk-rulebase cold-query)
-                    (mk-session)
+  (let [session (-> (mk-session [cold-query])
                     (insert (->Temperature 15 "MCI"))
                     (insert (->Temperature 20 "MCI")) ; Test multiple items in result.
                     (insert (->Temperature 10 "ORD"))
@@ -876,17 +842,15 @@

 (deftest test-mark-as-fired
   (let [rule-output (atom nil)
-        cold-rule (mk-rule [[Temperature (< temperature 20)]]
-                            (reset! rule-output ?__token__) )
-
-        session (-> (mk-rulebase)
-                    (add-productions cold-rule)
-                    (mk-session)
+        cold-rule (dsl/parse-rule [[Temperature (< temperature 20)]]
+                                  (reset! rule-output ?__token__) )
+
+        session (-> (mk-session [cold-rule])
                     (insert (->Temperature 10 "MCI"))
                     (fire-rules))]

     (is (=
-         (->Token [(->Temperature 10 "MCI")] {})
+         (eng/->Token [(->Temperature 10 "MCI")] {})
          @rule-output))

     ;; Reset the side effect then re-fire the rules
@@ -902,19 +866,17 @@
         (fire-rules))

     (is (=
-         (->Token [(->Temperature 10 "MCI")] {})
+         (eng/->Token [(->Temperature 10 "MCI")] {})
          @rule-output))))

 (deftest test-chained-inference
-  (let [item-query (mk-query [] [(?item <- Fourth)])
-
-        session (-> (mk-rulebase)
-                    (add-productions (mk-rule [(Third)] (insert! (->Fourth)))) ; Rule order shouldn't matter, but test it anyway.
-                    (add-productions (mk-rule [(First)] (insert! (->Second))))
-                    (add-productions (mk-rule [(Second)] (insert! (->Third))))
-                    (add-productions item-query)
-                    (mk-session)
+  (let [item-query (dsl/parse-query [] [[?item <- Fourth]])
+
+        session (-> (mk-session [(dsl/parse-rule [[Third]] (insert! (->Fourth)))
+                                 (dsl/parse-rule [[First]] (insert! (->Second)))
+                                 (dsl/parse-rule [[Second]] (insert! (->Third)))
+                                 item-query])
                     (insert (->First))
                     (fire-rules))]

@@ -926,19 +888,19 @@

 (comment ;; FIXME: node ids are currently not consistent...
   (deftest test-node-id-map
-    (let [cold-rule (mk-rule [(Temperature (< temperature 20))]
+    (let [cold-rule (dsl/parse-rule [[Temperature (< temperature 20)]]
                              (println "Placeholder"))
-          windy-rule (mk-rule [(WindSpeed (> windspeed 25))]
+          windy-rule (dsl/parse-rule [[WindSpeed (> windspeed 25)]]
                               (println "Placeholder"))

-          rulebase  (mk-rulebase cold-rule windy-rule)
-
-          cold-rule2 (mk-rule [(Temperature (< temperature 20))]
+          rulebase  (mk-session [cold-rule windy-rule])
+
+          cold-rule2 (dsl/parse-rule [[Temperature (< temperature 20)]]
                               (println "Placeholder"))
-          windy-rule2 (mk-rule [(WindSpeed (> windspeed 25))]
+          windy-rule2 (dsl/parse-rule [[WindSpeed (> windspeed 25)]]
                                (println "Placeholder"))

-          rulebase2 (mk-rulebase cold-rule2 windy-rule2)]
+          rulebase2 (mk-session [cold-rule2 windy-rule2])]

       ;; The keys should be consistent between maps since the rules are identical.
       (is (= (keys (:id-to-node rulebase))
@@ -948,13 +910,11 @@
       (is (= 4 (count (:id-to-node rulebase)))))))

 (deftest test-simple-test
-  (let [distinct-temps-query (mk-query [] [(Temperature (< temperature 20) (== ?t1 temperature))
-                                           (Temperature (< temperature 20) (== ?t2 temperature))
-                                           (test (< ?t1 ?t2))])
-
-        session (-> (mk-rulebase)
-                    (add-productions distinct-temps-query)
-                    (mk-session)
+  (let [distinct-temps-query (dsl/parse-query [] [[Temperature (< temperature 20) (= ?t1 temperature)]
+                                                  [Temperature (< temperature 20) (= ?t2 temperature)]
+                                                  [:test (< ?t1 ?t2)]])
+
+        session (-> (mk-session [distinct-temps-query])
                     (insert (->Temperature 15 "MCI"))
                     (insert (->Temperature 10 "MCI"))
                     (insert (->Temperature 80 "MCI")))]
@@ -966,13 +926,11 @@
 (deftest test-bean-support

   ;; Use TimeZone for this test as it is an available JavaBean-like object.
-  (let [tz-offset-query (mk-query [:?offset]
-                                  [[TimeZone (== ?offset rawOffset)
-                                             (== ?id ID)]])
+  (let [tz-offset-query (dsl/parse-query [:?offset]
+                                  [[TimeZone (= ?offset rawOffset)
+                                             (= ?id ID)]])

-        session (-> (mk-rulebase)
-                    (add-productions tz-offset-query)
-                    (mk-session)
+        session (-> (mk-session [tz-offset-query])
                     (insert (TimeZone/getTimeZone "America/Chicago")
                             (TimeZone/getTimeZone "UTC")))]

@@ -1018,13 +976,12 @@
             (query session sample/find-cold-and-windy))))))

 (deftest test-retract!
-  (let [not-cold-rule (mk-rule [[Temperature (> temperature 50)]]
+  (let [not-cold-rule (dsl/parse-rule [[Temperature (> temperature 50)]]
                                (retract! (->Cold 20)))

-        cold-query (mk-query [] [[Cold (== ?t temperature)]])
-
-        session (-> (mk-rulebase not-cold-rule cold-query)
-                    (mk-session)
+        cold-query (dsl/parse-query [] [[Cold (= ?t temperature)]])
+
+        session (-> (mk-session [not-cold-rule cold-query])
                     (insert (->Cold 20))
                     (fire-rules))]

@@ -1042,10 +999,9 @@
 (deftest test-destructured-args

   (comment
-    (let [cold-query (mk-query [] [(Temperature [{temp-arg :temperature}] (< temp-arg 20) (== ?t temp-arg))])
-
-          session (-> (mk-rulebase cold-query)
-                      (mk-session)
+    (let [cold-query (dsl/parse-query [] [[Temperature [{temp-arg :temperature}] (< temp-arg 20) (= ?t temp-arg)]])
+
+          session (-> (mk-session [cold-query])
                       (insert (->Temperature 15 "MCI"))
                       (insert (->Temperature 10 "MCI"))
                       (insert (->Temperature 80 "MCI")))]
@@ -1054,11 +1010,10 @@
              (set (query session cold-query)))))))

 (deftest test-general-map
-  (let [cold-query (mk-query []
-                             [[:temperature [{temp :value}] (< temp 20) (== ?t temp)]])
-
-        session (-> (mk-rulebase cold-query)
-                    (mk-session :fact-type-fn :type)
+  (let [cold-query (dsl/parse-query []
+                             [[:temperature [{temp :value}] (< temp 20) (= ?t temp)]])
+
+        session (-> (mk-session [cold-query] :fact-type-fn :type)
                     (insert {:type :temperature :value 15 :location "MCI"}
                             {:type :temperature :value 10 :location "MCI"}
                             {:type :windspeed :value 5 :location "MCI"}
@@ -1070,10 +1025,9 @@
 (defrecord RecordWithDash [test-field])

 (deftest test-bean-with-dash
-  (let [test-query (mk-query [] [[RecordWithDash (= ?f test-field)]])
-
-        session (-> (mk-rulebase test-query)
-                    (mk-session)
+  (let [test-query (dsl/parse-query [] [[RecordWithDash (= ?f test-field)]])
+
+        session (-> (mk-session [test-query])
                     (insert (->RecordWithDash 15)))]

     (is (= #{{:?f 15}}
@@ -1081,17 +1035,16 @@

 (deftest test-no-loop
-  (let [reduce-temp (mk-rule [[?t <- Temperature (> temperature 0) (== ?v temperature)]]
+  (let [reduce-temp (dsl/parse-rule [[?t <- Temperature (> temperature 0) (= ?v temperature)]]
                              (do
                                (retract! ?t)
                                (insert! (->Temperature (- ?v 1) "MCI")))
                              {:no-loop true})

-        temp-query (mk-query [] [[Temperature (== ?t temperature)]])
-
-
-        session (-> (mk-rulebase reduce-temp temp-query)
-                    (mk-session)
+        temp-query (dsl/parse-query [] [[Temperature (= ?t temperature)]])
+
+
+        session (-> (mk-session [reduce-temp temp-query])
                     (insert (->Temperature 10 "MCI"))
                     (fire-rules))]

@@ -1101,7 +1054,7 @@
 (defrule reduce-temp-no-loop
   "Example rule to reduce temperature."
   {:no-loop true}
-  [?t <- Temperature (== ?v temperature)]
+  [?t <- Temperature (= ?v temperature)]
   =>
   (do
     (retract! ?t)
@@ -1112,10 +1065,9 @@
   (let [rule-output (atom nil)
         ;; Insert a new fact and ensure it exists.

-        temp-query (mk-query [] [[Temperature (== ?t temperature)]])
-
-        session (-> (mk-rulebase reduce-temp-no-loop temp-query)
-                    (mk-session)
+        temp-query (dsl/parse-query [] [[Temperature (= ?t temperature)]])
+
+        session (-> (mk-session [reduce-temp-no-loop temp-query])
                     (insert (->Temperature 10 "MCI"))
                     (fire-rules))]

@@ -1125,20 +1077,18 @@

 ;; Test behavior discussed in https://github.com/rbrush/clara-rules/issues/35
 (deftest test-identical-facts
-  (let [ident-query (mk-query [] [[?t1 <- Temperature (= ?loc location)]
-                                [?t2 <- Temperature (= ?loc location)]
-                                [:test (not (identical? ?t1 ?t2))]])
+  (let [ident-query (dsl/parse-query [] [[?t1 <- Temperature (= ?loc location)]
+                                         [?t2 <- Temperature (= ?loc location)]
+                                         [:test (not (identical? ?t1 ?t2))]])

         temp (->Temperature 15 "MCI")
         temp2 (->Temperature 15 "MCI")

-        session (-> (mk-rulebase ident-query)
-                    (mk-session)
+        session (-> (mk-session [ident-query])
                     (insert temp
                             temp))

-        session-with-dups (-> (mk-rulebase ident-query)
-                              (mk-session)
+        session-with-dups (-> (mk-session [ident-query])
                               (insert temp
                                       temp2))]

@@ -1158,7 +1108,7 @@

 ;; An EDN string for testing. This would normally be stored in an external file. The structure simply needs to be a
 ;; sequence of maps matching the clara.rules.schema/Production schema.
-(def external-rules "[{:name \"cold-query\", :params #{:?l}, :lhs [{:type clara.rules.testfacts.Temperature, :constraints [(< temperature 50) (== ?t temperature) (== ?l location)]}]}]")
+(def external-rules "[{:name \"cold-query\", :params #{:?l}, :lhs [{:type clara.rules.testfacts.Temperature, :constraints [(< temperature 50) (= ?t temperature) (= ?l location)]}]}]")

 (deftest test-external-rules
   (let [session (-> (mk-session (edn/read-string external-rules))
@@ -1176,4 +1126,4 @@
            (set (query session "cold-query" :?l "MCI"))))

     (is (= #{{:?l "ORD" :?t 10}}
-           (set (query session "cold-query" :?l "ORD"))))))+           (set (query session "cold-query" :?l "ORD"))))))


->> is better than ->

->> is better than ->

--- clojure/anagrams.clj
+++ clojure/anagrams.clj
@@ -16,5 +16,5 @@
   (do
     (println "Exactly one argument is required")
     (System/exit 1))
-  (let [word (-> *command-line-args* first vec)]
+  (let [word (->> *command-line-args* first vec)]
     (generatePermutations word (dec (count word)))))


Inserts need wrapped values

Inserts need wrapped values

--- src/sdos_site/db.clj
+++ src/sdos_site/db.clj
@@ -58,7 +58,7 @@
                  :content content
                  :category category}]
     (-> (base-articles-query db)
-        (k/insert article))))
+        (k/insert (k/values article)))))

 (defn update-article
   [db {:keys [id date title author content category]}]


Remove `get-spec-keys` fn

Remove `get-spec-keys` fn

--- src/kixi/datastore/metadatastore/command_handler.clj
+++ src/kixi/datastore/metadatastore/command_handler.clj
@@ -224,16 +224,6 @@
                                   :kixi/user (::kc/user cmd)}
                                  payload))))))

-(defn get-spec-keys
-  [spec]
-  (->> spec
-       (s/get-spec)
-       (s/form)
-       (rest)
-       (drop 1)
-       (take-nth 2)
-       (reduce concat)))
-
 (defn create-sharing-change-handler
   [metadatastore]
   (let [authorised (partial ms/authorised metadatastore ::ms/meta-update)]


Adds eqlist?

Adds eqlist?

--- src/the_little_clojurian/chapter5.clj
+++ src/the_little_clojurian/chapter5.clj
@@ -58,7 +58,6 @@
   (is (= (occur* 'orange '((orange (beer)))) 1))
   (is (= (occur* 'orange '((banana split) and (orange) with sherbet (((and orange peanut) butter)))) 2)))

-
 (with-test
   (def subst*
     (fn [new old l]
@@ -113,3 +112,24 @@
   (is (= (leftmost '(apple)) 'apple))
   (is (= (leftmost '((apple))) 'apple))
   (is (= (leftmost '(((hot cider) with (green) tea))) 'hot)))
+
+(with-test
+  (def eqlist?
+    (fn [l1 l2]
+      (cond (and (null? l1) (null? l2)) true
+            (or (null? l1) (null? l2)) false
+            (and (atom? (car l1)) (atom? (car l2))) (and (equan? (car l1) (car l2))
+                                                         (eqlist? (cdr l1) (cdr l2)))
+            (or (atom? (car l1))
+                (atom? (car l2))) false
+            :else (and (eqlist? (car l1) (car l2))
+                       (eqlist? (cdr l1) (cdr l2))))))
+
+  (is (= (eqlist? '() '()) true))
+  (is (= (eqlist? '() '(foot)) false))
+  (is (= (eqlist? '(foot) '()) false))
+  (is (= (eqlist? '(foot) '(foot)) true))
+  (is (= (eqlist? '(foot rub) '(foot sub)) false))
+  (is (= (eqlist? '(strawberry ice cream) '(strawberry ice cream)) true))
+  (is (= (eqlist? '(strawberry ice cream) '(strawberry cream ice)) false))
+  (is (= (eqlist? '((coffee) (cup)) '((coffee) (cup))) true)))


fmtfix

fmtfix

--- src/soy_clj/core.clj
+++ src/soy_clj/core.clj
@@ -76,8 +76,7 @@
                     (newRenderer template-name)
                     (setData (camelize-keys data))
                     (renderStrict))]
-    [(.getContent content)
-     (content-kind (.getContentKind content))]))
+    [(.getContent content) (content-kind (.getContentKind content))]))

 (defn ordain-as-safe
   "Ordains the given content as safe content of the given kind which will not be


Batch timeout can be 0

Batch timeout can be 0

--- src/onyx/schema.cljc
+++ src/onyx/schema.cljc
@@ -68,7 +68,7 @@
    (s/optional-key :onyx/restart-pred-fn)
    (deprecated [:catalog-entry :model :onyx/restart-pred-fn])
    (s/optional-key :onyx/language) Language
-   (s/optional-key :onyx/batch-timeout) PosInt
+   (s/optional-key :onyx/batch-timeout) SPosInt
    (s/optional-key :onyx/doc) s/Str
    (s/optional-key :onyx/bulk?) s/Bool
    (s/optional-key :onyx/max-peers) PosInt


Schema changes to drop depricated ->Both and

improve readability of error messages by applying
value checks as a postcondition.

--- src/onyx/schema.cljc
+++ src/onyx/schema.cljc
@@ -9,8 +9,8 @@
           'keyword-namespaced?))

 (def Function
-  (s/either (s/pred var? 'var?)
-            (s/pred ifn? 'ifn?)))
+  (s/cond-pre (s/pred var? 'var?)
+              (s/pred ifn? 'ifn?)))

 (def TaskName
   (s/pred (fn [v]
@@ -23,30 +23,26 @@
   (= (count edge) 2))

 (def ^{:private true} edge-validator
-  (s/->Both [(s/pred vector? 'vector?)
-             (s/pred edge-two-nodes? 'edge-two-nodes?)
-             [TaskName]]))
+  (s/constrained [TaskName] (fn [edge]
+                              (and (= (count edge) 2)
+                                   (vector? edge))) 'edge-two-nodes?))

 (def Workflow
-  (s/->Both [(s/pred vector? 'vector?)
-             [edge-validator]]))
+  (s/constrained [edge-validator] vector? 'vector?))

 (def Language
   (s/enum :java :clojure))

-(def PosInt
-  (s/pred pos? 'pos?))
-
-(def Record
-  (s/pred record? 'record?))
-
-(def SPosInt
-  (s/pred (fn [v] (>= v 0)) 'spos?))
+(def PosInt
+  (s/constrained s/Int pos? 'pos?))
+
+(def SPosInt
+  (s/constrained s/Int (fn [v] (>= v 0)) 'spos?))

 (defn build-allowed-key-ns [nspace]
   (s/pred (fn [k]
             (or (not (keyword? k))
-                (not (= (name nspace)
+                (not (= (name nspace)
                         (namespace k)))))
           'unsupported-key-combination))

@@ -77,118 +73,121 @@
    (s/optional-key :onyx/required-tags) [s/Keyword]
    UnsupportedTaskMapKey s/Any})

-(def FluxPolicy
+(def FluxPolicy
   (s/enum :continue :kill :recover))
+
+(def FnPath
+  (s/cond-pre NamespacedKeyword s/Keyword))
+
+(def partial-grouping-task
+  {(s/optional-key :onyx/group-by-key) s/Any
+   (s/optional-key :onyx/group-by-fn) FnPath
+   :onyx/flux-policy FluxPolicy})
+
+(defn grouping-task? [task-map]
+  (and (#{:function :output} (:onyx/type task-map))
+       (or (not (nil? (:onyx/group-by-key task-map)))
+           (not (nil? (:onyx/group-by-fn task-map))))))
+
+(def partial-input-task
+  {:onyx/plugin (s/cond-pre NamespacedKeyword s/Keyword)
+   :onyx/medium s/Keyword
+   :onyx/type (s/enum :input)
+   (s/optional-key :onyx/fn) FnPath
+   (s/optional-key :onyx/input-retry-timeout) PosInt
+   (s/optional-key :onyx/pending-timeout) PosInt
+   (s/optional-key :onyx/max-pending) PosInt})
+
+(def partial-output-task
+  {:onyx/plugin (s/cond-pre NamespacedKeyword s/Keyword)
+   :onyx/medium s/Keyword
+   :onyx/type (s/enum :output)
+   (s/optional-key :onyx/fn) FnPath})
+
+(def NonNamespacedKeyword
+  (s/pred (fn [v]
+            (and (keyword? v)
+                 (not (namespace v))))
+          'keyword-non-namespaced))
+
+(def partial-java-plugin
+  {:onyx/plugin NonNamespacedKeyword
+   (s/optional-key :onyx/fn) FnPath})
+
+(def partial-clojure-plugin
+  {:onyx/plugin NamespacedKeyword
+   (s/optional-key :onyx/fn) FnPath})
+
+(def partial-fn-task
+  {:onyx/fn (s/cond-pre NamespacedKeyword s/Keyword)
+   (s/optional-key :onyx/plugin) (s/cond-pre NamespacedKeyword s/Keyword)})
+
+(def partial-clojure-fn-task
+  {:onyx/fn NamespacedKeyword})
+
+(def partial-java-fn-task
+  {:onyx/fn s/Keyword})
+
+(defn java? [task-map]
+  (= :java (:onyx/language task-map)))

 (defn valid-min-peers-max-peers-n-peers? [entry]
   (case (:onyx/flux-policy entry)
-    :continue
+    :continue
     (or (:onyx/n-peers entry)
         (:onyx/min-peers entry)
         (= (:onyx/max-peers entry) 1))
-    :kill
+    :kill
     (or (:onyx/n-peers entry)
         (:onyx/min-peers entry)
         (= (:onyx/max-peers entry) 2))
     :recover
     (or (:onyx/n-peers entry)
         (and (:onyx/max-peers entry)
-             (= (:onyx/max-peers entry)
+             (= (:onyx/max-peers entry)
                 (:onyx/min-peers entry)))
         (= (:onyx/max-peers entry) 1))))

-(def FnPath
-  (s/either NamespacedKeyword s/Keyword))
-
-(def FluxPolicyNPeers
-  (s/pred valid-min-peers-max-peers-n-peers? 'valid-flux-policy-min-max-n-peers))
-
-(def partial-grouping-task
-  {(s/optional-key :onyx/group-by-key) s/Any
-   (s/optional-key :onyx/group-by-fn) FnPath
-   :onyx/flux-policy FluxPolicy})
-
-(defn grouping-task? [task-map]
-  (and (#{:function :output} (:onyx/type task-map))
-       (or (not (nil? (:onyx/group-by-key task-map)))
-           (not (nil? (:onyx/group-by-fn task-map))))))
-
-(def partial-input-task
-  {:onyx/plugin (s/either NamespacedKeyword s/Keyword)
-   :onyx/medium s/Keyword
-   :onyx/type (s/enum :input)
-   (s/optional-key :onyx/fn) FnPath
-   (s/optional-key :onyx/input-retry-timeout) PosInt
-   (s/optional-key :onyx/pending-timeout) PosInt
-   (s/optional-key :onyx/max-pending) PosInt})
-
-(def partial-output-task
-  {:onyx/plugin (s/either NamespacedKeyword s/Keyword)
-   :onyx/medium s/Keyword
-   :onyx/type (s/enum :output)
-   (s/optional-key :onyx/fn) FnPath})
-
-(def NonNamespacedKeyword
-  (s/pred (fn [v]
-            (and (keyword? v)
-                 (not (namespace v))))
-          'keyword-non-namespaced))
-
-(def partial-java-plugin
-  {:onyx/plugin NonNamespacedKeyword
-   (s/optional-key :onyx/fn) FnPath})
-
-(def partial-clojure-plugin
-  {:onyx/plugin NamespacedKeyword
-   (s/optional-key :onyx/fn) FnPath})
-
-(def partial-fn-task
-  {:onyx/fn (s/either NamespacedKeyword s/Keyword)
-   (s/optional-key :onyx/plugin) (s/either NamespacedKeyword s/Keyword)})
-
-(def partial-clojure-fn-task
-  {:onyx/fn NamespacedKeyword})
-
-(def partial-java-fn-task
-  {:onyx/fn s/Keyword})
-
-(defn java? [task-map]
-  (= :java (:onyx/language task-map)))
-
-(def OutputTaskSchema
+(def OutputTaskSchema
   (let [base-output-schema (merge base-task-map partial-output-task)
         base-output-grouping (merge base-output-schema partial-grouping-task)
         java-output-grouping (merge base-output-grouping partial-java-plugin)
         clojure-output-grouping (merge base-output-grouping partial-clojure-plugin)]
     (s/conditional grouping-task?
-                   (s/conditional java?
-                                  (s/->Both [FluxPolicyNPeers java-output-grouping])
+                   (s/conditional java?
+                                  (s/constrained java-output-grouping
+                                                 valid-min-peers-max-peers-n-peers?
+                                                 'valid-flux-policy-min-max-n-peers)
                                   :else
-                                  (s/->Both [FluxPolicyNPeers clojure-output-grouping]))
-                   :else
+                                  (s/constrained clojure-output-grouping
+                                                 valid-min-peers-max-peers-n-peers?
+                                                 'valid-flux-policy-min-max-n-peers))
+                   :else
                    (s/conditional java?
                                   (merge base-output-schema partial-java-plugin)
                                   :else
                                   (merge base-output-schema partial-clojure-plugin)))))

-(def InputTaskSchema
-  (let [base-input-schema (merge base-task-map partial-input-task)]
+(def InputTaskSchema
+  (let [base-input-schema (merge base-task-map partial-input-task)]
     (s/conditional java?
                    (merge base-input-schema partial-java-plugin)
                    :else
                    base-input-schema)))

 (def FunctionTaskSchema
-  (let [base-function-task (merge base-task-map partial-fn-task)]
+  (let [base-function-task (merge base-task-map partial-fn-task)
+        java-function-task (merge base-function-task partial-grouping-task partial-java-fn-task)
+        clojure-function-task (merge base-function-task partial-grouping-task partial-clojure-fn-task)]
     (s/conditional grouping-task?
                    (s/conditional java?
-                                  (s/->Both [FluxPolicyNPeers (merge base-function-task
-                                                                     partial-grouping-task
-                                                                     partial-java-fn-task)])
+                                  (s/constrained java-function-task
+                                                 valid-min-peers-max-peers-n-peers?
+                                                 'valid-flux-policy-min-max-n-peers)
                                   :else
-                                  (s/->Both [FluxPolicyNPeers (merge base-function-task
-                                                                     partial-grouping-task
-                                                                     partial-clojure-fn-task)]))
+                                  (s/constrained clojure-function-task
+                                                 valid-min-peers-max-peers-n-peers?
+                                                 'valid-flux-policy-min-max-n-peers))
                    :else
                    (s/conditional java?
                                   (merge base-function-task partial-java-fn-task)
@@ -196,7 +195,7 @@
                                   (merge base-function-task partial-clojure-fn-task)))))

 (def TaskMap
-  (s/conditional #(= (:onyx/type %) :input)
+  (s/conditional #(= (:onyx/type %) :input)
                  InputTaskSchema
                  #(= (:onyx/type %) :output)
                  OutputTaskSchema
@@ -235,8 +234,8 @@

 (def FlowCondition
   {:flow/from s/Keyword
-   :flow/to (s/either s/Keyword [s/Keyword])
-   :flow/predicate (s/either s/Keyword [s/Any])
+   :flow/to (s/cond-pre s/Keyword [s/Keyword])
+   :flow/predicate (s/cond-pre s/Keyword [s/Any])
    (s/optional-key :flow/post-transform) NamespacedKeyword
    (s/optional-key :flow/thrown-exception?) s/Bool
    (s/optional-key :flow/action) FlowAction
@@ -262,7 +261,7 @@
   {:window/id s/Keyword
    :window/task TaskName
    :window/type WindowType
-   :window/aggregation (s/either s/Keyword [s/Keyword])
+   :window/aggregation (s/cond-pre s/Keyword [s/Keyword])
    (s/optional-key :window/init) s/Any
    (s/optional-key :window/window-key) s/Any
    (s/optional-key :window/min-value) s/Int
@@ -288,25 +287,26 @@
    (s/optional-key :aggregation/super-aggregation-fn) Function})

 (def WindowExtension
-  (s/both Record
-          {:window Window
-           :id s/Keyword
-           :task TaskName
-           :type WindowType
-           :aggregation (s/either s/Keyword [s/Keyword])
-           (s/optional-key :init) (s/maybe s/Any)
-           (s/optional-key :window-key) (s/maybe s/Any)
-           (s/optional-key :min-value) (s/maybe SPosInt)
-           (s/optional-key :range) (s/maybe Unit)
-           (s/optional-key :slide) (s/maybe Unit)
-           (s/optional-key :timeout-gap) (s/maybe Unit)
-           (s/optional-key :session-key) (s/maybe s/Any)
-           (s/optional-key :doc) (s/maybe s/Str)}))
+  (s/constrained
+   {:window Window
+    :id s/Keyword
+    :task TaskName
+    :type WindowType
+    :aggregation (s/cond-pre s/Keyword [s/Keyword])
+    (s/optional-key :init) (s/maybe s/Any)
+    (s/optional-key :window-key) (s/maybe s/Any)
+    (s/optional-key :min-value) (s/maybe SPosInt)
+    (s/optional-key :range) (s/maybe Unit)
+    (s/optional-key :slide) (s/maybe Unit)
+    (s/optional-key :timeout-gap) (s/maybe Unit)
+    (s/optional-key :session-key) (s/maybe s/Any)
+    (s/optional-key :doc) (s/maybe s/Str)}
+   record? 'record?))

 (def TriggerRefinement
   NamespacedKeyword)

-(def TriggerPeriod
+(def TriggerPeriod
   (s/enum :milliseconds :seconds :minutes :hours :days
           :mullisecond :second :minute :hour :day))

@@ -347,47 +347,49 @@

 (def TriggerCall
   {:trigger/init-state Function
-   :trigger/next-state Function
+   :trigger/next-state Function
    :trigger/trigger-fire? Function})

 (def TriggerState
-  (s/both Record
-          {:window-id s/Keyword
-           :refinement TriggerRefinement
-           :on s/Keyword
-           :sync s/Keyword
-           :fire-all-extents? (s/maybe s/Bool)
-           :pred (s/maybe s/Keyword)
-           :watermark-percentage (s/maybe double)
-           :doc (s/maybe s/Str)
-           :period (s/maybe TriggerPeriod)
-           :threshold (s/maybe TriggerThreshold)
-           :sync-fn (s/maybe Function)
-           :state s/Any
-           :id s/Any
-           :trigger Trigger
-           :init-state Function
-           :trigger-fire? Function
-           :next-trigger-state Function
-           :create-state-update Function
-           :apply-state-update Function}))
+  (s/constrained
+   {:window-id s/Keyword
+    :refinement TriggerRefinement
+    :on s/Keyword
+    :sync s/Keyword
+    :fire-all-extents? (s/maybe s/Bool)
+    :pred (s/maybe s/Keyword)
+    :watermark-percentage (s/maybe double)
+    :doc (s/maybe s/Str)
+    :period (s/maybe TriggerPeriod)
+    :threshold (s/maybe TriggerThreshold)
+    :sync-fn (s/maybe Function)
+    :state s/Any
+    :id s/Any
+    :trigger Trigger
+    :init-state Function
+    :trigger-fire? Function
+    :next-trigger-state Function
+    :create-state-update Function
+    :apply-state-update Function}
+   record? 'record?))

 (def StateEvent s/Any)

 (def WindowState
-  (s/both Record
-          {:window-extension WindowExtension
-           :trigger-states [TriggerState]
-           :window Window
-           :state {s/Any s/Any}
-           :state-event StateEvent
-           :event-results [StateEvent]
-           :init-fn Function
-           :create-state-update Function
-           :apply-state-update Function
-           :super-agg-fn (s/maybe Function)
-           (s/optional-key :new-window-state-fn) Function
-           (s/optional-key :grouping-fn) (s/either s/Keyword Function)}))
+  (s/constrained
+   {:window-extension WindowExtension
+    :trigger-states [TriggerState]
+    :window Window
+    :state {s/Any s/Any}
+    :state-event StateEvent
+    :event-results [StateEvent]
+    :init-fn Function
+    :create-state-update Function
+    :apply-state-update Function
+    :super-agg-fn (s/maybe Function)
+    (s/optional-key :new-window-state-fn) Function
+    (s/optional-key :grouping-fn) (s/cond-pre s/Keyword Function)}
+   record? 'record?))

 (def JobScheduler
   NamespacedKeyword)
@@ -417,7 +419,7 @@
    (s/optional-key :acker/exempt-tasks) [s/Keyword]})

 (def TenancyId
-  (s/either s/Uuid s/Str))
+  (s/cond-pre s/Uuid s/Str))

 (def EnvConfig
   {:zookeeper/address s/Str
@@ -517,21 +519,21 @@
    s/Keyword s/Any})

 (def PeerId
-  (s/either s/Uuid s/Keyword))
+  (s/cond-pre s/Uuid s/Keyword))

 (def PeerState
   (s/enum :idle :backpressure :active))

-(def PeerSite
+(def PeerSite
   {s/Any s/Any})

 (def JobId
-  (s/either s/Uuid s/Keyword))
+  (s/cond-pre s/Uuid s/Keyword))

 (def TaskId
-  (s/either s/Uuid s/Keyword))
-
-(def TaskScheduler
+  (s/cond-pre s/Uuid s/Keyword))
+
+(def TaskScheduler
   s/Keyword)

 (def SlotId
@@ -582,11 +584,11 @@
    (s/optional-key :peer-parent) s/Uuid
    (s/optional-key :entry-parent) s/Int})

-(def Reactions
+(def Reactions
   (s/maybe [LogEntry]))

 (def ReplicaDiff
-  (s/maybe (s/either {s/Any s/Any} #{s/Any})))
+  (s/maybe (s/cond-pre {s/Any s/Any} #{s/Any})))

 (def State
   {s/Any s/Any})


Fix typo in lazy-map-test

Fix typo in lazy-map-test

This was noticed by pjstadig/humane-test-output!

--- cortex/test/cljc/cortex/util_test.cljc
+++ cortex/test/cljc/cortex/util_test.cljc
@@ -144,8 +144,8 @@
     (is (= (-> (make-lazy-map)
              (dissoc :a :b)
              (keys)
-             (set)
-             #{:c}))))
+             (set))
+           #{:c})))
   (testing "lazy maps support default value for lookup"
     (is (= (:d (make-lazy-map) :default)
            :default))


removed commented code

removed commented code

--- src/ophion/query.clj
+++ src/ophion/query.clj
@@ -112,14 +112,6 @@
           (search/search connection label search))]
     (mapv :id results)))

-;; (defn search-index
-;;   [connection label ^GraphTraversalSource g {:keys [term search]}]
-;;   (let [results
-;;         (if term
-;;           (search/search connection label term search)
-;;           (search/search connection label search))]
-;;     (.V g (into-array (mapv :id results)))))
-
 (defn V
   [^GraphTraversalSource g vs]
   (.V g (into-array vs)))


limiting edges during query

limiting edges during query

--- src/ophion/query.clj
+++ src/ophion/query.clj
@@ -521,9 +521,13 @@
 (defn edges-for
   ([vertex] (edges-for vertex []))
   ([vertex labels] (edges-for vertex labels :both))
-  ([vertex labels direction]
-   (let [D (get directions direction)]
-     (iterator-seq (.edges vertex D (into-array String labels))))))
+  ([vertex labels direction] (edges-for vertex labels :both nil))
+  ([vertex labels direction limit]
+   (let [D (get directions direction)
+         it (iterator-seq (.edges vertex D (into-array String labels)))]
+     (if limit
+       (take limit it)
+       it))))

 (defn edge-properties
   [edge]
@@ -581,8 +585,8 @@
   ([vertex limit]
    (if vertex
      (let [props (vertex-properties vertex)
-           in (in-edge-map (edges-for vertex [] :in) universal-key limit)
-           out (out-edge-map (edges-for vertex [] :out) universal-key limit)]
+           in (in-edge-map (edges-for vertex [] :in limit) universal-key)
+           out (out-edge-map (edges-for vertex [] :out limit) universal-key)]
        (assoc props "in" in "out" out))
      {})))


Fix bugs in staggered union empty cases.

--- src/setbang/core.clj
+++ src/setbang/core.clj
@@ -16,6 +16,7 @@
             (if (= s (into #{} (range (count x))))
               (count x)
               s))
+        (empty? x) 0
         :else (map normalize x)))

 (defn is-mumber? [x]
@@ -136,10 +137,12 @@
                           (inc n)))))))

 (defn staggered-union [xs]
-  (lazy-seq
-   (let [ys (stagger xs)
-         y1 (first ys)]
-     (cons y1 (remove #(equality-check % y1) ys)))))
+  (if (empty? xs) ()
+      (lazy-seq
+       (let [ys (stagger xs)]
+         (if-let [y1 (first ys)]
+           (cons y1 (remove #(equality-check % y1) ys))
+           ())))))

 (defn gen-union [x-set]
   (cond


Add doo-all-tests for karma runners

Add doo-all-tests for karma runners

Bug: the total test count is artificially set to 0

--- library/src/doo/runner.clj
+++ library/src/doo/runner.clj
@@ -5,18 +5,25 @@
 (defmacro count-tests [namespaces]
   `(+ ~@(map (fn [ns]
                (count (filter #(:test (nth % 1) false)
-                        (cljs.analyzer.api/ns-publics (second ns)))))
+                        (cljs.analyzer.api/ns-publics ns))))
           namespaces)))

 (defmacro doo-all-tests []
   `(doo.runner/set-entry-point!
-     (fn [] (cljs.test/run-all-tests))))
+     (if (doo.runner/karma?)
+       (fn [tc#]
+         (jx.reporter.karma/start tc# 0)
+         (cljs.test/run-all-tests #".*"
+           (cljs.test/empty-env :jx.reporter.karma/karma)))
+       (fn []
+         (cljs.test/run-all-tests)))))

 (defmacro doo-tests [& namespaces]
   `(doo.runner/set-entry-point!
      (if (doo.runner/karma?)
        (fn [tc#]
-         (jx.reporter.karma/start tc# (doo.runner/count-tests ~namespaces))
+         (jx.reporter.karma/start tc#
+           (doo.runner/count-tests ~(map second namespaces)))
          (cljs.test/run-tests
            (cljs.test/empty-env :jx.reporter.karma/karma)
            ~@namespaces))


Modify octave jumps

Modify octave jumps

--- src/tenor/melody.clj
+++ src/tenor/melody.clj
@@ -20,19 +20,19 @@

 (defn up-leap [degree]
   "One leap up in the scale (More than 2 semitones)."
-  (+ (rand-nth [2 3 4 5 6 7]) degree))
+  (+ (rand-nth [2 3 4 5 6]) degree))

 (defn down-leap [degree]
   "One leap down in the scale (More than 2 semitones)."
-  (- (rand-nth [2 3 4 5 6 7]) degree))
+  (- (rand-nth [2 3 4 5 6]) degree))

 (defn up-octave [degree]
   "One perfect octave up (Example: C3 to C4)."
-  (+ 8 degree))
+  (+ 7 degree))

 (defn down-octave [degree]
   "One perfect octave down (Example: C4 to C3)."
-  (- 8 degree))
+  (- 7 degree))

 (defn weighted-random-interval-jumps [scale degree]
   "Generate an interval jump using weighted random selection,


Add db aliases for blob unpacking

Add db aliases for blob unpacking

--- src/cavm/h2.clj
+++ src/cavm/h2.clj
@@ -226,6 +226,15 @@
    `valueType` varchar(255) NOT NULL,
    `visibility` varchar(255),
    FOREIGN KEY (`field_id`) REFERENCES `field` (`id`) ON DELETE CASCADE)"])
+
+;
+; blob unpacking
+;
+
+(def unpack-aliases
+  ["CREATE ALIAS IF NOT EXISTS unpack FOR \"unpack_rows.unpack\""
+   "CREATE ALIAS IF NOT EXISTS unpackCode FOR \"unpack_rows.unpackCode\""
+   "CREATE ALIAS IF NOT EXISTS unpackValue FOR \"unpack_rows.unpackValue\""])

 (declare code)
 (defentity feature
@@ -951,7 +960,8 @@
     (exec-statements feature-table)
     (exec-statements code-table)
     (exec-statements field-position-table)
-    (exec-statements field-gene-table)))
+    (exec-statements field-gene-table)
+    (exec-statements unpack-aliases)))

 ;
 ; add TABLE handling for honeysql


Docstring fix.

Docstring fix.

--- src/oc/storage/util/migrate_bookmarks.clj
+++ src/oc/storage/util/migrate_bookmarks.clj
@@ -1,6 +1,6 @@
 (ns oc.storage.util.migrate-bookmarks
   "Get all the existing uncompleted follow-ups and create a bookmark for every one of them.
-   To perform a dry run and simulate the update run:
+   To perform a dry run and simulate the update use:

   lein run -m oc.storage.util.migrate-bookmark

@@ -9,6 +9,7 @@
   lein run -m oc.storage.util.migrate-bookmark -f

   Use -s/--self-only to create bookmarks only for self created follow-ups."
+
   (:require [clojure.string :as s]
             [rethinkdb.query :as r]
             [clojure.walk :refer (keywordize-keys)]


Update response->edn logic

Update response->edn logic

--- src/zirconia/utils.cljs
+++ src/zirconia/utils.cljs
@@ -43,16 +43,28 @@
   [data]
   (let [keys (map first data)]
     (if (not= (count keys) (count (distinct keys)))
-      (loop [data data next-col [] x []]
+      (loop [data data
+             next-col []
+             prev-key nil
+             x []]
         (if (empty? data)
           (conj x (into {} next-col))
-          (if (some #{(ffirst data)} (map first next-col))
-            (recur (rest data)
-                   [(first data)]
-                   (conj x (into {} next-col)))
-            (recur (rest data)
-                   (conj next-col (first data))
-                   x))))
+          ;; for beats tags when duplicate keys returned
+          ;; for the same record :\
+          (let [next-key (ffirst data)]
+            (if (= prev-key next-key)
+              (recur (rest data) next-col prev-key x)
+              ;; if previous key already exists in record
+              ;; move on to next
+              (if (some #{next-key} (map first next-col))
+                (recur (rest data)
+                       [(first data)]
+                       next-key
+                       (conj x (into {} next-col)))
+                (recur (rest data)
+                       (conj next-col (first data))
+                       next-key
+                       x))))))

       (into {} data))))


Add more error checking

Add more error checking

--- src/re_frame_async_flow_fx/core.cljs
+++ src/re_frame_async_flow_fx/core.cljs
@@ -33,14 +33,16 @@
         when->fn {:seen? all-events-seen? :all-events-seen? all-events-seen? :any-events-seen? any-events-seen?}]
     (->> rules
          (map-indexed (fn [index {:keys [when events dispatch]}]
+                        (let [w #(when->fn when)
+                              _  (if-not w (js/console.error "aync-flow: found illegal value for :when: " when))]
                         {:id        index
-                         :when      #(when->fn when)
+                         :when      w
                          :events    (if (seq events) (set events) #{events})
                          :disptach  (cond
                                       (vector? dispatch)  (list dispatch)
                                       (list? dispatch)    (map (fn [d] (if (= d :halt) halt-event d) dispatch))
                                       (= :halt dispatch)  (list halt-event)
-                                      :else  (js/console.error "aync-flow: dispatch value not valid: " dispatch))})))))
+                                      :else  (js/console.error "aync-flow: dispatch value not valid: " dispatch))}))))))

 (defn make-flow-event-handler


put arrows on edges

put arrows on edges

--- src/splash/core.cljs
+++ src/splash/core.cljs
@@ -206,6 +206,33 @@
               ])
         )

+
+    (go
+      (loop [n 1000]
+        (when (pos? n)
+          (<! (events/next-frame))
+          (recur (dec n))))
+      (let [left-arrow (font/make-text "100 48px Indie Flower" left)
+              right-arrow (font/make-text "100 48px Indie Flower" right)]
+
+          ;;
+          ;; arrows
+          ;;
+          (sprite/set-pos! left-arrow -200 0.0)
+          (sprite/set-pos! right-arrow 200 0.0)
+          (sprite/set-scale! left-arrow 2)
+          (sprite/set-scale! right-arrow 2)
+          (.addChild (-> canvas :layer :ui) left-arrow)
+          (.addChild (-> canvas :layer :ui) right-arrow)
+          (go (loop [n 0]
+                (let [w (.-innerWidth js/window)
+                      hw (/ w 2)
+                      x (* 0.9 hw)]
+                  (sprite/set-pos! left-arrow (- x) 0)
+                  (sprite/set-pos! right-arrow x 0)
+                  (<! (events/next-frame))
+                  (recur (inc n)))))))
+
     ;;
     ;; bouncing name
     ;;


minor bugfixes

minor bugfixes

--- src/splash/core.cljs
+++ src/splash/core.cljs
@@ -31,7 +31,6 @@

 (defonce render-go-block (go (while true
                (<! (events/next-frame))
-               ;(log "frame")
                ((:render-fn canvas)))))

 (defonce load-fonts (font/google ["Indie Flower"]))
@@ -113,7 +112,7 @@
     ;; bouncing name
     ;;
     (sprite/set-alpha! test-text 0.0)
-    (sprite/set-scale! test-text 6)
+    (sprite/set-scale! test-text 5)
     (set! (.-filters test-text) #js [(shaders/make-colour-bars)])
     (.addChild (-> canvas :layer :ui) test-text)
     (resources/fadein test-text :duration 5)
@@ -122,7 +121,7 @@
                 hh (/ h 2)
                 qh (/ h 4)]
             (sprite/set-pos! test-text 0 ;-200
-                             (+ 80 (- (* 0.1 qh (Math/sin (* 0.1 n))) qh))
+                             (+ 0 (- (* 0.1 qh (Math/sin (* 0.1 n))) qh))
                              ))
           (<! (events/next-frame))
           (recur (inc n))))
@@ -172,24 +171,24 @@
                       :alpha 1.0))]
       (macros/with-sprite-set canvas :stars
         [sprs star-spr]
-        (go (loop [c 0]
-              (<! (events/next-frame))
+        (loop [c 0]
+          (<! (events/next-frame))

-              (let [w (.-innerWidth js/window)
-                    h (.-innerHeight js/window)
-                    hw (/ w 2)
-                    hh (/ h 2)
-                    speed -1]
+          (let [w (.-innerWidth js/window)
+                h (.-innerHeight js/window)
+                hw (/ w 2)
+                hh (/ h 2)
+                speed -1]

-                (doall
-                 (map
-                  (fn [{:keys [x y z] :as old} sprite]
-                    (sprite/set-pos! sprite
-                                     (- (mod (- (* 4 x) (* speed c z)) w) hw)
-                                     (- (mod (* 4 y) h) hh)))
-                  stars-set
-                  star-spr)))
+            (doall
+             (map
+              (fn [{:keys [x y z] :as old} sprite]
+                (sprite/set-pos! sprite
+                                 (- (mod (- (* 4 x) (* speed c z)) w) hw)
+                                 (- (mod (* 4 y) h) hh)))
+              stars-set
+              star-spr)))

-              (recur (inc c))))))))
+          (recur (inc c)))))))

 (main)


CMR-1710: Replace single semi-colon with double semi-colon for a comment.

--- common-lib/test/cmr/common/test/date_time_range_parser.clj
+++ common-lib/test/cmr/common/test/date_time_range_parser.clj
@@ -36,8 +36,8 @@
          (t/date-time 1987 1 1 0 0 0) (t/date-time 1988 3 11 2 30 0)

          ;; This test fails in CI due to the issue descirbed in CMR-1737
-         ; "P1Y2M10DT2H30M/2008-05-11T15:30:00Z"
-         ; (t/date-time 2007 3 1 14 0 0) (t/date-time 2008 5 11 15 30 0)
+         ;; "P1Y2M10DT2H30M/2008-05-11T15:30:00Z"
+         ;; (t/date-time 2007 3 1 14 0 0) (t/date-time 2008 5 11 15 30 0)

          ;; This tests fail locally assuming the code is run on a machine
          ;; which is using Eastern Time Zone. But succeeds on a machine using UTC.


removing some nonsense

removing some nonsense


fix indent

fix indent

--- storm-core/test/clj/backtype/storm/grouping_test.clj
+++ storm-core/test/clj/backtype/storm/grouping_test.clj
@@ -21,23 +21,23 @@
   (:use [backtype.storm.daemon common])
   (:require [backtype.storm [thrift :as thrift]]))

- (deftest test-shuffle
-   (with-simulated-time-local-cluster [cluster :supervisors 4]
-     (let [topology (thrift/mk-topology
-                     {"1" (thrift/mk-spout-spec (TestWordSpout. true) :parallelism-hint 4)}
-                     {"2" (thrift/mk-bolt-spec {"1" :shuffle} (TestGlobalCount.)
-                                             :parallelism-hint 6)
-                      })
-           results (complete-topology cluster
-                                      topology
-                                      ;; important for test that
-                                      ;; #tuples = multiple of 4 and 6
-                                      :mock-sources {"1" (->> [["a"] ["b"]]
-                                                              (repeat 12)
-                                                              (apply concat))})]
-       (is (ms= (apply concat (repeat 6 [[1] [2] [3] [4]]))
-                (read-tuples results "2")))
-       )))
+(deftest test-shuffle
+  (with-simulated-time-local-cluster [cluster :supervisors 4]
+    (let [topology (thrift/mk-topology
+                    {"1" (thrift/mk-spout-spec (TestWordSpout. true) :parallelism-hint 4)}
+                    {"2" (thrift/mk-bolt-spec {"1" :shuffle} (TestGlobalCount.)
+                                            :parallelism-hint 6)
+                     })
+          results (complete-topology cluster
+                                     topology
+                                     ;; important for test that
+                                     ;; #tuples = multiple of 4 and 6
+                                     :mock-sources {"1" (->> [["a"] ["b"]]
+                                                             (repeat 12)
+                                                             (apply concat))})]
+      (is (ms= (apply concat (repeat 6 [[1] [2] [3] [4]]))
+               (read-tuples results "2")))
+      )))

 (deftest test-field
   (with-simulated-time-local-cluster [cluster :supervisors 4]


more TODO

more TODO

--- test/com/billpiel/sayid/core_test.clj
+++ test/com/billpiel/sayid/core_test.clj
@@ -943,10 +943,11 @@
 - refator some things in string_output to multimethods?
 x deep-trace :name should just be name. Do string concat in presentation logic
 x test querying w/ deep trace
-- safe print level/length for string out
-- upgrade puget -- use seq-limit
+x safe print level/length for string out
+x upgrade puget -- use seq-limit
+- FIX adding only deep-trace throws execption on execution -- happened in scheduler
+~ test profiling w/ deep trace
 - profile simulated tracer fn
-- test profiling w/ deep trace
 - profiling interface in core
 - rec-save-as should accept keyword or string
 - never return ws or recs from core fns


Fix Firefox would round values up incorrectly

--- src/sinusoides/views/decorators.cljs
+++ src/sinusoides/views/decorators.cljs
@@ -72,8 +72,8 @@
         cols        (max 1 (js/Math.round (/ width grid-size)))
         ratio       (/ grid-margin grid-size)
         size        (/ width (+ cols (* ratio (- cols 1))))
-        margin-px   (str (* ratio size) "px")
-        size-px     (str size "px")
+        margin-px   (str (js/Math.floor (* ratio size)) "px")
+        size-px     (str (js/Math.floor size) "px")
         font-size   (str (/ size grid-size) "em")
         grid-item
         (fn [idx child]


Connections housekeeping

Connections housekeeping

--- src/taoensso/carmine/connections.clj
+++ src/taoensso/carmine/connections.clj
@@ -28,11 +28,14 @@
 (defrecord Connection [^Socket socket spec in out]
   IConnection
   (conn-alive? [this]
-    (if (:listener? spec) true ; TODO Waiting on Ref. http://goo.gl/LPhIO
-      (= "PONG" (try (->> (taoensso.carmine/ping)
-                          (protocol/with-replies)
-                          (protocol/with-context this))
-                     (catch Exception _)))))
+    (if (:listener? spec)
+      true ; TODO Waiting on Ref. http://goo.gl/LPhIO
+      (= "PONG"
+        (try
+          (protocol/with-context this
+            (protocol/with-replies
+              (taoensso.carmine/ping)))
+          (catch Exception _)))))
   (close-conn [_] (.close socket)))

 (defprotocol IConnectionPool
@@ -49,23 +52,27 @@

 ;;;

-(defn make-new-connection [{:keys [host port password timeout-ms db] :as spec}]
+(defn make-new-connection
+  [{:keys [host port password timeout-ms db] :as spec}]
   (let [buff-size 16384 ; Err on the large size since we're pooling
         socket (doto (Socket. ^String host ^Integer port)
                  (.setTcpNoDelay true)
                  (.setKeepAlive true)
                  (.setSoTimeout ^Integer (or timeout-ms 0)))
-        conn (Connection. socket spec (-> (.getInputStream socket)
-                                          (BufferedInputStream. buff-size)
-                                          (DataInputStream.))
-                                      (-> (.getOutputStream socket)
-                                          (BufferedOutputStream. buff-size)))]
-    (when password (->> (taoensso.carmine/auth password)
-                        (protocol/with-replies)
-                        (protocol/with-context conn)))
-    (when (and db (not (zero? db))) (->> (taoensso.carmine/select (str db))
-                                         (protocol/with-replies)
-                                         (protocol/with-context conn)))
+        conn (Connection. socket spec
+               (-> (.getInputStream socket)
+                   (BufferedInputStream. buff-size)
+                   (DataInputStream.))
+               (-> (.getOutputStream socket)
+                   (BufferedOutputStream. buff-size)))
+
+        db (when (and db (not (zero? db)) db))]
+
+    (when (or password db)
+      (protocol/with-context conn
+        (protocol/with-replies ; Discard replies
+          (when password (taoensso.carmine/auth password))
+          (when db       (taoensso.carmine/select (str db))))))
     conn))

 ;; A degenerate connection pool: gives pool-like interface for non-pooled conns


fix repository url

fix repository url

--- ssclj/jar/build.boot
+++ ssclj/jar/build.boot
@@ -16,7 +16,7 @@

 (set-env!
   :repositories
-  #(reduce conj % [["sixsq" {:url "file:///Users/loomis/maven-local/snapshots-community-rhel7"}]])
+  #(reduce conj % [["sixsq" {:url (sixsq-nexus-url)}]])

   :dependencies
   #(vec (concat %


Refactor test code.

Refactor test code.

--- test/om_event_bus/impl_test.clj
+++ test/om_event_bus/impl_test.clj
@@ -27,6 +27,9 @@
   [ch]
   (doall (take-while some? (repeatedly #(safe-take! ch)))))

+(defn matches? [expected actual]
+  (= (sort expected) (sort actual)))
+
 ;=======================================================================================================================

 (deftest bus
@@ -76,8 +79,8 @@

     (testing "triggering"
       (trigger grandchild "event")
-      (is (= (sort ["[child] event" "[parent] event"])
-             (sort (take-all! os)))))
+      (is (matches? ["[child] event" "[parent] event"]
+                           (take-all! os))))
     (testing "shutdown"
       (shutdown parent)
       (trigger grandchild "event")
@@ -91,14 +94,14 @@
         grandchild (add-fork child (fn [e] (async/put! os (str "[grandchild] " e))))]
     (testing "triggering"
       (trigger bus "event")
-      (is (= (sort ["[grandchild] event" "[child] event" "[parent] event"])
-             (sort (take-all! os)))))
+      (is (matches? ["[grandchild] event" "[child] event" "[parent] event"]
+                    (take-all! os))))

     (testing "shutdown"
       (shutdown child)
       (trigger bus "event")
-      (is (= (sort ["[parent] event"])
-             (sort (take-all! os)))))))
+      (is (matches? ["[parent] event"]
+                    (take-all! os))))))

 (deftest event-handler
   (let [parent (event-bus (upstream-router))
@@ -133,24 +136,24 @@
     (testing "broadcasting to all"
      (let [{:keys [os broadcast]} (set-up)]
        (trigger broadcast "event")
-       (is (= (sort ["parent received 'event' from a parent"
-                     "child A received 'event' from a parent"
-                     "child B received 'event' from a parent"])
-              (sort (take-all! os))))))
+       (is (matches? ["parent received 'event' from a parent"
+                      "child A received 'event' from a parent"
+                      "child B received 'event' from a parent"]
+                     (take-all! os)))))

     (testing "sending down from child"
       (let [{:keys [os child-a-down]} (set-up)]
         (trigger child-a-down "event")
-        (is (= (sort ["parent received 'event' from a child"])
-               (sort (take-all! os))))))
+        (is (matches? ["parent received 'event' from a child"]
+                      (take-all! os)))))

     (testing "sending up from parent"
       (let [{:keys [os parent-up]} (set-up)]
         (trigger parent-up "event")

-        (is (= (sort ["child A received 'event' from a parent"
-                      "child B received 'event' from a parent"])
-               (sort (take-all! os))))))))
+        (is (matches? ["child A received 'event' from a parent"
+                       "child B received 'event' from a parent"]
+                      (take-all! os)))))))

 (deftest xforms
   (letfn [(mapping
@@ -170,9 +173,9 @@
             grandchild (add-fork child (fn [e] (async/put! os (str "[grandchild] " e))) (add-info " (pass grandchild)"))
             top (add-leg grandchild)]
         (trigger grandchild "event")
-        (is (= (sort ["[child] event (pass grandchild)"
-                      "[parent] event (pass grandchild) (pass child)"])
-               (sort (take-all! os))))))
+        (is (matches? ["[child] event (pass grandchild)"
+                       "[parent] event (pass grandchild) (pass child)"]
+                      (take-all! os)))))

     (testing "upstream forks"
       (let [os (async/chan 1024)
@@ -181,10 +184,10 @@
             child (add-fork parent (fn [e] (async/put! os (str "[child] " e))) (add-info " (pass child)"))
             grandchild (add-fork child (fn [e] (async/put! os (str "[grandchild] " e))) (add-info " (pass grandchild)"))]
         (trigger bottom "event")
-        (is (= (sort ["[grandchild] event (pass parent) (pass child)"
-                      "[child] event (pass parent)"
-                      "[parent] event"])
-               (sort (take-all! os))))))
+        (is (matches? ["[grandchild] event (pass parent) (pass child)"
+                       "[child] event (pass parent)"
+                       "[parent] event"]
+                      (take-all! os)))))

     (testing "downstream legs"
       (let [os (async/chan 1024)
@@ -193,8 +196,8 @@
             child (add-leg parent (add-info " (pass child)"))
             grandchild (add-leg child (add-info " (pass grandchild)"))]
         (trigger grandchild "event")
-        (is (= (sort ["[parent] event (pass grandchild) (pass child)"])
-               (sort (take-all! os))))))
+        (is (matches? ["[parent] event (pass grandchild) (pass child)"]
+                      (take-all! os)))))

     (testing "upstream legs"
       (let [os (async/chan 1024)
@@ -203,11 +206,9 @@
             child (add-leg parent (add-info " (pass child)"))
             grandchild (add-fork child (fn [e] (async/put! os (str "[grandchild] " e))) (add-info " (pass grandchild)"))]
         (trigger bottom "event")
-        (is (= (sort ["[grandchild] event (pass parent) (pass child)"])
-               (sort (take-all! os))))))))
-
-; TODO: Remove resolve-route and refactor the code.
-; TODO: refactor matching os so (sort ...) isn't necessary.
+        (is (matches? ["[grandchild] event (pass parent) (pass child)"]
+                      (take-all! os)))))))
+
 ; TODO: Attempt to use in core (downstream only).
 ; TODO: Move descriptor-related code to om-event-bus.descriptor.
 ; TODO: Use upstream in core.


Get all builds from Jenkins, don't limit ourselves by arbitrary pagination size 100 of Jenkins API

--- src/buildviz/jenkins/api.clj
+++ src/buildviz/jenkins/api.clj
@@ -11,10 +11,25 @@
   (let [response (get-json jenkins-url "/api/json")]
     (map :name (get response :jobs))))

+
+(defn- builds-response->builds [response job-name]
+  (->> (get response :allBuilds)
+       (map #(assoc % :job-name job-name))))
+
+(def pagination-size 10)
+
+(defn- get-builds-starting-from [jenkins-url job-name offset]
+  (let [offset-end (+ offset pagination-size)
+        response (get-json jenkins-url (format "/job/%s/api/json?tree=allBuilds[number,timestamp,duration,result,actions[lastBuiltRevision[SHA1],remoteUrls]]{%s,%s}" job-name offset offset-end))
+        builds (builds-response->builds response job-name)]
+    (if (> pagination-size (count builds))
+      builds
+      (let [next-offset (+ offset (count builds))]
+        (concat builds
+                (get-builds-starting-from jenkins-url job-name next-offset))))))
+
 (defn get-builds [jenkins-url job-name]
-  (let [response (get-json jenkins-url (format "/job/%s/api/json?tree=builds[number,timestamp,duration,result,actions[lastBuiltRevision[SHA1],remoteUrls]]" job-name))]
-    (->> (get response :builds)
-         (map #(assoc % :job-name job-name)))))
+  (get-builds-starting-from jenkins-url job-name 0))

 (defn get-test-report [jenkins-url job-name build-number]
   (let [test-report-url (format "/job/%s/%s/testReport/api/json" job-name build-number)]


remove unnecessary full-ns reference to `clojure.string`

--- src/vip/data_processor/validation/csv.clj
+++ src/vip/data_processor/validation/csv.clj
@@ -164,7 +164,7 @@
   [columns]
   (-> (comp (filter :required)
             (map :name)
-            (map clojure.string/lower-case))
+            (map str/lower-case))
       (eduction columns)))

 (defn make-row-translation-fn


Save the query to the client

Save the query to the client

Link the server side client caches and the server side queries

--- src/webapp/framework/server/systemfns.clj
+++ src/webapp/framework/server/systemfns.clj
@@ -566,9 +566,20 @@
   (let [
         existing-query     (get @cached-queries   query)
         existing-clients   (get @existing-query  :clients)
+
+        client-queries     (get @(get @realtime-clients   client-id) :queries)
+        this-query         (get @client-queries query)
         ]
-        (swap! existing-clients conj client-id)
-        ))
+    (do
+      (swap! existing-clients conj client-id)
+      (if (not this-query)
+        (swap! client-queries   assoc  query {}))
+      (println "")
+      (println "  add-client-to-query")
+      (println (str "    " @realtime-clients))
+      (println "")
+
+      )))

@@ -721,7 +732,7 @@

    ; ----------------------------------------------------------------
-   ; if this is an normal query
+   ; if this is a normal query
    ; ----------------------------------------------------------------
    :else


set default interpolation to nearest so scaled fonts look oldschool

--- src/splash/core.cljs
+++ src/splash/core.cljs
@@ -15,6 +15,10 @@
                      ))

 (enable-console-print!)
+
+;; makes fonts and text objects scale pixely (GL_NEAREST)
+;; looks better on oldschool games
+(set! (.-scaleModes.DEFAULT js/PIXI) (.-scaleModes.NEAREST js/PIXI))

 (defonce canvas
   (canv/init


Make parser a tiny bit prettier

Make parser a tiny bit prettier

--- src/utree/parser.clj
+++ src/utree/parser.clj
@@ -49,37 +49,41 @@
        (reduce nodify (initial-graph))
        (connect-parents)))

-
 ;;; Structure parser - sections and types

-(defn section-header?
-  [line]
-  (< 1 (count (take-while #(= \- %) line))))
-
-(defn section-type [[line]] (keyword (str/lower-case (str/trim (str/replace line #"^-+\s*" "")))))
+(defn section-type [line]
+  (if (re-seq #"^-+" line)
+    (-> line
+        (str/replace #"^-+" "")
+        (str/trim)
+        (str/lower-case)
+        (keyword))))

 (defn split-sections [lines]
-  (partition-by section-header? lines))
+  (partition-by section-type lines))

-(defmulti parse-section (fn [world type lines] type))
-(defmethod parse-section :utility
-  [world name lines]
-  (into world (hash-map :utility (lines->graph lines))))
+(defn keywordize-headers [coll]
+  (let [headers (map (comp section-type first) (take-nth 2 coll))
+        bodies (take-nth 2 (drop 1 coll))]
+    (map vector headers bodies)))

-(defmethod parse-section :alternatives
-  [world name lines]
-  (into world {:alternatives '()}))
+(def parsers
+  {:utility  lines->graph
+   :alternatives (fn [body] [])})

 (defn parse-world [sects]
-  (reduce
-   (fn [world [header body]] (parse-section world (section-type header) body))
-   {}
-   (partition 2 sects))
-)
+  (loop [world {}
+         ss (seq sects)]
+    (let [[header body] (first ss)]
+      (if (and header body)
+        (recur (assoc world header ((parsers header) body))
+               (next ss))
+        world))))

 (defn parse-file [filename]
   (-> filename
       (slurp)
       (str/split #"\n")
       (split-sections)
+      (keywordize-headers)
       (parse-world)))


Remove ^:const froms state code.

Remove ^:const froms state code.

--- src/uxbox/state.cljs
+++ src/uxbox/state.cljs
@@ -13,11 +13,11 @@

 (defonce state (atom {}))

-(def ^:const auth-l
+(def auth-l
   (-> (l/key :auth)
       (l/focus-atom state)))

-(def ^:const loader-l
+(def loader-l
   (-> (l/key :loader)
       (l/focus-atom state)))


ok *actually* finish speccing voke.entity

--- src/voke/entity.cljs
+++ src/voke/entity.cljs
@@ -5,8 +5,8 @@

 (s/def :entity/id int?)

-(s/def :geometry/x (s/and number? pos?))
-(s/def :geometry/y (s/and number? pos?))
+(s/def :geometry/x number?)
+(s/def :geometry/y number?)
 (s/def :geometry/vector2 (s/keys :req [:geometry/x :geometry/y]))
 (s/def :geometry/direction (s/nilable number?))

@@ -48,12 +48,11 @@
                                        :weapon/fire-direction
                                        :weapon/shots-per-second
                                        :weapon/shot-speed
-                                       :weapon-projectile-color
+                                       :weapon/projectile-color
                                        :weapon/projectile-shape]))

 (s/def :collision/type #{:good-guy
                          :bad-guy
-                         :projectile
                          :obstacle
                          :trap
                          :projectile
@@ -95,15 +94,15 @@

 (defn make-entity
   [entity-map]
-  (assoc entity-map :id (get-next-entity-id)))
+  (assoc entity-map :entity/id (get-next-entity-id)))

 (s/fdef make-entity
   :ret :entity/entity)

 (defn make-input
   []
-  {:intended-move-direction #{}
-   :intended-fire-direction []})
+  #:input {:intended-move-direction #{}
+           :intended-fire-direction []})

 (s/fdef make-input
   :ret :component/input)
@@ -131,8 +130,10 @@
     #:component {:shape     {:shape/width  25
                              :shape/height 25
                              :shape/type   :rectangle
-                             :shape/center {:x x :y y}}
-                 :motion    {:motion/velocity             {:x 0 :y 0}
+                             :shape/center {:geometry/x x
+                                            :geometry/y y}}
+                 :motion    {:motion/velocity             {:geometry/x 0
+                                                           :geometry/y 0}
                              :motion/affected-by-friction true
                              :motion/direction            nil
                              :motion/max-acceleration     2.0
@@ -143,6 +144,7 @@
                  :input     (make-input)}))

 (s/fdef player
+  :args (s/cat :x int? :y int?)
   :ret :entity/entity)

 (defn monster
@@ -151,8 +153,10 @@
     #:component {:shape     {:shape/width  25
                              :shape/height 25
                              :shape/type   :rectangle
-                             :shape/center {:x x :y y}}
-                 :motion    {:motion/velocity             {:x 0 :y 0}
+                             :shape/center {:geometry/x x
+                                            :geometry/y y}}
+                 :motion    {:motion/velocity             {:geometry/x 0
+                                                           :geometry/y 0}
                              :motion/affected-by-friction true
                              :motion/direction            nil
                              :motion/max-acceleration     1.5
@@ -175,7 +179,8 @@
     #:component {:shape     {:shape/width  width
                              :shape/height height
                              :shape/type   :rectangle
-                             :shape/center {:x x :y y}}
+                             :shape/center {:geometry/x x
+                                            :geometry/y y}}
                  :collision {:collision/type :obstacle}
                  :render    {:render/fill 0x333333}}))

@@ -192,8 +197,8 @@
                              :collision/collides-with        collides-with
                              :collision/destroyed-on-contact true}
                  :render    {:render/fill projectile-color}
-                 :motion    {:motion/velocity             {:x x-velocity
-                                                           :y y-velocity}
+                 :motion    {:motion/velocity             {:geometry/x x-velocity
+                                                           :geometry/y y-velocity}
                              :motion/direction            nil
                              :motion/affected-by-friction false
                              :motion/max-speed            (max x-velocity y-velocity)


Use regular read-string for get-version

Use regular read-string for get-version

--- desktop/src/nightweb_desktop/utils.clj
+++ desktop/src/nightweb_desktop/utils.clj
@@ -81,7 +81,7 @@
   []
   (let [project-clj (-> (java.io/resource "project.clj")
                         slurp
-                        edn/read-string)]
+                        read-string)]
     (if (= (name (nth project-clj 1)) "nightweb-desktop")
       (nth project-clj 2)
       "beta")))


Make ensure-keypair return the keypair name.

--- backend/src/circle/backend/ec2.clj
+++ backend/src/circle/backend/ec2.clj
@@ -158,7 +158,9 @@
         (throw e)))))

 (defn describe-keypairs
-  "With no arguments, returns all keypairs. When passed names of keys returns information about only those keys. Returns nil if a specified key can't be found"
+  "With no arguments, returns all keypairs. When passed names of keys
+  returns information about only those keys. Returns nil if a
+  specified key can't be found"
   [& names]
   (with-ec2-client client
     (try
@@ -175,11 +177,12 @@
           (throw e))))))

 (defn ensure-keypair
-  "Makes sure the key is uploaded to AWS. "
+  "Makes sure the key is uploaded to AWS. Returns the keypair name."
   [name pub-key]
   (let [key-name (str name "-" (sha1 pub-key))]
     (when-not (describe-keypairs key-name)
-      (import-keypair key-name pub-key))))
+      (import-keypair key-name pub-key))
+    key-name))

 (defn describe-image [ami]
   (with-ec2-client client