Adapt catacumba.impl.handlers to ratpack promise changes.

And helpers api changes.

--- src/clojure/catacumba/impl/handlers.clj
+++ src/clojure/catacumba/impl/handlers.clj
@@ -31,7 +31,7 @@
             [catacumba.stream :as stream]
             [catacumba.utils :as utils]
             [catacumba.impl.context :as ctx]
-            [catacumba.impl.helpers :as helpers]
+            [catacumba.impl.helpers :as ch]
             [catacumba.impl.http :as http])
   (:import ratpack.handling.Handler
            ratpack.handling.Context
@@ -42,8 +42,9 @@
            ratpack.http.TypedData
            ratpack.http.MutableHeaders
            ratpack.util.MultiValueMap
-           ratpack.exec.Fulfiller
+           ratpack.exec.Downstream
            ratpack.exec.Promise
+           ratpack.exec.Blocking
            catacumba.impl.context.DefaultContext
            org.reactivestreams.Publisher
            java.util.concurrent.CompletableFuture
@@ -145,17 +146,16 @@
         (send ctx)))

   CompletableFuture
-  (send [data ^Context ctx]
-    (p/then (helpers/promise ctx #(.accept % data))
-            (fn [response]
-              (send response ctx))))
+  (send [future' ^Context ctx]
+    (-> (ch/promise (fn [resolve] (resolve future')))
+        (ch/then #(send % ctx))))

   Publisher
   (send [data ^Context ctx]
     (let [^Response response (.getResponse ctx)]
       (->> (stream/publisher data)
-           (stream/transform (map helpers/bytebuffer))
-           (.stream ctx)
+           (stream/transform (map ch/bytebuffer))
+           (stream/bind-exec)
            (.sendStream response))))

   ;; TODO: reimplement this as chunked stream instread of
@@ -164,17 +164,17 @@
   InputStream
   (send [data ^Context ctx]
     (let [^Response response (.getResponse ctx)
-          ^Promise prom (.blocking ctx #(let [^bytes buffer (byte-array 1024)
-                                              ^ByteBuf buf (Unpooled/buffer (.available data))]
-                                          (loop [index 0]
-                                            (let [readed (.read data buffer 0 1024)]
-                                              (when-not (= readed -1)
-                                                (.writeBytes buf buffer 0 readed)
-                                                (recur (+ index readed)))))
-                                          buf))]
-      (.then prom (helpers/action
-                   (fn [buff]
-                     (.send response buff)))))))
+          ^Promise prom (ch/blocking
+                         (let [^bytes buffer (byte-array 1024)
+                               ^ByteBuf buf (Unpooled/buffer (.available data))]
+                           (loop [index 0]
+                             (let [readed (.read data buffer 0 1024)]
+                               (when-not (= readed -1)
+                                 (.writeBytes buf buffer 0 readed)
+                                 (recur (+ index readed)))))
+                           buf))]
+      (ch/then prom (fn [buff]
+                      (.send response buff))))))

 (extend-protocol IResponse
   DefaultContext
@@ -192,7 +192,7 @@

   Request
   (get-body* [^Request request]
-    (.getBody request)))
+    (Blocking/on (.getBody request))))

 (extend-protocol IHeaders
   DefaultContext
@@ -306,23 +306,6 @@
   (make-output-stream [req opts]
     (io/make-output-stream (get-body* req) opts)))

-(defn build-request
-  [^Request request]
-  (let [local-address (.getLocalAddress request)
-        remote-address (.getRemoteAddress request)]
-    {:server-port (.getPort local-address)
-     :server-name (.getHostText local-address)
-     :remote-addr (.getHostText remote-address)
-     :uri (str "/" (.getPath request))
-     :query-string (.getQuery request)
-     :scheme :http
-     :request-method (keyword (.. request getMethod getName toLowerCase))
-     :headers (get-headers* request)
-     :content-type (.. request getBody getContentType getType)
-     :content-length (Integer/parseInt (.. request getHeaders (get "Content-Length")))
-     :character-encoding (.. request getBody getContentType (getCharset "utf-8"))
-     :body (.. request getBody getInputStream)}))
-
 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
 ;; Public Api
 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
@@ -406,6 +389,10 @@
     (let [metadata (meta handler)]
       (:handler-type metadata)))
   :default :catacumba/default)
+
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+;; Adapters Implementation
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

 (defmethod adapter :catacumba/default
   [handler]
@@ -428,22 +415,36 @@
             context-params (ctx/context-params context)
             route-params (ctx/route-params context)
             context (-> (merge context context-params)
-                        (assoc :route-params route-params))
-            prom (helpers/promise ctx (fn [^Fulfiller ff]
-                                        (handler context #(.success ff %))))]
-        ;; TODO: use promise composition helpers
-        ;; instead of raw interop.
-        (.then ^Promise prom
-               (helpers/action
-                (fn [response]
-                  (handle-response response context))))))))
+                        (assoc :route-params route-params))]
+        (-> (ch/promise (fn [resolve] (handler context #(resolve %))))
+            (ch/then #(handle-response % context)))))))
+
+(defn build-request
+  [^Request request]
+   (let [local-address (.getLocalAddress request)
+         remote-address (.getRemoteAddress request)
+         body (Blocking/on (.getBody request))]
+     {:server-port (.getPort local-address)
+      :server-name (.getHostText local-address)
+      :remote-addr (.getHostText remote-address)
+      :uri (str "/" (.getPath request))
+      :query-string (.getQuery request)
+      :scheme :http
+      :request-method (keyword (.. request getMethod getName toLowerCase))
+      :headers (get-headers* request)
+      :content-type (.. body getContentType getType)
+      :content-length (Integer/parseInt (.. request getHeaders (get "Content-Length")))
+      :character-encoding (.. body getContentType (getCharset "utf-8"))
+      :body (.. body getInputStream)}))

 (defmethod adapter :catacumba/ring
   [handler]
   (reify Handler
     (^void handle [_ ^Context ctx]
       (let [context (ctx/context ctx)
-            request (build-request (:request context))
-            response (handler request)]
-        (when (satisfies? IHandlerResponse response)
-          (handle-response response context))))))
+            p (ch/blocking
+               (let [request (build-request (:request context))]
+                 (handler request)))]
+        (ch/then p (fn [response]
+                     (when (satisfies? IHandlerResponse response)
+                       (handle-response response context))))))))


making the indexing fn available so we can run it from the repl

--- src/com/ig/swagger/search/collector.clj
+++ src/com/ig/swagger/search/collector.clj
@@ -16,6 +16,8 @@
    :index-data                  [{:path            "/search"
                                   :spec-path       "http://ip1/a-tomcat-service/api-docs" ;; swagger-doc-url
                                   :swagger-version "1.2"
+                                  :service-name    "SwaggerSearch"
+                                  :service-version "0.0.1"
                                   :summary         "Search for API"
                                   :method          "GET"
                                   :ui-api-path     "http://ip1/a-tomcat-service/swagger/index.html#!/abc/operationSearch"
@@ -142,6 +144,7 @@
     {:json-client       json-client
      :http-client       http-client
      :initial-load-task (future (run-indexing))
+     :index-fn          run-indexing
      :scheduled-task    (schedule/schedule                  ;; TODO: make schedule configurable
                           {:minute (range 0 60 5)} run-indexing)}))


Update bukkit.clj

Update bukkit.clj

Fix repeated task api.

--- src/bukkure/bukkit.clj
+++ src/bukkure/bukkit.clj
@@ -53,8 +53,8 @@
   "Execute a given function repeatedly on the UI thread, delay and period in server ticks. If you specify async?, take care not to directly call any Bukkit API and, by extension, and clj-minecraft functions that use the Bukkit API within this function"
   [plugin fn delay period & [async?]]
   (if async?
-    (.runTaskTimerAsynchronously (scheduler) fn (long delay) (long period))
-    (.runTaskTimer (scheduler) fn (long delay) (long period))))
+    (.runTaskTimerAsynchronously (scheduler) plugin fn (long delay) (long period))
+    (.runTaskTimer (scheduler) plugin fn (long delay) (long period))))

 (defn cancel-task
   [task-id]
@@ -66,4 +66,4 @@

 (defn queued-task?
   [task-id]
-  (.isQueued (scheduler) task-id))+  (.isQueued (scheduler) task-id))


Smaller fake data.

Smaller fake data.


Playing with merged event / snapshot timeline.

--- src/cbfg/world/t1.cljs
+++ src/cbfg/world/t1.cljs
@@ -11,7 +11,22 @@
    {:text "hello"
     :controls ["play" "step" "pause"]
     :speed 1.0
-    :events [1 2 3 4]
+    :snapshots {0 {}
+                10 {:a 1 :b 2 :c 3 :d 4}
+                20 {:a 11 :b 22 :c 33 :d 44}}
+    :events [[0 :snapshot]
+             [1 :event [:a 1]]
+             [2 :event [:b 2]]
+             [3 :event [:c 3]]
+             [4 :event [:d 4]]
+             [10 :snapshot]
+             [11 :event [:a 11]]
+             [12 :event [:b 22]]
+             [13 :event [:c 33]]
+             [14 :event [:d 44]]
+             [20 :snapshot]
+             [21 :event [:a 11]]
+             [22 :event [:b 22]]]
     :world {:a 11 :b 22 :c 33}
     :hover nil}))

@@ -35,6 +50,11 @@
          (map (fn [[k v]] (dom/li nil (str k ":" v)))
               (:world app))))

+(defn render-snapshot [app owner ss-ts]
+  (apply dom/ul nil
+         (map (fn [[k v]] (dom/li nil (str k "=" v)))
+              (get-in app [:snapshots ss-ts] nil))))
+
 (defn init-roots [app-state]
   (om/root
    (fn [app owner]
@@ -43,13 +63,20 @@
                  (:controls app))))
    app-state
    {:target (. js/document (getElementById "controls"))})
