Fix clojurescript issues

Fix clojurescript issues

--- src/spec_tools/core.cljc
+++ src/spec_tools/core.cljc
@@ -119,7 +119,7 @@
         ::s/invalid)))
   (unform* [_ x] x)
   (explain* [_ path via in x]
-    (when (s/invalid? (if (pred x) x ::s/invalid))
+    (when (= ::s/invalid (if (pred x) x ::s/invalid))
       [{:path path :pred (s/abbrev form) :val x :via via :in in}]))
   (gen* [_ _ _ _] (if gfn
                     (gfn)
@@ -127,10 +127,8 @@
   (with-gen* [_ gfn] (->Type form pred gfn info))
   (describe* [_] form)
   IFn
-  (invoke [_ x]
-    (pred x))
-  (applyTo [this args]
-    (AFn/applyToHelper this args))) []
+  #?(:clj (invoke [_ x] (pred x))
+     :cljs (-invoke [_ x] (pred x))))

 #?(:clj
    (defmethod print-method Type


remove commented out code

remove commented out code

--- src/ads_txt_crawler/process.clj
+++ src/ads_txt_crawler/process.clj
@@ -42,35 +42,8 @@
 (defn is-error [status]
   (>= status 400))

-;; (defn read-ads-txt-url [url]
-;;   ;; read the contents of url
-;;   ;; - ignore non-text returns
-;;   ;; - ignore commented lines
-;;   ;; - parse lines into map of values
-;;   ;; - ignore
-;;   (let [{:keys [status headers body error] :as resp} (h/get-url url)]
-;;     (if error
-;;       (.println *err* (format "Error: %s for %s" (.toString error) url))
-;;       (if status
-;;         ;; if 4xx or 5xx status then there is no ads.txt file
-;;         (if (is-error status)
-;;           (.println *err* (format "Error: 400/500 level error for %s" url))
-;;           ;; if there are no headers then there is an issue
-;;           (if (not headers)
-;;             (.println *err* (format "Error: headers are blank for %s" url))
-;;             ;; the content-type needs to be text/plain
-;;             (if (is-text url headers)
-;;               (remove nil? (map process-line (clojure.string/split-lines body)))
-;;               (.println *err* (format "Error: non-text result for %s" url)))))
-;;         (.println *err* (format "Error: Unknown issue calling %s" url))))))
-
 (defn build-url [domain]
   (format "http://%s/ads.txt" domain))
-
-;; (defn process
-;;   "For a given domain build it's ads.txt url and return the urls it contains"
-;;   [domain]
-;;   (read-ads-txt-url (build-url domain)))

 (defn process-to-map
   "Return results in a map including a status value"


Implemented/copied output/helper functions.

--- src/semantic_csv/transducers.clj
+++ src/semantic_csv/transducers.clj
@@ -1,7 +1,22 @@
+;; # Core functionality as Transducers
+;;
+
 (ns semantic-csv.transducers
+  "# Transducers API namespace"
   (:require [clojure.java.io :as io]
             [clojure-csv.core :as csv]
             [semantic-csv.impl.core :as impl :refer [?>>]]))
+
+;; # Input processing functions
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+;;
+;; Note that all of these processing functions return a transducer unless otherwise stated.
+;; This allows for single passes accross collections.
+;;
+
+
+;;

+;; ## mappify

 (defn mappify
   "Takes a sequence of row vectors, as commonly produced by csv parsing libraries, and returns a sequence of
@@ -23,11 +38,33 @@
                 results)
             (rf results (impl/mappify-row @hdr input)))))))))

+;; Here's an example using the mappify transducers.
+;;
+;;     => (with-open [in-file (io/reader "test/test.csv")]
+;;          (transduce
+;;            (mappify)
+;;            conj
+;;            []
+;;            (csv/parse-csv in-file))
+;;
+;;     [{:this "# some comment lines..."}
+;;      {:this "1", :that "2", :more "stuff"}
+;;      {:this "2", :that "3", :more "other yeah"}]
+;;
+;;

+;;
+;; Note that `"# some comment lines..."` was really intended to be left out as a comment.
+;; We can address this with the following function:
+
+
+;;

+;; ## structify
+
 (defn structify
   "Takes a sequence of row vectors, as commonly produced by csv parsing libraries, and returns a sequence of
   structs. By default, the first row vector will be interpreted as a header, and used as the keys for the maps.
   However, this and other behaviour are customizable via an optional `opts` map with the following options:
-
+
   * `:keyify` - bool; specify whether header/column names should be turned into keywords (default: `true`).
   * `:header` - specify the header to use for map keys, preventing first row of data from being consumed as header."
   ([] (structify {}))
@@ -43,6 +80,27 @@
                 results)
             (rf results (apply struct (apply create-struct @hdr) input)))))))))

+;; Here's an example of structify:
+;;
+;;     => (with-open [in-file (io/reader "test/test.csv")]
+;;          (transduce
+;;            (structify)
+;;            conj
+;;            []
+;;            (csv/parse-csv in-file))
+;;
+;;     ({:this "# some comment lines..."}
+;;      {:this "1", :that "2", :more "stuff"}
+;;      {:this "2", :that "3", :more "other yeah"})
+;;
+;;

+;;
+;; Note that `"# some comment lines..."` was really intended to be left out as a comment.
+;; We can address this with the following function:
+
+
+;;

+;; ## remove-comments
 (defn remove-comments
   "Removes rows which start with a comment character (by default, `#`). Operates by checking whether
   the first item of every row in the collection matches a comment pattern. Also removes empty lines.
@@ -66,6 +124,28 @@
             (if (and x (commented? x))
               results
               (rf results input)))))))))
+
+;; Notice the remove-comments is placed before mappify.
+;; We want this done in order.  The order flows from left to right in the compose.
+;; This is a property of transducers.
+;;
+;;     => (with-open [in-file (io/reader "test/test.csv")]
+;;          (transduce
+;;            (comp (remove-comments) (mappify))
+;;            conj
+;;            []
+;;            (csv/parse-csv in-file)))
+;;
+;;     ({:this "1", :that "2", :more "stuff"}
+;;      {:this "2", :that "3", :more "other yeah"})
+;;
+;;

+;; Next, let's observe that `:this` and `:that` point to strings, while they should really be pointing to
+;; numeric values.
+;; This can be addressed with the following function:
+
+;;

+;; ## cast-with

 (defn cast-with
   "Casts the vals of each row according to `cast-fns`, which must either be a map of
@@ -91,17 +171,51 @@
               (do (vreset! fst input) (rf results input))) ;; fst is nil. reset fst and return the results.
             (rf results (impl/cast-row cast-fns input :only only :exception-handler exception-handler)))))))))

