auto-indenting improved: works with qualified symbols, and let* (letfn, etc.) Works for qualified symbols: works the same for some.ns/with-* than with-*

--- src/paredit/core.clj
+++ src/paredit/core.clj
@@ -265,17 +265,19 @@
                (-> t (t/delete offset 1) (t/shift-offset -1))))
          (-> t (t/delete offset 1) (t/shift-offset -1))))))

-(def lisp-forms (into #{} (map str '(let fn binding proxy reify extend extend-protocol extend-type bound-fn
+(def lisp-forms (into #{} (mapcat (fn [sym] [(str sym) (str "clojure.core/" sym)]) '(let fn binding proxy reify extend extend-protocol extend-type bound-fn
                             if if-not if-let when when-not when-let when-first condp case loop dotimes
                             for while do doto try catch locking dosync doseq dorun doall
                             -> -?> ->> future ns clojure.core/ns gen-class gen-interface))))
 (defn ^{:doc "Returns logical true if the String probably names a special form or macro var"}
   lisp-form? [^String s]
-  (or
-    (.startsWith s ".")
-    (.startsWith s "def")
-    (.startsWith s "with")
-    (lisp-forms s)))
+  (let [name (name (symbol s))]
+    (or
+      (.startsWith s ".")
+      (.startsWith name "def")
+      (.startsWith name "with")
+      (.startsWith name "let")
+    (lisp-forms s))))

 (defn indent-column
   "pre-condition: line-offset is already the starting offset of a line"


Fixing bug in creating selection op in query plan.

--- src/plasma/query.clj
+++ src/plasma/query.clj
@@ -117,16 +117,25 @@
   "Add the selection operators corresponding to a set of predicates
   to a query plan."
   [plan preds]
-  (reduce
-    (fn [plan pred]
-      (let [select-key (get-in plan [:pbind (:binding pred)])
-            op (plan-op :select (:root plan) select-key pred)]
-        (assoc-in (assoc plan :root (:id op))
-                  [:ops (:id op)] op)))
-    plan
-    preds))
-
-(defn path* [q]
+  (let [; flatten with binding name because each bind-point could
+        ; have more than one predicate attached (and ...)
+        flat-preds (partition 2 (mapcat (fn [[bind pred-seq]]
+                         (interleave (repeat bind)
+                                     pred-seq)) preds))]
+    (reduce
+      (fn [plan [binding pred]]
+        (println "pred: " pred)
+        (let [select-key (get-in plan [:pbind binding])
+              op (plan-op :select (:root plan) select-key pred)]
+          (assoc-in (assoc plan :root (:id op))
+                    [:ops (:id op)] op)))
+      plan
+      flat-preds)))
+
+(defn path*
+  "Helper function to 'parse' a path expression and generate an initial
+  query plan."
+  [q]
   (let [[bindings body]
         (cond
           (and (vector? (first q))  ; (path [:a :b :c])
@@ -154,13 +163,32 @@
 (defmacro path [& args]
   `(path* (quote ~args)))

-(defn optimize-query-plan [plan]
+(defn optimize-query-plan
+  [plan]
   plan)

+; TODO: Deal with nil receive op...
 (defn op-node
   "Instantiate an operator node based on a plan node."
-  [plan plan-node]
-  ())
+  [plan op-node]
+  (let [{:keys [ops]} plan
+        {:keys [type id op args]} op-node
+        op-name (symbol (str (name op) "-op"))
+        op-fn (ns-resolve 'plasma.operator op-name)]
+    (case type
+      :plasma.operator/traverse
+      (apply op-fn id nil args)
+
+      :plasma.operator/join
+      (apply op-fn id (map #(get ops %) args))
+
+      :plasma.operator/project
+      :plasma.operator/aggregate
+      :plasma.operator/parameter
+      :plasma.operator/receive
+      :plasma.operator/send
+      :plasma.operator/select
+    ))

 (defn build-query
   "Depth first traversal of query plan, resulting in a fully realized
@@ -168,15 +196,9 @@
   [{:keys [ops pbind root] :as plan}]
   (let [receiver (receive-op (uuid))]))

-;
-;
 ;(filter (fn [arg]
 ;          (or
 ;           ()
 ;           (and (uuid? arg)
 ;                (contains? query-ops arg)))
 ;        (:args op))
-;
-;
-;
-


Rearrange texture constructor so reflection isn't needed

--- src/play_clj/g2d.clj
+++ src/play_clj/g2d.clj
@@ -46,12 +46,12 @@
           TextureRegion.)
       (isa? (type arg) Pixmap)
       (-> ^Pixmap arg Texture. TextureRegion.)
-      (isa? (type arg) TextureRegion)
-      arg
+      (isa? (type arg) Texture)
+      (-> ^Texture arg TextureRegion.)
       (isa? (type arg) TextureEntity)
-      (TextureRegion. ^TextureRegion (:object arg))
+      (-> ^TextureRegion (:object arg) TextureRegion.)
       :else
-      (TextureRegion. arg))))
+      arg)))

 (defmacro texture
   "Returns an entity based on [TextureRegion](http://libgdx.badlogicgames.com/nightlies/docs/api/com/badlogic/gdx/graphics/g2d/TextureRegion.html).


Add initial implementation for subscribe and publish functions.

--- src/postal/core.cljs
+++ src/postal/core.cljs
@@ -168,6 +168,53 @@
     (ps/-send socket (frame-encode frame))
     (wait-frame client :response (:id frame)))))

+(defn- send-subscription-request
+  [client id dest data]
+  (let [socket (:socket client)
+        frame {:cmd :novelty
+               :id id
+               :dest dest
+               :data data}]
+    (ps/-send socket (frame-encode frame))
+    (wait-frame client :response id)))
+
+(defn subscribe
+  "Return a lazy stream that will subscribe to the server
+  when an subscription is attached."
+  ([client dest]
+   (subscribe client dest nil nil))
+  ([client dest data]
+   (subscribe client dest data nil))
+  ([client dest data opts]
+   (let [id (random-uuid)]
+     (s/create (fn [sink]
+                 (let [stream (->> (:message-stream client)
+                                   (s/filter #(= (:cmd %) :message))
+                                   (s/filter #(= (:subscription %) id)))
+                       unsub (s/subscribe stream #(sink %) #(sink %) #(sink nil))]
+                   (-> (send-subscription-request client id dest data)
+                       (p/catch (fn [error]
+                                  (unsub)
+                                  (if (instance? js/Error error)
+                                    (sink error)
+                                    (sink (ex-info "Error" error))))))
+                   unsub))))))
+
+(defn publish
+  "Sends a :publish frame to the server."
+  ([client dest]
+   (publish client dest nil nil))
+  ([client dest data]
+   (publish client dest data nil))
+  ([client dest data opts]
+   (let [socket (:socket client)
+         frame {:cmd :publish
+                :id (random-uuid)
+                :dest dest
+                :data data}]
+    (ps/-send socket (frame-encode frame))
+    (wait-frame client :response (:id frame)))))
+
 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
 ;; Helpers
 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;


whitespace

whitespace

--- src/prais2/data.cljs
+++ src/prais2/data.cljs
@@ -101,8 +101,6 @@
 ;;;
 ;; graphic renders
 ;;;
-
-

 (rum/defc bar < rum/static
           ([slider hi-val lo-val bar-type fill]


forgot to close quote

forgot to close quote

--- src/such/function_makers.clj
+++ src/such/function_makers.clj
@@ -30,6 +30,7 @@
    Note: this predates [[some-fn]]. It differs in that it always returns
    `true` or `false`, and that it allows zero arguments (which produces a
    function that always returns `true`).
+"
   [& preds]
   (if (empty? preds)
     (constantly true)


Working!

Working!

--- src/re_com/time.cljs
+++ src/re_com/time.cljs
@@ -154,7 +154,7 @@
   Re-validate what has been entered. Then update the model."
   [ev input-model min max callback previous-val]
   (let [time-int (string->time-integer @input-model)
-        validated-int (validated-time-integer time-int @min @max previous-val)]
+        validated-int (validated-time-integer time-int min max previous-val)]
     (reset! input-model (display-string (time-int->hour-minute validated-int)))
     (when (and callback (not (= validated-int previous-val)))
       (callback validated-int))))
@@ -206,7 +206,7 @@
   "This is the markup for the time input."
   [ & {:keys [model previous-val min max on-change disabled style hide-border show-time-icon :as args]}]
   {:pre [(superset? time-api (keys args))]}
-  (println (str "model: " @model " prev: " previous-val " min: " @min " max: " @max)) ;; TODO remove this
+  ;;(println (str "model: " @model " prev: " previous-val " min: " min " max: " max))
   (let [def-style {:flex "none"
                    :margin-top "0px"
                    :padding-left "2px"
@@ -236,10 +236,10 @@
   [& {:keys [model minimum maximum on-change]}]
   (let [deref-model (deref-or-value model)
         input-model (atom-on (display-string (time-int->hour-minute deref-model)) "")
-        min (atom-on minimum 0)
-        max (atom-on maximum 2359)]
-    (validate-max-min @min @max)                  ;; This will throw an error if the parameters are invalid
-    (if-not (valid-time-integer? deref-model @min @max)
+        min (if minimum minimum 0)
+        max (if maximum maximum 2359)]
+    (validate-max-min min max)                  ;; This will throw an error if the parameters are invalid
+    (if-not (valid-time-integer? deref-model min max)
       (throw (js/Error. (str "model " deref-model " is not a valid time integer or is outside the min/max range."))))
      (fn [& {:keys [model disabled hide-border show-time-icon style]}]
        [private-time-input
@@ -260,12 +260,12 @@
   (let [deref-model (deref-or-value model)
         input-from-model  (atom-on (display-string (time-int->hour-minute(first deref-model))) nil)
         input-to-model    (atom-on (display-string (time-int->hour-minute(last  deref-model))) nil)
-        min (atom-on minimum 0)
-        max (atom-on maximum 2359)]
-  (validate-max-min @min @max)                  ;; This will throw an error if the parameters are invalid
-  (if-not (valid-time-integer? (first deref-model) @min @max)
+        min (if minimum minimum 0)
+        max (if maximum maximum 2359)]
+  (validate-max-min min max)                  ;; This will throw an error if the parameters are invalid
+  (if-not (valid-time-integer? (first deref-model) min max)
     (throw (js/Error. (str "model for FROM time: " @input-from-model " is not a valid time integer."))))
-  (if-not (valid-time-integer? (last deref-model) @min @max)
+  (if-not (valid-time-integer? (last deref-model) min max)
     (throw (js/Error. (str "model for TO time: " @input-to-model " is not a valid time integer."))))
   (if-not (< (first deref-model) (last deref-model))
       (throw (js/Error. (str "TO " @input-to-model " is less than FROM " @input-from-model "."))))


fx - check :dispatch effect val to be vector? & introduce new effect :dispatch-n for

--- src/re_frame/fx.cljc
+++ src/re_frame/fx.cljc
@@ -1,10 +1,17 @@
 (ns re-frame.fx
-  (:require [re-frame.router :refer [dispatch]]
-            [re-frame.db :refer [app-db]]
-            [re-frame.events]
-            [re-frame.interop :refer [ratom? set-timeout!]]
-            [re-frame.loggers    :refer [console]]))
+  (:require
+    [re-frame.router  :refer [dispatch]]
+    [re-frame.db      :refer [app-db]]
+    [re-frame.events  :as events]
+    [re-frame.interop :refer [ratom? set-timeout!]]
+    [re-frame.loggers :refer [console]]))

+;; ---- Spec schema -----------------------------------------------------------
+;; TODO use Spec to validate events for :dispatch and :dispatch-n
+;; e.g. (when (= :cljs.spec/invalid (s/conform ::event val))
+;;        (console :error (s/explain-str ::event val)))
+;; (s/def ::event (s/and vector? (complement empty?)))
+;; (s/def ::events-n (s/coll-off ::event))

 ;; -- Registration ------------------------------------------------------------

@@ -39,11 +46,11 @@

 (defn dispatch-helper
   "There are cases where either one event is to be dipatched or a list of them"
-  [effect]
+  [event]
   (cond
-    (vector? effect) (dispatch effect)
-    (seq? effect)    (dorun (map dispatch effect))
-    :else (console :error "re-frame: expected :dispatch effect to be a list or vector, but got: " effect)))
+    (vector? event) (dispatch event)
+    (seq? event)    (dorun (map dispatch event))
+    :else (console :error "re-frame: expected :dispatch event to be a list or vector, but got: " event)))

 ;; Example:
 ;; {:dispatch-later {200  [:event-id "param"]    ;;  in 200ms do this: (dispatch [:event-id "param"])
@@ -57,24 +64,38 @@
       (set-timeout! #(dispatch-helper events) ms))))

-;; Supply either a vector or a list of vectors. For example:
+;; Supply a vector. For example:
 ;;
 ;;   {:dispatch [:event-id "param"] }
-;;
-;;   {:dispatch (list [:do :all] [:three :of] [:these]) }
-;;
+
 (register
   :dispatch
   (fn [val]
-    (dispatch-helper val)))
+    (when-not (vector? val)
+      (console :warn "re-frame: :dispatch fx val expected vector got:" val))
+    (dispatch val)))
+
+
+;; Supply sequencial coll. For example:
+;;
+;;   {:dispatch-n (list [:do :all] [:three :of] [:these])}
+;;
+;; Coll can be anything that returns true to sequential? but should not be a map
+;; NOTE: this does not include Set
+(register
+  :dispatch-n
+  (fn [val]
+    (when (or (-> val sequential? not) (map? val))
+      (console :warn "re-frame: :dispatch-n fx val expected sequential not map got:" val))
+    (doseq [event val] (dispatch event))))

 (register
   :deregister-event-handler
   (fn [val]
     (if (sequential? val)
-      (doall (map re-frame.events/clear-handler! val))
-      (re-frame.events/clear-handler! val))))
+      (doall (map events/clear-handler! val))
+      (events/clear-handler! val))))

 (register


minor fixes

minor fixes

--- src/replify/core.clj
+++ src/replify/core.clj
@@ -6,15 +6,17 @@
             [cljs.repl.rhino :as rhino])
   (:gen-class))

-(defonce compile-cljs
-  ^{:doc "Compile Cljs compiler for faster src compilations"}
+(defn compile-cljs
+  "Compile Cljs compiler for faster src compilations"
+  []
   (do
     (compile 'cljs.repl.node)
     (compile 'cljs.repl.browser)
     (compile 'cljs.core)))

-(defn watch [main & options]
+(defn watch
   "Watch for Cljs src changes"
+  [main & options]
   (println "Watching for changes ...")
   (b/watch "src"
            {:main main
@@ -41,8 +43,9 @@
      (future
        (watch main)))))

-(defn release [& options]
+(defn release
   "Release Cljs src for production (advanced compilation)"
+  [& options]
   (println "Building 'Release' ...")
   (let [start (System/nanoTime)]
     (b/build "src"
@@ -52,8 +55,9 @@
               :verbose true})
     (println "... done. Elapsed" (/ (- (System/nanoTime) start) 1e9) "seconds")))

-(defn start-node-repl [& options]
+(defn start-node-repl
   "Start a Node Repl"
+  [& options]
   (println "Starting Node REPL ...")
   (repl/repl* (node/repl-env)
               {:output-dir "target"
@@ -61,10 +65,11 @@
                :cache-analysis true
                :source-map true}))

-(defn start-rhino-repl [& options]
+(defn start-rhino-repl
   "Start a Rhino Repl"
+  [& options]
   (println "Starting Rhino REPL ...")
-  (repl/repl* (node/repl-env)
+  (repl/repl* (rhino/repl-env)
               {:output-dir "target"
                :optimizations :none
                :cache-analysis true
@@ -72,14 +77,15 @@

 (defn start-brepl [& options]
   (println "Starting Browser REPL ...")
-  (repl/repl* (rhino/repl-env)
+  (repl/repl* (browser/repl-env)
               {:output-dir "target"
                :optimizations :none
                :cache-analysis true
                :source-map true}))

-(defn -main [args]
+(defn -main
   "If invoked on the CLI, compile cljs and start a node repl"
+  [args]
   (compile-cljs)
   (build args)
   (start-node-repl))


just need to send the file...

just need to send the file...

--- src/server/core.cljs
+++ src/server/core.cljs
@@ -19,6 +19,7 @@

 (def io (.listen socketio server))

+(def redis-subscribe-download-request-client (.createClient (nodejs/require "redis")))
 (def redis-subscribe-client (.createClient (nodejs/require "redis")))
 (def redis-publish-client (.createClient (nodejs/require "redis")))

@@ -31,7 +32,10 @@
   (println "A user has connected!")
   (.on socket "new-file-request"
     (fn []
-      (println "New file request!")))
+      (println "New file request!")
+      (.incr rooms/redis-client (str "file-request:" (.-id socket))
+        (fn [err reply]
+          (.publish redis-publish-client "file-download-request" (.-id socket))))))
   (.on socket "disconnect" (fn []
     (.get rooms/redis-client (string/join ["users:" (.-id socket)])
       (fn [err reply]
@@ -71,6 +75,18 @@
                         :file absolute-file-path}]
               (.publish redis-publish-client "file-upload" (transit/write writer data)))))))))

+(.subscribe redis-subscribe-download-request-client "file-download-request")
+(.on redis-subscribe-download-request-client "message"
+  (fn [channel message]
+    (if (= channel "file-download-request")
+      (rooms/get-room-from-id message
+        (fn [err reply]
+          (.get rooms/redis-client (str "file-request:" message)
+            (fn [err r]
+              (.lindex rooms/redis-client (str (.toString reply) ":music") (- 1 (.toString r))
+                (fn [err reply]
+                  (println (.toString reply)))))))))))
+
 ; TODO: Move to rooms namespace (or something)
 ; TODO: probably dont even need this subscription anymore...
 (.subscribe redis-subscribe-client "file-upload")


Added some comments

Added some comments

--- src/wishlistd/cljs/main.cljs
+++ src/wishlistd/cljs/main.cljs
@@ -5,10 +5,13 @@
   (:use-macros [crate.macros :only [defpartial]]
                [fetch.macros :only [letrem]]))

+; ACCESS VARIABLES FOR IMPORTANT ELEMENTS

 (def $create  ($ "#create-wishlist"))
 (def $content ($ "#box"))
 (def $header  ($ "#title-box"))
+
+; HTML PARTIALS

 (defpartial wish-li [{:keys [description url]}]
   [:li.wish
@@ -31,6 +34,8 @@
 (defpartial wishlist-title [title]
   [:input {:type "text" :class "title" :value title}])

+; GETTING AND SETTING
+
 (defn get-path []
   (.pop
     (.split js/window.location.pathname "/")))


Calendar now cached.

Calendar now cached.

--- src/vertigo/core.clj
+++ src/vertigo/core.clj
@@ -70,25 +70,12 @@
 (defn retrieve-shows-by-date [date]
   (let [formatted-date (unparse (formatter "dd.MM.yyyy") date)
         cached-shows   (get @shows-db formatted-date)]
-    (if cached-shows
-      {:date           formatted-date
-       :shows-by-genre cached-shows}
-      (let [new-shows (parse-shows-and-group-by-genre
-                        (zip/xml-zip
-                          (xml/parse
-                            (str
-                              "http://finnkino.fi/xml/Schedule/?area=1002&dt="
-                              formatted-date))))]
-        {:date           formatted-date
-         :shows-by-genre (get
-                           (swap! shows-db assoc
-                                             formatted-date
-                                             new-shows)
-                           formatted-date)}))))
+    {:date           formatted-date
+     :shows-by-genre cached-shows}))

-(defn retrieve-shows-for-whole-week []
+(defn apply-on-whole-week [f]
   (let [dates (take 7 (iterate #(.plusDays % 1) (now)))]
-    (map retrieve-shows-by-date dates)))
+    (map f dates)))

 (def events-db (atom {}))

@@ -106,9 +93,24 @@
                      (swap! events-db assoc event-id new-event)
                      event-id)}))))

+(defn retrieve-and-store-shows-from-finnkino [date]
+  (let [formatted-date (unparse (formatter "dd.MM.yyyy") date)
+        new-shows
+          (parse-shows-and-group-by-genre
+            (zip/xml-zip
+              (xml/parse
+                (str
+                  "http://finnkino.fi/xml/Schedule/?area=1002&dt="
+                  formatted-date))))]
+    (swap! shows-db assoc
+                      formatted-date
+                      new-shows)))
+
 (defroutes handler
   (GET "/" []
-    (views/calendar (retrieve-shows-for-whole-week))))
+    (views/calendar (apply-on-whole-week retrieve-shows-by-date)))
+  (GET "/execute-batch" []
+    (apply-on-whole-week retrieve-and-store-shows-from-finnkino)))

 (run-jetty handler {:port 8080 :join? false})


ui-v2 top-nav fix repeated organizations loading

--- src-cljs/frontend/components/app.cljs
+++ src-cljs/frontend/components/app.cljs
@@ -119,7 +119,8 @@
               app-without-container-data (dissoc-in app state/container-data-path)
               dom-com (dominant-component app owner)
               show-header-and-footer? (not= :signup (:navigation-point app))
-              api-ch (get-in app [:comms :api])]
+              api-ch (get-in app [:comms :api])
+              organizations-loaded? (seq (get-in app state/top-nav-orgs-path))]
           (reset! keymap {["ctrl+s"] persist-state!
                           ["ctrl+r"] restore-state!})
           (html
@@ -135,7 +136,8 @@
                         {:opts {:keymap keymap
                                 :error-ch (get-in app [:comms :errors])}})
               (when (and inner? logged-in? (feature/enabled? :ui-v2))
-                (api/get-orgs api-ch)
+                (if-not organizations-loaded?
+                  (api/get-orgs api-ch))
                 (om/build top-nav/top-nav app-without-container-data))
               (when (and inner? logged-in?)
                 (om/build aside/aside-nav (dissoc app-without-container-data :current-build-data)))


[#2262] Adapt a.l.endpoint.split-column

[#2262] Adapt a.l.endpoint.split-column

--- backend/src/akvo/lumen/endpoint/split_column.clj
+++ backend/src/akvo/lumen/endpoint/split_column.clj
@@ -1,6 +1,7 @@
 (ns akvo.lumen.endpoint.split-column
   (:require [akvo.lumen.protocols :as p]
             [akvo.lumen.lib :as lib]
+            [akvo.lumen.db.transformation :as db.transformation]
             [akvo.lumen.lib.transformation.split-column :as transformation]
             [clojure.spec.alpha :as s]
             [akvo.lumen.component.tenant-manager :as tenant-manager]
@@ -8,8 +9,6 @@
             [clojure.tools.logging :as log]
             [hugsql.core :as hugsql]
             [integrant.core :as ig]))
-
-(hugsql/def-db-fns "akvo/lumen/lib/transformation.sql")

 (defn sort-pattern-analysis-by [pattern-analysis sort-by*]
   (->> (seq (:analysis pattern-analysis))
@@ -22,12 +21,12 @@
         tenant :tenant}]
     (let [query           (json/parse-string (get query-params "query") keyword)
           tenant-conn     (p/connection tenant-manager tenant)
-          dataset-version (latest-dataset-version-by-dataset-id tenant-conn {:dataset-id dataset-id})
+          dataset-version (db.transformation/latest-dataset-version-by-dataset-id tenant-conn {:dataset-id dataset-id})
           sql-query       {:table-name  (:table-name dataset-version)
                            :column-name (:columnName query)
                            :limit       (str (:limit query "200"))}
           values          (map (comp str (keyword (:columnName query)))
-                               (select-random-column-data tenant-conn sql-query))
+                               (db.transformation/select-random-column-data tenant-conn sql-query))
           pattern-analysis (transformation/pattern-analysis (re-pattern "[^a-zA-Z0-9\\s]") values)]
       (lib/ok {:analysis (sort-pattern-analysis-by pattern-analysis :total-row-coincidences)}))))


Prevent noisy warning in test case

Prevent noisy warning in test case

We now have a separate test for unknown keys.

--- src/test/clojure/clojure/tools/cli_test.clj
+++ src/test/clojure/clojure/tools/cli_test.clj
@@ -78,7 +78,7 @@
               [[integer? port?] ["Must be an integer" "Must be between 0 and 65536"]]
               [[identity] ["Should be backwards compatible"]]]))))
   (testing "accepts maps as option specs without munging values"
-    (is (= (compile-option-specs [{:id ::foo :short-opt "-f" :long-opt "--foo" :bad-key nil}])
+    (is (= (compile-option-specs [{:id ::foo :short-opt "-f" :long-opt "--foo"}])
            [{:id ::foo :short-opt "-f" :long-opt "--foo"}])))
   (testing "warns about unknown keys"
     (^{:cljs 'do} when ^:clj *assert*


Don't sync ongoing builds for Go

Don't sync ongoing builds for Go

--- scripts/gosync.clj
+++ scripts/gosync.clj
@@ -45,13 +45,14 @@

 (defn parse-build-info [json-response]
   (let [build-info (:building_info (first json-response))
-        start-time (tc/to-long (tf/parse (:build_building_date build-info)))
-        end-time (tc/to-long (tf/parse (:build_completed_date build-info)))
-        result (:result build-info)
-        outcome (if (= "Passed" result) "pass" "fail")]
-    (-> {}
-        (build-times start-time end-time)
-        (assoc :outcome outcome))))
+        result (:result build-info)]
+    (when-not (= "Unknown" result)
+      (let [start-time (tc/to-long (tf/parse (:build_building_date build-info)))
+            end-time (tc/to-long (tf/parse (:build_completed_date build-info)))
+            outcome (if (= "Passed" result) "pass" "fail")]
+        (-> {}
+            (build-times start-time end-time)
+            (assoc :outcome outcome))))))

 (defn build-for [{jobId :jobId}]
   (let [build (get-json "/jobStatus.json?pipelineName=&stageName=&jobId=%s" jobId)]
@@ -191,6 +192,7 @@
        (mapcat job-instances-for-stage)
        (map augment-job-with-inputs)
        (map job-data-for-instance)
+       (filter #(some? (:build %)))
        (map augment-job-instance-with-junit-xml)))

 (put-to-buildviz (map make-build-instance job-instances))


Moved to google closure svg graphics.

Moved to google closure svg graphics.

--- ClojureScript/hello.cljs
+++ ClojureScript/hello.cljs
@@ -2,18 +2,21 @@

 (ns hello
     (:use
-        [goog.dom :only [appendChild createDom]]
+        [goog.dom :only [appendChild createDom createTextNode removeChildren]]
         [goog.events :only [listen]]
         [goog.events.EventType :only [CLICK]]
+        [goog.graphics :only [createGraphics Stroke SolidFill]]
         ))

 (def pos (atom 0))
 (def keys-pressed (atom (set)))
+(def my-code-url "https://github.com/pauldoo/scratch/blob/master/ClojureScript/hello.cljs")

 (defn print-to-log [v]
     (.log js/console v))

-(defn foobar [t canvas y event] (do
+(defn foobar [t canvas-element y event] (do
+    (print-to-log "hello")
     (cond
         (= t :up)
             (swap! keys-pressed disj (.keyCode event))
@@ -21,28 +24,28 @@
             (swap! keys-pressed conj (.keyCode event))
         :else
             nil)
-    (let [ctx (.getContext canvas "2d")
-        x (swap! pos inc)]
+    (let [x (swap! pos inc)
+        graphics (goog.graphics/createGraphics 400 300)]
         (do
-            (. ctx (save))
-            (.clearRect ctx 0 0 (.width canvas) (.height canvas))
-            (set! (.fillStyle ctx) "red")
-            (.fillRect ctx x y 100 50)
-            (. ctx (restore))
+            (.drawCircle graphics x y 30 (Stroke. 2 "green") (SolidFill. "yellow"))
+            (goog.dom/removeChildren canvas-element)
+            (.render graphics canvas-element)
             ))))

 (defn ^:export main []
     (let [
-        canvas (goog.dom/createDom "canvas" (.strobj {
-            "width" 400
-            "height" 300
-            "style" "border: 1px solid #000000"
-            }) "")
+        canvas (goog.dom/createDom "div" {} "")
         button (goog.dom/createDom "button" {} "Click!")]
         (do
             (goog.events/listen button goog.events.EventType/CLICK (partial foobar :click canvas 100))
             (goog.events/listen document.body goog.events.EventType/KEYDOWN (partial foobar :down canvas 50) true)
             (goog.events/listen document.body goog.events.EventType/KEYUP (partial foobar :up canvas 150) true)
-            (dorun (map (partial goog.dom/appendChild document.body)
-                [(goog.dom/createDom "h1" {} "Hello!") canvas button])))))
+            (goog.dom/appendChild document.body (goog.dom/createDom "div" {}
+                (goog.dom/createDom "h1" {} "Work in progress..")
+                (goog.dom/createDom "div" {} "Try clicking the button, or pressing keys.")
+                (goog.dom/createDom "div" {}
+                    (goog.dom/createTextNode "My code lives here: ")
+                    (goog.dom/createDom "a" (.strobj {"href" my-code-url}) my-code-url))
+                button
+                canvas)))))


Divided process method into smaller ones.

--- src/app/interactive.clj
+++ src/app/interactive.clj
@@ -23,6 +23,41 @@
     "NUM = #'[0-9]+'                                       \n"
     "STR = #'\"[^\"]*\"'                                   \n")))

+(declare interactive)
+
+(defn- exit []
+  (println "Exit..."))
+
+(defn- list-loaded-classes [state]
+  (let [loadedCus (:cus state)]
+    (if loadedCus
+      (do
+        (println "Listing types currently loaded:")
+        (doseq [cu (:cus state)]
+          (doseq [t (.getTypes cu)]
+            (println " *" (getQName t))))
+        (println "No classes loaded. Use <load> first"))
+      (interactive state))))
+
+(defn- help [state]
+  (println "h/help                      : print this help message")
+  (println "q/quit/exit                 : close the shell")
+  (println "list                        : list classes loaded")
+  (println "mc/many-constructors th NUM : list classes with NUM or more constructors")
+  (interactive state))
+
+(defn- load-classes [ast]
+  (let [dirnameWithApex (nth (nth (first ast) 2) 1)
+        dirname (subs dirnameWithApex 1 (+ (.length dirnameWithApex) -1))]
+    (println "Loading" dirname)
+    (let [loadedCus (cus dirname)]
+      (println "Java files loaded:" (.size loadedCus))
+      (interactive {:cus loadedCus}))))
+
+(defn- mc-operation [state]
+  (printOperation classesWithManyConstructorsOp (:cus state) 5)
+  (interactive state))
+
 (defn process [state input rp]
   (let
    [ast (command-parser input)]
@@ -33,35 +68,11 @@
         (rp state))
       (let [command (ffirst ast)]
         (cond
-          (= command :EXIT) (println "Exit...")
-          (= command :LIST)
-          (let [loadedCus (:cus state)]
-            (if loadedCus
-              (do
-                (println "Listing types currently loaded:")
-                (doseq [cu (:cus state)]
-                  (doseq [t (.getTypes cu)]
-                    (println " *" (getQName t))))
-                (println "No classes loaded. Use <load> first"))
-              (rp state)))
-          (= command :HELP)
-          (do
-            (println "h/help                      : print this help message")
-            (println "q/quit/exit                 : close the shell")
-            (println "list                        : list classes loaded")
-            (println "mc/many-constructors th NUM : list classes with NUM or more constructors")
-            (rp state))
-          (= command :LOAD)
-          (let [dirnameWithApex (nth (nth (first ast) 2) 1)
-                dirname (subs dirnameWithApex 1 (+ (.length dirnameWithApex) -1))]
-            (println "Loading" dirname)
-            (let [loadedCus (cus dirname)]
-              (println "Java files loaded:" (.size loadedCus))
-              (rp {:cus loadedCus})))
-          (= command :MC)
-          (do
-            (printOperation classesWithManyConstructorsOp (:cus state) 5)
-            (rp state))
+          (= command :EXIT) (exit)
+          (= command :LIST) (list-loaded-classes state)
+          (= command :HELP) (help state)
+          (= command :LOAD) (load-classes ast)
+          (= command :MC) (mc-operation state)
           :else (println "Command not implemented: " command))))))

 (defn interactive [state]


Add comment

Add comment

--- src/clj/cglossa/data_import/utils.clj
+++ src/clj/cglossa/data_import/utils.clj
@@ -4,6 +4,11 @@
             [me.raynes.conch :as conch]))

 (defn read-csv [file]
+  ;; We don't use quotes around fields (since we separate them by tabs),
+  ;; but clojure.data.csv will treat quotes as field separators unless we
+  ;; set it to something else - so use a carect, which we are unlikely to
+  ;; encounter in texts. Needs a better solution of course (maybe a patch
+  ;; to the csv library).
   (csv/read-csv file :separator \tab :quote \^))

 (defn write-csv [file data]


compile-spec only on demand

compile-spec only on demand

--- src/cljc/commos/delta/compscribe.cljc
+++ src/cljc/commos/delta/compscribe.cljc
@@ -37,27 +37,29 @@
   "Recursively transform spec [endpoint hooks] [endpoint
   flattened-keys-hooks flattened-keys-hooks-grouped-by-pks hooks].
   The resulting structure provides fast lookups required during live
-  dispatch."
+  dispatch.  Returns compiled spec untransformed."
   [spec]
   (let [spec? #(::spec (meta %))
         mark-spec #(vary-meta % assoc ::spec true)]
-    (->> (mark-spec spec)
-         (prewalk (fn [form]
-                    (if (spec? form)
-                      (let [[endpoint specs] form]
-                        (mark-spec
-                         (if (vector? specs)
-                           [endpoint {[] (mark-spec specs)}]
-                           (let [specs (flatten-keys specs)]
-                             [endpoint (zipmap (keys specs)
-                                               (map mark-spec
-                                                    (vals specs)))]))))
-                      form)))
-         (postwalk (fn [form]
-                     (if (spec? form)
-                       (let [[endpoint specs] form]
-                         [endpoint specs (group-by-pks specs)])
-                       form))))))
+    (cond->
+        (spec? spec)
+        (->> (mark-spec)
+             (prewalk (fn [form]
+                        (if (spec? form)
+                          (let [[endpoint specs] form]
+                            (mark-spec
+                             (if (vector? specs)
+                               [endpoint {[] (mark-spec specs)}]
+                               (let [specs (flatten-keys specs)]
+                                 [endpoint (zipmap (keys specs)
+                                                   (map mark-spec
+                                                        (vals specs)))]))))
+                          form)))
+             (postwalk (fn [form]
+                         (if (spec? form)
+                           (let [[endpoint specs] form]
+                             [endpoint specs (group-by-pks specs)])
+                           form)))))))

 (defn- dissoc-in
   ;; from org.clojure/core.incubator, copy & pasted due to lack of


update cider version

update cider version

--- .lein/profiles.clj
+++ .lein/profiles.clj
@@ -1,7 +1,7 @@
 {:user
  {:plugins
   [
-   [cider/cider-nrepl "0.9.0"]
+   [cider/cider-nrepl "0.9.1"]
    [lein-midje "3.1.3"]
    [lein-try "0.4.1"]
    [lein-marginalia "0.7.1"]


[.lein] Remove eastwood; it's breaking 'lein new'

--- .lein/profiles.clj
+++ .lein/profiles.clj
@@ -1,7 +1,6 @@
 {:user {:plugins [[lein-exec "0.3.0"]
                   [lein-depgraph "0.1.0"]
-                  [lein-deps-tree "0.1.2"]
-                  [jonase/eastwood "0.1.2"]]
+                  [lein-deps-tree "0.1.2"]]
         :dependencies [[org.clojure/tools.namespace "0.2.4"]
                        [criterium "0.4.2"]
                        [slamhound "1.5.5"]]


cleanup

cleanup

--- src/babel/generate.cljc
+++ src/babel/generate.cljc
@@ -100,16 +100,14 @@

 (defn add-bolt-at [top-bolt bolt path bolt-at model depth max-depth truncate? & [take-n]]
   (mapfn #(do-defaults % model)
-         (let [comp-paths (find-comp-paths bolt-at)
-               comp-bolts
-               (mapfn #(comp-path-to-bolts bolt-at % model (+ 1 depth) max-depth)
-                      comp-paths)]
+         (let [comp-paths (find-comp-paths bolt-at)]
            (mapfn #(assoc-in bolt path %)
                   (lazy-seq
                    (add-comps bolt-at
                               model
                               comp-paths
-                              comp-bolts
+                              (mapfn #(comp-path-to-bolts bolt-at % model (+ 1 depth) max-depth)
+                                     comp-paths)
                               (+ 1 depth)
                               max-depth
                               top-bolt


remove unneeded (take): has no effect on performance

--- src/babel/generate.cljc
+++ src/babel/generate.cljc
@@ -110,7 +110,7 @@
   (mapfn #(do-defaults % model)
          (let [comp-paths (find-comp-paths bolt-at)
                comp-bolts
-               (mapfn #(take take-n (comp-path-to-bolts bolt-at % model (+ 1 depth) max-depth))
+               (mapfn #(comp-path-to-bolts bolt-at % model (+ 1 depth) max-depth)
                       comp-paths)]
            (log/trace (str "add-bolt-at:" ((:morph-ps model) bolt-at) "; comp-paths: " (string/join "," comp-paths)))
            (when (not (some empty? comp-bolts))


remove TODO comment since it's been done.

--- src/babel/generate.cljc
+++ src/babel/generate.cljc
@@ -193,7 +193,6 @@
           true
           (lazy-cat bolts-at lexemes))))

-;; TODO: lightning-bolts should use this.
 (defn get-lexemes [model spec]
   (if (= false (get-in spec [:phrasal] false))
     (filter not-fail?


support {:disable true}

support {:disable true}

--- src/babel/lexiconfn.clj
+++ src/babel/lexiconfn.clj
@@ -27,8 +27,18 @@
         ;; (i.e. vectorize the values of the map).
         lexicon-stage-1 (listify lexicon-source)

+        remove-disable (map-function-on-map-vals
+                        lexicon-stage-1
+                        (fn [k v]
+                          (remove #(= :fail %)
+                                  (map (fn [lexeme]
+                                         (if (= true (get-in lexeme [:disable]))
+                                           :fail
+                                           lexeme))
+                                       v))))
+
         phon-lexicon (map-function-on-map-vals
-                      lexicon-stage-1
+                      remove-disable
                       (fn [lexical-string lexical-val]
                         (phonize-fn lexical-val lexical-string)))


Update views.clj

Update views.clj

--- src/briefcase/views.clj
+++ src/briefcase/views.clj
@@ -142,7 +142,7 @@
   (let [data (yaml/parse-string (slurp "resources/content/background.yml"))]
     (main-layout request "yobriefca.se"
       [:h1 "People"]
-      [:h2 "James Hughes"]
+      [:h1 "James Hughes"]
       [:ul
         (for [{ href :href name :name } (:links data)]
           [:li [:a { :href href } name]])]


don't always fire off a future when compressing

--- src/byte_transforms.clj
+++ src/byte_transforms.clj
@@ -19,7 +19,8 @@
      OutputStream
      InputStream
      PipedInputStream
-     PipedOutputStream]
+     PipedOutputStream
+     ByteArrayOutputStream]
     [java.security
      MessageDigest]
     [java.nio
@@ -280,7 +281,8 @@
   [x options]
   (InflaterInputStream. (bytes/to-input-stream x options)))

-(defn- in->wrapped-out->in [^InputStream stream output-wrapper options]
+(defn- in->wrapped-out->in
+  [^InputStream stream output-wrapper options]
   (let [chunk-size (get options :chunk-size 65536)
         out (PipedOutputStream.)
         in (PipedInputStream. out chunk-size)
@@ -299,10 +301,33 @@

     in))

+(defn bytes->wrapped-out->bytes
+  [bytes output-wrapper options]
+  (if (or (instance? ByteBuffer bytes)
+        (instance? byte-array bytes))
+    (let [^ByteBuffer buf (bytes/to-byte-buffer bytes)
+          out (ByteArrayOutputStream.)
+          ^OutputStream compressor (output-wrapper out)
+          ^bytes ary (clojure.core/byte-array 1024)]
+      (loop []
+        (let [remaining (.remaining buf)]
+          (when (pos? remaining)
+            (let [len (p/min remaining 1024)]
+              (.get buf ary 0 len)
+              (.write compressor ary 0 len)
+              (recur)))))
+      (.close compressor)
+      (.close out)
+      (.toByteArray out))
+    (in->wrapped-out->in
+      (bytes/to-input-stream bytes options)
+      output-wrapper
+      options)))
+
 (def-compressor gzip
   [x options]
-  (in->wrapped-out->in
-    (bytes/to-input-stream x options)
+  (bytes->wrapped-out->bytes
+    x
     #(GzipCompressorOutputStream. %)
     options))

@@ -312,24 +337,36 @@

 (def-compressor snappy
   [x options]
-  (if (<= (bytes/conversion-cost x byte-array) (bytes/conversion-cost x (seq-of byte-array)))
+  (cond
+    (instance? byte-array x)
+    (Snappy/compress ^bytes x)
+
+    (<= (bytes/conversion-cost x byte-array) (bytes/conversion-cost x (seq-of byte-array)))
     (Snappy/compress (bytes/to-byte-array x options))
+
+    :else
     (map
       #(Snappy/compress ^bytes %)
       (bytes/to-byte-arrays x (update-in options [:chunk-size] #(or % 32278))))))

 (def-decompressor snappy
   [x options]
-  (if (<= (bytes/conversion-cost x byte-array) (bytes/conversion-cost x (seq-of byte-array)))
+  (cond
+    (instance? byte-array x)
+    (Snappy/uncompress x)
+
+    (<= (bytes/conversion-cost x byte-array) (bytes/conversion-cost x (seq-of byte-array)))
     (Snappy/uncompress (bytes/to-byte-array x options))
+
+    :else
     (map
       #(Snappy/uncompress ^bytes %)
       (bytes/to-byte-arrays x (update-in options [:chunk-size] #(or % 32278))))))

 (def-compressor bzip2
   [x options]
-  (in->wrapped-out->in
-    (bytes/to-input-stream x options)
+  (bytes->wrapped-out->bytes
+    x
     #(BZip2CompressorOutputStream. %)
     options))

@@ -343,8 +380,8 @@

 (def-compressor lzo
   [x options]
-  (in->wrapped-out->in
-    (bytes/to-input-stream x options)
+  (bytes->wrapped-out->bytes
+    x
     #(LzoOutputStream. %
        (-> (LzoLibrary/getInstance) (.newCompressor nil nil))
        (* 25 1024))


More lane tests.

More lane tests.

--- src/cbfg/lane-test.cljs
+++ src/cbfg/lane-test.cljs
@@ -24,12 +24,54 @@
              in-ch (achan actx)
              out-ch (achan actx)
              g (make-lane-pump tlp in-ch out-ch make-echo-lane)]
-         (if (and (do
-                    (aput tlp in-ch {:lane :a :x 1})
-                    (e n
-                       (atake tlp out-ch)
-                       [:a 0 {:lane :a :x 1}]
-                       nil)))
+         (if (and (do (aput tlp in-ch {:lane :a :op :hi :x 1})
+                      (e n
+                         (atake tlp out-ch)
+                         [:a 0 {:lane :a :op :hi :x 1}]
+                         nil))
+                  (do (aput tlp in-ch {:lane :b :x 2})
+                      (e n
+                         (atake tlp out-ch)
+                         [:b 0 {:lane :b :x 2}]
+                         nil))
+                  (do (aput tlp in-ch {:x 3})
+                      (e n
+                         (atake tlp out-ch)
+                         [nil 0 {:x 3}]
+                         nil))
+                  (do (aput tlp in-ch {:lane :a :x 10})
+                      (e n
+                         (atake tlp out-ch)
+                         [:a 1 {:lane :a :x 10}]
+                         nil))
+                  (do (aput tlp in-ch {:x 30})
+                      (e n
+                         (atake tlp out-ch)
+                         [nil 1 {:x 30}]
+                         nil))
+                  (do (aput tlp in-ch {:lane :x :op :close-lane})
+                      (e n
+                         (atake tlp out-ch)
+                         {:lane :x :op :close-lane :status :not-found}
+                         nil))
+                  (do (aput tlp in-ch {:lane :a :x 100})
+                      (e n
+                         (atake tlp out-ch)
+                         [:a 2 {:lane :a :x 100}]
+                         nil))
+                  (do (aput tlp in-ch {:lane :a :op :close-lane})
+                      (e n
+                         (atake tlp out-ch)
+                         {:lane :a :op :close-lane :status :ok}
+                         nil))
+                  (do (aput tlp in-ch {:lane :a :x 1000})
+                      (e n
+                         (atake tlp out-ch)
+                         [:a 0 {:lane :a :x 1000}]
+                         nil))
+                  (do (aclose tlp in-ch)
+                      (aclose tlp out-ch)
+                      true))
            "pass"
            (str "FAIL: on test-grouper #" @n)))))


remove -v2 output: not used by verbcoach anymore

--- src/babel/reader.clj
+++ src/babel/reader.clj
@@ -117,6 +117,8 @@
                                   " that matches spec: " target-spec))))

         ;; choose a random expression from the results of the above.
+        ;; TODO: should choose a random one using SQL rather than taking them
+        ;; all and choosing a random one
         (let [size-of-results (.size results)
               index-of-result (rand-int (.size results))
               debug (log/debug (str "number of target results:" size-of-results))
@@ -192,23 +194,7 @@
                                         (json-read-str (first (map :target_structure results)))))]
               {:source-id (first (map :source_id results))
                :source (first (map :source results))
-               :source-v2 {:language source-language
-                           :surface (first (map :source results))
-                           :locale source-locale}
                :target-spec target-spec
-               :targets-v2 (map (fn [result]
-                                  {:surface (get result :target)
-                                   :language target-language
-                                   :locale target-locale
-                                   :root (:target_root result)
-                                   :lexemes
-                                   (let [structure (json-read-str (:target_structure result))]
-                                     (remove nil?
-                                             [(get-in structure [:comp :italiano :italiano])
-                                              (get-in structure [:root :italiano :infinitive])
-                                              (get-in structure [:root :italiano :infinitive])
-                                              (get-in structure [:root :italiano :italiano])]))})
-                               results)
                :targets (map :target results)})))))))))

 (defn get-lexeme [canonical language & [ spec ]]


Cleanup commented out code.

Cleanup commented out code.

--- src/brute/entity.clj
+++ src/brute/entity.clj
@@ -30,16 +30,6 @@
             (assoc! :entity-component-types (-> system :entity-component-types (assoc entity #{})))
             persistent!)))

-#_
-(defn create-entity!
-    "Creates an entity and returns it. An entity is just an UUID"
-    []
-    (let (java.util.UUID/randomUUID)
-        (dosync
-            (alter all-entities conj entity)
-            (alter entity-component-types assoc entity #{}))
-        entity))
-
 (defmulti get-component-type
           "Returns the type for a given component. Using a multimethod with 'class' as the dispatch-fn to allow for extensibility per application.
           By default returns the class of the component."
@@ -62,25 +52,10 @@
             (assoc! :entity-component-types (assoc ects entity (-> ects (get entity) (conj type))))
             persistent!)))

-#_
-(defn add-component!
-    "Add a component instance to a given entity. Will overwrite a component if already set."
-    [entity instance]
-    (dosync
-        (let [type (get-component-type instance)]
-            (alter entity-components assoc-in [type entity] instance)
-            (alter entity-component-types assoc entity (conj (get @entity-component-types entity) type)))))
-
 (defn get-component
     "Get the component data for a specific component type"
     [system entity type]
     (-> system :entity-components (get-in [type entity])))
-
-#_
-(defn get-component
-    "Get the component data for a specific component type"
-    [entity type]
-    (get-in @entity-components [type entity]))

 (defn get-all-entities-with-component
     "Get all the entities that have a given component type"
@@ -101,20 +76,6 @@
             (assoc! :entity-component-types (assoc entity-component-types entity (-> entity-component-types (get entity) (disj type))))
             persistent!)))

-#_
-(defn remove-component!
-    "Remove a component instance from an entity"
-    [entity instance]
-    (let [type (get-component-type instance)]
-        (dosync
-            (alter entity-components assoc type (dissoc (get @entity-components type) entity))
-            (alter entity-component-types assoc entity (disj (get @entity-component-types entity) type)))))
-
-#_
-(reduce (fn [v e]
-            (assoc v e (dissoc (get v e) :e)))
-        m k)
-
 (defn kill-entity
     "Destroy an entity completely."
     [system entity]
@@ -127,17 +88,6 @@
                                                             (transient (:entity-components system)) (get entity-component-types entity))))
             persistent!)))

-#_
-(defn kill-entity!
-    "Destroy an entity completely."
-    [entity]
-    (dosync
-        (let [component-types (get @entity-component-types entity)]
-            (alter all-entities disj entity)
-            (alter entity-component-types dissoc entity)
-            (doseq [type component-types]
-                (alter entity-components assoc type (dissoc (get @entity-components type) entity))))))
-
 (defn get-all-components-on-entity
     "Get all the components on a specific entity. Useful for debugging"
     [system entity]


for non-pom files just write them w/o slurping

--- src/clojars/repo.clj
+++ src/clojars/repo.clj
@@ -10,11 +10,11 @@
             [ring.util.response :as response])
   (:import java.io.StringReader))

-(defn save-to-file [sent-file body]
+(defn save-to-file [sent-file input]
   (-> sent-file
       .getParentFile
       .mkdirs)
-  (spit sent-file body))
+  (io/copy input sent-file))

 (defroutes routes
   (PUT ["/:group/:artifact/:file"
@@ -24,7 +24,7 @@
          (authorized!
           (string/replace group "/" ".")
           (save-to-file (io/file (config :repo) group artifact file)
-                        (slurp body))
+                        body)
           {:status 201 :headers {} :body nil})))
   (PUT ["/:group/:artifact/:version/:file"
         :group #".+" :artifact #"[^/]+" :version #"[^/]+" :file #"[^/]+"]
@@ -33,8 +33,8 @@
          (with-account
            (authorized!
             (string/replace group "/" ".")
-            (let [contents (slurp body)]
-              (if (.endsWith file ".pom")
+            (if (.endsWith file ".pom")
+              (let [contents (slurp body)]
                 (if (find-jar groupname artifact version)
                   (update-jar account
                               (merge
@@ -47,12 +47,15 @@
                                     {:group groupname
                                      :name  artifact
                                      :version version})))
+                (save-to-file (io/file (config :repo) group artifact version file)
+                              contents))
+              (do
                 (when-not (find-jar groupname artifact version)
                   (add-jar account  {:group groupname
                                      :name  artifact
-                                     :version version})))
-              (save-to-file (io/file (config :repo) group artifact version file)
-                            contents))
+                                     :version version}))
+                (save-to-file (io/file (config :repo) group artifact version file)
+                              body)))
             {:status 201 :headers {} :body nil})))))

 (defn wrap-file-at [app dir prefix]


Removing storage from colors dashboard

Removing storage from colors dashboard

--- frontend/src/uxbox/main/ui/dashboard/colors.cljs
+++ frontend/src/uxbox/main/ui/dashboard/colors.cljs
@@ -80,7 +80,7 @@
              {:on-double-click edit}
              (:name coll)]
             [:span.dashboard-title-field
-             (:name coll "Storage")]))]
+             (:name coll)]))]
        (when (and own? coll)
          [:div.edition
           (if edit?
@@ -121,29 +121,13 @@
        (if (:edit @local)
          [:div
           [:input.element-title
-            {:value (if (:name @local) (:name @local) (if coll name "Storage"))
+            {:value (if (:name @local) (:name @local) name)
              :on-change on-input-change
              :on-key-down on-input-keyup}]
           [:span.close {:on-click on-cancel} i/close]]
-         [:span.element-title
-          (if coll name "Storage")])
+         [:span.element-title name])
        [:span.element-subtitle
         (tr "ds.num-elements" (t/c colors))]])))
-
-(def ^:private storage-num-colors-ref
-  (-> (comp (l/in [:colors-collections nil :colors])
-            (l/lens count))
-      (l/derive st/state)))
-
-(mx/defc nav-item-storage
-  {:mixins [mx/static mx/reactive]}
-  [selected?]
-  (let [num-colors (mx/react storage-num-colors-ref)
-        on-click #(st/emit! (dc/select-collection :own nil))]
-    [:li {:on-click on-click :class (when selected? "current")}
-     [:span.element-title "Storage"]
-     [:span.element-subtitle
-      (tr "ds.num-elements" (t/c num-colors))]]))

 (mx/defc nav-section
   {:mixins [mx/static]}
@@ -161,8 +145,6 @@
         [:a.btn-primary
          {:on-click #(st/emit! (dc/create-collection))}
          "+ New library"]])
-     (when own?
-       (nav-item-storage (nil? selected)))
      (for [coll colls
            :let [selected? (= (:id coll) selected)
                  key (str (:id coll))]]
@@ -220,7 +202,6 @@
                     (on-select id))]
     [:ul.move-list
      [:li.title title]
-     [:li [:a {:href "#" :on-click #(on-select % nil)} "Storage"]]
      (for [coll colls
            :let [id (:id coll)
                  name (:name coll)]]


Update copyright of RPM

Update copyright of RPM

--- src/leiningen/new/cljskel/project.clj
+++ src/leiningen/new/cljskel/project.clj
@@ -59,7 +59,7 @@

   :rpm {:name "{{lower-name}}"
         :summary "RPM for {{upper-name}} service"
-        :copyright "Microsoft {{year}}"
+        :copyright "MixRadio {{year}}"
         :preinstall {:scriptFile "scripts/rpm/preinstall.sh"}
         :postinstall {:scriptFile "scripts/rpm/postinstall.sh"}
         :preremove {:scriptFile "scripts/rpm/preremove.sh"}


DXML-9: Eliminate one instance of reflection via a type hint

Signed-off-by: Ryan Senior <f1d27374ad67c65ad142d03675bbdd3b80b82f07@gmail.com>

--- src/main/clojure/clojure/data/xml.clj
+++ src/main/clojure/clojure/data/xml.clj
@@ -291,6 +291,10 @@
    and xml-input-factory-props for more information. Defaults coalescing true."
   [s & {:as props}]
   (let [fac (new-xml-input-factory (merge {:coalescing true} props))
+        ;; Reflection on following line cannot be eliminated via a
+        ;; type hint, because s is advertised by fn parse to be an
+        ;; InputStream or Reader, and there are different
+        ;; createXMLStreamReader signatures for each of those types.
         sreader (.createXMLStreamReader fac s)]
     (pull-seq sreader)))

@@ -344,7 +348,7 @@
     (emit e sw)
     (.toString sw)))

-(defn indenting-transformer []
+(defn ^javax.xml.transform.Transformer indenting-transformer []
   (doto (-> (javax.xml.transform.TransformerFactory/newInstance) .newTransformer)
     (.setOutputProperty (javax.xml.transform.OutputKeys/INDENT) "yes")
     (.setOutputProperty (javax.xml.transform.OutputKeys/METHOD) "xml")


clean code

clean code

Signed-off-by: Yen-Chin Lee <082d453d72dce940e12089a4ad48b97cfe1f3ec4@gmail.com>

--- src/cljs/chip8/cpu.cljs
+++ src/cljs/chip8/cpu.cljs
@@ -80,6 +80,10 @@
   [state st]
   (assoc-in state [:cpu :st] st))

+(defn- update-draw-flag
+  [state draw-flag]
+  (assoc-in state [:cpu :draw-flag] draw-flag))
+
 (defn- update-stack
   ([{{:keys [stack]} :cpu :as state} idx val]
    (update-stack state (assoc stack idx val)))
@@ -164,6 +168,7 @@
   (-> state
       (update-memory (vec rom) 0x200)))

+;; FIXME:
 (defn opcode-00E0
   "Clear the screen. This function will also set draw-flag to 1
   to make canvas function refresh."
@@ -171,7 +176,8 @@
   (-> state
       (assoc :screen (screen/make-screen))
       (assoc-in [:cpu :draw-flag] 1)
-      (assoc-in [:cpu :pc] 2)))
+      (update-draw-flag 1)
+      (update-pc 2)))

 (defn opcode-00EE
   "Return from a subroutine."


cleanup PersistentArrayMap perf enhancements

--- src/cljs/cljs/core.cljs
+++ src/cljs/cljs/core.cljs
@@ -3870,21 +3870,15 @@

 ;;; PersistentArrayMap

-(defn equiv-nil [k k']
+(defn- equiv-nil [k k']
   (nil? k'))

-(defn equiv-identical [k k']
-  (identical? k k'))
-
-(defn equiv-default [k k']
-  (= k k'))
-
-(defn equiv-pred [x]
+(defn- equiv-pred [x]
   (cond
-    ^boolean (goog/isString x) equiv-identical
+    ^boolean (goog/isString x) identical?
     (nil? x) equiv-nil
-    (number? x) equiv-identical
-    :else equiv-default))
+    (number? x) identical?
+    :else =))

 (defn- array-map-index-of [m k]
   (let [arr  (.-arr m)
@@ -3896,9 +3890,7 @@
         ^boolean (pred k (aget arr i)) i
         :else (recur (+ i 2))))))

-(declare TransientArrayMap)
-
-(defn array-extend-kv [arr k v]
+(defn- array-extend-kv [arr k v]
   (let [l (alength arr)
         narr (make-array (+ l 2))]
     (loop [i 0]
@@ -3908,6 +3900,8 @@
     (aset narr l k)
     (aset narr (inc l) v)
     narr))
+
+(declare TransientArrayMap)

 (deftype PersistentArrayMap [meta cnt arr ^:mutable __hash]
   Object


Prints strings correctly via println.

Prints strings correctly via println.

--- src/cljs/cljs/core.cljs
+++ src/cljs/cljs/core.cljs
@@ -2111,9 +2111,7 @@
      (list (str (when-let [nspc (namespace obj)]
                   (str nspc "/"))
                 (name obj)))
-     (get opts :readably)
-     (list (goog.string.quote obj))
-     :else (list obj)))
+     :else (list (goog.string.quote obj))))

   LazySeq
   (-pr-seq [coll opts] (pr-sequential pr-seq "(" " " ")" opts coll))


* src/cljs/cljs/core.cljs: double perf of next on lists

--- src/cljs/cljs/core.cljs
+++ src/cljs/cljs/core.cljs
@@ -1408,7 +1408,10 @@
   ASeq
   ISeq
   (-first [coll] first)
-  (-rest [coll] rest)
+  (-rest [coll]
+    (if (== count 1)
+      nil
+      rest))

   IStack
   (-peek [coll] first)


move seq and rest to eliminate some declaration warnings.

--- src/cljs/cljs/core.cljs
+++ src/cljs/cljs/core.cljs
@@ -308,6 +308,16 @@

 ;;;;;;;;;;;;;;;;;;; fundamentals ;;;;;;;;;;;;;;;

+(defn ^seq seq
+  "Returns a seq on the collection. If the collection is
+  empty, returns nil.  (seq nil) returns nil. seq also works on
+  Strings."
+  [coll]
+  (when-not (nil? coll)
+    (if (satisfies? ASeq coll)
+      coll
+      (-seq coll))))
+
 (defn first
   "Returns the first item in the collection. Calls seq on its
   argument. If coll is nil, returns nil."
@@ -318,6 +328,19 @@
       (let [s (seq coll)]
         (when-not (nil? s)
           (-first s))))))
+
+(defn ^seq rest
+  "Returns a possibly empty seq of the items after the first. Calls seq on its
+  argument."
+  [coll]
+  (if-not (nil? coll)
+    (if (satisfies? ISeq coll)
+      (-rest coll)
+      (let [s (seq coll)]
+        (if-not (nil? s)
+          (-rest s)
+          ())))
+    ()))

 (defn ^seq next
   "Returns a seq of the items after the first. Calls seq on its
@@ -671,30 +694,6 @@

   IHash
   (-hash [coll] (hash-coll coll)))
-
-(defn ^seq seq
-  "Returns a seq on the collection. If the collection is
-  empty, returns nil.  (seq nil) returns nil. seq also works on
-  Strings."
-  [coll]
-  (when-not (nil? coll)
-    (if (satisfies? ASeq coll)
-      coll
-      (-seq coll))))
-
-
-(defn ^seq rest
-  "Returns a possibly empty seq of the items after the first. Calls seq on its
-  argument."
-  [coll]
-  (if-not (nil? coll)
-    (if (satisfies? ISeq coll)
-      (-rest coll)
-      (let [s (seq coll)]
-        (if-not (nil? s)
-          (-rest s)
-          ())))
-    ()))

 (defn second
   "Same as (first (next x))"


CLJS-820: Missing invoke without arguments in MetaFn

--- src/cljs/cljs/core.cljs
+++ src/cljs/cljs/core.cljs
@@ -1209,6 +1209,8 @@
     (MetaFn. afn new-meta))
   Fn
   IFn
+  (-invoke [_]
+    (afn))
   (-invoke [_ a]
     (afn a))
   (-invoke [_ a b]


pluggable reporting based on keywords. remove ITestReporter, DefaultReporter etc.

--- src/cljs/cljs/test.cljs
+++ src/cljs/cljs/test.cljs
@@ -226,12 +226,6 @@
   cljs.test
   (:require-macros
    [clojure.template :as temp]))
-
-;; =============================================================================
-;; Protocols
-
-(defprotocol ITestReporter
-  (-do-report [_ env m]))

 ;; =============================================================================
 ;; Default Reporting
@@ -266,15 +260,15 @@
    'is' call 'report' to indicate results.  The argument given to
    'report' will be a map with a :type key."
      :dynamic true}
-  report (fn [_ m] (:type m)))
+  report (fn [env m] [(:reporter env) (:type m)]))

 (defmethod report :default [env m]
   (prn m))

-(defmethod report :pass [env m]
+(defmethod report [::default :pass] [env m]
   (inc-report-counter env :pass))

-(defmethod report :fail [env m]
+(defmethod report [::default :fail] [env m]
   (println "\nFAIL in" (testing-vars-str env m))
   (when (seq (:testing-contexts env))
     (println (testing-contexts-str env)))
@@ -283,7 +277,7 @@
   (println "  actual:" (pr-str (:actual m)))
   (inc-report-counter env :fail))

-(defmethod report :error [env m]
+(defmethod report [::default :error] [env m]
   (println "\nERROR in" (testing-vars-str env m))
   (when (seq (:testing-contexts env))
     (println (testing-contexts-str env)))
@@ -292,28 +286,20 @@
   (print "  actual: ") (prn (:actual m))
   (inc-report-counter env :error))

-(defmethod report :summary [env m]
+(defmethod report [::default :summary] [env m]
   (println "\nRan" (:test m) "tests containing"
     (+ (:pass m) (:fail m) (:error m)) "assertions.")
   (println (:fail m) "failures," (:error m) "errors.")
   env)

-(defmethod report :begin-test-ns [env m]
+(defmethod report [::default :begin-test-ns] [env m]
   (println "\nTesting" (name (:ns m)))
   env)

 ;; Ignore these message types:
-(defmethod report :end-test-ns [env m] env)
-(defmethod report :begin-test-var [env m] env)
-(defmethod report :end-test-var [env m] env)
-
-(deftype DefaultReporter []
-  ITestReporter
-  (-do-report [_ env m]
-    (report env m)))
-
-(defn default-reporter []
-  (DefaultReporter.))
+(defmethod report [::default :end-test-ns] [env m] env)
+(defmethod report [::default :begin-test-var] [env m] env)
+(defmethod report [::default :end-test-var] [env m] env)

 (defn file-and-line
   [exception depth]
@@ -329,10 +315,10 @@
             :fail (merge (file-and-line (js/Error.) 1) m)
             :error (merge (file-and-line (:actual m) 0) m)
             m)]
-   (-do-report (:reporter env) env m)))
+   (report env m)))

 (defn empty-env
-  ([] (empty-env (default-reporter)))
+  ([] (empty-env ::default))
   ([reporter]
    {:report-counters {:test 0 :pass 0 :fail 0 :error 0}
     :testing-vars ()


Add support for Trigonometry functions.

Add support for Trigonometry functions.

--- src/cljx/quil/core.cljx
+++ src/cljx/quil/core.cljx
@@ -219,7 +219,6 @@
     #+cljs
     (.abs (current-applet) n))

-#+clj
 (defn
   ^{:requires-bindings false
     :processing-name "acos()"
@@ -231,7 +230,8 @@
   function expects the values in the range of -1 to 1 and values are
   returned in the range 0 to Math/PI (3.1415927)."
   [n]
-  (PApplet/acos (float n)))
+  #+clj (PApplet/acos (float n))
+  #+cljs (.acos (current-applet) n))

 #+clj
 (defn
@@ -365,7 +365,6 @@
       (.arc (current-applet) (float x) (float y) (float width) (float height)
         (float start) (float stop) (int arc-mode)))))

-#+clj
 (defn
   ^{:requires-bindings false
     :processing-name "asin()"
@@ -377,9 +376,9 @@
   expects the values in the range of -1 to 1 and values are returned
   in the range -PI/2 to PI/2."
   [n]
-  (PApplet/asin (float n)))
-
-#+clj
+  #+clj (PApplet/asin (float n))
+  #+cljs (.asin (current-applet) n))
+
 (defn
   ^{:requires-bindings false
     :processing-name "atan()"
@@ -392,9 +391,9 @@
   Infinity (exclusive) and values are returned in the range -PI/2 to
   PI/2 ."
   [n]
-  (PApplet/atan (float n)))
-
-#+clj
+  #+clj (PApplet/atan (float n))
+  #+cljs (.atan (current-applet) n))
+
 (defn
   ^{:requires-bindings false
     :processing-name "atan2()"
@@ -410,7 +409,8 @@
   and the x-coordinate is the second due the the structure of
   calculating the tangent."
   [y x]
-  (PApplet/atan2 (float y) (float x)))
+  #+clj (PApplet/atan2 (float y) (float x))
+  #+cljs (.atan2 (current-applet) y x))

 #+clj
 (defn
@@ -1026,7 +1026,6 @@
      (.copy dest-img src-img (int sx) (int sy) (int swidth) (int sheight)
             (int dx) (int dy) (int dwidth) (int dheight))))

-#+clj
 (defn
   ^{:requires-bindings false
     :processing-name "cos()"
@@ -1038,7 +1037,8 @@
   of the angle parameter to be provided in radians (values from 0 to
   Math/PI*2). Values are returned in the range -1 to 1."
   [angle]
-  (PApplet/cos (float angle)))
+  #+clj (PApplet/cos (float angle))
+  #+cljs (.cos (current-applet) angle))

 #+clj
 (defn
@@ -1331,7 +1331,6 @@
   []
   (PApplet/day))

-#+clj
 (defn
   ^{:requires-bindings false
     :processing-name "degrees()"
@@ -1346,7 +1345,8 @@
   trigonometric methods in Processing require their parameters to be
   specified in radians."
   [radians]
-  (PApplet/degrees (float radians)))
+  #+clj (PApplet/degrees (float radians))
+  #+cljs (.degrees (current-applet) radians))

 (defn
   ^{:requires-bindings true
@@ -2937,7 +2937,6 @@
   ([cx cy cz x3 y3 z3]
    (.quadraticVertex (current-graphics) (float cx) (float cy) (float cz) (float x3) (float y3) (float z3))))

-#+clj
 (defn
   ^{:requires-bindings false
     :processing-name "radians()"
@@ -2952,7 +2951,8 @@
   methods in Processing require their parameters to be specified in
   radians."
   [degrees]
-  (PApplet/radians (float degrees)))
+  #+clj (PApplet/radians (float degrees))
+  #+cljs (.radians (current-applet) degrees))

 (defn
   ^{:requires-bindings true
@@ -3603,7 +3603,6 @@
   [shine]
   (.shininess (current-graphics) (float shine)))

-#+clj
 (defn
   ^{:requires-bindings false
     :processing-name "sin()"
@@ -3615,7 +3614,8 @@
   of the angle parameter to be provided in radians (values from 0 to
   6.28). A float within the range -1 to 1 is returned."
   [angle]
-  (PApplet/sin (float angle)))
+  #+clj (PApplet/sin (float angle))
+  #+cljs (.sin (current-applet) angle))

 (defn
   ^{:requires-bindings true
@@ -3844,7 +3844,6 @@
   [weight]
   (.strokeWeight (current-graphics) (float weight)))

-#+clj
 (defn
   ^{:requires-bindings false
     :processing-name "tan()"
@@ -3857,7 +3856,8 @@
   radians (values from 0 to PI*2). Values are returned in the range
   infinity to -infinity."
   [angle]
-  (PApplet/tan (float angle)))
+  #+clj (PApplet/tan (float angle))
+  #+cljs (.tan (current-applet) angle))

 #+clj
 (defn