R O T A T I O N B O Y S

R O T A T I O N B O Y S

--- src/kushana/core.cljs
+++ src/kushana/core.cljs
@@ -17,7 +17,8 @@
       :name "sphere1"
       :segments 16
       :diameter 2
-      :position (v3 0 1 0)}
+      :position (v3 0 1 0)
+      :timer 0}
      {:component :mesh/ground
       :name "ground1"
       :width 6
@@ -34,12 +35,16 @@
       :reload-scene  input-args
       :reload-logic  (assoc scene :update-fn  input-args)
       :none          (let [[sid sphere] (->name scene-graph "sphere1")
-                           old-pos (:x (:position sphere))
-                           new-pos [(inc old-pos) 0 0]
-                           new-sphere (assoc sphere :position new-pos)
-                           new-graph (assoc scene-graph sid new-sphere)]
-                       (println scene)
-                       (assoc scene :scene-graph scene-graph))))
+                           {t :timer {y :y} :position} sphere
+                           new-pos (v3 (* 3 (.sin js/Math (/ t 10)))
+                                       y
+                                       (* 3 (.cos js/Math (/ t 10))))
+                           new-sphere (-> sphere
+                                          (assoc :position new-pos)
+                                          (assoc :timer (inc t)))
+                           new-graph (assoc scene-graph sid new-sphere)
+                           new-scene (assoc scene :scene-graph new-graph)]
+                       new-scene)))
   :clearColor (c3 0.2 0.4 0.5))

 (defonce scene-atom (atom scene))
@@ -52,5 +57,5 @@
    :antialias true
    :resize    true))

-(defn on-jsload [] (put! engine [:reload-logic (:update-fn scene)]))
+(defn on-jsload [] (put! engine [:reload-scene scene]))


Better search logic for source-paths

Better search logic for source-paths

Only search for files in source-paths for local files

--- src/less4clj/core.clj
+++ src/less4clj/core.clj
@@ -62,16 +62,17 @@
     (.toByteArray out)))

 (defn custom-less-source
-  [source-paths uri parent]
+  [source-paths type uri parent]
   (proxy [LessSource] []
     (relativeSource ^LessSource [^String import-filename]
       (util/dbug "importing %s at %s\n" import-filename parent)
-      (if-let [[uri parent]
-               (or (find-local-file import-filename parent)
-                   (some #(find-local-file import-filename %) source-paths)
-                   (find-resource import-filename parent)
-                   (find-webjars import-filename))]
-        (custom-less-source source-paths uri parent)
+      (if-let [[uri parent type]
+               (or (some-> (or (find-local-file import-filename parent)
+                               ; Don't search from other source-paths if looking for import from resource
+                               (and (= type :file) (some #(find-local-file import-filename %) source-paths))) (conj :file))
+                   (some-> (or (find-resource import-filename parent)
+                               (find-webjars import-filename)) (conj :resource)))]
+        (custom-less-source source-paths type uri parent)
         (not-found!)))
     (getContent ^String []
       (try
@@ -108,7 +109,7 @@
     (try
       (let [result (-> (DefaultLessCompiler.)
                        (.compile
-                         (custom-less-source source-paths (.toURI input-file) (.getParent input-file))
+                         (custom-less-source source-paths :file (.toURI input-file) (.getParent input-file))
                          (build-configuration options)))]
         (spit output-file (.getCss result))
         (when source-map (spit source-map-output (.getSourceMap result)))


Fix package.json path.

Fix package.json path.

--- src/lexemic/core.cljs
+++ src/lexemic/core.cljs
@@ -3,7 +3,7 @@
             [lexemic.sentiment.simple :as sentiment]))

 (def ^:private version
-  (.-version (node/require "./package.json")))
+  (.-version (node/require "../package.json")))
 (def ^:private fs
   (node/require "fs"))


running render loop, doesn't handle context

--- src-cljs/hello.cljs
+++ src-cljs/hello.cljs
@@ -4,12 +4,20 @@
 (defn create-canvas []
   (let [width (aget js/window "innerWidth")
         height (aget js/window "innerHeight")
-        canvas (js/document.createElement "canvas")]
+        canvas (.createElement js/document "canvas")]
     (aset canvas "width" width)
     (aset canvas "height" height)
-    (js/document.body.appendChild canvas)
+    (.appendChild js/document.body canvas)
     (.getContext canvas "2d")))
+
+(defn render []
+  (.log js/console "frame"))
+
+(defn animate []
+  (render)
+  (.requestAnimationFrame js/window animate))

 (defn ^:export main []
   (let [context (create-canvas)]
-    (.fillRect context 10 10 200 200)))
+    (.fillRect context 10 10 200 200)
+    (animate)))


Fix this variable reference in tab-menu-items

--- src/lt/objs/tabs.cljs
+++ src/lt/objs/tabs.cljs
@@ -87,10 +87,10 @@
                       (conj items
                             {:label "Move tab to new tabset"
                              :order 1
-                             :click (fn [] (cmd/exec! :tabs.move-new-tabset obj))}
+                             :click (fn [] (cmd/exec! :tabs.move-new-tabset this))}
                             {:label "Close tab"
                              :order 2
-                             :click (fn [] (object/raise obj :close))})))
+                             :click (fn [] (object/raise this :close))})))

 (defn ->index [obj]
   (when (and obj @obj (::tabset @obj))


Show jobs as 'waiting to run' if we're waiting for another job to finish.

--- src/marcgrep/core.clj
+++ src/marcgrep/core.clj
@@ -227,10 +227,12 @@
     (while (>= (count (filter (complement future-done?) current-jobs))
                (:max-concurrent-jobs @config))
       ;; sit around and wait for a job to finish
+      (doseq [job (filter #(= (:status @%) :not-started) @job-queue)]
+        (swap! job assoc :status :waiting))
       (Thread/sleep 5000))

     ;; Snapshot the job queue and mark those jobs as running
-    (when-let [jobs (seq (filter #(= (:status @%) :not-started)
+    (when-let [jobs (seq (filter #(#{:not-started :waiting} (:status @%))
                                  @job-queue))]
       (doseq [job jobs] (swap! job assoc :status :running))

@@ -275,6 +277,7 @@

 (def status-text {:not-started "Not started"
+                  :waiting "Waiting to run"
                   :running "Running"
                   :completed "Finished!"})


update make-template-output-filename

update make-template-output-filename

--- src/misaki/config.clj
+++ src/misaki/config.clj
@@ -155,26 +155,9 @@
   [#^String tag-name]
   (str *tag-out-dir* tag-name ".html"))

-; =make-template-output-filename
-(defmulti make-template-output-filename class)
-(defmethod make-template-output-filename String
-  [tmpl-name]
-  (make-template-output-filename (template-name->file tmpl-name)))
-
-(defmethod make-template-output-filename File
-;  "Make template output filename from template name"
-  [file]
-  (let [date (get-date-from-file file)
-        filename (-?> (.getName file) remove-date-from-name delete-extension)]
-    (if (post-file? file)
-      (render *post-filename-format*
-              {:year (-> date year str)
-               :month (->> date month (format "%02d"))
-               :day (->> date day (format "%02d"))
-               :filename filename})
-      (delete-extension (.getName file)))))
-
+; =make-post-output-filename
 (defn make-post-output-filename
+  "Make post output filename from java.io.File"
   [#^File file]
   (let [date (get-date-from-file file)
         filename (-?> (.getName file) remove-date-from-name delete-extension)]
@@ -184,9 +167,24 @@
              :day (->> date day (format "%02d"))
              :filename filename})))

+; =make-template-output-filename
+(defmulti make-template-output-filename
+  "Make template output filename from template name"
+  class)
+
+(defmethod make-template-output-filename String
+  [tmpl-name]
+  (make-template-output-filename (template-name->file tmpl-name)))
+
+(defmethod make-template-output-filename File
+  [file]
+  (if (post-file? file)
+    (make-post-output-filename file)
+    (delete-extension (.getName file))))
+
 ; =make-post-url
 (defn make-post-url
-  "Make post url from file(java.io.File)"
+  "Make post url from java.io.File"
   [#^File file]
   (str "/" (make-template-output-filename file)))


remove debug vcr statement

remove debug vcr statement

--- src/parinfer/vcr.cljs
+++ src/parinfer/vcr.cljs
@@ -83,8 +83,7 @@
   (when-let [stop-chan (get-in @vcr [key- :stop-chan])]
     (close! stop-chan))
   (swap! vcr assoc-in [key- :stop-chan] (chan))
-  (let [show? (= key- :warn-good)
-        cm (get-in @state [key- :cm])
+  (let [cm (get-in @state [key- :cm])
         recording (get @vcr key-)
         timescale (get recording :timescale 1)
         loop? (get recording :loop? true)
@@ -93,29 +92,24 @@
         cursor (gdom/getElementByClass "CodeMirror-cursors" element)]
     (set! (.. cursor -style -visibility) "visible")
     (go-loop []
-      (when show? (println "resetting"))
       (swap! state assoc-in [key- :text] (:init-value recording))
       (loop [changes (:changes recording)]
         (when (seq changes)
           (let [{:keys [change selections dt] :as data} (first changes)
-                _ (when show? (println "waiting for" dt))
                 tchan (timeout (/ dt timescale))
                 stop-chan (:stop-chan recording)
                 [v c] (alts! [tchan stop-chan])]
             (when (not= c stop-chan)
-              (when show? (println "applying change."))
               (cond
                 change (apply-change cm change)
                 selections (apply-selections cm selections)
                 :else nil)
               (recur (rest changes))))))
       (when loop?
-        (when show? (println "restarting in" loop-delay))
         (let [tchan (timeout loop-delay)
               stop-chan (:stop-chan recording)
               [v c] (alts! [tchan stop-chan])]
           (when (not= c stop-chan)
-            (when show? (println "restarting!"))
             (recur)))))))

 (defn stop-playing!


Make display protocol wording a little more generic.

--- src/org/playasophy/wonderdome/display.clj
+++ src/org/playasophy/wonderdome/display.clj
@@ -6,6 +6,6 @@

   (set-colors!
     [display colors]
-    "Sets the color of the pixels in the display. The colors should be a vector
-    of strips, where each strip is a vector of colors to set at each pixel
-    index (or nil to leave the color unchanged)."))
+    "Sets the color of the pixels in the display. The colors should be a
+    sequence of strips, where each strip is a sequence of colors to set at each
+    pixel index (or nil to leave the color unchanged)."))


improved UI

improved UI

--- src/penjat/views.cljs
+++ src/penjat/views.cljs
@@ -50,13 +50,12 @@
       []
       (let [letters (clojure.string/join " "
                                          (map #(if (contains? @guesses %) % "_") @word))]
-        [:div
-         (str "guesses: " letters)]))))
+        [:div.new-todo letters]))))

 (defn missed-letters
   [misses]
-  [:div (str "misses:" (apply str (interpose ","  misses)))])
+  [:div.new-todo (apply str (interpose ","  misses))])

 (defn gallow
@@ -96,8 +95,8 @@
     (fn play-page-render
       []
       [:div
+       [guessed-letters]
        [key-input]
-       [guessed-letters]
        [gallow]
        [missed-letters @misses]])))


Break synth init out into its own function

--- src/playmary/one.cljs
+++ src/playmary/one.cljs
@@ -163,13 +163,17 @@
     (or (and f-instrument (f-instrument instrument event))
         instrument)))

+(defn maybe-init-synths
+  [instrument]
+  (if (:sound-ready instrument)
+    instrument
+    (add-synths-to-instrument instrument)))
+
 (defn fire-touch-data-on-instrument
   [instrument data]
-  (if (-> instrument :sound-ready)
-    (reduce fire-event-on-instrument
-            instrument
-            (touch-data->touches data))
-    (recur (add-synths-to-instrument instrument) data)))
+  (reduce fire-event-on-instrument
+          (maybe-init-synths instrument)
+          (touch-data->touches data)))

 (defn update-size [instrument canvas-id]
   (let [{w :w h :h :as window-size} (util/get-window-size)]


Use   for spaces

Use   for spaces

--- src/text_justification/core.cljs
+++ src/text_justification/core.cljs
@@ -1,11 +1,12 @@
 (ns ^:figwheel-always text-justification.core
     (:require [reagent.core :as reagent :refer [atom]]
-              [goog.dom :as dom]))
+              [goog.dom :as dom]
+              [goog.string :as gstring]))

 (enable-console-print!)

-(defonce text-id "text")
 (defonce page-width 11)
+(defonce space-char (gstring/unescapeEntities " ")) ;; \u00A0 ?
 (defonce target-el (dom/getElement "justified-text"))

 (defn get-text-el []
@@ -47,14 +48,14 @@
     spaces_per_break_f (float (/ chars_left (dec str_len)))
     spaces_per_break_i (int spaces_per_break_f)
     extra_space_every_X_words (/ 1 (- spaces_per_break_f spaces_per_break_i))]
-    ; (if (> char_count max_width)
+    ; (if (> char_count max_width) ;; TODO restore this
       ; (throw (Exception. "Could not stretch string, it is already too long")))
     (second (reduce (fn [acc e] ;; run reduce and take second component
       (let [ word_id (first acc) res (second acc)
         space_count (if (>= word_id str_len) 0 ;; last word TODO add some padding here if needed -> (test ["b" "l" "e" "h"] 11)
           (+ spaces_per_break_i
             (if (== (mod word_id extra_space_every_X_words) 0) 1 0))) ;; add extra space every X words
-        spaces (apply str (repeat space_count "_"))]
+        spaces (apply str (repeat space_count space-char))]
         [(inc word_id) (str res e spaces)]))
       [1 ""] line))
 ))
@@ -62,17 +63,20 @@

 (defn execute []
   (.log js/console "Execute !!!")
-  (set! (.-innerHtml target-el) "") ;; clear
+  (dom/removeChildren target-el)
+
   (let [strs (seq (.split (get-text) #" "))
     justified_lines (second (text_justification strs page-width))]
-    ; (print justified_lines)
+    ;;(print ">>" justified_lines)
+    ;;(print "<<" strs)
     (doseq [line_strs justified_lines]
       (let [line (stretch_string line_strs page-width)
         el (.createElement js/document "div")]
         (println "line:" line)
         (.appendChild target-el el)
         (set! (.-innerText el) line)
-        ))))
+        )))
+  )

 ;; remove listeners from text area