+
   (om/root
    (fn [app owner]
      (apply dom/ul nil
-            (map (fn [x] (dom/li nil x))
+            (map (fn [[ts kind & rest]]
+                   (dom/li nil
+                           (str ts)
+                           (str kind)
+                           (when (= kind :snapshot)
+                             (render-snapshot app owner ts))))
                  (:events app))))
    app-state
    {:target (. js/document (getElementById "events"))})
+
   (om/root render-world app-state
            {:target (. js/document (getElementById "world"))})
   (om/root render-world app-state


Better head merging

Better head merging

--- src/clj_crud/todos.clj
+++ src/clj_crud/todos.clj
@@ -14,7 +14,7 @@
 (defn todos-page-layout [ctx]
   (c/emit-application
    ctx
-   [:head] (html/after (html/select todos-page-html [:head]))
+   [:head html/last-child] (html/after (html/select todos-page-html [:head html/first-child]))
    [:#content] (html/substitute (html/select todos-page-html [:#content]))))

 (defresource todos-page


Remove fully-qualified names of Java classes

--- src/cljakstab/core.clj
+++ src/cljakstab/core.clj
@@ -2,43 +2,46 @@
   (:import (org.jakstab Main Options Program AnalysisManager)
            (org.jakstab.ssl Architecture)
            (org.jakstab.loader DefaultHarness)
-           (org.jakstab.analysis ControlFlowReconstruction)))
+           (org.jakstab.analysis ControlFlowReconstruction)
+           java.security.Permission
+           java.io.File))

 (defn init-options
   "Jakstab stores options in singleton Options class"
   [opts]
-  (set! org.jakstab.Options/mainFilename (:mainFile opts))
-  (org.jakstab.AnalysisManager/getInstance))
+  (set! Options/mainFilename (:mainFile opts))
+  (AnalysisManager/getInstance))

 (defn security-manager-proxy []
   (proxy
-      [java.lang.SecurityManager] []
+      [SecurityManager] []
     (checkPermission [perm]
-      (if (not (= "setSecurityManager" (.getName ^java.security.Permission perm)))
+      (if (not (= "setSecurityManager" (.getName ^Permission perm)))
         nil))
     (checkExit [code]
       (throw
-       (java.lang.SecurityException.
+       (SecurityException.
         (str "catched exit with code " code))))))

 (defmacro disable-system-exit [& exprs]
-  `(let [old-mgr# (java.lang.System/getSecurityManager)
+  `(let [old-mgr# (System/getSecurityManager)
          new-mgr# (security-manager-proxy)]
      (try
        (do
-         (java.lang.System/setSecurityManager new-mgr#)
+         (System/setSecurityManager new-mgr#)
          ~@exprs)
-       (finally (java.lang.System/setSecurityManager old-mgr#)))))
+       (finally (System/setSecurityManager old-mgr#)))))

 (defn find-jumps
   "find unresolved jumps in specified binary"
   [binary-file]
   (init-options {:mainFile binary-file})
   (disable-system-exit
-   (let [arch (org.jakstab.ssl.Architecture. (.getValue org.jakstab.Options/sslFilename))
-         program (org.jakstab.Program/createProgram arch)
-         file (.getAbsoluteFile (java.io.File. binary-file))]
+   (let [arch (Architecture. (.getValue Options/sslFilename))
+         program (Program/createProgram arch)
+         file (.getAbsoluteFile (File. binary-file))]
      (.loadMainModule program file)
-     (.installHarness program (org.jakstab.loader.DefaultHarness.))
-     (let [cfr (org.jakstab.analysis.ControlFlowReconstruction. program)]
-       (.run cfr)))))
+     (.installHarness program (DefaultHarness.))
+     (let [cfr (ControlFlowReconstruction. program)]
+       (.run cfr)
+       cfr))))


CMR-2481: Updated migration to handle tombstones correctly

--- metadata-db-app/src/migrations/033_replace_tags_namespace_and_value_with_tag_key.clj
+++ metadata-db-app/src/migrations/033_replace_tags_namespace_and_value_with_tag_key.clj
@@ -18,7 +18,7 @@
   (println "migrations.033-replace-tags-namespace-and-value-with-tag-key up...")
   (doseq [result (h/query "SELECT * from cmr_tags")]
     (print-message result)
-    (let [{:keys [id metadata]} result
+    (let [{:keys [id metadata deleted native_id]} result
           metadata (-> metadata
                        (util/gzip-blob->string)
                        (edn/read-string))
@@ -26,13 +26,22 @@
           {:keys [namespace value tag-key]} metadata
           tag-key (or tag-key
                       (str/lower-case (str namespace "." value)))
+          ;; Tombstones don't have metadata so the best we can do is replace the char 29 with a
+          ;; dot.
+          native-id (if deleted
+                      (str/replace native_id (str (char 29)) ".")
+                      tag-key)
+          metadata (if deleted
+                     metadata
+                     (-> metadata
+                      (assoc :tag-key tag-key)
+                      (dissoc :namespace :value :category)))
           metadata (-> metadata
-                       (assoc :tag-key tag-key)
-                       (dissoc :namespace :value :category)
                        pr-str
                        util/string->gzip-bytes)
-          result (assoc result :metadata metadata :native_id tag-key)]
+          result (assoc result :metadata metadata :native_id native-id)]
       (j/update! (config/db) "cmr_tags" result ["id = ?" id]))))
+

 (defn down
   "Migrates the database down from version 33."
@@ -41,20 +50,23 @@
   (println "NOTE: category field and original native-id cannot be recovered")
   (doseq [result (h/query "SELECT * from cmr_tags")]
     (print-message result)
-    (let [{:keys [id metadata]} result
-          metadata (-> metadata
-                       (util/gzip-blob->string)
-                       (edn/read-string))
-          tag-key (:tag-key metadata)
-          ;; There is no way to properly recover a namespace and value that have a
-          ;; "." in the value.
-          [_ namespace value] (re-matches #"(.*)\.(.*$)" tag-key)
-          native-id (str namespace (char 29) value)
-          metadata (-> metadata
-                       (assoc :namespace namespace
-                              :value value)
-                       (dissoc :tag-key)
-                       pr-str
-                       util/string->gzip-bytes)
-          result (assoc result :metadata metadata :native_id native-id)]
+    (let [{:keys [id metadata deleted native_id]} result
+          result (if deleted
+                   ;; Just replace the . at the end of the native id with a group separator.
+                  (let [native-id (str/replace native_id #"\.(.*?$)" (str (char 29) "$1"))]
+                    (assoc result :native_id native-id))
+                  ;; There is no way to properly recover a namespace and value that have a
+                  ;; "." in the value.
+                  (let [metadata (-> metadata
+                                     util/gzip-blob->string
+                                     edn/read-string)
+                        tag-key (:tag-key metadata)
+                        [_ namespace value] (re-matches #"(.*)\.(.*$)" tag-key)
+                        native-id (str namespace (char 29) value)
+                        metadata (-> metadata
+                                     (assoc :namespace namespace :value value)
+                                     (dissoc :tag-key)
+                                     pr-str
+                                     util/string->gzip-bytes)]
+                     (assoc result :metadata metadata :native_id native-id)))]
       (j/update! (config/db) "cmr_tags" result ["id = ?" id]))))


Add more schema validation to api

Add more schema validation to api

--- src/onyx/api.clj
+++ src/onyx/api.clj
@@ -177,6 +177,7 @@
   ([peer-config job-id]
      (kill-job peer-config job-id {:monitoring :no-op}))
   ([peer-config job-id monitoring-config]
+     (validator/validate-peer-config peer-config)
      (when (nil? job-id)
        (throw (ex-info "Invalid job id" {:job-id job-id})))
      (let [client (component/start (system/onyx-client peer-config monitoring-config))
@@ -196,6 +197,7 @@
   ([peer-config ch]
      (subscribe-to-log peer-config ch {:monitoring :no-op}))
   ([peer-config ch monitoring-config]
+     (validator/validate-peer-config peer-config)
      (let [env (component/start (system/onyx-client peer-config monitoring-config))]
        {:replica (extensions/subscribe-to-log (:log env) ch)
         :env env})))
@@ -210,6 +212,7 @@
   ([peer-config]
    (gc peer-config {:monitoring :no-op}))
   ([peer-config monitoring-config]
+   (validator/validate-peer-config peer-config)
    (let [id (java.util.UUID/randomUUID)
            client (component/start (system/onyx-client peer-config monitoring-config))
            entry (create-log-entry :gc {:id id})
@@ -232,6 +235,7 @@
   ([peer-config job-id]
      (await-job-completion peer-config job-id {:monitoring-config {:monitoring :no-op}}))
   ([peer-config job-id {:keys [monitoring-config timeout-ms]}]
+   (validator/validate-peer-config peer-config)
    (let [job-id (validator/coerce-uuid job-id)
          client (component/start (system/onyx-client peer-config monitoring-config))
          ch (chan 100)


Add more detail to the music tutorial.

Add more detail to the music tutorial.

--- src/klangmeister/ui/music_tutorial.cljs
+++ src/klangmeister/ui/music_tutorial.cljs
@@ -13,7 +13,7 @@
     "(phrase [3/3 3/3 2/3 1/3 3/3] ; You can change both the durations and the pitches.
         [ 72  72  72  74  76])"]
    :then
-   ["We can chain together two melodies to make a longer one."
+   ["We can combine two melodies to make a longer one."
     "(->>
   (phrase [3/3 3/3 2/3 1/3 3/3] ; Can you recognise the tune yet?
           [ 72  72  72  74  76])
@@ -21,8 +21,9 @@
     (phrase [2/3 1/3 2/3 1/3 3/3]
             [ 76  74  76  77  79])))"]
    :with
-   ["Alternatively, we can play two melodies at the same time. If they're well-chosen, we'll get harmony."
-   "(->>
+   ["Alternatively, we can play two melodies at the same time. If they're well-chosen, we'll get harmony. If not, we might
+    still get something interesting."
+   "(->> ; The arrow combines melodies like connect-> combines synthesiser nodes.
   (phrase [3/3 3/3 2/3 1/3 3/3]
           [ 72  72  72  74  76])
   (with
@@ -36,10 +37,11 @@
   (with
     (phrase [2/3 1/3 2/3 1/3 3/3]
             [ 76  74  76  77  79]))
-  (times 2))"]
+  (times 2)) ; What happens if the times is put before the with? Why?"]
    :bpm
-   ["So far every unit of time has been a second. If we want to speed up or slow down the music, we can define how many
-    beats-per-minute there are."
+   ["So far every unit of time has been a second, in other words 60 beats per minute.
+    If we want to speed up or slow down the music, we can define how many beats-per-minute there are. We use 'tempo' to
+    update the time and duration of each note according to the chosen 'bpm'."
     "(->>
   (phrase [3/3 3/3 2/3 1/3 3/3]
           [ 72  72  72  74  76])
@@ -49,7 +51,7 @@
   (times 2)
   (tempo (bpm 90))) ; Try making the music faster or slower."]
    :key
-   ["We have to be careful which pitches we choose. A given piece of music focuses on certain pitches and ignores others. For example, 72 and 74 are in C major, but 73 is not. A convenient way to write songs in-key is to number the notes within the key and then later use code to translate those numbers into specific pitches. Here we use the where function to put each note in C major."
+   ["We have to be careful which pitches we choose if we want the result to sound musical. A given piece of music focuses on certain pitches and ignores others, determined by the key of the piece. For example, 72 and 74 are in C major, but 73 is not. A convenient way to write songs in-key is to number the notes within the key and then later use code to translate those numbers into specific pitches. Here we use 'where' to put each note in C major."
     "(->>
   (phrase [3/3 3/3 2/3 1/3 3/3]
           [  0   0   0   1   2])


Fix error in XML rendering pipeline

Fix error in XML rendering pipeline

--- src/main/clojure/cascade/dispatcher.clj
+++ src/main/clojure/cascade/dispatcher.clj
@@ -109,7 +109,7 @@
     (debug "Streaming XML response")
     (.setContentType response "text/html")
     (with-open [writer (.getWriter response)]
-      (.write out "<?xml version=\"1.0\"?>\n")
+      (.write writer "<?xml version=\"1.0\"?>\n")
       (render-xml prepared writer)))
   true)


Rename empty cats.monad namespace.

Rename empty cats.monad namespace.

--- src/cats/monad.cljc
+++ src/cats/monad.cljc
@@ -1,26 +0,0 @@
-;; Copyright (c) 2014, Andrey Antukh
-;; Copyright (c) 2014, Alejandro Gómez
-;; All rights reserved.
-;;
-;; Redistribution and use in source and binary forms, with or without
-;; modification, are permitted provided that the following conditions
-;; are met:
-;;
-;; 1. Redistributions of source code must retain the above copyright
-;;    notice, this list of conditions and the following disclaimer.
-;; 2. Redistributions in binary form must reproduce the above copyright
-;;    notice, this list of conditions and the following disclaimer in the
-;;    documentation and/or other materials provided with the distribution.
-;;
-;; THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
-;; IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
-;; OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
-;; IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
-;; INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
-;; NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-;; DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-;; THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-;; (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
-;; THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-(ns cats.monad)


GAWB-2189: taking out logging messages

GAWB-2189: taking out logging messages

--- src/cljs/main/broadfcui/page/workspace/method_configs/method_config_editor.cljs
+++ src/cljs/main/broadfcui/page/workspace/method_configs/method_config_editor.cljs
@@ -45,7 +45,6 @@
      (react/call :load-agora-method this props state))
    :load-agora-method
    (fn [{:keys [state]} method-ref]
-     (utils/log "get-agora-method " method-ref)
      (endpoints/call-ajax-orch
       {:endpoint (endpoints/get-agora-method (:namespace method-ref) (:name method-ref) (:snapshotId method-ref))
        :headers utils/content-type=json
@@ -169,7 +168,7 @@
                  [comps/SidebarButton {:color :exception-state :margin :top
                                        :text "Cancel Editing" :icon :cancel
                                        :onClick (fn []
-                                                  (this :load-new-method-template (utils/log (:prev-snapshot-id @state)))
+                                                  (this :load-new-method-template (:prev-snapshot-id @state))
                                                   (swap! state assoc :editing? false))}]))]))]))
    :-render-main
    (fn [{:keys [state this]}]
@@ -268,25 +267,24 @@
                      (swap! state dissoc :blocker :editing?)
                      (if success?
                        (do ((:on-rename props) name)
-                           (swap! state assoc :loaded-config (get-parsed-response) :blocker nil)
-                           (utils/log))
+                           (swap! state assoc :loaded-config (get-parsed-response) :blocker nil))
                        (comps/push-error-response (get-parsed-response false))))})))
    :load-validated-method-config
    (fn [{:keys [state props]}]
      (endpoints/call-ajax-orch
-       {:endpoint (endpoints/get-validated-workspace-method-config (:workspace-id props) (:config-id props))
-        :on-done (fn [{:keys [success? get-parsed-response status-text]}]
-                   (if success?
-                     (let [response (get-parsed-response)]
-                       (endpoints/call-ajax-orch
-                         {:endpoint endpoints/get-inputs-outputs
-                          :payload (get-in response [:methodConfiguration :methodRepoMethod])
-                          :headers utils/content-type=json
-                          :on-done (fn [{:keys [success? get-parsed-response]}]
-                                     (if success?
-                                       (swap! state assoc :loaded-config (utils/log response) :inputs-outputs (get-parsed-response))
-                                       (swap! state assoc :error (:message (get-parsed-response)))))}))
-                     (swap! state assoc :error status-text)))}))
+      {:endpoint (endpoints/get-validated-workspace-method-config (:workspace-id props) (:config-id props))
+       :on-done (fn [{:keys [success? get-parsed-response status-text]}]
+                  (if success?
+                    (let [response (get-parsed-response)]
+                      (endpoints/call-ajax-orch
+                       {:endpoint endpoints/get-inputs-outputs
+                        :payload (get-in response [:methodConfiguration :methodRepoMethod])
+                        :headers utils/content-type=json
+                        :on-done (fn [{:keys [success? get-parsed-response]}]
+                                   (if success?
+                                     (swap! state assoc :loaded-config response :inputs-outputs (get-parsed-response))
+                                     (swap! state assoc :error (:message (get-parsed-response)))))}))
+                    (swap! state assoc :error status-text)))}))
    :load-new-method-template
    (fn [{:keys [state refs props]} new-snapshot-id]
      (let [[method-namespace method-name] (map (fn [key]
@@ -299,8 +297,6 @@
                        :methodName method-name
                        :methodVersion new-snapshot-id}]
        (swap! state assoc :blocker "Updating...")
-       (utils/log "METHOD REF")
-       (utils/log method-ref)
        (react/call :load-agora-method (@refs "methodDetailsViewer") {:namespace method-namespace
                                                           :name method-name
                                                           :snapshotId new-snapshot-id})
@@ -325,7 +321,6 @@
                                                          (let [template {:methodConfiguration (merge valid-response config-namespace+name)}]
                                                            (if success?
                                                                (swap! state assoc
-                                                                      ;:loaded-config (utils/log (merge template (dissoc valid-response :methodConfiguration)))
                                                                       :loaded-config valid-response
                                                                       :inputs-outputs (get-parsed-response)))
                                                              (swap! state assoc :error (:message (get-parsed-response)))))})


bug fix

bug fix

--- src/cljs/org/broadinstitute/firecloud_ui/page/workspace/method_configs/tab.cljs
+++ src/cljs/org/broadinstitute/firecloud_ui/page/workspace/method_configs/tab.cljs
@@ -41,7 +41,7 @@
                       [MethodConfigImporter {:workspace-id (:workspace-id props)
                                              :after-import (fn [config]
                                                              (swap! state dissoc :show-import-overlay?)
-                                                             ((:on-config-imported props) config))}]])}])
+                                                             ((:on-config-imported props) (config->id config)))}]])}])
       (let [server-response (:server-response @state)
             {:keys [configs error-message]} server-response]
         (cond


added win state to modal

added win state to modal

--- src/cellf/core.cljs
+++ src/cellf/core.cljs
@@ -218,48 +218,55 @@
                 :vid-offset  (* 100 (/ (max 1 (.abs js/Math (- vw vh))) (max 1 (* vw 2))))
                 :canvas-node canvas
                 :ctx         (.getContext canvas "2d")
-                :show-about  true})
+                :show-about?  true})
               (js/setTimeout start! 500))))
           (aset "src" data)))
       (swap! app-state assoc :media-error? true)))))

