Make bam-index.writer immutable

Make bam-index.writer immutable

--- src/cljam/bam_index/writer.clj
+++ src/cljam/bam_index/writer.clj
@@ -1,7 +1,6 @@
 (ns cljam.bam-index.writer
-  (:require [clojure.java.io :refer [file]]
+  (:require [clojure.java.io :as io]
             [clojure.tools.logging :as logging]
-            [clojure.pprint :refer [pprint]] ;; TODO for debug only
             [cljam.lsb :as lsb]
             [cljam.cigar :as cgr]
             [cljam.util :refer [gen-vec]]
@@ -90,96 +89,123 @@
 ;; index
 ;;

-; OPTIMIZE: make-index! is slow
+(defrecord ^:private MetaData
+  [first-offset last-offset aligned-alns unaligned-alns])
+
+(defn- meta-data
+  ([]
+     (MetaData. -1 0 0 0))
+  ([first-offset last-offset aligned-alns unaligned-alns]
+     (MetaData. first-offset last-offset aligned-alns unaligned-alns)))
+
+(defrecord ^:private LinearIndexStatus
+  [lidx largest-lidx-seen])
+
+(defn- linear-index-status
+  ([]
+     (LinearIndexStatus. (gen-vec max-lidx-size 0) -1))
+  ([lidx largest-lidx-seen]
+     (LinearIndexStatus. lidx largest-lidx-seen)))
+
+(defrecord ^:private IndexStatus
+  [bin-index linear-index-status meta-data])
+
+(defn- index-status
+  ([]
+     (IndexStatus. {} (linear-index-status) (meta-data)))
+  ([bin-index linear-index-status meta-data]
+     (IndexStatus. bin-index linear-index-status meta-data)))
+
+(defn- update-meta-data
+  [meta-data aln]
+  (let [{:keys [first-offset last-offset aligned-alns unaligned-alns]} meta-data
+        {:keys [beg end]} (:chunk (:meta aln))
+        ;; Update
+        first-offset'   (if (or (< (bgzf-util/compare beg first-offset) 1)
+                                (= first-offset -1))
+                          beg first-offset)
+        last-offset'    (if (< (bgzf-util/compare last-offset end) 1)
+                          end last-offset)
+        aligned-alns'   (if (zero? (bit-and (:flag aln) 4))
+                          (inc aligned-alns) aligned-alns)
+        unaligned-alns' (if-not (zero? (bit-and (:flag aln) 4))
+                          (inc unaligned-alns) unaligned-alns)]
+    (->MetaData first-offset' last-offset' aligned-alns' unaligned-alns')))
+
+;;; bin-index > {bin1 chunks1, bin2 chunks2, ...}
+;;; e.g. {8  [{:beg 0, :end 10} ...]
+;;;       10 [...]}
+
+(defn- update-bin-index
+  [bin-index aln]
+  (let [{:keys [beg end] :as achunk} (:chunk (:meta aln))
+        bin (sam-util/compute-bin aln)]
+    (if-let [chunks (get bin-index bin)]
+      (if (bgzf-util/same-or-adjacent-blocks? (:end (last chunks)) beg)
+        (let [l (assoc (last chunks) :end end)]
+          (assoc bin-index bin (conj (pop chunks) l)))
+        (assoc bin-index bin (conj chunks achunk)))
+      (assoc bin-index bin (vector achunk)))))
+
+(defn- update-linear-index-status
+  [linear-index-status aln]
+  (let [{:keys [lidx largest-lidx-seen]} linear-index-status
+        {:keys [beg]} (:chunk (:meta aln))
+        aln-beg (:pos aln)
+        aln-end (+ aln-beg (cgr/count-ref (:cigar aln)))
+        win-beg (if (zero? aln-end)
+                  (pos->lidx-offset (dec aln-beg))
+                  (pos->lidx-offset aln-beg))
+        win-end (if (zero? aln-end)
+                  win-beg
+                  (pos->lidx-offset aln-end))]
+    (let [lidx' (loop [i win-beg, lidx* lidx]
+                  (if (<= i win-end)
+                    (let [l (nth lidx i)]
+                      (if (or (zero? l) (< beg l))
+                        (recur (inc i) (assoc lidx* i beg))
+                        (recur (inc i) lidx*)))
+                    lidx*))
+          largest-lidx-seen' (if (> win-end largest-lidx-seen)
+                               win-end largest-lidx-seen)]
+      (->LinearIndexStatus lidx' largest-lidx-seen'))))
+
+(defn- update-index-status
+  [index-status aln]
+  (let [{:keys [bin-index linear-index-status meta-data]} index-status
+        ;; Update
+        meta-data'           (update-meta-data meta-data aln)
+        bin-index'           (update-bin-index bin-index aln)
+        linear-index-status' (update-linear-index-status linear-index-status aln)]
+    (->IndexStatus bin-index' linear-index-status' meta-data')))
+
 (defn- make-index!
   [refs alns]
-  (let [indices (atom {})
-        ref-name (atom nil)
-        bins (atom nil)
-        bins-seen (atom 0)
-        lidx (atom (gen-vec max-lidx-size 0))
-        largest-lidx-seen (atom -1)
-        meta (atom {:first-offset -1
-                    :last-offset 0
-                    :aligned-alns 0
-                    :unaligned-alns 0})
-        no-coordinate-alns (atom 0)]
-    ;; meta data
-    (doseq [aln alns]
-      (when (nil? @ref-name)
-        (reset! ref-name (:rname aln))
-        (reset! bins (gen-vec (bin-count refs (:rname aln)))))
-      (when-not (= (:rname aln) @ref-name)
-        (swap! indices assoc @ref-name {:meta @meta
-                                        :bins @bins
-                                        :lidx (optimize-lidx @lidx @largest-lidx-seen)})
-        (reset! ref-name (:rname aln))
-        (reset! bins (gen-vec (bin-count refs (:rname aln))))
-        (reset! bins-seen 0)
-        (reset! lidx (gen-vec max-lidx-size 0))
-        (reset! largest-lidx-seen -1)
-        (reset! meta {:first-offset -1
-                      :last-offset 0
-                      :aligned-alns 0
-                      :unaligned-alns 0}))
-      (if (zero? (:pos aln))
-        (swap! no-coordinate-alns inc)
-        (do (if-not (zero? (bit-and (:flag aln) 4))
-              (swap! meta update-in [:unaligned-alns] inc)
-              (swap! meta update-in [:aligned-alns] inc))
-            (if (or (< (bgzf-util/compare (:beg (:chunk (:meta aln)))
-                                          (:first-offset @meta)) 1)
-                    (= (:first-offset @meta) -1))
-              (swap! meta assoc :first-offset (:beg (:chunk (:meta aln)))))
-            (if (< (bgzf-util/compare (:last-offset @meta)
-                                      (:end (:chunk (:meta aln)))) 1)
-              (swap! meta assoc :last-offset (:end (:chunk (:meta aln)))))))
-      ;; bins
-      (let [chunk-beg (:beg (:chunk (:meta aln)))
-            chunk-end (:end (:chunk (:meta aln)))]
-        (let [bin-idx (sam-util/compute-bin aln)
-              bin (if (nil? (nth @bins bin-idx))
-                    (do
-                      (swap! bins assoc bin-idx {:idx bin-idx, :chunks nil})
-                      (swap! bins-seen inc)
-                      (nth @bins bin-idx))
-                    (nth @bins bin-idx))]
-          ;; chunk
-          (if (seq (:chunks bin))
-            (if (bgzf-util/same-or-adjacent-blocks? (:end (last (:chunks bin)))
-                                                    chunk-beg)
-              (let [last-idx (dec (count (:chunks bin)))
-                    last-chunk (last (:chunks bin))
-                    new-chunks (assoc (:chunks bin) last-idx (assoc last-chunk :end chunk-end))
-                    new-bin (assoc bin :chunks new-chunks)]
-                (swap! bins assoc bin-idx new-bin))
-              (let [new-bin (update-in bin [:chunks] conj (:chunk (:meta aln)))]
-                (swap! bins assoc bin-idx new-bin)))
-            (let [new-bin (assoc bin :chunks (vector (:chunk (:meta aln))))]
-              (swap! bins assoc bin-idx new-bin))))
-        ;; linear index
-        (let [aln-beg (:pos aln)
-              aln-end (+ aln-beg (cgr/count-ref (:cigar aln)))
-              window-beg (if (zero? aln-end)
-                           (pos->lidx-offset (dec aln-beg))
-                           (pos->lidx-offset aln-beg))
-              window-end (if (zero? aln-end)
-                           window-beg
-                           (pos->lidx-offset aln-end))]
-          (if (> window-end @largest-lidx-seen)
-            (reset! largest-lidx-seen window-end))
-          (loop [win window-beg]
-            (when (<= win window-end)
-              (if (or (zero? (nth @lidx win))
-                      (< chunk-beg (nth @lidx win)))
-                (swap! lidx assoc win chunk-beg))
-              (recur (inc win)))))))
-    (swap! indices assoc
-           @ref-name {:meta @meta
-                      :bins @bins
-                      :lidx (optimize-lidx @lidx @largest-lidx-seen)}
-           :no-coordinate-alns @no-coordinate-alns)
-    @indices))
+  (loop [[aln & rest] alns
+         ref-name (:rname aln)
+         idx-status (index-status)
+         no-coordinate-alns 0
+         indices {}]
+    (if aln
+      (let [ref-name' (:rname aln)
+            new-ref? (not= ref-name' ref-name)
+            idx-status' (update-index-status
+                         (if new-ref? (index-status) idx-status) aln)
+            no-coordinate-alns' (if (zero? (:pos aln))
+                                  (inc no-coordinate-alns)
+                                  no-coordinate-alns)
+            indices' (if new-ref?
+                       (assoc indices ref-name {:meta (:meta-data idx-status)
+                                                :bins (:bin-index idx-status)
+                                                :lidx (optimize-lidx (:lidx (:linear-index-status idx-status))
+                                                                     (:largest-lidx-seen (:linear-index-status idx-status)))})
+                       indices)]
+        (recur rest ref-name' idx-status' no-coordinate-alns' indices'))
+      (assoc indices ref-name {:meta (:meta-data idx-status)
+                               :bins (:bin-index idx-status)
+                               :lidx (optimize-lidx (:lidx (:linear-index-status idx-status))
+                                                    (:largest-lidx-seen (:linear-index-status idx-status)))}
+                     :no-coordinate-alns no-coordinate-alns))))

 (defn- make-index
   [refs alns]
@@ -189,7 +215,7 @@
                                 :last-offset 0
                                 :aligned-alns 0
                                 :unaligned-alns 0}
-                         :bins []
+                         :bins {}
                          :lidx []}) refs))
    (make-index! refs alns)))