@@ -81,15 +85,18 @@
   )

 ;; add keyup listner to text-el
- (.addEventListener (get-text-el) "keyup" (fn []
+ (.addEventListener (get-text-el) "keyup" (fn [] ;; TODO only characters, not f.e. arrows
   (execute)
   ))

-
+(execute)

 (comment
+
+
+
 (defn render-query [results]
   (str
     "<ul>"


Remove extra code from android/core

Remove extra code from android/core

--- src/trustroots/android/core.cljs
+++ src/trustroots/android/core.cljs
@@ -34,7 +34,6 @@
       ;;                   :on-icon-press (fn [_]
       ;;                                 (.openDrawer @drawer))}]
       (case name
-        ; ":inbox"        [inbox-page  {:style (get-in s/styles [:pages :main])}]
         ":inbox"        [inbox-page  {:style (get-in s/styles [:pages :main])}]
         ":conversation" [conversation-page  {:style (get-in s/styles [:pages :main])}]
         ":login"        [login-page {:style (get-in s/styles [:pages :login])}])]))


Fix --help with no arguments

Fix --help with no arguments

--- src/bltool/core.clj
+++ src/bltool/core.clj
@@ -98,11 +98,10 @@
 (t/ann -main [(t/Vec String) -> Nothing])
 (defn -main
   [& argv]
-  (let [[opts args _] (getopts argv)
-        command (if (:help opts) "help" (first args))]
+  (let [[opts args _] (getopts argv)]
     (binding [*opts* (resolve-io opts)]
       (try+
-        (if (:help opts)
+        (if (contains? opts :help)
           (show-help (:help opts))
           (execute))
         (catch String _


Rename with-resource to with-kept and clean up

--- src/reagent/ratom.clj
+++ src/reagent/ratom.clj
@@ -13,34 +13,29 @@
      (deref co#)
      co#))

-(defmacro with-resource [bindings & body]
+(defmacro with-kept [bindings & body]
   (assert (vector? bindings))
-  (let [v (gensym "res-v")
-        init (gensym "res-init-v")
-        bs (into [] (map-indexed (fn [i x]
-                                   (if (even? i)
-                                     x
-                                     (let [pos (-> (/ i 2) int)]
-                                       `(if ~init
-                                          (aget ~v ~pos)
-                                          (aset ~v ~pos ~x)))))
-                                 bindings))
+  (let [v (gensym "bind-v")
+        bs (->> bindings
+                (map-indexed (fn [i x]
+                               (if (even? i)
+                                 x
+                                 (let [pos (quot i 2)]
+                                   `(if (> (alength ~v) ~pos)
+                                      (aget ~v ~pos)
+                                      (aset ~v ~pos ~x))))))
+                vec)
         [forms destroy] (let [fin (last body)]
                           (if (and (list? fin)
                                    (= 'finally (first fin)))
                             [(butlast body) `(fn [] ~@(rest fin))]
                             [body nil]))]
-    `(let [o# (cljs.core/js-obj)
-           ~v (reagent.ratom/get-cached-values (quote ~v) o#)
-           ~init (if (true? (.-init ~v))
-                   true
-                   (do
-                     (set! (.-init ~v) true)
-                     false))]
+    `(let [destroy-obj# (cljs.core/js-obj)
+           ~v (reagent.ratom/get-cached-values (quote ~v) destroy-obj#)]
        (let ~bs
-         (let [dest# ~destroy
+         (let [destroy# ~destroy
                res# (do ~@forms)]
            (if (reagent.ratom/reactive?)
-             (set! (.-destroy o#) ~destroy)
-             (dest#))
+             (set! (.-destroy destroy-obj#) destroy#)
+             (destroy#))
            res#)))))


Add fn for search-wiki and imdb.

Add fn for search-wiki and imdb.

--- src/beebster_clj/core.clj
+++ src/beebster_clj/core.clj
@@ -123,5 +123,22 @@
       (split-lines result))))

+(def wiki-search-string
+  "http://en.wikipedia.org/w/index.php?search=")
+
+(defn wiki-url
+  "return wikipedia url for search queries."
+  [searchterm]
+  (apply str wiki-search-string searchterm))
+
+(def imdb-search-string
+  "http://imdb.com/find?q=")
+
+(defn imdb-url
+  "return imdb url for search queries."
+  [searchterm]
+  (apply str imdb-search-string searchterm))

+
+


Worked compatibility and api

Worked compatibility and api

--- src/beehive_http/core.clj
+++ src/beehive_http/core.clj
@@ -18,11 +18,13 @@
                                  RequestBuilder
                                  AsyncHttpProvider
                                  AsyncHttpClientConfig$Builder)
-           (com.ning.http.client.providers.netty NettyAsyncHttpProviderConfig NettyAsyncHttpProvider)
+           (com.ning.http.client.providers.netty NettyAsyncHttpProviderConfig
+                                                 NettyAsyncHttpProvider)
            (com.ning.http.client.providers.netty.response NettyResponse)
            (net.uncontended.precipice ServiceProperties RejectedActionException)
            (net.uncontended.precipice_implementations.asynchttp HttpAsyncService)
            (java.util.concurrent TimeUnit)
+           (java.util Map)
            (org.jboss.netty.util HashedWheelTimer)))

 (set! *warn-on-reflection* true)
@@ -37,10 +39,19 @@
         provider (NettyAsyncHttpProvider. client-config)]
     (AsyncHttpClient. ^AsyncHttpProvider provider)))

-(defn request [url]
-  (.build (doto (RequestBuilder.)
-            (.setUrl ^String url)
-            (.setRequestTimeout 500))))
+(defn format-headers [headers]
+  (into {} (mapv (fn [[k v]]
+                   [k (if (sequential? v) v (vector v))])
+                 headers)))
+
+(defn request [url & {:keys [timeout headers body method]}]
+  (let [builder (RequestBuilder.)]
+    (.setUrl builder ^String url)
+    (when method (.setMethod builder ^String method))
+    (when headers (.setHeaders builder ^Map (format-headers headers)))
+    (when body (.setBody builder ^bytes body))
+    (when timeout (.setRequestTimeout builder 500))
+    (.build builder)))

 (defn response [^NettyResponse response]
   {:status (.getStatusCode response)


Improve protocol defintion and docstrings on crypto ns.

--- src/buddy/core/crypto.clj
+++ src/buddy/core/crypto.clj
@@ -52,9 +52,17 @@
 ;; Cipher protocol declaration.
 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

+(defprotocol BlockCipher
+  "Common interface to block ciphers."
+  (get-block-size [_] "Get block size in bytes."))
+
+(defprotocol StreamCipher
+  "Common interface to stream ciphers.")
+
 (defprotocol Cipher
-  (initialize! [obj params] "Initialize cipher")
-  (process-block! [obj input] "Encrypt/Decrypt a block of bytes."))
+  "Common interface to both, stream and block ciphers."
+  (initialize! [_ params] "Initialize cipher")
+  (process-block! [_ input] "Encrypt/Decrypt a block of bytes."))

 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
 ;; Implementation details.


Use 'error' function instead of 'assert' for better analyzer error messages

--- src/clj/cljs/analyzer.clj
+++ src/clj/cljs/analyzer.clj
@@ -273,7 +273,8 @@

 (defmethod parse 'if
   [op env [_ test then else :as form] name]
-  (assert (>= (count form) 3) "Too few arguments to if")
+  (when (< (count form) 3)
+    (throw (error env "Too few arguments to if")))
   (let [test-expr (disallowing-recur (analyze (assoc env :context :expr) test))
         then-expr (analyze env then)
         else-expr (analyze env else)]
@@ -315,7 +316,8 @@
                 (analyze (assoc catchenv :locals locals) `(do ~@(rest cblock))))
         body (if name (pop body) body)
         try (analyze (if (or name finally) catchenv env) `(do ~@body))]
-    (when name (assert (not (namespace name)) "Can't qualify symbol in catch"))
+    (when (and name (namespace name))
+      (throw (error env "Can't qualify symbol in catch")))
     {:env env :op :try* :form form
      :try try
      :finally finally
@@ -336,7 +338,8 @@
         protocol (-> sym meta :protocol)
         dynamic (-> sym meta :dynamic)
         ns-name (-> env :ns :name)]
-    (assert (not (namespace sym)) "Can't def ns-qualified name")
+    (when (namespace sym)
+      (throw (error env "Can't def ns-qualified name")))
     (let [env (if (or (and (not= ns-name 'cljs.core)
                            (core-name? env sym))
                       (get-in @namespaces [ns-name :uses sym]))
@@ -486,7 +489,8 @@

 (defmethod parse 'letfn*
   [op env [_ bindings & exprs :as form] name]
-  (assert (and (vector? bindings) (even? (count bindings))) "bindings must be vector of even number of elements")
+  (when-not (and (vector? bindings) (even? (count bindings)))
+    (throw (error env "bindings must be vector of even number of elements")))
   (let [n->fexpr (into {} (map (juxt first second) (partition 2 bindings)))
         names    (keys n->fexpr)
         context  (:context env)
@@ -523,7 +527,8 @@

 (defn analyze-let
   [encl-env [_ bindings & exprs :as form] is-loop]
-  (assert (and (vector? bindings) (even? (count bindings))) "bindings must be vector of even number of elements")
+  (when-not (and (vector? bindings) (even? (count bindings)))
+    (throw (error encl-env "bindings must be vector of even number of elements")))
   (let [context (:context encl-env)
         [bes env]
         (disallowing-recur
@@ -532,7 +537,8 @@
                 bindings (seq (partition 2 bindings))]
            (if-let [[name init] (first bindings)]
              (do
-               (assert (not (or (namespace name) (.contains (str name) "."))) (str "Invalid local name: " name))
+               (when (or (namespace name) (.contains (str name) "."))
+                 (throw (error encl-env (str "Invalid local name: " name))))
                (let [init-expr (binding [*loop-lets* (cons {:params bes} (or *loop-lets* ()))]
                                  (analyze env init))
                      be {:name name
@@ -587,8 +593,10 @@
   (let [context (:context env)
         frame (first *recur-frames*)
         exprs (disallowing-recur (vec (map #(analyze (assoc env :context :expr) %) exprs)))]
-    (assert frame "Can't recur here")
-    (assert (= (count exprs) (count (:params frame))) "recur argument count mismatch")
+    (when-not frame
+      (throw (error env "Can't recur here")))
+    (when-not (= (count exprs) (count (:params frame)))
+      (throw (error env "recur argument count mismatch")))
     (reset! (:flag frame) true)
     (assoc {:env env :op :recur :form form}
       :frame frame
@@ -601,7 +609,8 @@

 (defmethod parse 'new
   [_ env [_ ctor & args :as form] _]
-  (assert (symbol? ctor) "First arg to new must be a symbol")
+  (when-not (symbol? ctor)
+    (throw (error env "First arg to new must be a symbol")))
   (disallowing-recur
    (let [enve (assoc env :context :expr)
          ctorexpr (analyze enve ctor)
@@ -633,12 +642,12 @@
                        (symbol? target)
                        (do
                          (let [local (-> env :locals target)]
-                           (assert (or (nil? local)
-                                       (and (:field local)
-                                            (or (:mutable local)
-                                                (:unsynchronized-mutable local)
-                                                (:volatile-mutable local))))
-                                   "Can't set! local var or non-mutable field"))
+                           (when-not (or (nil? local)
+                                         (and (:field local)
+                                              (or (:mutable local)
+                                                  (:unsynchronized-mutable local)
+                                                  (:volatile-mutable local))))
+                             (throw (error env "Can't set! local var or non-mutable field"))))
                          (analyze-symbol enve target))

                        :else
@@ -647,7 +656,8 @@
                            (when (:field targetexpr)
                              targetexpr))))
            valexpr (analyze enve val)]
-       (assert targetexpr "set! target must be a field or a symbol naming a var")
+       (when-not targetexpr
+         (throw (error env "set! target must be a field or a symbol naming a var")))
        (cond
         (= targetexpr ::set-unchecked-if) {:env env :op :no-op}
         :else {:env env :op :set! :form form :target targetexpr :val valexpr
@@ -685,7 +695,8 @@

 (defmethod parse 'ns
   [_ env [_ name & args :as form] _]
-  (assert (symbol? name) "Namespaces must be named by a symbol.")
+  (when-not (symbol? name)
+    (throw (error env "Namespaces must be named by a symbol.")))
   (let [docstring (if (string? (first args)) (first args))
         args      (if docstring (next args) args)
         metadata  (if (map? (first args)) (first args))
@@ -694,8 +705,10 @@
         (reduce (fn [s [k exclude xs]]
                   (if (= k :refer-clojure)
                     (do
-                      (assert (= exclude :exclude) "Only [:refer-clojure :exclude (names)] form supported")
-                      (assert (not (seq s)) "Only one :refer-clojure form is allowed per namespace definition")
+                      (when-not (= exclude :exclude)
+                        (throw (error env "Only [:refer-clojure :exclude (names)] form supported")))
+                      (when (seq s)
+                        (throw (error env "Only one :refer-clojure form is allowed per namespace definition")))
                       (into s xs))
                     s))
                 #{} args)
@@ -704,19 +717,19 @@
         valid-forms (atom #{:use :use-macros :require :require-macros :import})
         error-msg (fn [spec msg] (str msg "; offending spec: " (pr-str spec)))
         parse-require-spec (fn parse-require-spec [macros? spec]
-                             (assert (or (symbol? spec) (vector? spec))
-                                     (error-msg spec "Only [lib.ns & options] and lib.ns specs supported in :require / :require-macros"))
+                             (when-not (or (symbol? spec) (vector? spec))
+                               (throw (error env (error-msg spec "Only [lib.ns & options] and lib.ns specs supported in :require / :require-macros"))))
                              (when (vector? spec)
-                               (assert (symbol? (first spec))
-                                       (error-msg spec "Library name must be specified as a symbol in :require / :require-macros"))
-                               (assert (odd? (count spec))
-                                       (error-msg spec "Only :as alias and :refer (names) options supported in :require"))
-                               (assert (every? #{:as :refer} (map first (partition 2 (next spec))))
-                                       (error-msg spec "Only :as and :refer options supported in :require / :require-macros"))
-                               (assert (let [fs (frequencies (next spec))]
-                                         (and (<= (fs :as 0) 1)
-                                              (<= (fs :refer 0) 1)))
-                                       (error-msg spec "Each of :as and :refer options may only be specified once in :require / :require-macros")))
+                               (when-not (symbol? (first spec))
+                                 (throw (error env (error-msg spec "Library name must be specified as a symbol in :require / :require-macros"))))
+                               (when-not (odd? (count spec))
+                                 (throw (error env (error-msg spec "Only :as alias and :refer (names) options supported in :require"))))
+                               (when-not (every? #{:as :refer} (map first (partition 2 (next spec))))
+                                 (throw (error env (error-msg spec "Only :as and :refer options supported in :require / :require-macros"))))
+                               (when-not (let [fs (frequencies (next spec))]
+                                           (and (<= (fs :as 0) 1)
+                                                (<= (fs :refer 0) 1)))
+                                 (throw (error env (error-msg spec "Each of :as and :refer options may only be specified once in :require / :require-macros")))))
                              (if (symbol? spec)
                                (recur macros? [spec])
                                (let [[lib & opts] spec
@@ -730,17 +743,16 @@
                                        (ns-unalias *ns* alias)
                                        (clojure.core/alias alias (.name ns))))
                                    (let [alias-type (if macros? :macros :fns)]
-                                     (assert (not (contains? (alias-type @aliases)
-                                                             alias))
-                                             (error-msg spec ":as alias must be unique"))
+                                     (when (contains? (alias-type @aliases) alias)
+                                       (throw (error env (error-msg spec ":as alias must be unique"))))
                                      (swap! aliases
                                             update-in [alias-type]
                                             conj alias)))
-                                 (assert (or (symbol? alias) (nil? alias))
-                                         (error-msg spec ":as must be followed by a symbol in :require / :require-macros"))
-                                 (assert (or (and (sequential? referred) (every? symbol? referred))
-                                             (nil? referred))
-                                         (error-msg spec ":refer must be followed by a sequence of symbols in :require / :require-macros"))
+                                 (when-not (or (symbol? alias) (nil? alias))
+                                   (throw (error env (error-msg spec ":as must be followed by a symbol in :require / :require-macros"))))
+                                 (when-not (or (and (sequential? referred) (every? symbol? referred))
+                                               (nil? referred))
+                                   (throw (error env (error-msg spec ":refer must be followed by a sequence of symbols in :require / :require-macros"))))
                                  (when-not macros?
                                    (swap! deps conj lib))
                                  (merge
@@ -748,12 +760,12 @@
                                      {rk (merge {alias lib} {lib lib})})
                                    (when referred {uk (apply hash-map (interleave referred (repeat lib)))})))))
         use->require (fn use->require [[lib kw referred :as spec]]
-                       (assert (and (symbol? lib) (= :only kw) (sequential? referred) (every? symbol? referred))
-                               (error-msg spec "Only [lib.ns :only (names)] specs supported in :use / :use-macros"))
+                       (when-not (and (symbol? lib) (= :only kw) (sequential? referred) (every? symbol? referred))
+                         (throw (error env (error-msg spec "Only [lib.ns :only (names)] specs supported in :use / :use-macros"))))
                        [lib :refer referred])
         parse-import-spec (fn parse-import-spec [spec]
-                            (assert (and (symbol? spec) (nil? (namespace spec)))
-                                    (error-msg spec "Only lib.Ctor specs supported in :import"))
+                            (when-not (and (symbol? spec) (nil? (namespace spec)))
+                              (throw (error env (error-msg spec "Only lib.Ctor specs supported in :import"))))
                             (swap! deps conj spec)
                             (let [ctor-sym (symbol (last (string/split (str spec) #"\.")))]
                               {:import  {ctor-sym spec}
@@ -765,10 +777,10 @@
                       :import         parse-import-spec}
         {uses :use requires :require uses-macros :use-macros requires-macros :require-macros imports :import :as params}
         (reduce (fn [m [k & libs]]
-                  (assert (#{:use :use-macros :require :require-macros :import} k)
-                          "Only :refer-clojure, :require, :require-macros, :use and :use-macros libspecs supported")
-                  (assert (@valid-forms k)
-                          (str "Only one " k " form is allowed per namespace definition"))
+                  (when-not (#{:use :use-macros :require :require-macros :import} k)
+                    (throw (error env "Only :refer-clojure, :require, :require-macros, :use and :use-macros libspecs supported")))
+                  (when-not (@valid-forms k)
+                    (throw (error env (str "Only one " k " form is allowed per namespace definition"))))
                   (swap! valid-forms disj k)
                   (apply merge-with merge m (map (spec-parsers k) libs)))
                 {} (remove (fn [[r]] (= r :refer-clojure)) args))]
@@ -900,7 +912,8 @@

 (defmethod parse 'js*
   [op env [_ jsform & args :as form] _]
-  (assert (string? jsform))
+  (when-not (string? jsform)
+    (throw (error env "Invalid js* form")))
   (if args
     (disallowing-recur
      (let [seg (fn seg [^String s]
@@ -1017,7 +1030,8 @@
                 :column (or (-> form meta :column)
                             (:column env)))]
       (let [op (first form)]
-        (assert (not (nil? op)) "Can't call nil")
+        (when (nil? op)
+          (throw (error env "Can't call nil")))
         (let [mform (macroexpand-1 env form)]
           (if (identical? form mform)
             (wrapping-errors env


fix resolve-var handling of property access on local symbols

--- src/clj/cljs/analyzer.clj
+++ src/clj/cljs/analyzer.clj
@@ -333,7 +333,7 @@
                  suffix (subs s (inc idx))
                  lb (-> env :locals prefix)]
              (if lb
-               {:name (symbol (str (:name lb) suffix))}
+               {:name (symbol (str (:name lb)) suffix)}
                (let [cur-ns (-> env :ns :name)]
                  (if-let [full-ns (get-in @env/*compiler* [::namespaces cur-ns :imports prefix])]
                    {:name (symbol (str full-ns) suffix)}


* src/clj/cljs/compiler.clj: only extract params from methods

--- src/clj/cljs/compiler.clj
+++ src/clj/cljs/compiler.clj
@@ -861,7 +861,9 @@
                    (when fn-var?
                      {:fn-var true
                       :info {:max-fixed-arity (:max-fixed-arity init-expr)
-                             :methods (:methods init-expr)}})))))
+                             :methods (map (fn [m]
+                                             {:params (:params m)})
+                                           (:methods init-expr))}})))))
       (merge {:env env :op :def :form form
               :name name :doc doc :init init-expr}
              (when tag {:tag tag})


add new helper function `truthy-constant?` for `if` statement emission. If the `test` is a truthy constant just emit the `then` branch. This resolves Google Closure warnings about dead branches ahead of time.

--- src/clj/cljs/compiler.clj
+++ src/clj/cljs/compiler.clj
@@ -357,26 +357,30 @@
   (when-not (= :statement (:context env))
     (emit-wrap env (emit-constant form))))

+(defn truthy-constant? [{:keys [op form]}]
+  (and (= op :constant)
+       form
+       (not (or (and (string? form) (= form ""))
+                (and (number? form) (zero? form))))))
+
 (defn safe-test? [env e]
   (let [tag (ana/infer-tag env e)]
-    (or (#{'boolean 'seq} tag)
-        (when (= (:op e) :constant)
-          (let [form (:form e)]
-            (not (or (and (string? form) (= form ""))
-                     (and (number? form) (zero? form)))))))))
+    (or (#{'boolean 'seq} tag) (truthy-constant? e))))

 (defmethod emit* :if
   [{:keys [test then else env unchecked]}]
   (let [context (:context env)
         checked (not (or unchecked (safe-test? env test)))]
-    (if (= :expr context)
-      (emits "(" (when checked "cljs.core.truth_") "(" test ")?" then ":" else ")")
-      (do
-        (if checked
-          (emitln "if(cljs.core.truth_(" test "))")
-          (emitln "if(" test ")"))
-        (emitln "{" then "} else")
-        (emitln "{" else "}")))))
+    (if (truthy-constant? test)
+      (emitln then)
+      (if (= :expr context)
+        (emits "(" (when checked "cljs.core.truth_") "(" test ")?" then ":" else ")")
+        (do
+          (if checked
+            (emitln "if(cljs.core.truth_(" test "))")
+            (emitln "if(" test ")"))
+          (emitln "{" then "} else")
+          (emitln "{" else "}"))))))

 (defmethod emit* :case*
   [{:keys [v tests thens default env]}]


Uncomment *cljs-warn-on-undeclared* in compiler.

--- src/clj/cljs/compiler.clj
+++ src/clj/cljs/compiler.clj
@@ -49,7 +49,7 @@
       ms)))

 (defn confirm-var-exists [env prefix suffix]
-  (when true ;;*cljs-warn-on-undeclared*
+  (when *cljs-warn-on-undeclared*
     (let [crnt-ns (-> env :ns :name)]
       (when (= prefix crnt-ns)
         (when-not (-> @namespaces crnt-ns :defs suffix)


Clean up schema definitions

Clean up schema definitions

--- src/clj/runbld/schema.clj
+++ src/clj/runbld/schema.clj
@@ -11,51 +11,51 @@
    :hash   s/Str})

 (def OptsEmail
-  {(s/required-key :from              ) s/Str
-   (s/required-key :host              ) s/Str
-   (s/required-key :max-failure-notify) s/Num
-   (s/required-key :pass              ) s/Str
-   (s/required-key :port              ) (s/cond-pre s/Num s/Str)
-   (s/required-key :template-html     ) (s/cond-pre s/Str java.io.File)
-   (s/required-key :template-txt      ) (s/cond-pre s/Str java.io.File)
-   (s/required-key :text-only         ) s/Bool
-   (s/required-key :tls               ) s/Bool
-   (s/required-key :to                ) (s/cond-pre s/Str [s/Str])
-   (s/required-key :user              ) s/Str})
+  {:from               s/Str
+   :host               s/Str
+   :max-failure-notify s/Num
+   :pass               s/Str
+   :port               (s/cond-pre s/Num s/Str)
+   :template-html      (s/cond-pre s/Str java.io.File)
+   :template-txt       (s/cond-pre s/Str java.io.File)
+   :text-only          s/Bool
+   :tls                s/Bool
+   :to                 (s/cond-pre s/Str [s/Str])
+   :user               s/Str})

 (def OptsProcess
-  {(s/required-key :program   ) s/Str
-   (s/required-key :args      ) [s/Str]
-   (s/required-key :cwd       ) s/Str
-   (s/required-key :scriptfile) s/Str
-   (s/required-key :inherit-exit-code ) s/Bool})
+  {:program           s/Str
+   :args              [s/Str]
+   :cwd               s/Str
+   :scriptfile        s/Str
+   :inherit-exit-code s/Bool})

 (def OptsElasticsearch
-  {(s/required-key :build-index          ) s/Str
-   (s/required-key :build-index-search   ) s/Str
-   (s/required-key :build-index-write    ) s/Str
-   (s/required-key :failure-index        ) s/Str
-   (s/required-key :failure-index-search ) s/Str
-   (s/required-key :failure-index-write  ) s/Str
-   (s/required-key :max-index-bytes      ) s/Num
-   (s/required-key :conn                 ) Connection
-   (s/optional-key :http-opts            ) {s/Keyword s/Any}
-   (s/optional-key :url                  ) s/Str})
+  {:build-index          s/Str
+   :build-index-search   s/Str
+   :build-index-write    s/Str
+   :failure-index        s/Str
+   :failure-index-search s/Str
+   :failure-index-write  s/Str
+   :max-index-bytes      s/Num
+   :conn                 Connection
+   (s/optional-key :http-opts) {s/Keyword s/Any}
+   (s/optional-key :url)       s/Str})

 (def OptsS3
-  {(s/required-key :access-key) s/Str
-   (s/required-key :secret-key) s/Str
-   (s/required-key :bucket    ) s/Str
-   (s/required-key :prefix    ) s/Str})
+  {:access-key s/Str
+   :secret-key s/Str
+   :bucket     s/Str
+   :prefix     s/Str})

 (def Opts
-  {(s/required-key :job-name    ) s/Str
-   (s/required-key :version     ) VersionInfo
-   (s/required-key :configfile  ) (s/maybe s/Str)
-   (s/required-key :email       ) OptsEmail
-   (s/required-key :es          ) OptsElasticsearch
-   (s/required-key :process     ) OptsProcess
-   (s/required-key :s3          ) OptsS3})
+  {:job-name   s/Str
+   :version    VersionInfo
+   :configfile (s/maybe s/Str)
+   :email      OptsEmail
+   :es         OptsElasticsearch
+   :process    OptsProcess
+   :s3         OptsS3})

 (def BuildSystem
   {:arch                   s/Str
@@ -83,78 +83,67 @@
   {s/Str s/Any})

 (def Build
-  {:org                 s/Str
-   :project             s/Str
-   :branch              s/Str
-   :job-name-extra      s/Str
-   :job-name            s/Str
-   :org-project-branch  s/Str
-   :scheduler-type      s/Str
-   :url                 s/Str
-   :console-url         s/Str
-   :tags                [s/Str]
-   (s/optional-key :number) s/Str
+  {:org                       s/Str
+   :project                   s/Str
+   :branch                    s/Str
+   :job-name-extra            s/Str
+   :job-name                  s/Str
+   :org-project-branch        s/Str
+   :scheduler-type            s/Str
+   :url                       s/Str
+   :console-url               s/Str
+   :tags                      [s/Str]
+   (s/optional-key :number)   s/Str
    (s/optional-key :executor) s/Str
-   (s/optional-key :node) s/Str
+   (s/optional-key :node)     s/Str
    })

 (def SchedulerInfo
-  {(s/required-key :type     ) (s/maybe s/Str)
-   (s/required-key :url      ) (s/maybe s/Str)
-   (s/required-key :node     ) (s/maybe s/Str)})
+  {:type (s/maybe s/Str)
+   :url  (s/maybe s/Str)
+   :node (s/maybe s/Str)})

 (def OptsStage2
-  (merge Opts {(s/required-key :sys) BuildSystem
-               (s/required-key :logger) clojure.lang.IFn}))
+  (merge Opts {:sys    BuildSystem
+               :logger clojure.lang.IFn}))

 (def OptsStage3
-  (merge OptsStage2 {(s/required-key :env) Env}))
+  (merge OptsStage2 {:env Env}))

 (def OptsStage4
-  (merge OptsStage3 {(s/required-key :scheduler) (s/protocol Scheduler)}))
+  (merge OptsStage3 {:scheduler (s/protocol Scheduler)}))

 (def OptsStage5
-  (merge OptsStage4 {(s/required-key :id) s/Str
-                     (s/required-key :build) Build}))
+  (merge OptsStage4 {:id    s/Str
+                     :build Build}))

 (def OptsFinal
-  (merge OptsStage5 {(s/required-key :vcs) {s/Keyword s/Any}}))
+  (merge OptsStage5 {:vcs {s/Keyword s/Any}}))

 (def ProcessResult
-  {(s/required-key :cmd            ) [s/Str]
-   (s/required-key :cmd-source     ) s/Str
-   (s/required-key :err-accuracy   ) s/Int
-   (s/required-key :err-bytes      ) s/Num
-   (s/required-key :err-file       ) s/Str
-   (s/required-key :err-file-bytes ) s/Int
-   (s/required-key :exit-code      ) s/Num
-   (s/required-key :millis-end     ) s/Num
-   (s/required-key :millis-start   ) s/Num
-   (s/required-key :out-accuracy   ) s/Int
-   (s/required-key :out-bytes      ) s/Num
-   (s/required-key :out-file       ) s/Str
-   (s/required-key :out-file-bytes ) s/Int
-   (s/required-key :status         ) s/Str
-   (s/required-key :time-end       ) s/Str
-   (s/required-key :time-start     ) s/Str
-   (s/required-key :took           ) s/Num})
+  {:cmd            [s/Str]
+   :cmd-source     s/Str
+   :err-accuracy   s/Int
+   :err-bytes      s/Num
+   :err-file       s/Str
+   :err-file-bytes s/Int
+   :exit-code      s/Num
+   :millis-end     s/Num
+   :millis-start   s/Num
+   :out-accuracy   s/Int
+   :out-bytes      s/Num
+   :out-file       s/Str
+   :out-file-bytes s/Int
+   :status         s/Str
+   :time-end       s/Str
+   :time-start     s/Str
+   :took           s/Num})

 (def StoredProcessResult
-  {:cmd             [s/Str]
-   :cmd-source      s/Str
+  (assoc
+   (dissoc ProcessResult :err-file :out-file)
    :err-accuracy    s/Num
-   :err-bytes       s/Num
-   :err-file-bytes  s/Num
-   :exit-code       s/Num
-   :millis-end      s/Num
-   :millis-start    s/Num
-   :out-accuracy    s/Num
-   :out-bytes       s/Num
-   :out-file-bytes  s/Num
-   :status          s/Str
-   :time-end        s/Str
-   :time-start      s/Str
-   :took            s/Num})
+   :out-accuracy    s/Num))

 (def VcsLog
   {
@@ -177,28 +166,28 @@
    })

 (def XML
-  {(s/required-key :tag     ) s/Keyword
-   (s/required-key :attrs   ) {s/Keyword s/Str}
-   (s/required-key :content ) [s/Any]})
+  {:tag     s/Keyword
+   :attrs   {s/Keyword s/Str}
+   :content [s/Any]})

 (def FailedTestCase
-  {(s/required-key :error-type ) s/Str
-   (s/required-key :class      ) s/Str
-   (s/required-key :test       ) s/Str
-   (s/required-key :stacktrace ) s/Str
-   (s/required-key :summary    ) s/Str
-   (s/required-key :type       ) s/Str
-   (s/optional-key :message    ) s/Str})
+  {:error-type s/Str
+   :class      s/Str
+   :test       s/Str
+   :stacktrace s/Str
+   :summary    s/Str
+   :type       s/Str
+   (s/optional-key :message) s/Str})

 (def TestSummary
-  {(s/required-key :errors    ) s/Num
-   (s/required-key :failures  ) s/Num
-   (s/required-key :tests     ) s/Num
-   (s/required-key :skipped   ) s/Num
-   (s/required-key :failed-testcases ) [FailedTestCase]})
+  {:errors   s/Num
+   :failures s/Num
+   :tests    s/Num
+   :skipped  s/Num
+   :failed-testcases [FailedTestCase]})

 (def TestReport
-  {(s/required-key :report-has-tests) s/Bool
+  {:report-has-tests        s/Bool
    (s/optional-key :report) TestSummary})

 (def StoredTestSummary
@@ -217,18 +206,18 @@
 (def StoredFailure
   (merge
    FailedTestCase
-   {(s/required-key :build-id ) s/Str
-    (s/required-key :time     ) s/Str
-    (s/required-key :org      ) s/Str
-    (s/required-key :project  ) s/Str
-    (s/required-key :branch   ) s/Str}))
+   {:build-id s/Str
+    :time     s/Str
+    :org      s/Str
+    :project  s/Str
+    :branch   s/Str}))

 (def StoredBuild
-  {:id s/Str
+  {:id      s/Str
    :version VersionInfo
-   :build Build
-   :sys BuildSystem
-   :vcs VcsLog
+   :build   Build
+   :sys     BuildSystem
+   :vcs     VcsLog
    :process StoredProcessResult
    :test (s/maybe StoredTestSummary)})

@@ -328,16 +317,15 @@
     {:build-id m/not-analyzed}}})

 (def EmailCtx
-  {(s/required-key :id     ) s/Str
-   (s/required-key :version) VersionInfo
-   (s/required-key :build  ) Build
-   (s/required-key :sys    ) BuildSystem
-   (s/required-key :email  ) {(s/required-key :to) s/Str
-                              (s/required-key :subject) s/Str
-                              }
-   (s/required-key :vcs    ) VcsLog
-   (s/required-key :process) (merge StoredProcessResult
-                                    {(s/required-key :cmd) s/Str
-                                     (s/required-key :args) s/Str
-                                     (s/required-key :took-human) s/Str})
-   (s/required-key :test) (s/maybe StoredTestSummary)})
+  {:id s/Str
+   :version VersionInfo
+   :build Build
+   :sys BuildSystem
+   :email {:to s/Str
+           :subject s/Str}
+   :vcs VcsLog
+   :process (merge StoredProcessResult
+                   {:cmd s/Str
+                    :args s/Str
+                    :took-human s/Str})
+   :test (s/maybe StoredTestSummary)})


Fix number reading

Fix number reading

--- src/clj/wombat/reader.clj
+++ src/clj/wombat/reader.clj
@@ -120,9 +120,19 @@

 (defn read-number
   [^LineNumberingPushbackReader rdr c]
-  (let [tok (read-token rdr c)]
-    (or (match-number tok)
-        (throw (NumberFormatException. (str "Invalid number: " tok))))))
+  (let [sb (StringBuilder.)]
+    (.append sb (char c))
+    (loop []
+      (let [c (.read rdr)]
+        (if (or (= -1 c)
+                (Character/isWhitespace c)
+                (contains? form-tokens (char c)))
+          (unread rdr c)
+          (do
+            (.append sb (char c))
+            (recur)))))
+    (or (match-number (.toString sb))
+        (throw (NumberFormatException. (str "Invalid number: " (.toString sb)))))))

 (defmulti read-form
   (fn [rdr c] (form-tokens (char c))))


Fix setting starting faction when loading game state from URL

--- src/clj/zetawar/game.cljs
+++ src/clj/zetawar/game.cljs
@@ -1180,9 +1180,8 @@
     (let [game (conn-game)
           starting-faction-eid (e (faction-by-color @conn game starting-faction-color))
           current-faction-eid (e (faction-by-color @conn game current-faction-color))]
-      (d/transact! conn [{:db/id (-> (conn-game) :game/map e)
-                          :map/starting-faction starting-faction-eid}
-                         {:db/id (e game)
+      (d/transact! conn [{:db/id (e game)
+                          :game/starting-faction starting-faction-eid
                           :game/current-faction current-faction-eid}]))
     game-id))


fix typo ::listener-key -> ::listener-keys

--- src/cljs/dato/lib/db.cljs
+++ src/cljs/dato/lib/db.cljs
@@ -114,7 +114,7 @@
                            (fn [s]
                              (update-in s [::listener-keys listen-trigger]
                                         #(or % (.getNextUniqueId (.getInstance IdGenerator))))))
-      (let [key (om/get-state owner [::listener-key listen-trigger])]
+      (let [key (om/get-state owner [::listener-keys listen-trigger])]
         (add-trigger-fn conn trigger key (fn [tx-report]
                                            (if (om/mounted? owner)
                                              (om/refresh! owner)


Testing git credential store

Testing git credential store

--- src/cljs/metime/core.cljs
+++ src/cljs/metime/core.cljs
@@ -233,22 +233,22 @@
                                               :poll-interval 2000}})]

              "#calendar"
-               [:div [:h1 "Calendar page"]]
+               [:div [:h1 {:style {:height "500px"}} "Calendar page"]]

              "#tables"
-               [:div [:h1 "Tables page"]]
+               [:div {:style {:height "500px"}} [:h1 "Tables page"]]

              "#file-manager"
-               [:div [:h1 "File manager page"]]
+               [:div {:style {:height "500px"}} [:h1 "File manager page"]]

              "#user"
-               [:div [:h1 "User page"]]
+               [:div {:style {:height "500px"}} [:h1 "User page"]]

              "#login"
-               [:div [:h1 "Login page"]]
+               [:div {:style {:height "500px"}} [:h1 "Login page"]]

              "default"
-               [:div [:h1 "The default page"]]))))
+               [:div {:style {:height "500px"}} [:h1 "The default page"]]))))

 (defn main []
   (doto history


Switch to :require-macros from :use-macros.

--- src/cljs/quil/sketch.cljs
+++ src/cljs/quil/sketch.cljs
@@ -4,7 +4,7 @@
             [goog.dom :as dom]
             [goog.events :as events]
             [goog.events.EventType :as EventType])
-  (:use-macros [quil.sketch :only [with-sketch]]))
+  (:require-macros [quil.sketch :as sketch]))

 (def ^:dynamic
   *applet* nil)
@@ -43,7 +43,7 @@
         (when-let [handler (opts quil-name)]
           (aset prc (name processing-name)
                 (fn []
-                  (with-sketch prc
+                  (sketch/with-sketch prc
                     (handler)))))))

 (defn make-sketch [options]


more functions in the pegging game

more functions in the pegging game

--- src/clojure_noon/core.clj
+++ src/clojure_noon/core.clj
@@ -1004,3 +1004,46 @@

 (connect {} 15 1 2 4)

+(defn connect-right
+  [board max-pos pos]
+  (let [neighbor (inc pos)
+        destination (inc neighbor)]
+    (if-not (or (triangular? neighbor) (triangular? pos))
+      (connect board max-pos pos neighbor destination)
+      board)))
+
+(defn connect-down-left
+  [board max-pos pos]
+  (let [row (row-num pos)
+        neighbor (+ row pos)
+        destination (+ 1 row neighbor)]
+    (connect board max-pos pos neighbor destination)))
+
+(defn connect-down-right
+  [board max-pos pos]
+  (let [row (row-num pos)
+        neighbor (+ 1 row pos)
+        destination (+ 2 row neighbor)]
+    (connect board max-pos pos neighbor destination)))
+
+(defn add-pos
+  "Pegs the position and performs the connections"
+  [board max-pos pos]
+  (let [pegged-board (assoc-in board [pos :pegged] true)]
+    (reduce (fn [new-board connection-creation-fn]
+              (connection-creation-fn new-board max-pos pos))
+            pegged-board
+            [connect-right connect-down-left connect-down-right])))
+
+(add-pos {} 15 1)
+
+
+(defn new-board
+  "Creates a new board with the given number of rows"
+  [rows]
+  (let [initial-board {:rows rows}
+        max-pos (row-tri rows)]
+    reduce (fn [board pos] (add-pos board max-pos pos))
+    initial-board
+    (range 1 (inc max-pos))))
+


Use bulk-import to save xml-tree-validations

It's safer than assuming all the errors in a feed can be handled by a
single INSERT.

--- src/vip/data_processor/validation/xml.clj
+++ src/vip/data_processor/validation/xml.clj
@@ -235,10 +235,9 @@
   [ctx]
   (let [results-id (:import-id ctx)
         errors (postgres/xml-tree-validation-values ctx)]
-    (when-not (empty? errors)
-      (korma/insert postgres/xml-tree-validations
-        (korma/values errors))))
-  ctx)
+    (postgres/bulk-import ctx
+                          postgres/xml-tree-validations
+                          errors)))

 (defn determine-spec-version [ctx]
   (let [xml-file (first (:input ctx))]


Make New app have a few things

Make New app have a few things

So not so simple but shows interactivity and components

--- src/webapp/framework/server/systemfns.clj
+++ src/webapp/framework/server/systemfns.clj
@@ -1902,7 +1902,22 @@
   (do
     (sql "insert into coils_applications (application_name,application_code) values (?,?)"
          ["name"
-          "(defn-ui-component     sub-component   [app] {} (div nil \"... sub component\"))\r\n\r\n
-(defn-ui-component     main   [app] {}\r\n  (div nil\r\n     (component sub-component app []) \r\n     (component sub-component app []) \r\n \"New app\"))"])
+          (str
+           "(def counter (atom 0))\n\n"
+
+           "(defn-ui-component     sub-component   [app] {} \n"
+           "    (div nil \n"
+           "        (input {:type \"button\" \n"
+           "                :style {:margin \"20px\"}\n"
+           "                :value (str \"Click me: \" @counter \" times\")\n"
+           "                :onClick #(do\n"
+           "                              (swap! counter inc)\n"
+           "                              (refresh))})))\n\n"
+
+           "(defn-ui-component     main   [app] {}\n"
+           "    (div nil\n"
+           "        (component sub-component app []) \n"
+           "        (component sub-component app []) \n"
+           "         \"New app\"))")])
     {}))


got labels working

got labels working

--- statspop/src/statspop/charts/scatter.cljs
+++ statspop/src/statspop/charts/scatter.cljs
@@ -16,11 +16,13 @@
     {:chart-type js/Chartist.Line
      :data data
      :options {:showLine false
-               :axisX {:high 5
-                       :low 0
-                       :scaleMinSpace 20
-                       :referenceValue 3
+               :axisX {:type js/Chartist.AutoScaleAxis
                        :onlyInteger true}
+               ;; :axisX {:high 5
+               ;;         :low 0
+               ;;         :scaleMinSpace 20
+               ;;         :referenceValue 3
+               ;;         :onlyInteger true}
                :axisY {:high 200
                        :low 0
                        :scaleMinSpace 20


work-days-count tests

work-days-count tests

--- test-cljs/cljs_workcalendar/api_test.cljs
+++ test-cljs/cljs_workcalendar/api_test.cljs
@@ -72,6 +72,19 @@
       2012 1  1  2 2012 1 12
       2012 1 12  -3 2011 12 30)))

-
-
-
+(deftest work-day-count-test
+  (let [service (cs/createWorkCalendarService)]
+    (are [from-year from-month from-day
+          to-year to-month to-day
+          expected-length]
+      (= expected-length (.work-day-count service
+                                          (js/Date. from-year
+                                                    (dec from-month)
+                                                    from-day)
+                                          (js/Date. to-year
+                                                    (dec to-month)
+                                                    to-day)))
+      2012 1 1 2012 1 10 1
+      2012 1 1 2012 1 31 16
+      2012 5 1 2012 5 31 21
+      2012 6 1 2012 6 30 20)))


Add selenium test for action type changes.

--- test/clj/hatnik/selenium/actions_test.clj
+++ test/clj/hatnik/selenium/actions_test.clj
@@ -261,6 +261,49 @@
                [{:file "new file2" :regex "new regex2"
                  :replacement "new replacement2"}]}))))))

+(deftest change-action-type-test
+  (run-with-driver
+   (fn [driver]
+
+     ; Create email action
+     (let [[project] (find-projects-on-page driver)]
+       (open-add-action-dialog driver project)
+       (change-action-type driver "email")
+       (set-input-text-from-map driver
+                                {:library-input "quil"
+                                 :email-subject "Email subject"
+                                 :email-body "Email body"})
+       (apply-changes driver))
+
+     ; Check that action has expected fields
+     (let [[project] (find-projects-on-page driver)
+           action (first (:actions project))]
+       (open-edit-action-dialog driver action)
+       (is (= (action-params driver)
+              {:library-input "quil"
+               :action-type "email"
+               :email-subject "Email subject"
+               :email-body "Email body"})))
+
+     ; Change action type to github-issue and set only repository
+     (change-action-type driver "github-issue")
+     (set-input-text-from-map driver
+                              {:gh-repo "nbeloglazov/hatnik"})
+     (apply-changes driver)
+
+     ; Check that action now is github-issue. Fields values should
+     ; stay the same, only names changed (email subject -> issue title,
+     ; email body -> issue body).
+     (let [[project] (find-projects-on-page driver)
+           action (first (:actions project))]
+       (open-edit-action-dialog driver action)
+       (is (= (action-params driver)
+              {:library-input "quil"
+               :action-type "github-issue"
+               :gh-repo "nbeloglazov/hatnik"
+               :gh-issue-title "Email subject"
+               :gh-issue-body "Email body"}))))))
+
 (comment

   (def system (start-test-system))


Fix connect test

Fix connect test

--- test/com/wsscode/pathom/connect_test.cljc
+++ test/com/wsscode/pathom/connect_test.cljc
@@ -295,7 +295,7 @@
   (testing "stops processing if entity is nil"
     (is (= (parser {::p/entity (atom {:user/id 2})}
              [{:user/network [:network/id]}])
-           {})))
+           {:user/network :com.wsscode.pathom.core/not-found})))

   (testing "short circuit error "
     (is (thrown-with-msg? clojure.lang.ExceptionInfo #"requirements could not be met."


acquire transform's attribute details from a generic fn - so we can choose to supply/default/calculate them in different ways...

--- src/main/clojure/org/dada/core.clj
+++ src/main/clojure/org/dada/core.clj
@@ -235,7 +235,7 @@
 ;; TODO: creation of extra literal and composed values
 ;;----------------------------------------

-(defn make-transformer [#^ISeq getters #^Metadata metadata #^View view]
+(defn make-transformer [#^ISeq init-fns #^Metadata metadata #^View view]
   (new
    Transformer
    (list view)
@@ -245,28 +245,48 @@
     (transform
      [input]
      ;; TODO: this code needs to be FAST - executed online
-     (.create metadata #^Collection (map (fn [#^Getter getter] (.get getter input)) getters)))
+     (.create metadata #^Collection (map (fn [#^IFn init-fn] (init-fn input)) init-fns)))
     )))
+
+;; returns [key type init-fn]
+(defmulti do-transform-attribute (fn [descrip md] (class descrip)))
+
+;; simple one-to-one mapping
+(defmethod do-transform-attribute
+  clojure.lang.Keyword [#^Keyword key #^Metadata md]
+  (let [key-name (name key)
+	type(.getAttributeType md key-name)
+	getter (.getAttributeGetter md key-name)
+	value-fn (fn [value] (.get getter value))]
+    [key type value-fn]))
+
+;;(defmethod do-transform-attribute
+;;  clojure.lang.PersistentList [#^ISeq attribute #^Metadata md]
+;;  (apply do-transform-attribute attribute))
+
+(defn third [s] (nth s 2))

 (defn do-transform [#^String suffix #^Model src-model #^Keyword key-key #^Keyword version-key &
 		    #^ISeq attribute-keys]
   (let [#^Metadata model-metadata (.getMetadata src-model)
-	get-attribute-type (fn [key] (.getAttributeType model-metadata (name key)))
-	key-type (get-attribute-type key-key)
-	version-type (get-attribute-type version-key)
-	attribute-types (map get-attribute-type attribute-keys)
-	attribute-getters
+	key-details (do-transform-attribute key-key model-metadata)
+	key-type (second key-details)
+	version-details (do-transform-attribute version-key model-metadata)
+	version-type (second version-details)
+	attribute-details (map #(do-transform-attribute % model-metadata) attribute-keys)
+	attribute-types (map second attribute-details)
+	init-fns
 	(list*
-	 (.getAttributeGetter model-metadata (name key-key))
-	 (.getAttributeGetter model-metadata (name version-key))
-	 (map (fn [attribute-key] (.getAttributeGetter model-metadata (name attribute-key))) attribute-keys))
+	 (third key-details)
+	 (third version-details)
+	 (map third attribute-details))
 	attributes (interleave attribute-keys attribute-types)
 	class-name (name (gensym "org.dada.demo.whales.Transform"))
 	superclass Object
 	view-metadata (class-metadata class-name superclass key-key version-key (concat (list key-key key-type version-key version-type) attributes))
 	view-name (str (.getName src-model) "." suffix)
 	view (model view-name view-metadata)
-	transformer (make-transformer attribute-getters view-metadata view)]
+	transformer (make-transformer init-fns view-metadata view)]
     (connect src-model transformer)
     view))


fix unused arguments

fix unused arguments

--- src/crucible/encoding.clj
+++ src/crucible/encoding.clj
@@ -4,10 +4,10 @@
             [camel-snake-kebab.core :refer [->PascalCase]]
             [crucible.encoding.keys :refer [->key]]))

-(defmethod ->key :aws-template-format-version [kw]
+(defmethod ->key :aws-template-format-version [_]
   "AWSTemplateFormatVersion")

-(defn validate-element [elements-map element]
+(defn validate-element [_ element]
   element)

 (defmulti rewrite-element-data (fn [[type _]] type))


Remove bundle references

Remove bundle references

--- src/ctia/http/handler.clj
+++ src/ctia/http/handler.clj
@@ -30,8 +30,11 @@
 =======
              [verdict :refer [verdict-routes]]
              [graphql :refer [graphql-routes]]
+<<<<<<< HEAD
              [bundle :refer [bundle-routes]]
 >>>>>>> First draft of GraphQL support
+=======
+>>>>>>> Remove bundle references
              [version :refer [version-routes]]]
             [ring.middleware.not-modified :refer [wrap-not-modified]]))


Something is working

Something is working

--- 6clojure/day3.clj
+++ 6clojure/day3.clj
@@ -1,7 +1,7 @@
 (ns .usr.local.google.home.rkj.misc.7lang.6clojure.day3
   "TODO(rkj): write a description of the package!")

-(def queue-chairs (atom []))
+(def queue-chairs (atom (clojure.lang.PersistentQueue/EMPTY)))
 (def barber-chair (atom []))
 (def barber (agent []))
 (def shop (agent []))
@@ -9,48 +9,77 @@
 (def customer-cut (atom 0))
 (def HAIRCUT-TIME 2500)
 (def SPAWN-TIME 1000)
-
+(def PRINT-TIME 600)
 (def printer (agent []))

 (defn err-handler-fn [ag ex]
-  (println "error occured: " ex " and we still have value " @ag))
-(set-error-handler! printer err-handler-fn)
+  (println "error occured: " ex " and we still have value " @ag)
+  (.printStackTrace ex)
+  (println "------------"))

-(defn get-haircut [customer]
-  (send printer println customer " is getting haircut")
+(set-error-handler! barber err-handler-fn)
+(set-error-handler! shop err-handler-fn)
+
+(declare do-haircut)
+
+(defn next-client [who]
+  (reset! barber-chair [])
+  (println "barber is handling next client")
+  (if (> (count @queue-chairs) 0)
+    (let [next-customer (peek @queue-chairs)]
+      (swap! queue-chairs pop)
+      (println "Barber will cut " next-customer " and those are waiting" @queue-chairs)
+      (do-haircut next-customer))
+    (println "barber is going to sleep")))
+
+(defn wake-up [barber customer]
+  (do-haircut customer))
+
+(defn do-haircut [customer]
+  (println customer "is getting haircut")
   (swap! barber-chair conj customer)
   (Thread/sleep HAIRCUT-TIME)
-  (send printer println customer " got haircut")
-  (reset! barber-chair [])
-  (swap! customer-cut inc))
+  (println customer "got haircut")
+  (swap! customer-cut inc)
+  (send-off barber next-client))

 (defn wait-for-haircut [customer]
-  )
+  (if (< (count @queue-chairs) 3)
+    (swap! queue-chairs conj customer)
+    (println "Barber is busy and no place for" customer))
+  customer)

 (defn customer-action [customer]
   (if (= 0 (count @barber-chair))
-    (get-haircut customer)
+    (send-off barber wake-up customer)
     (wait-for-haircut customer)))

 (defn add-customer [state]
-  (let [customer (agent (str "Customer " (swap! counter inc)))]
+  (let [customer (agent (str "Customer " (swap! counter inc)))
+        wrapper (agent customer)]
     (set-error-handler! customer err-handler-fn)
-    (send-off customer customer-action)
+    (send-off wrapper customer-action)
     []))

+(defn print-world []
+  (println "\n**********")
+  (println "Barber: " @barber-chair)
+  (println "Queue: " (seq @queue-chairs))
+  (printf "Customer visited: %d, cut: %d\n" @counter @customer-cut)
+  (println "=============\n"))
+
+(defn print-loop [who]
+  (while true
+    (print-world)
+    (Thread/sleep PRINT-TIME)))
+
+(send printer print-loop)
+
 (defn spawn [time]
-  (send printer println "Spawning")
+  (println "Spawning")
   (Thread/sleep time)
   (send shop add-customer)
   time)

-(defn print-world [who]
-  (println "\n**********")
-  (println "Barber: " @barber-chair)
-  (println "Queue: " @queue-chairs)
-  (printf "Customer visited: %d, cut: %d\n" @counter @customer-cut)
-  (println "=============\n"))
-
 (while true
-  (spawn SPAWN-TIME)
-  (send printer print-world))
+  (spawn SPAWN-TIME))


(maint) Add a helper function to print diff-schema-maps output

This function accepts the output map from diff-schema-maps and converts
the internal lists into vectors and pretty prints the results, making it
easy to copy and paste into a deftest

--- test/puppetlabs/puppetdb/testutils/db.clj
+++ test/puppetlabs/puppetdb/testutils/db.clj
@@ -1,6 +1,7 @@
 (ns puppetlabs.puppetdb.testutils.db
   (:require [clojure.data]
             [clojure.java.jdbc :as sql]
+            [clojure.pprint :refer [pprint]]
             [clojure.set :as set]
             [clojure.string :as str]
             [clojure.test]
@@ -531,3 +532,12 @@
                         "\nRight Only:\n" (pprint-str right-only)
                         "\nSame:\n" (pprint-str same)))
                  diff-list)))
+
+(defn print-diff-schema-maps
+  "This function pretty prints the output from diff-schema-maps after changing
+  the internal sequences into vectors. This makes it easy to copy and paste
+  into a deftest that checks diff-schema-maps output"
+  [diff]
+  (pprint (reduce-kv (fn [m k v] (assoc m k (when (seq? v) (vec v))))
+                     {}
+                     diff)))


src/riemann/xymon.clj: send-line: opts needs to be updated outside of the try statement so that we can also use updated values inside the catch

--- src/riemann/xymon.clj
+++ src/riemann/xymon.clj
@@ -91,20 +91,20 @@
   as a function with the exception as its parameter.
   "
   [opts line]
-  (try
-    (let [opts (merge
-                {:host "127.0.0.1" :port 1984 :timeout 5
-                 :error-handler *send-line-error-handler*}
-                opts)
-          addr (InetSocketAddress. (:host opts) (:port opts))
-          sock (Socket.)]
-      (.setSoTimeout sock (:timeout opts))
-      (.connect sock addr (:timeout opts))
-      (with-open [writer (io/writer sock)]
-        (.write writer line)
-        (.flush writer)))
-    (catch Exception e
-      ((:error-handler opts) e))))
+  (let [opts (merge
+              {:host "127.0.0.1" :port 1984 :timeout 5
+               :error-handler *send-line-error-handler*}
+              opts)]
+    (try
+      (let [addr (InetSocketAddress. (:host opts) (:port opts))
+            sock (Socket.)]
+        (.setSoTimeout sock (:timeout opts))
+        (.connect sock addr (:timeout opts))
+        (with-open [writer (io/writer sock)]
+          (.write writer line)
+          (.flush writer)))
+      (catch Exception e
+        ((:error-handler opts) e)))))

 (defn xymon
   "


Load data folder files at startup

Load data folder files at startup

--- src/robinson/main.clj
+++ src/robinson/main.clj
@@ -51,6 +51,9 @@

    * a `:screen` to render the world

+   * a `:data` the contents of the `/data` folder with the filename (excluding
+   extention) as the key and the contents as the value.
+
    * `quests` that are loaded dynamically on startup."
   []
   (let [terminal  (swingterminal/make-terminal 80 24)
@@ -74,7 +77,15 @@
         dialog (apply merge (map (fn [[k v]]
                                    {k (dialog->fsm v)})
                                  (apply merge (map :dialog quests))))
-        state {:world world :screen terminal :quests quest-map :dialog dialog}
+        data  (apply hash-map
+                (mapcat (fn [file]
+                          [(keyword (.getName file))
+                           (->> (.getPath file)
+                             (slurp)
+                             (clojure.edn/read-string))])
+                        (.listFiles (clojure.java.io/file "data"))))
+        _ (info "loaded data" data)
+        state {:world world :screen terminal :quests quest-map :dialog dialog :data data}
         state (reduce (fn [state _] (add-npcs state 1)) state (range 5))]

     ;; tick once using the rest (.) command to update visibility


add a couple unit tests to validate input checks on user password reset.

--- test/metabase/api/user_test.clj
+++ test/metabase/api/user_test.clj
@@ -180,3 +180,12 @@
 (expect "You don't have permissions to do that."
   ((user->client :rasta) :put 403 (format "user/%d/password" (user->id :trashbird)) {:password "anything"
                                                                                :old_password "whatever"}))
+
+;; Test input validations on password change
+(expect "'password' is a required param."
+  ((user->client :rasta) :put 400 (format "user/%d/password" (user->id :rasta)) {}))
+
+;; Make sure that if current password doesn't match we get a 400
+(expect "password mismatch"
+  ((user->client :rasta) :put 400 (format "user/%d/password" (user->id :rasta)) {:password "anything"
+                                                                                :old_password "mismatched"}))


Only return the queried fields of the requested state

--- src/server/parser.clj
+++ src/server/parser.clj
@@ -14,10 +14,8 @@

 (defmethod readf :state
   [{:keys [custard query]} _ {:keys [state]}]
-  {:value (or (some->> state
-                       second
-                       (.state custard))
-              nil)})
+  (let [state (.state custard (second state))]
+    {:value (when state (select-keys state query))}))

 (defmethod readf :project
   [{:keys [custard]} _ {:keys [state]}]


fixed 56 (last commit was 55)

fixed 56 (last commit was 55)

--- src/server/rooms.cljs
+++ src/server/rooms.cljs
@@ -312,7 +312,7 @@
                       (fn [num-of-tracks]
                         (println "Num-of-tracks:" num-of-tracks)
                         (if (> num-of-tracks 0)
-                          (if (> current-track-num (- num-of-tracks 1))
+                          (if (>= current-track-num (- num-of-tracks 1))
                             (.decr redis-client (redis-room-prefix room "current-track")
                               (fn [err track-num]
                                 (set-current-track-position room -1


removed obsolete function

removed obsolete function

--- src/server/rooms.cljs
+++ src/server/rooms.cljs
@@ -238,13 +238,6 @@
         (fn [err reply]
           (callback reply))))))

-(defn user-track-complete [socket-id callback]
-  (get-room-from-user-id socket-id
-    (fn [room]
-      (.lpush redis-client (str "room:" room ":track-complete") socket-id
-        (fn [err reply]
-          (callback reply))))))
-
 (defn client-sync [room-id sync-command socket-id callback]
   (get-num-of-users room-id
     (fn [num-users]


(TK-10) Add context-listener test case

(TK-10) Add context-listener test case

Add additional test-case with non-empty list of context-listeners.
add-context-handler is now being tested with both an empty and
non-empty list of listeners.

--- test/clj/puppetlabs/trapperkeeper/services/webserver/jetty9_service_handlers_test.clj
+++ test/clj/puppetlabs/trapperkeeper/services/webserver/jetty9_service_handlers_test.clj
@@ -123,6 +123,7 @@
       (let [s                        (get-service app :WebserverService)
             path-context             "/ernie"
             path-context2            "/gonzo"
+            path-context3            "/goblinking"
             path-ring                "/bert"
             path-servlet             "/foo"
             path-servlet2            "/misspiggy"
@@ -137,6 +138,11 @@
             ring-handler             (fn [req] {:status 200 :body "Hi world"})
             body                     "This is a test"
             servlet                  (SimpleServlet. body)
+            context-listeners        [(reify ServletContextListener
+                                        (contextInitialized [this event]
+                                          (doto (.addServlet (.getServletContext event) "simple" servlet)
+                                            (.addMapping (into-array [path-servlet]))))
+                                        (contextDestroyed [this event]))]
             war                      "helloWorld.war"
             target                   {:host "0.0.0.0"
                                       :port 9000
@@ -146,6 +152,7 @@
                                       :path "/kermit"}]
         (add-context-handler dev-resources-dir path-context)
         (add-context-handler dev-resources-dir path-context2 [])
+        (add-context-handler dev-resources-dir path-context3 context-listeners)
         (add-ring-handler ring-handler path-ring)
         (add-servlet-handler servlet path-servlet)
         (add-servlet-handler servlet path-servlet2 {})
@@ -157,6 +164,8 @@
                               :endpoint path-context}
                              {:type :context :base-path dev-resources-dir
                               :context-listeners [] :endpoint path-context2}
+                             {:type :context :base-path dev-resources-dir
+                              :context-listeners context-listeners :endpoint path-context3}
                              {:type :ring :endpoint path-ring}
                              {:type :servlet :servlet (type servlet) :endpoint path-servlet}
                              {:type :servlet :servlet (type servlet) :endpoint path-servlet2}


chop dead footer

chop dead footer

--- src/sledge/server.clj
+++ src/sledge/server.clj
@@ -110,17 +110,6 @@
     (map (fn [url] [:script {:src url :type "text/javascript"}])
          (:dev scripts))
     [:script "goog.require(\"sledge.core\");"]
-    #_
-    [:footer {}
-     ;; maybe this can go into a popup or 'about'
-     ;; item somewhere
-     [:p "Copyright ©2014 Daniel Barlow"]
-     [:p
-      [:a {:href "http://www.gnu.org/licenses/agpl.html"}
-       "GNU Affero General Public Licence"]
-      " | "
-      [:a {:href "http://github.com/telent/sledge"}
-       "Download"]]]
     ]])


minor cleanups and a rename TODO

minor cleanups and a rename TODO

--- src/midje/internal_ideas/fakes.clj
+++ src/midje/internal_ideas/fakes.clj
@@ -250,6 +250,8 @@
     (and (list? thing)
       (mockable-function-symbol? (first thing)))))

+;; TODO: Alex Dec 27, 2011 - rename, in what WAY are these substitutions augmented??? -there's the new name!
+
 (defn augment-substitutions [substitutions fake-form]
   (let [needed-keys (filter mockable-funcall? (fake-form-funcall-arglist fake-form))]
     ;; Note: because I like for a function's metaconstants to be
@@ -269,9 +271,8 @@

 (defn folded-fake? [form]
   (and (sequential? form)
-    (= 'midje.semi-sweet/fake (first form))
-    ;; We now know this: (fake (f ...arg... ...arg...) ...)
-    (some mockable-funcall? (fake-form-funcall-arglist form))))
+       (= 'midje.semi-sweet/fake (first form))
+       (some mockable-funcall? (fake-form-funcall-arglist form))))

 (defn- unfolding-step
   "This walks through a `pending` list that may contain fakes. Each element is


Add IAlias protocol.

Add IAlias protocol.

--- src/suricatta/dsl.clj
+++ src/suricatta/dsl.clj
@@ -22,6 +22,9 @@

 (defprotocol IName
   (name [_] "Name constructor"))
+
+(defprotocol IAlias
+  (as* [_ params] "Alias constructor"))

 (defprotocol IOnStep
   (on [_ conditions]))
@@ -119,14 +122,28 @@
   Object
   (val [v] (DSL/val v)))

+(extend-protocol IAlias
+  org.jooq.Name
+  (as* [n args]
+    (.as n (first args)))
+
+  org.jooq.DerivedColumnList
+  (as* [n args]
+    (.as n (first args)))
+
+  org.jooq.Table
+  (as* [n args]
+    (let [^String alias (first args)]
+      (->> (into-array String (rest args))
+           (.as n alias)))))
+
 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
 ;; Common DSL functions
 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

 (defn as
-  "Set alias."
-  [q name]
-  (.as q name))
+  [o & args]
+  (as* o args))

 (defn field
   [data & {:keys [alias] :as opts}]


make the handlers types to avoid advanced optimization issues

--- src/transit/core.cljs
+++ src/transit/core.cljs
@@ -35,44 +35,50 @@
               :prefersStrings false}
          (clj->js opts)))))

-(defn keyword-handler []
-  #js {:tag (fn [v] ":")
-       :rep (fn [v] (.-fqn v))
-       :stringRep (fn [v] (.-fqn v))})
+(deftype KeywordHandler []
+  Object
+  (tag [_ v] ":")
+  (rep [_ v] (.-fqn v))
+  (stringRep [_ v] (.-fqn v)))

-(defn symbol-handler []
-  #js {:tag (fn [v] "$")
-       :rep (fn [v] (.-str v))
-       :stringRep (fn [v] (.-str v))})
+(deftype SymbolHandler []
+  Object
+  (tag [_ v] "$")
+  (rep [_ v] (.-str v))
+  (stringRep [_ v] (.-str v)))

-(defn list-handler []
-  #js {:tag (fn [v] "list")
-       :rep (fn [v]
-              (let [ret #js []]
-                (doseq [x v] (.push ret x))
-                (t/tagged "array" ret)))
-       :stringRep (fn [v] nil)})
+(deftype ListHandler []
+  Object
+  (tag [_ v] "list")
+  (rep [_ v]
+    (let [ret #js []]
+      (doseq [x v] (.push ret x))
+      (t/tagged "array" ret)))
+  (stringRep [_ v] nil))

-(defn map-handler []
-  #js {:tag (fn [v] "map")
-       :rep (fn [v] v)
-       :stringRep (fn [v] nil)})
+(deftype MapHandler []
+  Object
+  (tag [_ v] "map")
+  (rep [_ v] v)
+  (stringRep [_ v] nil))

-(defn set-handler []
-  #js {:tag (fn [v] "set")
-       :rep (fn [v]
-              (let [ret #js []]
-                (doseq [x v] (.push ret x))
-                (t/tagged "array" ret)))
-       :stringRep (fn [v] nil)})
+(deftype SetHandler []
+  Object
+  (tag [_ v] "set")
+  (rep [_ v]
+    (let [ret #js []]
+      (doseq [x v] (.push ret x))
+      (t/tagged "array" ret)))
+  (stringRep [v] nil))

-(defn vector-handler []
-  #js {:tag (fn [v] "array")
-       :rep (fn [v]
-              (let [ret #js []]
-                (doseq [x v] (.push ret x))
-                ret))
-       :stringRep (fn [v] nil)})
+(deftype VectorHandler []
+  Object
+  (tag [_ v] "array")
+  (rep [_ v]
+    (let [ret #js []]
+      (doseq [x v] (.push ret x))
+      ret))
+  (stringRep [_ v] nil))

 (deftype MapIterator [^:mutable seq]
   Object
@@ -85,36 +91,42 @@
 (defn writer
   ([type] (writer type nil))
   ([type opts]
-     (t/writer (name type)
-       (opts-merge
-         #js {:mapIterator
-              (fn [m] (MapIterator. (seq m)))
-              :handlers
-              #js [cljs.core/Keyword               (keyword-handler)
-                   cljs.core/Symbol                (symbol-handler)
-                   cljs.core/Range                 (list-handler)
-                   cljs.core/List                  (list-handler)
-                   cljs.core/Cons                  (list-handler)
-                   cljs.core/EmptyList             (list-handler)
-                   cljs.core/LazySeq               (list-handler)
-                   cljs.core/RSeq                  (list-handler)
-                   cljs.core/IndexedSeq            (list-handler)
-                   cljs.core/ChunkedCons           (list-handler)
-                   cljs.core/ChunkedSeq            (list-handler)
-                   cljs.core/PersistentQueueSeq    (list-handler)
-                   cljs.core/PersistentQueue       (list-handler)
-                   cljs.core/PersistentArrayMapSeq (list-handler)
-                   cljs.core/PersistentTreeMapSeq  (list-handler)
-                   cljs.core/NodeSeq               (list-handler)
-                   cljs.core/ArrayNodeSeq          (list-handler)
-                   cljs.core/KeySeq                (list-handler)
-                   cljs.core/ValSeq                (list-handler)
-                   cljs.core/PersistentArrayMap    (map-handler)
-                   cljs.core/PersistentHashMap     (map-handler)
-                   cljs.core/PersistentTreeMap     (map-handler)
-                   cljs.core/PersistentHashSet     (set-handler)
-                   cljs.core/PersistentTreeSet     (set-handler)
-                   cljs.core/PersistentVector      (vector-handler)
-                   cljs.core/Subvec                (vector-handler)]}
-         (clj->js opts)))))
+     (let [keyword-handler (KeywordHandler.)
+           symbol-handler  (SymbolHandler.)
+           list-handler    (ListHandler.)
+           map-handler     (MapHandler.)
+           set-handler     (SetHandler.)
+           vector-handler  (VectorHandler.)]
+      (t/writer (name type)
+        (opts-merge
+          #js {:mapIterator
+               (fn [m] (MapIterator. (seq m)))
+               :handlers
+               #js [cljs.core/Keyword               keyword-handler
+                    cljs.core/Symbol                symbol-handler
+                    cljs.core/Range                 list-handler
+                    cljs.core/List                  list-handler
+                    cljs.core/Cons                  list-handler
+                    cljs.core/EmptyList             list-handler
+                    cljs.core/LazySeq               list-handler
+                    cljs.core/RSeq                  list-handler
+                    cljs.core/IndexedSeq            list-handler
+                    cljs.core/ChunkedCons           list-handler
+                    cljs.core/ChunkedSeq            list-handler
+                    cljs.core/PersistentQueueSeq    list-handler
+                    cljs.core/PersistentQueue       list-handler
+                    cljs.core/PersistentArrayMapSeq list-handler
+                    cljs.core/PersistentTreeMapSeq  list-handler
+                    cljs.core/NodeSeq               list-handler
+                    cljs.core/ArrayNodeSeq          list-handler
+                    cljs.core/KeySeq                list-handler
+                    cljs.core/ValSeq                list-handler
+                    cljs.core/PersistentArrayMap    map-handler
+                    cljs.core/PersistentHashMap     map-handler
+                    cljs.core/PersistentTreeMap     map-handler
+                    cljs.core/PersistentHashSet     set-handler
+                    cljs.core/PersistentTreeSet     set-handler
+                    cljs.core/PersistentVector      vector-handler
+                    cljs.core/Subvec                vector-handler]}
+          (clj->js opts))))))


(PDB-4637) Fold migrate! into initialize-schema

--- src/puppetlabs/puppetdb/scf/migrate.clj
+++ src/puppetlabs/puppetdb/scf/migrate.clj
@@ -1518,8 +1518,8 @@
    33 add-certname-id-to-certnames
    34 add-certname-id-to-resource-events
    ;; This dummy migration ensures that even databases that were up to
-   ;; date when the "vacuum analyze" code was added to migrate! will
-   ;; still analyze their existing databases.
+   ;; date when the "vacuum analyze" code was added to run-migrations
+   ;; will still analyze their existing databases.
    35 (fn [] true)
    36 rename-environments-name-to-environment
    37 add-jsonb-columns-for-metrics-and-logs
@@ -1671,20 +1671,6 @@
     (analyze-if-exists (apply set/union small-tables tables))
     (not (empty? tables))))

-(defn migrate! []
-  "Migrates database to the latest schema version. Does nothing if
-  database is already at the latest schema version.  Returns true if
-  there were any migrations.  In most cases, initialize-schema should
-  be called instead."
-  (try
-    (run-migrations)
-    (catch java.sql.SQLException e
-      (log/error e (trs "Caught SQLException during migration"))
-      (loop [ex (.getNextException e)]
-        (when ex
-          (log/error ex (trs "Unraveled exception"))
-          (recur (.getNextException ex))))
-      (throw e))))

 ;; SPECIAL INDEX HANDLING

@@ -1734,6 +1720,14 @@
   true if and only if any migrations were run.  Assumes the database status,
   version, etc. has already been validated."
   []
-  (let [migrated? (migrate!)]
-    (indexes!)
-    migrated?))
+  (try
+    (let [migrated? (run-migrations)]
+      (indexes!)
+      migrated?)
+    (catch java.sql.SQLException e
+      (log/error e (trs "Caught SQLException during migration"))
+      (loop [ex (.getNextException e)]
+        (when ex
+          (log/error ex (trs "Unraveled exception"))
+          (recur (.getNextException ex))))
+      (throw e))))


Fix connecting screen

Fix connecting screen

--- src/robinson/ui/components/robinson.clj
+++ src/robinson/ui/components/robinson.clj
@@ -1,4 +1,4 @@
-;; Functions for rendering state to screen
+;; Functions for rendering state to screen)
 (ns robinson.ui.components.robinson
   (:require
             [taoensso.timbre :as log]
@@ -1710,6 +1710,13 @@
     (async/<! (async/timeout (rand-nth [1200 600])))
     (recur (update tidbit-freqs n inc))))

+(def spinner-chars (atom (cycle ["/" "-" "\\" "|"])))
+(def spinner-routine
+  (go-loop []
+    (swap! spinner-chars rest)
+    (async/<! (async/timeout 100))
+    (recur)))
+
 (zc/def-component Loading
   [this]
   (let [{:keys [state]} (zc/props this)]
@@ -1727,7 +1734,7 @@
                 [:text {} [""]]
                 [:text {:style {:left -6}} [(format "Generating %s..." (nth loading-tidbits @tidbit-index))]]
                 [:text {} [""]]
-                [:text {:style {:left 3}} [(nth ["/" "-" "\\" "|"] (mod (swap! loading-index inc) 4))]]]]]]]]]]]])))
+                [:text {:style {:left 3}} [(first @spinner-chars)]]]]]]]]]]]])))

 (zc/def-component Connecting
   [this]
@@ -1739,8 +1746,12 @@
             [:view {:style {:width "100%" :height "100%" :background-color (rcolor/color->rgb :black)}} [
               [:view {:style {:position :absolute
                               :top 10
-                              :left 36}} [
-                [:text {} ["Connecting..."]]]]]]]]]]]])))
+                              :left 36
+                              :width 80
+                              :height 24}} [
+                [:text {} ["Connecting..."]]
+                [:text {} [""]]
+                [:text {:style {:left 5}} [(first @spinner-chars)]]]]]]]]]]]])))

 (zc/def-component ConnectionFailed
   [this]


check for svn conflicts

check for svn conflicts

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


Fixing pipeline

Fixing pipeline


Fix the static emit case

Fix the static emit case

--- src/oxcart/emitter/jvm/emitter.clj
+++ src/oxcart/emitter/jvm/emitter.clj
@@ -541,7 +541,7 @@

 (defmethod -emit :invoke
   [{:keys [fn args env to-clear?]} frame]
-  (if-not (= :var (:op fn))
+  (if (#{:var :the-var} (:op fn))
     ;; static var invoke case
     (let [frame (dissoc frame :to-clear?)]
       `[~@(mapcat #(emit % frame) (take 19 args))
@@ -550,7 +550,7 @@
         ~@(when to-clear?
             [[:insn :ACONST_NULL]
              [:var-insn :clojure.lang.Object/ISTORE 0]])
-        [:invoke-static [`(keyword (var->class (:var fn)) "invoke") ~@(repeat (min 20 (count args)) :java.lang.Object)] :java.lang.Object]])
+        [:invoke-static [~(keyword (var->class (:var fn)) "invoke") ~@(repeat (min 20 (count args)) :java.lang.Object)] :java.lang.Object]])

     ;; general invoke case
     `[~@(emit fn frame)


Add the default route by default as the fnx one.

--- src/fnx/views/welcome.clj
+++ src/fnx/views/welcome.clj
@@ -63,3 +63,7 @@
         (map input-fields-ns namespaces)
         (str "No namespace with " ns))])))

+;; Routing by default on fnx
+(defpage "/" []
+  (render "/:ns" {:ns "fnx"}))
+


Properly shutdown, fix recon timeout.

Properly shutdown, fix recon timeout.

--- src/goldrausch/okcoin.clj
+++ src/goldrausch/okcoin.clj
@@ -52,11 +52,14 @@
                        :open (fn [ws]
                                (info "ws-opened" ws)
                                (go-loop [m (<! out)]
-                                 (when m
+                                 (if m
                                    (do
                                      (debug "client sending msg to:" url m)
                                      (cli/send ws :text (json/write-str m))
-                                     (recur (<! out)))))
+                                     (recur (<! out)))
+                                   (do
+                                     (async/put! close-ch :shutdown)
+                                     (cli/close ws))))
                                (async/put! opener [in out])
                                (async/close! opener))
                        :text (fn [ws ms]
@@ -69,9 +72,9 @@
                        :error (fn [ws err] (error err "ws-error" url)
                                 (async/close! opener)
                                 (async/close! close-ch)))
-        (<! (timeout 60))
-        (<! close-ch) ;; wait on unblocking close
-        (recur)))
+        (<! (timeout 60000))
+        (when-not (= (<! close-ch) :shutdown)
+          (recur)))) ;; wait on unblocking close
     opener))

 (def schema [{:db/id #db/id[:db.part/db]


CMR-496: Added named exchange to rabbit mq

--- index-queue-app/src/cmr/index_queue/services/callback_service.clj
+++ index-queue-app/src/cmr/index_queue/services/callback_service.clj
@@ -9,11 +9,12 @@
             [langohr.channel :as lch]
             [langohr.queue :as lq]
             [langohr.consumers :as lc]
-            [langohr.basic :as lb]))
+            [langohr.basic :as lb]
+            [langohr.exchange  :as le]))

 (def exchange-name
   "The name of the queue exchange to use to retrieve messages"
-  (cfg/config-value :indexer-queue-exchange ""))
+  (cfg/config-value :indexer-queue-exchange "indexer.exchange"))

 (def queue-name
   "The name of the queue to use to retrieve messages"
@@ -66,15 +67,8 @@
   ;; prevents this.
   (lb/qos ch 1)
   (lq/declare ch queue-name {:exclusive false :auto-delete false})
-  ;(lq/bind ch queue-name exchange-name)
+  (lq/bind ch queue-name exchange-name {:routing-key queue-name})
   (lc/subscribe ch queue-name message-handler {:auto-ack false}))
-
-(defn create-queue-channels
-  "Creates channels for the indexing queue"
-  [num-channels]
-  (let [conn (rmq/connect)]
-    (for [n num-channels]
-      (lch/open conn))))

 (defrecord MessageConsumer
   [
@@ -116,7 +110,9 @@
   [num-channels]
   (let [conn (rmq/connect)
         channels (doall (for [_ (range num-channels)]
-                          (lch/open conn)))]
+                          (let [ch (lch/open conn)]
+                            (le/declare ch exchange-name "direct")
+                            ch)))]

     (->MessageConsumer conn channels false)))

@@ -124,7 +120,7 @@
 (comment
   (let [conn (rmq/connect)
         ch (lch/open conn)]
-    (lb/publish ch "" queue-name "Hi!" {:content-type "text/plain" :type "index-concept"}))
+    (lb/publish ch exchange-name queue-name "Hi!" {:routing-key queue-name :content-type "text/plain" :type "index-concept"}))

   )


Report execution time. Kind of

Report execution time. Kind of

--- src/bejeweled_bot/core.clj
+++ src/bejeweled_bot/core.clj
@@ -65,3 +65,5 @@
   ;  ))

 )
+
+(time (-main))


Improve function naming on compact signing ns.

--- src/buddy/sign/compact.clj
+++ src/buddy/sign/compact.clj
@@ -97,55 +97,51 @@
     :else
     (nippy/freeze data)))

