Remove let over the tests

Remove let over the tests

--- test/clojure/clojurewerkz/cassaforte/cql_test.clj
+++ test/clojure/clojurewerkz/cassaforte/cql_test.clj
@@ -1,6 +1,6 @@
 (ns clojurewerkz.cassaforte.cql-test
   (:refer-clojure :exclude [update])
-  (:require [clojurewerkz.cassaforte.test-helper :as th]
+  (:require [clojurewerkz.cassaforte.test-helper :as th :refer [*session*]]
             [clojurewerkz.cassaforte.client      :as client]
             [clojurewerkz.cassaforte.policies    :as cp]
             [clojurewerkz.cassaforte.uuids       :as uuids]
@@ -20,270 +20,294 @@
 (use-fixtures :each th/with-temporary-keyspace)

-(let [s (th/make-test-session)]
-  (deftest test-insert
-    (let [r {:name "Alex" :city "Munich" :age (int 19)}]
-      (insert s :users r)
-      (is (= r (first (select s :users))))
-      (truncate s :users)))
-
-  (deftest test-update
-    (testing "Simple updates"
-      (let [r {:name "Alex" :city "Munich" :age (int 19)}]
-        (insert s :users r)
-        (is (= r (first (select s :users))))
-        (update s :users
-                {:age (int 25)}
-                (where {:name "Alex"}))
-        (is (= {:name "Alex" :city "Munich" :age (int 25)}
-               (first (select s :users))))))
-
-    (testing "One of many update"
-      (dotimes [i 3]
-        (insert s :user_posts {:username "user1"
-                               :post_id (str "post" i)
-                               :body (str "body" i)}))
-
-      (update s :user_posts
-              {:body "bodynew"}
-              (where {:username "user1"
-                      :post_id "post1"}))
-      (is (= "bodynew"
-             (get-in
-              (select s :user_posts
-                      (where {:username "user1"
-                              :post_id "post1"}))
-              [0 :body])))))
-
-
-  (deftest test-update-with-compound-key
-    (let [t   :events_by_device_id_and_date
-          fmt (tf/formatter "yyyy-MM-dd")
-          id  "device-000000001"
-          qc  [[=  :device_id id]
-               [=  :date "2014-11-13"]
-               [=  :created_at (uuids/start-of (cc/to-long (date-time 2014 11 13 12)))]]]
-      (testing "Bulk update"
-        (truncate s t)
-        (is (= 0 (perform-count s t)))
-        (doseq [i  (range 1 15)]
-          (let [dt (date-time 2014 11 i 12)
-                td (uuids/start-of (cc/to-long dt))]
-
-            (insert s t {:created_at td
-                         :device_id  id
-                         :date       (tf/unparse fmt dt)
-                         :payload    (str "body" i)})))
-        (is (= 14 (perform-count s t)))
-        (is (= 14 (count (select s t))))
-        (is (= 1  (count (select s t (where qc)))))
-        (update s t
-                {:payload "updated payload"}
-                (where qc))
-        (let [x (first (select s t (where qc)))]
-          (is (= "updated payload" (:payload x))))
-        (truncate s t))))
-
-  (deftest test-delete
-    (testing "Delete whole row"
-      (dotimes [i 3]
-        (insert s :users {:name (str "name" i) :age (int i)}))
-      (is (= 3 (perform-count s :users)))
-      (delete s :users
-              (where {:name "name1"}))
-      (is (= 2 (perform-count s :users)))
-      (truncate s :users))
-
-    (testing "Delete a column"
-      (insert s :users {:name "name1" :age (int 19)})
-      (delete s :users
-              (columns :age)
-              (where {:name "name1"}))
-      (is (nil? (:age (select s :users))))
-      (truncate s :users)))
-
-  (deftest test-insert-with-timestamp
-    (let [r {:name "Alex" :city "Munich" :age (int 19)}]
-      (insert s :users r
-              (using {:timestamp (.getTime (java.util.Date.))}))
-      (is (= r (first (select s :users))))
-      (truncate s :users)))
-
-  (deftest test-ttl
+(deftest test-insert
+  (let [r {:name "Alex" :city "Munich" :age (int 19)}]
+    (insert *session* :users r)
+    (is (= r (first (select *session* :users))))
+    (truncate *session* :users)))
+
+(deftest test-update
+  (testing "Simple updates"
+    (let [r {:name "Alex"
+             :city "Munich"
+             :age  (int 19)}]
+      (insert *session* :users r)
+      (is (= r (first (select *session* :users))))
+      (update *session* :users
+              {:age (int 25)}
+              (where {:name "Alex"}))
+      (is (= {:name "Alex" :city "Munich" :age (int 25)}
+             (first (select *session* :users))))))
+
+  (testing "One of many update"
     (dotimes [i 3]
-      (insert s :users {:name (str "name" i)
-                        :city (str "city" i)
-                        :age  (int i)}
-              (using {:ttl (int 2)})))
-    (is (= 3 (perform-count s :users)))
-    (Thread/sleep 2100)
-    (is (= 0 (perform-count s :users))))
-
-
-  (deftest test-counter
-    (testing "Increment by"
-      (update s :user_counters
-              {:user_count (new-query-api/increment-by 5)}
-              (where {:name "user1"}))
-
-      (is (= 5 (-> (select s :user_counters)
+      (insert *session* :user_posts {:username "user1"
+                                     :post_id (str "post" i)
+                                     :body (str "body" i)}))
+
+    (update *session* :user_posts
+            {:body "bodynew"}
+            (where {:username "user1"
+                    :post_id "post1"}))
+    (is (= "bodynew"
+           (get-in
+            (select *session* :user_posts
+                    (where {:username "user1"
+                            :post_id "post1"}))
+            [0 :body])))))
+
+
+(deftest test-update-with-compound-key
+  (let [t   :events_by_device_id_and_date
+        fmt (tf/formatter "yyyy-MM-dd")
+        id  "device-000000001"
+        qc  [[=  :device_id id]
+             [=  :date "2014-11-13"]
+             [=  :created_at (uuids/start-of (cc/to-long (date-time 2014 11 13 12)))]]]
+    (testing "Bulk update"
+      (truncate *session* t)
+      (is (= 0 (perform-count *session* t)))
+      (doseq [i  (range 1 15)]
+        (let [dt (date-time 2014 11 i 12)
+              td (uuids/start-of (cc/to-long dt))]
+
+          (insert *session* t {:created_at td
+                               :device_id  id
+                               :date       (tf/unparse fmt dt)
+                               :payload    (str "body" i)})))
+      (is (= 14 (perform-count *session* t)))
+      (is (= 14 (count (select *session* t))))
+      (is (= 1  (count (select *session* t (where qc)))))
+      (update *session* t
+              {:payload "updated payload"}
+              (where qc))
+      (let [x (first (select *session* t (where qc)))]
+        (is (= "updated payload" (:payload x))))
+      (truncate *session* t))))
+
+(deftest test-delete
+  (testing "Delete whole row"
+    (dotimes [i 3]
+      (insert *session* :users {:name (str "name" i)
+                                :age (int i)}))
+    (is (= 3 (perform-count *session* :users)))
+    (delete *session* :users
+            (where {:name "name1"}))
+    (is (= 2 (perform-count *session* :users)))
+    (truncate *session* :users))
+
+  (testing "Delete a column"
+    (insert *session* :users {:name "name1" :age (int 19)})
+    (delete *session* :users
+            (columns :age)
+            (where {:name "name1"}))
+    (is (nil? (:age (select *session* :users))))
+    (truncate *session* :users)))
+
+(deftest test-insert-with-timestamp
+  (let [r {:name "Alex" :city "Munich" :age (int 19)}]
+    (insert *session* :users
+            r
+            (using {:timestamp (.getTime (java.util.Date.))}))
+    (is (= r (first (select *session* :users))))
+    (truncate *session* :users)))
+
+(deftest test-ttl
+  (dotimes [i 3]
+    (insert *session* :users {:name (str "name" i)
+                              :city (str "city" i)
+                              :age  (int i)}
+            (using {:ttl (int 2)})))
+  (is (= 3 (perform-count *session* :users)))
+  (Thread/sleep 2100)
+  (is (= 0 (perform-count *session* :users))))
+
+
+(deftest test-counter
+  (testing "Increment by"
+    (update *session* :user_counters
+            {:user_count (new-query-api/increment-by 5)}
+            (where {:name "user1"}))
+
+    (is (= 5 (-> (select *session* :user_counters)
+                 first
+                 :user_count))))
+
+  (testing "Decrement by"
+    (update *session* :user_counters
+            {:user_count (new-query-api/decrement-by 5)}
+            (where {:name "user1"}))
+
+    (is (= 0 (-> (select *session* :user_counters)
+                 first
+                 :user_count))))
+
+  (testing "Increment with explicit params"
+    (update *session* :user_counters
+            {:user_count (new-query-api/increment-by 500)}
+            (where {:name "user1"}))
+    (is (= 500 (-> (select *session* :user_counters)
                    first
                    :user_count))))

-    (testing "Decrement by"
-      (update s :user_counters
-              {:user_count (new-query-api/decrement-by 5)}
-              (where {:name "user1"}))
-
-      (is (= 0 (-> (select s :user_counters)
-                   first
-                   :user_count))))
-
-    (testing "Increment with explicit params"
-      (update s :user_counters
-              {:user_count (new-query-api/increment-by 500)}
-              (where {:name "user1"}))
-      (is (= 500 (-> (select s :user_counters)
-                     first
-                     :user_count))))
-
-    (testing "Decrement with explicit params"
-      (update s :user_counters
-              {:user_count (new-query-api/increment-by 5000000)}
-              (where {:name "user1"}))
-      (is (= 5000500 (-> (select s :user_counters)
-                         first
-                         :user_count))))
-
-    (testing "Increment with a large number"
-      (update s :user_counters
-              {:user_count (new-query-api/increment-by 50000000000000)}
-              (where {:name "user1"}))
-      (is (= 50000005000500 (-> s
-                                (select :user_counters)
-                                first
-                                :user_count)))))
-
-  (deftest test-counter-2
-    (dotimes [i 100]
-      (update s :user_counters
-              {:user_count (new-query-api/increment)}
-              (where {:name "user1"})))
-    (is (= 100 (-> (select s :user_counters)
-                   first
-                   :user_count))))
-
-  (deftest test-index-filtering-range
-    (create-index s :city
-                  (new-query-api/on-table :users)
-                  (new-query-api/and-column :city))
-    (create-index s :age
-                  (new-query-api/on-table :users)
-                  (new-query-api/and-column :age))
-
-    (dotimes [i 10]
-      (insert s :users {:name (str "name_" i)
-                        :city "Munich"
-                        :age  (int i)}))
-
+  (testing "Decrement with explicit params"
+    (update *session* :user_counters
+            {:user_count (new-query-api/increment-by 5000000)}
+            (where {:name "user1"}))
+    (is (= 5000500 (-> (select *session* :user_counters)
+                       first
+                       :user_count))))
+
+  (testing "Increment with a large number"
+    (update *session* :user_counters
+            {:user_count (new-query-api/increment-by 50000000000000)}
+            (where {:name "user1"}))
+    (is (= 50000005000500 (-> *session*
+                              (select :user_counters)
+                              first
+                              :user_count)))))
+
+(deftest test-counter-2
+  (dotimes [i 100]
+    (update *session* :user_counters
+            {:user_count (new-query-api/increment)}
+            (where {:name "user1"})))
+  (is (= 100 (-> (select *session* :user_counters)
+                 first
+                 :user_count))))
+
+(deftest test-index-filtering-range
+  (create-index *session* :city
+                (new-query-api/on-table :users)
+                (new-query-api/and-column :city))
+  (create-index *session* :age
+                (new-query-api/on-table :users)
+                (new-query-api/and-column :age))
+
+  (dotimes [i 10]
+    (insert *session* :users {:name (str "name_" i)
+                              :city "Munich"
+                              :age  (int i)}))
+
+  (is (= (set (range 6 10))
+         (->> (select *session* :users
+                      (where [[= :city "Munich"]
+                              [> :age (int 5)]])
+                      (allow-filtering))
+              (map :age)
+              set))))
+
+(deftest test-index-filtering-range-alt-syntax
+  (create-index *session* :city
+                (new-query-api/on-table :users)
+                (new-query-api/and-column :city))
+  (create-index *session* :age
+                (new-query-api/on-table :users)
+                (new-query-api/and-column :age))
+
+  (dotimes [i 10]
+    (insert *session* :users {:name (str "name_" i)
+                              :city "Munich"
+                              :age  (int i)}))
+
+  (let [res (select *session* :users
+                    (where [[= :city "Munich"]
+                            [> :age (int 5)]])
+                    (allow-filtering))]
     (is (= (set (range 6 10))
-           (->> (select s :users
-                        (where [[= :city "Munich"]
-                                [> :age (int 5)]])
-                        (allow-filtering))
+           (->> res
                 (map :age)
                 set))))
-
-  (deftest test-index-filtering-range-alt-syntax
-    (create-index s :city
-                  (new-query-api/on-table :users)
-                  (new-query-api/and-column :city))
-    (create-index s :age
-                  (new-query-api/on-table :users)
-                  (new-query-api/and-column :age))
-
-    (dotimes [i 10]
-      (insert s :users {:name (str "name_" i)
-                        :city "Munich"
-                        :age  (int i)}))
-
-    (let [res (select s :users
-                      (where [[= :city "Munich"]
-                              [> :age (int 5)]])
-                      (allow-filtering))]
-      (is (= (set (range 6 10))
-             (->> res
-                  (map :age)
-                  set))))
-    (truncate s :users))
-
-  (deftest test-index-exact-match
-    (create-index s :city
-                  (new-query-api/on-table :users)
-                  (new-query-api/and-column :city))
-    (create-index s :age
-                  (new-query-api/on-table :users)
-                  (new-query-api/and-column :age))
-
-    (dotimes [i 10]
-      (insert s :users {:name (str "name_" i)
-                        :city (str "city_" i)
-                        :age  (int i)}))
-
-    (let [res (select s :users
-                      (where {:city "city_5"})
-                      (allow-filtering))]
-      (is (= 5
-             (-> res
-                 first
-                 :age))))
-    (truncate s :users)))
-
-;; (deftest test-select-where
-;;   (insert s :users {:name "Alex"   :city "Munich"        :age (int 19)})
-;;   (insert s :users {:name "Robert" :city "Berlin"        :age (int 25)})
-;;   (insert s :users {:name "Sam"    :city "San Francisco" :age (int 21)})
-
-;;   (is (= "Munich" (get-in (select s :users (where {:name "Alex"})) [0 :city]))))
-
-;; (deftest test-select-where-without-fetch
-;;   (insert s :users {:name "Alex"   :city "Munich"        :age (int 19)})
-;;   (insert s :users {:name "Robert" :city "Berlin"        :age (int 25)})
-;;   (insert s :users {:name "Sam"    :city "San Francisco" :age (int 21)})
-
-;;   (is (= "Munich" (get-in (client/execute s
-;;                                           "SELECT * FROM users where name='Alex';"
-;;                                           :fetch-size Integer/MAX_VALUE) [0 :city]))))
-
-;; (deftest test-select-in
-;;   (insert s :users {:name "Alex"   :city "Munich"        :age (int 19)})
-;;   (insert s :users {:name "Robert" :city "Berlin"        :age (int 25)})
-;;   (insert s :users {:name "Sam"    :city "San Francisco" :age (int 21)})
-
-;;   (let [users (select s :users
-;;                       (where [[:in :name ["Alex" "Robert"]]]))]
-;;     (is (= "Munich" (get-in users [0 :city])))
-;;     (is (= "Berlin" (get-in users [1 :city])))))
-
-;; (deftest test-select-order-by
-;;   (dotimes [i 3]
-;;     (insert s :user_posts {:username "Alex" :post_id  (str "post" i) :body (str "body" i)}))
-
-;;   (is (= [{:post_id "post0"}
-;;           {:post_id "post1"}
-;;           {:post_id "post2"}]
-;;          (select s :user_posts
-;;                  (columns :post_id)
-;;                  (where {:username "Alex"})
-;;                  (order-by [:post_id]))))
-
-;;   (is (= [{:post_id "post2"}
-;;           {:post_id "post1"}
-;;           {:post_id "post0"}]
-;;          (select s :user_posts
-;;                  (columns :post_id)
-;;                  (where {:username "Alex"})
-;;                  (order-by [:post_id :desc])))))
+  (truncate *session* :users))
+
+(deftest test-index-exact-match
+  (create-index *session* :city
+                (new-query-api/on-table :users)
+                (new-query-api/and-column :city))
+  (create-index *session* :age
+                (new-query-api/on-table :users)
+                (new-query-api/and-column :age))
+
+  (dotimes [i 10]
+    (insert *session* :users {:name (str "name_" i)
+                              :city (str "city_" i)
+                              :age  (int i)}))
+
+  (let [res (select *session* :users
+                    (where {:city "city_5"})
+                    (allow-filtering))]
+    (is (= 5
+           (-> res
+               first
+               :age))))
+  (truncate *session* :users))
+
+(deftest test-select-where
+  (insert *session* :users {:name "Alex"
+                            :city "Munich"
+                            :age  (int 19)})
+  (insert *session* :users {:name "Robert"
+                            :city "Berlin"
+                            :age  (int 25)})
+  (insert *session* :users {:name "Sam"
+                            :city "San Francisco"
+                            :age  (int 21)})
+
+  (is (= "Munich" (get-in (select *session* :users (where {:name "Alex"})) [0 :city]))))
+
+(deftest test-select-where-without-fetch
+  (insert *session* :users {:name "Alex"
+                            :city "Munich"
+                            :age (int 19)})
+  (insert *session* :users {:name "Robert"
+                            :city "Berlin"
+                            :age  (int 25)})
+  (insert *session* :users {:name "Sam"
+                            :city "San Francisco"
+                            :age  (int 21)})
+
+  (is (= "Munich" (get-in (client/execute *session*
+                                          "SELECT * FROM users where name='Alex';"
+                                          :fetch-size Integer/MAX_VALUE) [0 :city]))))
+
+(deftest test-select-in
+  (insert *session* :users {:name "Alex"
+                            :city "Munich"
+                            :age  (int 19)})
+  (insert *session* :users {:name "Robert"
+                            :city "Berlin"
+                            :age  (int 25)})
+  (insert *session* :users {:name "Sam"
+                            :city "San Francisco"
+                            :age  (int 21)})
+
+  (let [users (select *session* :users
+                      (where [[:in :name ["Alex" "Robert"]]]))]
+    (is (= "Munich" (get-in users [0 :city])))
+    (is (= "Berlin" (get-in users [1 :city])))))
+
+(deftest test-select-order-by
+  (dotimes [i 3]
+    (insert *session* :user_posts
+            {:username "Alex"
+             :post_id  (str "post" i)
+             :body     (str "body" i)}))
+
+  (is (= [{:post_id "post0"}
+          {:post_id "post1"}
+          {:post_id "post2"}]
+         (select *session* :user_posts
+                 (columns :post_id)
+                 (where {:username "Alex"})
+                 (order-by :post_id))))
+
+  (is (= [{:post_id "post2"}
+          {:post_id "post1"}
+          {:post_id "post0"}]
+         (select *session* :user_posts
+                 (columns :post_id)
+                 (where {:username "Alex"})
+                 (order-by (new-query-api/desc :post_id))))))

 ;; (deftest test-select-range-query
 ;;   (create-table s :tv_series


SER-2525 | clean up dependencies, make it more clear that we normalize metric name

--- src/vignette/perfmonitoring/core.clj
+++ src/vignette/perfmonitoring/core.clj
@@ -1,7 +1,5 @@
 (ns vignette.perfmonitoring.core
-  (:import (java.net DatagramSocket DatagramPacket InetAddress))
-  (:require [cheshire.core :as json]
-            [vignette.common.logger :as log]
+  (:require [vignette.common.logger :as log]
             [environ.core :refer [env]]
             [prometheus.core :as prometheus]))

@@ -9,27 +7,28 @@

 (defonce metrics-registry (atom nil))

-(defn unify [counter]
+; prometheus accepts only underscores
+(defn normalize [counter]
   (clojure.string/replace (name counter) "-" "_"))

 (defn register [store]
   (->
    store
-   (prometheus/register-counter app (unify :convert-error) "Conversion error" [])
-   (prometheus/register-counter app (unify :exception-count) "Total exception occured" [])
-   (prometheus/register-counter app (unify :request-count) "Total requests number" [])
-   (prometheus/register-counter app (unify :bad-request-path-count) "Total bad path requests" [])
-   (prometheus/register-counter app (unify :thumbnail-cache-hit) "Cache hit counter" [])
-   (prometheus/register-counter app (unify :generate-thumbnail) "Thumbnail generation counter" [])
-   (prometheus/register-counter app (unify :connection-pool-timeout) "Timeout counter" [])
-   (prometheus/register-histogram app (unify :request-time) "Requests time histogram in ms" [] [1.0, 2.0, 5.0, 10.0, 25.0, 50.0, 75.0, 100.0, 200.0, 400.0, 600.0, 800.0, 1000.0, 1500.0, 2000.0, 3000.0, 5000.0])
-   (prometheus/register-histogram app (unify :imagemagick) "Imagemagick time histogram in ms" [] [1.0, 2.0, 5.0, 10.0, 25.0, 50.0, 75.0, 100.0, 200.0, 400.0, 600.0, 800.0, 1000.0, 1500.0, 2000.0, 3000.0, 5000.0])
-   (prometheus/register-histogram app (unify :s3-get) "s3 get image time histogram in ms" [] [1.0, 2.0, 5.0, 10.0, 25.0, 50.0, 75.0, 100.0, 200.0, 400.0, 600.0, 800.0, 1000.0, 1500.0, 2000.0, 3000.0, 5000.0])
-   (prometheus/register-histogram app (unify :s3-put) "s3 put image time histogram in ms" [] [1.0, 2.0, 5.0, 10.0, 25.0, 50.0, 75.0, 100.0, 200.0, 400.0, 600.0, 800.0, 1000.0, 1500.0, 2000.0, 3000.0, 5000.0])
-   (prometheus/register-histogram app (unify :s3-delete) "s3 delete image time histogram in ms" [] [1.0, 2.0, 5.0, 10.0, 25.0, 50.0, 75.0, 100.0, 200.0, 400.0, 600.0, 800.0, 1000.0, 1500.0, 2000.0, 3000.0, 5000.0])
-   (prometheus/register-histogram app (unify :s3-bucket-exists) "s3 check bucket image time histogram in ms" [] [1.0, 2.0, 5.0, 10.0, 25.0, 50.0, 75.0, 100.0, 200.0, 400.0, 600.0, 800.0, 1000.0, 1500.0, 2000.0, 3000.0, 5000.0])
-   (prometheus/register-histogram app (unify :s3-bucket-create) "s3 create bucket image time histogram in ms" [] [1.0, 2.0, 5.0, 10.0, 25.0, 50.0, 75.0, 100.0, 200.0, 400.0, 600.0, 800.0, 1000.0, 1500.0, 2000.0, 3000.0, 5000.0])
-   (prometheus/register-histogram app (unify :s3-list-objects) "s3 list objects time histogram in ms" [] [1.0, 2.0, 5.0, 10.0, 25.0, 50.0, 75.0, 100.0, 200.0, 400.0, 600.0, 800.0, 1000.0, 1500.0, 2000.0, 3000.0, 5000.0])
+   (prometheus/register-counter app (normalize :convert-error) "Conversion error" [])
+   (prometheus/register-counter app (normalize :exception-count) "Total exception occured" [])
+   (prometheus/register-counter app (normalize :request-count) "Total requests number" [])
+   (prometheus/register-counter app (normalize :bad-request-path-count) "Total bad path requests" [])
+   (prometheus/register-counter app (normalize :thumbnail-cache-hit) "Cache hit counter" [])
+   (prometheus/register-counter app (normalize :generate-thumbnail) "Thumbnail generation counter" [])
+   (prometheus/register-counter app (normalize :connection-pool-timeout) "Timeout counter" [])
+   (prometheus/register-histogram app (normalize :request-time) "Requests time histogram in ms" [] [1.0, 2.0, 5.0, 10.0, 25.0, 50.0, 75.0, 100.0, 200.0, 400.0, 600.0, 800.0, 1000.0, 1500.0, 2000.0, 3000.0, 5000.0])
+   (prometheus/register-histogram app (normalize :imagemagick) "Imagemagick time histogram in ms" [] [1.0, 2.0, 5.0, 10.0, 25.0, 50.0, 75.0, 100.0, 200.0, 400.0, 600.0, 800.0, 1000.0, 1500.0, 2000.0, 3000.0, 5000.0])
+   (prometheus/register-histogram app (normalize :s3-get) "s3 get image time histogram in ms" [] [1.0, 2.0, 5.0, 10.0, 25.0, 50.0, 75.0, 100.0, 200.0, 400.0, 600.0, 800.0, 1000.0, 1500.0, 2000.0, 3000.0, 5000.0])
+   (prometheus/register-histogram app (normalize :s3-put) "s3 put image time histogram in ms" [] [1.0, 2.0, 5.0, 10.0, 25.0, 50.0, 75.0, 100.0, 200.0, 400.0, 600.0, 800.0, 1000.0, 1500.0, 2000.0, 3000.0, 5000.0])
+   (prometheus/register-histogram app (normalize :s3-delete) "s3 delete image time histogram in ms" [] [1.0, 2.0, 5.0, 10.0, 25.0, 50.0, 75.0, 100.0, 200.0, 400.0, 600.0, 800.0, 1000.0, 1500.0, 2000.0, 3000.0, 5000.0])
+   (prometheus/register-histogram app (normalize :s3-bucket-exists) "s3 check bucket image time histogram in ms" [] [1.0, 2.0, 5.0, 10.0, 25.0, 50.0, 75.0, 100.0, 200.0, 400.0, 600.0, 800.0, 1000.0, 1500.0, 2000.0, 3000.0, 5000.0])
+   (prometheus/register-histogram app (normalize :s3-bucket-create) "s3 create bucket image time histogram in ms" [] [1.0, 2.0, 5.0, 10.0, 25.0, 50.0, 75.0, 100.0, 200.0, 400.0, 600.0, 800.0, 1000.0, 1500.0, 2000.0, 3000.0, 5000.0])
+   (prometheus/register-histogram app (normalize :s3-list-objects) "s3 list objects time histogram in ms" [] [1.0, 2.0, 5.0, 10.0, 25.0, 50.0, 75.0, 100.0, 200.0, 400.0, 600.0, 800.0, 1000.0, 1500.0, 2000.0, 3000.0, 5000.0])
   ))

 (defn init []
@@ -41,7 +40,7 @@
   [points]
   (doseq [[counter inc] points]
     (try
-      (prometheus/increase-counter @metrics-registry app (unify counter) [] inc)
+      (prometheus/increase-counter @metrics-registry app (normalize counter) [] inc)
       (catch Exception e
         (log/warn "prometheus publish failed" {:exception (str e) :counter counter})))))

@@ -53,6 +52,6 @@
       ~@body
       (finally
           (try
-            (prometheus/track-observation @metrics-registry app (unify ~metric) (- (current-time) start#) [])
+            (prometheus/track-observation @metrics-registry app (normalize ~metric) (- (current-time) start#) [])
             (catch Exception e#
               (log/warn "prometheus timer failed" {:exception (str e#) :counter ~metric})))))))


Log batch rate

Log batch rate

--- src/whisper2cyanite/metric_store.clj
+++ src/whisper2cyanite/metric_store.clj
@@ -106,7 +106,8 @@
     (log/info (str "The metric store has been created. "
                    "Keyspace: " keyspace ", "
                    "channel size: " chan-size ", "
-                   "batch size: " batch-size))
+                   "batch size: " batch-size ", "
+                   "batch rate: " batch-rate))
     (reify
       MetricStore
       (insert [this tenant rollup period path timeseries file]


minor: add debug logs

minor: add debug logs

--- ssclj/jar/src/main/clojure/com/sixsq/slipstream/ssclj/usage/record_keeper.clj
+++ ssclj/jar/src/main/clojure/com/sixsq/slipstream/ssclj/usage/record_keeper.clj
@@ -63,13 +63,17 @@
 (defn- metric-summary
   [usage-metric]
   (str (:start-timestamp usage-metric)
+       "-" (:end-timestamp usage-metric)
        " " (:cloud-vm-instanceid usage-metric)
        " [" (:metric-name usage-metric) "/" (:metric-value usage-metric) "]"))

 (defn- close-record
   ([usage-metric close-timestamp options]
    (log/debug "Closing usage-record " close-timestamp (metric-summary usage-metric))
+   (log/debug "open urs " (ur/open-records usage-metric))
+   (log/debug "close: options " options)
    (doseq [ur (ur/open-records usage-metric)]
+     (log/debug "editing ur" ur)
      (db/edit (assoc ur :end-timestamp close-timestamp) options)))
   ([usage-metric options]
    (close-record usage-metric (:end-timestamp usage-metric) options)))
@@ -77,6 +81,7 @@
 (defn- open-record
   [usage-metric options]
   (log/debug "Opening usage-record " (metric-summary usage-metric))
+  (log/debug "open: options " options)
   (let [new-record (-> usage-metric
                        (assoc :resourceURI ur/resource-uri)
                        (assoc :id (str "usage-record/" (cu/random-uuid)))
@@ -104,6 +109,7 @@

 (defn- insertEnd
   [usage-event-json options]
+  (log/debug "insertEnd usage-event-json " usage-event-json)
   (doseq [usage-metric (usage-metrics usage-event-json)]
     (process-metric-event usage-metric :stop options)))


ensure that display is only created once

--- dada-swt/src/main/clojure/org/dada/swt/new.clj
+++ dada-swt/src/main/clojure/org/dada/swt/new.clj
@@ -23,24 +23,25 @@

 ;;--------------------------------------------------------------------------------

- (if (not *compile-files*)
-   (do
-     (def ^Display *display* (Display.))
-     (.start
-      (Thread.
-       (fn []
-	   (def ^Display *display* (Display.))
-	   (swt-loop *display*))))))
+(let [display (atom nil)]
+  (defn ensure-display []
+    (swap! display (fn [d] (or d (Display.))))))
+
+(if (not *compile-files*)
+  (.start
+   (Thread.
+    (fn []
+      (swt-loop (ensure-display))))))

 ;; TODO - detach View on closing
 (defn inspect [query]
   (.asyncExec
-   *display*
+   (ensure-display)
    (fn []
        (let [[metadata-fn data-fn] query
 	     results (data-fn)
 	     [^Model metamodel] results
-	     ^Composite shell (create-shell *display* (.getName metamodel))
+	     ^Composite shell (create-shell (ensure-display) (.getName metamodel))
 	     ^Composite component (create results shell)]
 	 (trace results)
 	 (.pack component)


Added convenience health check fn.

Added convenience health check fn.


Test that issue #28 is fixed.

Test that issue #28 is fixed.

--- test/active/clojure/record_test.cljc
+++ test/active/clojure/record_test.cljc
@@ -768,3 +768,10 @@
          canif?
          [])
        "Illegal argument")))
+
+(deftest typo-in-field-name-test
+  (is (throws-exception?
+       (define-record-type Schlingel
+         (make-schlingel name) schlingel?
+         [nam schlingel-name])
+       "Illegal argument")))


adding workflow to feature

adding workflow to feature

--- test/celestial/features/digitial.clj
+++ test/celestial/features/digitial.clj
@@ -1,13 +1,28 @@
 (ns celestial.features.digitial
   "digital ocean support"
   (:require
+    [celestial.fixtures.core :refer (with-defaults is-type? with-admin with-conf)]
+    [celestial.persistency.systems :as s]
+    [celestial.fixtures.data :refer (redis-type local-conf redis-freenas)]
+    [celestial.fixtures.populate :refer (populate-system)]
+    [celestial.integration.workflows.common :refer (spec get-spec)]
+    [celestial.workflows :as wf]
     [celestial.model :refer (vconstruct)]
     [celestial.fixtures.core :refer (with-conf) :as f]
     [celestial.fixtures.data :refer [redis-digital]])
   (:use midje.sweet)
+  (:import clojure.lang.ExceptionInfo)
  )

 (with-conf
   (let [{:keys [machine digital-ocean]} redis-digital]
     (fact "legal digital-ocean system" :digital-ocean
        (:spec (vconstruct redis-digital)) => (contains {:name "red1.local"}))))
+
+(with-admin
+  (with-conf local-conf
+    (with-state-changes [(before :facts (populate-system redis-type redis-digital))]
+      (fact "digital-ocean creation workflows" :integration :digital-ocean :workflow
+          (wf/create (spec)) => nil
+          (wf/stop (spec)) => nil
+          (wf/destroy (spec)) => nil))))


remove usued 'using'

remove usued 'using'

--- test/clj_money/models/users_test.clj
+++ test/clj_money/models/users_test.clj
@@ -4,8 +4,7 @@
             [clojure.data :refer [diff]]
             [environ.core :refer [env]])
   (:use [clj-money.models.users :as users]
-        [clj-money.test-helpers :refer :all])
-  (:import clojure.lang.ExceptionInfo))
+        [clj-money.test-helpers :refer :all]))

 (def data-store (env :db))


Bugfix: Correctly add data to new data model

Include "date_part" field, for partitioning purposes

--- src-clj/tamarack/model.clj
+++ src-clj/tamarack/model.clj
@@ -2,6 +2,7 @@
   (:require [clj-time.core :as time]
             [clj-time.format :as time-format]
             [clj-time.coerce :as time-coerce]
+            [clj-time.periodic :as time-periodic]
             [qbits.alia :as alia]
             [qbits.hayt :as hayt]
             [tamarack.util :as util]))
@@ -45,6 +46,15 @@
                                      60000))
                             60000)))

+(defn timestamp-date-part [timestamp]
+  (time-format/unparse timestamp-date-format timestamp))
+
+(defn dates-between [from to]
+  (let [interval (time/interval from (time/plus to (time/hours 24)))]
+    (map timestamp-date-part
+         (take-while (partial time/within? interval)
+                     (time-periodic/periodic-seq from (time/hours 24))))))
+
 (defn process-request-data [app-id data]
   (let [{errors :errors
          requests :requests
@@ -59,7 +69,8 @@
                                      :requests (hayt/inc-by requests)
                                      :errors (hayt/inc-by errors)})
                                    (hayt/where {:app_id app-id
-                                                :timestamp (time-coerce/to-long timestamp-minute)}))]
+                                                :timestamp (time-coerce/to-long timestamp-minute)
+                                                :date_part (timestamp-date-part timestamp-minute)}))]
     (alia/execute session query-minute)))

 (defn process-endpoint-data [app-id data]
@@ -78,7 +89,8 @@
                                      :errors (hayt/inc-by errors)})
                                    (hayt/where {:app_id app-id
                                                 :endpoint endpoint
-                                                :timestamp (time-coerce/to-long timestamp-minute)}))]
+                                                :timestamp (time-coerce/to-long timestamp-minute)
+                                                :date_part (timestamp-date-part timestamp-minute)}))]
     (alia/execute session query-minute)))

 (defn request-data-by-minute [app-id from to]
@@ -87,6 +99,7 @@
         query (hayt/select :request_by_minute
                            (hayt/columns :timestamp :total_time :requests :errors)
                            (hayt/where [[= :app_id app-id]
+                                        [:in :date_part (dates-between from to)]
                                         [>= :timestamp from-long]
                                         [<= :timestamp to-long]]))]
     (alia/execute session query)))