-(defn modal [{:keys [stream media-error? show-about] :as app}]
-  (apply dom/div #js {
-    :className (str "modal" (when (or (not stream) media-error? show-about) " active"))}
-    (dom/h1 nil "Cellf")
-    (cond
-      media-error?
-        (dom/p nil
-          "Sorry, Cellf doesn't work without camera access."
-          (dom/button #js {:onClick get-camera!} "try again"))
-
-      (not stream)
-        (dom/p nil
-          (str
-            "Cellf is an interactive experiment that puts a twist on the classic "
-            "sliding puzzle game. Click OK to prompt for camera access.")
-          (dom/button #js {:onClick get-camera!} "ok"))
-
-      show-about
-        [
+(defn modal [{:keys [stream media-error? show-about? cells win-state grid-size] :as app}]
+  (let [winner?    (= cells win-state)
+        no-stream? (not stream)]
+    (dom/div #js {
+      :className (str "modal" (when (or no-stream? media-error? show-about? winner?) " active"))}
+      (dom/h1 nil "Cellf")
+      (cond
+        media-error?
+          (dom/p nil
+            "Sorry, Cellf doesn't work without camera access."
+            (dom/button #js {:onClick get-camera!} "try again"))
+
+        no-stream?
           (dom/p nil
             (str
-              "Simply click a square next to the empty space to move it. "
-              "When you shuffle them into the correct order, you win."))
+              "Cellf is an interactive experiment that puts a twist on the classic "
+              "sliding puzzle game. Click OK to prompt for camera access.")
+            (dom/button #js {:onClick get-camera!} "ok"))
+
+        winner?
           (dom/p nil
-            (str
-              "You can also export a replay of your moves to an animated gif. "
-              "Cellf is ")
-            (dom/a #js {:href "https://github.com/dmotz/cellf"} "open source")
-            ". For more experiments like this, visit "
-            (dom/a #js {:href "http://oxism.com"} "oxism.com")
-            \.
-            (dom/button #js {:onClick #(om/update! app [:show-about] false)} "got it"))])))
+            "You win!"
+            (dom/button #js {:onClick #(set-grid-size! app grid-size)} "new game"))
+
+        show-about?
+          (dom/div nil
+            (dom/p nil
+              (str
+                "Simply click a square next to the empty space to move it. "
+                "When you shuffle them into the correct order, you win."))
+            (dom/p nil
+              (str
+                "You can also export a replay of your moves to an animated gif. "
+                "Cellf is ")
+              (dom/a #js {:href "https://github.com/dmotz/cellf"} "open source")
+              ". For more experiments like this, visit "
+              (dom/a #js {:href "http://oxism.com"} "oxism.com")
+              \.
+              (dom/button #js {:onClick #(om/update! app [:show-about?] false)} "got it")))))))

 (om/root
-  (fn [{:keys [stream cells win-state moves tick tick-ms grid-size show-nums] :as app} owner]
+  (fn [{:keys [stream moves tick tick-ms grid-size show-nums] :as app} owner]
     (reify
       om/IDidMount
       (did-mount [_]
@@ -295,9 +302,6 @@

               (when stream
                 (dom/div nil
-                  (when (= cells win-state)
-                    (dom/h1 nil "You win!"))
-
                   (dom/label
                     #js {:className "move-count"}
                     (str (inc tick) \/ move-count))


fix bug

fix bug

--- src/clj/jsk/job.clj
+++ src/clj/jsk/job.clj
@@ -88,8 +88,8 @@

 (defn- create-triggers [job-id]
   (info "Creating triggers for job " job-id)
-  (let [schedules (get-job-schedule-info job-id)]
-    (q/schedule-cron-job! job-id ju/job-type-id schedules)))
+  (doseq [{:keys[node-schedule-id cron-expression]} (get-job-schedule-info job-id)]
+    (q/schedule-cron-job! node-schedule-id job-id ju/job-type-id cron-expression)))

 ;-----------------------------------------------------------------------
 ; Associates a job to a set of schedule-ids.


Remove old code that provided back-compat for CLJS 1.9.542

--- src/expound/alpha.cljc
+++ src/expound/alpha.cljc
@@ -945,16 +945,7 @@
   ([spec form]
    (expound-str spec form {}))
   ([spec form opts]
-   ;; expound was initially released with support
-   ;; for CLJS 1.9.542 which did not include
-   ;; the value in the explain data, so we patch it
-   ;; in to avoid breaking back compat (at least for now)
-   (let [explain-data (s/explain-data spec form)]
-     (printer-str opts
-                  (if explain-data
-                    (assoc explain-data
-                           ::s/value form)
-                    nil)))))
+   (printer-str opts (s/explain-data spec form))))

 (s/fdef expound
   :args (s/cat :spec :expound.spec/spec
@@ -1030,3 +1021,5 @@
   "Given a sequence of results from `clojure.spec.test.alpha/check`, returns a string summarizing the results."
   [check-results]
   (with-out-str (explain-results check-results)))
+
+(def install! [])


minor updates

minor updates

--- kafka-clj/src/kafka_clj/consumer.clj
+++ kafka-clj/src/kafka_clj/consumer.clj
@@ -117,7 +117,7 @@

     {:ch ch :p-close #(close! ch) :p-send #(>!! ch %)}))

-(defn send-request-and-wait [producer group-conn topic-offsets msg-ch {:keys [fetch-timeout] :or {fetch-timeout 10000} :as conf}]
+(defn send-request-and-wait [producer group-conn topic-offsets msg-ch {:keys [fetch-timeout] :or {fetch-timeout 30000} :as conf}]
   "Returns [the messages, and fetch errors], if any error was or timeout was detected the function returns otherwise it waits for a FetchEnd message
    and returns.
   "
@@ -160,7 +160,7 @@
 		        (do
                 (p-close)
                 (close-client (:client producer));we close to force a reconnect
-                (error "Timeout while requesting data from " producer " for topics " (keys topic-offsets)) [(vals resp) fetch-errors]))))))
+                (error "Timeout while requesting data from " producer " for topics " topic-offsets) [(vals resp) fetch-errors]))))))

 (defn consume-broker [producer group-conn topic-offsets msg-ch conf]


name correctly reflects the impl

name correctly reflects the impl

--- src/crawler/dom.clj
+++ src/crawler/dom.clj
@@ -437,7 +437,7 @@
         {}
         xpaths-nodes-paths))))

-(defn xpaths-hrefs-tokens
+(defn xpaths-hrefs-tokens-with-position
   "Utilize an initial class-based grouping.
    Then add position information in the XPath to
    achieve a finer grouping."


added position information

added position information

--- src/crawler/dom.clj
+++ src/crawler/dom.clj
@@ -130,6 +130,37 @@
            (.getValue))
        (catch Exception e nil)))

+(defn child-position
+  [parent a-w3c-node]
+  (let [child-node-list (.getChildNodes parent)
+        child-nodes-cnt (.getLength child-node-list)]
+    (.indexOf
+     (map
+      #(.isSameNode
+        a-w3c-node
+        (.item child-node-list %))
+      (range child-nodes-cnt))
+     true)))
+
+(defn is-first-child?
+  [a-w3c-node]
+  (let [parent (.getParentNode a-w3c-node)]
+    (and parent
+         (= 0 (child-position
+               parent a-w3c-node)))))
+
+(defn is-last-child?
+  [a-w3c-node]
+  (let [parent (.getParentNode a-w3c-node)]
+    (and parent
+         (=
+          (-
+           (.getLength
+            (.getChildNodes parent))
+           1)
+          (child-position
+           parent a-w3c-node)))))
+
 (defn tag-id-class-node
   "Returns a list containing a tag's name, its id
 - formatted slightly - and its classes - formatted slightly"
@@ -140,25 +171,34 @@
         silent-fail-attr  (fn [attr key] (try (.getValue
                                               (.getNamedItem attr key))
                                              (catch Exception e nil)))
+

-        attributes        (.getAttributes a-w3c-node)]
-
-    (list (.getNodeName a-w3c-node)
+        attributes        (.getAttributes a-w3c-node)
+
+        is-first?         (is-first-child? a-w3c-node)
+
+        is-last?          (is-last-child? a-w3c-node)]
+
+    (list (.getNodeName a-w3c-node)               ; name
           (-> attributes
               (silent-fail-attr "id")
-              format-attr)
+              format-attr)                        ; id
           (map
            format-attr
            (-> attributes
                (silent-fail-attr "class")
-               (silent-fail-split #"\s+"))))))
+               (silent-fail-split #"\s+")))       ; class
+
+          is-first?
+
+          is-last?)))

 (defn tag-id-class->xpath
   "Args:
     a-tag-id-class : a tag, its id and a list of classes
    Returns:
     a component that fits in an xpath"
-  [[tag id class-list]]
+  [[tag id class-list is-first? is-last?]]
   (let [formatted-id      (format "contains(@id,'%s')" id)
         formatted-classes (map
                            #(format "contains(@class,'%s')" %)
@@ -166,8 +206,24 @@

     (if (not (empty? class-list))
-      (map #(format "%s[%s]" tag %) formatted-classes)
-      (list tag))))
+      (map #(cond (and (not is-first?)
+                       (not is-last?))
+                  (format "%s[%s]" tag %)
+
+                  is-first?
+                  (format "%s[%s][1]" tag %)
+
+                  is-last?
+                  (format "%s[%s][last()]" tag %)) formatted-classes)
+      (cond (and (not is-first?)
+                 (not is-last?))
+            (list tag)
+
+            is-first?
+            (list (format "%s[1]" tag))
+
+            is-last?
+            (list (format "%s[last()]" tag))))))

 (defn tag-node->xpath
   [a-tagnode]


Return ragam-name of kriti with kriti endpoint.

--- src/kosha/db/kriti.clj
+++ src/kosha/db/kriti.clj
@@ -4,9 +4,10 @@
 (defn kriti
   "Retrieve details of a kriti given it's kriti_id."
   [kriti-id]
-  (let [q ["SELECT kriti_id, name, composer, taala, url, lyrics, meaning, ragam_id, data_source
-            FROM kritis
-            WHERE kriti_id = ?; "
+  (let [q ["SELECT k.kriti_id, k.name, k.composer, k.taala, k.url, k.lyrics, k.meaning, k.ragam_id, k.data_source, r.name AS ragam_name
+            FROM kritis k
+            JOIN ragams r
+            ON k.kriti_id = ? AND r.ragam_id = k.ragam_id; "
            kriti-id]]
     (first (db-util/run-query q))))


Fix issue #63. Catch and warn on project read exceptions.

--- src/leiningen/voom.clj
+++ src/leiningen/voom.clj
@@ -303,10 +303,16 @@
                                (:err data)))
                  (throw e)))))))))

+(defn safe-project-read [p]
+  (try (project/read p)
+       (catch Exception e
+         (println "Found and skipped bad project at: " p)
+         nil)))
+
 (defn find-project
   [pgroup pname candidate]
   (for [p (find-project-files candidate)
-        :let [{:keys [group name] :as prj} (project/read p)]
+        :let [{:keys [group name] :as prj} (safe-project-read p)]
         :when (and (= group pgroup)
                    (= name pname))]
     prj))


CMR-3193: Fix case where facets being removed cause science keywords children to be empty

--- search-app/src/cmr/search/services/query_execution/facets/hierarchical_v2_facets.clj
+++ search-app/src/cmr/search/services/query_execution/facets/hierarchical_v2_facets.clj
@@ -236,11 +236,13 @@
   "V2 facets only include science keyword facets which have a category of Earth Science. Removes
   any facets which have any other category if the field is :science-keywords."
   [hierarchical-facet field]
-  (if (and (= :science-keywords-h field) (:children hierarchical-facet))
-      (update hierarchical-facet :children
-              (fn [children]
-                (filter #(= "Earth Science" (:title %)) children)))
-      hierarchical-facet))
+  (if (= :science-keywords-h field)
+    (let [updated-facet (update hierarchical-facet :children
+                                (fn [children]
+                                  (filter #(= "Earth Science" (:title %)) children)))]
+      (when (seq (:children updated-facet))
+        updated-facet))
+    hierarchical-facet))

 (defn- hierarchical-bucket-map->facets-v2
   "Takes a map of elastic aggregation results for a nested field. Returns a hierarchical facet for
@@ -256,10 +258,10 @@
         facets-with-zero-matches (create-facets-with-zero-matches base-url query-params field
                                                                   subfield-term-tuples)]
     (if (seq facets-with-zero-matches)
-        ;; Add in links to remove any hierarchical fields that have been applied to the query-params
-        ;; but do not have any matching collections.
-        (update hierarchical-facet :children #(concat % facets-with-zero-matches))
-        hierarchical-facet)))
+      ;; Add in links to remove any hierarchical fields that have been applied to the query-params
+      ;; but do not have any matching collections.
+      (update hierarchical-facet :children #(concat % facets-with-zero-matches))
+      hierarchical-facet)))

 (defn create-hierarchical-v2-facets
   "Parses the elastic aggregations and generates the v2 facets for all hierarchical fields."


fixed order dependencies

fixed order dependencies

--- src/jasons_game/world.clj
+++ src/jasons_game/world.clj
@@ -1,12 +1,4 @@
 (ns jasons_game.world)
-
-;; World
-; The world is a map of object names to objects.
-(def world {})
-
-(defn populate-world []
-  (add-thing "Edwin" {:type :person
-                      :location [0 0 0]}))

 ;; Things
@@ -33,3 +25,12 @@
   [name location]
   (def world
     (assoc-in world [name :location] location)))
+
+
+;; World
+; The world is a map of object names to objects.
+(def world {})
+
+(defn populate-world []
+  (add-thing "Edwin" {:type :person
+                      :location [0 0 0]}))


Be more verbose about the JVM in lein version.

--- src/leiningen/version.clj
+++ src/leiningen/version.clj
@@ -2,4 +2,6 @@
   "Print Leiningen's version to standard out.")

 (defn version []
-  (println "Leiningen" (System/getProperty "leiningen.version")))
+  (println "Leiningen" (System/getProperty "leiningen.version")
+           "on Java" (System/getProperty "java.version")
+           (System/getProperty "java.vm.name")))


Fix type in variable

Fix type in variable

--- src/ruuvi_server/database/event_dao.clj
+++ src/ruuvi_server/database/event_dao.clj
@@ -124,7 +124,7 @@
                  (where {:id event_id})))
   )

-(def ^{:private true} cache-event-extension-type (cache/create-cache-region :event-extension-type 10000 (* 24 60 60 1000)))
+(def ^{:private true} cache-event-extra-data (cache/create-cache-region :event-extension-type 10000 (* 24 60 60 1000)))

 ;; TODO cache access to event-extension-type
 (defn- get-event-extra-data [event-id]


WIP - Evolution du bot CSB en Clojure avec l'objectif d'améliorer le classement en ligue argent

--- clojure/codingame/competition/coders-strike-back/src/coders_strike_back/core.clj
+++ clojure/codingame/competition/coders-strike-back/src/coders_strike_back/core.clj
@@ -43,8 +43,8 @@
     (>= (Math/abs next-checkpoint-angle) 90) "0"
     (> (Math/abs next-checkpoint-angle) 72) "20"
     (> (Math/abs next-checkpoint-angle) 54) "40"
-    (> (Math/abs next-checkpoint-angle) 36) "80"
-    (> (Math/abs next-checkpoint-angle) 18) "100"
+    (> (Math/abs next-checkpoint-angle) 36) "60"
+    (> (Math/abs next-checkpoint-angle) 18) "80"
     (<= (Math/abs next-checkpoint-angle) 18) "100"
     true "100"))


Check for the renderer

Check for the renderer

--- src/cljs/daveconservatoire/site/ui/vexflow.cljs
+++ src/cljs/daveconservatoire/site/ui/vexflow.cljs
@@ -72,7 +72,7 @@
   (componentDidMount [this]
     (go
       (require-vexflow)
-      (<! (wait-for (fn [] (gobj/get js/window "Vex"))))
+      (<! (wait-for (fn [] (gobj/getValueByKeys js/window #js ["Vex" "Flow" "Renderer"]))))
       (let [div (gobj/get this "el")]
         (render-score (om/props this) div))))


Drop fn sith-lords.pending-sith-lord-item

--- src/cljs/flux_challenge_reagent/sith_lords.cljs
+++ src/cljs/flux_challenge_reagent/sith_lords.cljs
@@ -21,12 +21,9 @@
 (defn sith-lords []
   (map :sith-lord @items))

-(defn- pending-sith-lord-item [id]
-  (if id {:id id} nil))
-
 (defn- assoc-pending-sith-lord [items index id]
-  (if (and (>= index 0) (< index (count items)) id (nil? (get items index)))
-    (assoc items index (pending-sith-lord-item id))
+  (if (and (>= index 0) (< index (count items)) (nil? (get-in items [index :id])))
+    (assoc items index {:id id})
     items))

 (defn- abort-request! [item]
@@ -67,12 +64,12 @@
   (case direction
     :up (let [first-sith-lord (-> items first :sith-lord)
               master-id (get-in first-sith-lord ["master" "id"])
-              master-item (pending-sith-lord-item master-id)]
+              master-item {:id master-id}]
           (abort-request! (peek items))
           (into [master-item] (pop items)))
     :down (let [last-sith-lord (-> items last :sith-lord)
                 apprentice-id (get-in last-sith-lord ["apprentice" "id"])
-                apprentice-item (pending-sith-lord-item apprentice-id)]
+                apprentice-item {:id apprentice-id}]
             (abort-request! (nth items 0))
             (conj (subvec items 1) apprentice-item))))


Revert "New QA branch"

Revert "New QA branch"

--- src/cljs/wombats_web_client/constants/urls.cljs
+++ src/cljs/wombats_web_client/constants/urls.cljs
@@ -1,7 +1,7 @@
 (ns wombats-web-client.constants.urls)

 ;; Remote Dev
-(def base-api-url "//qa.api.wombats.io")
+(def base-api-url "//dev.api.wombats.io")

 ;; Local Dev
 #_(def base-api-url "//localhost:8888")


add TODO

add TODO

--- src/main/om_css/core.cljc
+++ src/main/om_css/core.cljc
@@ -325,5 +325,6 @@
                (println (string/join "\n" (vals new-state)))
                (println))))))))