@@ -205,11 +231,11 @@
         ;; bins
         (if (zero? (count (:bins index)))
           (lsb/write-int wtr 0)
-          (let [bins (filter #(not (nil? %)) (:bins index))]
+          (let [bins (:bins index)]
             ;; # of bins
             (lsb/write-int wtr (inc (count bins)))
             (doseq [bin bins]
-              (write-bin wtr bin))
+              (write-bin wtr {:idx (first bin), :chunks (second bin)}))
             ;; meta data
             (write-meta-data wtr (:meta index))))
         ;; linear index
@@ -225,16 +251,16 @@

 (defn writer
   [f refs]
-  (->BAIWriter (DataOutputStream. (FileOutputStream. (file f)))
+  (->BAIWriter (DataOutputStream. (FileOutputStream. (io/file f)))
                refs
-               f))
+               (.getAbsolutePath (io/file f))))

 (defn write-index
   [^BAIWriter wtr alns]
   (try
     (write-index*! (.writer wtr) (.refs wtr) alns)
     (catch Exception e (do
-                         (let [f (file (.f wtr))]
+                         (let [f (io/file (.f wtr))]
                            (when (.exists f)
                              (.delete f)))
                          (logging/error "Failed to create BAM index")


clean up

clean up

--- src/cljocker/hh/dsl/docker.clj
+++ src/cljocker/hh/dsl/docker.clj
@@ -1,4 +1,5 @@
 (ns cljocker.hh.dsl.docker
+  (:refer-clojure :exclude [resolve])
   (:require [clojure.string :as s]
             [clojure.test :refer :all]
             [clojure.set :refer :all]))
@@ -29,23 +30,20 @@
    " "
    (s/join " " v)))

-(defn resolve-args [args]
+(defn- resolve [args]
   (cond
     (vector? args) args
     (seq? args) (vec args)
     (function? args) (args)
     :else [args]))

-(defn- build-instruction [instruction args]
+(defn- build-instruction [instruction args m]
   (if (contains? INSTRUCTIONS instruction)
-    (instruction-concat instruction (resolve-args args))
-    ""))
-
-(defn- build [instruction args m]
-  (let [result (build-instruction instruction args)]
-    (if (empty? result)
-      m
-      (conj m result))))
+    (->> args
+         (resolve)
+         (instruction-concat instruction)
+         (conj m))
+    m))

 (defn validate [[first & rest :as spec]]
   (cond
@@ -79,7 +77,7 @@
        (docker spec [])
        (throw (new IllegalArgumentException reason)))))
   ([[instruction args & rest] m]
-   (let [m (build instruction args m)]
+   (let [m (build-instruction instruction args m)]
      (if (seq rest)
        (docker rest m) m))))


No dash

No dash

--- src/clojure/fault/patterns.clj
+++ src/clojure/fault/patterns.clj
@@ -34,7 +34,7 @@
   (let [[key {:keys [service]}] (load-balancer)]
     (core/perform-action service (get key->fn key))))

-(defn shot-gun [key->service action-count]
+(defn shotgun [key->service action-count]
   (let [key-service-tuples (vec key->service)
         service-count (count key->service)
         rand-fn (fn [] (rand-int service-count))]


http-kit/clojure: Create startup function stub.

--- src/clojure/src/dnsresolvd.clj
+++ src/clojure/src/dnsresolvd.clj
@@ -14,4 +14,13 @@

 (ns dnsresolvd)

+(defn startup
+    "Starts up the daemon."
+    [args]
+
+    (println args)
+
+;   TODO: Implement the daemon startup function.
+)
+
 ; vim:set nu et ts=4 sw=4:


Use a map for doing a request

Use a map for doing a request

--- src/core/async/http/client.clj
+++ src/core/async/http/client.clj
@@ -129,14 +129,15 @@
           (doseq [header-value header-values]
             (.addHeader request-builder header-name header-value)))))))

-(defn request [method url
-               & [{:keys [^AsyncHttpClient client
-                          status-chan
-                          headers-chan
-                          body-chan
-                          error-chan
-                          timeout
-                          headers] :as options}]]
+(defn request [{:keys [^AsyncHttpClient client
+                       url
+                       method
+                       status-chan
+                       headers-chan
+                       body-chan
+                       error-chan
+                       timeout
+                       headers] :as options}]

   (let [cl (or client default-client)
         chans {:status-chan  (or status-chan (chan 1))
@@ -162,23 +163,22 @@
      :error   (chans :error-chan)}))

 (defn get [url & [options]]
-  (request :get url options))
-
-(defn sync-request [method url & [{:keys [^AsyncHttpClient client
-                                          timeout
-                                          headers]}]]
+  (request (merge {:method :get :url url} options)))
+
+(defn sync-request [{:keys [^AsyncHttpClient client
+                            url
+                            method
+                            timeout
+                            headers] :as options}]
   (let [out-chan (chan 1024)
         error-chan (chan 1)]

-    (request method
-             url
-             {:client       client
-              :status-chan  out-chan
-              :headers-chan out-chan
-              :body-chan    out-chan
-              :error-chan   error-chan
-              :timeout      timeout
-              :headers      headers})
+    (request (merge
+               options
+               {:status-chan  out-chan
+                :headers-chan out-chan
+                :body-chan    out-chan
+                :error-chan   error-chan}))

     (let [error-or-status (async/alts!! [error-chan out-chan])]
       (m/match [error-or-status]
@@ -200,7 +200,7 @@
                  {:error ex})))))

 (defn sync-get [url & [options]]
-  (sync-request :get url options))
+  (sync-request (merge {:method :get :url url} options)))

 (defn basic-get [client url & [options]]
   (.execute


Readd/fix plates

Readd/fix plates

--- src/dactyl_keyboard/dactyl.clj
+++ src/dactyl_keyboard/dactyl.clj
@@ -13,13 +13,13 @@
 ;; Shape parameters ;;
 ;;;;;;;;;;;;;;;;;;;;;;

-(def nrows 5)
-(def ncols 6)
+(def nrows 4)
+(def ncols 5)

 (def α (/ π 12))                        ; curvature of the columns
 (def β (/ π 36))                        ; curvature of the rows
 (def centerrow (- nrows 3))             ; controls front-back tilt
-(def centercol 2)                       ; controls left-right tilt / tenting (higher number is more tenting)
+(def centercol 3)                       ; controls left-right tilt / tenting (higher number is more tenting)
 (def tenting-angle (/ π 12))            ; or, change this for more precise tenting control
 (def column-style
   (if (> nrows 5) :orthographic :standard))  ; options include :standard, :orthographic, and :fixed
@@ -32,7 +32,7 @@

 (def thumb-offsets [6 -3 7])

-(def keyboard-z-offset 14)              ; controls overall height; original=9 with centercol=3; use 15 for centercol=2
+(def keyboard-z-offset 9)               ; controls overall height; original=9 with centercol=3; use 15 for centercol=2

 (def extra-width 2.5)                   ; extra space between the base of keys; original= 2
 (def extra-height 1.0)                  ; original= 0.5
@@ -773,3 +773,13 @@
                                 ; wire-posts
                   )))

+(spit "things/right-plate.scad"
+      (write-scad
+                   (cut
+                     (translate [0 0 -0.1]
+                       (difference (union case-walls
+                                          teensy-holder
+                                          ; rj9-holder
+                                          screw-insert-outers)
+                                   (translate [0 0 -10] screw-insert-screw-holes))
+                  ))))


Refactor test to move away from global state

--- test/buildviz/handler_test.clj
+++ test/buildviz/handler_test.clj
@@ -9,22 +9,14 @@
             [buildviz.handler :as handler]))

-(def builds (atom {}))
-(def tests (atom {}))
-
 (defn dummy-persist [_])

-(def app (handler/create-app (build-results builds tests) dummy-persist dummy-persist))
-
-(defn- reset-app! []
-  (reset! builds {})
-  (reset! tests {}))
-
-(defn each-fixture [f]
-  (reset-app!)
-  (f))
-
-(use-fixtures :each each-fixture)
+(defn the-app []
+  (let [builds (atom {})
+        tests (atom {})]
+    (handler/create-app (build-results builds tests)
+                        dummy-persist
+                        dummy-persist)))

 ;; helpers

@@ -54,165 +46,169 @@

 ;; test fixtures