@@ -97,6 +110,7 @@
         query (hayt/select :request_endpoint_by_minute_for_agg
                            (hayt/columns :timestamp :endpoint :total_time :requests :errors)
                            (hayt/where [[= :app_id app-id]
+                                        [:in :date_part (dates-between from to)]
                                         [>= :timestamp from-long]
                                         [<= :timestamp to-long]]))]
     (alia/execute session query)))


Reimplement deflate helpers.

Reimplement deflate helpers.

In order to fix unexpected exception on uncompress function
and use safer idioms for treat internal stream.

--- src/buddy/util/deflate.clj
+++ src/buddy/util/deflate.clj
@@ -28,29 +28,25 @@
   "Given a plain byte array, compress it and
   return an other byte array."
   [^bytes input]
-  (let [out (ByteArrayOutputStream.)
-        def (Deflater. Deflater/DEFLATED true)
-        dout (DeflaterOutputStream. out def)]
-    (.write dout input)
-    (.close dout)
-    (.toByteArray out)))
+  (let [os (ByteArrayOutputStream.)
+        opts (Deflater. Deflater/DEFLATED true)]
+    (with-open [dos (DeflaterOutputStream. os opts)]
+      (.write dos input))
+    (.toByteArray os)))

 (defn uncompress
   "Given a compressed data as byte-array,
   uncompress it and return as an other
   byte array."
   [^bytes input]
-  (let [input (ByteArrayInputStream. bytes)
-        inflater (Inflater. true)
-        infout (InflaterInputStream. input inflater)
-        output (ByteArrayOutputStream.)
-        buffer (byte-array 1024)]
-    (loop []
-      (let [readed (.read infout buffer)]
-        (when (pos? readed)
-          (.write output buffer 0 readed)
-          (recur))))
-    (.close infout)
-    (.close output)
-    (.toByteArray output)))
-
+  (let [buf (byte-array 1024)
+        os (ByteArrayOutputStream.)
+        opts (Inflater. true)]
+    (with-open [is (ByteArrayInputStream. input)
+                iis (InflaterInputStream. is opts)]
+      (loop []
+        (let [readed (.read iis buf)]
+          (when (pos? readed)
+            (.write os buf 0 readed)
+            (recur)))))
+    (.toByteArray os)))