+;; TODO: Don't really want to be generating a CSS file on the server
 #?(:clj
    (setup-io!))


use insert-multi! for dummy data

use insert-multi! for dummy data

--- src/bk1/db.clj
+++ src/bk1/db.clj
@@ -34,11 +34,14 @@
                                               [:entity_id :integer "NOT NULL" "REFERENCES entities(id)"]])]))

 (defn add-dummy-data [db]
-  (sql/insert! db :entities {:id 1 :name "Entity One"})
-  (sql/insert! db :accounts {:id 1 :name "Test One" :entity_id 1})
-  (sql/insert! db :accounts {:id 2 :name "Test Two" :entity_id 1})
-  (sql/insert! db :transactions {:amount 42.95 :credit 2 :debit 1})
-  (sql/insert! db :transactions {:amount 12.34 :credit 2 :debit 1}))
+  (sql/insert-multi! db :entities
+                     [{:id 1 :name "Entity One"}])
+  (sql/insert-multi! db :accounts
+                     [{:id 1 :name "Test One" :entity_id 1}
+                      {:id 2 :name "Test Two" :entity_id 1}])
+  (sql/insert-multi! db :transactions
+                     [{:amount 42.95 :credit 2 :debit 1}
+                      {:amount 12.34 :credit 2 :debit 1}]))

 (defn run-and-record [db migration]
   (println "Running migration:" (:name (meta migration)))


start refactor of auto-complete to support engines

--- src/chat/client/views/new_message.cljs
+++ src/chat/client/views/new_message.cljs
@@ -13,6 +13,32 @@
             (-> (.toLowerCase s) (string/replace #"\s" "")))]
     (not= -1 (.indexOf (normalize s) (normalize m)))))

+
+; pattern - regex that will be tried
+; results - fn that returns results that will be shown if pattern matches
+;    inputs:
+;       query - is the partial text that was matched
+;       thread-id - id of the thread
+;    output:
+;       an array of maps, each containing:
+;         :html - html to be displayed for the result
+;         :action - fn to be triggered when result picked
+
+
+(def engines
+  [
+   {:pattern #"(?:.|\n)*#(\S*)"
+    :results (fn [query thread-id]
+               (when query
+                 (let [thread-tag-ids (-> (store/id->thread thread-id)
+                                          :tag-ids
+                                          set)]
+                   ; suggest tags
+                   (->> (store/all-tags)
+                        (remove (fn [t]
+                                  (contains? thread-tag-ids (t :id))))
+                        (filter (fn [t]
+                                  (fuzzy-matches? (t :name) query)))))))}])
 ; TODO: autocomplete mentions
 (defn new-message-view [config owner]
   (reify
@@ -33,11 +59,7 @@
                                :tag-ids
                                set)
             partial-tag (second (re-matches #"(?:.|\n)*#(\S*)" text))
-            results (->> (store/all-tags)
-                         (remove (fn [t]
-                                   (contains? thread-tag-ids (t :id))))
-                         (filter (fn [t]
-                                   (fuzzy-matches? (t :name) partial-tag))))
+            results ((get-in engines [0 :results]) partial-tag (config :thread-id))
             highlight-next!
             (fn []
               (om/update-state! owner :highlighted-result-index


fine grained logging about task startup

fine grained logging about task startup

--- src/clj/backtype/storm/daemon/task.clj
+++ src/clj/backtype/storm/daemon/task.clj
@@ -172,6 +172,7 @@
 (defn mk-task [conf storm-conf topology-context storm-id mq-context cluster-state storm-active-atom transfer-fn]
   (let [task-id (.getThisTaskId topology-context)
         component-id (.getThisComponentId topology-context)
+        _ (log-message "Loading task " component-id ":" task-id)
         task-info (.getTaskToComponent topology-context)
         active (atom true)
         uptime (uptime-computer)
@@ -282,6 +283,7 @@
                                       :kill-fn report-error-and-die))
         system-threads [heartbeat-thread]
         all-threads  (concat executor-threads system-threads)]
+    (log-message "Finished loading task " component-id ":" task-id)
     (reify
        Shutdownable
        (shutdown
@@ -323,6 +325,8 @@
 (defmethod mk-executors ISpout [^ISpout spout storm-conf puller send-fn storm-active-atom
                                 ^TopologyContext topology-context task-stats report-error-fn]
   (let [wait-fn (fn [] @storm-active-atom)
+        task-id (.getThisTaskId topology-context)
+        component-id (.getThisComponentId topology-context)
         max-spout-pending (storm-conf TOPOLOGY-MAX-SPOUT-PENDING)
         deserializer (TupleDeserializer. storm-conf topology-context)
         event-queue (ConcurrentLinkedQueue.)
@@ -335,8 +339,7 @@
                                   (.add event-queue #(fail-spout-msg spout storm-conf spout-id tuple time-delta task-stats)))
                                 )))
         send-spout-msg (fn [out-stream-id values message-id out-task-id]
-                         (let [task-id (.getThisTaskId topology-context)
-                               gen-id (MessageId/generateId)
+                         (let [gen-id (MessageId/generateId)
                                tuple-id (if message-id
                                           (MessageId/makeRootId gen-id)
                                           (MessageId/makeUnanchored))
@@ -369,7 +372,9 @@
                                                    ^List tuple ^Object message-id]
                                        (send-spout-msg stream-id tuple message-id out-task-id)
                                        ))]
+    (log-message "Opening spout " component-id ":" task-id)
     (.open spout storm-conf topology-context (SpoutOutputCollector. output-collector))
+    (log-message "Opened spout " component-id ":" task-id)
     [(fn []
        ;; This design requires that spouts be non-blocking
        (loop []
@@ -454,10 +459,12 @@
                           (^void reportError [this ^Throwable error]
                                  (report-error-fn error)
                                  ))]
+    (log-message "Preparing bolt " component-id ":" task-id)
     (.prepare bolt
               storm-conf
               topology-context
               (OutputCollectorImpl. topology-context output-collector))
+    (log-message "Prepared bolt " component-id ":" task-id)
     ;; TODO: can get any SubscribedState objects out of the context now
     [(fn []
        ;; synchronization needs to be done with a key provided by this bolt, otherwise:


Start implementing s-pankki bank statement handling by reading the file, removing utf-8 bom from it and transforming the csv to clojure data

--- src/clj/my_money/services/bank_csv.clj
+++ src/clj/my_money/services/bank_csv.clj
@@ -68,4 +68,7 @@
       csv->clj))

 (defmethod read-bank-statement :spankki [file]
-  (println ":spankki called"))
+  (-> file
+      slurp
+      (str/replace "\uFEFF" "")
+      csv->clj))


Hide up button when at the top level

Hide up button when at the top level

--- src/clojure/nightcode/file_browser.clj
+++ src/clojure/nightcode/file_browser.clj
@@ -94,7 +94,7 @@
                            (map create-tile)
                            (remove nil?)))
     (s/config! (s/select file-browser [:#up])
-               :enabled? (not (contains? @ui/tree-projects path)))))
+               :visible? (not (contains? @ui/tree-projects path)))))

 (add-watch ui/tree-selection
            :show-file-browser


adding feature group name

adding feature group name

--- src/clojure/zensols/nlparse/tok_re.clj
+++ src/clojure/zensols/nlparse/tok_re.clj
@@ -28,7 +28,8 @@
    :conj-regexp? true
    :is-regexp? false
    ;; :omit-single-stopword? true
-   :first-det-chop? true})
+   :first-det-chop? true
+   :feature-group-name "$0"})

 (defn item
   "Create an item used to create a pattern/line in the Stanford CoreNLP regular
@@ -161,7 +162,8 @@
                    (str/join ";")
                    (#(str "[{" % "}]")))))]
     (when-not (empty? word-regexes)
-      (let [pat (:pattern item)
+      (let [{pat :pattern} item
+            {:keys [feature-group-name]} item
             pats (if (:is-regexp? item)
                    (:content item)
                    (str/join " " (map fmt-pattern word-regexes)))
@@ -173,7 +175,7 @@
         (if (:id item)
           (print (format ",Annotate($0,zstriid,\"%s\")" (:id item))))
         (when (:features item)
-          (print ",Annotate($0,zstrfeat,\"")
+          (print (str ",Annotate(" feature-group-name ",zstrfeat,\""))
           (print (format-features (:features item)))
           (print "\")"))
         (print ")}")))))


CMR-273: Adding concept-id for searching granules to help verify they are deleted. Will test properly when the issue is taken.

--- src/cmr/search/services/parameters.clj
+++ src/cmr/search/services/parameters.clj
@@ -36,7 +36,8 @@
              :short_name :collection-query
              :version :collection-query
              :temporal :temporal
-             :project :string}})
+             :project :string
+             :concept-id :string}})

 (defn- param-name->type
   "Returns the query condition type based on the given concept-type and param-name."


Extended docstring for factorize-context

Signed-off-by: Daniel Borchmann <25857343a15bf1edafebc2912e82ecf775c585c1@mailbox.tu-dresden.de>

--- src/conexp/contrib/factor_analysis.clj
+++ src/conexp/contrib/factor_analysis.clj
@@ -16,7 +16,9 @@
 ;;; Interface

 (defmulti factorize-context
-  "Factorize context by given method."
+  "Factorize context by given method. Note that the method determines
+  whether the context is a formal context (as in the boolean case) or
+  a many-valued one (as in the fuzzy case)."
   {:arglists '([method context & args])}
   (fn [method context & _] method))


privatise web/authenticated?

privatise web/authenticated?

--- src/cu/web.clj
+++ src/cu/web.clj
@@ -21,7 +21,7 @@
 (def bucket (env :log-bucket))
 (def log-key (env :log-key))

-(defn authenticated? [username password]
+(defn- authenticated? [username password]
   (and (= username (env :cu-username))
        (= password (env :cu-password))))


CMR-2354 Adds test to ensure UMM JSON is returned unmodified

--- system-int-test/test/cmr/system_int_test/search/collection_concept_retrieval_test.clj
+++ system-int-test/test/cmr/system_int_test/search/collection_concept_retrieval_test.clj
@@ -160,6 +160,7 @@
                                              :accept "application/vnd.nasa.cmr.umm+json"})
           content-type (get-in response [:headers "Content-Type"])]
       (is (= 200 (:status response)))