-(defn a-build [jobName buildNr content]
+(defn a-build [app jobName buildNr content]
   (json-put-request app
                     (format "/builds/%s/%s" jobName buildNr)
                     content))

-(defn some-test-results [job-name build-no content]
+(defn some-test-results [app job-name build-no content]
   (xml-put-request app
                    (format "/builds/%s/%s/testresults" job-name build-no)
                    content))

+;; tests
+
 (deftest Storage
   (testing "PUT to /builds/:job/:build"
     ;; PUT should return 200
-    (is (= (:status (json-put-request app "/builds/abuild/1" {}))
+    (is (= (:status (json-put-request (the-app) "/builds/abuild/1" {}))
            200))

     ;; PUT should return 400 for unknown parameters
-    (is (= (:status (json-put-request app "/builds/abuild/1" {:unknown "value"}))
+    (is (= (:status (json-put-request (the-app) "/builds/abuild/1" {:unknown "value"}))
            400))

     ;; PUT should return 400 for illegal outcome
-    (is (= (:status (json-put-request app "/builds/abuild/1" {:outcome "banana"}))
+    (is (= (:status (json-put-request (the-app) "/builds/abuild/1" {:outcome "banana"}))
            400))

     ;; PUT should return content
-    (let [response (json-put-request app "/builds/abuild/1" {:start 42 :end 43})
+    (let [response (json-put-request (the-app) "/builds/abuild/1" {:start 42 :end 43})
           resp-data (json/parse-string (:body response))]
       (is (= resp-data
              {"start" 42 "end" 43}))))

   (testing "GET to /builds/:job/:build"
     ;; GET should return 200
-    (a-build "anotherBuild" 1 {:start 42 :end 43})
-    (let [response (get-request app "/builds/anotherBuild/1")]
-      (is (= (:status response) 200)))
+    (let [app (the-app)]
+      (a-build app "anotherBuild" 1 {:start 42 :end 43})
+      (is (= (:status (get-request app "/builds/anotherBuild/1"))
+             200)))

     ;; GET should return content stored by PUT
-    (a-build "yetAnotherBuild" 1, {:start 42 :end 43})
-    (is (= (json-body (get-request app "/builds/yetAnotherBuild/1"))
-           {"start" 42 "end" 43}))
+    (let [app (the-app)]
+      (a-build app "yetAnotherBuild" 1, {:start 42 :end 43})
+      (is (= (json-body (get-request app "/builds/yetAnotherBuild/1"))
+             {"start" 42 "end" 43})))

     ;; GET should return 404 if job not found
-    (is (= (:status (get-request app "/builds/unknownBuild/10"))
+    (is (= (:status (get-request (the-app) "/builds/unknownBuild/10"))
            404))

     ;; GET should return 404 if build not found
-    (a-build "anExistingBuild" 1, {:start 42 :end 43})
-    (is (= (:status (get-request app "/builds/anExistingBuild/2"))
-           404))
+    (let [app (the-app)]
+      (a-build app "anExistingBuild" 1, {:start 42 :end 43})
+      (is (= (:status (get-request app "/builds/anExistingBuild/2"))
+             404)))

     ;; Different jobs should not interfere with each other
-    (a-build "someBuild" 1, {:start 42 :end 43})
-    (is (= (:status (get-request app "/builds/totallyUnrelatedBuild/1"))
-           404))))
+    (let [app (the-app)]
+      (a-build app "someBuild" 1, {:start 42 :end 43})
+      (is (= (:status (get-request app "/builds/totallyUnrelatedBuild/1"))
+             404)))))

 (deftest JUnitStorage
   (testing "PUT to /builds/:job/:build/testresults"
-    (is (= 204 (:status (xml-put-request app "/builds/mybuild/1/testresults" "<testsuites></testsuites>"))))
-    (is (= 400 (:status (xml-put-request app "/builds/mybuild/1/testresults" "not xml")))))
+    (is (= 204 (:status (xml-put-request (the-app) "/builds/mybuild/1/testresults" "<testsuites></testsuites>"))))
+    (is (= 400 (:status (xml-put-request (the-app) "/builds/mybuild/1/testresults" "not xml")))))

   (testing "GET to /builds/:job/:build/testresults"
-    (some-test-results "abuild" "42" "<testsuites></testsuites>")
-    (let [response (get-request app "/builds/abuild/42/testresults")]
-      (is (= 200 (:status response))))
-
-    (some-test-results "anotherBuild" "2" "<testsuites></testsuites>")
-    (let [response (get-request app "/builds/anotherBuild/2/testresults")]
-      (is (= "<testsuites></testsuites>" (:body response))))
-
-    (some-test-results "anotherBuild" "2" "<testsuites></testsuites>")
-    (let [response (get-request app "/builds/anotherBuild/2/testresults")]
-      (is (= {"Content-Type" "application/xml;charset=UTF-8"} (:headers response))))
-
-    (let [response (get-request app "/builds/missingJob/1/testresults")]
-      (is (= 404 (:status response))))
-
-    (some-test-results "jobMissingABuild" "1" "<testsuites></testsuites>")
-    (let [response (get-request app "/builds/jobMissingABuild/2/testresults")]
-      (is (= 404 (:status response))))
-
-    (some-test-results "job" "1" "<?xml version=\"1.0\" encoding=\"UTF-8\"?><testsuite name=\"suite\"><testcase name=\"case\"></testcase></testsuite>")
-    (let [response (json-get-request app "/builds/job/1/testresults")]
+    (let [app (the-app)]
+      (some-test-results app "abuild" "42" "<testsuites></testsuites>")
+      (let [response (get-request app "/builds/abuild/42/testresults")]
+        (is (= 200
+               (:status (get-request app "/builds/abuild/42/testresults"))))))
+
+    (let [app (the-app)]
+      (some-test-results app "anotherBuild" "2" "<testsuites></testsuites>")
+      (is (= "<testsuites></testsuites>"
+             (:body (get-request app "/builds/anotherBuild/2/testresults")))))
+
+    (let [app (the-app)]
+      (some-test-results app "anotherBuild" "2" "<testsuites></testsuites>")
+      (is (= {"Content-Type" "application/xml;charset=UTF-8"}
+             (:headers (get-request app "/builds/anotherBuild/2/testresults")))))
+
+    (is (= 404
+           (:status (get-request (the-app) "/builds/missingJob/1/testresults"))))
+
+    (let [app (the-app)]
+      (some-test-results app "jobMissingABuild" "1" "<testsuites></testsuites>")
+      (is (= 404
+             (:status (get-request app "/builds/jobMissingABuild/2/testresults")))))
+
+    (let [app (the-app)]
+      (some-test-results app "job" "1" "<?xml version=\"1.0\" encoding=\"UTF-8\"?><testsuite name=\"suite\"><testcase name=\"case\"></testcase></testsuite>")
       (is (= [{"name" "suite"
                "children" [{"name" "case"
-                            "status" "pass"}]}] (json/parse-string (:body response)))))
+                            "status" "pass"}]}]
+             (json-body (json-get-request app "/builds/job/1/testresults")))))
     ))

 (deftest JobsSummary
   (testing "GET to /jobs"
     ;; GET should return 200
-    (let [response (get-request app "/jobs")]
-      (is (= (:status response) 200)))
+    (is (= (:status (get-request (the-app) "/jobs"))
+           200))

     ;; GET should return empty list
-    (let [response (plain-get-request app "/jobs")]
-      (is (= (:body response)
-             "job,averageRuntime,totalCount,failedCount,flakyCount\n")))
+    (is (= (:body (plain-get-request (the-app) "/jobs"))
+           "job,averageRuntime,totalCount,failedCount,flakyCount\n"))

     ;; GET should return job summary
-    (reset-app!)
-    (a-build "someBuild" 1, {:start 10 :end 20 :outcome "pass" :inputs [{:id 42 :revision "dat_revision"}]})
-    (a-build "someBuild" 2, {:start 30 :end 60 :outcome "fail" :inputs [{:id 42 :revision "dat_revision"}]})
-    (a-build "someBuild" 3, {:start 70 :end 90 :outcome "fail" :inputs [{:id 42 :revision "other_revision"}]})
-    (a-build "someBuild" 4, {:start 100 :end 120 :outcome "pass" :inputs [{:id 42 :revision "yet_another_revision"}]})
-    (let [response (plain-get-request app "/jobs")]
-      (is (= (:body response)
+    (let [app (the-app)]
+      (a-build app "someBuild" 1, {:start 10 :end 20 :outcome "pass" :inputs [{:id 42 :revision "dat_revision"}]})
+      (a-build app "someBuild" 2, {:start 30 :end 60 :outcome "fail" :inputs [{:id 42 :revision "dat_revision"}]})
+      (a-build app "someBuild" 3, {:start 70 :end 90 :outcome "fail" :inputs [{:id 42 :revision "other_revision"}]})
+      (a-build app "someBuild" 4, {:start 100 :end 120 :outcome "pass" :inputs [{:id 42 :revision "yet_another_revision"}]})
+      (is (= (:body (plain-get-request app "/jobs"))
              (join ["job,averageRuntime,totalCount,failedCount,flakyCount\n"
                     (format "someBuild,%.8f,4,2,1\n" 0.00000023)]))))

     ;; GET should return empty map for json by default
-    (reset-app!)
-    (let [response (json-get-request app "/jobs")
-          resp-data (json/parse-string (:body response))]
-      (is (= resp-data {})))
+    (is (= (json-body (json-get-request (the-app) "/jobs"))
+           {}))

     ;; GET should return job summary
-    (reset-app!)
-    (a-build "someBuild" 1, {:start 42 :end 43})
-    (a-build "anotherBuild" 1, {:start 10 :end 12})
-    (is (= (json-body (json-get-request app "/jobs"))
-           {"someBuild" {"averageRuntime" 1 "totalCount" 1}
-            "anotherBuild" {"averageRuntime" 2 "totalCount" 1}}))
+    (let [app (the-app)]
+      (a-build app "someBuild" 1, {:start 42 :end 43})
+      (a-build app "anotherBuild" 1, {:start 10 :end 12})
+      (is (= (json-body (json-get-request app "/jobs"))
+             {"someBuild" {"averageRuntime" 1 "totalCount" 1}
+              "anotherBuild" {"averageRuntime" 2 "totalCount" 1}})))

     ;; GET should return total build count
-    (reset-app!)
-    (a-build "runOnce" 1, {})
-    (a-build "runTwice" 1, {})
-    (a-build "runTwice" 2, {})
-    (let [response (json-get-request app "/jobs")
-          resp-data (json/parse-string (:body response))]
-      (is (= resp-data {"runTwice" {"totalCount" 2}
-                        "runOnce" {"totalCount" 1}})))
+    (let [app (the-app)]
+      (a-build app "runOnce" 1, {})
+      (a-build app "runTwice" 1, {})
+      (a-build app "runTwice" 2, {})
+      (is (= (json-body (json-get-request app "/jobs"))
+             {"runTwice" {"totalCount" 2}
+              "runOnce" {"totalCount" 1}})))

     ;; GET should return failed build count
-    (reset-app!)
-    (a-build "flakyBuild" 1, {:outcome "pass"})
-    (a-build "flakyBuild" 2, {:outcome "fail"})
-    (a-build "brokenBuild" 1, {:outcome "fail"})
-    (let [response (json-get-request app "/jobs")
-          resp-data (json/parse-string (:body response))]
-      (is (= resp-data {"flakyBuild" {"failedCount" 1 "totalCount" 2 "flakyCount" 0}
-                        "brokenBuild" {"failedCount" 1 "totalCount" 1 "flakyCount" 0}})))
+    (let [app (the-app)]
+      (a-build app "flakyBuild" 1, {:outcome "pass"})
+      (a-build app "flakyBuild" 2, {:outcome "fail"})
+      (a-build app "brokenBuild" 1, {:outcome "fail"})
+      (is (= (json-body (json-get-request app "/jobs"))
+             {"flakyBuild" {"failedCount" 1 "totalCount" 2 "flakyCount" 0}
+              "brokenBuild" {"failedCount" 1 "totalCount" 1 "flakyCount" 0}})))

     ;; GET should return error build count
-    (reset-app!)
-    (a-build "goodBuild" 1, {:outcome "pass"})
-    (let [response (json-get-request app "/jobs")
-          resp-data (json/parse-string (:body response))]
-      (is (= resp-data {"goodBuild" {"failedCount" 0 "totalCount" 1 "flakyCount" 0}})))
+    (let [app (the-app)]
+      (a-build app "goodBuild" 1, {:outcome "pass"})
+      (is (= (json-body (json-get-request app "/jobs"))
+             {"goodBuild" {"failedCount" 0 "totalCount" 1 "flakyCount" 0}})))

     ;; GET should return a flaky build count
-    (reset-app!)
-    (a-build "flakyBuild" 1, {:outcome "pass" :inputs [{:id 42 :revision "dat_revision"}]})
-    (a-build "flakyBuild" 2, {:outcome "fail" :inputs [{:id 42 :revision "dat_revision"}]})
-    (let [response (json-get-request app "/jobs")
-          resp-data (json/parse-string (:body response))]
-      (is (= resp-data {"flakyBuild" {"failedCount" 1 "totalCount" 2 "flakyCount" 1}})))
+    (let [app (the-app)]
+      (a-build app "flakyBuild" 1, {:outcome "pass" :inputs [{:id 42 :revision "dat_revision"}]})
+      (a-build app "flakyBuild" 2, {:outcome "fail" :inputs [{:id 42 :revision "dat_revision"}]})
+      (is (= (json-body (json-get-request app "/jobs"))
+             {"flakyBuild" {"failedCount" 1 "totalCount" 2 "flakyCount" 1}})))
     ))

 (def a-timestamp (tc/to-long (t/from-time-zone (t/date-time 1986 10 14 4 3 27 456) (t/default-time-zone))))
@@ -221,178 +217,155 @@
 (deftest PipelineRuntimeSummary
   (testing "GET to /pipelineruntime"
     ;; GET should return 200
-    (let [response (get-request app "/pipelineruntime")]
-      (is (= 200 (:status response))))
+    (is (= 200
+           (:status (get-request (the-app) "/pipelineruntime"))))

     ;; GET should return empty list by default
-    (reset-app!)
-    (let [response (get-request app "/pipelineruntime")
-          resp-data (:body response)]
-      (is (= "date\n" resp-data)))
+    (is (= "date\n"
+           (:body (get-request (the-app) "/pipelineruntime"))))

     ;; GET should return the average runtime for each job as well as total
-    (reset-app!)
-    (a-build "aBuild" 1, {:start a-timestamp :end (+ a-timestamp 1000)})
-    (a-build "aBuild" 2, {:start (+ a-timestamp 2000) :end (+ a-timestamp 4001)})
-    (a-build "aBuild" 3, {:start (+ a-timestamp a-day) :end (+ a-timestamp a-day 4000)})
-    (a-build "anotherBuild" 1, {:start a-timestamp :end (+ a-timestamp 4000)})
-    (a-build "buildWithoutTimestamps" 1, {:outcome "pass"})
-    (let [response (get-request app "/pipelineruntime")
-          resp-data (:body response)]
+    (let [app (the-app)]
+      (a-build app "aBuild" 1, {:start a-timestamp :end (+ a-timestamp 1000)})
+      (a-build app "aBuild" 2, {:start (+ a-timestamp 2000) :end (+ a-timestamp 4001)})
+      (a-build app "aBuild" 3, {:start (+ a-timestamp a-day) :end (+ a-timestamp a-day 4000)})
+      (a-build app "anotherBuild" 1, {:start a-timestamp :end (+ a-timestamp 4000)})
+      (a-build app "buildWithoutTimestamps" 1, {:outcome "pass"})
       (is (= (join "\n" ["date,aBuild,anotherBuild"
                          (format "1986-10-14,%.8f,%.8f" 0.00001737 0.00004630)
                          (format "1986-10-15,%.8f," 0.00004630)
                          ""])
-             resp-data)))
+             (:body (get-request app "/pipelineruntime")))))
     ))

 (deftest FailPhases
   (testing "GET to /failphases"
     ;; GET should return 200
-    (let [response (get-request app "/failphases")]
-      (is (= 200 (:status response))))
+    (is (= 200
+           (:status (get-request (the-app) "/failphases"))))

     ;; GET should return empty list by default
-    (reset-app!)
-    (let [response (get-request app "/failphases")
-          resp-data (:body response)]
-      (is (= "start,end,culprits\n" resp-data)))
+    (is (= "start,end,culprits\n"
+           (:body (get-request (the-app) "/failphases"))))

     ;; GET should return fail phases
-    (reset-app!)
-    (a-build "badBuild" 1, {:end a-timestamp :outcome "fail"})
-    (a-build "anotherBuild" 1, {:end (+ a-timestamp 10000) :outcome "fail"})
-    (a-build "anotherBuild" 2, {:end (+ a-timestamp 20000) :outcome "pass"})
-    (a-build "badBuild" 2, {:end (+ a-timestamp 30000) :outcome "pass"})
-    (let [response (get-request app "/failphases")
-          resp-data (:body response)]
-      (is (= "start,end,culprits\n1986-10-14 04:03:27,1986-10-14 04:03:57,anotherBuild|badBuild\n" resp-data)))
+    (let [app (the-app)]
+      (a-build app "badBuild" 1, {:end a-timestamp :outcome "fail"})
+      (a-build app "anotherBuild" 1, {:end (+ a-timestamp 10000) :outcome "fail"})
+      (a-build app "anotherBuild" 2, {:end (+ a-timestamp 20000) :outcome "pass"})
+      (a-build app "badBuild" 2, {:end (+ a-timestamp 30000) :outcome "pass"})
+      (is (= "start,end,culprits\n1986-10-14 04:03:27,1986-10-14 04:03:57,anotherBuild|badBuild\n"
+             (:body (get-request app "/failphases")))))

     ;; GET should return empty list by default as JSON
-    (reset-app!)
-    (let [response (json-get-request app "/failphases")
-          resp-data (json/parse-string (:body response))]
-      (is (= [] resp-data)))
+    (is (= []
+           (json-body (json-get-request (the-app) "/failphases"))))

     ;; GET should return fail phases as JSON
-    (reset-app!)
-    (a-build "badBuild" 1, {:end 42 :outcome "fail"})
-    (a-build "badBuild" 2, {:end 80 :outcome "pass"})
-    (let [response (json-get-request app "/failphases")
-          resp-data (json/parse-string (:body response))]
-      (is (= [{"start" 42 "end" 80 "culprits" ["badBuild"]}] resp-data)))
+    (let [app (the-app)]
+      (a-build app "badBuild" 1, {:end 42 :outcome "fail"})
+      (a-build app "badBuild" 2, {:end 80 :outcome "pass"})
+      (is (= [{"start" 42 "end" 80 "culprits" ["badBuild"]}]
+             (json-body (json-get-request app "/failphases")))))
     ))

 (deftest FailuresSummary
   (testing "GET to /failures"
     ;; GET should return 200
-    (let [response (get-request app "/failures")]
-      (is (= 200 (:status response))))
+    (is (= 200
+           (:status (get-request (the-app) "/failures"))))

     ;; GET should return an empty list in CSV
-    (reset-app!)
-    (let [response (get-request app "/failures")]
-      (is (= "failedCount,job,testsuite,classname,name\n"
-             (:body response))))
+    (is (= "failedCount,job,testsuite,classname,name\n"
+           (:body (get-request (the-app) "/failures"))))

     ;; GET should include a list of failing test cases
-    (reset-app!)
-    (a-build "failingBuild" 1, {:outcome "fail"})
-    (some-test-results "failingBuild" "1" "<testsuites><testsuite name=\"a suite\"><testcase name=\"a test\" classname=\"a class\"><failure/></testcase></testsuite></testsuites>")
-    (a-build "failingBuild" 2, {:outcome "fail"})
-    (some-test-results "failingBuild" "2" "<testsuites><testsuite name=\"a suite\"><testcase name=\"a test\" classname=\"a class\"><failure/></testcase></testsuite></testsuites>")
-    (a-build "anotherFailingBuild" 1, {:outcome "fail"})
-    (some-test-results "anotherFailingBuild" "1" "<testsuites><testsuite name=\"another suite\"><testsuite name=\"nested suite\"><testcase name=\"another test\" classname=\"some class\"><failure/></testcase></testsuite></testsuite></testsuites>")
-    (a-build "failingBuildWithoutTestResults" 1, {:outcome "fail"})
-    (a-build "passingBuild" 1, {:outcome "pass"})
-    (some-test-results "passingBuild" "1" "<testsuites><testsuite name=\"suite\"><testcase name=\"test\" classname=\"class\"></testcase></testsuite></testsuites>")
-    (let [response (get-request app "/failures")]
+    (let [app (the-app)]
+      (a-build app "failingBuild" 1, {:outcome "fail"})
+      (some-test-results app "failingBuild" "1" "<testsuites><testsuite name=\"a suite\"><testcase name=\"a test\" classname=\"a class\"><failure/></testcase></testsuite></testsuites>")
+      (a-build app "failingBuild" 2, {:outcome "fail"})
+      (some-test-results app "failingBuild" "2" "<testsuites><testsuite name=\"a suite\"><testcase name=\"a test\" classname=\"a class\"><failure/></testcase></testsuite></testsuites>")
+      (a-build app "anotherFailingBuild" 1, {:outcome "fail"})
+      (some-test-results app "anotherFailingBuild" "1" "<testsuites><testsuite name=\"another suite\"><testsuite name=\"nested suite\"><testcase name=\"another test\" classname=\"some class\"><failure/></testcase></testsuite></testsuite></testsuites>")
+      (a-build app  "failingBuildWithoutTestResults" 1, {:outcome "fail"})
+      (a-build app "passingBuild" 1, {:outcome "pass"})
+      (some-test-results app "passingBuild" "1" "<testsuites><testsuite name=\"suite\"><testcase name=\"test\" classname=\"class\"></testcase></testsuite></testsuites>")
       (is (= (join "\n" ["failedCount,job,testsuite,classname,name"
                          "1,anotherFailingBuild,another suite: nested suite,some class,another test"
                          "2,failingBuild,a suite,a class,a test"
                          ""])
-             (:body response))))
+             (:body (get-request app "/failures")))))

     ;; GET should return empty map by default for JSON
-    (reset-app!)
-    (let [response (json-get-request app "/failures")
-          resp-data (json/parse-string (:body response))]
-      (is (= {} resp-data)))
+    (is (= {}
+           (json-body (json-get-request (the-app) "/failures"))))

     ;; GET should include a list of failing test cases for JSON
-    (reset-app!)
-    (a-build "failingBuild" 1, {:outcome "fail"})
-    (some-test-results "failingBuild" "1" "<testsuites><testsuite name=\"a suite\"><testcase name=\"a test\"><failure/></testcase></testsuite></testsuites>")
-    (a-build "anotherFailingBuild" 1, {:outcome "fail"})
-    (some-test-results "anotherFailingBuild" "1" "<testsuites><testsuite name=\"another suite\"><testcase name=\"another test\"><failure/></testcase></testsuite></testsuites>")
-    (a-build "failingBuildWithoutTestResults" 1, {:outcome "fail"})
-    (a-build "passingBuild" 1, {:outcome "pass"})
-    (some-test-results "passingBuild" "1" "<testsuites><testsuite name=\"suite\"><testcase name=\"test\"></testcase></testsuite></testsuites>")
-    (let [response (json-get-request app "/failures")
-          resp-data (json/parse-string (:body response))]
+    (let [app (the-app)]
+      (a-build app "failingBuild" 1, {:outcome "fail"})
+      (some-test-results app "failingBuild" "1" "<testsuites><testsuite name=\"a suite\"><testcase name=\"a test\"><failure/></testcase></testsuite></testsuites>")
+      (a-build app "anotherFailingBuild" 1, {:outcome "fail"})
+      (some-test-results app "anotherFailingBuild" "1" "<testsuites><testsuite name=\"another suite\"><testcase name=\"another test\"><failure/></testcase></testsuite></testsuites>")
+      (a-build app "failingBuildWithoutTestResults" 1, {:outcome "fail"})
+      (a-build app "passingBuild" 1, {:outcome "pass"})
+      (some-test-results app "passingBuild" "1" "<testsuites><testsuite name=\"suite\"><testcase name=\"test\"></testcase></testsuite></testsuites>")
       (is (= {"failingBuild" {"failedCount" 1 "children" [{"name" "a suite"
                                                            "children" [{"name" "a test"
                                                                         "failedCount" 1}]}]}
               "anotherFailingBuild" {"failedCount" 1 "children" [{"name" "another suite"
                                                                   "children" [{"name" "another test"
                                                                                "failedCount" 1}]}]}}
-             resp-data)))
+             (json-body (json-get-request app "/failures")))))
     ))

 (deftest TestsuitesSummary
   (testing "GET to /testsuites"
     ;; GET should return 200
-    (let [response (json-get-request app "/testsuites")]
-      (is (= 200 (:status response))))
+    (is (= 200
+           (:status (json-get-request (the-app) "/testsuites"))))

     ;; GET should return empty map by default
-    (let [response (json-get-request app "/testsuites")
-          resp-data (json/parse-string (:body response))]
-      (is (= {} resp-data)))
+    (is (= {}
+           (json-body (json-get-request (the-app) "/testsuites"))))

     ;; GET should include a list of builds with test cases
-    (reset-app!)
-    (a-build "aBuild" 1, {})
-    (some-test-results "aBuild" "1" "<testsuites><testsuite name=\"a suite\"><testcase name=\"a test\" time=\"10\"></testcase></testsuite></testsuites>")
-    (a-build "aBuild" 2, {})
-    (some-test-results "aBuild" "2" "<testsuites><testsuite name=\"a suite\"><testcase name=\"a test\" time=\"30\"></testcase></testsuite></testsuites>")
-    (let [response (json-get-request app "/testsuites")
-          resp-data (json/parse-string (:body response))]
+    (let [app (the-app)]
+      (a-build app "aBuild" 1, {})
+      (some-test-results app "aBuild" "1" "<testsuites><testsuite name=\"a suite\"><testcase name=\"a test\" time=\"10\"></testcase></testsuite></testsuites>")
+      (a-build app "aBuild" 2, {})
+      (some-test-results app "aBuild" "2" "<testsuites><testsuite name=\"a suite\"><testcase name=\"a test\" time=\"30\"></testcase></testsuite></testsuites>")
       (is (= {"aBuild" {"children" [{"name" "a suite"
                                      "children" [{"name" "a test"
                                                   "averageRuntime" 20000}]}]}}
-             resp-data)))
+             (json-body (json-get-request app "/testsuites")))))

     ;; GET should return CSV by default