Clarify the API of the h* functions

Clarify the API of the h* functions

--- src/catalog/layout/fop.clj
+++ src/catalog/layout/fop.clj
@@ -37,17 +37,14 @@
            :space-after "11pt"} opts)
    (layout/translations h)])

-(defn h1 [h]
-  (heading h (hash [nil h]) {:break-before "odd-page" :font-size "21pt" :role "H1"}))
-
-(defn h2 [fmt h]
-  (heading h (hash [fmt h]) {:font-size "17pt" :role "H2"}))
-
-(defn h3 [fmt genre h]
-  (heading h (hash [fmt genre h]) {:font-size "15pt" :role "H3"}))
-
-(defn h4 [fmt genre subgenre h]
-  (heading h (hash [fmt genre subgenre h]) {:font-size "13pt" :role "H3"}))
+(defn h1 [fmt]
+  (heading fmt (hash [fmt]) {:break-before "odd-page" :font-size "21pt" :role "H1"}))
+
+(defn h2 [fmt genre]
+  (heading genre (hash [fmt genre]) {:font-size "17pt" :role "H2"}))
+
+(defn h3 [fmt genre subgenre]
+  (heading subgenre (hash [fmt genre subgenre]) {:font-size "15pt" :role "H3"}))

 (def ^:private running-header-class-name "running-header")