+      (is (= json (:body response)))
       (is (= "application/vnd.nasa.cmr.umm+json" (mt/base-mime-type-of content-type)))
       (is (= "1.0" (mt/version-of content-type))))))


slightly better handling of meta data

slightly better handling of meta data

--- support/src/figwheel/client/file_reloading.cljs
+++ support/src/figwheel/client/file_reloading.cljs
@@ -105,13 +105,21 @@
   (dev-assert (all? namespace-file-map? files))
   (sort topo-compare-file-msg files))

+(defn store-meta-data-for-files! [files]
+  (dev-assert (all? namespace-file-map? files))
+  ;; store meta data
+  (doseq [{:keys [namespace meta-data]}
+          (filter #(and (:meta-data %) (:namespace %)) files)]
+    (swap! ns-meta-data assoc namespace meta-data)))
+
 (defn expand-files-to-include-deps [file-msgs]
   (dev-assert (all? namespace-file-map? file-msgs))
+  (store-meta-data-for-files! file-msgs)
   (let [current-ns    (set (map :namespace file-msgs))
         dependent-ns  (set (mapcat ns-that-depend-on current-ns))
         additional-ns (difference dependent-ns current-ns)
         additional-files (map (fn [x] { :namespace x
-                                       :meta-data nil
+                                       :meta-data (get @ns-meta-data x)
                                        :file (resolve-ns x)
                                        :type :namespace }) additional-ns)]
     (topo-sort-files (concat (set file-msgs)
@@ -205,8 +213,8 @@
        #_(.isProvided_ js/goog (name namespace)))
    (not (:figwheel-no-load (or meta-data {})))))

-(defn js-reload [{:keys [request-url namespace meta-data] :as file-msg} callback]
-  (when meta-data (swap! ns-meta-data assoc namespace meta-data))
+(defn js-reload [{:keys [request-url namespace] :as file-msg} callback]
+  (dev-assert (namespace-file-map? file-msg))
   (if (reload-file? file-msg)
     (reload-file file-msg callback)
     (do


Only set state to :active on signal-ready if it is inactive

This ensures :backpressure is not unset - this will be reset by the
peer when the queue is cleared

--- src/onyx/log/commands/signal_ready.clj
+++ src/onyx/log/commands/signal_ready.clj
@@ -7,7 +7,8 @@

 (defmethod extensions/apply-log-entry :signal-ready
   [{:keys [args]} replica]
-  (if (some #{(:id args)} (into #{} (:peers replica)))
+  (if (and (some #{(:id args)} (:peers replica))
+           (#{:idle :warming-up :nil} (get (:peer-state replica) (:id args) :nil)))
     (assoc-in replica [:peer-state (:id args)] :active)
     replica))

@@ -25,4 +26,3 @@
     (when (common/should-seal? new {:job job} state message-id)
       (>!! (:seal-ch state) true)))
   state)
-


Ensure init-locals are placed properly in trigger map.

--- src/onyx/windowing/window_compile.cljc
+++ src/onyx/windowing/window_compile.cljc
@@ -52,8 +52,7 @@
                         trigger)))
       (-> trigger
           (filter-ns-key-map "trigger")
-          (into locals)
-          (assoc :trigger trigger)
+          (assoc :trigger (into trigger locals))
           (assoc :state-context-window? state-context-window?)
           (assoc :state-context-trigger? state-context-trigger?)
           (assoc :pre-evictor pre-evictor)


actual counter implementation

actual counter implementation

--- src/org/spootnik/cyanite/es_client.clj
+++ src/org/spootnik/cyanite/es_client.clj
@@ -7,7 +7,8 @@
             [clojure.string :as str]
             [org.httpkit.client :as http]
             [cheshire.core :as json]
-            [clojure.tools.logging :refer [error info debug]])
+            [clojure.tools.logging :refer [error info debug]]
+            [org.spootnik.cyanite.util :refer [counter-inc!]])
   (:import clojurewerkz.elastisch.rest.Connection))

 (defn multi-get
@@ -18,7 +19,10 @@
    #(if (= 200 (:status %))
       (let [bod (json/decode (:body %) true)]
         (func (filter :found (:docs bod))))
-      (error "ES responded with non-200: " ))))
+      (do
+        (counter-inc! :index.get_error 1)
+        (error "ES responded with non-200: " ))
+      )))

 (comment "Note: i've ditched the optional args to ES, refer to orignal elastich code for how they should return")


Use global for simple-chapter version

Use global for simple-chapter version

--- src/qcast/feed/ext/simple_chapters.clj
+++ src/qcast/feed/ext/simple_chapters.clj
@@ -3,6 +3,10 @@
   qcast.feed.ext.simple-chapters
   (:require [hiccup.util :refer [escape-html]]))

+
+;;; Globals
+
+(def ^:private version "1.2")

 ;;; Interface