-;; TODO: properly implement except first as transducer.  need to take n functions and apply then in order as in ->>.
-;; (defn except-first
-;;   []
-;;   (fn [rf]
-;;     (let [fst (volatile! nil)]
-;;       (fn
-;;         ([] (rf))
-;;         ([results] (rf results))
-;;         ([results input]
-;;          (if @fst
-;;            (rf results)))))))
+;; Let's try casting a numeric column using this function:
+;;
+;;     => (with-open [in-file (io/reader "test/test.csv")]
+;;          (transduce
+;;            (comp
+;;              (remove-comments)
+;;              (mappify)
+;;              (cast-with {:this #(Integer/parseInt %)}))
+;;            conj
+;;            []
+;;            (csv/parse-csv in-file)))
+;;
+;;     ({:this 1, :that "2", :more "stuff"}
+;;      {:this 2, :that "3", :more "other yeah"})
+;;
+;; Alternatively, if we want to cast multiple columns using a single function, we can do so
+;; by passing a single casting function as the first argument.
+;;
+;;     => (with-open [in-file (io/reader "test/test.csv")]
+;;          (transduce
+;;            (comp
+;;              (remove-comments)
+;;              (mappify)
+;;              (cast-with #(Integer/parseInt %) {:only [:this :that]}))
+;;            conj
+;;            []
+;;            (csv/parse-csv in-file)))
+;;
+;;     ({:this 1, :that 2, :more "stuff"}
+;;      {:this 2, :that 3, :more "other yeah"})
+;;
+;; Note that this function handles either map or vector rows.
+;; In particular, if you’ve imported data without consuming a header (by either not using mappify or
+;; by passing `:header false` to `process` or `slurp-csv` below), then the columns can be keyed by their
+;; zero-based index.
+;; For instance, `(cast-with {0 #(Integer/parseInt %) 1 #(Double/parseDouble %)} rows)`
+;; will parse the first column as integers and the second as doubles.
+;;
+;;

+;; It's worth pointing out this function isn't strictly an _input_ processing function, but could be
+;; used for intermediate or output preparation processing.
+
+
+;;

+;; ## process

 (defn process
   "This function wraps together the most frequently used input processing capabilities,
@@ -140,6 +254,19 @@
   ([]
    (process {})))

+;; Using this function, the code we've been building above is reduced to the following:
+;;
+;;     (with-open [in-file (io/reader "test/test.csv")]
+;;       (transduce
+;;         (process {:cast-fns {:this #(Integer/parseInt %)}})
+;;         conj
+;;         []
+;;         (csv/parse-csv in-file)))
+
+
+;;

+;; ## parse-and-process
+
 (defn parse-and-process
   "This is a convenience function for reading a csv file using `clojure/data.csv` and passing it through `process`
   with the given set of options (specified _last_ as kw_args, in contrast with our other processing functions).
@@ -151,6 +278,14 @@
     (transduce (process rest-options) conj []
      (impl/apply-kwargs csv/parse-csv csv-readable parser-opts))))

+;;     (with-open [in-file (io/reader "test/test.csv")]
+;;         (parse-and-process in-file
+;;                            :cast-fns {:this #(Integer/parseInt %)}))
+
+
+;;

+;; ## slurp-csv
+
 (defn slurp-csv
   "This convenience function let's you `parse-and-process` csv data given a csv filename. Note that it is _not_
   lazy, and must read in all data so the file handle can be closed."
@@ -158,3 +293,246 @@
   (let [rest-options (dissoc opts :parser-opts)]
     (with-open [in-file (io/reader csv-filename)]
        (impl/apply-kwargs parse-and-process in-file opts))))
+
+;; For the ultimate in _programmer_ laziness:
+;;
+;;     (slurp-csv "test/test.csv"
+;;                :cast-fns {:this #(Integer/parseInt %)})
+
+
+;;

+;; # Some casting functions for your convenience
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+;;
+;; These functions can be imported and used in your `:cast-fns` specification.
+;; They focus on handling some of the mess of dealing with numeric casting.
+
+;; ## ->int
+
+(defn ->int
+  "Translate to int from string or other numeric. If string represents a non integer value,
+  it will be rounded down to the nearest int."
+  [v]
+  (if (string? v)
+    (-> v clojure.string/trim Double/parseDouble int)
+    (int v)))
+
+;; ## ->long
+
+(defn ->long
+  "Translate to long from string or other numeric. If string represents a non integer value,
+  will be rounded down to the nearest long."
+  [v]
+  (if (string? v)
+    (-> v clojure.string/trim Double/parseDouble long)
+    (long v)))
+
+;; ## ->float
+
+(defn ->float
+  "Translate to float from string or other numeric."
+  [v]
+  (if (string? v)
+    (-> v clojure.string/trim Float/parseFloat)
+    (float v)))
+
+;; ## ->double
+
+(defn ->double
+  "Translate to double from string or other numeric."
+  [v]
+  (if (string? v)
+    (-> v clojure.string/trim Double/parseDouble)
+    (double v)))
+
+;;     (slurp-csv "test/test.csv"
+;;                :cast-fns {:this ->int})
+
+;; Note these functions place a higher emphasis on flexibility and convenience than performance, as you can
+;; likely see from their implementations.
+;; If maximum performance is a concern for you, and your data is fairly regular, you may be able to get away with
+;; less robust functions, which shouldn't be hard to implement yourself.
+;; For most cases though, the performance of those provided here should be fine.
+
+
+;;

+;; # Output processing functions
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+
+
+;; As with the input processing functions, the output processing functions are designed to be small,
+;; composable pieces which help you push your data through to a third party writer.
+;; And as with the input processing functions, higher level, opinionated, but configurable functions
+;; are offered which automate some of this for you.
+;;
+;; We've already looked at `cast-with`, which can be useful in output as well as input
+;; processing.
+;; Another important function we'll need is one that takes a sequence of maps and turns it into a sequence
+;; of vectors since this is what most of our csv writing/formatting libraries will want.
+
+
+;;

+;; ## vectorize
+
+(defn vectorize
+  "Take a sequence of maps, and transform them into a sequence of vectors. Options:
+
+  * `:header` - The header to be used. If not specified, this defaults to `(-> rows first keys)`. Only
+    values corresponding to the specified header will be included in the output, and will be included in the
+    order corresponding to this argument.
+  * `:prepend-header` - Defaults to true, and controls whether the `:header` vector should be prepended
+    to the output sequence.
+  * `:format-header` - If specified, this function will be called on each element of the `:header` vector, and
+    the result prepended to the output sequence. The default behaviour is to leave strings alone but stringify
+    keyword names such that the `:` is removed from their string representation. Passing a falsey value will
+    leave the header unaltered in the output."
+  ([]
+   (vectorize {}))
+  ([{:keys [header prepend-header format-header]
+     :or {prepend-header true format-header impl/stringify-keyword}}]
+   (fn [rf]
+     (let [hdr (volatile! header)]
+       (fn
+         ([] (rf))
+         ([result] (rf result))
+         ([result input]
+          (if (empty? @hdr)
+            (do (vreset! hdr (into [] (keys input)))
+                (if prepend-header
+                  (rf
+                   (if format-header
+                     (conj result (mapv format-header @hdr))
+                     (conj result @hdr))
+                   (mapv (partial get input) @hdr))))
+            (rf result (mapv (partial get input) @hdr)))
+          ))))))
+
+
+;; Let's see this in action:
+;;
+;;     => (let [data [{:this "a" :that "b"}
+;;                    {:this "x" :that "y"}]]
+;;          (transduce (vectorize) conj [] data))
+;;     (["this" "that"]
+;;      ["a" "b"]
+;;      ["x" "y"])
+;;
+;; With some options:
+;;
+;;     => (let [data [{:this "a" :that "b"}
+;;                    {:this "x" :that "y"}]]
+;;          (transduce (vectorize {:header [:that :this]
+;;                      :prepend-header false})
+;;                     conj
+;;                     []
+;;                     data))
+;;     (["b" "a"]
+;;      ["y" "x"])
+
+
+;;

+;; ## batch
+
+(defn batch
+  "Does not return a transducer. Takes sequence of items and returns a
+  sequence of batches of items from the original sequence, at most `n` long."
+  [n rows]
+  (partition n n [] rows))
+
+;; This function can be useful when working with `clojure-csv` when writing lazily.
+;; The `clojure-csv.core/write-csv` function does not actually write to a file, but just formats the data you
+;; pass in as a CSV string.
+;; If you're working with a lot of data, calling this function would build a single massive string of the
+;; results, and likely crash.
+;; To write _lazily_, you have to take some number of rows, write them, and repeat till you're done.
+;; Our `batch` function helps by giving you a lazy sequence of batches of `n` rows at a time, letting you pass
+;; _that_ through to something that writes off the chunks lazily.
+
+
+;;

+;; And as promised, a function for doing all the dirty work for you:
+
+
+;;

+;; ## spit-csv
+
+(defn spit-csv
+  "Convenience function for spitting out CSV data to a file using `clojure-csv`.
+
+  * `file` - Can be either a filename string, or a file handle.
+  * `opts` - Optional hash of settings.
+  * `rows` - Can be a sequence of either maps or vectors; if the former, vectorize will be
+      called on the input with `:header` argument specifiable through `opts`.
+
+  The Options hash can have the following mappings:
+
+  * `:batch-size` - How many rows to format and write at a time?
+  * `:cast-fns` - Formatter(s) to be run on row values. As with `cast-with` function, can be either a map
+     of `column-name -> cast-fn`, or a single function to be applied to all values. Note that `str` is called
+     on all values just before writing regardless of `:cast-fns`.
+  * `:writer-opts` - Options hash to be passed along to `clojure-csv.core/write-csv`.
+  * `:header` - Header to be passed along to `vectorize`, if necessary.
+  * `:prepend-header` - Should the header be prepended to the rows written if `vectorize` is called?"
+  ([file rows]
+   (spit-csv file {} rows))
+  ([file
+    {:keys [batch-size cast-fns writer-opts header prepend-header]
+     :or   {batch-size 20 prepend-header true}
+     :as   opts}
+    rows]
+   (if (string? file)
+     (with-open [file-handle (io/writer file)]
+       (spit-csv file-handle opts rows))
+     ; Else assume we already have a file handle
+     (let [cast-fn (when cast-fns (cast-with cast-fns))
+           vect-fn (when (-> rows first map?) (vectorize {:header header :prepend-header prepend-header}))
+           vect-rows (transduce (apply comp (remove nil? [cast-fn vect-fn (cast-with str)])))]
+       (->> vect-rows
+            (batch batch-size)
+            (map #(impl/apply-kwargs csv/write-csv % writer-opts))
+            (reduce
+             (fn [w rowstr]
+               (.write w rowstr)
+               w)
+             file))))))
+
+;; Note that since we use `clojure-csv` here, we offer a `:batch-size` option that lets you format and write small
+;; batches of rows out at a time, to avoid constructing a massive string representation of all the data in the
+;; case of bigger data sets.
+
+
+;;

+;; # One last example showing everything together
+;;
+;; Let's see how Semantic CSV works in the context of a little data pipeline.
+;; We're going to thread data in, transform into maps, run some computations for each row and assoc in,
+;; then write the modified data out to a file, all lazily.
+;;
+;; First let's show this with `clojure/data.csv`, which I find a little easier to use for writing:
+;;
+;;     (require '[clojure.data.csv :as cd-csv])
+;;
+;;     (with-open [in-file (io/reader "test/test.csv")
+;;                 out-file (io/writer "test-out.csv")]
+;;       (->>
+;;         (transduce
+;;           (comp
+;;             (remove-comments)
+;;             (mappify)
+;;             (cast-with {:this ->int :that ->float})
+;;             ;; Do your processing...
+;;             (map
+;;               (fn [row]
+;;                 (assoc row :jazz (* (:this row)
+;;                                     (:that row)))))
+;;             (vectorize))
+;;           conj
+;;           []
+;;           (cd-csv/read-csv in-file))
+;;         (cd-csv/write-csv out-file)))
+;;
+;;
+;;

+;; And there you have it.
+;; A simple, composable, and easy to use library for taking you the extra mile with CSV processing in
+;; Clojure.


call done on locks

call done on locks

--- src/server/client-interface.cljs
+++ src/server/client-interface.cljs
@@ -61,13 +61,14 @@
       (rooms/disconnect (.-id socket)
         (fn [room-id]
           (redis-lock. room-id
-            (fn [_]
+            (fn [done]
               (rooms/handle-disconnect room-id
                 (fn []
                   (rooms/get-all-users room-id
                     (fn [users]
                       (if-not (empty? users)
-                        (.emit (.to io room-id) "users-list" (clj->js users)))))
+                        (.emit (.to io room-id) "users-list" (clj->js users)))
+                      (done)))
                   (println (str (.-id socket) " has disconnected from " room-id))))))))))

   (.on socket "sign-in"
@@ -449,7 +450,7 @@
                       (println "Upload of" original-filename
                                "from" (.-id socket) "is complete!")
                       (redis-lock. room
-                        (fn [_]
+                        (fn [done]
                           (let [magic (Magic. (.-MAGIC_MIME_TYPE mmm))]
                             (.detectFile magic temp-absolute-file-path
                               (fn [_ mime-type]
@@ -487,7 +488,8 @@
                                                               (if-not started?
                                                                 (rooms/get-num-of-tracks room
                                                                   (fn [num-of-tracks]
-                                                                    (change-track room (- num-of-tracks 1) (.v4 js-uuid)))))))))))))))))))))))))))))))))))))))
+                                                                    (change-track room (- num-of-tracks 1) (.v4 js-uuid))
+                                                                    (done))))))))))))))))))))))))))))))))))))))

 (defn start-listening! []
   (.on io "connection" connection))


Expanded the Ring response map to include a :commit? key; this is needed for filters like the Blobstore which do their own work on uncommitted servlet responses.

--- src/appengine_magic/servlet.clj
+++ src/appengine_magic/servlet.clj
@@ -115,12 +115,14 @@

 (defn- adapt-servlet-response [^HttpServletResponse response,
-                               {:keys [status headers body] :as response-map}]
-  (if status
-      (.setStatus response status)
-      (throw (RuntimeException. "handler response status not set")))
-  (when headers (set-response-headers response headers))
-  (when body (set-response-body response body)))
+                               {:keys [commit? status headers body]
+                                :or {commit? true}}]
+  (when commit?
+    (if status
+        (.setStatus response status)
+        (throw (RuntimeException. "handler response status not set")))
+    (when headers (set-response-headers response headers))
+    (when body (set-response-body response body))))

 (defn make-servlet-service-method [ring-handler]


Added test for echo resource

Added test for echo resource

--- test/trumpet_server/api/rest_test.clj
+++ test/trumpet_server/api/rest_test.clj
@@ -52,6 +52,33 @@
                           ; Then
                           (:trumpeteersInRange location-response) => 2)