show all of the piggyback orgs on the org settings page

--- frontend/components/org_settings.cljs
+++ frontend/components/org_settings.cljs
@@ -384,6 +384,7 @@
           user-login (:login (get-in app state/user-path))
           user-orgs (get-in app state/user-organizations-path)
           plan (get-in app state/org-plan-path)
+          ;; orgs that this user can add to piggyback orgs
           elligible-piggyback-orgs (-> (map :login user-orgs)
                                        (set)
                                        (conj user-login)
@@ -415,14 +416,14 @@
             [:div.span12
              [:form
               [:div.controls
-               (for [org elligible-piggyback-orgs]
+               ;; orgs that this user can add to piggyback orgs and existing piggyback orgs
+               (for [org (clojure.set/union elligible-piggyback-orgs (set (:piggieback_orgs plan)))]
                  [:div.control
                   [:label.checkbox
                    [:input
                     (let [checked? (contains? selected-piggyback-orgs org)]
                       {:value org
                        :checked checked?
-                       ;; Note: this is broken if the org is already in piggieback_orgs, need to explicitly pass the value :(
                        :on-change #(utils/edit-input controls-ch (conj state/selected-piggyback-orgs-path org) % :value (not checked?))
                        :type "checkbox"})]
                    org]])]


Heads up when server is loading a database file.

--- src/clj/fleetdb/server.clj
+++ src/clj/fleetdb/server.clj
@@ -65,24 +65,35 @@
       (stacktrace/pst-on System/err false e)
       (.println System/err))))

+(defn- report-loading-start []
+  (print "Loading database file...")
+  (flush))
+
+(defn- report-loading-end []
+  (println "done"))
+
+(defn- report-ready [port]
+  (println "FleetDB listening on port" port))
+
 (defn run [db-path ephemeral port addr threads password]
   (let [inet          (InetAddress/getByName addr)
         server-socket (ServerSocket. port 10000 inet)
         pool          (thread-pool/init threads)
-        loading       (and db-path (file/exist? db-path))
-        dba           (if ephemeral
-                        (if loading
-                          (embedded/load-ephemeral db-path)
-                          (embedded/init-ephemeral))
-                        (if loading
-                          (embedded/load-persistent db-path)
-                          (embedded/init-persistent db-path)))]
-    (printf "FleetDB listening on port %d\n" port)
-    (flush)
-    (loop []
-      (let [socket (doto (.accept server-socket))]
-        (thread-pool/submit pool #(handler dba socket password)))
-      (recur))))
+        loading       (and db-path (file/exist? db-path))]
+    (if loading (report-loading-start))
+    (let [dba (if ephemeral
+                (if loading
+                  (embedded/load-ephemeral db-path)
+                  (embedded/init-ephemeral))
+                (if loading
+                  (embedded/load-persistent db-path)
+                  (embedded/init-persistent db-path)))]
+      (if loading (report-loading-end))
+      (report-ready port)
+      (loop []
+        (let [socket (doto (.accept server-socket))]
+          (thread-pool/submit pool #(handler dba socket password)))
+        (recur)))))

 (defn- print-help []
   (println "FleetDB Server                                             ")


fix missing end the run on Shinobi

fix missing end the run on Shinobi

--- src/clj/game/cards-ice.clj
+++ src/clj/game/cards-ice.clj
@@ -490,7 +490,8 @@
                 {:label "Trace 2 - Do 2 net damage"
                  :trace {:base 2 :msg "do 2 net damage" :effect (effect (damage :net 2 {:card card}))}}
                 {:label "Trace 3 - Do 3 net damage"
-                 :trace {:base 3 :msg "do 3 net damage" :effect (effect (damage :net 3 {:card card}))}}]}
+                 :trace {:base 3 :msg "do 3 net damage and end the run"
+                         :effect (effect (damage :net 3 {:card card}) (end-run))}}]}

    "Snoop"
    {:abilities [{:msg "place 1 power counter on Snoop" :effect (effect (add-prop card :counter 1))}
@@ -632,4 +633,4 @@
                 {:msg "look at the top card of R&D"
                  :optional {:prompt (msg "Add " (:title (first (:deck corp))) " to bottom of R&D?")
                             :msg "add the top card of R&D to the bottom"
-                            :effect (effect (move (first (:deck corp)) :deck))}}]}})+                            :effect (effect (move (first (:deck corp)) :deck))}}]}})


change id helmsman looks for to generate resource uris