@@ -21,4 +25,4 @@
      (assoc-in (chapter start title link-url) [1 :image] image-url)))

 (defn chapters [& chapters]
-  [:psc:chapters {:version "1.2"} (map #(apply chapter %) chapters)])
+  [:psc:chapters {:version version} (map #(apply chapter %) chapters)])


Rename project artifact/group

Rename project artifact/group

Make that part match a similar change in weald

Update weald dependency so I can find it on clojars. Don't
particularly want to depend on a SNAPSHOT version, but I do want to
verify that version works before I commit to more release versions.

Broke down and incremented org.clojure/tools.logging dependency to
avoid conflict with aleph's version.

--- build.boot
+++ build.boot
@@ -1,13 +1,14 @@
-(def project 'frereth-cp)
+(def project 'frereth/cp)
 (def version "0.0.1-SNAPSHOT")

 (set-env! :resource-paths #{"src/clojure"}
-          :dependencies '[[adzerk/boot-test "RELEASE" :scope "test"]
+          :dependencies '[[adzerk/bootlaces "0.1.13" :scope "test"]
+                          [adzerk/boot-test "RELEASE" :scope "test"]
                           ;; Stick with whichever version of netty this inherits.
                           ;; That library isn't shy about breaking backwards compatibility
                           ;; between build versions.
                           [aleph "0.4.7-alpha3"]
-                          [com.frereth.weald "0.0.1"]
+                          [frereth/weald "0.0.3-SNAPSHOT"]
                           ;; TODO: Eliminate these logging dependencies.
                           ;; I have no business imposing them on library
                           ;; users
@@ -20,7 +21,7 @@
                           [org.clojure/test.check "0.10.0-alpha3" :scope "test" :exclusions [org.clojure/clojure]]
                           ;; TODO: Eliminate this dependency. It's another one
                           ;; that I really don't have any business imposing on anyone else
-                          [org.clojure/tools.logging "0.4.0" :exclusions [org.clojure/clojure]]
+                          [org.clojure/tools.logging "0.4.1" :exclusions [org.clojure/clojure]]
                           ;; TODO: Move this into the dev task
                           ;; (sadly, it isn't a straight copy/paste)
                           [samestep/boot-refresh "0.1.0" :scope "test" :exclusions [org.clojure/clojure]]


Reduce build pipeline complexity

Reduce build pipeline complexity

--- build.boot
+++ build.boot
@@ -22,30 +22,13 @@
  '[adzerk.boot-reload :refer [reload]]
  '[pandeiro.boot-http :refer [serve]])

-(deftask build []
-  (cljs))
-
-(deftask run []
+(deftask dev []
   (comp (serve)
         (watch)
-        (reload)
         (speak)
-        (build)))
+        (reload :on-jsload 'app.app/init)
+        (cljs :optimizations :none :source-map true)
+        (target)))

-(deftask production []
-  (task-options! cljs {:optimizations :advanced})
-   identity)
-
-(deftask development []
-  (task-options! cljs {:optimizations :none
-                       :source-map true}
-                 reload {:on-jsload 'app.app/init})
-   identity)
-
-(deftask dev []
-  (comp (development)
-        (run)))
-
-(deftask produce []
-  (comp (production)
-        (build)))
+(deftask prod []
+  (cljs :optimizations :advanced))


Fix bad SCM URI

Fix bad SCM URI

--- build.boot
+++ build.boot
@@ -5,7 +5,7 @@
   :source-paths #{"src"}
   :description "A toolkit for processing jar files"
   :url "https://github.com/irresponsible/unscrew"
-  :scm {:url "https://github.com/irresponsible/unscrew.git"}
+  :scm {:url "https://github.com/irresponsible/unscrew"}
   :developers {"James Laver" "james@seriesofpipes.com"}
   :license {"MIT" "https://en.wikipedia.org/MIT_License"}
   :dependencies '[[org.clojure/clojure "1.8.0" :scope "provided"]


bump version to 0.2.0-SNAPSHOT

bump version to 0.2.0-SNAPSHOT

Signed-off-by: Gregg Reynolds <d0f77bc71a9867acdcb4f62f012b858edad79160@norc.org>

--- build.boot
+++ build.boot
@@ -1,5 +1,5 @@
 (def +project+ 'migae/boot-gae)
-(def +version+ "0.1.1-SNAPSHOT")
+(def +version+ "0.2.0-SNAPSHOT")

 (set-env!
  :source-paths #{"src"}


Extract version to a var.

Extract version to a var.

--- build.boot
+++ build.boot
@@ -3,9 +3,11 @@
                   [clj.rb "0.2.1"]]
   :src-paths    ["src"])

+(def +version+ "0.1.0")
+
 (task-options!
   pom [:project 'boot-jruby
-       :version "0.1.0"
+       :version +version+
        :description "Boot task to execute JRuby code."
        :url "https://github.com/tobias/boot-jruby"
        :scm {:url "https://github.com/tobias/boot-jruby"}


Update pom [skip ci]

Update pom [skip ci]

--- build.boot
+++ build.boot
@@ -40,8 +40,11 @@
 (def +version+ "0.6.1-SNAPSHOT")

 (task-options!
-  pom  {:project 'moxaj/mikron
-        :version +version+})
+  pom  {:project     'moxaj/mikron
+        :version     +version+
+        :description "mikron is a schema-based serialization library for Clojure and ClojureScript"
+        :url         "https://github.com/moxaj/mikron"
+        :licence     {"Eclipse Public License" "http://www.eclipse.org/legal/epl-v10.html"}})

 (bootlaces/bootlaces! +version+
   :dont-modify-paths? true)


minor improvements

minor improvements

--- build.boot
+++ build.boot
@@ -45,9 +45,10 @@
   (let [tgt (core/tmp-dir!)]
     (core/with-pre-wrap [fs]
       (core/empty-dir! tgt)
-      (if-let [html-file (first (by-name [file] (core/input-files fs)))]
+      (if-let [html-file (first (by-path [file] (core/input-files fs)))]
         (let [f   (copy html-file tgt)
               txt (slurp f)]
+          (util/info "Injecting %s into %s...\n" scripts file)
           (spit f (inject-scripts txt (->> fs
                                            core/input-files
                                            (by-path scripts)


Update boot-cljs

Update boot-cljs

--- build.boot
+++ build.boot
@@ -2,7 +2,7 @@
   :source-paths #{"src/clj" "src/cljs"}
   :resource-paths #{"resources"}
   :dependencies '[[org.clojure/test.check "0.9.0" :scope "test"]
-                  [adzerk/boot-cljs "1.7.228-1" :scope "test"]
+                  [adzerk/boot-cljs "1.7.228-2" :scope "test"]
                   ; cljs deps
                   [org.clojure/clojurescript "1.9.456" :scope "test"]
                   [paren-soup "2.8.4" :scope "test"]


cleanup

cleanup

--- build.boot
+++ build.boot
@@ -1,5 +1,4 @@
 (set-env!
-  :src-paths    #{"src"}
   :dependencies '[[org.clojure/clojure       "1.6.0"          :scope "provided"]
                   [boot/core                 "2.0.0-pre5"     :scope "provided"]
                   [tailrecursion/boot-useful "0.1.0-SNAPSHOT" :scope "test"]
@@ -7,8 +6,7 @@

 (def +VERSION+ "0.0-2371-3")

-(require
-  '[tailrecursion.boot-useful :refer [push-snapshot push-release]])
+(require '[tailrecursion.boot-useful :refer :all])

 (task-options!
   pom  [:project        'tailrecursion/boot-cljs


Revert "Update content-pre-wrap to content-task". Handle in separate PR.

This reverts commit 85c144b75fd369d2e63bea2c5e171021893d178c.

--- build.boot
+++ build.boot
@@ -33,7 +33,7 @@

 (deftask header-links
   []
-  (content-task
+  (content-pre-wrap
    {:task-name "header-links"
     :render-form-fn (fn [data] `(io.perun.site/add-header-link-content ~data))
     :paths-fn #(content-paths % {:filterer guide? :extensions [".html"]})


Bump play-cljs template

Bump play-cljs template

--- build.boot
+++ build.boot
@@ -7,7 +7,7 @@
                   [leiningen "2.7.0" :exclusions [leiningen.search]]
                   [ring "1.4.0"]
                   [clojail "1.0.6"]
-                  [play-cljs/lein-template "0.5.1"]])
+                  [play-cljs/lein-template "0.6.1"]])

 (task-options!
   sift {:include #{#"\.jar$"}}


Add junit as a test dependency

Add junit as a test dependency

--- build.boot
+++ build.boot
@@ -1,5 +1,6 @@
 (set-env!
- :source-paths #{"src"})
+ :source-paths #{"src"}
+ :dependencies '[[junit "4.12" :scope "test"]])

 (def +version+ "0.1.0")


Updating boot-gzip

Updating boot-gzip

--- build.boot
+++ build.boot
@@ -14,7 +14,7 @@
    [devcards "0.2.2" :scope "test"]
    [nightlight "1.3.2" :scope "test"]
    [org.clojure/tools.nrepl "0.2.12" :scope "test"]
-   [org.martinklepsch/boot-gzip "0.1.2" :scope "test"]
+   [org.martinklepsch/boot-gzip "0.1.3" :scope "test"]
    [org.slf4j/slf4j-nop "1.7.21" :scope "test"]
    [pandeiro/boot-http "0.7.6" :scope "test"]
    [perun "0.3.0" :scope "test"]


Don't include development artifacts for prod

--- build.boot
+++ build.boot
@@ -48,4 +48,6 @@
   (comp
     (middleman)
     (cljs :optimizations :advanced)
+    (sift :invert true :include #{#"main.out/.*"
+                                  #"ui.html$"})
     (target :dir #{"target"})))


only build app in release

only build app in release

--- build.boot
+++ build.boot
@@ -24,6 +24,6 @@
 (deftask release []
   (comp
    (less :compression true)
-   (cljs :optimizations :advanced)
+   (cljs :ids #{"main"} :optimizations :advanced)
    (sift :include #{#"(^index\.html|^main\.js|^styles.css)"})
    (target :dir #{"target"})))


Update boot with check and bootlaces

Update boot with check and bootlaces

--- build.boot
+++ build.boot
@@ -1,31 +1,39 @@
-(set-env! :dependencies
-          '[[org.clojure/clojure "1.7.0"]
-            [org.clojure/core.match "0.3.0-alpha4"]
-            [prismatic/schema "1.0.5"]
-            [environ "1.0.2"]
-            [org.clojure/tools.cli "0.3.3"]
-            [clj-jgit "0.8.8"]
-            [clj-http "2.1.0"]
-            [cheshire "5.5.0"]
-            [throttler "1.0.0"]
-            [org.slf4j/slf4j-nop "1.7.18"]
-            [grimradical/clj-semver "0.3.0-20130920.191002-3" :exclusions [org.clojure/clojure]]
-            ; testing
-            [org.clojure/tools.namespace "0.2.11" :scope "test"]
-            [org.clojure/test.check "0.9.0" :scope "test"]
-            [clj-http-fake "1.0.2" :scope "test"]
-            [adzerk/boot-test "1.1.1" :scope "test"]]
-          :source-paths #{"src/"})
+(def +version+ "0.1.0-SNAPSHOT")

-(ns-unmap 'boot.user 'test)
+(set-env!
+ :source-paths #{"src/"}
+ :dependencies
+ '[[org.clojure/clojure "1.8.0"]
+   [org.clojure/core.match "0.3.0-alpha4"]
+   [prismatic/schema "1.0.5"]
+   [environ "1.0.2"]
+   [org.clojure/tools.cli "0.3.3"]
+   [clj-jgit "0.8.8"]
+   [clj-http "2.1.0"]
+   [cheshire "5.5.0"]
+   [throttler "1.0.0"]
+   [org.slf4j/slf4j-nop "1.7.18"]
+   [grimradical/clj-semver "0.3.0-20130920.191002-3" :exclusions [org.clojure/clojure]]
+   ; testing
+   [org.clojure/tools.namespace "0.2.11" :scope "test"]
+   [org.clojure/test.check "0.9.0" :scope "test"]
+   [clj-http-fake "1.0.2" :scope "test"]
+   [adzerk/boot-test "1.1.1" :scope "test"]
+   [tolitius/boot-check "0.1.1" :scope "test"]
+   [boot/core "2.5.1" :scope "provided"]
+   [adzerk/bootlaces "0.1.13" :scope "test"]])

 (require
  '[github-changelog.core :refer [changelog]]
- '[adzerk.boot-test :refer :all])
+ '[adzerk.boot-test :as boot-test]
+ '[tolitius.boot-check :as check]
+ '[adzerk.bootlaces :refer :all])
+
+(bootlaces! +version+)

 (task-options!
  pom {:project 'hu.ssh/github-changelog
-      :version "0.1.0-SNAPSHOT"
+      :version +version+
       :description "GitHub changelog"
       :url "https://github.com/raszi/github-changelog"
       :license {:name "MIT"
@@ -33,14 +41,34 @@
  jar {:main 'github-changelog.cli}
  aot {:all true})

-(deftask testing-helper []
+#_(deftask check-sources
+  "Checks source code for possible improvements/simplifications"
+  []
+  (comp
+   (check/with-bikeshed)
+   check/with-eastwood)
+   (check/with-yagni)
+   (check/with-kibit))
+
+(deftask testing-helper
   "Sets up the environment for testing"
+  []
   (merge-env! :source-paths #{"test"})
   identity)

-(deftask auto-test []
-  "Test everything whenever source changes"
+(ns-unmap 'boot.user 'test)
+
+(deftask test
+  "Runs the test suite"
+  []
+  (comp
+   (testing-helper)
+   (boot-test/test)))
+
+(deftask auto-test
+  "Tests everything whenever source changes"
+  []
   (comp
    (testing-helper)
    (watch)
-   (test)))
+   (boot-test/test)))


Start 2.5.1-SNAPSHOT

Start 2.5.1-SNAPSHOT

--- build.boot
+++ build.boot
@@ -28,7 +28,7 @@
 (task-options!
   sift {:include #{#"\.jar$"}}
   pom {:project 'nightcode
-       :version "2.5.0"
+       :version "2.5.1-SNAPSHOT"
        :description "An IDE for Clojure"
        :url "https://github.com/oakes/Nightcode"
        :license {"Public Domain" "http://unlicense.org/UNLICENSE"}}


releasing 0.1.12

releasing 0.1.12

--- build.boot
+++ build.boot
@@ -1,4 +1,4 @@
-(def +version+ "0.1.12")
+(def +version+ "0.1.13-SNAPSHOT")

 (set-env!
   :source-paths #{"src"}


update to pro-starter version

update to pro-starter version

--- build.boot
+++ build.boot
@@ -18,7 +18,7 @@
                             [com.stuartsierra/component   "0.3.2"]

                             ;; Database
-                            [com.datomic/datomic-free "0.9.5544"]
+                            [com.datomic/datomic-pro "0.9.5554"]

                             ;; HTTP Server
                             [io.pedestal/pedestal.service "0.5.1"]
@@ -36,7 +36,10 @@
                             ;; Logging
                             [org.slf4j/jul-to-slf4j     "1.7.21"]
                             [org.slf4j/jcl-over-slf4j   "1.7.21"]
-                            [org.slf4j/log4j-over-slf4j "1.7.21"]])
+                            [org.slf4j/log4j-over-slf4j "1.7.21"]]
+          :repositories #(conj % ["my-datomic" {:url "https://my.datomic.com/repo"
+                                                :username (System/getenv "DATOMIC_USERNAME")
+                                                :password (System/getenv "DATOMIC_PASSWORD")}]))

 ;; Load testing tasks
 (require '[adzerk.boot-test :refer :all])


Add dep for java 9

Add dep for java 9

--- build.boot
+++ build.boot
@@ -10,6 +10,7 @@
                   [cljsjs/codemirror "5.24.0-1" :scope "test"]
                   ; clj deps
                   [org.clojure/clojure "1.9.0-beta3"]
+                  [javax.xml.bind/jaxb-api "2.3.0"] ; necessary for Java 9 compatibility
                   [leiningen "2.8.0" :exclusions [leiningen.search]]
                   [ring "1.6.1"]
                   [hawk "0.2.11"]


Update to boot-test 1.2.0

Update to boot-test 1.2.0

--- build.boot
+++ build.boot
@@ -10,7 +10,7 @@
   :developers {"James Laver" "james@seriesofpipes.com"}
   :license {"MIT" "https://en.wikipedia.org/MIT_License"}
   :dependencies '[[org.clojure/clojure      "1.9.0-alpha15"  :scope "provided"]
-                  [adzerk/boot-test         "1.1.2"  :scope "test"]
+                  [adzerk/boot-test         "1.2.0"  :scope "test"]
                   [org.clojure/tools.nrepl  "0.2.12" :scope "test"]])

 (require '[adzerk.boot-test :as t])


Bump aleph version to next alpha

Bump aleph version to next alpha

--- build.boot
+++ build.boot
@@ -11,7 +11,7 @@
                           #_[aleph "0.4.4" :exclusions [io.netty/netty-all
                                                       org.clojure/tools.logging]]
                           ;; Alt: Try this instead
-                          [aleph "0.4.5-alpha4"]
+                          [aleph "0.4.5-alpha5"]
                           ;; Note that 5.0.0 is up to alpha2
                           [io.netty/netty-all "4.1.20.Final"]
                           ;; TODO: Eliminate these logging dependencies.


Require `boot-test` for CircleCi

Require `boot-test` for CircleCi

--- build.boot
+++ build.boot
@@ -3,7 +3,7 @@

 (set-env! :resource-paths #{"resources" "src"}
           :source-paths #{"test"}
-          :dependencies '[[org.clojure/clojure "RELEASE" :scope "provided"]
+          :dependencies '[[org.clojure/clojure "1.9.0-alpha17" :scope "provided"]
                           [adzerk/boot-test "RELEASE" :scope "test"]
                           [adzerk/bootlaces "0.1.13" :scope "test"]])

@@ -25,3 +25,5 @@
   "Build and install the project locally."
   []
   (comp (pom) (jar) (install)))
+
+(require '[adzerk.boot-test :refer [test]])


add browser repl

add browser repl

--- build.boot
+++ build.boot
@@ -2,20 +2,23 @@
  :source-paths    #{"src" "test" "styles"}
  :resource-paths  #{"html" "build"}
  :dependencies    '[[adzerk/boot-cljs          "1.7.48-6"]
+                    [adzerk/boot-cljs-repl     "0.2.0"]
                     [adzerk/boot-reload        "0.4.1"]
                     [deraen/boot-less          "0.4.2"]
                     [org.clojure/clojurescript "1.7.145"]
                     [pandeiro/boot-http        "0.7.0"]])

 (require
- '[adzerk.boot-cljs   :refer [cljs]]
- '[adzerk.boot-reload :refer [reload]]
- '[deraen.boot-less   :refer [less]]
- '[pandeiro.boot-http :refer [serve]])
+ '[adzerk.boot-cljs      :refer [cljs]]
+ '[adzerk.boot-cljs-repl :refer [cljs-repl start-repl]]
+ '[adzerk.boot-reload    :refer [reload]]
+ '[deraen.boot-less      :refer [less]]
+ '[pandeiro.boot-http    :refer [serve]])

 (deftask dev []
   (comp
    (watch)
+   (cljs-repl)
    (reload :on-jsload 'frontend.dev/refresh)
    (less)
    (cljs)


Filter on regex as well as path for reformat

--- build.boot
+++ build.boot
@@ -2,7 +2,7 @@
  :source-paths #{"src/java" "src/clj" "test" "build.boot"}
  :resource-paths #{"resources"}
  :format-paths #{"src/clj" "build.boot" "test"}
- ;:format-regex #"\.clj[sx]?$"
+ :format-regex #"\.(?:clj[sx]?|boot)$"
  :dependencies '[[adzerk/boot-test "1.1.0" :scope "test"]
                  [org.clojure/clojure "1.8.0"]
                  [commons-io "2.4"]
@@ -42,9 +42,9 @@
 (require '[adzerk.boot-test :refer :all])

 (deftask build []
-	(comp
-  (javac)
-  (aot :namespace '#{schedule.solver.types})))
+  (comp
+   (javac)
+   (aot :namespace '#{schedule.solver.types})))

 (require '[cljfmt.core :refer [reformat-string]]
          '[clojure.java.io :as io]
@@ -56,10 +56,10 @@
   (cljfmt.core/reformat-string s {}))

 (defn fix-path [{:keys [file action]}]
-  (let [paths (:format-paths boot.pod/env)
-        path (.getAbsolutePath file)
-        matches (-> (filter #(str/includes? path %) paths) empty? not)]
-    (if matches
+  (let [path (.getAbsolutePath file)
+        matches-path (-> boot.pod/env :format-paths ((partial filter #(str/includes? path %))) empty? not)
+        matches-regex (-> boot.pod/env :format-regex (#(re-find % path)) nil? not)]
+    (if (and matches-path matches-regex)
       (let  [original (slurp file)
              revised  (reformat-str original)]
         (if (not= original revised)


Update deps

Update deps

--- build.boot
+++ build.boot
@@ -14,10 +14,10 @@
                   [org.clojure/tools.nrepl "0.2.12"    :scope "test"]
                   [adzerk/boot-reload     "0.4.2"      :scope "test"]
                   [adzerk/boot-test       "1.0.7"      :scope "test"]
-                  [deraen/boot-less       "0.4.4"      :scope "test"]
+                  [deraen/boot-less       "0.5.0"      :scope "test"]
                   ;; For boot-less
                   [org.slf4j/slf4j-nop    "1.7.13"     :scope "test"]
-                  [deraen/boot-sass       "0.1.1"      :scope "test"]
+                  [deraen/boot-sass       "0.2.0"      :scope "test"]
                   [deraen/boot-ctn        "0.1.0"      :scope "test"]

                   ; Backend


Update play-cljs template

Update play-cljs template

--- build.boot
+++ build.boot
@@ -11,7 +11,7 @@
                   [org.clojure/clojure "1.9.0-alpha14"]
                   [leiningen "2.7.0" :exclusions [leiningen.search]]
                   [ring "1.4.0"]
-                  [play-cljs/lein-template "0.8.0.1"]
+                  [play-cljs/lein-template "0.9.0"]
                   [eval-soup "1.2.0" :exclusions [org.clojure/core.async]]
                   [org.eclipse.jgit/org.eclipse.jgit "4.6.0.201612231935-r"]])


More correctly call set-env! in boot test

--- build.boot
+++ build.boot
@@ -111,7 +111,6 @@
 (deftask build
   "Build the final artifact, if no type is passed in, it builds production."
   [t type VAL kw "The build type, either prod or dev"]
-
   (let [options (options (or type :prod))]
     (boot.util/info "Building %s profile...\n" (:type options))
     (apply set-env! (reduce #(into %2 %1) [] (:env options)))
@@ -138,11 +137,11 @@
 (ns-unmap 'boot.user 'test)

 (deftask test
-  "Run tests, if no type is passed in, it tests against production."
+  "Run tests, if no type is passed in, it tests against the production build."
   [t type VAL kw "The build type, either prod or dev"]
   (let [options (options (or type :prod))]
     (boot.util/info "Testing %s profile...\n" (:type options))
-    (set-env! :source-paths (conj (get-in options [:env :source-paths]) "test/cljs" ))
+    (apply set-env! (reduce #(into %2 %1) [] (update-in (:env options) [:source-paths] conj "test/cljs")))
     (apply test-cljs (reduce #(into %2 %1) [] (:test-cljs options)))))

 (deftask auto-test


use a specific appengine-tools-sdk version (for now)

--- build.boot
+++ build.boot
@@ -15,7 +15,7 @@
                    [adzerk/boot-test "1.0.7" :scope "test"]
                    ;; ;; we need this so we can import KickStart for the run task:
                    ;; FIXME: what if user wants a different sdk version?
-                   [com.google.appengine/appengine-tools-sdk RELEASE]
+                   [com.google.appengine/appengine-tools-sdk "1.9.73"]
                    ])

 (task-options!


Update cljs

Update cljs

--- build.boot
+++ build.boot
@@ -4,7 +4,7 @@
   :source-paths #{"src/cljs" "src/less" "src/scss" "test/clj" "test/cljs"}
   :resource-paths #{"src/clj" "src/cljc"}
   :dependencies '[[org.clojure/clojure    "1.9.0-alpha13"]
-                  [org.clojure/clojurescript "1.9.229"]
+                  [org.clojure/clojurescript "1.9.293"]

                   [boot/core              "2.6.0"      :scope "test"]
                   [adzerk/boot-cljs       "1.7.228-2"  :scope "test"]


Fix format-commands #4

Fix format-commands #4

--- build.boot
+++ build.boot
@@ -51,8 +51,10 @@

 (defn run-commands
   [& commands]
-  (util/info (str "Running command: ")
-             (apply str (apply format-commands commands)))
+  (util/info (str "Input commands:\n" (str (vec commands)) "\n\n"))
+  (util/info (str "Running command: \n"
+                  (apply str (apply format-commands commands))
+                  "\n\n"))
   (->> commands
        (apply format-commands)
        (apply util/dosh)))


eliminate guard devices

eliminate guard devices

--- src/node/server/core.cljs
+++ src/node/server/core.cljs
@@ -7,7 +7,7 @@
    [cljs.nodejs :as nodejs]
    [cljs.core.async :as async :refer [chan close! timeout put!]]
    [reagent.core :as reagent :refer [atom]]
-   [app.core :refer [static-page active-devices monitor-devices track-devices guard-devices]]
+   [app.core :refer [static-page active-devices monitor-devices track-devices]]
    [app.pubnub :as pubnub]
    [server.nexmo :as nexmo]))


Fix parse of env vars to integer.

Fix parse of env vars to integer.

--- src/oc/storage/config.clj
+++ src/oc/storage/config.clj
@@ -117,5 +117,5 @@

 (defonce unread-days-limit (or (env :unread-days-limit) 30))

-(defonce unseen-cap-days (Integer/parseInt (or (env :unseen-cap-days) (* 365 50))))
-(defonce pins-sort-pivot-days (Integer/parseInt (or (env :pins-sort-pivot-days) (* 365 100))))
+(defonce unseen-cap-days (Integer/parseInt (or (env :unseen-cap-days) (str (* 365 50)))))
+(defonce pins-sort-pivot-days (Integer/parseInt (or (env :pins-sort-pivot-days) (str (* 365 100)))))


[css] Move all kinds of definitions to toplevel.

--- src-cljs/pepa/style.cljs
+++ src-cljs/pepa/style.cljs
@@ -648,18 +648,18 @@
                :min-height (px tags-min-height)
                :line-height (px (+ 2 tags-min-height))}
      [:&.tag-box (list
-                   {:padding {:left (px tag-icon-box)
-                              :top (px 6)}
-                    :border (str "1px solid " border-dark)
-                    :border-radius (px 3)
-                    :height :auto
-                    :background {:image (image-url "tag-icon.svg")
-                                 :repeat :no-repeat
-                                 :size (px 14)
-                                 :position [[(px 8) (px 8)]]
-                                 :color :white}
-                    :white-space :initial}
-                   (calc-property :width ["100%" -  (px tag-icon-box)]))
+                  {:padding {:left (px tag-icon-box)
+                             :top (px 6)}
+                   :border (str "1px solid " border-dark)
+                   :border-radius (px 3)
+                   :height :auto
+                   :background {:image (image-url "tag-icon.svg")
+                                :repeat :no-repeat
+                                :size (px 14)
+                                :position [[(px 8) (px 8)]]
+                                :color :white}
+                   :white-space :initial}
+                  (calc-property :width ["100%" -  (px tag-icon-box)]))
       [:&:before {:content (pr-str "Tags:")
                   :font-size (em 1.2)
                   :display :block
@@ -904,19 +904,19 @@
                  :background :transparent}]]
     [:&.file-drop
      {:background "red"}]
-    clear-a-css
-    button-css
-    generic-input-css
-
-    dropdown-css
-    sidebar-css
-    tags-css
-    upload-css
-    search-css

     [:main {:height "100%", :width "100%"
             :overflow-x :hidden}
-     workflow-css]]))
+     workflow-css]]
+   clear-a-css
+   button-css
+   generic-input-css
+
+   dropdown-css
+   sidebar-css
+   tags-css
+   upload-css
+   search-css))

 ;;; Apply the CSS


Reduce unnecessary key lookups for perf reasons

--- src/onyx/plugin/kafka.clj
+++ src/onyx/plugin/kafka.clj
@@ -315,7 +315,7 @@
   (.close (:kafka/producer event)))

 (defn- message->producer-record
-  [{:keys [serializer-fn topic]} m]
+  [serializer-fn topic m]
   (let [message (:message m)
         k (some-> m :key serializer-fn)
         p (some-> m :partition int)
@@ -345,7 +345,7 @@
       (doall
        (->> messages
             (map (fn [msg]
-                   (send-async! producer (message->producer-record this (:message msg)))))
+                   (send-async! producer (message->producer-record serializer-fn topic (:message msg)))))
             (doall)
             (run! deref)))
       {}))


minor fix to install-service

minor fix to install-service

Signed-off-by: Gregg Reynolds <d0f77bc71a9867acdcb4f62f012b858edad79160@norc.org>

--- src/migae/boot_gae.clj
+++ src/migae/boot_gae.clj
@@ -832,9 +832,9 @@
   (fn middleware [next-handler]
     (fn handler [fileset]
       (let [e (boot/get-env)
-            target-dir (get-target-dir fileset false)
+            ;; target-dir (get-target-dir fileset false)
             jarname (util/jarname project version)
-            jarpath (str target-dir "/" jarname)
+            ;; jarpath (str target-dir "/" jarname)
             target-middleware (comp
                                (builtin/pom)
                                (builtin/jar)


Updated

Updated

--- build.boot
+++ build.boot
@@ -5,7 +5,7 @@
 ;; the file LICENSE at the root of this distribution.

 (def project 'dollabs/plan-schema)
-(def version "0.3.3")
+(def version "0.3.4")
 (def description "Temporal Planning Network schema utilities")
 (def project-url "https://github.com/dollabs/plan-schema")
 (def main 'plan-schema.cli)


Fix cljs version

Fix cljs version

--- build.boot
+++ build.boot
@@ -1,7 +1,7 @@
 (set-env!
   :resource-paths #{"src/cljc" "src/js/foreign"}
   :dependencies   '[[org.clojure/clojure         "1.9.0-alpha16"]
-                    [org.clojure/clojurescript   "1.9.522"]
+                    [org.clojure/clojurescript   "1.9.542"]

                     [adzerk/boot-test            "1.2.0"     :scope "test"]
                     [pandeiro/boot-http          "0.7.6"     :scope "test"]


update re-com dependency

update re-com dependency

--- build.boot
+++ build.boot
@@ -28,7 +28,7 @@
                        [replumb/replumb             "0.2.2-SNAPSHOT"]
                        [cljsjs/highlight            "8.4-0"]
                        [re-console                  "0.1.4-SNAPSHOT"]
-                       [re-com                      "0.7.0-alpha2"]
+                       [re-com                      "0.8.1"]
                        [cljs-ajax                   "0.5.1"]
                        [hickory                     "0.5.4"]
                        [cljsjs/showdown             "0.4.0-1"]


Adding acl token cache to to fix problem pausing and resuming jobs.

--- ingest-app/src/cmr/ingest/system.clj
+++ ingest-app/src/cmr/ingest/system.clj
@@ -12,6 +12,7 @@
             [cmr.ingest.config :as config]
             [cmr.ingest.services.jobs :as ingest-jobs]
             [cmr.common.jobs :as jobs]
+            [cmr.acl.core :as acl]
             [cmr.oracle.connection :as oracle]
             [cmr.common.config :as cfg]))

@@ -34,6 +35,7 @@
               :db (oracle/create-db (config/db-spec connection-pool-name))
               :zipkin (context/zipkin-config "Ingest" false)
               :scheduler (jobs/create-clustered-scheduler `system-holder ingest-jobs/jobs)
+              :caches {acl/token-imp-cache-key (acl/create-token-imp-cache)}
               :relative-root-url (transmit-config/ingest-relative-root-url)}]
      (transmit-config/system-with-connections sys [:metadata-db :indexer :echo-rest]))))


Fix printing of mela number in kriti blurb

--- src/movertone/html.clj
+++ src/movertone/html.clj
@@ -178,7 +178,7 @@
              (str "Janyam of "
                   (display-ragam-name (:parent-mela-name ragam))
                   " (" (:parent-mela-num ragam) ")")]
-            [:p.more-info (str "This is Melakartha no. " num)])])]
+            [:p.more-info (str "This is Melakartha no. " (:num ragam))])])]
       [:br]
       (when (seq (:lyrics kriti))
         [:h2 "Lyrics"])


langohr wants a map

langohr wants a map

--- src/myshelf/worker.clj
+++ src/myshelf/worker.clj
@@ -18,12 +18,13 @@
   (:gen-class))

 (def default-exchange "")
-(def connection-params (or (System/getenv "CLOUDAMQP_URL")
-                           {:host "localhost"
-                            :port 5672
-                            :username "guest"
-                            :password "guest"
-                            :vhost "/"}))
+(def connection-params (if-let [uri (System/getenv "CLOUDAMQP_URL")]
+                         {:uri uri}
+                         {:host "localhost"
+                          :port 5672
+                          :username "guest"
+                          :password "guest"
+                          :vhost "/"}))
 (def worker-queue "myshelf.worker")
 (def reply-queue "myshelf.reply")
 (def goodreads-creds (atom {}))


reverting to joodo 0.10.0

reverting to joodo 0.10.0

--- config.clj
+++ config.clj
@@ -1,7 +1,7 @@
 {
  :version "0.10.3"
  :clojure-version "1.4.0"
- :joodo-version "0.12.0"
+ :joodo-version "0.10.0"
  :speclj-version "2.3.2"
  :gae-version "1.7.0"
 }


hundreds fix for parsing

hundreds fix for parsing


Added utility function.

Added utility function.

--- src/dragon/util.clj
+++ src/dragon/util.clj
@@ -44,3 +44,9 @@
       (string/replace acc (str k) v))
     date-format
     date-map))
+
+(defn sanitize-str
+  [str]
+  (-> str
+      (string/replace #"\W+" "-")
+      (string/lower-case)))


Upload requires admin authorization

Upload requires admin authorization

--- src/ansel/server.clj
+++ src/ansel/server.clj
@@ -73,16 +73,17 @@
           (assoc (resp/redirect (str (:context req) "/")) :flash "passwords don't match!")))

   (GET "/upload" req
-    (friend/authenticated (render req "upload.html")))
+    (friend/authorize #{"admin"} (render req "upload.html")))

   (POST "/upload" req
-    (let [uploaded         (get-in req [:params :files])
-          album            (get-in req [:params :album])
-          process-uploaded (partial process-uploaded-file album)]
-      {:status 200
-        :headers {"Content-Type" "application/json"}
-        :body (pretty-json
-                {:files (map process-uploaded uploaded)})}))
+    (friend/authorize #{"admin"}
+      (let [uploaded         (get-in req [:params :files])
+            album            (get-in req [:params :album])
+            process-uploaded (partial process-uploaded-file album)]
+        {:status 200
+          :headers {"Content-Type" "application/json"}
+          :body (pretty-json
+                  {:files (map process-uploaded uploaded)})})))

   (GET "/image/:image" req
     (let [image-name (get-in req [:params :image])


resources.clj edited online with Bitbucket

--- resources/resources.clj
+++ resources/resources.clj
@@ -1,4 +1,4 @@
-{:detrit {:size 31
+{:detrit {:size 0
           :max-size 1e4}
  :soil {:size 0.0
         :max-size 100}


Further refine increment-keys

Further refine increment-keys

--- src/parbench/utils.clj
+++ src/parbench/utils.clj
@@ -7,9 +7,7 @@

    Keys with a null value will be set to 1."
   [src-map & xs]
-  (merge
-    src-map
-    (into {} (map #(vector %1 (inc (get src-map %1 0))) xs))))
+  (into src-map (map #(vector %1 (inc (get src-map %1 0))) xs)))

 (defn send-bench-msg
   "Enqueue a message of the format {:dtype data-type :data data}


capitalize c

capitalize c

--- frontend/components/language_landing.cljs
+++ frontend/components/language_landing.cljs
@@ -21,7 +21,7 @@

 (def templates
   {"ruby" {:language "Ruby"
-           :headline "CircleCI makes Continous Integration and Deployment for Ruby projects a breeze."
+           :headline "CircleCI makes Continuous Integration and Deployment for Ruby projects a breeze."
            :logo-path (utils/cdn-path "/img/outer/languages/ruby-logo.svg")
            :features [{:feature "CircleCI provides support for a wide variety of Ruby versions and gems, including Ruby on Rails. It is trivial to add any packages or frameworks that are not installed on our machines by default, allowing you to effortlessly customize your test enviroment.  CircleCI also supports Test::Unit, RSpec, Cucumber, Spinach, Jasmine, Konacha, and just about any other testing framework you use for your Ruby project."
                        :title "Built For Ruby"