-    (reset-app!)
-    (a-build "aBuild" 1, {})
-    (some-test-results "aBuild" "1" "<testsuites><testsuite name=\"a suite\"><testcase name=\"a,test\" classname=\"a class\" time=\"10\"></testcase></testsuite></testsuites>")
-    (let [response (get-request app "/testsuites")]
-      (is (= (:body response)
+    (let [app (the-app)]
+      (a-build app  "aBuild" 1, {})
+      (some-test-results app "aBuild" "1" "<testsuites><testsuite name=\"a suite\"><testcase name=\"a,test\" classname=\"a class\" time=\"10\"></testcase></testsuite></testsuites>")
+      (is (= (:body (get-request app "/testsuites"))
              (join ["averageRuntime,job,testsuite,classname,name\n"
                     (format "%.8f,aBuild,a suite,a class,\"a,test\"\n" 0.00011574)]))))

     ;; GET should handle nested testsuites in CSV
-    (reset-app!)
-    (a-build "aBuild" 1, {})
-    (some-test-results "aBuild" "1" "<testsuites><testsuite name=\"a suite\"><testsuite name=\"nested suite\"><testcase name=\"a,test\" classname=\"a class\" time=\"10\"></testcase></testsuite></testsuite></testsuites>")
-    (let [response (plain-get-request app "/testsuites")]
-      (is (= (:body response)
+    (let [app (the-app)]
+      (a-build app "aBuild" 1, {})
+      (some-test-results app "aBuild" "1" "<testsuites><testsuite name=\"a suite\"><testsuite name=\"nested suite\"><testcase name=\"a,test\" classname=\"a class\" time=\"10\"></testcase></testsuite></testsuite></testsuites>")
+      (is (= (:body (plain-get-request app "/testsuites"))
              (join ["averageRuntime,job,testsuite,classname,name\n"
                     (format "%.8f,aBuild,a suite: nested suite,a class,\"a,test\"\n" 0.00011574)]))))

     ;; GET should not include builds without test cases
-    (reset-app!)
-    (a-build "aBuild" 1, {})
-    (let [response (json-get-request app "/testsuites")
-          resp-data (json/parse-string (:body response))]
-      (is (= {} resp-data)))
+    (let [app (the-app)]
+      (a-build app "aBuild" 1, {})
+      (is (= {}
+             (json-body (json-get-request app "/testsuites")))))
     ))

 (deftest EntryPoint
   (testing "GET to /"
-    (let [response (get-request app "/")]
-      (is (= 302 (:status response))))
-
-    (let [response (get-request app "/")]
-      (is (= "/index.html" (get (:headers response) "Location"))))))
+    (is (= 302
+           (:status (get-request (the-app) "/"))))
+
+    (is (= "/index.html"
+           (get (:headers (get-request (the-app) "/")) "Location")))))


Adding etags

Adding etags

--- apoya-app/src/clj/apoya/app.clj
+++ apoya-app/src/clj/apoya/app.clj
@@ -24,14 +24,24 @@
         (let [compile-fn (fleet [label] template {:escaping :xml})]
           {:body (.toString (compile-fn i18n/label))})))))