--- src/clj/traveler/utils.clj
+++ src/clj/traveler/utils.clj
@@ -26,7 +26,7 @@
   "Generate the relative uri to a resource"
   [request path]
   (str
-   (h-uri/assemble (h-nav/id->uri-path request :traveler/resources))
+   (h-uri/assemble (h-nav/id->uri-path request :traveler/root))
    path))

 (defn id-uri


Removing success notifications automatically after 3 seconds

Keeping any others around until the user closes them.

https://app.asana.com/0/17212341701456/41147566342789

--- src/cljs/memento/core.cljs
+++ src/cljs/memento/core.cljs
@@ -171,7 +171,19 @@
 (register-handler
   :set-message
   (fn [app-state [_ msg class]]
-    (assoc-in app-state [:ui-state :last-message] {:text msg :class class})))
+    (let [message {:text msg :class class}]
+      ; TODO: Consider changing this for a keyword
+      (if (= class "alert-success")
+        (js/setTimeout #(dispatch [:set-message-if-same message nil]) 3000))
+      (assoc-in app-state [:ui-state :last-message] message))))
+
+(register-handler
+  :set-message-if-same
+  (fn [app-state [_ msg new-msg]]
+    (if (= msg (get-in app-state [:ui-state :last-message]))
+      (assoc-in app-state [:ui-state :last-message] new-msg)
+      app-state
+      )))

 (register-handler
   :update-note


fix reference table output regression caused by api restructure

--- src/cljs_api_gen/write.clj
+++ src/cljs_api_gen/write.clj
@@ -416,7 +416,7 @@
 (defn readme-api-symbols
   [result api-type]
   ;; clj-name-type-history tuples
-  (let [all (select-keys (:symbols result) (get-in result [:api api-type]))
+  (let [all (select-keys (:symbols result) (get-in result [:api api-type :symbol-names]))
         get-display-name (fn [{:keys [parent-type] :as item}]
                            (cond-> (:name item)
                              parent-type (replace (str parent-type ".") "")


Extract column conversion into as-col-array

--- src/clojure/flambo/sql.clj
+++ src/clojure/flambo/sql.clj
@@ -107,10 +107,14 @@
   ([sql-context database-name]
    (seq (.tableNames sql-context database-name))))

+(defn- as-col-array
+  [exprs]
+  (into-array Column (map sqlf/col exprs)))
+
 (defn select
   "Select a set of columns"
   [df & exprs]
-  (.select df (into-array Column (map sqlf/col exprs))))
+  (.select df (as-col-array exprs)))

 (defn where
   "Filters DataFrame rows using SQL expression"
@@ -119,11 +123,11 @@

 (defn group-by
   [df & exprs]
-  (.groupBy df (into-array Column (map sqlf/col exprs))))
+  (.groupBy df (as-col-array exprs)))

 (defn agg
   [df expr & exprs]
-  (.agg df (sqlf/col expr) (into-array Column (map sqlf/col exprs))))
+  (.agg df (sqlf/col expr) (as-col-array exprs)))

 ;; DataFrame
 (defn register-temp-table


Working on further tests.

Working on further tests.

--- test/re-com/selection_list_test.cljs
+++ test/re-com/selection_list_test.cljs
@@ -4,13 +4,18 @@
             [reagent.core :as reagent]
             [re-com.selection-list :as s-list]))

-
+;; --- Utilities ---

 (defn div-app []
   (let [div (.createElement js/document "div")]
     (set! (.-id div) "app")
     div))

+(extend-type js/NodeList
+  ISeqable
+  (-seq [array] (array-seq array 0)))
+
+;; --- Tests ---
 (deftest test-selection-list
   (let [new-comp (reagent/render-component
                    [s-list/selection-list
@@ -30,9 +35,31 @@
                     :choices [{:id "1" :name "item 1"} {:id "2" :name "item 2"} {:id "3" :name "item 3"}]
                     :model #{"2"}
                     :multi-select? false
-                    :on-change #(println %)]
+                    :on-change #()]
                    (div-app))
         props (last (-> new-comp .-_renderedComponent .-props .-argv .-tail))]
       (is (false? (:multi-select? props))  "Expected :multi-select? to default to true.")))

+(deftest test-selection-list-with-id-fn
+  (let [selected (reagent/atom #{"2"})
+        new-comp (reagent/render-component
+                   [s-list/selection-list
+                    :choices [{:id "1" :name "item 1"} {:id "2" :name "item 2"} {:id "3" :name "item 3"}]
+                    :model selected
+                    :label-fn :name
+                    ;;:id-fn identity
+                    :on-change #(print "selected: " %)]
+                   (div-app))
+        props       (last (-> new-comp .-_renderedComponent .-props .-argv .-tail))
+        dom-node    (.getDOMNode new-comp)
+        firstCkGrp  (-> dom-node .-childNodes first .-childNodes first .-childNodes first .-childNodes)
+        firstCk     (first firstCkGrp)
+        firstLbl    (second firstCkGrp)]
+      (is (ifn?  (:id-fn props))       "Expected :id-fn to be a function.")
+      (is (ifn?  (:label-fn props))    "Expected :label-fn to be a function.")
+      (is (= "item 1" (.-textContent firstLbl)) "Expected label for the first check box to use the :name of the element.")
+      ;; Removed the next two lines as the click event doesn't update the model. Checkbox shows 'checked' after the click but no on-change is triggered.
+      #_(.click firstCk)
+      #_(is (= #{"1"} @selected) "Expected set of selected values to match first element.")))
+


fdef:s

fdef:s

--- src/adventofcode1/four.clj
+++ src/adventofcode1/four.clj
@@ -80,7 +80,9 @@
 (defn valid-room-name?
   "Return true if room is valid."
   [name]
-  (> (valid-room-name name) 0))
+  (try
+    (> (valid-room-name name) 0)
+    (catch Throwable _ false)))

 (defn sum-sectorid-of-valid-room-names
@@ -88,7 +90,8 @@
   (reduce + (map valid-room-name names)))

 (s/fdef rotate-char
-        :args (s/cat :text char? :n integer?)
+        ;; we need to require a pos? or zero? here since negative values doesn't work
+        :args (s/cat :text char? :n (s/and integer? (s/or :zero zero? :pos pos?)))
         :ret  char?)

 (defn rotate-char
@@ -98,13 +101,20 @@
     (char (if (> res 122) (+ 97 (mod (- res 97) 26)) res))))

 (s/fdef rotate-string
-        :args (s/cat :text string? :n integer?)
+        :args (s/cat :text string? :n (s/and integer? (s/or :zero zero? :pos pos?)))
         :ret  string?)

 (defn rotate-string
   "Rotate each char in lower-case string n positions."
   [text n]
   (clojure.string/join (map #(rotate-char % n) (or (seq text) []))))
+
+(s/fdef find-northpole
+        ;; need a better way to generate valid room names
+        ;; ExceptionInfo Couldn't satisfy such-that predicate after 100 tries.  clojure.core/ex-info (core.clj:4725)
+        :args (s/cat :names (s/coll-of (s/and string? valid-room-name?)))
+        :ret  (s/or :not-found nil :found (s/tuple integer? string?)))
+

 (defn find-northpole
   [names]


Improve benchmark output

Improve benchmark output

--- benchmarks/caesium/crypto/secretbox_benchmark.clj
+++ benchmarks/caesium/crypto/secretbox_benchmark.clj
@@ -66,18 +66,25 @@

 (def sizes (map (partial bit-shift-left 1) [6 8 10 12 20 24]))

+(defn ^:private describe-buffer
+  [x]
+  (cond
+    (instance? (Class/forName "[B") x) "array"
+    (instance? ByteBuffer x) (if (.isDirect ^ByteBuffer x) "dbuf" "ibuf")
+    :else (type x)))
+
 (defmacro bench-secretnonce
   [prefix fs converter]
   `(let [rand-buf# (comp ~converter randombytes)]
     (doseq [[size# ptext#] (map (juxt identity rand-buf#) sizes)
-             f# ~fs]
+            [f# f-sym#] (map vector ~fs (quote ~fs))]
        (let [key# (rand-buf# s/keybytes)
              nonce# (rand-buf# s/noncebytes)
              out# (rand-buf# (+ s/macbytes size#))]
          (print-title ~prefix
-                      f#
+                      f-sym#
                       (fmt-bytes size#)
-                      (mapv type [out# ptext# nonce# key#]))
+                      (mapv describe-buffer [out# ptext# nonce# key#]))
          (bench (f# out# ptext# nonce# key#))))))

 (deftest ^:benchmark to-buf!-benchmarks


structural edition issue: bad parse made weird things happen. Now bad parse implies structural edition commands are disabled

--- ccw.core/src/ccw/editors/antlrbased/PareditAutoEditStrategy.clj
+++ ccw.core/src/ccw/editors/antlrbased/PareditAutoEditStrategy.clj
@@ -82,7 +82,9 @@
 (defn -customizeDocumentCommand
   [#^ccw.editors.antlrbased.PareditAutoEditStrategy this, #^IDocument document, #^DocumentCommand command]
   (let [^IClojureEditor editor (-> this .state deref :editor)]
-    (when (and (.doit command) (not (.isInEscapeSequence editor)))
+    (when (and (.doit command)
+               (not (.isInEscapeSequence editor))
+               (.getParsed editor))
       (let [signed-selection (bean (.getSignedSelection editor))
             ;_ (println (str "signed-selection:" signed-selection))
             document-text {:text (.get document)


Add a sample map

Add a sample map

--- router/src/router/core.clj
+++ router/src/router/core.clj
@@ -6,6 +6,13 @@
             [ring.util.response :refer [response]]
             [router.haproxy :as h])
   (:gen-class))
+
+(def services-sample
+  "Sample services map needed to generate a valid HAProxy template"
+  (hash-map
+    {:name "users-a-l" :regex "/users/[a-l]"} ["0.0.0.0:8000" "0.0.0.0:8001"]
+    {:name "users-m-z" :regex "/users/[m-z]"} ["0.0.0.0:8002" "0.0.0.0:8003"]
+    {:name "profiles"  :regex "/profiles"}    ["0.0.0.0:8004"]))

 (def services
   (atom {}))


Autocompleter upgraded to support cider 0.9.0-SNAPSHOT

--- src/lt/plugins/cljrefactor/completer.cljs
+++ src/lt/plugins/cljrefactor/completer.cljs
@@ -32,6 +32,11 @@
                            :end (:end token)}
                           "__prefix__"))))

+(defn create-hints [completions]
+  (map #(do #js {:completion (:candidate %)
+                 :text (:candidate %)})
+       completions))
+
 (behavior ::completer.res
           :triggers #{:editor.eval.clj.result.refactor.complete}
           :reaction (fn [ed res]
@@ -39,7 +44,7 @@
                         (if-not ok?
                           (object/raise ed :editor.exception {:line (-> ret :meta :line)})
                           (when-let [completions (:completions ret)]
-                            (object/merge! ed {::hints (map #(do #js {:completion %}) completions)})
+                            (object/merge! ed {::hints (create-hints completions)})
                             (object/raise ac/hinter :refresh!)))
                         (notifos/done-working))))


Player names are now separated with newlines

--- src/mafia_votecount/views/create_game.clj
+++ src/mafia_votecount/views/create_game.clj
@@ -1,7 +1,7 @@
 (ns mafia-votecount.views.create-game
   (:refer-clojure :exclude [resolve])
   (:use clojurewerkz.urly.core)
-  (:require [clojure.string]
+  (:require [clojure.string :as string]
             [mafia-votecount.models :as models]
             [mafia-votecount.scraper.team-liquid :as scraper]))

@@ -11,8 +11,8 @@
     (nth 3)))

 (defn- add-players [game-id players-string]
-  (let [players (clojure.string/split players-string #"\s+")]
-    (models/add-players game-id players)))
+  (->> (map string/trim (string/split-lines players-string))
+    (models/add-players game-id)))

 (defn add-game [url-string hoster-name players-string]
   (let [url (url-like url-string)]


fix syntax-quote*

fix syntax-quote*

--- src/main/clojure/clojure/tools/reader.clj
+++ src/main/clojure/clojure/tools/reader.clj
@@ -570,13 +570,16 @@
      (instance? SyntaxQuotedSet form) (syntax-quote-coll 'clojure.core/hash-set (:val form))

      (instance? IRecord form) form
+     (map? form) (syntax-quote-coll (map-func form) (flatten-map form))
      (vector? form) (list 'clojure.core/vec (syntax-quote-coll nil form))
+     (set? form) (syntax-quote-coll 'clojure.core/hash-set form)

      (or (seq? form) (list? form))
      (let [seq (seq form)]
        (if seq
          (syntax-quote-coll nil seq)
          '(clojure.core/list)))
+
      :else (throw (UnsupportedOperationException. "Unknown Collection type")))

     (or (keyword? form)


also migrate build-report UI

also migrate build-report UI

--- src/main/shadow/cljs/build_report/ui.cljs
+++ src/main/shadow/cljs/build_report/ui.cljs
@@ -171,22 +171,21 @@
 (def schema
   {:module
    {:type :entity
-    :attrs {:module-id [:primary-key any?]
-            :groups [:many :group]}}
+    :primary-key :module-id
+    :joins {:groups [:many :group]}}

    :group
    {:type :entity
-    :attrs {:group-id [:primary-key any?]
-            :items [:many :group-item]}}
+    :primary-key :group-id
+    :joins {:items [:many :group-item]}}

    :group-item
    {:type :entity
-    :attrs {:group-item-id [:primary-key any?]}}
+    :primary-key :group-item-id}

    :resource
    {:type :entity
-    :attrs {:resource-id [:primary-key any?]}}
-
+    :primary-key :resource-id}
    })


highlighted current track works (inefficiently)

--- src/frontend/renderer.cljs
+++ src/frontend/renderer.cljs
@@ -161,6 +161,9 @@

 (defn track-view [data owner]
   (reify
+    om/IShouldUpdate
+    (should-update [_ _ _]
+      true)
     om/IRender
     (render [this]
       (let [tags (.-tags data)


OO|RR: Show table header regardless of data availability Search input needs to be constantly visible

--- src/hatti/views/table.cljs
+++ src/hatti/views/table.cljs
@@ -309,10 +309,10 @@
                     (with-info (get-in app-state [:table-page :submission-clicked]))
                     {:opts (merge (select-keys opts #{:delete-record! :role})
                                   {:view :table})})
-          (if no-data?
-            [:h3 "No Data"]
-            (om/build table-header app-state))
-            [:div {:id table-id :class "slickgrid"}]])))
+          (om/build table-header nil)
+          [:div {:id table-id :class "slickgrid"}
+           (when no-data?
+             [:span {:class "empty-state"} "No data"])]])))
     om/IDidMount
     (did-mount [_]
       (let [data (get-in app-state [:data])]


Fixed kibit errors in virtual-product.

Fixed kibit errors in virtual-product.

Also reformatted some of the long lines.

--- virtual-product-app/src/cmr/virtual_product/data/source_to_virtual_mapping.clj
+++ virtual-product-app/src/cmr/virtual_product/data/source_to_virtual_mapping.clj
@@ -54,120 +54,127 @@
   "A map of source collection provider id and entry titles to virtual product configs"
   {["LPDAAC_ECS" "ASTER L1A Reconstructed Unprocessed Instrument Data V003"]
    {:short-name "AST_L1A"
-    :virtual-collections [{:entry-title "ASTER L2 Surface Emissivity V003"
-                           :short-name "AST_05"
-                           :version-id "003"
-                           :matcher tir-mode?}
-                          {:entry-title "ASTER L2 Surface Reflectance SWIR and ASTER L2 Surface Reflectance VNIR V003"
-                           :short-name "AST_07"
-                           :version-id "003"
-                           :matcher (match-all swir-mode? vnir1-mode? vnir2-mode? day-granule?)}
-                          {:entry-title "ASTER L2 Surface Reflectance VNIR and Crosstalk Corrected SWIR V003"
-                           :short-name "AST_07XT"
-                           :version-id "003"
-                           :matcher (match-all swir-mode? vnir1-mode? vnir2-mode? day-granule?)}
-                          {:entry-title "ASTER L2 Surface Temperature V003"
-                           :short-name "AST_08"
-                           :version-id "003"
-                           :matcher tir-mode?}
-                          {:entry-title "ASTER L2 Surface Radiance VNIR and SWIR V003"
-                           :short-name "AST_09"
-                           :version-id "003"
-                           :matcher (match-all swir-mode? vnir1-mode? vnir2-mode? day-granule?)}
-                          {:entry-title "ASTER L2 Surface Radiance - VNIR and Crosstalk Corrected SWIR V003"
-                           :short-name "AST_09XT"
-                           :version-id "003"
-                           :matcher (match-all swir-mode? vnir1-mode? vnir2-mode? day-granule?)}
-                          {:entry-title "ASTER L2 Surface Radiance TIR V003"
-                           :short-name "AST_09T"
-                           :version-id "003"
-                           :matcher tir-mode?}
-                          {:entry-title "ASTER Digital Elevation Model V003"
-                           :short-name "AST14DEM"
-                           :version-id "003"
-                           :matcher (match-all vnir1-mode? vnir2-mode? day-granule?)}
-                          {:entry-title "ASTER Registered Radiance at the Sensor - Orthorectified V003"
-                           :short-name "AST14OTH"
-                           :version-id "003"
-                           :matcher (match-all vnir1-mode? vnir2-mode? day-granule?)}
-                          {:entry-title "ASTER Orthorectified Digital Elevation Model (DEM) V003"
-                           :short-name "AST14DMO"
-                           :version-id "003"
-                           :matcher (match-all vnir1-mode? vnir2-mode? day-granule?)}
-                          {:entry-title "ASTER L1B Registered Radiance at the Sensor V003"
-                           :short-name "AST_L1B"
-                           :version-id "003"}]}
+    :virtual-collections [
+      {:entry-title "ASTER L2 Surface Emissivity V003"
+       :short-name "AST_05"
+       :version-id "003"
+       :matcher tir-mode?}
+      {:entry-title "ASTER L2 Surface Reflectance SWIR and ASTER L2 Surface Reflectance VNIR V003"
+       :short-name "AST_07"
+       :version-id "003"
+       :matcher (match-all swir-mode? vnir1-mode? vnir2-mode? day-granule?)}
+      {:entry-title "ASTER L2 Surface Reflectance VNIR and Crosstalk Corrected SWIR V003"
+       :short-name "AST_07XT"
+       :version-id "003"
+       :matcher (match-all swir-mode? vnir1-mode? vnir2-mode? day-granule?)}
+      {:entry-title "ASTER L2 Surface Temperature V003"
+       :short-name "AST_08"
+       :version-id "003"
+       :matcher tir-mode?}
+      {:entry-title "ASTER L2 Surface Radiance VNIR and SWIR V003"
+       :short-name "AST_09"
+       :version-id "003"
+       :matcher (match-all swir-mode? vnir1-mode? vnir2-mode? day-granule?)}
+      {:entry-title "ASTER L2 Surface Radiance - VNIR and Crosstalk Corrected SWIR V003"
+       :short-name "AST_09XT"
+       :version-id "003"
+       :matcher (match-all swir-mode? vnir1-mode? vnir2-mode? day-granule?)}
+      {:entry-title "ASTER L2 Surface Radiance TIR V003"
+       :short-name "AST_09T"
+       :version-id "003"
+       :matcher tir-mode?}
+      {:entry-title "ASTER Digital Elevation Model V003"
+       :short-name "AST14DEM"
+       :version-id "003"
+       :matcher (match-all vnir1-mode? vnir2-mode? day-granule?)}
+      {:entry-title "ASTER Registered Radiance at the Sensor - Orthorectified V003"
+       :short-name "AST14OTH"
+       :version-id "003"
+       :matcher (match-all vnir1-mode? vnir2-mode? day-granule?)}
+      {:entry-title "ASTER Orthorectified Digital Elevation Model (DEM) V003"
+       :short-name "AST14DMO"
+       :version-id "003"
+       :matcher (match-all vnir1-mode? vnir2-mode? day-granule?)}
+      {:entry-title "ASTER L1B Registered Radiance at the Sensor V003"
+       :short-name "AST_L1B"
+       :version-id "003"}]}
    ["GES_DISC" "OMI/Aura Surface UVB Irradiance and Erythemal Dose Daily L3 Global 1.0x1.0 deg Grid V003 (OMUVBd) at GES DISC"]
    {:short-name "OMUVBd"
-    :virtual-collections [{:entry-title "OMI/Aura Surface UVB UV Index, Erythemal Dose, and Erythemal Dose Rate Daily L3 Global 1.0x1.0 deg Grid V003 (OMUVBd_ErythemalUV) at GES DISC"
-                           :short-name "OMUVBd_ErythemalUV"
-                           :version-id "003"}]}
+    :virtual-collections [
+      {:entry-title "OMI/Aura Surface UVB UV Index, Erythemal Dose, and Erythemal Dose Rate Daily L3 Global 1.0x1.0 deg Grid V003 (OMUVBd_ErythemalUV) at GES DISC"
+       :short-name "OMUVBd_ErythemalUV"
+       :version-id "003"}]}
    ["GES_DISC" "Aqua AIRS Level 3 Daily Standard Physical Retrieval (AIRS+AMSU) V006 (AIRX3STD) at GES DISC"]
    {:short-name "AIRX3STD"
-    :virtual-collections [{:entry-title "Aqua AIRS Level 3 Daily Standard Physical Retrieval (AIRS+AMSU) Water Vapor Mass Mixing Ratio V006 (AIRX3STD_H2O_MMR_Surf) at GES DISC"
-                           :short-name "AIRX3STD_H2O_MMR_Surf"
-                           :version-id "006"}
-                          {:entry-title "Aqua AIRS Level 3 Daily Standard Physical Retrieval (AIRS+AMSU) Outgoing Longwave Radiation V006 (AIRX3STD_OLR) at GES DISC"
-                           :short-name "AIRX3STD_OLR"
-                           :version-id "006"}
-                          {:entry-title "Aqua AIRS Level 3 Daily Standard Physical Retrieval (AIRS+AMSU) Surface Air Temperature V006 (AIRX3STD_SurfAirTemp) at GES DISC"
-                           :short-name "AIRX3STD_SurfAirTemp"
-                           :version-id "006"}
-                          {:entry-title "Aqua AIRS Level 3 Daily Standard Physical Retrieval (AIRS+AMSU) Surface Skin Temperature V006 (AIRX3STD_SurfSkinTemp) at GES DISC"
-                           :short-name "AIRX3STD_SurfSkinTemp"
-                           :version-id "006"}
-                          {:entry-title "Aqua AIRS Level 3 Daily Standard Physical Retrieval (AIRS+AMSU) Total Carbon Monoxide V006 (AIRX3STD_TotCO) at GES DISC"
-                           :short-name "AIRX3STD_TotCO"
-                           :version-id "006"}
-                          {:entry-title "Aqua AIRS Level 3 Daily Standard Physical Retrieval (AIRS+AMSU) Outgoing Longwave Radiation Clear Sky V006 (AIRX3STD_ClrOLR) at GES DISC"
-                           :short-name "AIRX3STD_ClrOLR"
-                           :version-id "006"}
-                          {:entry-title "Aqua AIRS Level 3 Daily Standard Physical Retrieval (AIRS+AMSU) Methane Total Column V006 (AIRX3STD_TotCH4) at GES DISC"
-                           :short-name "AIRX3STD_TotCH4"
-                           :version-id "006"}]}
+    :virtual-collections [
+      {:entry-title "Aqua AIRS Level 3 Daily Standard Physical Retrieval (AIRS+AMSU) Water Vapor Mass Mixing Ratio V006 (AIRX3STD_H2O_MMR_Surf) at GES DISC"
+       :short-name "AIRX3STD_H2O_MMR_Surf"
+       :version-id "006"}
+      {:entry-title "Aqua AIRS Level 3 Daily Standard Physical Retrieval (AIRS+AMSU) Outgoing Longwave Radiation V006 (AIRX3STD_OLR) at GES DISC"
+       :short-name "AIRX3STD_OLR"
+       :version-id "006"}
+      {:entry-title "Aqua AIRS Level 3 Daily Standard Physical Retrieval (AIRS+AMSU) Surface Air Temperature V006 (AIRX3STD_SurfAirTemp) at GES DISC"
+       :short-name "AIRX3STD_SurfAirTemp"
+       :version-id "006"}
+      {:entry-title "Aqua AIRS Level 3 Daily Standard Physical Retrieval (AIRS+AMSU) Surface Skin Temperature V006 (AIRX3STD_SurfSkinTemp) at GES DISC"
+       :short-name "AIRX3STD_SurfSkinTemp"
+       :version-id "006"}
+      {:entry-title "Aqua AIRS Level 3 Daily Standard Physical Retrieval (AIRS+AMSU) Total Carbon Monoxide V006 (AIRX3STD_TotCO) at GES DISC"
+       :short-name "AIRX3STD_TotCO"
+       :version-id "006"}
+      {:entry-title "Aqua AIRS Level 3 Daily Standard Physical Retrieval (AIRS+AMSU) Outgoing Longwave Radiation Clear Sky V006 (AIRX3STD_ClrOLR) at GES DISC"
+       :short-name "AIRX3STD_ClrOLR"
+       :version-id "006"}
+      {:entry-title "Aqua AIRS Level 3 Daily Standard Physical Retrieval (AIRS+AMSU) Methane Total Column V006 (AIRX3STD_TotCH4) at GES DISC"
+       :short-name "AIRX3STD_TotCH4"
+       :version-id "006"}]}
    ["GES_DISC" "Aqua AIRS Level 3 Monthly Standard Physical Retrieval (AIRS+AMSU) V006 (AIRX3STM) at GES DISC"]
    {:short-name "AIRX3STM"
-    :virtual-collections [{:entry-title "Aqua AIRS Level 3 Monthly Standard Physical Retrieval (AIRS+AMSU) Clear Sky Outgoing Longwave Flux V006 (AIRX3STM_ClrOLR) at GES DISC"
-                           :short-name "AIRX3STM_ClrOLR"
-                           :version-id "006"}
-                          {:entry-title "Aqua AIRS Level 3 Monthly Standard Physical Retrieval (AIRS+AMSU) Water Vapor Mass Mixing Ratio at Surface V006 (AIRX3STM_H2O_MMR_Surf) at GES DISC"
-                           :short-name "AIRX3STM_H2O_MMR_Surf"
-                           :version-id "006"}
-                          {:entry-title "Aqua AIRS Level 3 Monthly Standard Physical Retrieval (AIRS+AMSU) Outgoing Longwave Radiation V006 (AIRX3STM_OLR) at GES DISC"
-                           :short-name "AIRX3STM_OLR"
-                           :version-id "006"}
-                          {:entry-title "Aqua AIRS Level 3 Monthly Standard Physical Retrieval (AIRS+AMSU) Surface Air Temperature V006 (AIRX3STM_SurfAirTemp) at GES DISC"
-                           :short-name "AIRX3STM_SurfAirTemp"
-                           :version-id "006"}
-                          {:entry-title "Aqua AIRS Level 3 Monthly Standard Physical Retrieval (AIRS+AMSU) Surface Skin Temperature V006 (AIRX3STM_SurfSkinTemp) at GES DISC"
-                           :short-name "AIRX3STM_SurfSkinTemp"
-                           :version-id "006"}
-                          {:entry-title "Aqua AIRS Level 3 Monthly Standard Physical Retrieval (AIRS+AMSU) Total Carbon Monoxide V006 (AIRX3STM_TotCO) at GES DISC"
-                           :short-name "AIRX3STM_TotCO"
-                           :version-id "006"}
-                          {:entry-title "Aqua AIRS Level 3 Monthly Standard Physical Retrieval (AIRS+AMSU) Methane Total Column V006 (AIRX3STM_TotCH4) at GES DISC"
-                           :short-name "AIRX3STM_TotCH4"
-                           :version-id "006"}]}
+    :virtual-collections [
+      {:entry-title "Aqua AIRS Level 3 Monthly Standard Physical Retrieval (AIRS+AMSU) Clear Sky Outgoing Longwave Flux V006 (AIRX3STM_ClrOLR) at GES DISC"
+       :short-name "AIRX3STM_ClrOLR"
+       :version-id "006"}
+      {:entry-title "Aqua AIRS Level 3 Monthly Standard Physical Retrieval (AIRS+AMSU) Water Vapor Mass Mixing Ratio at Surface V006 (AIRX3STM_H2O_MMR_Surf) at GES DISC"
+       :short-name "AIRX3STM_H2O_MMR_Surf"
+       :version-id "006"}
+      {:entry-title "Aqua AIRS Level 3 Monthly Standard Physical Retrieval (AIRS+AMSU) Outgoing Longwave Radiation V006 (AIRX3STM_OLR) at GES DISC"
+       :short-name "AIRX3STM_OLR"
+       :version-id "006"}
+      {:entry-title "Aqua AIRS Level 3 Monthly Standard Physical Retrieval (AIRS+AMSU) Surface Air Temperature V006 (AIRX3STM_SurfAirTemp) at GES DISC"
+       :short-name "AIRX3STM_SurfAirTemp"
+       :version-id "006"}
+      {:entry-title "Aqua AIRS Level 3 Monthly Standard Physical Retrieval (AIRS+AMSU) Surface Skin Temperature V006 (AIRX3STM_SurfSkinTemp) at GES DISC"
+       :short-name "AIRX3STM_SurfSkinTemp"
+       :version-id "006"}
+      {:entry-title "Aqua AIRS Level 3 Monthly Standard Physical Retrieval (AIRS+AMSU) Total Carbon Monoxide V006 (AIRX3STM_TotCO) at GES DISC"
+       :short-name "AIRX3STM_TotCO"
+       :version-id "006"}
+      {:entry-title "Aqua AIRS Level 3 Monthly Standard Physical Retrieval (AIRS+AMSU) Methane Total Column V006 (AIRX3STM_TotCH4) at GES DISC"
+       :short-name "AIRX3STM_TotCH4"
+       :version-id "006"}]}
    ["LPDAAC_ECS" "ASTER Level 1 precision terrain corrected registered at-sensor radiance V003"]
    {:short-name "AST_L1T"
-    :virtual-collections [{:entry-title "ASTER Level 1 Full Resolution Browse Thermal Infrared V003"
-                           :short-name "AST_FRBT"
-                           :version-id "003"
-                           :matcher (matches-on-psa "FullResolutionThermalBrowseAvailable" "YES")}
-                          {:entry-title "ASTER Level 1 Full Resolution Browse Visible Near Infrared V003"
-                           :short-name "AST_FRBV"
-                           :version-id "003"
-                           :matcher (matches-on-psa "FullResolutionVisibleBrowseAvailable" "YES")}]}
+    :virtual-collections [
+      {:entry-title "ASTER Level 1 Full Resolution Browse Thermal Infrared V003"
+       :short-name "AST_FRBT"
+       :version-id "003"
+       :matcher (matches-on-psa "FullResolutionThermalBrowseAvailable" "YES")}
+      {:entry-title "ASTER Level 1 Full Resolution Browse Visible Near Infrared V003"
+       :short-name "AST_FRBV"
+       :version-id "003"
+       :matcher (matches-on-psa "FullResolutionVisibleBrowseAvailable" "YES")}]}
    ["GES_DISC" "GLDAS Noah Land Surface Model L4 3 hourly 1.0 x 1.0 degree V2.0 (GLDAS_NOAH10_3H) at GES DISC"]
    {:short-name "GLDAS_NOAH10_3H"
-    :virtual-collections [{:entry-title "GLDAS Noah Land Surface Model L4 3 hourly 1.0 x 1.0 degree Rain Rate, Avg. Surface Skin Temp., Soil Moisture V2.0 (GLDAS_NOAH10_3Hourly) at GES DISC"
-                           :short-name "GLDAS_NOAH10_3Hourly"
-                           :version-id "2.0"}]}
+    :virtual-collections [
+      {:entry-title "GLDAS Noah Land Surface Model L4 3 hourly 1.0 x 1.0 degree Rain Rate, Avg. Surface Skin Temp., Soil Moisture V2.0 (GLDAS_NOAH10_3Hourly) at GES DISC"
+       :short-name "GLDAS_NOAH10_3Hourly"
+       :version-id "2.0"}]}
    ["GES_DISC" "GLDAS Noah Land Surface Model L4 Monthly 1.0 x 1.0 degree V2.0 (GLDAS_NOAH10_M) at GES DISC"]
    {:short-name "GLDAS_NOAH10_M"
-    :virtual-collections [{:entry-title "GLDAS Noah Land Surface Model L4 Monthly 1.0 x 1.0 degree Rain Rate, Avg. Surface Skin Temp., Soil Moisture V2.0 (GLDAS_NOAH10_Monthly) at GES DISC"
-                           :short-name "GLDAS_NOAH10_Monthly"
-                           :version-id "2.0"}]}})
+    :virtual-collections [
+      {:entry-title "GLDAS Noah Land Surface Model L4 Monthly 1.0 x 1.0 degree Rain Rate, Avg. Surface Skin Temp., Soil Moisture V2.0 (GLDAS_NOAH10_Monthly) at GES DISC"
+       :short-name "GLDAS_NOAH10_Monthly"
+       :version-id "2.0"}]}})

 (def virtual-product-to-source-mapping
   "A map derived from the map source-to-virtual-product-mapping. This map consists of keys which are
@@ -368,7 +375,7 @@
 (defn- ast-l1t-virtual-browse-qa-urls
   "Returns the online resource urls for virtual granule of the given AST_L1T granule"
   [virtual-umm virtual-short-name]
-  (let [browse-qa-urls (filter #(not (ruh/downloadable-url? %)) (:related-urls virtual-umm))
+  (let [browse-qa-urls (remove ruh/downloadable-url? (:related-urls virtual-umm))
         [browse-psa browse-suffix] (if (= "AST_FRBT" virtual-short-name)
                                      ["FullResolutionThermalBrowseAvailable" ".TIR.jpg"]
                                      ["FullResolutionVisibleBrowseAvailable" ".VNIR.jpg"])
@@ -400,10 +407,12 @@

 (defmethod update-virtual-granule-umm ["LPDAAC_ECS" "AST_L1A"]
   [virtual-umm provider-id source-short-name virtual-short-name]
-  (-> virtual-umm
-      (update-in [:product-specific-attributes]
-                 (fn [psas] (filter #((l1a/short-name->additional-attributes virtual-short-name)
-                                      (:name %)) psas)))))
+  (update-in
+    virtual-umm
+    [:product-specific-attributes]
+    (fn [psas]
+      (filter #((l1a/short-name->additional-attributes virtual-short-name)
+                (:name %)) psas))))

 (defn generate-virtual-granule-umm
   "Generate the virtual granule umm based on source granule umm"


Add option to manually disable button

Add option to manually disable button

--- frontend/src/cruncher/utils/views.cljs
+++ frontend/src/cruncher/utils/views.cljs
@@ -13,12 +13,13 @@

 (defn button-primary
   "Create dom element of a bootstrap primary button."
-  [fn & strs]
-  (dom/button #js {:className "btn btn-primary"
-                   :onClick   fn
-                   :disabled  (or (lib/loading?) (lib/progress?))
-                   :react-key (lib/get-unique-key)}
-              strs))
+  ([fn not-empty? str]
+   (dom/button #js {:className "btn btn-primary"
+                    :onClick   fn
+                    :disabled  (or (lib/loading?) (lib/progress?) (not not-empty?))
+                    :react-key (lib/get-unique-key)}
+               str))
+  ([fn str] (button-primary fn true str)))

 (defn fa-icon
   "Wrapper for font-awesome icons."


first stop editing, then change selection/cursor

--- cljs/src/main/plastic/main/editor/selections.cljs
+++ cljs/src/main/plastic/main/editor/selections.cljs
@@ -11,36 +11,27 @@
 (defn clear-selection [editors [selector]]
   (editor/apply-to-editors editors selector
     (fn [editor]
-      (-> editor
-        (editing/stop-editing)
-        (editor/set-selection #{})))))
+      (editing/stop-editing editor #(editor/set-selection % #{})))))

 (defn set-selection [editors [selector selection]]
   (editor/apply-to-editors editors selector
     (fn [editor]
-      (-> editor
-        (editing/stop-editing)
-        (editor/set-selection selection)))))
+      (editing/stop-editing editor #(editor/set-selection % selection)))))

 (defn toggle-selection [editors [selector selection]]
   (editor/apply-to-editors editors selector
     (fn [editor]
-      (-> editor
-        (editing/stop-editing)
-        (editor/toggle-selection selection)))))
+      (editing/stop-editing editor #(editor/toggle-selection % selection)))))

 (defn set-cursor [editors [selector cursor link?]]
   (editor/apply-to-editors editors selector
     (fn [editor]
-      (-> editor
-        (editor/set-cursor cursor link?)))))
+      (editing/stop-editing editor #(editor/set-cursor % cursor link?)))))

 (defn clear-cursor [editors [selector]]
   (editor/apply-to-editors editors selector
     (fn [editor]
-      (-> editor
-        (editing/stop-editing)
-        (editor/set-cursor nil)))))
+      (editing/stop-editing editor #(editor/set-cursor % nil)))))

 ; ----------------------------------------------------------------------------------------------------------------------
 ; register handlers


print results of errors

print results of errors

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

--- plugins/SlideExplorer2/src/slide_explorer/tile_cache.clj
+++ plugins/SlideExplorer2/src/slide_explorer/tile_cache.clj
@@ -17,7 +17,7 @@
   [memory-tile-atom key image-processor]
   (swap! memory-tile-atom cache/add-item key image-processor)
   (when-let [dir (tile-dir memory-tile-atom)]
-    (.submit file-executor #(disk/write-tile dir key image-processor))))
+    (reactive/submit file-executor #(disk/write-tile dir key image-processor))))

 (defn load-tile
   [memory-tile-atom key]


should pass lib name to eval-str* from require

--- src/main/cljs/cljs/js.cljs
+++ src/main/cljs/cljs/js.cljs
@@ -109,9 +109,9 @@
            (assert (or (map? resource) (nil? resource))
              "*load-fn* may only return a map or nil")
            (if resource
-             (let [{:keys [lang source]} resource]
+             (let [{:keys [name lang source]} resource]
                (condp = lang
-                 :clj (eval-str* bound-vars source opts
+                 :clj (eval-str* bound-vars source name opts
                         (fn [ret] (cb true)))
                  :js  (do
                         ((:*eval-fn* bound-vars) resource)


make tests pass

make tests pass

--- src/main/om_css/utils.cljc
+++ src/main/om_css/utils.cljc
@@ -20,17 +20,16 @@
                     (keyword? cns))
             cns
             (let [cns' (map #(format-class-name component-info %)
-                         cns)]
+                         (if (sequential? cns) cns [cns]))]
               (if (sequential? cns)
                 (into [] cns')
                 (first cns'))))
      ;; only transform keywords at runtime, vectors and strings have
      ;; already been prefixed at macro-expansion time
-     :cljs (->> cns
+     :cljs (->> (if (sequential? cns) cns [cns])
              (map #(cond->> %
                      (keyword? %) (format-class-name component-info)))
              (string/join " "))))

 (defn format-class-names [component-info cns]
-  (let [cns (if (sequential? cns) cns [cns])]
-    (format-cns* component-info cns)))
+  (format-cns* component-info cns))


Story ID: develop Summary: Quick react warning fix, gave ui-filter-selector a :keyfn

--- src/untangled_spec/reporters/browser.cljs
+++ src/untangled_spec/reporters/browser.cljs
@@ -118,7 +118,7 @@
                              :onClick (set-filter! this-filter)}
                         (str this-filter)))))

-(def ui-filter-selector (om/factory FilterSelector))
+(def ui-filter-selector (om/factory FilterSelector {:keyfn :this-filter}))

 (defui Filters
        Object
@@ -132,7 +132,7 @@
                                                       :this-filter %})
                                 [:all :manual :failed])))))

-(def ui-filters (om/factory Filters))
+(def ui-filters (om/factory Filters ))

 (defn debounce [f interval]
   (let [timeout (atom nil)]


[Server] Revert behavioural change from #391

Looks like this could cause issues in the wild,
e.g. https://github.com/ptaoussanis/sente/issues/336.

Will instead add a new API and deprecate `with-channel`.

--- src/org/httpkit/server.clj
+++ src/org/httpkit/server.clj
@@ -198,9 +198,6 @@
   asynchronous HTTP or WebSocket channel, and returns {:body AsyncChannel}
   as an implementation detail.

-  Note: for WebSocket requests, WebSocket handshake will be sent *after*
-  body is evaluated. I.e. body cannot call `send!`.
-
   ;; Asynchronous HTTP response (with optional streaming)
   (defn my-async-handler [request]
     (with-channel request ch ; Request's channel
@@ -242,8 +239,8 @@
      (if (:websocket? ring-req#)
        (if-let [sec-ws-accept# (websocket-handshake-check ring-req#)]
          (do
-           ~@body ; Eval body before handshake to allow hooks to be established, Ref. #318
            (send-checked-websocket-handshake! ~ch-name sec-ws-accept#)
+           ~@body
            {:body ~ch-name})
          {:status 400 :body "Bad Sec-WebSocket-Key header"})
        (do ~@body {:body ~ch-name}))))


account -> project (#1263)

account -> project (#1263)

--- src/cljs/main/broadfcui/page/billing/create_project.cljs
+++ src/cljs/main/broadfcui/page/billing/create_project.cljs
@@ -40,7 +40,7 @@
               [:div {:style {:width 750}
                      :data-test-id "create-billing-project-form"}
                (when (:creating? @state)
-                 (blocker "Creating billing account..."))
+                 (blocker "Creating billing project..."))
                [:div {:style {:fontSize "120%"}}
                 "1. Enter a unique name:"]
                [input/TextField {:ref "name-field" :autoFocus true


Improve path construction impl in storages module.

--- vendor/storages/impl.clj
+++ vendor/storages/impl.clj
@@ -98,6 +98,9 @@
   String
   (-uri [v] (URI. v)))

+(def ^:private empty-string-array
+  (make-array String 0))
+
 (extend-protocol pt/IPath
   Path
   (-path [v] v)
@@ -109,13 +112,13 @@
   (-path [v] (Paths/get (.toURI v)))

   String
-  (-path [v] (Paths/get v (make-array String 0)))
+  (-path [v] (Paths/get v empty-string-array))

   clojure.lang.Sequential
   (-path [v]
-    (let [fv (first v)
-          mv (rest v)]
-      (Paths/get ^String fv (into-array String mv)))))
+    (reduce #(.resolve %1 %2)
+            (pt/-path (first v))
+            (map pt/-path (rest v)))))

 (defn- path->input-stream
   [^Path path]


CMR-3430: cleaned up the code.

CMR-3430: cleaned up the code.

--- system-int-test/test/cmr/system_int_test/search/collection_keyword_search_test.clj
+++ system-int-test/test/cmr/system_int_test/search/collection_keyword_search_test.clj
@@ -1,7 +1,6 @@
 (ns cmr.system-int-test.search.collection-keyword-search-test
   "Integration test for CMR collection search by keyword terms"
   (:require
-    [clojure.java.io :as io]
     [clojure.test :refer :all]
     [cmr.common.util :refer [are3]]
     [cmr.search.data.keywords-to-elastic :as k2e]


[#248] update akvo-flow clojars version

[#248] update akvo-flow clojars version

--- api/project.clj
+++ api/project.clj
@@ -15,7 +15,7 @@
                  [ring/ring-json "0.4.0"]
                  [ring-jetty-component "0.3.1"]
                  [commons-fileupload "1.3.1"]
-                 [org.akvo.flow/akvo-flow "20220120-233458.89643d80" :classifier "classes" :exclusions [org.simplejavamail/simple-java-mail]]
+                 [org.akvo.flow/akvo-flow "20221115-123123.ac209264" :classifier "classes" :exclusions [org.simplejavamail/simple-java-mail]]
                  [org.akvo/commons "0.4.5" :exclusions [org.clojure/tools.nrepl]]
                  [raven-clj "1.5.0"]
                  [javax.jdo/jdo2-api "2.3-eb"]


Make link handling more flexible

Make link handling more flexible

so we can later handle links in editorials, etc

--- src/catalog/layout/fop.clj
+++ src/catalog/layout/fop.clj
@@ -109,10 +109,13 @@
             api-key
             (string/replace record-id "/" "."))))

-(defn- external-link [record-id title]
-  [:fo:basic-link {:external-destination (to-url record-id)
-                   :indicate-destination true}
+(defn- external-link [url title]
+  [:fo:basic-link
+   {:external-destination url :indicate-destination true}
    title])
+
+(defn- link-to-online-catalog [record-id title]
+  (external-link (to-url record-id) title))

 (defn- block [& args]
   (if (map? (first args))
@@ -144,7 +147,7 @@
   [creator record-id title subtitles name-of-part source-publisher source-date]
   (block {:keep-with-next "always"}
      (bold (wrap creator "" ": " false)
-           (external-link record-id (layout/periodify title)))
+           (link-to-online-catalog record-id (layout/periodify title)))
      (when subtitles " ")
      (layout/render-subtitles subtitles)
      (wrap name-of-part " ")
@@ -221,7 +224,7 @@
            description producer library-signature]}]
   (list-item
    (block {:keep-with-next "always"}
-     (bold (external-link record-id (layout/periodify title)))
+     (bold (link-to-online-catalog record-id (layout/periodify title)))
      (layout/render-subtitles subtitles))
    (block (wrap directed-by "Regie: " "") (wrap actors " Schauspieler: " ""))
    (block (wrap movie_country))
@@ -235,7 +238,7 @@
            game-description accompanying-material library-signature]}]
   (list-item
    (block {:keep-with-next "always"}
-     (bold (external-link record-id (layout/periodify title)))
+     (bold (link-to-online-catalog record-id (layout/periodify title)))
      (layout/render-subtitles subtitles)
      (layout/wrap creator " "))
    (block (wrap source-publisher))


factor out public group join & register functions

--- src/chat/server/routes.clj
+++ src/chat/server/routes.clj
@@ -70,6 +70,35 @@
   ; TODO: add mobile routse for public joining & password resets
   (GET "/*" []
     (get-html "mobile")))
+
+(defn register-user
+  [email group-id]
+  (let [id (db/uuid)
+        avatar (identicons/id->identicon-data-url id)
+        ; XXX: copied from chat.shared.util/nickname-rd
+        disallowed-chars #"[ \t\n\]\[!\"#$%&'()*+,.:;<=>?@\^`{|}~/]"
+        nick (-> (first (string/split email #"@"))
+                 (string/replace disallowed-chars ""))
+        ; TODO: guard against duplicate nickname?
+        u (db/create-user! {:id id
+                            :email email
+                            :password (random-nonce 50)
+                            :avatar avatar
+                            :nickname nick})]
+    (db/user-add-to-group! id group-id)
+    (db/user-subscribe-to-group-tags! id group-id)
+    (sync/broadcast-group-change group-id
+                                 [:group/new-user (db/user-by-id id)])
+    id))
+
+(defn join-group
+  [user-id group-id]
+  (when-not (db/user-in-group? user-id group-id)
+    (db/user-add-to-group! user-id group-id)
+    (db/user-subscribe-to-group-tags! user-id group-id)
+    (sync/broadcast-group-change
+      group-id
+      [:group/new-user (db/user-by-id user-id)])))

 (defroutes api-public-routes
   ; check if already logged in
@@ -156,27 +185,11 @@
               (assoc bad-resp :body "Invalid email")
               (if (db/user-with-email email)
                 (assoc bad-resp
-                  :body (str "A user is already registered with that email.\n"
-                             "Log in and try joining"))
-                (let [id (db/uuid)
-                      avatar (identicons/id->identicon-data-url id)
-                      ; XXX: copied from chat.shared.util/nickname-rd
-                      disallowed-chars #"[ \t\n\]\[!\"#$%&'()*+,.:;<=>?@\^`{|}~/]"
-                      nick (-> (first (string/split email #"@"))
-                               (string/replace disallowed-chars ""))
-                      u (db/create-user! {:id id
-                                                        :email email
-                                                        :password (random-nonce 50)
-                                                        :avatar avatar
-                                                        :nickname nick})
+                       :body (str "A user is already registered with that email.\n"
+                                  "Log in and try joining"))
+                (let [user-id (register-user email group-id)
                       referer (get-in req [:headers "referer"] (env :site-url))
                       [proto _ referrer-domain] (string/split referer #"/")]
-                  (do
-                    (db/user-add-to-group! id group-id)
-                    (db/user-subscribe-to-group-tags! id group-id)
-                    (sync/broadcast-group-change
-                      group-id
-                      [:group/new-user (db/user-by-id id)]))
                   {:status 302 :headers {"Location" (str proto "//" referrer-domain)}
                    :session (assoc (req :session) :user-id id)
                    :body ""}))))))))
@@ -191,13 +204,7 @@
             (assoc bad-resp :body "No such group or the group is private")
             (if-let [user-id (get-in req [:session :user-id])]
               (do
-                (when-not (db/user-in-group? user-id group-id)
-                  (do
-                    (db/user-add-to-group! user-id group-id)
-                    (db/user-subscribe-to-group-tags! user-id group-id)
-                    (sync/broadcast-group-change
-                      group-id
-                      [:group/new-user (db/user-by-id user-id)])))
+                (join-group user-id group-id)
                 (let [referer (get-in req [:headers "referer"] (env :site-url))
                       [proto _ referrer-domain] (string/split referer #"/")]
                   {:status 302


upgraded result - ready to add :errors or :unknown :angles or :points or any other vectors nested in a given map

--- src/clj/ephemeris/core.clj
+++ src/clj/ephemeris/core.clj
@@ -61,16 +61,20 @@
     {}))

 ;; expects an atom map, key, and value to assoc
+;; alternatively, k can be a vector of keys where get-in yields a vector value
 ;; returns the value for further use
 (defn- result [a k v]
-  (do (swap! a assoc k v)
-   v))
+  (if (vector? k)
+    (do (reset! a (assoc-in @a k (conj (get-in @a k) v)))
+      v)
+    (do (swap! a assoc k v)
+      v)))

 (defn calc
   ([] (calc {}))
   ([stuff]
    (let [want (merge defaults stuff)
-         re (atom {:errors []})
+         re (atom {:unknown {:angles [] :points []} :errors []})
          sw (SwissEph.)
          jd (result re :jd (utc-to-jd (:utc want)))
          eph (result re :ephemeris :MOSEPH) ;; can become :SWIEPH or :JPLEPH


oops, pings need user id

oops, pings need user id

--- src/clj/tictag/tagtime.clj
+++ src/clj/tictag/tagtime.clj
@@ -58,7 +58,6 @@
   (->> (str/split log #"\n")
        (map parse-line)
        (filter #(not (nil? %)))
-       (map #(assoc % :user-id user-id))
        (reduce (fn [accu {:keys [local-time ts] :as m}]
                  (if local-time
                    (conj accu m)
@@ -68,4 +67,5 @@
                [])
        (map add-tz-offset)
        (map #(select-keys % [:tz-offset :ts :tags]))
+       (map #(assoc % :user-id user-id))
        seq))


fixed

fixed

--- src/cljs/html2om/core.cljs
+++ src/cljs/html2om/core.cljs
@@ -77,10 +77,21 @@
   {:value "bar"}
   )

+#_(defmethod readf :om-text/om-text
+  [{:keys [state ast] :as env} k params]
+  (println "ast is"
+           ast)
+  {:remote ast
+   ;:value "hello there"
+   }
+  )
 (defmethod readf :om-text/om-text
   [{:keys [state] :as env} k params]
-  {:remote true}
-  )
+  (let [st @state
+        local-val (:om-text/om-text st)]
+      {:value local-val
+      :remote true}))
+

 (defmethod readf :value
   [{:keys [state] :as env} k params]
@@ -104,7 +115,9 @@
 ;; Root

 (def data
-  (atom {:value ""}))
+  (atom {:value ""
+         :om-text/om-text ""
+         }))

 (def parser (om/parser {:read readf
                         :mutate mutatef
@@ -119,7 +132,7 @@
                                 (println "calling cb" (prn-str x))
                                 ; this receives {:om-text/om-text "foo"}
                                 ; but dom/pre in RootView won't be updated
-                                (cb x)
+                                (cb x data)
                                 )
      }
     )


Fixed typo on thought remove confirm

Fixed typo on thought remove confirm

--- src/cljs/memento/core.cljs
+++ src/cljs/memento/core.cljs
@@ -521,7 +521,7 @@
                    {:placement :top
                     :overlay   tooltip}
                    [:span {:class    "btn btn-danger btn-xs icon-margin-left"
-                           :on-click #(when (js/confirm "Are you sure you want to remove the thought/")
+                           :on-click #(when (js/confirm "Are you sure you want to remove the thought from the cluster?")
                                         (dispatch [:cluster-remove-thought (:id cluster) (:id memory)]))}
                     [:i {:class "fa fa-minus"}]]])]
     [:span


Add buttons for tool selection

Add buttons for tool selection

--- src/cljs/pizarra/core.cljs
+++ src/cljs/pizarra/core.cljs
@@ -126,14 +126,23 @@
     om/IRender
     (render [_]
       (dom/div nil
+               (dom/label nil "Line width")
                (dom/input #js {:type "text"
                                :value (get-in tools [:props :lineWidth])
                                :onChange (fn [e]
                                            (om/update! tools [:props :lineWidth] (js/parseInt (.-value (.-currentTarget e)))))})
+               (dom/label nil "Color")
                (dom/input #js {:type "text"
                                :value (get-in tools [:props :strokeStyle])
                                :onChange (fn [e]
-                                           (om/update! tools [:props :strokeStyle] (.-value (.-currentTarget e))))})))))
+                                           (om/update! tools [:props :strokeStyle] (.-value (.-currentTarget e))))})
+               (dom/button #js {:disabled (= (om/value (:current tools)) :freehand)
+                                :onClick (fn [e]
+                                           (om/update! tools [:current] :freehand))} "Freebird")
+               (dom/button #js {:disabled (= (om/value (:current tools)) :line)
+                                :onClick (fn [e]
+                                           (om/update! tools [:current] :line))} "Line")
+               ))))

 (defn app-component [app owner]
   (reify
@@ -209,6 +218,7 @@
 (deref app-state)

 (swap! app-state assoc-in [:tools :props :lineWidth] 3)
+(swap! app-state assoc-in [:tools :current] :line)

 (swap! app-state update-in [:canvas :dimensions] assoc :width 900 :height 300)


Remove debug println

Remove debug println

--- src/cljs/re_form/core.cljs
+++ src/cljs/re_form/core.cljs
@@ -119,7 +119,6 @@
     :component-will-receive-props
     (fn [_ coll]
       (let [new-props (second coll)]
-        (println new-props)
         (deinit (:form-name new-props))
         (init new-props)))


Handle doc calls for &, catch, and finally

The standard ClojureScript REPL handles doc calls for & by mapping it
to fn, and for catch and finally by mapping it to try

--- src/cljs/replumb/repl.cljs
+++ src/cljs/replumb/repl.cljs
@@ -540,6 +540,12 @@
                                  (common/wrap-error error)
                                  (common/wrap-success nil))))))))

