debugging travis error

debugging travis error

--- src/clojento/utils/temp_db.clj
+++ src/clojento/utils/temp_db.clj
@@ -32,7 +32,6 @@
    :delete-on-exit true})

 (defn create-temp-db [ & {:as options} ]
-  (throw (Exception. "my exception message"))
   (let [config   (merge temp-db-defaults options)
         file     (java.io.File/createTempFile (:name-prefix config) ".mv.db")
         absolute (.getAbsolutePath file)


Cosmetic redesign of deftrait macro

Cosmetic redesign of deftrait macro

Drop unnecessary fn and wrapping into a list

--- src/clojure/neko/ui/traits.clj
+++ src/clojure/neko/ui/traits.clj
@@ -16,7 +16,7 @@
             [neko.context :as context]
             [neko.listeners.view :as view-listeners])
   (:use [neko.-utils :only [memoized]])
-  (:import [android.widget LinearLayout$LayoutParams]
+  (:import [android.widget LinearLayout$LayoutParams TextView]
            [android.view View ViewGroup$LayoutParams]
            android.util.TypedValue
            java.util.HashMap))
@@ -67,9 +67,10 @@
   (let [[docstring args] (if (string? (first args))
                            [(first args) (next args)]
                            [nil args])
-        match-pred (if (> (count args) 1)
-                     (first args) name)
-        codegen-body (last args)
+        [match-pred args] (if-not (vector? (first args))
+                            [(first args) (next args)]
+                            [name args])
+        codegen-body args
         dissoc-fn `(fn [a#] (dissoc a# ~name))]
     `(do
        (alter-meta! #'apply-trait
@@ -77,7 +78,7 @@
        (defmethod apply-trait ~name
          [trait# widget# attributes# options#]
          (if (~match-pred attributes#)
-           (let [result# (~codegen-body widget# attributes# options#)]
+           (let [result# ((fn ~@codegen-body) widget# attributes# options#)]
              (if (map? result#)
                [(:attributes-fn result# ~dissoc-fn)
                 (:options-fn result# identity)]
@@ -93,19 +94,18 @@

   Example: `[:button {:def ok}]` defines a var `ok` which stores the
   button object."
-  (fn [wdg attributes _]
-    (let [sym (:def attributes)]
-      (intern (symbol (namespace sym)) (symbol (name sym)) wdg))))
+  [wdg {:keys [def]} _]
+  (intern (symbol (namespace def)) (symbol (name def)) wdg))

 ;; ### Basic traits

 (deftrait :text
   "Sets widget's text to a string, integer ID or a keyword
   representing the string resource provided to `:text` attribute."
-  (fn [wdg {:keys [text]} _]
-    (.setText ^android.widget.TextView wdg (if (keyword? text)
-                                             ^int (res/get-string text)
-                                             ^String text))))
+  [^TextView wdg, {:keys [text]} _]
+  (if (keyword? text)
+    (.setText wdg ^int (res/get-string text))
+    (.setText wdg ^CharSequence text)))

 ;; ### Layout parameters attributes

@@ -130,17 +130,17 @@
   attributes and sets a proper LayoutParams according to container
   type."
   #(some % [:layout-width :layout-height :layout-weight])
-  (fn [wdg {:keys [layout-width layout-height layout-weight]}
-      {:keys [container-type]}]
-    (case (kw/keyword-by-classname container-type)
-      :linear-layout
-      (.setLayoutParams ^View
-       wdg (linear-layout-params layout-width layout-height layout-weight))
-
-      (.setLayoutParams ^View
-       wdg (default-layout-params layout-width layout-height)))
-    {:attributes-fn #(dissoc % :layout-width :layout-height
-                             :layout-weight)}))
+  [^View wdg, {:keys [layout-width layout-height layout-weight]}
+   {:keys [container-type]}]
+  (case (kw/keyword-by-classname container-type)
+    :linear-layout
+    (.setLayoutParams
+     wdg (linear-layout-params layout-width layout-height layout-weight))
+
+    (.setLayoutParams
+     wdg (default-layout-params layout-width layout-height)))
+  {:attributes-fn #(dissoc % :layout-width :layout-height
+                           :layout-weight)})

 (defn- kw->unit-id [unit-kw]
   (case unit-kw
@@ -173,66 +173,64 @@
   vectors like `[number unit-kw]`, where unit keyword is one of the
   following: :px, :dip, :sp, :pt, :in, :mm."
   #(some % [:padding :padding-bottom :padding-left :padding-right :padding-top])
-  (fn [wdg {:keys [padding padding-bottom padding-left
-                  padding-right padding-top]} _]
-    (.setPadding ^View wdg
-                 (padding-value->pixels (or padding-left padding 0))
-                 (padding-value->pixels (or padding-top padding 0))
-                 (padding-value->pixels (or padding-right padding 0))
-                 (padding-value->pixels (or padding-bottom padding 0)))
-    {:attributes-fn #(dissoc % :padding :padding-bottom :padding-left
-                             :padding-right :padding-top)}))
+  [wdg {:keys [padding padding-bottom padding-left
+               padding-right padding-top]} _]
+  (.setPadding ^View wdg
+               (padding-value->pixels (or padding-left padding 0))
+               (padding-value->pixels (or padding-top padding 0))
+               (padding-value->pixels (or padding-right padding 0))
+               (padding-value->pixels (or padding-bottom padding 0)))
+  {:attributes-fn #(dissoc % :padding :padding-bottom :padding-left
+                           :padding-right :padding-top)})

 (deftrait :container
-  "Puts the type of the widget its type into the options map so
-  subelement can use the container type to choose the correct
-  LayoutParams instance."
+  "Puts the type of the widget onto the options map so subelement can
+  use the container type to choose the correct LayoutParams instance."
   (constantly true)
-  (fn [wdg _ __]
-    {:options-fn #(assoc % :container-type (type wdg))}))
+  [wdg _ __]
+  {:options-fn #(assoc % :container-type (type wdg))})

 ;; ### Listener traits

 (deftrait :on-click
   "Takes :on-click attribute, which should be function of one
   argument, and sets it as an OnClickListener for the widget."
-  (fn [wdg {:keys [on-click]} _]
-    (.setOnClickListener ^View wdg (view-listeners/on-click-call on-click))))
+  [^View wdg, {:keys [on-click]} _]
+  (.setOnClickListener wdg (view-listeners/on-click-call on-click)))

 (deftrait :on-create-context-menu
   "Takes :on-create-context-menu attribute, which should be function
   of three arguments, and sets it as an OnCreateContextMenuListener
   for the object."
-  (fn [wdg {:keys [on-create-context-menu]} _]
-    (.setOnCreateContextMenuListener ^View
-     wdg (view-listeners/on-create-context-menu-call on-create-context-menu))))
+  [^View wdg, {:keys [on-create-context-menu]} _]
+  (.setOnCreateContextMenuListener
+   wdg (view-listeners/on-create-context-menu-call on-create-context-menu)))

 (deftrait :on-focus-change
   "Takes :on-focus-change attribute, which should be function of two
   arguments, and sets it as an OnFocusChangeListener for the object."
-  (fn [wdg {:keys [on-focus-change]} _]
-    (.setOnFocusChangeListener ^View
-     wdg (view-listeners/on-focus-change-call on-focus-change))))
+  [^View wdg, {:keys [on-focus-change]} _]
+  (.setOnFocusChangeListener
+   wdg (view-listeners/on-focus-change-call on-focus-change)))

 (deftrait :on-key
   "Takes :on-key attribute, which should be function of three
   arguments, and sets it as an OnKeyListener for the widget."
-  (fn [wdg {:keys [on-key]} _]
-    (.setOnKeyListener ^View wdg (view-listeners/on-key-call on-key))))
+  [^View wdg, {:keys [on-key]} _]
+  (.setOnKeyListener wdg (view-listeners/on-key-call on-key)))

 (deftrait :on-long-click
   "Takes :on-long-click attribute, which should be function of one
   argument, and sets it as an OnLongClickListener for the widget."
-  (fn [wdg {:keys [on-long-click]} code _]
-    (.setOnLongClickListener ^View
-     wdg (view-listeners/on-long-click-call on-long-click))))
+  [^View wdg, {:keys [on-long-click]} _]
+  (.setOnLongClickListener
+   wdg (view-listeners/on-long-click-call on-long-click)))

 (deftrait :on-touch
   "Takes :on-touch attribute, which should be function of two
   arguments, and sets it as an OnTouchListener for the widget."
-  (fn [wdg {:keys [on-touch]} code _]
-    (.setOnTouchListener ^View
-     wdg (view-listeners/on-touch-call on-touch))))
+  [^View wdg, {:keys [on-touch]} _]
+  (.setOnTouchListener wdg (view-listeners/on-touch-call on-touch)))

 ;; ### ID storing traits

@@ -246,15 +244,15 @@
   (def foo (make-ui [:linear-layout {:id-holder true}
                      [:button {:id ::abutton}]]))
   (::abutton (.getTag foo)) => internal Button wdgect."
-  (fn [wdg _ __]
-    (.setTag ^View wdg (HashMap.))
-    {:options-fn #(assoc % :id-holder wdg)}))
+  [^View wdg, _ __]
+  (.setTag wdg (HashMap.))
+  {:options-fn #(assoc % :id-holder wdg)})

 (deftrait :id
   "Takes `:id` attribute, which should be a keyword, and stores the
   current widget in ID-holder's tag (see docs for `:id-holder`
   trait)."
-  (fn [wdg {:keys [id]} {:keys [^View id-holder]}]
-    (if (nil? id-holder)
-      (throw (Exception. ":id trait: id-holder is undefined in this UI tree."))
-      (.put ^HashMap (.getTag id-holder) id wdg))))
+  [wdg {:keys [id]} {:keys [^View id-holder]}]
+  (if (nil? id-holder)
+    (throw (Exception. ":id trait: id-holder is undefined in this UI tree."))
+    (.put ^HashMap (.getTag id-holder) id wdg)))


Druid driver tweaks :unamused:

Druid driver tweaks :unamused:

--- test/metabase/test/data/druid.clj
+++ test/metabase/test/data/druid.clj
@@ -115,12 +115,5 @@
           :destroy-db!                  (constantly nil)}))

-(defn- destroy-druid-test-data
-  {:expectations-options :after-run}
-  []
-  ;; TODO
-  )
-
-;; TODO - spin up a cluster on AWS (?)
 ;; TODO - don't log druid query during sync
 ;; TODO - make `:paging` a feature?


Add in all currently defined syntax/rule props.

--- test/smallex/test/parser/smlx.clj
+++ test/smallex/test/parser/smlx.clj
@@ -23,6 +23,7 @@
           :else
           matched)))

+;; Hack to not increase sizedness of tests by too much.
 (defmacro ^:private change-max-size
   [name max-size]
   `(alter-meta! (var ~name) assoc
@@ -31,15 +32,57 @@
                                            :max-size ~max-size)
                                :test-var (str '~name))))))

-(defspec def-count-equal-to-rule-count
-  (prop/for-all [grammar (gen/fmap str s-gen/grammar)]
-    (let [item-seq (-> grammar StringReader. SMLXLexer. iterator-seq)
-          parsed (smlx/parse item-seq)]
-      (testing "'def' count in legal grammar should be equal to rule count"
-        (is (= (count (:rules parsed))
-               (count (filter #(= :def (:type %)) item-seq))))))))
+(defmacro ^:private deftest-grammar
+  [name bind-names & body]
+  (let [grammar (gensym "grammar")]
+    `(do (defspec ~name
+           (prop/for-all [~grammar (gen/fmap str s-gen/grammar)]
+             (let [~@(interleave bind-names
+                                 `[(-> ~grammar StringReader.
+                                       SMLXLexer. iterator-seq)
+                                   (smlx/parse ~(first bind-names))])]
+               ~@body)))
+         (change-max-size ~name 40))))

-(change-max-size def-count-equal-to-rule-count 40)
+(deftest-grammar def-count-equal-to-rule-count
+  [item-seq grammar]
+  (testing "'def' count in legal grammar should be equal to rule count"
+    (is (= (count (:rules grammar))
+           (count (filter #(= :def (:type %)) item-seq))))))
+
+(deftest-grammar alias-count-equal-to-aliases
+  [item-seq grammar]
+  (testing "'alias' count in legal grammar should be equal to alias count"
+    (is (= (count (:aliases grammar))
+           (count (filter #(= :alias (:type %)) item-seq))))))
+
+(deftest-grammar equivalent-aliases
+  [item-seq grammar]
+  (testing "aliases in grammar and item-seq should be equivalent"
+    (is (= (-> grammar :aliases keys set)
+           (->> item-seq
+                (filter-afterv #(= :alias (:type %)))
+                (map :value)
+                set)))))
+
+(deftest-grammar equivalent-rules
+  [item-seq grammar]
+  (testing "rules in grammar and item-seq should be equivalent"
+    (is (= (-> grammar :rules keys set)
+           (->> item-seq
+                (filter-afterv #(= :def (:type %)))
+                (map :value)
+                set)))))
+
+(deftest-grammar dependent-rule-ordering
+  [item-seq grammar]
+  (testing "rules in grammar is prioritised by ordering from grammar file"
+    (is (= (->> (:rules grammar)
+                (sort-by (fn [[_ expr]] (-> expr meta :priority)))
+                (map key))
+           (->> item-seq
+                (filter-afterv #(= :def (:type %)))
+                (map :value))))))

 (deftest test-clj-spec
   (with-open [rdr (io/reader (io/resource "clojure.smlx"))]


Test username constraints

Test username constraints

--- test/swartz/models/users_test.clj
+++ test/swartz/models/users_test.clj
@@ -5,11 +5,27 @@

 (use-fixtures :each clean-db)

-(deftest test-create
-  (let [username "foobar"
-        password "password"
-        user (users/create<! test-db username password)]
-    (is (= username (:username (first (users/find-all test-db)))))))
+(deftest test-create-with-username-and-password
+  (create-test-user)
+  (is (= (:username user-params)
+         (:username (first (users/find-all test-db))))))
+
+(deftest test-create-with-duplicate-username
+  (create-test-user)
+  (try
+    (create-test-user)
+    (catch Exception e
+      (is (= (class e) org.postgresql.util.PSQLException)))
+    (finally
+      (is (= 1 (count (users/find-all test-db)))))))
+
+(deftest test-create-with-no-username
+  (try
+    (create-test-user (assoc user-params :username nil))
+    (catch Exception e
+      (is (= (class e) org.postgresql.util.PSQLException)))
+    (finally
+      (is (empty? (users/find-all test-db))))))

 (deftest test-find-all
   (let [user1 (users/create<! test-db "foobar" "password")


Change how path creating is done slightly, allowing path override.

--- src/incise/parsers/helpers.clj
+++ src/incise/parsers/helpers.clj
@@ -7,23 +7,26 @@
 (defn dashify
   "Dashify a title, replacing all non word characters with a dash."
   [^String title]
-  (str \/ (-> title
-              (s/lower-case)
-              (s/replace #"[^\w]" "-"))))
+  (-> title
+      (s/lower-case)
+      (s/replace #"[^\w]" "-")))

 (defn date-time->path
   "Convert a DateTime to a path like string."
   [date-time]
   (str (when date-time
-         (str \/ (tm/year date-time)
-              \/ (tm/month date-time)
-              \/ (tm/day date-time)))))
+         (str (tm/year date-time) \/
+              (tm/month date-time) \/
+              (tm/day date-time) \/))))

 (def date-str->path (comp date-time->path tc/from-string))

 (defn Parse->path
-  [^Parse {:keys [date title extension]}]
-  (str (date-str->path date) (dashify title) extension))
+  [^Parse {:keys [path layout date title extension]}]
+  (or path
+      (str (when (= layout :post) (date-str->path date))
+           (dashify title)
+           extension)))

 (defn extension [^File file]
   "Get the extension, enforcing lower case, on the given file."


Mute query logging.

Mute query logging.

--- src/kixi/hecuba/storage/db.clj
+++ src/kixi/hecuba/storage/db.clj
@@ -51,7 +51,6 @@
       this))
   hecuba/Cassandra
   (hecuba/-execute [this query opts]
-    (log/infof "Trying query: %s with opts: %s" (hayt/->raw query) opts)
     (try
       (alia/execute (:session this) (->raw-with-logging query) opts)
       (catch Throwable t (log/errorf t "Query execution failed: %s opts: %s" (hayt/->raw query) opts)


Fix invalid JSON schema for instants

Fix invalid JSON schema for instants

--- src/spec_tools/json_schema.cljc
+++ src/spec_tools/json_schema.cljc
@@ -108,10 +108,9 @@
 (defmethod accept-spec #?(:cljs 'clojure.core/bigdec? :clj 'clojure.future/bigdec?) [_ _ _ _] {:type "number" :format "double"})

-; TODO: FIX TYPE
 ; inst? (fmap #(java.util.Date. %)
 ;             (large-integer))
-(defmethod accept-spec #?(:cljs 'clojure.core/inst? :clj 'clojure.future/inst?) [_ _ _ _] {:type "number" :format "double"})
+(defmethod accept-spec #?(:cljs 'clojure.core/inst? :clj 'clojure.future/inst?) [_ _ _ _] {:type "string" :format "date-time"})

 ; seqable? (one-of [(return nil)
 ;                   (list simple)


Only process exhaust-input if job is still active

--- src/onyx/log/commands/exhaust_input.clj
+++ src/onyx/log/commands/exhaust_input.clj
@@ -4,11 +4,14 @@
             [schema.core :as s]
             [onyx.schema :refer [Replica LogEntry Reactions ReplicaDiff State]]
             [onyx.extensions :as extensions]
+            [taoensso.timbre :refer [info]]
             [onyx.log.commands.common :as common]))

 (s/defmethod extensions/apply-log-entry :exhaust-input :- Replica
   [{:keys [args]} :- LogEntry replica]
-  (update-in replica [:exhausted-inputs (:job args)] union #{(:task args)}))
+  (if (some #{(:job args)} (:jobs replica))
+    (update-in replica [:exhausted-inputs (:job args)] union #{(:task args)})
+    replica))

 (s/defmethod extensions/replica-diff :exhaust-input :- ReplicaDiff
   [{:keys [args]} old new]


Fixed a policy typo and use of wrong symbol for ES

--- src/terraboot/elasticsearch.clj
+++ src/terraboot/elasticsearch.clj
@@ -71,7 +71,7 @@
   (json/generate-string {"Version" "2012-10-17",
                          "Statement" [{"Action" "es:*",
                                        "Principal" "*",
-                                       "Resource" (output-of "aws_elasticsearch_domain" name :arn),
+                                       "Resource" (str (output-of "aws_elasticsearch_domain" name :arn) "/*"),
                                        "Effect" "Allow",
                                        "Condition"
                                        {
@@ -177,7 +177,7 @@
                                                                               (vpc-id-of "aws_security_group" "all-servers")
                                                                               (vpc-id-of "aws_security_group" "elb-kibana")
                                                                               ]
-                                                     :user_data (logstash-user-data-coreos (output-of "aws_elasticsearch_domain" name :domain_name) region)
+                                                     :user_data (logstash-user-data-coreos (output-of "aws_elasticsearch_domain" name :endpoint) region)
                                                      :associate_public_ip_address true
                                                      :subnet_id (vpc-id-of "aws_subnet" "public-a")
                                                      :iam_instance_profile (vpc-id-of "aws_iam_instance_profile" "logstash")})


Fix up flow test with cas chans.

Fix up flow test with cas chans.

--- test/onyx/peer/flow_test.clj
+++ test/onyx/peer/flow_test.clj
@@ -1,7 +1,8 @@
 (ns onyx.peer.flow-test
-  (:require [midje.sweet :refer :all]
-            [onyx.system :refer [onyx-development-env]]
-            [onyx.queue.hornetq-utils :as hq-util]
+  (:require [clojure.core.async :refer [chan >!! <!! close! sliding-buffer]]
+            [midje.sweet :refer :all]
+            [onyx.peer.task-lifecycle-extensions :as l-ext]
+            [onyx.plugin.core-async]
             [onyx.api]))

 (def id (java.util.UUID/randomUUID))
@@ -18,83 +19,69 @@

 (def echo 1000)

-(def people-in-queue (str (java.util.UUID/randomUUID)))
-
-(def colors-in-queue (str (java.util.UUID/randomUUID)))
-
-(def children-out-queue (str (java.util.UUID/randomUUID)))
-
-(def adults-out-queue (str (java.util.UUID/randomUUID)))
-
-(def athletes-wa-out-queue (str (java.util.UUID/randomUUID)))
-
-(def everyone-out-queue (str (java.util.UUID/randomUUID)))
-
-(def red-out-queue (str (java.util.UUID/randomUUID)))
-
-(def blue-out-queue (str (java.util.UUID/randomUUID)))
-
-(def green-out-queue (str (java.util.UUID/randomUUID)))
-
-(def hq-config {"host" (:host (:non-clustered (:hornetq config)))
-                "port" (:port (:non-clustered (:hornetq config)))})
-
-(hq-util/create-queue! hq-config people-in-queue)
-(hq-util/create-queue! hq-config colors-in-queue)
-(hq-util/create-queue! hq-config children-out-queue)
-(hq-util/create-queue! hq-config adults-out-queue)
-(hq-util/create-queue! hq-config athletes-wa-out-queue)
-(hq-util/create-queue! hq-config everyone-out-queue)
-(hq-util/create-queue! hq-config red-out-queue)
-(hq-util/create-queue! hq-config blue-out-queue)
-(hq-util/create-queue! hq-config green-out-queue)
-
-(hq-util/write-and-cap!
- hq-config people-in-queue
- [{:age 24 :job "athlete" :location "Washington"}
-  {:age 17 :job "programmer" :location "Washington"}
-  {:age 18 :job "mechanic" :location "Vermont"}
-  {:age 13 :job "student" :location "Maine"}
-  {:age 42 :job "doctor" :location "Florida"}
-  {:age 64 :job "athlete" :location "Pennsylvania"}
-  {:age 35 :job "bus driver" :location "Texas"}
-  {:age 50 :job "lawyer" :location "California"}
-  {:age 25 :job "psychologist" :location "Washington"}]
- echo)
-
-(hq-util/write-and-cap!
- hq-config colors-in-queue
- [{:color "red" :extra-key "Some extra context for the predicates"}
-  {:color "blue" :extra-key "Some extra context for the predicates"}
-  {:color "white" :extra-key "Some extra context for the predicates"}
-  {:color "green" :extra-key "Some extra context for the predicates"}
-  {:color "orange" :extra-key "Some extra context for the predicates"}
-  {:color "black" :extra-key "Some extra context for the predicates"}
-  {:color "purple" :extra-key "Some extra context for the predicates"}
-  {:color "cyan" :extra-key "Some extra context for the predicates"}
-  {:color "yellow" :extra-key "Some extra context for the predicates"}]
- echo)
+(def people-in-chan (chan (inc n-messages)))
+
+(def colors-in-chan (chan (inc n-messages)))
+
+(def children-out-chan (chan (sliding-buffer (inc n-messages))))
+
+(def adults-out-chan (chan (sliding-buffer (inc n-messages))))
+
+(def athletes-wa-out-chan (chan (sliding-buffer (inc n-messages))))
+
+(def everyone-out-chan (chan (sliding-buffer (inc n-messages))))
+
+(def red-out-chan (chan (sliding-buffer (inc n-messages))))
+
+(def blue-out-chan (chan (sliding-buffer (inc n-messages))))
+
+(def green-out-chan (chan (sliding-buffer (inc n-messages))))
+
+(doseq [x [{:age 24 :job "athlete" :location "Washington"}
+           {:age 17 :job "programmer" :location "Washington"}
+           {:age 18 :job "mechanic" :location "Vermont"}
+           {:age 13 :job "student" :location "Maine"}
+           {:age 42 :job "doctor" :location "Florida"}
+           {:age 64 :job "athlete" :location "Pennsylvania"}
+           {:age 35 :job "bus driver" :location "Texas"}
+           {:age 50 :job "lawyer" :location "California"}
+           {:age 25 :job "psychologist" :location "Washington"}]]
+  (>!! people-in-chan x))
+
+(>!! people-in-chan :done)
+
+(doseq [x [{:color "red" :extra-key "Some extra context for the predicates"}
+           {:color "blue" :extra-key "Some extra context for the predicates"}
+           {:color "white" :extra-key "Some extra context for the predicates"}
+           {:color "green" :extra-key "Some extra context for the predicates"}
+           {:color "orange" :extra-key "Some extra context for the predicates"}
+           {:color "black" :extra-key "Some extra context for the predicates"}
+           {:color "purple" :extra-key "Some extra context for the predicates"}
+           {:color "cyan" :extra-key "Some extra context for the predicates"}
+           {:color "yellow" :extra-key "Some extra context for the predicates"}]]
+  (>!! colors-in-chan x))
+
+(>!! colors-in-chan :done)
+
+(close! people-in-chan)
+(close! colors-in-chan)

 (def catalog
   [{:onyx/name :people-in
-    :onyx/ident :hornetq/read-segments
+    :onyx/ident :core.async/read-from-chan
     :onyx/type :input
-    :onyx/medium :hornetq
-    :onyx/consumption :concurrent
-    :hornetq/queue-name people-in-queue
-    :hornetq/host (:host (:non-clustered (:hornetq config)))
-    :hornetq/port (:port (:non-clustered (:hornetq config)))
-    :onyx/batch-size batch-size}
+    :onyx/medium :core.async
+    :onyx/batch-size batch-size
+    :onyx/max-peers 1
+    :onyx/doc "Reads segments from a core.async channel"}

    {:onyx/name :colors-in
-    :onyx/ident :hornetq/read-segments
+    :onyx/ident :core.async/read-from-chan
     :onyx/type :input
-    :onyx/medium :hornetq
-    :onyx/consumption :concurrent
-    :hornetq/queue-name colors-in-queue
-    :hornetq/host (:host (:non-clustered (:hornetq config)))
-    :hornetq/port (:port (:non-clustered (:hornetq config)))
-    :onyx/batch-size batch-size}
+    :onyx/medium :core.async
+    :onyx/batch-size batch-size
+    :onyx/max-peers 1
+    :onyx/doc "Reads segments from a core.async channel"}

    {:onyx/name :process-children
     :onyx/fn :onyx.peer.flow-test/process-children
@@ -139,74 +126,87 @@
     :onyx/batch-size batch-size}

    {:onyx/name :children-out
-    :onyx/ident :hornetq/write-segments
-    :onyx/type :output
-    :onyx/medium :hornetq
-    :onyx/consumption :concurrent
-    :hornetq/queue-name children-out-queue
-    :hornetq/host (:host (:non-clustered (:hornetq config)))
-    :hornetq/port (:port (:non-clustered (:hornetq config)))
-    :onyx/batch-size batch-size}
+    :onyx/ident :core.async/write-to-chan
+    :onyx/type :output
+    :onyx/medium :core.async
+    :onyx/batch-size batch-size
+    :onyx/max-peers 1
+    :onyx/doc "Writes segments to a core.async channel"}

    {:onyx/name :adults-out
-    :onyx/ident :hornetq/write-segments
-    :onyx/type :output
-    :onyx/medium :hornetq
-    :onyx/consumption :concurrent
-    :hornetq/queue-name adults-out-queue
-    :hornetq/host (:host (:non-clustered (:hornetq config)))
-    :hornetq/port (:port (:non-clustered (:hornetq config)))
-    :onyx/batch-size batch-size}
+    :onyx/ident :core.async/write-to-chan
+    :onyx/type :output
+    :onyx/medium :core.async
+    :onyx/batch-size batch-size
+    :onyx/max-peers 1
+    :onyx/doc "Writes segments to a core.async channel"}

    {:onyx/name :athletes-wa-out
-    :onyx/ident :hornetq/write-segments
-    :onyx/type :output
-    :onyx/medium :hornetq
-    :onyx/consumption :concurrent
-    :hornetq/queue-name athletes-wa-out-queue
-    :hornetq/host (:host (:non-clustered (:hornetq config)))
-    :hornetq/port (:port (:non-clustered (:hornetq config)))
-    :onyx/batch-size batch-size}
+    :onyx/ident :core.async/write-to-chan
+    :onyx/type :output
+    :onyx/medium :core.async
+    :onyx/batch-size batch-size
+    :onyx/max-peers 1
+    :onyx/doc "Writes segments to a core.async channel"}

    {:onyx/name :everyone-out
-    :onyx/ident :hornetq/write-segments
-    :onyx/type :output
-    :onyx/medium :hornetq
-    :onyx/consumption :concurrent
-    :hornetq/queue-name everyone-out-queue
-    :hornetq/host (:host (:non-clustered (:hornetq config)))
-    :hornetq/port (:port (:non-clustered (:hornetq config)))
-    :onyx/batch-size batch-size}
+    :onyx/ident :core.async/write-to-chan
+    :onyx/type :output
+    :onyx/medium :core.async
+    :onyx/batch-size batch-size
+    :onyx/max-peers 1
+    :onyx/doc "Writes segments to a core.async channel"}

    {:onyx/name :red-out
-    :onyx/ident :hornetq/write-segments
-    :onyx/type :output
-    :onyx/medium :hornetq
-    :onyx/consumption :concurrent
-    :hornetq/queue-name red-out-queue
-    :hornetq/host (:host (:non-clustered (:hornetq config)))
-    :hornetq/port (:port (:non-clustered (:hornetq config)))
-    :onyx/batch-size batch-size}
+    :onyx/ident :core.async/write-to-chan
+    :onyx/type :output
+    :onyx/medium :core.async
+    :onyx/batch-size batch-size
+    :onyx/max-peers 1
+    :onyx/doc "Writes segments to a core.async channel"}

    {:onyx/name :blue-out
-    :onyx/ident :hornetq/write-segments
-    :onyx/type :output
-    :onyx/medium :hornetq
-    :onyx/consumption :concurrent
-    :hornetq/queue-name blue-out-queue
-    :hornetq/host (:host (:non-clustered (:hornetq config)))
-    :hornetq/port (:port (:non-clustered (:hornetq config)))
-    :onyx/batch-size batch-size}
+    :onyx/ident :core.async/write-to-chan
+    :onyx/type :output
+    :onyx/medium :core.async
+    :onyx/batch-size batch-size
+    :onyx/max-peers 1
+    :onyx/doc "Writes segments to a core.async channel"}

    {:onyx/name :green-out
-    :onyx/ident :hornetq/write-segments
-    :onyx/type :output
-    :onyx/medium :hornetq
-    :onyx/consumption :concurrent
-    :hornetq/queue-name green-out-queue
-    :hornetq/host (:host (:non-clustered (:hornetq config)))
-    :hornetq/port (:port (:non-clustered (:hornetq config)))
-    :onyx/batch-size batch-size}])
+    :onyx/ident :core.async/write-to-chan
+    :onyx/type :output
+    :onyx/medium :core.async
+    :onyx/batch-size batch-size
+    :onyx/max-peers 1
+    :onyx/doc "Writes segments to a core.async channel"}])
+
+(defmethod l-ext/inject-lifecycle-resources :people-in
+  [_ _] {:core.async/chan people-in-chan})
+
+(defmethod l-ext/inject-lifecycle-resources :colors-in
+  [_ _] {:core.async/chan colors-in-chan})
+
+(defmethod l-ext/inject-lifecycle-resources :children-out
+  [_ _] {:core.async/chan children-out-chan})
+
+(defmethod l-ext/inject-lifecycle-resources :adults-out
+  [_ _] {:core.async/chan adults-out-chan})
+
+(defmethod l-ext/inject-lifecycle-resources :athletes-wa-out
+  [_ _] {:core.async/chan athletes-wa-out-chan})
+
+(defmethod l-ext/inject-lifecycle-resources :everyone-out
+  [_ _] {:core.async/chan everyone-out-chan})
+
+(defmethod l-ext/inject-lifecycle-resources :red-out
+  [_ _] {:core.async/chan red-out-chan})
+
+(defmethod l-ext/inject-lifecycle-resources :blue-out
+  [_ _] {:core.async/chan blue-out-chan})
+
+(defmethod l-ext/inject-lifecycle-resources :green-out
+  [_ _] {:core.async/chan green-out-chan})

 (def workflow
   [[:people-in :process-children]


Simplify images dashboard initialization event impl.

--- src/uxbox/main/data/images.cljs
+++ src/uxbox/main/data/images.cljs
@@ -30,21 +30,12 @@
           (assoc-in [:dashboard :images] data)
           (assoc-in [:dashboard :section] :dashboard/images))))

-  ;; rs/EffectEvent
-  ;; (-apply-effect [_ state]
-  ;;   (when (nil? (:image-colls-by-id state))
-  ;;     (reset! st/loader true)))
-
-  rs/WatchEvent
-  (-apply-watch [_ state s]
-    (if (nil? (:image-colls-by-id state))
-      (rx/merge
-       (rx/of (fetch-collections))
-         (->> (rx/filter collections-fetched? s)
-              (rx/take 1)
-              (rx/do #(reset! st/loader false))
-              (rx/ignore)))
-      (rx/empty))))
+  rs/WatchEvent
+  (-apply-watch [_ state s]
+    (rx/merge
+     (rx/of (fetch-collections))
+     (when (uuid? id)
+       (rx/of (fetch-images id))))))

 (defn initialize
   [type id]


Document job-execution-context.

Document job-execution-context.

--- src/fhofherr/simple/core/job_execution.clj
+++ src/fhofherr/simple/core/job_execution.clj
@@ -1,4 +1,15 @@
 (ns fhofherr.simple.core.job-execution
+  "Create and manage job executions.
+
+  Job executions represent a single execution of a Simple CI job. A job
+  execution owns a [[job-descriptor]]. During its lifetime a job execution
+  transitions through the following states:
+
+  * *created*: the job execution has just been created.
+  * *queued*: the job execution has been queued for execution. It has not been
+    executed yet.
+  * *executing*: the job execution is currently executing.
+  * *finished*: the job execution is finished executing."
   (:require [fhofherr.simple.core [status-model :as sm]
              [job-execution-context :as ex-ctx]]))

@@ -10,7 +21,7 @@
                                     (keys)
                                     (set)))

-(defrecord JobExecution [state context]
+(defrecord ^{:no-doc true} JobExecution [state context]

   sm/Stateful
   (current-state [^JobExecution this] (:state this))
@@ -28,31 +39,38 @@
           (get possible-state-transitions $)
           (contains? $ s))))

+(alter-meta! #'->JobExecution assoc :no-doc true)
+(alter-meta! #'map->JobExecution assoc :no-doc true)
+
 (defn job-execution?
   "Check if `obj` is a job execution"
   [obj]
   (instance? JobExecution obj))

 (defn make-job-execution
-  [context]
-  (map->JobExecution {:context context
+  "Create a new job execution and make it owner of the job execution
+  context `ctx`."
+  [ctx]
+  (map->JobExecution {:context ctx
                       :state ::created}))
 (defn created?
+  "Check if `job-exec`s state is *created*."
   [^JobExecution job-exec]
   (= ::created (sm/current-state job-exec)))

 (defn mark-queued
+  "Mark `job-exec` as *queued*."
   [^JobExecution job-exec]
   (sm/transition-to-state job-exec ::queued))

 (defn queued?
+  "Check if `job-exec`s state is *queued*."
   [^JobExecution job-exec]
   (= ::queued (sm/current-state job-exec)))

 (defn update-context
-  "Apply the function `f` job the job execuction `job-exec`'s
-  job execution context and replace the old context with the new one.
-  `f` must return another job execution context."
+  "Apply the function `f` job the job execuction `job-exec`'s job execution
+  context. Replace the old context with the new one returned by `f`."
   [^JobExecution job-exec f & args]
   (letfn [(apply-f [ctx]
             {:post [(ex-ctx/job-execution-context? %)]}
@@ -60,16 +78,19 @@
     (update-in job-exec [:context] apply-f)))

 (defn mark-executing
+  "Mark `job-exec` as *executing*."
   [^JobExecution job-exec]
   (as-> job-exec $
         (update-context $ ex-ctx/mark-executing)
         (sm/transition-to-state $ ::executing)))

 (defn executing?
+  "Check if `job-exec`s state is *executing*."
   [^JobExecution job-exec]
   (= ::executing (sm/current-state job-exec)))

 (defn mark-finished
+  "Mark `job-exec` as *finished*."
   [^JobExecution job-exec]
   (letfn [(update-ctx [ctx] (if (ex-ctx/failed? ctx)
                               ctx
@@ -79,5 +100,6 @@
           (sm/transition-to-state $ ::finished))))

 (defn finished?
+  "Check if `job-exec`s state is *finished*."
   [^JobExecution job-exec]
   (= ::finished (sm/current-state job-exec)))


Remove unused code.

Remove unused code.

--- src/uxbox/main/ui/shapes/selection.cljs
+++ src/uxbox/main/ui/shapes/selection.cljs
@@ -165,15 +165,11 @@
             (dom/stop-propagation event)
             (rlocks/acquire! :shape/resize)
             (start-path-edition id index))]
-    (let [
-          ;;tmx (geom/transformation-matrix shape)
-          ;;points (map #(gpt/transform % tmx) points)
-          ]
-      [:g.controls
-       (for [[index {:keys [x y]}] (map-indexed vector points)]
-         [:circle {:cx x :cy y :r 3
-                   :on-mouse-down (partial on-mouse-down index)
-                   :fill "red"}])])))
+    [:g.controls
+     (for [[index {:keys [x y]}] (map-indexed vector points)]
+       [:circle {:cx x :cy y :r 3
+                 :on-mouse-down (partial on-mouse-down index)
+                 :fill "red"}])]))

 (mx/defc selection-handlers
   {:mixins [mx/reactive mx/static]}


Korjattu klusterin nimi

Korjattu klusterin nimi

--- clj-test-utils/src/clj_test_utils/elasticsearch_mock_utils.clj
+++ clj-test-utils/src/clj_test_utils/elasticsearch_mock_utils.clj
@@ -11,7 +11,7 @@
       (reset! embedded-elastic (-> (EmbeddedElastic/builder)
                                    (.withElasticVersion "6.0.0")
                                    (.withSetting PopularProperties/HTTP_PORT port)
-                                   (.withSetting PopularProperties/CLUSTER_NAME "my_cluster")
+                                   (.withSetting PopularProperties/CLUSTER_NAME "elasticsearch")
                                    (.build)))
       (.start @embedded-elastic))


Assume larger cost for join

Assume larger cost for join

--- sre/src/ingraph/sre/ingraph_proto_1.clj
+++ sre/src/ingraph/sre/ingraph_proto_1.clj
@@ -197,7 +197,7 @@
   Join [source edge target]
   Vertex [source] Vertex [target] -> DirectedEdge [source edge target])
 (defweight
-  Join [op & rest] 0.5)
+  Join [op & rest] 5)
 (deftask
   Join
   (let [[v e w] bindings
@@ -214,7 +214,7 @@
   JoinByType [source edge target type]
   Vertex [source] Vertex [target] Known [type] -> DirectedEdge [source edge target] HasType [edge type])
 (defweight
-  JoinByType [op & rest] 0.1)
+  JoinByType [op & rest] 2)
 (deftask
   JoinByType
   (let [[v e w t] bindings


Simplify generators and extract the gen merging

--- test/onyx/flow_conditions/flow_conditions_gen_test.clj
+++ test/onyx/flow_conditions/flow_conditions_gen_test.clj
@@ -22,79 +22,55 @@
    :flow/from (gen/return from-task)
    :flow/exclude-keys (gen/vector gen/keyword)))

+(defn merge-gen-maps [gen1 gen2]
+  (gen/bind gen1
+            (fn [m]
+              (gen/fmap #(merge m %) gen2))))
+
 (defn flow-to-all-gen [base-gen]
-  (gen/bind
-   base-gen
-   (fn [v]
-     (let [g (gen/hash-map :flow/to (gen/return :all))]
-       (gen/fmap #(merge v %) g)))))
+  (merge-gen-maps (gen/return {:flow/to :all})
+                  base-gen))

 (defn flow-to-none-gen [base-gen]
-  (gen/bind
-   base-gen
-   (fn [v]
-     (let [g (gen/hash-map :flow/to (gen/return :none))]
-       (gen/fmap #(merge v %) g)))))
+  (merge-gen-maps (gen/return {:flow/to :none})
+                  base-gen))

 (defn flow-to-tasks-gen [base-gen]
-  (gen/bind
-   base-gen
-   (fn [v]
-     (let [g (gen/hash-map :flow/to (gen/vector gen/keyword))]
-       (gen/fmap #(merge v %) g)))))
+  (merge-gen-maps (gen/hash-map :flow/to (gen/vector gen/keyword))
+                  base-gen))

 (defn true-flow-condition-gen [base-gen]
-  (gen/bind
-   base-gen
-   (fn [v]
-     (let [g (gen/return ::true-pred)
-           true-gen (gen/hash-map :flow/predicate g
-                                  :pred/val (gen/return true))]
-       (gen/fmap #(merge v %) true-gen)))))
+  (merge-gen-maps (gen/return {:flow/predicate ::true-pred
+                               :pred/val true})
+                  base-gen))

 (defn false-flow-condition-gen [base-gen]
-  (gen/bind
-   base-gen
-   (fn [v]
-     (let [g (gen/return ::false-pred)
-           false-gen (gen/hash-map :flow/predicate g
-                                   :pred/val (gen/return false))]
-       (gen/fmap #(merge v %) false-gen)))))
+  (merge-gen-maps (gen/return {:flow/predicate ::false-pred
+                               :pred/val false})
+                  base-gen))

 (defn short-circuit-flow-condition-gen [base-gen]
-  (gen/bind
-   base-gen
-   (fn [v]
-     (let [g (gen/hash-map :flow/short-circuit? (gen/return true))]
-       (gen/fmap #(merge v %) g)))))
+  (merge-gen-maps (gen/return {:flow/short-circuit? true})
+                  base-gen))

 (defn exception-flow-condition-gen [base-gen]
-  (gen/bind
-   base-gen
-   (fn [v]
-     (let [g (gen/hash-map
-              :flow/thrown-exception? (gen/return true)
-              :flow/short-circuit? (gen/return true)
-              :flow/post-transform (gen/one-of
-                                    [(gen/return nil)
-                                     (gen/return ::post-transform)]))]
-       (gen/fmap #(merge v %) g)))))
+  (merge-gen-maps (gen/hash-map
+                    :flow/thrown-exception? (gen/return true)
+                    :flow/short-circuit? (gen/return true)
+                    :flow/post-transform (gen/one-of
+                                           [(gen/return nil)
+                                            (gen/return ::post-transform)]))
+                  base-gen))

 (defn post-transformation-flow-gen [base-gen]
-  (gen/bind
-   base-gen
-   (fn [v]
-     (let [g (gen/hash-map :flow/transform (gen/return ::post-transform))]
-       (gen/fmap #(merge v %) g)))))
+  (merge-gen-maps (gen/return {:flow/transform ::post-transform})
+                  base-gen))

 (defn retry-flow-condition-gen [base-gen]
-  (gen/bind
-   base-gen
-   (fn [v]
-     (let [g (gen/hash-map :flow/action (gen/return :retry)
-                           :flow/short-circuit? (gen/return true)
-                           :flow/to (gen/return nil))]
-       (gen/fmap #(merge v %) g)))))
+  (merge-gen-maps (gen/hash-map :flow/action (gen/return :retry)
+                                :flow/short-circuit? (gen/return true)
+                                :flow/to (gen/return nil))
+                  base-gen))

 (defn maybe-predicate [g]
   (gen/frequency


Trigger fetch commits on event notification

--- src/all/cider_ci/server/resources/commits/front.cljs
+++ src/all/cider_ci/server/resources/commits/front.cljs
@@ -425,5 +425,6 @@
    ])

 (defn event-handler [event]
-  (js/console.log (with-out-str (pprint event))))
-
+  ;(js/console.log (with-out-str (pprint event)))
+  (fetch-commits))
+


doh ! somehow I checked in some unfinished work - this fixes compilation, but I still have a runtime issue - working on it...

--- dada-demo/src/main/clojure/org/dada/demo/whales.clj
+++ dada-demo/src/main/clojure/org/dada/demo/whales.clj
@@ -30,6 +30,10 @@

 (defn rnd [seq] (nth seq (rand-int (count seq))))

+(import org.dada.core.MetadataImpl)
+(import org.dada.core.Getter)
+(import org.dada.core.Attribute)
+
 ;;--------------------------------------------------------------------------------
 ;; Oceans
 ;;--------------------------------------------------------------------------------
@@ -47,13 +51,14 @@

 (insert *metamodel* oceans-model)

-(insert-n
- oceans-model
- [(Ocean. "arctic"   0 0        17880)
-  (Ocean. "atlantic" 0 41100000 28232)
-  (Ocean. "indian"   0 28350000 23808)
-  (Ocean. "pacific"  0 64100000 35797)
-  (Ocean. "southern" 0 0        23737)])
+(if (not *compile-files*)
+  (insert-n
+   oceans-model
+   [(Ocean. "arctic"   0 0        17880)
+    (Ocean. "atlantic" 0 41100000 28232)
+    (Ocean. "indian"   0 28350000 23808)
+    (Ocean. "pacific"  0 64100000 35797)
+    (Ocean. "southern" 0 0        23737)]))

 ;;--------------------------------------------------------------------------------
 ;; Whales
@@ -361,7 +366,7 @@
       join-metadata
       whales-model
       {:ocean oceans-model}
-      (fn [id version ^Whale whale [[ocean]]] ;TODO - type hints
+      (fn [id version ^Whale whale [[^Ocean ocean]]]
 	(let [[type length weight] (if whale [(.type whale)(.length whale)(.weight whale)][nil 0 0])
 	      [ocean ocean-max-depth ocean-area] (if ocean [(.id ocean)(.max-depth ocean)(.area ocean)] [nil 0 0])]
 	  (Join. id version type length weight ocean ocean-area ocean-max-depth)


fix typo

fix typo

--- src/main/clojure/clojure/tools/analyzer/passes/js/infer_tag.clj
+++ src/main/clojure/clojure/tools/analyzer/passes/js/infer_tag.clj
@@ -135,7 +135,7 @@
 (defmethod -infer-tag :try
   [{:keys [body catches] :as ast}]
   (let [{:keys []} body]
-    (merge ast (select-keys [tag return-tag arglists ignore-tag] body))s))
+    (merge ast (select-keys [:tag :return-tag :arglists :ignore-tag] body))))

 ;;TODO: handle :ignore-tag ?
 (defmethod -infer-tag :fn-method


Adds key override for cool-down key (#168)

The resulting json key from cool-down spec is Cooldown and not CoolDown. I added an override to stay compatible with the current keys. However we could just correct the spec key to be ::cooldown. https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-as-group.html#cfn-as-group-cooldown

--- src/crucible/aws/auto_scaling/auto_scaling_group.clj
+++ src/crucible/aws/auto_scaling/auto_scaling_group.clj
@@ -1,7 +1,10 @@
 (ns crucible.aws.auto-scaling.auto-scaling-group
   "AWS::AutoScaling::AutoScalingGroup"
   (:require [clojure.spec.alpha :as s]
-            [crucible.resources :refer [spec-or-ref] :as res]))
+            [crucible.resources :refer [spec-or-ref] :as res]
+            [crucible.encoding.keys :refer [->key]]))
+
+(defmethod ->key :cool-down [_] "Cooldown")

 (s/def ::default-result (spec-or-ref string?))
 (s/def ::heartbeat-timeout (spec-or-ref string?))


Send change trigger when updating a vote.

--- src/oc/storage/api/entries.clj
+++ src/oc/storage/api/entries.clj
@@ -417,7 +417,7 @@
       :else
       reply)))

-(defn- update-poll-vote [conn entry poll user reply-id add?]
+(defn- update-poll-vote [conn org board entry poll user reply-id add?]
   (let [user-has-voted? (some #(when (= % (:user-id user)) %) (:replies poll))

         updated-poll-replies (mapv (partial update-reply (:user-id user) reply-id add?) (:replies poll))
@@ -426,6 +426,7 @@
         filtered-polls (filterv #(not= (:poll-uuid %) (:poll-uuid poll)) (:polls entry))
         final-entry (assoc entry :polls (vec (conj filtered-polls updated-poll)))
         updated-entry (entry-res/update-entry-no-user! conn (:uuid entry) final-entry)]
+    (notification/send-trigger! (notification/->trigger :update org board {:new updated-entry :old entry} user nil (api-common/get-change-client-id ctx)))
     {:updated-entry updated-entry}))

 ;; ----- Resources - see: http://clojure-liberator.github.io/liberator/assets/img/decision-graph.svg
@@ -1084,8 +1085,10 @@
                 false))})

   ;; Actions
-  :post! (fn [ctx] (update-poll-vote conn (:existing-entry ctx) (:existing-poll ctx) (:user ctx) reply-id true))
-  :delete! (fn [ctx] (update-poll-vote conn (:existing-entry ctx) (:existing-poll ctx) (:user ctx) reply-id false))
+  :post! (fn [ctx] (update-poll-vote conn (:existing-org ctx) (:existing-board ctx) (:existing-entry ctx)
+                    (:existing-poll ctx) (:user ctx) reply-id true))
+  :delete! (fn [ctx] (update-poll-vote conn (:existing-org ctx) (:existing-board ctx) (:existing-entry ctx)
+                    (:existing-poll ctx) (:user ctx) reply-id false))

   ;; Responses
   :handle-ok (by-method {


Fix #1

Fix #1

This patch fixes issue #1 by reworking check-vars to examine the
dependency set of vars in a def rather than checking the def'd var
itself. Note that this means check-vars should be run after tree-shaking
to escape errors in unreachable code (for instance the definition of
c.c/eval which is self-reaching).

--- src/oxcart/passes/warnings.clj
+++ src/oxcart/passes/warnings.clj
@@ -58,7 +58,9 @@
   "λ Whole-AST → options → Whole-AST

   Emits the appropriate error messages when banned or unsupported vars
-  are used by input program.
+  are used by input program. Note that checking is done over all forms
+  in the Whole-AST, and that to escape errors from unreachable code
+  tree shaking must be performed prior to this analysis pass.

   options:
     :suppress-errors
@@ -102,31 +104,39 @@

      ;; do a single pass over the forms
      (doseq [ast forms]
-       (if-let [var (pattern/def->var ast)]
-         (cond (contains? banned-vars var)
-               ;; outright banned vars
-               (do (when-not suppress-errors
-                     (reset! error? true))
-                   (error (str (util/format-line-info ast)
-                               ", Program makes use of banned var:"
-                               var)))
-
-              (contains? banned-set var)
-              ;; user banned vars
-              (do (when-not suppress-errors
-                    (reset! error? true))
-                  (error (str (util/format-line-info ast)
-                              ", Program makes use of user banned var:"
-                              var)))
-
-              (and (contains? dangerous-vars var)
-                   warn-unsupported)
-              ;; unsupported vars
-              (do (when warnings-as-errors
-                    (reset! error? true))
-                  (warn (str (util/format-line-info ast)
-                             ", Program makes use of flagged var:"
-                             var))))))
+       (when-let [var (pattern/def->var ast)]
+         (when-let [deps (get dep-map var) ;; :- #{Var}
+                    ]
+           (when-let [i (intersection deps banned-vars) ;; :- #{Var}
+                      ]
+             ;; outright banned vars
+             (when-not suppress-errors
+               (reset! error? true))
+
+             (doseq [error-var i]
+               (error (str (util/format-line-info ast)
+                           ", Program makes use of banned var:"
+                           error-var))))
+
+           (when-let [i (intersection deps banned-set)]
+             ;; user banned vars
+             (when-not suppress-errors
+               (reset! error? true))
+
+             (doseq [error-var i]
+               (error (str (util/format-line-info ast)
+                           ", Program makes use of user banned var:"
+                           error-var))))
+
+           (when-let [i (intersection deps dangerous-vars)]
+             ;; unsupported vars
+             (when warnings-as-errors
+               (reset! error? true))
+
+             (doseq [warn-var i]
+               (warn (str (util/format-line-info ast)
+                          ", Program makes use of flagged var:"
+                          warn-var)))))))

      (assert (not @error?)
              "Errors were generated in checking.")


Don't force entities to have an :object key

--- src/play_clj/core_graphics.clj
+++ src/play_clj/core_graphics.clj
@@ -492,7 +492,7 @@
   (let [^Batch batch (.getBatch renderer)]
     (.begin batch)
     (doseq [{:keys [additive? opacity] :as entity} entities]
-      (when-not (instance? Actor (u/get-obj entity :object))
+      (when-not (instance? Actor (:object entity))
         (when additive?
           (.setBlendFunction ^Batch batch (gl :gl-src-alpha) (gl :gl-one)))
         (.setColor batch (color 1 1 1 (or opacity 1.0)))


only enable deps-tree by default

only enable deps-tree by default

--- profiles.clj
+++ profiles.clj
@@ -1,6 +1,10 @@
 {
  :user {
-   :plugins [[lein-clojars "0.9.0"] [lein-light "0.0.4"] [lein-catnip "0.5.0"]]
+   :plugins [
+             ;[lein-clojars "0.9.0"]
+             ;[lein-light "0.0.4"]
+             [lein-deps-tree "0.1.2"]
+             ]
    :repl-options {
      :init (do
        (use '[table.core :only (table)])


Start watch with empty map

Start watch with empty map

--- src/main/clojure/com/stuartsierra/lazytest/watch.clj
+++ src/main/clojure/com/stuartsierra/lazytest/watch.clj
@@ -21,7 +21,7 @@
   "Sent as an agent action, stops a directory-watching agent."
   [state]
   (remove-watch *agent* ::watch)
-  false)
+  nil)

 (defn ns-mod-time-agent
   "Creates an agent that monitors namespaces for changes to their
@@ -35,7 +35,7 @@
                     (Thread/sleep delay)
                     (send *agent* upd)
                     (ns-mod-times dir)))]
-    (doto (agent true)
+    (doto (agent {})
       (send updater))))

 (defn- newer-namespaces [older newer]
@@ -73,7 +73,7 @@
     :delay - time (ms) between directory scans"
   [d & options]
   (let [{:keys [reporter] :or {reporter spec-report}} options]
-    (reporter (run-spec (find-namespaces-in-dir d)))
     (apply watch-dir d
-           (fn [names] (reporter (run-spec names :reload)))
+           (fn [names]
+             (reporter (run-spec names :reload)))
            options)))


Remove unneeded logging

Remove unneeded logging

--- src/replme/cljs/websocket.cljs
+++ src/replme/cljs/websocket.cljs
@@ -33,4 +33,4 @@
   [socket]
   (let [out-chan (chan)]
     (set! (.-onmessage socket) (handle-fn out-chan))
-    (pub out-chan (fn [{:keys [destination]}] (println destination) destination))))
+    (pub out-chan (fn [{:keys [destination]}] destination))))


cleanup

cleanup

--- src/metabase/driver/generic_sql/native.clj
+++ src/metabase/driver/generic_sql/native.clj
@@ -47,6 +47,6 @@
                             columns first-row)}})
        (catch java.sql.SQLException e
          {:status :failed
-          :error (->> (.getMessage e)                                               ; error message comes back like 'Column "ZID" not found; SQL statement: ... [error-code]
-                      (re-find (re-pattern (format "(.*);\\s*SQL statement:" sql))) ; the user already knows the SQL, and error message is meaningless
-                      second)})))                                                   ; so just return the part of the exception that is relevant
+          :error (->> (.getMessage e)     ; error message comes back like 'Column "ZID" not found; SQL statement: ... [error-code]
+                      (re-find #"^(.*);") ; the user already knows the SQL, and error code is meaningless
+                      second)})))         ; so just return the part of the exception that is relevant


renames/cleanups

renames/cleanups

--- src/midje/util/thread_safe_var_nesting.clj
+++ src/midje/util/thread_safe_var_nesting.clj
@@ -20,31 +20,30 @@
 ;; Variables that might not be bound
 (def unbound-marker :midje/special-midje-unbound-marker)

-(defn restore-one-root [[^clojure.lang.Var variable new-value]]
+(defn restore-one-root [[^clojure.lang.Var the-var new-value]]
   (if (= new-value unbound-marker)
-    (.unbindRoot variable)
-    (alter-var-root variable (fn [current-value] new-value))))
+    (.unbindRoot the-var)
+    (alter-var-root the-var (fn [current-value] new-value))))

-(defn alter-one-root [[^clojure.lang.Var variable new-value]]
-   (if (bound? variable)
-     (let [old-value (deref variable)]
-       (alter-var-root variable (fn [current-value] new-value))
-       [variable old-value])
-     (do
-       (.bindRoot variable new-value)
-       [variable unbound-marker])))
+(defn alter-one-root [[^clojure.lang.Var the-var new-value]]
+  (if (bound? the-var)
+    (let [old-value (deref the-var)]
+      (alter-var-root the-var (fn [current-value] new-value))
+      [the-var old-value])
+    (do
+      (.bindRoot the-var new-value)
+      [the-var unbound-marker])))

-(defn with-altered-roots* [binding-map function]
-  (let [old-bindings (into {} (for [pair binding-map] (alter-one-root pair)))]
-    (try (function)
-         ;; Can't use doseq inside a finally clause.
-         (finally (dorun (map restore-one-root old-bindings))))))
+(defn with-altered-roots* [binding-map f]
+  (let [old-bindings (into {} (for [var+new-value binding-map] (alter-one-root var+new-value)))]
+    (try (f)
+      (finally (dorun (map restore-one-root old-bindings))))))

 (defmacro with-altered-roots
   "Used instead of with-bindings because bindings are thread-local
    and will require specially declared vars in Clojure 1.3"
-  [binding-map & rest]
-  `(with-altered-roots* ~binding-map (fn [] ~@rest)))
+  [binding-map & body]
+  `(with-altered-roots* ~binding-map (fn [] ~@body)))

 ;; Values associated with namespaces
@@ -77,4 +76,4 @@
      (finally (pop-from-namespace ~key-name))))

 (defn namespace-values-inside-out [key-name]
-  (apply concat (namespace-value key-name)))
+  (apply concat (namespace-value key-name)))


Added thread-first.

Added thread-first.

I'm thinking just spitting the suggestions out into a list is a Bad Idea.
So, two things to do in the immediate future:
	* Change suggestions into a list of maps instead of strings
	* Fix the parser so it doesn't freak out on those two tests -
	  they're failing not because of the thread-first algorithm, but
	  because the parser can't turn them into trees!

--- formatter/src/formatter/extensions/thread_first.clj
+++ formatter/src/formatter/extensions/thread_first.clj
@@ -2,8 +2,64 @@
   (:require [instaparse.core :as insta]
             [formatter.parser :as par]))

-(defn process-code [params]
-  params)
+(def ^:dynamic *min-depth* 3)
+(def ^:dynamic *max-nonfirst-depth* 2)
+(def ^:dynamic *do-not-nest* #{})
+
+(defn count-nonfirst-nesting
+  "Counts the nesting level of the function node"
+  [tree]
+  (let [tree-vecs (filter #(and (vector? %) (= (first %) :Eval)) tree)]
+    (if (> (count tree-vecs) 0)
+        (inc (apply max (map count-nonfirst-nesting tree-vecs)))
+        1)))
+
+(defn count-first-nesting
+  "Counts the nesting levels of the tree, excluding functions listed in the
+  *do-not-nest* var."
+  [node]
+  (loop [node node n 0 nonfirst-n 0]
+    (let [node-vecs (filter vector? node)]
+      (cond
+        (contains? *do-not-nest* (second (first node-vecs)))
+          [n nonfirst-n]
+        (and (= :Eval (first node)))
+          (recur (second node-vecs)
+                 (inc n)
+                 (max nonfirst-n
+                      (count-nonfirst-nesting (rest (rest node-vecs)))))
+        :else
+          [n nonfirst-n]))))
+
+(defn find-nested-nodes
+  "Finds nodes with a thread-last nesting level greater than or equal to n.
+  For example, for n=1 and a tree parsed from (+ 3 (* 9 2)) it would return a
+  vector of two elements containing trees representing (+3 (* 9 2)) and
+  (* 9 2)."
+  [tree]
+  (let [[nesting nonfirst-nesting] (count-first-nesting tree)
+        tree-nodes (filter vector? tree)
+        result (mapcat find-nested-nodes tree-nodes)]
+    (if (and (<= nonfirst-nesting *max-nonfirst-depth*)
+             (>= nesting *min-depth*))
+        (cons tree (remove #(= (second tree-nodes) %) result))
+        (mapcat find-nested-nodes tree-nodes))))
+
+(defn nodes-to-strings
+  "Takes a vector or nodes and returns a vector of strings."
+  [nodes]
+  (map #(->> %
+             (flatten)
+             (filter string?)
+             (apply str))
+        nodes))
+
+(defn process-code [{:keys [tree suggestions] :as params}]
+  (->> (find-nested-nodes tree)
+       (nodes-to-strings)
+       (map clojure.string/trim)
+       (reduce conj suggestions)
+       (assoc params :suggestions)))

 (def extension
   {:description "thread-first adds to suggestions possible locations to use ->"


Fix `diff-paths` and `interp-paths` in tests

--- src/test/cljc/mikron/test/core_macros.cljc
+++ src/test/cljc/mikron/test/core_macros.cljc
@@ -14,7 +14,7 @@
   [test-methods test-cases]
   (compiler.util/macro-context {:gen-syms [schema dataset]}
     `(do ~@(for [[schema-name schema-def] test-cases]
-             `(let [~schema  (mikron/schema ~schema-def :diff true :interp true)
+             `(let [~schema  (mikron/schema ~schema-def :diff-paths true :interp-paths true)
                     ~dataset (repeatedly 100 #(mikron/gen ~schema))]
                 ~@(for [method test-methods]
                     `(test/deftest ~(gensym (str (name method) "-" (name schema-name)))


Meikel's suggestion as a workaround to IBM JVM wierdness... : http://groups.google.com/group/clojure/browse_thread/thread/182ce7b4bfe8e193

--- src/test/clojure/org/dada/CoreTestCase.clj
+++ src/test/clojure/org/dada/CoreTestCase.clj
@@ -9,7 +9,7 @@
 	       ;;[test-attribute-array [] void]
 	       ]
      )
-    (:use [org.dada.core])
+    (:use org.dada.core)
     (:import [junit.framework TestCase] ;;[]
 	     ))


bugfix score-collect-join, add debug traces to various sig/coll fns, update triple-vertex-spec, make triple-graph-logger more generic (and cljs compatible), update test sketches

--- src/thi/ng/fabric/triples.cljc
+++ src/thi/ng/fabric/triples.cljc
@@ -32,20 +32,23 @@
   (f/collect-pure
    (fn [val incoming]
      (debug :update-index spo incoming)
-     (transduce
-      (map (fn [[op id t]] [op id (nth t spo)]))
-      (completing
-       (fn [acc [op id x]]
-         (case op
-           :add    (update acc x (fnil conj #{}) id)
-           :remove (if-let [idx (acc x)]
-                     (if (= #{id} idx)
-                       (dissoc acc x)
-                       (update acc x disj id))
-                     acc)
-           (do (warn "ignoring unknown index signal op:" op)
-               acc))))
-      val incoming))))
+     (debug :old-index val)
+     (let [val (transduce
+                (map (fn [[op id t]] [op id (nth t spo)]))
+                (completing
+                 (fn [acc [op id x]]
+                   (case op
+                     :add    (update acc x (fnil conj #{}) id)
+                     :remove (if-let [idx (acc x)]
+                               (if (= #{id} idx)
+                                 (dissoc acc x)
+                                 (update acc x disj id))
+                               acc)
+                     (do (warn "ignoring unknown index signal op:" op)
+                         acc))))
+                val incoming)]
+       (debug :new-index val)
+       val))))

 (defn signal-index-select
   [vertex [idx sel]]
@@ -148,7 +151,9 @@
     (assoc q-spec :qvar-result resv)))

 (defn score-collect-join
-  [vertex] (if (== (count (::f/signal-map @(:state vertex))) 2) 1 0))
+  [vertex]
+  (let [state @(:state vertex)]
+    (if (and (seq (::f/uncollected state)) (== (count (::f/signal-map @(:state vertex))) 2)) 1 0)))

 (defn add-join!
   [g qa qb]
@@ -215,10 +220,14 @@
   [g spo]
   (f/add-vertex!
    g {} {::f/collect-fn      (collect-index spo)
-         ::f/score-signal-fn f/score-signal-with-new-edges
+         ::f/score-signal-fn (fn [v] (let [score (f/score-signal-with-new-edges v)]
+                                      (info (:id v) :index-score score)
+                                      score))
          }))

-(def triple-vertex-spec {::f/score-collect-fn (constantly 0)})
+(def triple-vertex-spec
+  {::f/score-collect-fn (constantly 0)
+   ::f/score-signal-fn f/score-signal-with-new-edges})

 (defrecord TripleGraph
     [g indices triples queries rules]
@@ -313,30 +322,38 @@
     (f/add-edge! g src v f/signal-forward nil)
     v))

-;; #?(:clj (taoensso.timbre/set-level! :warn))
-
-#?(:clj
-   (defn triple-logger
-     [path]
-     (let [ch (->> (comp
-                    (filter
-                     (fn [[op id val]]
-                       (and (#{:add-vertex :remove-vertex} op) (vector? val))))
-                    (map
-                     (fn [[op _ t]] [({:add-vertex :+ :remove-vertex :-} op) t])))
-                   (chan 1024))]
-       (go-loop []
-         (let [t (<! ch)]
-           (when t
-             (spit path (str (pr-str t) "\n") :append true)
-             (recur))))
-       ch)))
+(def triple-log-transducer
+  (comp
+   (filter
+    (fn [[op v]]
+      (and (#{:add-vertex :remove-vertex} op) (vector? @v))))
+   (map
+    (fn [[op v]] [({:add-vertex :+ :remove-vertex :-} op) @v]))))
+
+(defn add-triple-graph-logger
+  [g log-fn]
+  (let [ch        (chan 1024 triple-log-transducer)
+        log->chan #(go (>! ch %))
+        watch-id  (keyword (gensym))]
+    (go-loop []
+      (let [t (<! ch)]
+        (when t
+          (log-fn t)
+          (recur))))
+    (f/add-watch! g :add-vertex watch-id log->chan)
+    (f/add-watch! g :remove-vertex watch-id log->chan)
+    {:graph g :chan ch :watch-id watch-id}))
+
+(defn remove-triple-graph-logger
+  [{:keys [graph watch-id chan]}]
+  (f/remove-watch! graph :add-vertex watch-id)
+  (f/remove-watch! graph :remove-vertex watch-id)
+  (close! chan))

 (defn ^:export start-async
   []
-  (let [;;log (triple-logger "triple-log.edn")
-        ;;g (triple-graph (f/logged-compute-graph (f/compute-graph) log))
-        g (triple-graph (f/compute-graph))
+  (let [g (triple-graph (f/compute-graph))
+        log (add-triple-graph-logger g #(spit "triple-log.edn" (str (pr-str %) "\n") :append true))
         toxi (:result (add-query! g :toxi ['toxi nil nil]))
         types (:result (add-query! g :types [nil 'type nil]))
         projects (:result (add-query! g :projects [nil 'type 'project]))
@@ -392,16 +409,20 @@
              [toxi knows noah]
              [geom tag clojure]
              [fabric tag clojure]])
-          (loop []
-            (let [res (<! ctx-chan)]
-              (warn :result res)
-              (when (= :converged (:type res))
-                (warn :all (sort @all))
-                (warn :pq @pq)
-                (warn :jq @jq)
-                (warn :tq @tq)
-                (f/stop! ctx)
-                (recur))))))
+          (<! ctx-chan)
+          ;;(warn :result res)
+          (warn :all (sort @all))
+          (warn :pq @pq)
+          (warn :jq @jq)
+          (warn :tq @tq)
+          (remove-triple! g '[geom tag clojure])
+          (remove-triple! g '[fabric type project])
+          (<! ctx-chan)
+          (warn :jq @jq)
+          (warn :tq @tq)
+          (f/stop! ctx)
+          (do (remove-triple-graph-logger log)
+              (warn :done))))

     {:g        g
      :ctx      ctx
@@ -420,9 +441,10 @@

 (defn ^:export start-sync
   []
-  (let [;;log (triple-logger "triple-log.edn")
+  (let [;;log (add-triple-graph-logger "triple-log.edn")
         ;;g (triple-graph (f/logged-compute-graph (f/compute-graph) log))
         g (triple-graph (f/compute-graph))
+        log (add-triple-graph-logger g #(spit "triple-log.edn" (str (pr-str %) "\n") :append true))
         toxi (:result (add-query! g :toxi ['toxi nil nil]))
         types (:result (add-query! g :types [nil 'type nil]))
         projects (:result (add-query! g :projects [nil 'type 'project]))
@@ -480,6 +502,11 @@
     (warn @pq)
     (warn @jq)
     (warn @tq)
+    (f/signal! (remove-triple! g '[fabric tag clojure]) f/sync-vertex-signal)
+    (warn :result3 (f/execute! ctx))
+    (warn @all)
+    (warn @tq)
+    (remove-triple-graph-logger log)
     {:g        g
      :ctx      ctx
      :all      all


correspondences-to-ranges

correspondences-to-ranges

--- test/atom_finder/patch_test.clj
+++ test/atom_finder/patch_test.clj
@@ -23,5 +23,5 @@

          (->> "patch/97574c57cf26ace9b8609575bbab66465924fef7_partial.patch"
               resource-path slurp parse-diff
-              patch-correspondences)
+              patch-correspondences correspondences-to-ranges)
          ))


test to ensure `default` isn't evaluated when unused in `maybe`

--- test/cats/monad/maybe_spec.cljc
+++ test/cats/monad/maybe_spec.cljc
@@ -155,12 +155,13 @@
       (t/is (maybe/just? m1)))))

 (t/deftest maybe-test
-  (let [n (maybe/nothing)
-        j (maybe/just 42)]
+  (let [n          (maybe/nothing)
+        j          (maybe/just 42)
+        wrap-in-ex (fn [v] (do (throw (ex-info "shouldn't run" {})) v))]
     (t/is (= 42 (maybe/maybe 42 n inc)))
     (t/is (= 43 (maybe/maybe 42 j inc)))
-    (t/is (= 42 (maybe/maybe 42 n (do (throw (ex-info "shouldn't run" {}))
-                                      inc))))
+    (t/is (= 42 (maybe/maybe 42 n (wrap-in-ex inc))))
+    (t/is (= 43 (maybe/maybe (wrap-in-ex 42) j inc)))
     (t/is (thrown?
             #?(:clj  java.lang.AssertionError
                :cljs js/Error)


change test symbol

change test symbol

--- test/clj_money/trading_test.clj
+++ test/clj_money/trading_test.clj
@@ -26,7 +26,7 @@
    :accounts [{:name "IRA"
                :type :asset
                :content-type :commodities}
-              {:name "APPL"
+              {:name "AAPL"
                :type :asset
                :parent-id "IRA"
                :content-type :commodity}
@@ -45,7 +45,7 @@
               {:name "Checking"
                :type :asset}]
    :commodities [{:name "Apple, Inc."
-                  :symbol "APPL"
+                  :symbol "AAPL"
                   :exchange :nasdaq}]
    :transactions [{:transaction-date (t/local-date 2016 1 1)
                    :description "Opening balance"
@@ -81,7 +81,7 @@
         "The result contains a lot-transaction")
     (is (empty? (-> result :lot-transaction validation/error-messages))
         "The lot transaction is valud")
-    (is (= "Purchase 100 shares of APPL at 10.000" (-> result :transaction :description)) "The transaction description describes the purchase")))
+    (is (= "Purchase 100 shares of AAPL at 10.000" (-> result :transaction :description)) "The transaction description describes the purchase")))

 (deftest purchase-a-commodity-with-a-fee
   (let [context (serialization/realize storage-spec purchase-context)
@@ -519,11 +519,11 @@
                                          :created-at
                                          :updated-at)))
         expected [{:transaction-date (t/local-date 2017 3 2)
-                   :description "Sell 25 shares of APPL at 15.000"
+                   :description "Sell 25 shares of AAPL at 15.000"
                    :action :credit
                    :account-id (:id lt-capital-gains)
                    :amount 125M
-                   :memo "Sell 25 shares of APPL at 15.00"
+                   :memo "Sell 25 shares of AAPL at 15.00"
                    :balance 125M
                    :index 0}]]
     (is (= expected gains-items) "The capital gains account is credited the correct amount")))
@@ -554,11 +554,11 @@
                                          :created-at
                                          :updated-at)))
         expected [{:transaction-date (t/local-date 2017 3 1)
-                   :description "Sell 25 shares of APPL at 15.000"
+                   :description "Sell 25 shares of AAPL at 15.000"
                    :action :credit
                    :account-id (:id st-capital-gains)
                    :amount 125M
-                   :memo "Sell 25 shares of APPL at 15.00"
+                   :memo "Sell 25 shares of AAPL at 15.00"
                    :balance 125M
                    :index 0}]]
     (is (= expected gains-items) "The capital gains account is credited the correct amount")))
@@ -587,11 +587,11 @@
                                          :created-at
                                          :updated-at)))
         expected [{:transaction-date (t/local-date 2017 3 2)
-                   :description "Sell 100 shares of APPL at 8.500"
+                   :description "Sell 100 shares of AAPL at 8.500"
                    :action :debit
                    :account-id (:id capital-loss)
                    :amount 150M
-                   :memo "Sell 100 shares of APPL at 8.50"
+                   :memo "Sell 100 shares of AAPL at 8.50"
                    :balance 150M
                    :index 0}]]
     (is (= expected gains-items) "The capital loss account is credited the correct amount")))


Return the wish list instead of just the code.

--- src/wishlistd/models/redis.clj
+++ src/wishlistd/models/redis.clj
@@ -20,7 +20,7 @@
         as-json (encode with-code)]
     (r/with-server db
       (r/set code as-json))
-    code)) ; return the code
+    with-code)) ; return the wishlist

 (defn read-wishlist [code]
   "Get a single wishlist from datastore."


Add header-codec tests.

Add header-codec tests.

--- test/multicodec/codecs_test.clj
+++ test/multicodec/codecs_test.clj
@@ -26,6 +26,29 @@
       [tag (slurp input)])))

+(deftest header-codec
+  (let [foo (mock-codec :foo "/foo")]
+    (testing "codec construction"
+      (let [codec (codecs/wrap-headers foo)]
+        (is (= "/foo" (:header codec))
+            "header should inherit wrapped codec by default"))
+      (let [codec (codecs/wrap-headers foo "/bar")]
+        (is (= "/bar" (:header codec))
+            "header should be settable with second arg")))
+    (let [codec (codecs/wrap-headers foo)]
+      (testing "encoding roundtrip"
+        (let [encoded (mc/encode codec 1234)]
+          (is (= "/foo" (mh/read-header! (ByteArrayInputStream. encoded)))
+              "should write codec header to content")
+          (is (= [:foo "1234"] (mc/decode codec encoded))
+              "should read header and delegate to codec")))
+      (testing "bad header"
+        (let [baos (ByteArrayOutputStream.)]
+          (codecs/write-header-encoded! "/bar" foo baos :abc)
+          (is (thrown? RuntimeException
+                       (mc/decode codec (.toByteArray baos)))))))))
+
+
 (deftest multiplex-codec
   (testing "codec construction"
     (is (thrown? IllegalArgumentException (codecs/mux-codec))


Update routing to use boxure/call-in-box when calling handlers.


Noop nemesis for now

Noop nemesis for now

--- src/copycat_jepsen/core.clj
+++ src/copycat_jepsen/core.clj
@@ -210,7 +210,7 @@
             :model   (model/cas-register)
             :checker   (checker/compose {:html timeline/html
                                          :linear checker/linearizable})
-            :nemesis  (nemesis/partition-random-halves)
+            :nemesis  (nemesis/noop)
             :ssh      {:private-key-path "/home/vagrant/.ssh/id_rsa"}
             :node-set node-set})))


Added test for getting one history

Added test for getting one history

--- test/staircase/test/handler.clj
+++ test/staircase/test/handler.clj
@@ -10,7 +10,7 @@

   (exists? [_ id] existance)
   (get-all [_] things)
-  (get-one [_ id] (first (filter #(= (:id %1) id) things)))
+  (get-one [_ id] (first (filter #(= (str (:id %1)) (str id)) things)))
   (update [_ id doc] updated)
   (delete [_ id])
   (create [_ doc] (doc "id")))
@@ -41,6 +41,12 @@
           response (app req)]
       (is (= (:status response) 200))
       (is (= (:body response) "{\"data\":\"mock\",\"id\":1}"))))
+
+  (testing "GET /histories/1"
+    (let [req (-> (json-request :get "/histories/1"))
+          response (app req)]
+      (is (= (:status response) 200))
+      (is (= (:body response) "{\"data\":\"mock\",\"id\":1}"))))

   (testing "not-found route"
     (let [response (app (request :get "/invalid"))]


Remove shutdown hook, encourage more graceful shutdown


no special case for websockets component

--- Clojure-Websockets/MainApp/src/cljs/birdwatch/core.cljs
+++ Clojure-Websockets/MainApp/src/cljs/birdwatch/core.cljs
@@ -9,7 +9,8 @@
             [birdwatch.ui.pagination :as pag]
             [cljs.core.match :refer-macros [match]]
             [birdwatch.state.comp :as c]
-            [matthiasn.systems-toolbox.switchboard :as sb]))
+            [matthiasn.systems-toolbox.switchboard :as sb]
+            [matthiasn.systems-toolbox.sente :as sente]))

 (enable-console-print!)

@@ -17,9 +18,9 @@

 (def switchboard (sb/component))

-(sb/send-mult
+(sb/send-mult-cmd
   switchboard
-  [[:cmd/make-ws-comp]
+  [[:cmd/wire-comp {:cmp-id :ws-comp :cmp (sente/component)}]
    [:cmd/make-comp {:cmp-id :state-comp :mk-state-fn c/mk-state :handler-fn c/handle-incoming}]
    [:cmd/make-comp {:cmp-id :tweets-comp :mk-state-fn tw/make-state :state-pub-handler-fn tw/state-pub-handler}]
    [:cmd/make-comp {:cmp-id :cloud-comp :mk-state-fn cloud/mk-state :state-pub-handler-fn cloud/state-pub-handler
@@ -36,9 +37,9 @@
    [:cmd/make-r-comp {:cmp-id :sort-comp :view-fn st/sort-view :dom-id "sort-buttons"}]
    [:cmd/make-r-comp {:cmp-id :pag-comp :view-fn pag/pagination-view :dom-id "pagination"}]

-   [:cmd/tap-comp [:state-comp :ws]]
+   [:cmd/tap-comp [:state-comp :ws-comp]]
    [:cmd/tap-comps
-    [[:ws :tweets-comp :search-comp :sort-comp :pag-comp :cloud-comp :wc-c-comp]
+    [[:ws-comp :tweets-comp :search-comp :sort-comp :pag-comp :cloud-comp :wc-c-comp]
      :state-comp]]

    [:cmd/sub-comps


[#3086] Add functional test

[#3086] Add functional test

--- backend/test/akvo/lumen/lib/transformation_test.clj
+++ backend/test/akvo/lumen/lib/transformation_test.clj
@@ -389,7 +389,46 @@
         (is (= years-slash (map (comp tcc/from-long :c3) table-data)))
         (is (= years-hiphen (map (comp tcc/from-long :c4) table-data)))))))

-
+(deftest ^:functional merge-datasets-test-3086
+  (testing "https://github.com/akvo/akvo-lumen/issues/3086"
+    (let [registration-dataset-id (tu/import-file *tenant-conn* *error-tracker*
+                                                  {:dataset-name "registration"
+                                                   :kind         "clj-flow"
+                                                   :data         (tu/read-edn-flow-dataset "uat1" "697789115" "694759115")})
+          monitoring-dataset-id   (tu/import-file *tenant-conn* *error-tracker*
+                                                  {:dataset-name "monitoring"
+                                                   :kind         "clj-flow"
+                                                   :data         (tu/read-edn-flow-dataset "uat1" "697789115" "684819115")})
+          apply-transformation    (partial async-tx-apply {:tenant-conn *tenant-conn*} monitoring-dataset-id)
+          transformation          {"op" "core/merge-datasets",
+                                   "args"
+                                   {"source"
+                                    {"datasetId"            registration-dataset-id,
+                                     "mergeColumn"          "identifier",
+                                     "aggregationColumn"    nil,
+                                     "aggregationDirection" "DESC",
+                                     "mergeColumns"         ["device_id" "c707599115"]},
+                                    "target" {"mergeColumn" "identifier"}}}
+          [tag _ :as all]         (apply-transformation {:type           :transformation
+                                                         :transformation transformation})]
+      (let [{:keys [columns transformations]} (latest-dataset-version-by-dataset-id *tenant-conn*
+                                                                                {:dataset-id monitoring-dataset-id})]
+        (is (= ["identifier"
+                "instance_id"
+                "display_name"
+                "submitter"
+                "submitted_at"
+                "surveyal_time"
+                "device_id"
+                "c699849115"
+                "c688379115"
+                "c697789120"
+                "c678589115"
+                "d1"
+                "d2"] (mapv #(get % "columnName") columns)))
+        (is (= #{nil "692519115" "metadata" "697789118"} (into #{} (map #(get % "groupId") columns))))
+        )
+      )))

 (deftest ^:functional test-update-issue-2254
   (testing "Testing https://github.com/akvo/akvo-lumen/issues/2254 "


Select the correct radio button in the switch user dialog

--- android/src/clojure/net/nightweb/dialogs.clj
+++ android/src/clojure/net/nightweb/dialogs.clj
@@ -255,18 +255,22 @@
   [context content]
   (let [view (make-ui context [:scroll-view {}
                                [:radio-group {:orientation 1}]])
-        linear-layout (.getChildAt view 0)
+        radio-group (.getChildAt view 0)
         items (conj (vec (for [user-hash (read-user-list-file)]
                            (get-single-user-data {:userhash user-hash})))
                     {:title (get-string :create_user)})]
+    ; add each user to the list
     (future
-      (doseq [item items]
-        (let [title (if (= 0 (count (:title item)))
+      (doseq [i (range (count items))]
+        (let [item (get items i)
+              title (if (= 0 (count (:title item)))
                       (get-string :no_name)
                       (:title item))
               button (make-ui context [:radio-button {:text title
-                                                      :single-line true}])
+                                                      :single-line true
+                                                      :id i}])
               pad (make-dip context 10)]
+          (.setChecked button (is-me? (:userhash item)))
           (on-ui (set-text-size button default-text-size)
                  (.setPadding button pad pad pad pad)
                  (when (nil? (:userhash item))
@@ -275,7 +279,8 @@
                    button
                    (proxy [android.view.View$OnClickListener] []
                      (onClick [v])))
-                 (.addView linear-layout button)))))
+                 (.addView radio-group button)))))
+    ; display a dialog with the list
     (show-dialog context
                  nil
                  view


Increase dest start timeout for slow hardware [IMMUTANT-319]

--- modules/messaging/src/main/clojure/immutant/messaging/core.clj
+++ modules/messaging/src/main/clojure/immutant/messaging/core.clj
@@ -171,7 +171,7 @@
     (let [complete (promise)
           service-created (f izer complete)]
       (if service-created
-        (when-not (= "up" (deref complete 5000 nil))
+        (when-not (= "up" (deref complete 60000 nil))
           (throw (Exception. (format "Unable to start %s: %s" type name))))
         (log/info (format "%s already exists: %s" type name))))
     (throw (Exception. (format "Unable to start %s: %s" type name)))))


Add type hints to screenshot! function

Add type hints to screenshot! function

--- src/play_clj/core_utils.clj
+++ src/play_clj/core_utils.clj
@@ -16,7 +16,8 @@
     (screenshot! \"out.png\")
     (screenshot! (files! :external \"out.png\"))"
   ([]
-    (let [pic (Pixmap. (game :width) (game :height) (Pixmap$Format/RGBA8888))
+    (let [^Pixmap$Format pic-f (Pixmap$Format/RGBA8888)
+          ^Pixmap pic (Pixmap. ^long (game :width) ^long (game :height) pic-f)
           pixel-data (ScreenUtils/getFrameBufferPixels true)
           pixels (.getPixels pic)]
       (doto pixels
@@ -30,7 +31,7 @@
                    (files! :local path)
                    path)]
       (PixmapIO/writePNG handle pic)
-      (.dispose pic))))
+      (pixmap! pic :dispose))))

 ; static fields


Add dispose warning to screenshot! function

--- src/play_clj/core_utils.clj
+++ src/play_clj/core_utils.clj
@@ -9,7 +9,8 @@

 (defn screenshot!
   "Captures a screenshot and either returns it as a `pixmap` or saves it to the
-specified path.
+specified path. Note that when a `pixmap` is no longer needed, you must call
+`(pixmap! object :dispose)` to clear it from memory.

     (screenshot!)
     (screenshot! \"out.png\")


improve performance of (defn lightning-bolt): check if parent will accept a lexical head (get-in parent [:head :phrasal]) before trying to add any lexical heads

--- src/babel/generate.cljc
+++ src/babel/generate.cljc
@@ -108,6 +108,9 @@
                                                   [cat-set pred-set])
                      subset
                      (cond
+                       (= true (get-in parent [:head :phrasal]))
+                       []
+
                        (not (empty? non-empty-index-sets))
                        (reduce intersection-with-identity non-empty-index-sets)


rewrite (defn find-comp-paths-in) and remove unneeded param from (show-bolt)

--- src/babel/generate.cljc
+++ src/babel/generate.cljc
@@ -69,6 +69,7 @@
 (declare candidate-parents)
 (declare lazy-shuffle)
 (declare find-comp-paths-in)
+(declare bolt-depth)
 (declare add-all-comps)
 (declare add-all-comps-with-paths)

@@ -95,8 +96,9 @@
   (log/trace (str "add-all-comps with (empty? bolts): " (empty? bolts)))
   (lazy-mapcat
    (fn [bolt]
+     (log/debug (str "add-all-comps: adding comps to bolt: " (show-bolt bolt language-model)))
      (add-all-comps-with-paths [bolt] language-model total-depth
-                               (find-comp-paths-in bolt [:head])
+                               (find-comp-paths-in (bolt-depth bolt))
                                truncate-children max-total-depth))
    bolts))

@@ -127,11 +129,30 @@
     (cons (vec (concat (butlast path) [:comp]))
           (find-comp-paths-in bolt (concat path [:head])))))

+(defn bolt-depth [bolt]
+  (if-let [head (get-in bolt [:head] nil)]
+    (+ 1 (bolt-depth head))
+    0))
+
+(defn find-comp-paths-in [depth]
+  (cond
+    ;; most-frequent cases done statically:
+    (= 0 depth) nil
+    (= 1 depth) [[:comp]]
+    (= 2 depth) [[:head :comp][:comp]]
+    (= 3 depth) [[:head :head :comp][:head :comp][:comp]]
+    (= 4 depth) [[:head :head :head :comp][:head :head :comp][:head :comp][:comp]]
+
+    ;;
+    true
+    (cons (vec (concat (take (- depth 1) (repeatedly (fn [] :head))) [:comp]))
+          (find-comp-paths-in (- depth 1)))))
+
 (defn add-complement-to-bolt [bolt path language-model total-depth
                               & {:keys [max-total-depth truncate-children]
                                  :or {max-total-depth max-total-depth
                                       truncate-children true}}]
-  (log/debug (str "add-complement-to-bolt: " (show-bolt bolt path language-model)
+  (log/debug (str "add-complement-to-bolt: " (show-bolt bolt language-model)
                   "@[" (string/join " " path) "]" "^" total-depth))
   (let [index (:index language-model)
         lexicon (if (-> :generate :lexicon language-model)
@@ -167,7 +188,7 @@
                          (truncate unified [path])
                          unified)))
                   (let [debug (log/trace (str "add-complement-to-bolt(total-depth=" total-depth
-                                              ",path=" path ",bolt=(" (show-bolt bolt path language-model)
+                                              ",path=" path ",bolt=(" (show-bolt bolt language-model)
                                               "): calling generate-all(" (strip-refs spec) ");"
                                               "spec: " spec))
                         phrasal-complements (if (and (> max-total-depth total-depth)
@@ -189,7 +210,7 @@

                           (and (empty? filtered-lexical-complements)
                                (empty? phrasal-complements))
-                          (log/warn (str "add-complement-to-bolt: could generate neither phrasal nor lexical complements for parent: "
+                          (log/warn (str "add-complement-to-bolt: could generate neither phrasal nor lexical complements for bolt:" (show-bolt bolt language-model) "; immediate parent: "
                                           (get-in bolt (concat (butlast path) [:rule]) :norule) " "
                                           "while trying to create a complement: " (spec-info spec)))

@@ -220,7 +241,7 @@
   (log/info (str "lightning-bolts(depth=" depth
                  "; total-depth=" total-depth
                  "; max-total-depth=" max-total-depth
-                 "; spec info:" (spec-info spec)))
+                 "; spec info:" (spec-info spec) ")"))
   (let [morph (:morph language-model)
         grammar (:grammar language-model)
         index (:index language-model)
@@ -381,19 +402,18 @@
         (> (* 10 prob) (rand-int 10)))
       false)))

-(defn show-bolt [bolt path language-model]
+(defn show-bolt [bolt language-model]
   (if (nil? bolt)
     (exception (str "don't call show-bolt with bolt=null."))
     (let [morph (:morph language-model)]
       (if (nil? morph)
         (exception (str "don't call show-bolt with morph=null."))
-        (if (not (empty? path))
-          (str "[" (get-in bolt [:rule])
-               " '" (morph-with-recovery morph bolt) "'"
-               (let [head-bolt (get-in bolt [:head])]
-                 (if (not (nil? head-bolt))
-                   (let [rest-str (show-bolt (get-in bolt [:head]) (rest path) language-model)]
-                     (if (not (nil? rest-str))
-                       (str " -> " rest-str)))))
-               "]"))))))
-
+        (str "[" (get-in bolt [:rule])
+             " '" (morph-with-recovery morph bolt) "'"
+             (let [head-bolt (get-in bolt [:head])]
+               (if (not (nil? head-bolt))
+                 (let [rest-str (show-bolt (get-in bolt [:head]) language-model)]
+                   (if (not (nil? rest-str))
+                     (str " -> " rest-str)))))
+             "]")))))
+


Implement enabling the edit mode on F2

Implement enabling the edit mode on F2

--- src/reabledit/keyboard.cljs
+++ src/reabledit/keyboard.cljs
@@ -36,7 +36,7 @@
         (util/disable-edit! state element-id))

       ;; Arrow keys in navigation mode change the selection
-      ;; Enter in navigation mode enables editing mode
+      ;; Enter and F2 in navigation mode enables editing mode
       (nil? (:edit @state))
       (do
         (.preventDefault e)
@@ -47,4 +47,5 @@
           40 (f (min rows (inc current-row)) current-col)
           9 (f current-row (min cols (inc current-col)))
           13 (util/enable-edit! columns data state)
+          113 (util/enable-edit! columns data state)
           nil)))))


Minor fixes

Minor fixes

--- server/src/clinicico/server/handlers.clj
+++ server/src/clinicico/server/handlers.clj
@@ -13,7 +13,7 @@
 (def service-rpc-uri (str base "rpc#"))
 (def service-status-uri (str base "status#"))

-(defn dispatch
+(defn dispatch-rpc
   [method data]
   (let [{:keys [updates close results]} (service/publish method data)]
     (go (loop [update (<! updates)]
@@ -23,12 +23,12 @@
               (recur (<! updates))))))
     (try @results
          (catch Exception e
-           (do (log/error e)
-               (throw e))))))
+           {:error {:uri service-rpc-uri
+                    :message (.getMessage e)}}))))

 (defn service-run-rpc [method data]
   (if (service/available? method)
-    (dispatch method data)
+    (dispatch-rpc method data)
     {:error {:uri service-rpc-uri
              :message (str "service " method " not avaiable")}}))

@@ -42,5 +42,4 @@
       (wamp/http-kit-handler channel
                              {:on-call {service-rpc-uri (partial service-run-rpc method)}
                               :on-subscribe {service-status-uri true}
-                              :on-publish {service-status-uri true
-                                           (str service-status-uri "pub-only") true}}))))
+                              :on-publish {service-status-uri true}}))))


added test for error for rebalancing to zero executors

--- test/clj/backtype/storm/nimbus_test.clj
+++ test/clj/backtype/storm/nimbus_test.clj
@@ -432,6 +432,12 @@
       (bind slot-executors (slot-assignments cluster storm-id))
       (check-distribution slot-executors [1 1 1])
       (check-num-nodes slot-executors 3)
+
+      (is (thrown? InvalidTopologyException
+                   (.rebalance (:nimbus cluster) "test"
+                     (doto (RebalanceOptions.)
+                       (.set_num_executors {"1" 0})
+                       ))))
       )))

 (deftest test-cleans-corrupt


update to drone

update to drone

--- src/borderless/core.clj
+++ src/borderless/core.clj
@@ -31,30 +31,40 @@
   []
   (demo (sin-osc)))

+
+(defn tremelo [] (sin-osc:kr 0.5))
+
+(definst drone [freq 1000]
+  "Inst calls the synth macro which takes a synthesizer definition form. The saw function represents a unit-generator, or ugen. These are the basic building blocks for creating synthesizers, and they can generate or process both audio and control signals (odoc saw)"
+  (saw (+ freq (sin-osc:kr 0.5))))
+
+;; (defn ramp [tone ]
+;;   (ctl drone :freq
+
 ;;;;;;;;;;;;;;;;;;;;;
 ;; OSC Server      ;;
 ;;;;;;;;;;;;;;;;;;;;;

-(def PORT 12000)
+;; (def PORT 12000)

-(def server (osc-server PORT))
-(def client (osc-client "localhost" PORT))
+;; (def server (osc-server PORT))
+;; (def client (osc-client "localhost" PORT))

-(defn close-down! []
-  ;; remove handler
-  (osc-rm-handler server "/TSPS/personEntered")
+;; (defn close-down! []
+;;   ;; remove handler
+;;   (osc-rm-handler server "/TSPS/personEntered")

-  ;; stop listening and deallocate resources
-  (osc-close server))
+;;   ;; stop listening and deallocate resources
+;;   (osc-close server))

-(def noise-chooser
-  (fn [] (rand-nth noise)))
+;; (def noise-chooser
+;;   (fn [] (rand-nth noise)))

-(defn person-entered []
-  (osc-handle server "/TSPS/personEntered"
-              (fn [msg]
-                ((noise-chooser))
-                (println "Handler for /TSPS/personEntered: " msg))))
+;; (defn person-entered []
+;;   (osc-handle server "/TSPS/personEntered"
+;;               (fn [msg]
+;;                 ((noise-chooser))
+;;                 (println "Handler for /TSPS/personEntered: " msg))))

 (defn -main
   "I don't do a whole lot ... yet."


Remove TODO (see #4)

Remove TODO (see #4)

--- src/caesium/binding.clj
+++ src/caesium/binding.clj
@@ -87,8 +87,6 @@
      ^long ^{LongLong {}} msglen
      ^bytes ^{Pinned {}} key
      ^long ^{LongLong {}} keylen]
-
-    ;; TODO: how do I reference a crypto_generichash_state *?

     ^long ^{size_t {}} crypto_generichash_blake2b_bytes_min []
     ^long ^{size_t {}} crypto_generichash_blake2b_bytes_max []


GM: Add phantom js test-runners

GM: Add phantom js test-runners


Less let usage.

Less let usage.

--- src/cbfg/vis.cljs
+++ src/cbfg/vis.cljs
@@ -303,38 +303,38 @@
         (recur (inc num-events)))
     (let [el-event (str el-prefix "-event") ; Process U/I related events.
           el-html (str el-prefix "-html")
-          el-svg (str el-prefix "-svg")]
-      (go (let [world (conj w 'world-1)]    ; Can't use ago to initialize world.
-            (go-loop [vis-last nil          ; Process render-ch, updating U/I.
-                      vis-last-positions nil
-                      vis-last-html nil
-                      vis-last-svg nil
-                      prev-deltas nil]
-              (let [[vis-next deltas after event-str] (<! render-ch)
-                    next-deltas (take 20 (conj prev-deltas [after deltas]))]
-                (set-el-innerHTML el-event event-str)
-                (if after
-                  (let [vis-next-positions (atom {})
-                        actx-ch-ch-infos (group-by #(:first-taker-actx (second %)) (:chs vis-next))]
-                    (assign-positions vis-next world vis-next-positions actx-ch-ch-infos
-                                      (when (get-in vis-next [:actxs world :closed]) 0))
-                    (let [vis-next-html (apply str (flatten (vis-html-actx vis-next world
-                                                                           actx-ch-ch-infos)))
-                          vis-next-svg (apply str (flatten (vis-svg-actxs vis-next @vis-next-positions
-                                                                          deltas true prev-deltas)))]
-                      (when (not= vis-next-html vis-last-html)
-                        (set-el-innerHTML el-html vis-next-html)
-                        (when on-render-cb
-                          (on-render-cb vis-next)))
-                      (when (not= vis-next-svg vis-last-svg)
-                        (set-el-innerHTML el-svg vis-next-svg))
-                      (recur vis-next @vis-next-positions vis-next-html vis-next-svg next-deltas)))
-                  (let [vis-next-svg (apply str (flatten (vis-svg-actxs vis-last vis-last-positions
-                                                                        deltas false prev-deltas)))]
-                    (when (not= vis-next-svg vis-last-svg)
-                      (set-el-innerHTML el-svg vis-next-svg))
-                    (recur vis-last vis-last-positions vis-last-html vis-next-svg next-deltas)))))
-            (world-init-cb world)))
+          el-svg (str el-prefix "-svg")
+          world (conj w 'world-1)]    ; No ago for world actx init to avoid recursion.
+      (go-loop [vis-last nil          ; Process render-ch, updating U/I.
+                vis-last-positions nil
+                vis-last-html nil
+                vis-last-svg nil
+                prev-deltas nil]
+        (let [[vis-next deltas after event-str] (<! render-ch)
+              next-deltas (take 20 (conj prev-deltas [after deltas]))]
+          (set-el-innerHTML el-event event-str)
+          (if after
+            (let [vis-next-positions (atom {})
+                  actx-ch-ch-infos (group-by #(:first-taker-actx (second %)) (:chs vis-next))]
+              (assign-positions vis-next world vis-next-positions actx-ch-ch-infos
+                                (when (get-in vis-next [:actxs world :closed]) 0))
+              (let [vis-next-html (apply str (flatten (vis-html-actx vis-next world
+                                                                     actx-ch-ch-infos)))
+                    vis-next-svg (apply str (flatten (vis-svg-actxs vis-next @vis-next-positions
+                                                                    deltas true prev-deltas)))]
+                (when (not= vis-next-html vis-last-html)
+                  (set-el-innerHTML el-html vis-next-html)
+                  (when on-render-cb
+                    (on-render-cb vis-next)))
+                (when (not= vis-next-svg vis-last-svg)
+                  (set-el-innerHTML el-svg vis-next-svg))
+                (recur vis-next @vis-next-positions vis-next-html vis-next-svg next-deltas)))
+            (let [vis-next-svg (apply str (flatten (vis-svg-actxs vis-last vis-last-positions
+                                                                  deltas false prev-deltas)))]
+              (when (not= vis-next-svg vis-last-svg)
+                (set-el-innerHTML el-svg vis-next-svg))
+              (recur vis-last vis-last-positions vis-last-html vis-next-svg next-deltas)))))
+      (world-init-cb world)
       (let [toggle-ch (listen-el (gdom/getElement el-html) "click")] ; Process toggle U/I events.
         (go-loop []
           (let [actx-id (no-prefix (.-id (.-target (<! toggle-ch))))]


Changes to data to get mailing list

Changes to data to get mailing list

--- src/eddy/data.clj
+++ src/eddy/data.clj
@@ -2,6 +2,7 @@
   (:require [amazonica.aws.s3 :refer [get-object put-object list-objects]]
             [clj-time.format :as time-format]
             [environ.core :refer [env]]
+            [clojure.string :as string]
             [clojure.java.io :refer [reader]]))

 (def zephyrus-bucket (env :zephyrus-bucket))
@@ -33,8 +34,12 @@
 (defn get-email-template []
   (get-data data-bucket "template.html"))

+(defn get-mailing-list []
+  (string/split (get-data data-bucket "subscribers.txt") #"\n"))
+
 (defn put-last-check [date]
-  (put-data data-bucket "last-check" (str date)))
+  (put-data data-bucket "last-check" (str date))
+  (println "put"))

 (defn leaves-since-last-check []
   (leaves-after zephyrus-bucket (get-last-check)))