-(defn jclouds-resource [{:keys [uri]}]
+(defn jclouds-resource [{:keys [uri headers]}]
   (when (and (not (.endsWith uri "/"))
              (fs/site-blob-exists? uri))
     (let [mime-type (mime-type-of uri)
-          body (-> (fs/get-site-blob uri)
+          if-none-match (get headers "if-none-match")
+          res-blob (fs/get-site-blob uri)
+          etag (-> res-blob
+                   (.getMetadata)
+                   (.getETag))
+          body (-> res-blob
                    (.getPayload)
                    (.getInput))]
-      (response/content-type {:body body :status 200} mime-type))))
+      (if-not (= etag if-none-match)
+        (response/content-type {:body body
+                                :headers {"etag" etag}
+                                :status 200}
+                               mime-type)
+        {:status 304 :body "" :headers {"etag" etag}}))))

 (defn handle-errors [handler]
   (fn [request]


ARM: mx5: use config to define boot related addresses

Signed-off-by: Richard Zhao <bbd97e76288330e4315e9a841fcfb77b747adc43@freescale.com>
Acked-by: Uwe Kleine-König <181323dd666a182bc2d953e52d0ac3ab54cd8391@pengutronix.de>
Signed-off-by: Sascha Hauer <c00cbc2b736c26791a3822db86f8796fe9efff67@pengutronix.de>

--- arch/arm/mach-mx5/Makefile.boot
+++ arch/arm/mach-mx5/Makefile.boot
@@ -1,3 +1,3 @@
-   zreladdr-y	:= 0x90008000
-params_phys-y	:= 0x90000100
-initrd_phys-y	:= 0x90800000
+   zreladdr-$(CONFIG_ARCH_MX51)	:= 0x90008000
+params_phys-$(CONFIG_ARCH_MX51)	:= 0x90000100
+initrd_phys-$(CONFIG_ARCH_MX51)	:= 0x90800000


Test for function render-name-field

Test for function render-name-field

--- test/zg/html_renderer_test.clj
+++ test/zg/html_renderer_test.clj
@@ -160,3 +160,12 @@
             "test/expected/search-field7.html" (page/xhtml (render-search-field "word" "http://10.20.30.40/zg/" :whitelist))
             "test/expected/search-field8.html" (page/xhtml (render-search-field "word" "http://10.20.30.40/zg/" :blacklist)))))

+(deftest test-render-name-field
+    "Checking the function zg.html-renderer/render-name-field."
+    (testing "the function zg.html-renderer/render-name-field."
+        (are [x y] (= (slurp x) y)
+            "test/expected/name-field1.html" (page/xhtml (render-name-field "user name" ""))
+            "test/expected/name-field3.html" (page/xhtml (render-name-field "user name" "/"))
+            "test/expected/name-field5.html" (page/xhtml (render-name-field "user name" "http://10.20.30.40/"))
+            "test/expected/name-field7.html" (page/xhtml (render-name-field "user name" "http://10.20.30.40/zg/")))))
+


small cleanup

small cleanup

--- src/snergly/animation.cljs
+++ src/snergly/animation.cljs
@@ -34,17 +34,17 @@
                       :else          nil))))]
     (chain-seqs* ((first fs)) (rest fs))))

-(defn produce-distances [{:keys [start-row start-col] :as maze-params} ui grid-key color-family maze]
+(defn produce-distances [maze {:keys [start-row start-col] :as maze-params} ui grid-key color-family]
   (let [prev-distances (:distances maze)
-        [start-row start-col] (if prev-distances (:max-coord prev-distances) [start-row start-col])]
+        start (if prev-distances (:max-coord prev-distances) [start-row start-col])]
     (protocols/report-status ui "Finding distances …")
     (map #(assoc maze :distances %
                       grid-key {:distances %
                                 :color-family color-family
                                 :expected-max-distance (* (grid/grid-size maze) 0.8)})
-         (algs/distances-seq maze [start-row start-col]))))
+         (algs/distances-seq maze start))))

-(defn produce-path [{:keys [end-row end-col] :as maze-params} ui longest? maze]
+(defn produce-path [maze {:keys [end-row end-col] :as maze-params} ui longest?]
   (let [prev-distances (:distances maze)
         goal (if longest? (:max-coord prev-distances) [end-row end-col])]
     (protocols/report-status ui (str "Plotting path (" (inc (:max prev-distances)) " cells long) …"))
@@ -56,12 +56,12 @@
   (println (str "analysis: " analysis))
   (condp = analysis
     "none" []
-    "distances" [(partial produce-distances maze-params ui :dist1 :green)]
-    "path" [(partial produce-distances maze-params ui :dist1 :green)
-            (partial produce-path maze-params ui false)]
-    "longest path" [(partial produce-distances maze-params ui :dist1 :green)
-                    (partial produce-distances maze-params ui :dist2 :blue)
-                    (partial produce-path maze-params ui true)]))
+    "distances" [#(produce-distances % maze-params ui :dist1 :green)]
+    "path" [#(produce-distances % maze-params ui :dist1 :green)
+            #(produce-path % maze-params ui false)]
+    "longest path" [#(produce-distances % maze-params ui :dist1 :green)
+                    #(produce-distances % maze-params ui :dist2 :blue)
+                    #(produce-path % maze-params ui true)]))

 (defn produce-maze [{:keys [rows columns algorithm] :as maze-params} ui]
   (println (str "algorithm: " algorithm))


Use connection pool for sending events.

Use connection pool for sending events.

--- src/forces_assemble/handler.clj
+++ src/forces_assemble/handler.clj
@@ -8,6 +8,7 @@
             [monger.collection :as mc]
             [monger.operators :refer :all]
             [clj-http.client :as http]
+            [clj-http.conn-mgr :refer [make-reusable-conn-manager shutdown-manager]]
             [forces-assemble.http-utils :refer :all]
             [liberator.core :refer [defresource]]
             [liberator.dev :refer [wrap-trace]]))
@@ -109,6 +110,22 @@
               :form-params (build-notification event client)}))

 ;; Event logic
+(defn add-event-to-channel-with-pool
+  [channel-id event]
+  (let [cm (make-reusable-conn-manager)
+        api-key (str "key=" (or (env :firebase-api-key) ""))
+        added-event (add-event-to-channel-db channel-id event)]
+    (map (fn [client-token]
+           (println (str "Pushing: " client-token))
+           (println (str "Message: " (pr-str event)))
+           (http/post firebase-send-uri
+                      {:content-type :json
+                       :headers {"Authorization" api-key}
+                       :form-params (build-notification event client-token)
+                       :connection-manager cm}))
+         (get-user-tokens-on-channel channel-id))
+    (shutdown-manager cm)))
+
 (defn add-event-to-channel
   [channel-id event]
   (let [added-event (add-event-to-channel-db channel-id event)]
@@ -130,7 +147,7 @@
   :known-content-type? #(check-content-type % [application-json])
   :malformed? #(parse-json % ::data)
   :post! (fn [context]
-           (add-event-to-channel channel-id (::data context))))
+           (add-event-to-channel-with-pool channel-id (::data context))))

 (defresource channel-subscribers [channel-id]
   :allowed-methods [:post]
@@ -142,6 +159,7 @@

 (defroutes assemble-routes
   (GET "/" [] "Hello World2")
+  (GET "/hello" [] "More hellos")
   (ANY "/users/:id/token" [id] (user-tokens id))
   (ANY "/channels/:id/events" [id] (channel-events id))
   (ANY "/channels/:id/subscribers" [id] (channel-subscribers id))


Add debug output of aether traffic

Add debug output of aether traffic

--- boot/aether/src/boot/aether.clj
+++ boot/aether/src/boot/aether.clj
@@ -2,6 +2,7 @@
   (:require
    [clojure.java.io             :as io]
    [clojure.string              :as string]
+   [clojure.pprint              :as pprint]
    [cemerick.pomegranate.aether :as aether]
    [boot.util                   :as util]
    [boot.pod                    :as pod]
@@ -24,7 +25,8 @@
 (defn set-local-repo! [x] (reset! local-repo x))

 (defn transfer-listener
-  [{type :type meth :method {name :name repo :repository} :resource err :error}]
+  [{type :type meth :method {name :name repo :repository} :resource err :error :as info}]
+  (util/dbug "Aether: %s\n" (with-out-str (pprint/pprint info)))
   (when (and (.endsWith name ".jar") (= type :started))
     (util/info "Retrieving %s from %s\n" (.getName (io/file name)) repo)))


Convert to 24 hour hours.

Convert to 24 hour hours.

--- src/think/release/core.clj
+++ src/think/release/core.clj
@@ -148,7 +148,7 @@
            :snapshot? false
            :rest (if (config/get-config :date-version)
                    (str "-"
-                        (.format (SimpleDateFormat. "yyyy-MM-dd-hh-mm") (Date.)))
+                        (.format (SimpleDateFormat. "yyyy-MM-dd-HH-mm") (Date.)))
                    ""))
     (and (= bump-type :snapshot)
          (not (get version :snapshot?)))


remove startyear and endyear in o6registers

--- src_cljs/rrm/corecljs.cljs
+++ src_cljs/rrm/corecljs.cljs
@@ -2843,7 +2843,7 @@
                      :year [[v/required :message "Field is required"]
                             [year-after? :message "Year must greater than 1900"]
                             [year-before? :message "Year must less than 9999"]]
-                     :misalnumber [[v/required :message "Field is required"]]
+                     ;;:misalnumber [[v/required :message "Field is required"]]
                      ;; :startingdate [[v/required :message "Field is required"]
                      ;;                [date-year-after? :message "Year must greater than 1900"]
                      ;;                [date-year-before? :message "Year must less than 9999"]]
@@ -2872,7 +2872,7 @@
     (fn []
       [:div.form-group
        [:label.col-sm-3.control-label label]
-       [:div.col-sm-6 [input-int id ttype data-set label input-focus]]
+       [:div.col-sm-3 [input-int id ttype data-set label input-focus]]
        [:div.col-sm-3 (if (or @input-focus @focus)
                         (if (= nil (o6register-form-validator @data-set))
                           [:div]
@@ -2914,10 +2914,10 @@
      [:div.form-horizontal
       [:div.box-body
        [o6register-input-row :o6number  "O6 Number" "text" data-set focus]
-       [o6register-input-int-row :year "Year" "text" data-set focus]
-       [o6register-input-row :misalnumber "Misal Number" "text" data-set focus]
-       [o6register-input-row :startingdate "Starting Date" "date" data-set focus]
-       [o6register-input-row :endingdate "Ending Date" "date" data-set focus]
+       [o6register-input-row :year "Year" "text" data-set focus]
+      ;; [o6register-input-row :misalnumber "Misal Number" "text" data-set focus]
+     ;;  [o6register-input-row :startingdate "Starting Date" "date" data-set focus]
+       ;;[o6register-input-row :endingdate "Ending Date" "date" data-set focus]
        [o6-form-subdiv-sel "Sub Division Name" :subdivisionname (:subdivisions @storage) data-set focus]
        [o6register-input-row :racknumber "Rack Number" "text" data-set focus]
        [o6register-input-row :description "Description" "text" data-set focus]
@@ -2957,9 +2957,9 @@
                              :o6number (.-o6number dmt)
                              :subdivisionname (.-subdivisionname dmt)
                              :year (.-year dmt)
-                             :misalnumber (.-misalnumber dmt)
-                             :startingdate (.-startingdate dmt)
-                             :endingdate (.-endingdate dmt)
+                            ;; :misalnumber (.-misalnumber dmt)
+                            ;; :startingdate (.-startingdate dmt)
+                            ;; :endingdate (.-endingdate dmt)
                              :racknumber (.-racknumber dmt)
                              :description (.-description dmt)
                              })
@@ -3017,9 +3017,9 @@
           (when (is-admin-or-super-admin) [:th " "])
           [:th "O6 Number"]
           [:th "Year"]
-          [:th "Misal Number"]
-          [:th "Starting Date"]
-          [:th "Ending Date"]
+        ;;  [:th "Misal Number"]
+        ;;  [:th "Starting Date"]
+        ;;  [:th "Ending Date"]
           [:th "Sub Division Name"]
           [:th "Rack Number"]
           [:th "Description"]
@@ -3036,9 +3036,9 @@
                                     :on-click #(o6register-delete(.-id mt))}"Delete"]])
                    [:td (.-o6number mt)]
                    [:td (.-year mt)]
-                   [:td (.-misalnumber mt)]
-                   [:td (.-startingdate mt)]
-                   [:td (.-endingdate mt)]
+                 ;; [:td (.-misalnumber mt)]
+                 ;;  [:td (.-startingdate mt)]
+                 ;;  [:td (.-endingdate mt)]
                    [:td (.-subdivisionname mt)]
                    [:td (.-racknumber mt)]
                    [:td (.-description mt)]


Demo app cleanup

Demo app cleanup

Just some small changes for variable names (how come I still call them
vartiables?)

--- src/webapp/framework/client/components/main_view.cljs
+++ src/webapp/framework/client/components/main_view.cljs
@@ -23,31 +23,30 @@
 (defn-ui-component     main-to-do-component   [app]
   {}

-  (section {:id "todoapp" :style {:padding "20px" :width "100%"}}
+  (section {:id "todoapp"
+            :style {:padding "20px" :width "100%"}}
+
            (h2 nil "Todo app")
-           (div { :width "100%" :style {:padding "20px" :backgoundColor "white"}}
+
+           (div { :width "100%"
+                  :style {:padding "20px" :backgoundColor "white"}}
+
                 (input {
-                        :id "new_todo_item"
-                        :className "newTodo"
-                        :value (read-ui  app [:newitem2])
+                        :id          "new_todo_item"
+                        :className   "newTodo"
+                        :value      (read-ui  app [:new-to-do-item])

-                        :onChange (fn [event2]
-                                    (let [newtext      (.. event2 -target -value  )]
-                                      (write-ui  app  [:newitem2]  newtext)))
+                        :onChange   (fn [event]
+                                      (let [newtext      (.. event -target -value  )]
+                                        (write-ui  app  [:new-to-do-item]  newtext)))

-                        :onKeyDown  (fn [e]
+                        :onKeyDown  (fn [event]
                                       (do
-                                        (if (= (.-keyCode e  ) 13)
+                                        (if (= (.-keyCode event  ) 13)
                                           (go
-                                           ;(js/alert (read-ui  app [:newitem2]))
-                                           ;(log "ISERT :** "  newtext)
-
-                                           (log (pr-str (sql "insert into  coils_todo_items   (item) values (?)"
-                                                             [(read-ui  app [:newitem2])]  )))
-                                           (write-ui  app  [:newitem2]  "")
-                                           ))))
-
-                        })
+                                           (sql "insert into  coils_todo_items   (item) values (?)"
+                                                [(read-ui  app [:new-to-do-item])]  )
+                                           (write-ui  app  [:new-to-do-item]  "")))))})


Code cleanup

Code cleanup

The ACTIVE filter sometimes refreshes the page so moved false to a new
line

--- src/webapp/framework/client/components/main_view.cljs
+++ src/webapp/framework/client/components/main_view.cljs
@@ -119,7 +119,8 @@
                             (if (pos? (count completed-items))
                               (button {:style {  :width "34%" :textAlign "right"}
                                        :onClick #(do (go
-                                                   (sql "delete from  coils_todo_items  where item_status = 'COMPLETED'" []  )) false)
+                                                   (sql "delete from  coils_todo_items  where item_status = 'COMPLETED'" []  ))
+                                                   false)
                                                    } "Clear completed"))

                             ))))))))