+                    (fact "/echo broadcast the trumpet to trumpetees with the same messageId"
+                          ; Given
+
+                          ; Create trumpeteers
+                          (def trumpeteerResponse (->> (client/get "http://127.0.0.1:5000/api" {:query-params {"latitude" 55.583985 "longitude" 12.957578} :as :json}) :body))
+                          (def trumpeteeResponse (->> (client/get "http://127.0.0.1:5000/api" {:query-params {"latitude" 55.584126 "longitude" 12.957406} :as :json}) :body))
+
+
+                          ; Register trumpetee for subscription
+                          (def subscription (future (let [inputstream (:body (client/get (->> trumpeteeResponse :_links :subscribe :href) {:as :stream}))
+                                                          reader (io/reader inputstream)
+                                                          event (read-until-emptyline reader)
+                                                          trumpet (json/parse-string (re-find #"\{.*\}" event) true)
+                                                          has-trumpet-event-type? (.contains (re-find #"event:.*data:" event) "trumpet")]
+                                                      {:has-trumpet-event-type? has-trumpet-event-type? :trumpet trumpet})))
+
+                          ; Race-condition because subscription will return immeditaley and we'll post the trumpet before the subscription is registered.
+                          (Thread/sleep 500)
+
+                          ; When
+                          (client/post (str "http://127.0.0.1:5000/api/trumpeteers/" (->> trumpeteerResponse :trumpeteerId) "/echo") {:form-params {"message" "My trumpet" "messageId" "ABC123"}})
+
+                          ; Then
+                          (def event (deref subscription 3000 :timed-out))
+                          (:has-trumpet-event-type? event) => true
+                          (:trumpet event) => (just {:id "ABC123", :timestamp anything :message "My trumpet" :distanceFromSource anything :_links anything})
+                          (->> event :trumpet :_links :echo :href) => "http://127.0.0.1:5000/api/trumpeteers/2/echo")

                     (fact "/trumpet broadcast the trumpet to trumpetees"
                           ; Given


working on modifying sentences with prepositional phrases

--- src/babel/italiano/grammar.cljc
+++ src/babel/italiano/grammar.cljc
@@ -178,6 +178,24 @@
     :schema-symbol 'h32 ;; used by over-each-parent to know where to put children.
     :first :head}))

+(def c00
+  (unify-check
+   head-last
+   {:comment "c00"
+    :schema-symbol 'c00 ;; used by over-each-parent to know where to put children.
+    :first :comp
+    :comp {:synsem {:subcat '()}}
+    :head {:synsem {:subcat '()}}}))
+
+(def h00
+  (unify-check
+   head-first
+   {:comment "h00"
+    :schema-symbol 'h00 ;; used by over-each-parent to know where to put children.
+    :first :head
+    :comp {:synsem {:subcat '()}}
+    :head {:synsem {:subcat '()}}}))
+
 ;; </TODO: move to ug>
 ;; -- END SCHEMA DEFINITIONS

@@ -446,7 +464,39 @@
                            root-is-comp
                            {:head {:phrasal false
                                    :synsem {:cat :sent-modifier}}
-                            :rule "s-modifier"})))
+                            :rule "s-modifier"})
+
+;                   (unify-check c00
+;                                modified
+;                                (let [head-sem (atom :top)]
+;                                  {:modified true
+;                                   :synsem {:subcat '()
+;                                            :sem head-sem
+;                                            :cat :verb}
+;                                   :comp {:synsem {:cat :prep
+ ;                                                  :subcat '()
+ ;                                                  :sem head-sem}}
+ ;                                  :head {:modified false
+ ;;                                         :synsem {:cat :verb
+ ;                                                  :subcat '()
+ ;                                                  :sem head-sem}}
+ ;                                  :rule "s-modified-with-adjunct-first"}))
+
+                   (unify-check h00
+                                modified
+                                (let [head-sem (atom :top)]
+                                 {:synsem {:subcat '()
+                                           :sem head-sem
+                                           :cat :verb}
+                                  :comp {:synsem {:cat :prep
+                                                  :subcat '()
+                                                  :sem head-sem}}
+                                  :head {:modified false
+                                         :synsem {:cat :verb
+                                                  :subcat '()
+                                                  :sem head-sem}}
+                                  :rule "s-modified-with-adjunct-last"}))
+                   ))

 (defn aux-is-head-feature [phrase]
   (cond (= :verb (get-in phrase '(:synsem :cat)))


actually working

actually working

--- src/bracketolojy/tournament.clj
+++ src/bracketolojy/tournament.clj
@@ -86,7 +86,7 @@
     (partial compute-matchup pick-scoring upset-scoring)
     tournament-bracket))

-(defn update-future-pts [[field children] parent-team-map]
+(defn- update-child-future-pts [parent-team-map [field children]]
   "Update the future-pts of each team in the field using parent-team-map.  The future-pts for each team in the
   field is the team's average points plus the future-pts of the team in the parent-team-map."
   (vector
@@ -97,29 +97,37 @@
       field)
     children))

-(defn- compute-future-pts-helper [loc parent-team-map]
+(defn update-future-pts [[field children]]
+  "For each child in children, update the future-pts of the teams in that child's field.  The future-pts for each team
+  in a field is the team's average points plus the future-pts of the team in the parent field."
+  (vector
+    field
+    (let [parent-team-map (->>                                                ;create parent map
+                            field
+                            (map #((juxt :name identity) %))
+                            (into {}))]
+      (map
+        (partial update-child-future-pts parent-team-map)
+        children))))
+
+(defn- compute-future-pts-helper [loc]
   (if (zip/end? loc)
     loc
-    (let [updated-loc (zip/edit loc update-future-pts parent-team-map)]
-      (recur
-        (zip/next updated-loc)
-        (->>                                                ;create next parent map
-          (zip/node updated-loc)
-          first
-          (map #((juxt :name identity) %))
-          (into {}))))))
+    (recur (->>
+             (zip/edit loc update-future-pts)
+             zip/next))))

 (defn compute-future-pts [tp]
-  (->
+  (->>
+    (update-child-future-pts nil tp)
     (zip/zipper
       (fn [[_ cn]]
-        (vector? cn))
+        (or (vector? cn) (seq? cn)))
       (fn [[_ cn]]
-        cn)
+        (seq cn))
       (fn [node cn]
-        (assoc node 1 cn))
-      tp)
-    (compute-future-pts-helper nil)
+        (assoc node 1 cn)))
+    compute-future-pts-helper
     zip/root))

 ;(def bracket
@@ -160,7 +168,7 @@
 ;    ["UCLA"
 ;     "Tulsa"]]]
 ;  )
-;
+
 (def bracket
   [["VCU"
     "Stephen F. Austin"]


fix Titanium Ribs

fix Titanium Ribs

--- src/clj/game/cards-hardware.clj
+++ src/clj/game/cards-hardware.clj
@@ -616,7 +616,7 @@
    {:events
     {:pre-resolve-damage
      {:req (req (and (> (last targets) 0)
-                     (not (and (= (:active-player @state) :corp) (get-in @state [:damage] :damage-choose)))
+                     (runner-can-choose-damage? state)
                      (not (get-in @state [:damage :damage-replace]))))
       :effect (req (let [dtype target
                          dmg (last targets)]
@@ -625,19 +625,20 @@
                      (when (= dtype :brain)
                        (swap! state update-in [:runner :brain-damage] #(+ % dmg))
                        (swap! state update-in [:runner :hand-size-modification] #(- % dmg)))
-                     (swap! state assoc-in [:damage :damage-choose] true)
                      (show-wait-prompt state :corp "Runner to use Titanium Ribs to choose cards to be trashed")
                      (resolve-ability state side
                        {:prompt (msg "Choose " dmg " cards to trash for the " (name dtype) " damage") :player :runner
                         :choices {:max dmg :req #(and (in-hand? %) (= (:side %) "Runner"))}
                         :msg (msg "trash " (join ", " (map :title targets)))
-                        :effect (req (swap! state update-in [:damage] dissoc :damage-choose)
-                                     (clear-wait-prompt state :corp)
+                        :effect (req (clear-wait-prompt state :corp)
                                      (doseq [c targets]
-                                       (trash state side c {:cause dtype :unpreventable true})))}
+                                       (trash state side c {:cause dtype :unpreventable true}))
+                                     (trigger-event state side :damage-chosen))}
                       card nil)
-                      (trigger-event state side :damage dtype nil)))}}
-    :effect (effect (system-msg (str "suffers 2 meat damage from installing Titanium Ribs"))
+                      (trigger-event state side :damage dtype nil)))}
+     :damage-chosen {:effect (effect (enable-runner-damage-choice))}}
+    :effect (effect (enable-runner-damage-choice)
+                    (system-msg (str "suffers 2 meat damage from installing Titanium Ribs"))
                     (damage :meat 2 {:card card}))}

    "Turntable"


Plug the multi-reducer to obtain an asynchronous event based GUI

--- src/cljs/clojure_rest/core.cljs
+++ src/cljs/clojure_rest/core.cljs
@@ -1,11 +1,13 @@
 (ns clojure-rest.core
   (:require-macros
+    [clojure-rest.store :refer [def-multi-reducer]]
     [reagent.ratom :refer [reaction]])
   (:require
-    [reagent.core :as r]
     [clojure-rest.api :as api]
     [clojure-rest.fake-data :as fake]
+    [clojure-rest.store :as store]
     [clojure-rest.utils :as utils]
+    [reagent.core :as r]
   ))

 ; https://github.com/reagent-project/reagent/blob/master/src/reagent/core.cljs
@@ -108,51 +110,52 @@

 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

-(defn handle-drop
-  [cards e status]
-  (let [card-id (utils/get-transfer-data e :card-id int)]
-    (assoc-in cards [card-id :status] status)
-  ))
-
-(defn event-handlers
-  [cards]
-  {:on-add-card #(js/alert "toto - use route to display the form")
-   :on-toggle-all #(swap! cards toggle-all-cards)
-   :on-toggle-card #(swap! cards update-in [%1 :show-details] not)
-   :on-remove-task #(swap! cards update-in [%1] api/remove-task-at %2)
-   :on-check-task #(swap! cards update-in [%1 :tasks %2 :done] not)
-   :on-add-task #(swap! cards update-in [%1] api/add-task %2)
-   :on-card-drop #(swap! cards handle-drop %1 %2)
-  })
+(def-multi-reducer app-reducer
+  ; TODO - Try to use multi-methods instead
+  {:on-toggle-all (fn [store _]
+                    (toggle-all-cards store))
+   :on-toggle-card (fn [store card-id]
+                     (update-in store [card-id :show-details] not))
+   :on-remove-task (fn [store card-id task-id]
+                     (update-in store [card-id] api/remove-task-at task-id))
+   :on-check-task (fn [store card-id task-id]
+                    (update-in store [card-id :tasks task-id :done] not))
+   :on-add-task (fn [store card-id task]
+                  (update-in store [card-id] api/add-task task))
+   :on-card-drop (fn [cards card-id status]
+                   (assoc-in cards [card-id :status] status))
+   })
+
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

 (defn render-card
-  ; TODO - Try to remove the mess of call-backs
   "[Pure] Render a card"
-  [{:keys [on-toggle-card on-remove-task on-check-task on-add-task]
-    :as event-handlers}]
+  [dispatch]
   (fn [{:keys [card-id title description show-details tasks]
         :as card}]
-    (let [title-style (if show-details :div.card__title--is-open :div.card__title)
-          on-drag-start #(utils/set-transfer-data % :card-id card-id)]
+    (let [title-style (if show-details :div.card__title--is-open :div.card__title)]
       [:div.card
-       {:draggable true :onDragStart on-drag-start}
+       {:draggable true
+        :onDragStart #(utils/set-transfer-data % :card-id card-id)}
        [:div {:style (card-side-color card)}]
-       [title-style {:on-click #(on-toggle-card card-id)} title]
+       [title-style {:on-click #(dispatch :on-toggle-card card-id)} title]
        [:div.card__details
         (when-not show-details {:style {:display "none"}})
         description
-        [render-tasks tasks #(on-remove-task card-id %) #(on-check-task card-id %)]
-        [render-add-task #(on-add-task card-id %)]
+        [render-tasks tasks
+         #(dispatch :on-remove-task card-id %)
+         #(dispatch :on-check-task card-id %)]
+        [render-add-task #(dispatch :on-add-task card-id %)]
       ]]
   )))

 (defn render-column
   "[Pure] Render a column holding a set of cards"
-  [card-renderer on-card-drop]
+  [card-renderer dispatch]
   (fn [status cards]
     [:div.column
      {:onDragOver #(.preventDefault %)
-      :onDrop #(on-card-drop % status)}
+      :onDrop #(dispatch :on-card-drop (utils/get-transfer-data % :card-id int) status)}
      [:h1 (status->str status)]
      (for [c cards] ^{:key (:card-id c)} [card-renderer c])
     ]))
@@ -181,18 +184,20 @@

 (defn render-toggle-all
   "[Pure] Render the button to expand all cards"
-  [on-toggle-all]
+  [dispatch]
   (fn []
     [:button.header-button
-     {:type "button" :on-click on-toggle-all} "Expand all"]
+     {:type "button" :on-click #(dispatch :on-toggle-all)}
+     "Expand all"]
   ))

 (defn render-add-card
   "[Pure] Render the button to expand add a new card"
-  [on-add-card]
+  [dispatch]
   (fn []
     [:button.header-button
-     {:on-click on-add-card :type "button"} "Add card"]
+     {:on-click #(dispatch :on-add-card) :type "button"}
+     "Add card"]
   ))

 (defn render-app
@@ -200,15 +205,18 @@
   (let [filter (r/atom "")
         cards (r/cursor app-state [:cards])
         filtered (reaction (filter-by-title @filter @cards))
-        handlers (event-handlers cards)
-        card-renderer (render-card handlers)
-        column-rendered (render-column card-renderer (handlers :on-card-drop))
+
+        card-store (store/reducer-store cards app-reducer)
+        card-store-dispatch (store/dispatcher card-store)
+
+        card-renderer (render-card card-store-dispatch)
+        column-rendered (render-column card-renderer card-store-dispatch)
         board-renderer (render-board column-rendered)]
     (fn []
       [:div
        (render-filter filter)
-       [render-add-card (handlers :on-add-card)]
-       [render-toggle-all (handlers :on-toggle-all)]
+       [render-add-card card-store-dispatch]
+       [render-toggle-all card-store-dispatch]
        [board-renderer @filtered]
       ])
     ))


remove team-unit action duplication

remove team-unit action duplication

--- src/cljs/dodgeball/actions.cljs
+++ src/cljs/dodgeball/actions.cljs
@@ -42,36 +42,37 @@

 (defn determine-action [x y]
   (println (unit/selected-unit))
-  (cond
-   (and
-    (= nil (unit/selected-unit))
-    (boolean (unit/unit? x y (:turn @state/game))))
-   {:type   :select-unit
-    :id     (:id (unit/unit? x y (:turn @state/game)))
-    :coords {:x x :y y}}
+  (let [team-unit (unit/unit? x y (:turn @state/game))]
+    (cond
+     (and
+      (= nil (unit/selected-unit))
+      (boolean team-unit))
+     {:type   :select-unit
+      :id     (:id team-unit)
+      :coords {:x x :y y}}

-   (or
-     (boolean (unit/unit? x y (:turn @state/game)))
-     (not (unit/in-range? x y (:id (unit/selected-unit)))))
-   {:type   :deselect-unit
-    :id     (:id (unit/unit? x y (:turn @state/game)))
-    :coords {:x x :y y}}
+     (or
+       (boolean team-unit)
+       (not (unit/in-range? x y (:id (unit/selected-unit)))))
+     {:type   :deselect-unit
+      :id     (:id team-unit)
+      :coords {:x x :y y}}

-   (boolean (unit/unit? x y :balls))
-   {:type   :pickup-ball
-    :id     (:id (unit/unit? x y :balls))
-    :coords {:x x :y y}}
+     (boolean (unit/unit? x y :balls))
+     {:type   :pickup-ball
+      :id     (:id (unit/unit? x y :balls))
+      :coords {:x x :y y}}

-   (boolean (unit/unit? x y (unit/defense)))
-   {:type :attack
-    :id (:id (unit/unit? x y (:turn @state/game)))
-    :coords {:x x :y y}}
+     (boolean (unit/unit? x y (unit/defense)))
+     {:type :attack
+      :id (:id team-unit)
+      :coords {:x x :y y}}

-   (unit/in-range? x y (:id (unit/unit? x y (:turn @state/game))))
-   {:type :move-unit
-    :id (:id (unit/unit? x y (:turn @state/game)))
-    :coords {:x x :y y}}
+     (unit/in-range? x y (:id team-unit))
+     {:type :move-unit
+      :id (:id team-unit)
+      :coords {:x x :y y}}

-   :else
-     (println x y (:turn @state/game))))
+     :else
+       (println x y (:turn @state/game)))))


Let all state remain in core namespace

Let all state remain in core namespace

--- src/cljs/hacker_agent/core.cljs
+++ src/cljs/hacker_agent/core.cljs
@@ -6,8 +6,7 @@
             [goog.history.EventType :as EventType]
             [weasel.repl :as ws-repl]
             [cljs.core.async :as async :refer [put! chan <! >! close! merge]]
-            [pani.cljs.core :as p]
-            [hacker-agent.session :as session :refer [global-state global-put!]])
+            [pani.cljs.core :as p])
   (:import goog.History))

 (defonce hacker-root "https://hacker-news.firebaseio.com/v0")
@@ -64,6 +63,12 @@
 ;; State

 (defonce app-state (atom {}))
+
+(defn global-state [k & [default]]
+  (get @app-state k default))
+
+(defn global-put! [k v]
+  (swap! app-state assoc k v))

 (defonce firebase
   (let [fb (js/Firebase. "https://hacker-news.firebaseio.com/v0")]


Remove useless debug output.

Remove useless debug output.

--- src/clojure/clj_chess/game.cljc
+++ src/clojure/clj_chess/game.cljc
@@ -416,7 +416,6 @@
   of insertion are removed."
   [game byte-moves & {:keys [node-id remove-existing-moves?]
                       :or {node-id (current-node-id game)}}]
-  (prn byte-moves)
   (add-move-sequence game board/move-from-byte byte-moves
                      node-id
                      remove-existing-moves?))


More performance improvements by moving to a non-protocol, non-immutable data structure notification system.

--- src/clojure/freactive/core.cljs
+++ src/clojure/freactive/core.cljs
@@ -40,10 +40,23 @@
 (defn remove-invalidation-watch [this key]
   (-remove-invalidation-watch this key))

-(deftype ReactiveAtom [state meta validator watches]
+(deftype ReactiveAtom [state meta validator watches swatches]
   Object
   (equiv [this other]
     (-equiv this other))
+  (addSwatch [this key f]
+    (aset (.-swatches this) key f))
+  (removeSwatch [this key]
+    (js-delete (.-swatches this) key))
+  (notifySwatches [this oldVal newVal]
+    ;(doseq [[key f] invalidation-watches]
+    ;  (f key this))
+    (goog.object/forEach
+      (.-swatches this)
+      (fn [f key _]
+        (f key this oldVal newVal)))
+    (doseq [[key f] watches]
+      (f key this oldVal newVal)))

   cljs.core/IAtom

@@ -56,7 +69,11 @@
   cljs.core/IDeref
   (-deref [this]
     (when-let [invalidate *invalidate-rx*]
-      (-add-watch this invalidate invalidate)
+      ;(-add-watch this (.-id invalidate) invalidate)
+      (.addSwatch this (.-id invalidate)
+                  (fn [key ref _ _]
+                    (.removeSwatch ref key)
+                    (invalidate)))
       (when *trace-capture* (*trace-capture* this)))
     state)

@@ -71,8 +88,7 @@

   IWatchable
   (-notify-watches [this oldval newval]
-    (doseq [[key f] watches]
-      (f key this oldval newval)))
+    (.notifySwatches this oldval newval))
   (-add-watch [this key f]
     (set! (.-watches this) (assoc watches key f))
     this)
@@ -90,8 +106,7 @@
             (when-not (nil? validate)
               (assert (validate new-value) "Validator rejected reference state")))
           (set! (.-state a) new-value)
-          (when-not (empty? (.-watches a))
-            (-notify-watches a old-value new-value)))
+          (.notifySwatches a old-value new-value))
         new-value))

   ISwap
@@ -115,8 +130,8 @@
   change. If the new state is unacceptable, the validate-fn should
   return false or throw an Error. If either of these error conditions
   occur, then the value of the atom will not change."
-  ([x] (ReactiveAtom. x nil nil nil))
-  ([x & {:keys [meta validator]}] (ReactiveAtom. x meta validator nil)))
+  ([x] (ReactiveAtom. x nil nil nil #js {}))
+  ([x & {:keys [meta validator]}] (ReactiveAtom. x meta validator nil #js {})))

 (defprotocol IReactiveExpression
   (-invalidate [this])
@@ -131,11 +146,11 @@
              (if-not (empty? (.-watches reactive))
                ;; updates state and notifies watches
                (when (-compute reactive)
-                 (-notify-invalidation-watches reactive))
+                 ( .notifyInvalidationWatches reactive))
                ;; updates only invalidation watches
-               (-notify-invalidation-watches reactive))))
+               (.notifyInvalidationWatches reactive))))
           ([key ref]
-           (-remove-invalidation-watch ref key)
+           (.removeInvalidationWatch ref key)
            (sully))
           ([key ref _ _]
            (-remove-watch ref key)
@@ -160,7 +175,9 @@
 (defn get-add-remove-watch* [ref]
   (cond
     (satisfies? IInvalidates ref)
-    [add-invalidation-watch remove-invalidation-watch]
+    ;[add-invalidation-watch remove-invalidation-watch]
+    [(fn [ref key f] (.addInvalidationWatch ref key f))
+    (fn [ref key] (.removeInvalidationWatch ref key))]
     (satisfies? IWatchable ref)
     [add-watch remove-watch]))

@@ -171,7 +188,7 @@
   (when-let [invalidate *invalidate-rx*]
     (when *trace-capture* (*trace-capture* rx))
     (if (lazy? default-laziness)
-      (-add-invalidation-watch rx (.-id invalidate) invalidate)
+      (.addInvalidationWatch rx (.-id invalidate) invalidate)
       (-add-watch rx (.-id invalidate) invalidate))))

 (deftype ReactiveExpression [id ^:mutable state ^:mutable dirty f ^:mutable deps meta
@@ -180,6 +197,21 @@
   Object
   (equiv [this other]
     (-equiv this other))
+  (notifyInvalidationWatches [this]
+    ;(doseq [[key f] invalidation-watches]
+    ;  (f key this))
+    (goog.object/forEach
+      invalidation-watches
+      (fn [f key _]
+        (f key this))))
+  (addInvalidationWatch [this key f]
+    (aset invalidation-watches key f)
+    ;(set! (.-invalidation-watches this) (assoc invalidation-watches key f))
+    this)
+  (removeInvalidationWatch [this key]
+    ;(set! (.-invalidation-watches this) (dissoc invalidation-watches key))
+    (js-delete invalidation-watches key)
+    this)

   IReactive
   (-raw-deref [this]
@@ -378,13 +410,13 @@
    :-add-invalidation-watch
    (fn --add-invalidation-watch
      [this key f]
-     (aset invalidation-watches key f)
+     (aset (.-invalidation-watches this) key f)
      this)

    :-remove-invalidation-watch
    (fn -remove-invalidation-watch
      [this key]
-     (js-delete invalidation-watches key)
+     (js-delete (.-invalidation-watches this) key)
      this)})

 (defn cursor* [ref korks-or-getter setter lazy]


Switch DVal to deftype as it is not user-accessible record.

--- src/clojure/parkour/io/dval.clj
+++ src/clojure/parkour/io/dval.clj
@@ -10,7 +10,7 @@
            [org.apache.hadoop.filecache DistributedCache]))

 ;; Distributed value
-(defrecord DVal [value readv params dcm]
+(deftype DVal [value readv params dcm]
   Object
   (toString [_]
     (let [v (if (realized? value) @value :pending)]
@@ -60,8 +60,8 @@
   [^DVal dval ^Writer writer]
   (let [repr (if (nil? cser/*conf*)
                (str dval)
-               (let [{:keys [readv params dcm]} dval
-                     literal (pr-str [readv params (-> dcm keys vec)])]
+               (let [v (.-readv dval), p (.-params dval), dcm (.-dcm dval)
+                     literal (pr-str [v p (-> dcm keys vec)])]
                  (fs/distcache! cser/*conf* dcm)
                  (str "#parkour/dval " literal)))]
     (.write writer repr)))


Jodatime json generator

Jodatime json generator

--- src/clj/mokkameister/resources/coffee.clj
+++ src/clj/mokkameister/resources/coffee.clj
@@ -1,11 +1,25 @@
 (ns mokkameister.resources.coffee
   "API for web page (status / stats)"
   (:require [cheshire.core :as json]
+            [cheshire.generate :as generate]
+            [clj-time.core :as t]
+            [clj-time.coerce :as c]
             [liberator.core :refer [defresource]]
-            [mokkameister.db.persistence :refer [brew-stats latest-brews month-stats]]))
+            [mokkameister.db.persistence :refer [brew-stats find-last-regular-coffee month-stats]]))
+
+(defn add-common-json-encoders!*
+  "Non-memoize version of add-common-json-encoders!"
+  []
+  (generate/add-encoder
+    org.joda.time.DateTime
+    (fn [data jsonGenerator]
+      (.writeString jsonGenerator (c/to-string data)))))
+
+(add-common-json-encoders!*)

 (defn- status [_]
-  {:latest (latest-brews)})
+  (let [[latest] (find-last-regular-coffee)]
+    {:latest latest}))

 (defn- stats [_]
   {:brews (brew-stats)


Remove duplicated alerts.

Remove duplicated alerts.

--- src/cljs/hatnik/web/client/z_actions.cljs
+++ src/cljs/hatnik/web/client/z_actions.cljs
@@ -24,9 +24,8 @@

 (defn common-update-callback [msg data reply]
   (let [resp (js->clj reply)]
-    (if (= "ok" (get resp "result"))
-      (state/update-all-view)
-      (js/alert msg))))
+    (when (= "ok" (get resp "result"))
+      (state/update-all-view))))

 (defn create-new-project-callback [name reply]
   (let [resp (js->clj reply)]


Refactored infinitelives.utils.console/log to take arbitrary arguments and require only one line of code.

--- src/cljs/infinitelives/utils/console.cljs
+++ src/cljs/infinitelives/utils/console.cljs
@@ -1,25 +1,3 @@
 (ns infinitelives.utils.console)

-;;
-;; No host methods (static or not) can be used with partial as-is because partial only works with Clojure functions.
-;; What you really want is to use clojure.contrib.import-static to easily wrap those static methods:
-;;
-;; - Chas Emerick
-;;
-(defn log
-  ([a1]
-   (.log js/console a1))
-  ([a1 a2]
-   (.log js/console a1 a2))
-  ([a1 a2 a3]
-   (.log js/console a1 a2 a3))
-  ([a1 a2 a3 a4]
-   (.log js/console a1 a2 a3 a4))
-  ([a1 a2 a3 a4 a5]
-   (.log js/console a1 a2 a3 a4 a5))
-  ([a1 a2 a3 a4 a5 a6]
-   (.log js/console a1 a2 a3 a4 a5 a6))
-  ([a1 a2 a3 a4 a5 a6 a7]
-   (.log js/console a1 a2 a3 a4 a5 a6 a7))
-  ([a1 a2 a3 a4 a5 a6 a7 a8]
-   (.log js/console a1 a2 a3 a4 a5 a6 a7 a8)))
+(defn log [& args] (js/console.log.apply js/console (clj->js (into [] args))))


Fix info for gen mutation call

Fix info for gen mutation call

--- src/com/wsscode/pathom/gen.cljc
+++ src/com/wsscode/pathom/gen.cljc
@@ -78,7 +78,7 @@
 (defn gen-mutate [{::keys [settings] :as env} k params]
   {:action
    (fn []
-     (info env "Gen mutation called" k params)
+     (info env "Gen mutation called " k params)
      (when-let [{::keys [fn]} (get settings k)]
        (fn env)))})


Refactor.

Refactor.

--- src/fhofherr/clj_db_util/transactions.clj
+++ src/fhofherr/clj_db_util/transactions.clj
@@ -8,36 +8,6 @@

 (alter-meta! #'->Transaction assoc :no-doc true)
 (alter-meta! #'map->Transaction assoc :no-doc true)
-
-;; Special value to mark a transaction as stopped
-(def ^:private tx-stop {::connection nil ::value nil})
-
-(defn tx-return
-  "Take an arbitrary value `v` and wrap it into a transaction.
-
-  *Parameters*:
-
-  - `v` an arbitrary value to wrap into a transaction."
-  [v]
-  (Transaction. (fn [dialect con] {::connection con ::value v})))
-
-(defn tx-bind
-  "Take a transacton `tx` containting a value `v` and a function `f` of
-  one argument returning another transaction. Apply `f` to `v` and return
-  the resulting transaction.
-
-  *Parameters*:
-
-  - `tx` a transaction.
-  - `f` a function expecting one argument and returning a transaction."
-  [tx f]
-  (Transaction. (fn [dialect con]
-                  {:pre [dialect con]}
-                  (let [{con* ::connection v ::value} ((:op tx) dialect con)
-                        tx* (f v)]
-                    (if con*
-                      ((:op tx*) dialect con*)
-                      tx-stop)))))

 (defmacro deftx
   "Define a function that creates a transaction. The first entry of the
@@ -75,12 +45,39 @@
   [dialect con f v & vs]
   (apply f v vs))

-(defn tx-rollback
+(deftx tx-return
+  "Take an arbitrary value `v` and wrap it into a transaction.
+
+  *Parameters*:
+
+  - `v` an arbitrary value to wrap into a transaction."
+  [dialect db-spec v]
+  v)
+
+;; Can't use deftx here as we need to return con* for the ::connection.
+;; If we would use deftx con would be returned.
+(defn tx-bind
+  "Take a transacton `tx` containting a value `v` and a function `f` of
+  one argument returning another transaction. Apply `f` to `v` and return
+  the resulting transaction.
+
+  *Parameters*:
+
+  - `tx` a transaction.
+  - `f` a function expecting one argument and returning a transaction."
+  [tx f]
+  (Transaction. (fn [dialect con]
+                  {:pre [dialect con]}
+                  (let [{con* ::connection v ::value} ((:op tx) dialect con)
+                        tx* (f v)]
+                    (if-not (jdbc/db-is-rollback-only con*)
+                      ((:op tx*) dialect con*)
+                      {::connection con* ::value nil})))))
+
+(deftx tx-rollback
   "Rollback the transaction. Further steps won't be executed."
-  []
-  (Transaction. (fn [dialect con]
-                  (jdbc/db-set-rollback-only! con)
-                  tx-stop)))
+  [dialect con]
+  (jdbc/db-set-rollback-only! con))

 (defn- emit-tx-step
   [[arg tx-expr]]


query support for datomic in event storage

--- src/tango/event_file_storage.clj
+++ src/tango/event_file_storage.clj
@@ -10,6 +10,16 @@
 (defn create-message [topic payload]
   {:topic topic
    :payload payload})
+
+;; TODO - should be done in db serv
+(defn clean-db-from-data [data]
+  (clojure.walk/postwalk
+    (fn [form]
+      (cond
+        ;; Competition should have id
+        (:db/id form) (dissoc form :db/id)
+        :else form))
+    data))

 (defn- start-message-handler [in-channel out-channel storage-path datomic-uri]
   {:pre [(some? in-channel)
@@ -40,31 +50,38 @@
                    ;                                                    storage-path)})))

                    (let [conn (d/create-connection datomic-uri)
-                         tx (d/transact-competition conn [p])]
+                         tx (clean-db-from-data (d/transact-competition conn [p]))]
                      ;(log/info tx)
                      (async/put! out-channel (merge message
                                                     {:topic :event-file-storage/added
                                                      :payload :ok})))
                    [:event-file-storage/query p]
-                   (let [raw-data (fs/read-file storage-path)]
-                     (if (= 2 (count p))
-                       ;; pull
-                       (let [[pull-q [entity-k entity-v]] p
-                             entity (first (filterv #(= (get % entity-k) entity-v) raw-data))
-                             result (if (= pull-q '[*])
-                                      ;; full-pull, return the complete entity
-                                      entity
-                                      ;; partial pull
-                                      (select-keys entity pull-q))]
-                         (async/put! out-channel (merge message {:topic :event-file-storage/result
-                                                                 :payload result})))
-                       ;; query
-                       (let [[q-keys] p
-                             q-result (mapv #(select-keys % q-keys) raw-data)]
-                         (async/put! out-channel (merge message {:topic :event-file-storage/result
-                                                                 :payload q-result})))
-                       )
-                     )
+                   (let [query-result (d/query-competition (d/create-connection datomic-uri) (first p))]
+                     (log/info "Payload")
+                     (log/info p)
+                     (log/info "Result")
+                     (log/info query-result)
+                     (async/put! out-channel (merge message {:topic   :event-file-storage/result
+                                                             :payload query-result})))
+                   ;(let [raw-data (fs/read-file storage-path)]
+                   ;  (if (= 2 (count p))
+                   ;    ;; pull
+                   ;    (let [[pull-q [entity-k entity-v]] p
+                   ;          entity (first (filterv #(= (get % entity-k) entity-v) raw-data))
+                   ;          result (if (= pull-q '[*])
+                   ;                   ;; full-pull, return the complete entity
+                   ;                   entity
+                   ;                   ;; partial pull
+                   ;                   (select-keys entity pull-q))]
+                   ;      (async/put! out-channel (merge message {:topic :event-file-storage/result
+                   ;                                              :payload result})))
+                   ;    ;; query
+                   ;    (let [[q-keys] p
+                   ;          q-result (mapv #(select-keys % q-keys) raw-data)]
+                   ;      (async/put! out-channel (merge message {:topic :event-file-storage/result
+                   ;                                              :payload q-result})))
+                   ;    )
+                   ;  )
                    ;; (let [raw-data (fs/read-file storage-path)
                    ;;       q-result (mapv #(select-keys % p) raw-data)]
                    ;;   (async/put! out-channel (merge message {:topic :event-file-storage/result


🔊 Log stack traces; ring.logger didn't log them after all

--- src/territory_bro/middleware.clj
+++ src/territory_bro/middleware.clj
@@ -21,9 +21,7 @@
     (try
       (handler req)
       (catch Throwable t
-        ;; The stack trace is already logged by ring.logger if it originated from application code
-        ;; and otherwise it's from some ring middleware whose stack trace is not interesting.
-        (log/error "Uncaught exception:" (.toString t))
+        (log/error t "Uncaught exception")
         (-> (internal-server-error "Internal Server Error")
             (response/content-type "text/html; charset=utf-8"))))))


Fix debug output

Fix debug output

--- src/puppeteer/infra/client/container_builder.clj
+++ src/puppeteer/infra/client/container_builder.clj
@@ -11,7 +11,7 @@

 (defn create-build
   [{:keys [project-id client] :as comp} build]
-  (println (-> (GoogleCredential/getApplicationDefault) .getAccessToken))
+  (println (-> (GoogleCredential/getApplicationDefault)))
   (-> client
       .projects
       .builds


Optimize node comparison function for issue #71

--- src/main/clojure/clara/rules/compiler.clj
+++ src/main/clojure/clara/rules/compiler.clj
@@ -521,14 +521,23 @@

    ;; Compare items in a sequence until we find a difference.
    (sequential? left)
-   (if-let [[left-val right-val] ; Find the first tuple that's different.
-            (->> (map (fn [left-val right-val] [left-val right-val]) left right)
-                 (drop-while (fn [[left-val right-val]] (= 0 (gen-compare left-val right-val))))
-                 first)]
-     (gen-compare left-val right-val)
-
-     ;; All existing items matched, but check for differing lengths.
-     (- (count right) (count left)))
+   (loop [left-seq left
+          right-seq right]
+
+     (if (and (seq left-seq) (seq right-seq))
+
+       ;; Both sequences have content, so compare them and recur if necessary.
+       (let [result (gen-compare (first left-seq) (first right-seq)) ]
+         (if (not= 0 result)
+           result
+           (recur (rest left-seq) (rest right-seq))))
+
+       ;; At least one sequence is empty.
+       (cond
+
+        (seq left-seq) 1
+        (seq right-seq) -1
+        :default 0)))

    ;; Covert maps to sequences sorted by keys and compare those sequences.
    (map? left)


[#4490]: Advanced button is not collapsed on Profile tab when switching to another tab

Signed-off-by: Julien Eluard <c768e13f1ba4c3ebed2909a1fc1e4b50bb021a2f@gmail.com>

--- src/status_im/ui/screens/profile/user/views.cljs
+++ src/status_im/ui/screens/profile/user/views.cljs
@@ -128,6 +128,7 @@
 (defview advanced [{:keys [network networks dev-mode?]}]
   (letsubs [advanced? [:get :my-profile/advanced?]
             {:keys [sharing-usage-data?]} [:get-current-account]]
+    {:component-will-unmount #(re-frame/dispatch [:set :my-profile/advanced? false])}
     [react/view
      [react/touchable-highlight {:on-press #(re-frame/dispatch [:set :my-profile/advanced? (not advanced?)])
                                  :style    styles/advanced-button}


added mock version for sendmail.

added mock version for sendmail.

--- test/edeposit/amqp/kramerius/components_test.clj
+++ test/edeposit/amqp/kramerius/components_test.clj
@@ -147,11 +147,11 @@
                                           :routing-keys [[:internal :storage.response]]
                                           :handler (->
                                                     (comp
-                                                     (h/sendmail pc/send-message)
-                                                     ;; (h/sendmail (fn [msg]
-                                                     ;;               {:code 0,
-                                                     ;;                :error :SUCCESS,
-                                                     ;;                :message "message sent"}))
+                                                     ;;(h/sendmail pc/send-message)
+                                                     (h/sendmail (fn [msg]
+                                                                   {:code 0,
+                                                                    :error :SUCCESS,
+                                                                    :message "message sent"}))
                                                      h/save-email-at-workdir
                                                      (h/make-email :from "edeposit@edeposit.cz"
                                                                    :to "stavel.jan@gmail.com")


cassandra: fix broken test assertions

cassandra: fix broken test assertions

--- test/er_cassandra/model/alia/unique_key_test.clj
+++ test/er_cassandra/model/alia/unique_key_test.clj
@@ -197,7 +197,8 @@
         (is (= {:uber-key (t/uber-key m)
                 :uber-key-value [ida]
                 :key [:nick]
-                :key-value ["foo"]}))
+                :key-value ["foo"]}
+               key-desc))
         (is (= :deleted reason))
         (is (= nil dr))))

@@ -213,7 +214,8 @@
         (is (= {:uber-key (t/uber-key m)
                 :uber-key-value [ida]
                 :key [:nick]
-                :key-value ["foo"]}))
+                :key-value ["foo"]}
+               key-desc))
         (is (= :stale reason))))

     (testing "attempting to release someone else's key"
@@ -229,9 +231,10 @@

         (is (= :ok status))
         (is (= {:uber-key (t/uber-key m)
-                :uber-key-value [ida]
+                :uber-key-value [idb]
                 :key [:nick]
-                :key-value ["foo"]}))
+                :key-value ["foo"]}
+               key-desc))
         (is (= :stale reason))))))

@@ -571,9 +574,9 @@
         (is (= {:id id :nick nil :a "ana" :b "anb"}
                (select-keys fr [:id :nick :a :b])))
         (is (some? (:a_ttl fr)))
-        (is (= (> (:a_ttl fr) 5)))
+        (is (> (:a_ttl fr) 5))
         (is (some? (:a_writetime fr)))
-        (is (= (> (:a_writetime fr) 5)))))
+        (is (> (:a_writetime fr) 5))))

     (testing "update existing record"
       (let [id (uuid/v1)
@@ -610,9 +613,9 @@
         (is (= {:id id :nick "blah" :a "newa" :b "oldb"}
                (select-keys fr [:id :nick :a :b])))
         (is (some? (:a_ttl fr)))
-        (is (= (> (:a_ttl fr) 5)))
+        (is (> (:a_ttl fr) 5))
         (is (some? (:a_writetime fr)))
-        (is (= (> (:a_writetime fr) 5)))))
+        (is (> (:a_writetime fr) 5))))

     (testing "with if-not-exists"

@@ -644,7 +647,7 @@
             (is (= {:id id-b :nick nil :a "ana" :b "anb"}
                    (select-keys fr [:id :nick :a :b])))
             (is (some? (:a_ttl fr)))
-            (is (= (> (:a_ttl fr) 5)))))
+            (is (> (:a_ttl fr) 5))))

         (testing "if it does already exist"
           (let [r @(uk/upsert-primary-record-without-unique-keys
@@ -701,7 +704,7 @@
           (is (= {:id id :nick "bloogh" :a "newa" :b "newb"}
                  (select-keys fr [:id :nick :a :b])))
           (is (some? (:a_ttl fr)))
-          (is (= (> (:a_ttl fr) 5)))))
+          (is (> (:a_ttl fr) 5))))

       (testing "if it doesn't already exist"
         (let [id (uuid/v1)


(maint) Fix integration tests

(maint) Fix integration tests

--- test/puppetlabs/puppetdb/integration/reports.clj
+++ test/puppetlabs/puppetdb/integration/reports.clj
@@ -1,5 +1,6 @@
 (ns puppetlabs.puppetdb.integration.reports
   (:require [clojure.test :refer :all]
+            [clojure.string :refer [trim-newline]]
             [me.raynes.fs :as fs]
             [puppetlabs.puppetdb.integration.fixtures :as int]
             [puppetlabs.puppetdb.testutils.services :as svc-utils]
@@ -234,7 +235,15 @@

       (let [[report] (int/pql-query pdb "reports { certname = 'my_agent' and noop = false }")
             metrics (get-href pdb (get-in report [:metrics :href]))
-            logs  (get-href pdb (get-in report [:logs :href]))]
+            logs  (get-href pdb (get-in report [:logs :href]))
+            ;; In Puppet 7, disable_i18n is true by default, so the "Retrieving locales"
+            ;; log message does not exist
+            info-log-count (if (->> (int/bundle-exec {} "puppet" "--version")
+                                    :out
+                                    trim-newline
+                                    (re-matches #"^6.*"))
+                             6
+                             5)]

         (is (= #{{:name "total", :value 1, :category "events"}
                  {:name "changed", :value 1, :category "resources"}
@@ -254,9 +263,10 @@
                   (filter #(= "notice" (:level %))
                           logs))))

-        (is (= 5 (count
-                  (filter #(= "info" (:level %))
-                          logs))))))))
+        (is (= info-log-count
+               (count
+                 (filter #(= "info" (:level %))
+                         logs))))))))

 (defn read-gc-count-metric []
   ;; metrics are global, so...


parens are hard

parens are hard

--- src/vignette/http/middleware.clj
+++ src/vignette/http/middleware.clj
@@ -27,7 +27,7 @@
                            context))
           (error-response response-code thumb-map)))
       (catch Exception e
-        (println (.getMessage e)
+        (println (.getMessage e))
         (perf/publish {:exception-count 1})
         (log/warn (str e) {:path (:uri request)
                            :query (:query-string request)})


:module-hash-names now also takes a number

:module-hash-names true - uses the full hash
:module-hash-names 8 - uses the first 8 chars

closes #65

--- src/main/shadow/build/targets/browser.clj
+++ src/main/shadow/build/targets/browser.clj
@@ -303,15 +303,29 @@

   state)

-(defn hash-optimized-module [{:keys [output output-name] :as mod}]
-  (let [signature (util/md5hex output)]
+(defn hash-optimized-module [{:keys [output output-name] :as mod} module-hash-names]
+  (let [signature
+        (util/md5hex output)
+
+        signature
+        (cond
+          (true? module-hash-names)
+          signature
+          (and (number? module-hash-names)
+               (<= 0 module-hash-names 32))
+          (subs signature 0 module-hash-names)
+          :else
+          (throw (ex-info (format "invalid :module-hash-names value %s" module-hash-names)
+                   {:tag ::module-hash-names
+                    :module-hash-names module-hash-names})))]
+
     (assoc mod :output-name (str/replace output-name #".js$" (str "." signature ".js")))))

-(defn hash-optimized-modules [state]
+(defn hash-optimized-modules [state module-hash-names]
   (update state ::closure/modules
     (fn [optimized]
       (->> optimized
-           (map hash-optimized-module)
+           (map #(hash-optimized-module % module-hash-names))
            (into [])))))

 (defn flush [state mode {:keys [module-loader module-hash-names] :as config}]
@@ -322,13 +336,13 @@
         (flush-manifest false))
     :release
     (do (when (and (true? module-loader)
-                   (true? module-hash-names))
+                   module-hash-names)
           ;; FIXME: provide a way to export module config instead of appending it always.
           (throw (ex-info ":module-loader true defeats purpose of :module-hash-names" {})))
         (-> state
             (cond->
               module-hash-names
-              (hash-optimized-modules))
+              (hash-optimized-modules module-hash-names))
             (output/flush-optimized)
             (flush-manifest true)))))


pass context through to finished and started

--- frontend/controllers/api.cljs
+++ frontend/controllers/api.cljs
@@ -17,7 +17,7 @@
                                              format :json
                                              response-format :json
                                              keywords? true}}]
-  (put! channel [message :started])
+  (put! channel [message :started context])
   (ajax/GET url {:format format
                  :response-format response-format
                  :keywords? keywords?
@@ -27,7 +27,7 @@
                                                             :context context}])
                  :error-handler #(put! channel [message :failed {:resp %
                                                                  :context context}])
-                 :finally #(put! channel [message :finished])}))
+                 :finally #(put! channel [message :finished context])}))

 (defmulti api-event


Remove unnecessary parens

Remove unnecessary parens

--- modules/template/src/modular/template.clj
+++ modules/template/src/modular/template.clj
@@ -60,17 +60,17 @@
   use it to process the response of the delegate handler. The initial
   response is considered to be a template model, and merged with other
   template models from other components."
-  ([h & [k]]
-     (fn [req]
-       (if-let [merge-with-template (get-in req [::template k])]
-         (let [resp (h req)]
-           (merge resp {:body (merge-with-template req resp)}))
-         (throw
-          (if (::template req)
-            (if k
-              (ex-info (format "No template with key %s" k) {:key k})
-              (ex-info (format "No default template") {}))
-            (ex-info "wrap-template expects that a template is included in the system" {:key k})))))))
+  [h & [k]]
+  (fn [req]
+    (if-let [merge-with-template (get-in req [::template k])]
+      (let [resp (h req)]
+        (merge resp {:body (merge-with-template req resp)}))
+      (throw
+       (if (::template req)
+         (if k
+           (ex-info (format "No template with key %s" k) {:key k})
+           (ex-info (format "No default template") {}))
+         (ex-info "wrap-template expects that a template is included in the system" {:key k}))))))

 (defrecord TemplateModelMap []
   TemplateModel


[#1534] Remove unnecessary rows key

[#1534] Remove unnecessary rows key

--- backend/src/akvo/lumen/lib/dataset_impl.clj
+++ backend/src/akvo/lumen/lib/dataset_impl.clj
@@ -66,7 +66,7 @@
                                  {:as-arrays? true}))]
       (lib/ok
        (-> dataset
-           (select-keys [:columns :created :id :modified :rows :status :title :transformations :updated])
+           (select-keys [:columns :created :id :modified :status :title :transformations :updated])
            (rename-keys {:title :name})
            (assoc :rows data)
            (assoc :status "OK"))))


typo in migrate.clj

typo in migrate.clj

--- dev/migrate.clj
+++ dev/migrate.clj
@@ -42,7 +42,7 @@
               measurements-with-metadata (map #(update-in % [:reading_metadata] convert-metadata %)
                                               measurements)]
           (when measurements-with-metadata
-            (m/insert-measurements store measurements-with-metadata 100)))
+            (misc/insert-measurements store measurements-with-metadata 100)))
         (spit "/tmp/processed_sensors.txt" (str s "\n") :append true))))
   (log/info "Finished migrating reading metadata."))


Update `with-http-app` fixture to include default for url-prefix

--- test/com/puppetlabs/puppetdb/fixtures.clj
+++ test/com/puppetlabs/puppetdb/fixtures.clj
@@ -71,7 +71,8 @@
                                 {:scf-read-db          *db*
                                  :scf-write-db         *db*
                                  :command-mq           *mq*
-                                 :product-name         "puppetdb"}
+                                 :product-name         "puppetdb"
+                                 :url-prefix           ""}
                                 globals-overrides))]
        (f))))


Increase bench time for circle

Increase bench time for circle

--- test/onyx/plugin/input_benchmark_test.clj
+++ test/onyx/plugin/input_benchmark_test.clj
@@ -129,17 +129,20 @@
     (try
      (println "Topic is " test-topic)
      (write-data test-topic zk-address)
-     (Thread/sleep 10000)
+     ;; Appropriate time to settle before submitting the job
+     (Thread/sleep 5000)
      (let [job-ret (onyx.api/submit-job peer-config job)
            _ (println "Job ret" job-ret)
            job-id (:job-id job-ret)
            start-time (System/currentTimeMillis)
-           read-nothing-timeout 10000
+           read-nothing-timeout 30000
            read-segments (take-until-nothing! out read-nothing-timeout)]
        (is (= (* n-partitions messages-per-partition) (count read-segments)))
        (let [run-time (- (System/currentTimeMillis) start-time read-nothing-timeout)
              n-messages-total (* n-partitions messages-per-partition)]
-         (println (float (* 1000 (/ n-messages-total run-time))) "messages per second. Processed" n-messages-total "messages in" run-time "ms."))
+         (println (float (* 1000 (/ n-messages-total run-time)))
+                  "messages per second. Processed" n-messages-total
+                  "messages in" run-time "ms."))
        (onyx.api/kill-job peer-config job-id))
      (finally
       (doseq [p v-peers]


Type hint for parse-int

Type hint for parse-int

--- src/emender_jenkins/results.clj
+++ src/emender_jenkins/results.clj
@@ -7,7 +7,7 @@
 ;  http://www.eclipse.org/legal/epl-v10.html
 ;
 ;  Contributors:
-;      Pavel Tisnovsky
+;      Pavel Tisnovsky
 ;

 (ns emender-jenkins.results
@@ -101,7 +101,8 @@
             true)))

 (defn parse-int
-    [string]
+    "Parse the given string as an integer number."
+    [^String string]
     (java.lang.Integer/parseInt string))

 (defn parse-test-results


turn off body-params which was emptying request body and parse json explicitly

Also Revert "turn off commenting for reopening, no more training wheels"

This reverts commit 14fbbe8bc66ae371d3d07237b2b247486f4971ad.

Conflicts:
	src/gh_waiting_room/service.clj

--- src/gh_waiting_room/service.clj
+++ src/gh_waiting_room/service.clj
@@ -5,6 +5,7 @@
               [io.pedestal.service.http.route.definition :refer [defroutes]]
               [io.pedestal.service.interceptor :refer [defon-response]]
               [clostache.parser :refer [render-resource]]
+              [clojure.data.json :as json]
               [gh-waiting-room.config :refer [gh-user gh-hmac-secret]]
               [gh-waiting-room.github :refer [get! get-in! create-issue-comment
                                               viewable-issues fetch-gh-issues]]
@@ -34,7 +35,6 @@

 (defn verify-secret!
   [secret body x-hub-signature]
-  (prn "BODY" body)
   (let [expected (re-find #"(?<=sha1=).*$" (str x-hub-signature))
         actual (hex-hmac-sha1 secret body)]
     (prn "ACTUAL, EXPECTED:" actual expected)
@@ -44,24 +44,20 @@

 (defn webhook-page
   [request]
-  #_(prn "BODY" (slurp (:body request)))
-  #_(clojure.pprint/pprint request)
+  (let [body (slurp (:body request))]
+    (when-let [secret (gh-hmac-secret)]
+      (verify-secret! secret body (-> request :headers (get "x-hub-signature"))))

-  (when-let [secret (gh-hmac-secret)]
-    (verify-secret! secret (slurp (:body request)) (-> request :headers (get "X-Hub-Signature"))))
-
-  (let [params (-> request :json-params)
-        action (get! params "action")
-        full-name (get-in! params ["repository" "full_name"])
-        issue-num (get-in! params ["issue" "number"])
-        issue-id (format "%s#%s" full-name issue-num)]
-    (when (= action "opened")
-      (update-gh-issues)
-      (create-issue-comment @db issue-id issue-num))
-    (when (and
-           (some #{action} ["closed" "reopened"])
-           (some #(= (:id %) issue-id) (viewable-issues @db)))
-      (update-gh-issues)))
+    (let [params (json/read-str body)
+          action (get! params "action")
+          full-name (get-in! params ["repository" "full_name"])
+          issue-num (get-in! params ["issue" "number"])
+          issue-id (format "%s#%s" full-name issue-num)]
+      (when (some #{action} ["created" "reopened"])
+        (update-gh-issues)
+        (create-issue-comment @db issue-id issue-num))
+      (when (and (= action "closed") (some #(= (:id %) issue-id) (viewable-issues @db)))
+        (update-gh-issues))))
   {:status 200})

 (defon-response html-content-type
@@ -70,7 +66,7 @@

 (defroutes routes
   [[["/" {:get home-page}
-     ^:interceptors [(body-params/body-params) html-content-type]
+     ^:interceptors [html-content-type]
      ["/webhook" {:post webhook-page}]
      ]]])


Clean up debug output

Clean up debug output

--- test/dependable/resolve_test.clj
+++ test/dependable/resolve_test.clj
@@ -129,7 +129,6 @@
               {"c" package-c10})
              [:successful #{}])))

-    (println "starting ---")
     (testing (str "Asking to install a package that I have given as already "
                   "installed, even though the package isn't available.")
       (is (= (resolve-dependencies
@@ -140,7 +139,6 @@
               :present-packages {"b"
                                  (->package "b" 10 "b-loc10" nil)})
              [:successful #{}])))
-    (println "ending ---")
     (testing (str "Asking to install a package that is already "
                   "installed, but the installed version doesn't "
                   "suit, even though there is a suitable version "


Work in progress - refactoring.

Work in progress - refactoring.

--- ClojureScript/hello.cljs
+++ ClojureScript/hello.cljs
@@ -9,9 +9,8 @@

 (def pos (atom 0))

-(defn ^:export foobar []
-    (let [canvas (goog.dom/getElement "my-canvas")
-        ctx (.getContext canvas "2d")
+(defn foobar [canvas]
+    (let [ctx (.getContext canvas "2d")
         x (swap! pos inc)]
         (do
             (. ctx (save))
@@ -22,20 +21,15 @@
             )))

 (defn ^:export main []
-    (let [body document.body ;(goog.dom/getElement "my-body")
-        f (partial goog.dom/appendChild body)] (do
-        (f
-            (goog.dom/createDom "h1" {} "Hello!"))
-        (f
-            (goog.dom/createDom "canvas" (.strobj {
-                "id" "my-canvas"
-                "width" 600
-                "height" 600
-                "style" "border: 1px solid #000000"
-                }) ""))
-        (let [button (goog.dom/createDom "button" {} "Click!")] (do
-            (goog.events/listen button goog.events.EventType/CLICK foobar)
-            (f button)
-            button))
-)))
+    (let [
+        canvas (goog.dom/createDom "canvas" (.strobj {
+            "width" 600
+            "height" 600
+            "style" "border: 1px solid #000000"
+            }) "")
+        button (goog.dom/createDom "button" {} "Click!")]
+        (do
+            (goog.events/listen button goog.events.EventType/CLICK (partial foobar canvas))
+            (dorun (map (partial goog.dom/appendChild document.body)
+                [(goog.dom/createDom "h1" {} "Hello!") canvas button])))))


enhance satisfies? code gen using same approach as implements?, eliminates closures

--- src/main/clojure/cljs/core.cljc
+++ src/main/clojure/cljs/core.cljc
@@ -1871,16 +1871,24 @@
              [part bit] (fast-path-protocols p)
              msym       (symbol
                           (core/str "-cljs$lang$protocol_mask$partition" part "$"))]
-    `(let [~xsym ~x]
-       (if ~xsym
-         (let [bit# ~(if bit `(unsafe-bit-and (. ~xsym ~msym) ~bit))]
-           (if (or bit#
-                 ~(bool-expr `(. ~xsym ~(symbol (core/str "-" prefix)))))
+    (if-not (core/symbol? x)
+      `(let [~xsym ~x]
+         (if-not (nil? ~xsym)
+           (if (or ~(if bit `(unsafe-bit-and (. ~xsym ~msym) ~bit) false)
+                   ~(bool-expr `(. ~xsym ~(symbol (core/str "-" prefix)))))
              true
              (if (coercive-not (. ~xsym ~msym))
                (cljs.core/native-satisfies? ~psym ~xsym)
-               false)))
-         (cljs.core/native-satisfies? ~psym ~xsym)))))
+               false))
+           (cljs.core/native-satisfies? ~psym ~xsym)))
+      `(if-not (nil? ~x)
+         (if (or ~(if bit `(unsafe-bit-and (. ~x ~msym) ~bit) false)
+                 ~(bool-expr `(. ~x ~(symbol (core/str "-" prefix)))))
+           true
+           (if (coercive-not (. ~x ~msym))
+             (cljs.core/native-satisfies? ~psym ~x)
+             false))
+         (cljs.core/native-satisfies? ~psym ~x)))))

 (core/defmacro lazy-seq
   "Takes a body of expressions that returns an ISeq or nil, and yields


threading macro animation work

threading macro animation work

--- cljs-client/cljsinfo_client/threading_macro.cljs
+++ cljs-client/cljsinfo_client/threading_macro.cljs
@@ -21,9 +21,9 @@
 ;;------------------------------------------------------------------------------

 (hiccups/defhtml ex1-html []
-  [:div#line1.line-num "1"]
-  [:div#line2.line-num "2"]
-  [:div#line3.line-num "3"]
+  [:div#line1.line-num (grid -1 1) "1"]
+  [:div#line2.line-num (grid -1 2) "2"]
+  [:div#line3.line-num (grid -1 3) "3"]

   [:div#openParen1 "("]

@@ -48,49 +48,66 @@

 (def ex1-pos1 {
   :openParen1 [1 1]
-
   :arrow1 [2 1]
   :arrow2 [3 1]
   :symbolA [5 1]

-  :openParen2 [3 2]
-  :symbolB [4 2]
-  :symbolC [6 2]
-  :symbolD [8 2]
-  :closeParen2 [9 2]
-
-  :openParen3 [3 3]
-  :symbolX [4 3]
-  :symbolY [6 3]
-  :symbolZ [8 3]
-  :closeParen3 [9 3]
-
-  :closeParen1 [10 3]})
-
-(def ex1-pos2 {
-  :openParen1 [1 1]
-
-  :arrow1 [2 1]
-  :arrow2 [3 1]
-
-  :openParen2 [3 2]
-  :symbolB [4 2]
-  :symbolA [6 2]
+  :openParen2 [5 2]
+  :symbolB [6 2]
   :symbolC [8 2]
   :symbolD [10 2]
   :closeParen2 [11 2]

-  :openParen3 [3 3]
-  :symbolX [4 3]
-  :symbolY [6 3]
-  :symbolZ [8 3]
-  :closeParen3 [9 3]
-
-  :closeParen1 [10 3]})
+  :openParen3 [5 3]
+  :symbolX [6 3]
+  :symbolY [8 3]
+  :symbolZ [10 3]
+  :closeParen3 [11 3]
+
+  :closeParen1 [12 3]})
+
+(def ex1-pos2 {
+  :openParen1 [1 1]
+  :arrow1 [2 1]
+  :arrow2 [3 1]
+  :symbolA [5 1]
+
+  :openParen2 [5 2]
+  :symbolB [6 2]
+  :symbolC [10 2]
+  :symbolD [12 2]
+  :closeParen2 [13 2]
+
+  :openParen3 [5 3]
+  :symbolX [6 3]
+  :symbolY [8 3]
+  :symbolZ [10 3]
+  :closeParen3 [11 3]
+
+  :closeParen1 [12 3]})

 (def ex1-pos3 {
   :openParen1 [1 1]
-
+  :arrow1 [2 1]
+  :arrow2 [3 1]
+
+  :openParen2 [5 2]
+  :symbolB [6 2]
+  :symbolA [8 2]
+  :symbolC [10 2]
+  :symbolD [12 2]
+  :closeParen2 [13 2]
+
+  :openParen3 [5 3]
+  :symbolX [6 3]
+  :symbolY [8 3]
+  :symbolZ [10 3]
+  :closeParen3 [11 3]
+
+  :closeParen1 [12 3]})
+
+(def ex1-pos4 {
+  :openParen1 [1 1]
   :arrow1 [2 1]
   :arrow2 [3 1]

@@ -101,55 +118,75 @@
   :symbolD [12 1]
   :closeParen2 [13 1]

-  :openParen3 [3 2]
-  :symbolX [4 2]
-  :symbolY [6 2]
-  :symbolZ [8 2]
-  :closeParen3 [9 2]
-
-  :closeParen1 [10 2]})
-
-(def ex1-pos4 {
-  :openParen1 [1 1]
-
-  :arrow1 [2 1]
-  :arrow2 [3 1]
-
-  :openParen3 [3 2]
-  :symbolX [4 2]
-  :openParen2 [6 2]
-  :symbolB [7 2]
-  :symbolA [9 2]
-  :symbolC [11 2]
-  :symbolD [13 2]
-  :closeParen2 [14 2]
-  :symbolY [16 2]
-  :symbolZ [18 2]
-  :closeParen3 [19 2]
-
-  :closeParen1 [20 2]})
+  :openParen3 [5 2]
+  :symbolX [6 2]
+  :symbolY [8 2]
+  :symbolZ [10 2]
+  :closeParen3 [11 2]
+
+  :closeParen1 [12 2]})

 (def ex1-pos5 {
+  :openParen1 [1 1]
+  :arrow1 [2 1]
+  :arrow2 [3 1]
+
+  :openParen2 [5 1]
+  :symbolB [6 1]
+  :symbolA [8 1]
+  :symbolC [10 1]
+  :symbolD [12 1]
+  :closeParen2 [13 1]
+
+  :openParen3 [5 2]
+  :symbolX [6 2]
+  :symbolY [18 2]
+  :symbolZ [20 2]
+  :closeParen3 [21 2]
+
+  :closeParen1 [22 2]})
+
+(def ex1-pos6 {
+  :openParen1 [1 1]
+  :arrow1 [2 1]
+  :arrow2 [3 1]
+
+  :openParen2 [8 2]
+  :symbolB [9 2]
+  :symbolA [11 2]
+  :symbolC [13 2]
+  :symbolD [15 2]
+  :closeParen2 [16 2]
+
+  :openParen3 [5 2]
+  :symbolX [6 2]
+  :symbolY [18 2]
+  :symbolZ [20 2]
+  :closeParen3 [21 2]
+
+  :closeParen1 [22 2]})
+
+(def ex1-pos7 {
   :openParen1 nil
-
   :arrow1 nil
   :arrow2 nil

-  :openParen3 [3 2]
-  :symbolX [4 2]
-  :openParen2 [6 2]
-  :symbolB [7 2]
-  :symbolA [9 2]
-  :symbolC [11 2]
-  :symbolD [13 2]
-  :closeParen2 [14 2]
-  :symbolY [16 2]
-  :symbolZ [18 2]
-  :closeParen3 [19 2]
+  :openParen2 [8 2]
+  :symbolB [9 2]
+  :symbolA [11 2]
+  :symbolC [13 2]
+  :symbolD [15 2]
+  :closeParen2 [16 2]
+
+  :openParen3 [5 2]
+  :symbolX [6 2]
+  :symbolY [18 2]
+  :symbolZ [20 2]
+  :closeParen3 [21 2]

   :closeParen1 nil})

-(def ex1-pos6 {
+(def ex1-pos8 {
   :openParen1 nil
   :arrow1 nil
   :arrow2 nil
@@ -289,11 +326,14 @@
   (* n (+ animation-duration time-between)))

 (defn- animate! []
-  ; (js/setTimeout #(animate-to-position ex1-pos2) (round 1))
-  ; (js/setTimeout #(animate-to-position ex1-pos3) (round 2))
-  ; (js/setTimeout #(animate-to-position ex1-pos4) (round 3))
-  ; (js/setTimeout #(animate-to-position ex1-pos5) (round 4))
-  ; (js/setTimeout #(animate-to-position ex1-pos6) (round 5))
+  (set-position-instant! ex1-pos1)
+  (js/setTimeout #(animate-to-position ex1-pos2) (round 1))
+  (js/setTimeout #(animate-to-position ex1-pos3) (round 2))
+  (js/setTimeout #(animate-to-position ex1-pos4) (round 3))
+  (js/setTimeout #(animate-to-position ex1-pos5) (round 4))
+  (js/setTimeout #(animate-to-position ex1-pos6) (round 5))
+  (js/setTimeout #(animate-to-position ex1-pos7) (round 6))
+  (js/setTimeout #(animate-to-position ex1-pos8) (round 7))

   ; (set-position-instant! ex1-pos6)
   ; (js/setTimeout #(animate-to-position ex1-pos5) (round 2))
@@ -301,17 +341,12 @@
   ; (js/setTimeout #(animate-to-position ex1-pos3) (round 4))
   ; (js/setTimeout #(animate-to-position ex1-pos2) (round 5))
   ; (js/setTimeout #(animate-to-position ex1-pos1) (round 6))
-
-
-  (set-position-instant! ex2-pos1)
-
-
   )

 (defn init!
   "Initialize the threading macro page."
   []
-  ;(set-html! "threadingMacroBody" (ex1-html))
-  (set-html! "threadingMacroBody" (ex2-html))
+  (set-html! "threadingMacroBody" (ex1-html))
+  ;(set-html! "threadingMacroBody" (ex2-html))
   (animate!)
   )


handle colors better

handle colors better

git-svn-id: 03a8048b5ee8463be5048a3801110fb50f378627@10100 d0ab736e-dc22-4aeb-8dc9-08def0aa14fd

--- plugins/SlideExplorer2/src/slide_explorer/canvas.clj
+++ plugins/SlideExplorer2/src/slide_explorer/canvas.clj
@@ -28,7 +28,7 @@
                            RenderingHints/VALUE_ANTIALIAS_OFF)))))

 (def default-primitive-params
-  {:filled false :color Color/BLACK})
+  {:filled false :color :black})

 (def stroke-caps
   {:butt BasicStroke/CAP_BUTT
@@ -40,9 +40,35 @@
    :round BasicStroke/JOIN_ROUND
    :bevel BasicStroke/JOIN_BEVEL})

+(def colors
+  {:red Color/RED
+   :blue Color/BLUE
+   :green Color/GREEN
+   :cyan Color/CYAN
+   :magenta Color/MAGENTA
+   :yellow Color/YELLOW
+   :pink Color/PINK
+   :orange Color/ORANGE
+   :black Color/BLACK
+   :white Color/WHITE
+   :gray Color/GRAY
+   :grey Color/GRAY
+   :dark-gray Color/DARK_GRAY
+   :dark-grey Color/DARK_GRAY
+   :light-gray Color/LIGHT_GRAY
+   :light-grey Color/LIGHT_GRAY
+   })
+
+(defn color-object [color]
+  (cond
+    (integer? color) (Color. color)
+    (keyword? color) (colors color)
+    (string? color)  (colors (keyword color))
+    :else            color))
+
 (defn set-g2d-state [g2d {:keys [alpha color stroke rotate x y scale]}]
   (doto g2d
-    (.setColor (if color color Color/BLACK))
+    (.setColor (color-object (or color :black)))
     (.setComposite (if (or (not alpha)
                            (= alpha 1))
                      AlphaComposite/Src
@@ -247,18 +273,18 @@
    [:primitive-round-rect
     {:l 20 :t 10 :w 300 :h 300
      :arc-radius 100
-     :filled true :color Color/PINK
+     :filled true :color :pink
      :rotate 50}]
    [:primitive-round-rect
     {:l 20 :t 10 :w 300 :h 300
      :arc-radius 100 :rotate 50
-     :filled false :color Color/DARK_GRAY
+     :filled false :color (Color. 0xE06060)
      :stroke {:width 5
               :cap :round
-              :dashes [11 10] :dash-phase 0}}]
+              :dashes [10 10] :dash-phase 0}}]
    [:primitive-ellipse
     {:l 25 :t 15 :w 110 :h 90
-     :filled true :color Color/YELLOW :alpha 0.5}]
+     :filled true :color :yellow :alpha 0.5}]
    [:primitive-polygon
     {:vertices [{:x 100 :y 100}
                 {:x 50 :y 150}
@@ -266,7 +292,7 @@
                 {:x 160 :y 250}]
      :filled false
      :closed false
-     :color Color/ORANGE
+     :color :orange
      :alpha 0.8
      :stroke {:width 25
               :dashes [20 3 10 3 5 3]
@@ -275,7 +301,7 @@
               :miter-limit 10.0}}]
    [:primitive-text
     {:x 180 :y 120 :text "Testing..."
-     :color Color/BLUE
+     :color :blue
      :alpha 0.4
      :rotate 0.2
      :scale 1.1
@@ -286,16 +312,16 @@
             :strikethrough false
             :size 60}}]
    [:primitive-line
-    {:x 180 :y 220 :w 0 :h 50 :color Color/RED
+    {:x 180 :y 220 :w 0 :h 50 :color :red
      :stroke {:width 10 :cap :round}
      :alpha 0.7}]
    [:primitive-line
-    {:x 180 :y 220 :w 30 :h 0 :color Color/GREEN
+    {:x 180 :y 220 :w 30 :h 0 :color 0x00AA00
      :alpha 0.6
      :stroke {:width 4}}]
    [:primitive-arc
     {:l 30 :t 20 :w 150 :h 100
-     :start-angle 30 :arc-angle 100 :color Color/GREEN
+     :start-angle 30 :arc-angle 100 :color :green
      :filled true
      :alpha 0.7}]
    ])


CMR-6087: Fix doc string.

CMR-6087: Fix doc string.

--- transmit-lib/src/cmr/transmit/indexer.clj
+++ transmit-lib/src/cmr/transmit/indexer.clj
@@ -26,7 +26,7 @@
   (str (rebalance-collection-url conn index-set-id concept-id) "/finalize"))

 (defn get-index-set
-  "Submit a request to index-set app to fetch an index-set assoc with an id"
+  "Submit a request to indexer to fetch an index-set assoc with an id"
   [context id]
   (let [conn (config/context->app-connection context :indexer)
         response (client/request


functionality: encoders for classes

functionality: encoders for classes


Adjusted level 3.

Adjusted level 3.


Working on buffer functionality.

Working on buffer functionality.

* fixed buffer-write
* added buffer-<get, set, fill>

--- src/overtone/sc/buffer.clj
+++ src/overtone/sc/buffer.clj
@@ -61,7 +61,6 @@
     (free-id :audio-buffer id)
     :done))

-; TODO: Test me...
 (defn buffer-read
   "Read a section of an audio buffer."
   [buf start len]
@@ -77,7 +76,6 @@
         samples
         (let [msg-p (recv "/b_setn")
               msg (await-promise! msg-p)
-              ;_ (println "b_setn msg: " (take 3 (:args msg)))
               [buf-id bstart blen & samps] (:args msg)]
           (loop [idx bstart
                  samps samps]
@@ -86,12 +84,31 @@
               (recur (inc idx) (next samps))))
           (recur (+ recvd blen)))))))

-;; TODO: test me...
 (defn buffer-write
   "Write into a section of an audio buffer."
   [buf start len data]
   (assert (buffer? buf))
-  (snd "/b_setn" (:id buf) start len data))
+  (apply snd "/b_setn" (:id buf) start len (map double data)))
+
+(defn buffer-fill
+  "Fill a buffer range with a single value."
+  [buf start len val]
+  (assert (buffer? buf))
+  (snd "/b_fill" (:id buf) start len (double val)))
+
+(defn buffer-set
+  "Write a single value into a buffer."
+  [buf index val]
+  (assert (buffer? buf))
+  (snd "/b_set" (:id buf) index (double val)))
+
+(defn buffer-get
+  "Read a single value from a buffer."
+  [buf index]
+  (assert (buffer? buf))
+  (let [res (recv "/b_set")]
+    (snd "/b_get" (:id buf) index)
+    (last (:args (await-promise! res)))))

 (defn buffer-save
   "Save the float audio data in an audio buffer to a wav file."


Fix tests

Fix tests

--- backend/test/akvo/lumen/lib/user_test.clj
+++ backend/test/akvo/lumen/lib/user_test.clj
@@ -29,7 +29,7 @@
 (defn fixture [f]
   (migrate-tenant test-tenant)
   (binding [*emailer* (ig/init-key :akvo.lumen.component.emailer/dev-emailer {})
-            *keycloak* (ig/init-key :akvo.lumen.component.keycloak {:config {:keycloak keycloak-config}})
+            *keycloak* (ig/init-key :akvo.lumen.component.keycloak keycloak-config)
             *tenant-conn* (test-tenant-conn test-tenant)]
     (f)))


Formatting

Formatting

--- src/braid/client/bots/views/bots_page.cljs
+++ src/braid/client/bots/views/bots_page.cljs
@@ -88,8 +88,7 @@
                              {:bot-id (bot :id)
                               :on-complete (fn [info]
                                              (reset! detailed-info info))}]))}
-             "See bot config"]
-            )])])))
+             "See bot config"])])])))

 (defn group-bots-view []
   (let [group-id (subscribe [:open-group-id])


Simplify code by closing over props (b/c it is safe)

--- src/braid/client/ui/views/new_message.cljs
+++ src/braid/client/ui/views/new_message.cljs
@@ -86,10 +86,12 @@
         thread-text-kill-chan (chan)
         thread-text-chan (chan)
         throttled-thread-text-chan (debounce thread-text-chan 500)
-        thread-id (r/atom (config :thread-id))
+        ; safe to close over thread-id
+        thread-id (config :thread-id)
+        ; safe to close over new-message
         thread-text (config :new-message)

-        ; delibrately closing over value of sub
+        ; deliberately closing over value of sub
         state (r/atom {:text thread-text
                        :force-close? false
                        :highlighted-result-index 0
@@ -140,11 +142,11 @@
         set-text! (fn [text]
                     (let [text (.slice text 0 5000)]
                       (swap! state assoc :text text)
-                      (update-thread-text! @thread-id text)))
+                      (update-thread-text! thread-id text)))

         update-text! (fn [f]
                        (swap! state update :text f)
-                       (update-thread-text! @thread-id (@state :text)))
+                       (update-thread-text! thread-id (@state :text)))

         choose-result!
         (fn [result]
@@ -221,12 +223,8 @@
                        (dispatch [:new-message-text (merge v {:group-id (config :group-id)}) v])
                        (recur))
                      (dispatch [:new-message-text {:group-id (config :group-id)
-                                                   :thread-id @thread-id
+                                                   :thread-id thread-id
                                                    :content (@state :text)}])))))))
-
-       :component-will-update
-       (fn [c [_ new-config]]
-         (reset! thread-id (new-config :thread-id)))

        :component-will-unmount
        (fn []


semantics of 'open-or-prepare-was-called?' is now properly implemented

--- src/clj/backtype/storm/daemon/executor.clj
+++ src/clj/backtype/storm/daemon/executor.clj
@@ -379,8 +379,6 @@
       (fn []
         ;; If topology was started in inactive state, don't call (.open spout) until it's activated first.
         (sleep-until-true (fn [] @(:storm-active-atom executor-data)))
-        (reset! open-or-prepare-was-called? true)
-

         (log-message "Opening spout " component-id ":" (keys task-datas))
         (doseq [[task-id task-data] task-datas
@@ -433,8 +431,8 @@
                       )
                     (reportError [this error]
                       (report-error error)
-                      ))
-                  )))
+                      )))))
+        (reset! open-or-prepare-was-called? true)
         (log-message "Opened spout " component-id ":" (keys task-datas))

         (disruptor/consumer-started! (:receive-queue executor-data))
@@ -510,8 +508,7 @@
     [(async-loop
       (fn []
         (sleep-until-true (fn [] @(:storm-active-atom executor-data)))
-        (reset! open-or-prepare-was-called? true)
-
+
         (log-message "Preparing bolt " component-id ":" (keys task-datas))
         (doseq [[task-id task-data] task-datas
                 :let [^IBolt bolt-obj (:object task-data)
@@ -579,6 +576,7 @@
                        (reportError [this error]
                          (report-error error)
                          )))))
+        (reset! open-or-prepare-was-called? true)
         (log-message "Prepared bolt " component-id ":" (keys task-datas))

         (let [receive-queue (:receive-queue executor-data)


have TOPOLOGY-DEBUG show received messages as well

--- src/clj/backtype/storm/daemon/executor.clj
+++ src/clj/backtype/storm/daemon/executor.clj
@@ -299,12 +299,13 @@
 (defn mk-task-receiver [executor-data tuple-action-fn]
   (let [^KryoTupleDeserializer deserializer (:deserializer executor-data)
         task-ids (:task-ids executor-data)
+        debug? (= true (-> executor-data :storm-conf (get TOPOLOGY-DEBUG)))
         ]
     (disruptor/clojure-handler
       (fn [tuple-batch sequence-id end-of-batch?]
-        ;;(log-debug "Processing message " msg)
         (fast-list-iter [[task-id msg] tuple-batch]
           (let [^TupleImpl tuple (if (instance? Tuple msg) msg (.deserialize deserializer msg))]
+            (when debug? (log-message "Processing received message " tuple))
             (if task-id
               (tuple-action-fn task-id tuple)
               ;; null task ids are broadcast tuples


default driver to json-file instead of none

--- src/clj/swarmpit/docker/mapper/inbound.clj
+++ src/clj/swarmpit/docker/mapper/inbound.clj
@@ -297,7 +297,7 @@
       :secrets (->service-secrets service-spec)
       :variables (->service-variables service-spec)
       :labels (->service-labels service-labels)
-      :logdriver {:name (or (get-in service-task-template [:LogDriver :Name]) "none")
+      :logdriver {:name (or (get-in service-task-template [:LogDriver :Name]) "json-file")
                   :opts (->service-log-options service-task-template)}
       :resources {:reservation (->service-resource (get-in service-task-template [:Resources :Reservations]))
                   :limit       (->service-resource (get-in service-task-template [:Resources :Limits]))}


Use latest snapshot

Use latest snapshot

--- example-pipeline/project.clj
+++ example-pipeline/project.clj
@@ -4,7 +4,7 @@
   :license {:name "Eclipse Public License"
             :url "http://www.eclipse.org/legal/epl-v10.html"}
   :dependencies [[org.clojure/clojure "1.7.0"]
-                 [lambdaui "0.3.0-SNAPSHOT"]
+                 [lambdaui "0.3.7-SNAPSHOT"]
                  [lambdacd "0.9.0"]
                  [lambdacd-git "0.1.6"]
                  [http-kit "2.1.18"]]