+(defn doc-map-special-symbols
+  [sym]
+  (get '{&       fn
+         catch   try
+         finally try} sym sym))
+
 (defn process-doc
   [opts cb data sym]
   (call-back! (merge opts {:no-pr-str-on-value true})
@@ -547,11 +553,12 @@
               data
               (common/wrap-success
                (with-out-str
-                 (cond
-                   (docs/special-doc-map sym) (repl/print-doc (docs/special-doc sym))
-                   (docs/repl-special-doc-map sym) (repl/print-doc (docs/repl-special-doc sym))
-                   (ast/namespace @st sym) (repl/print-doc (select-keys (ast/namespace @st sym) [:name :doc]))
-                   :else (repl/print-doc (get-var opts (empty-analyzer-env) sym)))))))
+                 (let [sym (doc-map-special-symbols sym)]
+                   (cond
+                     (docs/special-doc-map sym) (repl/print-doc (docs/special-doc sym))
+                     (docs/repl-special-doc-map sym) (repl/print-doc (docs/repl-special-doc sym))
+                     (ast/namespace @st sym) (repl/print-doc (select-keys (ast/namespace @st sym) [:name :doc]))
+                     :else (repl/print-doc (get-var opts (empty-analyzer-env) sym))))))))

 (defn process-pst
   [opts cb data expr]


Cosmetic changes

Cosmetic changes

--- src/cljs/replumb/repl.cljs
+++ src/cljs/replumb/repl.cljs
@@ -637,19 +637,18 @@
         (recur second-form (read))))))

 (defn process-load-file
-  [{:keys [verbose read-file-fn! src-paths] :as opts} cb data filename]
+  [{:keys [verbose read-file-fn! src-paths] :as opts} cb data file-name]
   (let [call-back (partial call-back! opts cb data)]
     (if read-file-fn!
       (load/read-files-and-callback! verbose
-                                     (load/file-paths src-paths filename)
+                                     (load/file-paths src-paths file-name)
                                      read-file-fn!
-                                     (fn [result]
+                                     (fn [{:keys [source] :as result}]
                                        (if result
-                                         (let [eval-opts (load-eval-opts! opts filename)
-                                               src (:source result)]
-                                           (eval-str* eval-opts opts cb data src (last-form src)))
+                                         (let [eval-opts (load-eval-opts! opts file-name)]
+                                           (eval-str* eval-opts opts cb data source (last-form source)))
                                          (call-back (common/wrap-error
-                                                     (ex-info (str "Could not load file " filename) ex-info-data))))))
+                                                     (ex-info (str "Could not load file " file-name) ex-info-data))))))
       (do (when verbose
             (common/debug-prn "No :read-file-fn! provided, skipping file loading..."))
           (call-back (common/wrap-success nil))))))


expanded token seperators

expanded token seperators


ignore deftype in pprint code

ignore deftype in pprint code

--- src/cljs_api_gen/parse.clj
+++ src/cljs_api_gen/parse.clj
@@ -172,12 +172,13 @@

 (defn parse-deftype
   [form]
-  (let [name- (second form)
-        form (drop 2 form)
-        signature (first form)]
-  {:docstring nil
-   :signature [signature]
-   :type "type"}))
+  (when (not= *cur-ns* "cljs.pprint") ;; ignore custom deftypes here
+    (let [name- (second form)
+          form (drop 2 form)
+          signature (first form)]
+      {:signature (when signature
+                    [signature])
+       :type "type"})))

 (defmulti parse-form*
   (fn [form]


Reduce code dup in compose

Reduce code dup in compose

--- src/cljx/transom/core.cljx
+++ src/cljx/transom/core.cljx
@@ -92,9 +92,7 @@

 (defn compose
   ([doc old new]
-    (let [mappings (mappings-for doc old new)
-          rebased (set/rename-keys old mappings)
-          rebased (dissoc rebased nil)]
+    (let [rebased (rebase-keys doc old new)]
       (reduce
         (fn [composed [new-path new-edit]]
           (if (contains? composed new-path)