Split up demo app into separate UI components

So that the input field, the main todo list, and the footer were all
separate UI components. This will make the demo a lot nicer to show as
the debugger can then be shown

--- src/webapp/framework/client/components/main_view.cljs
+++ src/webapp/framework/client/components/main_view.cljs
@@ -21,31 +21,30 @@

-(defn-ui-component     main-to-do-component   [app]
+(defn-ui-component     new-do-item-component   [app]
+
   {}
-  (section
-   {:className "todoapp"}
-     (header {} (h2 nil "Todo app"))
-     (div {:className "main_div"}

-
-       (input-field {:placeholder  "Enter a new todo here"} app
+  (input-field {:placeholder  "Enter a new todo here"} app
          (fn [new-todo-item-text] (go
             (sql "insert into coils_todo_items
                             (item, item_status)
                   values
                             (?,                  ?)"
-                            [new-todo-item-text  "ACTIVE"]  ))))
-
-
-
-       (div {:className "smallGap"})
+                            [new-todo-item-text  "ACTIVE"]  )))))

-       (realtime select
+
+
+
+
+
+(defn-ui-component     to-do-list-component   [app]
+  {}
+  (realtime select
                       id, item, item_status
                  from
                       coils_todo_items
@@ -81,51 +80,87 @@
                              (go
                               (sql "delete from  coils_todo_items  where id = ?"
                                    [(<-- :id)]  ))
-                                          false)})))
+                                          false)}))))

-                (div {:className "mediumGap"})

-                (let [active-items      (select id from  coils_todo_items where item_status = 'ACTIVE' {})
-                      total-items       (select id from  coils_todo_items {})
-                      completed-items   (select id from  coils_todo_items where item_status = 'COMPLETED' {})
-                      ]

-                  (if (pos? (count total-items))
-                    (do
-                      (div {:style {:height "30px"}})
-                      (div {:id "footer" :style {:backgroundColor "white" :fontSize "12"}}
-                           (container
-                            (div {:style {:width "27%" :display "inline-block;" :textAlign "left"}
-                                  }  (str (count active-items) " items left"))
+(defn-ui-component     to-do-footer-component   [app]
+  {}

-                            (button {:style {:width "9%" :border (str (if (nil? (read-ui app [:show])) "1px solid"))}
-                                     :onClick #(do (write-ui app [:show] nil) false)
-                                    } "ALL")
+  (let [active-items      (select id from  coils_todo_items where item_status = 'ACTIVE' {})
+        total-items       (select id from  coils_todo_items {})
+        completed-items   (select id from  coils_todo_items where item_status = 'COMPLETED' {})
+        ]

-                            (button {:style {:width "13%" :border (str (if (= "ACTIVE" (read-ui app [:show])) "1px solid"))}
-                                     :onClick #(do (write-ui app [:show] "ACTIVE") false)
-                                    } "Active")
+    (if (pos? (count total-items))
+      (do
+        (div {:style {:height "30px"}})
+        (div {:id "footer" :style {:backgroundColor "white" :fontSize "12"}}
+             (container
+               (div {:style {:width "27%" :display "inline-block;" :textAlign "left"}
+                     }  (str (count active-items) " items left"))

-                            (button {:style {:width "17%" :border (str (if (= "COMPLETED" (read-ui app [:show])) "1px solid"))}
-                                     :onClick #(do (write-ui app [:show] "COMPLETED") false)
-                                    } "Completed")
+               (button {:style {:width "9%" :border (str (if (nil? (read-ui app [:show])) "1px solid"))}
+                        :onClick #(do (write-ui app [:show] nil) false)
+                        } "ALL")

-                            (if (pos? (count completed-items))
-                              (button {:style {  :width "34%" :textAlign "right"}
-                                       :onClick #(do (go
-                                                   (sql "delete from  coils_todo_items  where item_status = 'COMPLETED'" []  ))
-                                                   false)
-                                                   } "Clear completed"))
+               (button {:style {:width "13%" :border (str (if (= "ACTIVE" (read-ui app [:show])) "1px solid"))}
+                        :onClick #(do (write-ui app [:show] "ACTIVE") false)
+                        } "Active")

-                            ))))))))
+               (button {:style {:width "17%" :border (str (if (= "COMPLETED" (read-ui app [:show])) "1px solid"))}
+                        :onClick #(do (write-ui app [:show] "COMPLETED") false)
+                        } "Completed")
+
+               (if (pos? (count completed-items))
+                 (button {:style {  :width "34%" :textAlign "right"}
+                          :onClick #(do (go
+                                          (sql "delete from  coils_todo_items  where item_status = 'COMPLETED'" []  ))
+                                      false)
+                          } "Clear completed"))
+
+               ))))))

-(def-coils-app     main-view   main-to-do-component)

+
+
+
+
+(defn-ui-component     main-to-do-app   [app]
+  {}
+  (section
+    {:className "todoapp"}
+    (header {} (h2 nil "Todo app"))
+    (div {:className "main_div"}
+
+
+         (component  new-do-item-component   app  [])
+
+
+         (div {:className "smallGap"})
+
+
+
+         (component  to-do-list-component   app  [])
+
+
+
+         (div {:className "mediumGap"})
+
+
+         (component  to-do-footer-component   app  [])
+
+
+                )))
+
+
+(def-coils-app     main-view   main-to-do-app)
+


print exception and message when using clj-stacktrace

--- src/cake.clj
+++ src/cake.clj
@@ -34,6 +34,7 @@

 (defn print-stacktrace [e]
   (if-let [pst-color (*config* "clj-stacktrace")]
-    (clj-stacktrace/pst-on *out* (= "color" pst-color) e)
+    (do (printf "%s: %s" (.getName (class e)) (.getMessage e))
+        (clj-stacktrace/pst-on *out* (= "color" pst-color) e))
     (do (stacktrace/print-cause-trace e)
         (flush))))


extract mktemp command generation to function

--- plugins/matross/tasks/temp_file.clj
+++ plugins/matross/tasks/temp_file.clj
@@ -2,6 +2,12 @@
   (:require [matross.tasks.core :refer [deftask run-task task-result]]
             [clojure.string :refer [trim-newline]]
             [me.raynes.conch.low-level :refer [stream-to-string]]))
+
+
+(defn temp-file-command
+  "Generates the mktemp shell command for the given options"
+  [{:keys [temp-dir] :or {temp-dir "/tmp"}}]
+  (str "mktemp " temp-dir "/matross.XXXXXX"))

 (deftask temp-file
   "Creates  a temporary file on the target machine and returns the file path in [:data :path]"
@@ -13,8 +19,8 @@
               '(with-temp-files [tmp-a tmp-b]
                  (use-temp-files tmp-a tmp-b))]}

-  [conn {:keys [temp-dir] :or {temp-dir "/tmp"}}]
-  (let [mktemp (str "mktemp " temp-dir "/matross.XXXXXX")
+  [conn opts]
+  (let [mktemp (temp-file-command opts)
         {:keys [data succeeded?]} (run-task conn {:type :command :command mktemp})
         temp-file (trim-newline (stream-to-string data :out))]
     (task-result succeeded? true (assoc data :path temp-file))))


need to do some regex magic -.-

need to do some regex magic -.-

--- src/leiningen/html_creator.clj
+++ src/leiningen/html_creator.clj
@@ -47,10 +47,11 @@

 ; create
 (defn insert-extra-tags [form-groups-str entity field]
-  (s/replace form-groups-str #"checkbox" "ble"
-             ;(str "type=\"checkbox\" " "{%if " entity "." field " = 1 %}checked{% endif %}")
-             )
-  form-groups-str)
+  (s/replace form-groups-str #"type=\"checkbox\""
+             (str "type=\"checkbox\" " "{%if " entity "." field " = 1 %}checked{% endif %}"))
+  )
+
+(def t "<input class=\"form-control\" id=\"male\" name=\"male\" type=\"checkbox\" />")

 (t/ann create-html [pt/entity-description -> String])
 (defn create-html [dataset]


ARM: mxs: add dtb-y target into Makefile.boot

Add dtb-y target into Makefile.boot, so that "make ARCH=arm dtbs" can
build out all the dtbs listed there.  It's very useful for build-testing
all the <board>.dts when imx28.dtsi changes.

Signed-off-by: Shawn Guo <912cf7eb7d8018e2943586ae6657d21fd4e38239@linaro.org>

--- arch/arm/mach-mxs/Makefile.boot
+++ arch/arm/mach-mxs/Makefile.boot
@@ -1 +1,10 @@
 zreladdr-y += 0x40008000
+
+dtb-y += apx4devkit.dtb \
+	 cfa10036.dtb \
+	 imx23-evk.dtb \
+	 imx23-olinuxino.dtb \
+	 imx28-evk.dtb \
+	 m28evk.dtb \
+	 stmp378x_devb.dtb \
+	 tx28.dtb \


CLJS-1416: cljs.util/last-modified leaks files

--- src/main/clojure/cljs/util.cljc
+++ src/main/clojure/cljs/util.cljc
@@ -142,7 +142,14 @@
 (defn last-modified [src]
   (cond
     (file? src) (.lastModified ^File src)
-    (url? src) (.getLastModified (.openConnection ^URL src))
+    (url? src)
+    (let [conn (.openConnection ^URL src)]
+      (try
+        (.getLastModified conn)
+        (finally
+          (let [ins (.getInputStream conn)]
+            (when ins
+              (.close ins))))))
     :else
     (throw
       (IllegalArgumentException. (str "Cannot get last modified for " src)))))


Ian: bootstrap theme with navbar

Ian: bootstrap theme with navbar

--- src/main/clojure/routr/web.clj
+++ src/main/clojure/routr/web.clj
@@ -102,12 +102,41 @@
      (include-js
        "http://code.jquery.com/jquery-2.1.1.min.js"
        "http://code.jquery.com/ui/1.11.2/jquery-ui.min.js"
-       "https://maxcdn.bootstrapcdn.com/bootstrap/3.2.0/js/bootstrap.min.js")
+       "https://maxcdn.bootstrapcdn.com/bootstrap/3.2.0/js/bootstrap.min.js"
+       (str "https://maps.googleapis.com/maps/api/js?key=" (System/getenv "GOOGLE_API_KEY")))
      (include-css "/css/root.css")
      [:title "Routr"]]
       [:body
-       [:p
-        (str "You (" (:name (:identity session)) ") are signed in!")]]))
+       [:nav {:class "navbar navbar-default navbar-fixed-top" :role "navigation"}
+        [:div {:class "container"}
+         [:div {:class "navbar-header"}
+          [:button {:type "button" :class "navbar-toggle collapsed" :data-toggle "collapse" :data-target "#navbar" :aria-expanded "false" :aria-controls "navbar"}
+           [:span {:class "sr-only"} "Toggle navigation"]
+           [:span {:class "icon-bar"}]
+           [:span {:class "icon-bar"}]
+           [:span {:class "icon-bar"}]
+           [:a {:class "navbar-brand" :href "#"} "Routr"]]
+          [:div {:id "navbar" :class "navbar-collapse collapse"}
+           [:ul {:class "nav navbar-nav"}
+            [:li {:class "active"}
+             [:a {:href "#"} "Home"]]
+            [:li {:class "active"} [:a {:href "#"} "Home"]]
+            [:li [:a {:href "#about"} "About"]]
+            [:li [:a {:href "#contact"} "Contact"]]
+            [:li {:class "dropdown"}
+             [:a {:href "#" :class "dropdown-toggle" :data-toggle "dropdown"} "Dropdown" [:span {:class "caret"}]]
+             [:ul {:class "dropdown-menu" :role "menu"}
+              [:li [:a {:href "#"} "Action"]]
+              [:li {:class "divider"}]
+              [:li {:class "dropdown-header"} "Navigation header"]
+              [:li [:a {:href "#"} "Another action"]]]]]
+           [:ul {:class "nav navbar-nav navbar-right"}
+              [:li [:a {:href "../navbar"} "Default"]]
+              [:li [:a {:href "../navbar-static-top"} "Static top"]]
+              [:li {:class "active"} [:a {:href "./"} "Fixed top"]]]]]]]
+
+       [:div {:class "container"}
+        [:p (str "You (" (:name (:identity session)) ") are signed in!")]]]))

 (defroutes the-routes
   (GET "/whereiam" [point]


Finally settle on a discard draw layer

Finally settle on a discard draw layer

--- cljs/src/gin/ui/game_panel.cljs
+++ cljs/src/gin/ui/game_panel.cljs
@@ -338,7 +338,8 @@
            (dom/set-card-class discard-card-el (str (name suit) "_" (name rank)))
            (animator/slide discard-card-el discard-position)))
        (when-let [discard-card-el (:dom/el (last discard-cards-es))]
-         (dom/show-on-top discard-card-el)
+         (when (= (count opp-cards-es) 10)
+           (dom/show-on-top discard-card-el))
          (if us-pick-card
            (set-drag-handler discard-card-el (discard-drag-handler conn))
            (set-drag-handler discard-card-el (undraggable-handler conn))))