-(defn encode
+(defn sign
   "Sign arbitrary length string/byte array using
   compact sigining method."
   [data key & [{:keys [alg compress]
                 :or {alg :hs256 compress true}}]]
-  (exc/try-on
-   (let [input (serialize data compress)
-         salt (nonce/random-nonce 8)
-         stamp (codecs/long->bytes (util/timestamp))
-         signature (-> (bytes/concat input salt stamp)
-                       (calculate-signature key alg))]
-     (str/join "." [(codecs/bytes->safebase64 input)
-                    (codecs/bytes->safebase64 signature)
-                    (codecs/bytes->safebase64 salt)
-                    (codecs/bytes->safebase64 stamp)]))))
+  (let [input (serialize data compress)
+        salt (nonce/random-nonce 8)
+        stamp (codecs/long->bytes (util/timestamp))
+        signature (-> (bytes/concat input salt stamp)
+                      (calculate-signature key alg))]
+    (str/join "." [(codecs/bytes->safebase64 input)
+                   (codecs/bytes->safebase64 signature)
+                   (codecs/bytes->safebase64 salt)
+                   (codecs/bytes->safebase64 stamp)])))
+
+(defn unsign
+  "Given a signed message, verify it and return
+  the decoded data."
+  [data key & [{:keys [alg compress max-age]
+                :or {alg :hs256 compress true}}]]
+  (let [[input signature salt stamp] (str/split data #"\." 4)
+        input (codecs/safebase64->bytes input)
+        signature (codecs/safebase64->bytes signature)
+        salt (codecs/safebase64->bytes salt)
+        stamp (codecs/safebase64->bytes stamp)
+        candidate (bytes/concat input salt stamp)]
+    (when-not (verify-signature candidate signature key alg)
+      (throw+ {:type :validation :cause :auth :message "Message seems corrupt or manipulated."}))
+    (let [now (util/timestamp)
+          stamp (codecs/bytes->long stamp)]
+      (when (and (number? max-age) (> (- now stamp) max-age))
+        (throw+ {:type :validation :cause :max-age
+                 :message (format "Token is older than %s" max-age)}))
+      (nippy/thaw input {:v1-compatibility? false}))))
+
+(defn encode
+  "Sign arbitrary length string/byte array using
+  compact sigining method and return date wrapped in
+  a Success instance of the Exception monad."
+  [& args]
+  (exc/try-on (apply sign args)))

 (defn decode
   "Given a signed message, verify it and return
-  the decoded data.
-
-  This function returns a monadic either instance,
-  and if some error is happens in process of decoding
-  and verification, it will be reported in an
-  either/left instance."
-  [data key & [{:keys [alg compress max-age]
-                :or {alg :hs256 compress true}}]]
-  (exc/try-on
-   (let [[input signature salt stamp] (str/split data #"\." 4)
-         input (codecs/safebase64->bytes input)
-         signature (codecs/safebase64->bytes signature)
-         salt (codecs/safebase64->bytes salt)
-         stamp (codecs/safebase64->bytes stamp)
-         candidate (bytes/concat input salt stamp)]
-     (when-not (verify-signature candidate signature key alg)
-       (throw+ {:type :validation :cause :auth :message "Message seems corrupt or manipulated."}))
-
-     (let [now (util/timestamp)
-           stamp (codecs/bytes->long stamp)]
-       (when (and (number? max-age) (> (- now stamp) max-age))
-         (throw+ {:type :validation :cause :max-age
-                  :message (format "Token is older than max-age (%s)" max-age)}))
-       (nippy/thaw input {:v1-compatibility? false})))))
-
-(defn sign
-  "Not monadic version of encode."
+  the decoded data wrapped in a Success instance
+  of the Exception monad."
   [& args]
-  (deref (apply encode args)))
-
-(defn unsign
-  "Not monadic version of decode."
-  [& args]
-  (deref (apply decode args)))
+  (exc/try-on (apply unsign args)))