Tweak to day 5.

Tweak to day 5.

--- clojure/src/advent2017/day5.clj
+++ clojure/src/advent2017/day5.clj
@@ -4,8 +4,7 @@

 (def puzzle (->> (clojure.java.io/reader "../2017/day5.data")
                  (line-seq)
-                 (map #(Integer/parseInt %))
-                 (vec)))
+                 (mapv #(Integer/parseInt %))))

 (defn solve [inc-fn input]
   (loop [input' (transient input)


Add loads more duplication, and we're done!

--- clojure/src/yatzy_clj/yatzy.clj
+++ clojure/src/yatzy_clj/yatzy.clj
@@ -14,13 +14,9 @@
     )
   )

-(defn tally-die [dice]
-  (for [i (range 1 7)]
-    (apply + (for [die dice] (if (= die i) 1 0))))
-  )
-
 (defn yatzy [dice]
-  (let [counts (tally-die dice)
+  (let [counts (for [i (range 1 7)]
+                 (apply + (for [die dice] (if (= die i) 1 0))))
         result (first
                  (remove nil?
                          (for [i (range 0 6)]
@@ -99,7 +95,8 @@
   )

 (defn score_pair [dice]
-  (let [counts (tally-die dice)
+  (let [counts (for [i (range 1 7)]
+                 (apply + (for [die dice] (if (= die i) 1 0))))
         result (first
                  (remove nil?
                          (for [at (range 0 6)]
@@ -113,7 +110,8 @@
     (if (= nil result) 0 result)))

 (defn two-pair [dice]
-  (let [counts (tally-die dice)
+  (let [counts (for [i (range 1 7)]
+                 (apply + (for [die dice] (if (= die i) 1 0))))
         values (remove nil?
                        (for [i (range 0 6)]
                          (if (>= (nth counts (- 6 i 1)) 2)
@@ -132,7 +130,8 @@
   )

 (defn four-of-a-kind [dice]
-  (let [tallies (tally-die dice)
+  (let [tallies (for [i (range 1 7)]
+                  (apply + (for [die dice] (if (= die i) 1 0))))
         result (first
                  (remove nil?
                          (for [i (range 0 6)]
@@ -196,7 +195,8 @@
       0)))

 (defn full-house [dice]
-  (let [tallies (tally-die dice)
+  (let [tallies (for [i (range 1 7)]
+                  (apply + (for [die dice] (if (= die i) 1 0))))
         _2_at (first
                 (remove nil?
                         (for [i (range 0 6)]


Fix problem with main ns name changing for each compilation

This broke the main shim after second compilation. Problem didn't occur
with boot-reload as it doesn't reload the shim.

--- src/adzerk/boot_cljs.clj
+++ src/adzerk/boot_cljs.clj
@@ -102,7 +102,8 @@
   (let [tmp-src (core/tmp-dir!)]
     {:pod         (new-pod! tmp-src)
      :initial-ctx {:tmp-src tmp-src
-                   :tmp-out (core/tmp-dir!)}}))
+                   :tmp-out (core/tmp-dir!)
+                   :main-ns-name (name (gensym "main"))}}))

 (defn- compile-1
   [compilers task-opts macro-changes write-main? {:keys [path] :as cljs-edn}]
@@ -113,7 +114,7 @@
   (let [{:keys [pod initial-ctx]} (get @compilers path)
         ctx (-> initial-ctx
                 (assoc :main (-> (read-cljs-edn cljs-edn)
-                                 (assoc :ns-name (name (gensym "main")))))
+                                 (assoc :ns-name (:main-ns-name initial-ctx))))
                 (wrap/compiler-options task-opts)
                 (wrap/main write-main?)
                 wrap/source-map)


Add documentation for :trigger/period and :trigger/threshold

--- src/onyx/information_model.cljc
+++ src/onyx/information_model.cljc
@@ -321,6 +321,20 @@
             {:doc "A fully qualified, namespaced keyword pointing to a function on the classpath at runtime. This function takes the window contents as its argument. Its return value is ignored. This function is invoked when the trigger fires, and is used to do any arbitrary action with the window contents, such as sync them to a database."
              :type :keyword
              :optional? false}
+
+            :trigger/period
+            {:doc "A timer trigger sleeps for a duration of `:trigger/period`. When it is done sleeping, the `:trigger/sync` function is invoked with its usual arguments. The trigger goes back to sleep and repeats itself."
+             :type :keyword
+             :required-when ["`:trigger/on` is `:timer`"]
+             :choices [:milliseconds :seconds :minutes :hours :days]
+             :optional? true}
+
+            :trigger/threshold
+            {:doc "A segment trigger will fire every threshold of segments."
+             :required-when ["`:trigger/on` is `:segments`"]
+             :type [:integer :elements]
+             :example [5 :elements]
+             :optional? true}

             :trigger/fire-all-extents?
             {:doc "When set to `true`, if any particular extent fires in reaction to this trigger, all extents also fire."


Fix components args.

Fix components args.

--- web-server/src/cljs/hatnik/web/client/components.cljs
+++ web-server/src/cljs/hatnik/web/client/components.cljs
@@ -22,23 +22,23 @@
                     (dom/div #js {:className "panel-body"}
                              body))))

-(defn render-action [action]
+(defn render-action [project-id action]
   (dom/p nil
          (get action "type")))

-(defn actions-table [actions]
+(defn actions-table [id actions]
   (let [rendered
         (map (fn [action]
                (dom/div #js {:className "col-md-4"}
-                        (render-action action)))
+                        (render-action id action)))
              actions)]
     (apply dom/div #js {:className "row"}
            (concat rendered
                    [(dom/div #js {:className "col-md-4"}
                              (dom/p nil "Add new Action"))]))))

-(defn project-header [project]
+(defn project-header [id project]
   (dom/div #js {:className "project-header"}
    (dom/p nil (get project "name"))
    (dom/span #js {:className "glyphicon glyphicon-pencil project-header-button"})))
@@ -51,7 +51,7 @@
        (map
         (fn [prj]
           (accordion-panel
-           :header (project-header prj)
-           :body (actions-table (get prj "actions"))
+           :header (project-header (get prj "id") prj)
+           :body (actions-table (get prj "id") (get prj "actions"))
            :body-id (str "__" (get prj "name"))))
         (:projects data))))))


Made the shader use the program.

Made the shader use the program.

--- src/petulant_life/rendering.clj
+++ src/petulant_life/rendering.clj
@@ -108,8 +108,14 @@
   (GL30/glBindVertexArray vao)
   (GL20/glEnableVertexAttribArray 0)

+  ;; Using a shader.
+  (GL20/glUseProgram shader)
+
   ;; Actually drawing the square.
   (GL11/glDrawArrays GL11/GL_TRIANGLES 0 (* 2 vct))
+
+  ;; Disabling the shader.
+  (GL20/glUseProgram 0)

   ;; Cleaning up the VAO.
   (GL20/glDisableVertexAttribArray 0)


Move processing out of find-symbol-reply

--- src/refactor_nrepl/refactor.clj
+++ src/refactor_nrepl/refactor.clj
@@ -68,7 +68,7 @@
   (or (contains-var var-name alias-info node)
       (contains-const? var-name alias-info node)))

-(defn- find-symbol [name ast]
+(defn- find-symbol-in-ast [name ast]
   (when ast
     (find-nodes ast (partial contains-var-or-const? name (alias-info ast)))))

@@ -96,7 +96,7 @@
   (let [file-content (slurp file)
         locs (->> file-content
                   ns-ast
-                  (find-symbol fully-qualified-name)
+                  (find-symbol-in-ast fully-qualified-name)
                   (filter #(first %)))]
     (when-not (empty? locs)
       (map #(conj % (.getCanonicalPath file) (match file-content (first %) (second %)))
@@ -148,13 +148,16 @@
         (->> (find-nodes [top-level-form-ast] #(and (#{:local :binding} (:op %)) (= local-var-name (-> % :name)) (:local %)))
              (map #(conj (vec (take 4 %)) var-name (.getCanonicalPath (java.io.File. file)) (match ns-string (first %) (second %)))))))))

-(defn- find-symbol-reply [{:keys [transport file ns name clj-dir loc-line loc-column] :as msg}]
+(defn- find-symbol [{:keys [file ns name clj-dir loc-line loc-column]}]
+  (or (when (and file (not-empty file)) (not-empty (find-local-symbol file name loc-line loc-column)))
+      (find-global-symbol file ns name clj-dir)))
+
+(defn- find-symbol-reply [{:keys [transport] :as msg}]
   (try
-    (let [syms (or (when (and file (not-empty file)) (not-empty (find-local-symbol file name loc-line loc-column)))
-                      (find-global-symbol file ns name clj-dir))]
-      (doseq [found-sym syms]
-        (transport/send transport (response-for msg :occurrence found-sym)))
-      (transport/send transport (response-for msg :syms-count (count syms)
+    (let [occurrences (find-symbol msg)]
+      (doseq [occurrence occurrences]
+        (transport/send transport (response-for msg :occurrence occurrence)))
+      (transport/send transport (response-for msg :syms-count (count occurrences)
                                               :status :done)))
     (catch Exception e
       (transport/send transport


link to tag in model page

link to tag in model page

--- src/semtag_web/client/view.cljs
+++ src/semtag_web/client/view.cljs
@@ -13,6 +13,10 @@
       (str (.substring s 0 (- max-length 3)) "...")
       s)))

+;;; link fns
+(defn- link-tag [tag]
+  [:a {:href (str "/tag/" tag)} tag])
+
 ;;; td formatters
 (defn- td-url [url]
   [:td [:a {:href url} (shorten-to url 40)]])
@@ -21,9 +25,7 @@
   [:td
   (interpose
     ", "
-    (map
-      (fn [tag] (vec [:a {:href (str "/tag/" tag)} tag]))
-      (string/split tags #";")))])
+    (map link-tag (string/split tags #";")))])

 (defn- td-model [model]
    [:td [:a {:href (str "/" model)} model]])
@@ -69,7 +71,7 @@

 (defpartial model-row [row & fields]
   [:tr
-   [:td (:name row)]
+   [:td (if (seq (:name row)) (link-tag (:name row)) (:name row))]
    (td-url (:url row))
    [:td (:desc row)]
    (td-tags (:tags row))])


CLJS-672: source maps + optimizations + :libs breaks building

Only copy over files to the output directory if the js file record
contains :source-url information.

--- src/clj/cljs/closure.clj
+++ src/clj/cljs/closure.clj
@@ -890,15 +890,18 @@
     (if (or (not url)
             (= (.getProtocol url) "jar"))
       (write-javascript opts js)
+      ;; always copy original sources to the output directory
+      ;; when source maps enabled
       (let [out-file (if-let [ns (and (:source-map opts)
                                       (first (:provides js)))]
                        (io/file (io/file (output-directory opts))
-                         (ana/ns->relpath ns)))]
-        (when (and out-file
+                         (ana/ns->relpath ns)))
+            source-url (:source-url js)]
+        (when (and out-file source-url
                    (or (not (.exists ^File out-file))
-                       (> (.lastModified (io/file (:source-url js)))
+                       (> (.lastModified (io/file source-url))
                           (.lastModified out-file))))
-          (spit out-file (slurp (:source-url js))))
+          (spit out-file (slurp source-url)))
         js))))

 (comment


log optimization activity under :verbose

--- src/clj/cljs/closure.clj
+++ src/clj/cljs/closure.clj
@@ -881,6 +881,8 @@
 (defn optimize
   "Use the Closure Compiler to optimize one or more JavaScript files."
   [opts & sources]
+  (when (or *verbose* (:verbose opts))
+    (util/debug-prn "Applying optimizations" (:optimizations opts)))
   (let [closure-compiler (make-closure-compiler)
         ^List externs (load-externs opts)
         compiler-options (make-options opts)


During build, compile any required cljs file that is on the classpath.

--- src/clj/cljs/closure.clj
+++ src/clj/cljs/closure.clj
@@ -365,6 +365,12 @@
   (let [state (build-index coll)]
     (distinct (:order (reduce comp/dependency-order-visit (assoc state :order []) (keys state))))))

+(defn js-dependency-index
+  "Returns the index for all JavaScript dependencies. Lookup by
+  namespace or file name."
+  [opts]
+  (build-index (concat (goog-dependencies) (library-dependencies opts))))
+
 (defn dependencies
   "Given a sequence of Closure namespace strings, return the list of
   all dependencies in dependency order. The returned list includes all
@@ -374,7 +380,7 @@
   the value is a list of directories containing third-party
   libraries."
   [opts requires]
-  (let [index (build-index (concat (goog-dependencies) (library-dependencies opts)))]
+  (let [index (js-dependency-index opts)]
     (loop [requires requires
            deps []]
       (if (seq requires)
@@ -418,17 +424,18 @@
   files will be compiled to the working directory if they do not
   already exist."
   [opts requires]
-  (letfn [(cljs-deps [coll] (filter #(.startsWith % "cljs.") coll))]
-    (loop [requires (cljs-deps requires)
-           deps {}]
-      (if (seq requires)
-        (let [next-ns (first requires)
-              js (get-compiled-cljs opts next-ns)
-              new-requires (remove #(or (contains? deps %)
-                                        (contains? (set requires) %))
-                                   (cljs-deps (-requires js)))]
-          (recur (concat (rest requires) new-requires) (assoc deps next-ns js)))
-        (dependency-order (vals deps))))))
+  (let [index (js-dependency-index opts)]
+    (letfn [(cljs-deps [coll] (filter #(not (contains? index %)) coll))]
+     (loop [requires (cljs-deps requires)
+            deps {}]
+       (if (seq requires)
+         (let [next-ns (first requires)
+               js (get-compiled-cljs opts next-ns)
+               new-requires (remove #(or (contains? deps %)
+                                         (contains? (set requires) %))
+                                    (cljs-deps (-requires js)))]
+           (recur (concat (rest requires) new-requires) (assoc deps next-ns js)))
+         (dependency-order (vals deps)))))))

 (comment
   ;; only get cljs deps
@@ -447,12 +454,13 @@
   (let [requires (mapcat -requires inputs)
         required-cljs (cljs-dependencies opts requires)
         required (dependencies opts (concat (mapcat -requires required-cljs) requires))]
-    (concat (map #(-> (javascript-file (or (:url %) (io/resource (:file %)))
-                                       (:provides %)
-                                       (:requires %))
-                      (assoc :group (:group %))) required)
-            required-cljs
-            inputs)))
+    (distinct
+     (concat (map #(-> (javascript-file (or (:url %) (io/resource (:file %)))
+                                        (:provides %)
+                                        (:requires %))
+                       (assoc :group (:group %))) required)
+             required-cljs
+             inputs))))

 (comment
   ;; add dependencies to literal js


fix docstring - merge doesn't flow

fix docstring - merge doesn't flow

--- src/clj/clojure/spec.clj
+++ src/clj/clojure/spec.clj
@@ -444,8 +444,7 @@
 (defmacro merge
   "Takes map-validating specs (e.g. 'keys' specs) and
   returns a spec that returns a conformed map satisfying all of the
-  specs.  Successive conformed values propagate through rest of
-  predicates. Unlike 'and', merge can generate maps satisfying the
+  specs.  Unlike 'and', merge can generate maps satisfying the
   union of the predicates."
   [& pred-forms]
   `(merge-spec-impl '~(mapv res pred-forms) ~(vec pred-forms) nil))


Hint return type, eliminates lots of reflection warnings in tests

--- src/clj_http/cookies.clj
+++ src/clj_http/cookies.clj
@@ -38,7 +38,8 @@
      :value (.getValue cookie)
      :version (.getVersion cookie)})])

-(defn to-basic-client-cookie
+(defn ^org.apache.http.impl.cookie.BasicClientCookie2
+  to-basic-client-cookie
   "Converts a cookie seq into a BasicClientCookie2."
   [[cookie-name cookie-content]]
   (doto (BasicClientCookie2. (name cookie-name)


Moved time to hero

Moved time to hero

No more bouncing ...

--- src/cljs/kenny/core.cljs
+++ src/cljs/kenny/core.cljs
@@ -56,6 +56,7 @@
    :life 100
    :position (hero-start-position grid-content)
    :game-won false
+   :time [60]
    }
   )

@@ -66,7 +67,6 @@
                    :settings {:bounce [3]
                               :red-trampete [5]
                               :blue-trampete [3]
-                              :time [60]
                               }})

 (def app-state (local-storage (atom default-data) "game"))
@@ -200,15 +200,14 @@
     )
   )

-(defn time-up? [settings app hero]
-  (if (> 0 (first (get-in settings [:time])))
-    (merge hero {:life 0})
-    (do
-      (om/transact! app [:settings :time 0] (fn [old-time] (do
-                                                             (console-log old-time)
-                                                             (- old-time 0.04))))
-      hero
-          )))
+(defn time-up? [original-hero app hero]
+
+    (if (> 0 (get-in original-hero [:time 0]))
+      (update-in hero [:life] (fn [_] 0))
+      (update-in hero [:time 0] - 0.04)
+      )
+
+  )

 (defn game-over? [original-hero hero]
   (if (or (> 0 (get-in hero [:position :bottom]))
@@ -235,11 +234,11 @@
                            ((partial vertical-block original-hero))
                            move-left
                            move-right
-                           ((partial bouncing bounce))
+                           ;;((partial bouncing bounce))
                            ((partial on-blue-trampete? blue-trampete))
                            ((partial on-red-trampete? red-trampete))
                            spike-damage
-                           ((partial time-up? settings app))
+                           ((partial time-up? original-hero app))
                            ((partial home? original-hero))
                            ((partial game-over? original-hero))
                            )]
@@ -349,7 +348,7 @@
                             ))
     ))

-(defn settings-form [settings]
+(defn settings-form [app]
   (reify
     om/IRenderState
     (render-state [this state]
@@ -357,15 +356,15 @@
                  (dom/tbody nil
                             (dom/tr nil
                                     (dom/th nil "Red Trampoline")
-                                    (om/build table-cell (:red-trampete settings) {:init-state {:options (mapv (fn [i] [i]) (range 1 7))}})
+                                    (om/build table-cell (get-in app [:settings :red-trampete]) {:init-state {:options (mapv (fn [i] [i]) (range 1 7))}})
                                     )
                             (dom/tr nil
                                     (dom/th nil "Blue Trampoline")
-                                    (om/build table-cell (:blue-trampete settings) {:init-state {:options (mapv (fn [i] [i]) (range 1 7))}})
+                                    (om/build table-cell (get-in app [:settings :blue-trampete]) {:init-state {:options (mapv (fn [i] [i]) (range 1 7))}})
                                     )
                             (dom/tr nil
                                     (dom/th nil "Spiel Dauer")
-                                    (om/build table-cell (:time settings) {:init-state {:options (mapv (fn [i] [i]) (range 30 61))}})
+                                    (om/build table-cell (get-in app [:hero :time]) {:init-state {:options (mapv (fn [i] [i]) (range 30 61))}})
                                     )
                             )

@@ -442,7 +441,7 @@
                (dom/h2 nil "Der Raster")
                (om/build grid-table (:grid app))
                (dom/h2 nil "Einstellungen")
-               (om/build settings-form (:settings app))
+               (om/build settings-form app)
                )
       )))

@@ -451,7 +450,7 @@
     om/IRender
     (render [this]
       (dom/div #js {:className "status-bar"}
-               (dom/span #js {:className "life"} (str "Time: " (ceil (first (get-in app [:settings :time])))))
+               (dom/span #js {:className "life"} (str "Time: " (ceil (get-in app [:hero :time 0]))))
                (dom/span #js {:className "life"} (str "Leben: " (get-in app [:hero :life]) "%"))
                (dom/button #js {:onClick (fn [e] (do
                                                    (om/transact! app [:hero] (fn [_] default-hero))


Reduze z-index to allow fighweel popup

Reduze z-index to allow fighweel popup

--- src/cljs/klang/core.cljs
+++ src/cljs/klang/core.cljs
@@ -124,7 +124,7 @@
               :width "calc(100% - 2em - 8em)"
               :top "1em"
               :height "calc(100% - 2em)"
-              :z-index 87509
+              :z-index 9922 ;; fighweel has 10k
               :color "#fff"
               :background "#000"
               :padding 0
@@ -140,7 +140,7 @@
     :width "calc(8em)"
     :top "1em"
     :height "calc(100% - 2em)"
-    :z-index 87509
+    :z-index 9922
     :color "#fff"
     :background "#000"
     :opacity .9


Return time elapsed as a float.

Return time elapsed as a float.

--- src/cmr/opendap/util.clj
+++ src/cmr/opendap/util.clj
@@ -23,7 +23,7 @@

 (defn timed
   [start]
-  (- (now) start))
+  (float (- (now) start)))

 (defn most-frequent
   "This identifies the most frequently occuring data in a collection


add function to get all code files

add function to get all code files

--- src/codeitlater/core.clj
+++ src/codeitlater/core.clj
@@ -1,4 +1,5 @@
 (ns codeitlater.core
+  (:require [clojure.java.io :as io])
   (:gen-class))

 (def testMark "//")
@@ -22,9 +23,22 @@
         (list lineNum comment))
       )))

+(defn get-all-files
+  ([]
+   (doall (map #(.getPath %) (file-seq (io/file ".")))))
+  ([root]
+   (doall (map #(.getPath %) (file-seq (io/file root)))))
+  ([root & filetypes]
+   (let [typepatterns (for [filetype filetypes] (re-pattern (str filetype "$")))]
+     (for [thisfile (doall (file-seq (io/file root)))
+           typepattern typepatterns
+           :let [filename (.getPath thisfile)]
+           :when (re-find typepattern filename)]
+       filename)))
+  )
+
 (defn -main [& args]
   (println args)
   (println (read-comments-inline (make-pattern testMark) "aaa//test"))
   (println (read-comments-in-file "/Users/ccQ/Desktop/log"
                                   (partial read-comments-inline (make-pattern testMark)))))
-