Add subheading to integrations/*

Add subheading to integrations/*

--- src-cljs/frontend/components/integrations.cljs
+++ src-cljs/frontend/components/integrations.cljs
@@ -98,7 +98,7 @@
 (def integration-data
   {:heroku {:hero {:icon (utils/cdn-path "/img/outer/integrations/heroku-logo.svg")
                    :heading "Deploy to Heroku from CircleCI"
-                   :text "Experience a simple, modern continuous delivery workflow now."}
+                   :subheading "Experience a simple, modern continuous delivery workflow now."}
             :features [{:type :text
                         :title "Test before you deploy. Always."
                         :icon "circle"
@@ -143,7 +143,7 @@
                              "docs on deploying to Heroku."]]}
    :saucelabs {:hero {:icon nil
                       :heading "Test with Sauce Labs on CircleCI"
-                      :text "Test against hundreds of mobile and desktop browsers."}
+                      :subheading "Test against hundreds of mobile and desktop browsers."}
                :features [{:type :text
                            :title "Selenium WebDriver"
                            :icon "fail"
@@ -244,17 +244,19 @@
                   ;                       :allowFullscreen true}]
                   [:button.close {:aria-label "Close"
                                   :on-click #(raise! owner [:close-video])}]])
-               [:div.jumbotron
-                common/language-background-jumbotron
-                [:section.container
-                 [:div.row
-                  [:div.hero-title.center-block
-                   [:div.text-center
-                    (if-let [icon-src (get-in data [:hero :icon])]
-                      [:img.hero-logo {:src icon-src}])]
-                   [:h1.text-center (get-in data [:hero :heading])]]]]
-                [:div.row.text-center
-                 (common/sign-up-cta owner (str "integrations/" (name integration)))]]
+               (let [hero (:hero data)]
+                 [:div.jumbotron
+                  common/language-background-jumbotron
+                  [:section.container
+                   [:div.row
+                    [:div.hero-title.center-block
+                     [:div.text-center
+                      (if-let [icon-src (:icon hero)]
+                        [:img.hero-logo {:src icon-src}])]
+                     [:h1.text-center (:heading hero)]
+                     [:h3.text-center (:subheading hero)]]]]
+                  [:div.row.text-center
+                   (common/sign-up-cta owner (str "integrations/" (name integration)))]])

                [:div.outer-section
                 [:section.container


unused code

unused code

--- src/neo4j_meetup/import.clj
+++ src/neo4j_meetup/import.clj
@@ -271,16 +271,6 @@
 (defn timed [fn description]
   (println (str description ":" (with-out-str (time (fn))))))

-(comment (defn -main [& args]
-  (timed clear-all "clear")
-  (timed #(create-time-tree 2011 2014) "time-tree")
-  (timed #(db/tx-api create-group (load-json "data/groups-2014-05-14.json")) "groups")
-  (let [file (clojure.java.io/file "data/members-2014-05-14/12962072.json")]
-    (timed #(db/tx-api create-member
-                       (map (fn [data] ( merge {:groupid (extract-group-id file)} data))
-                            (load-json (.getPath file))))
-           (str "members of " (extract-group-id file))))))
-
 (defn save-json [file data]
   (clojure.core/spit file (json/write-str data)))

@@ -290,14 +280,6 @@
                                (mapcat (fn [data] (map #(:topics %) data)))
                                flatten
                                (clojure.core/set))))
-
-(comment (defn import-topics [member-files]
-           (->>  member-files
-                 (take 1)
-                 (map #(load-json (.getPath %)))
-                 (mapcat (fn [data] (map #(count ( :topics %)) data)))
-                 (reduce +)
-                 )))

 (defn -main [& args]
   (let [member-files


stop processing unchanged lines if quit flag set

--- lib/src/parinfer/indent_mode.cljc
+++ lib/src/parinfer/indent_mode.cljc
@@ -398,9 +398,10 @@
         new-cache (last (:postindent-states state))
         more? (< (inc old-i) (count (:lines prev-state)))
         can-skip? (and new-cache (= new-cache cache))]
-    (if (and can-skip? more?)
-      (reduced (fill-rest-with-cache prev-state state old-i))
-      state)))
+    (cond
+      (:quit? state) (reduced state)
+      (and can-skip? more?) (reduced (fill-rest-with-cache prev-state state old-i))
+      :else state)))

 (defn process-unchanged-lines
   "process the lines after those that have changed."


Count all substrings the easy way

Count all substrings the easy way


Make :checkpoint/force-reset? non-optional

--- src/onyx/plugin/datomic.clj
+++ src/onyx/plugin/datomic.clj
@@ -24,7 +24,7 @@
               (s/optional-key :datomic/log-start-tx) s/Int
               (s/optional-key :datomic/log-end-tx) s/Int
               (s/optional-key :checkpoint/key) s/Str
-              (s/optional-key :checkpoint/force-reset?) s/Bool
+              :checkpoint/force-reset? s/Bool
               (s/optional-key :onyx/max-peers) (s/enum 1)
               (s/optional-key :onyx/n-peers) (s/enum 1)
               UserTaskMapKey s/Any}]))


Fns for stamping log entries.

Fns for stamping log entries.

--- src/onyx/sync/zookeeper.clj
+++ src/onyx/sync/zookeeper.clj
@@ -272,6 +272,52 @@
         data (serialize-edn content)]
     {:node (zk/create (:conn sync) node :data data :persistent? true :sequential? true)}))

+(defn create-log-entry [sync f content]
+  (let [prefix (:onyx/id (:opts sync))
+        node (str (f prefix) "/log-entry-")]
+    {:node (zk/create-all (:conn sync) node :persistent? true :sequential? true)}
+    content))
+
+(defmethod extensions/create [ZooKeeper :born-log]
+  [sync _ content]
+  (create-log-entry sync born-log-path content))
+
+(defmethod extensions/create [ZooKeeper :death-log]
+  [sync _ content]
+  (create-log-entry sync death-log-path content))
+
+(defmethod extensions/create [ZooKeeper :planning-log]
+  [sync _ content]
+  (create-log-entry sync planning-log-path content))
+
+(defmethod extensions/create [ZooKeeper :ack-log]
+  [sync _ content]
+  (create-log-entry sync ack-log-path content))
+
+(defmethod extensions/create [ZooKeeper :evict-log]
+  [sync _ content]
+  (create-log-entry sync evict-log-path content))
+
+(defmethod extensions/create [ZooKeeper :offer-log]
+  [sync _ content]
+  (create-log-entry sync offer-log-path content))
+
+(defmethod extensions/create [ZooKeeper :revoke-log]
+  [sync _ content]
+  (create-log-entry sync revoke-log-path content))
+
+(defmethod extensions/create [ZooKeeper :seal-log]
+  [sync _ content]
+  (create-log-entry sync seal-log-path content))
+
+(defmethod extensions/create [ZooKeeper :complete-log]
+  [sync _ content]
+  (create-log-entry sync complete-log-path content))
+
+(defmethod extensions/create [ZooKeeper :shutdown-log]
+  [sync _ content]
+  (create-log-entry sync shutdown-log-path content))
+
 (defmethod extensions/create-node ZooKeeper
   [sync node]
   (zk/create (:conn sync) node :persistent? true))


Delete old ZooKeeper ns.

Delete old ZooKeeper ns.

--- src/onyx/sync/zookeeper.clj
+++ src/onyx/sync/zookeeper.clj
@@ -1,10 +0,0 @@
-(ns ^:no-doc onyx.sync.zookeeper
-  (:require [clojure.data.fressian :as fressian]
-            [com.stuartsierra.component :as component]
-            [taoensso.timbre]
-            [zookeeper :as zk]
-            [zookeeper.util :as util]
-            [onyx.extensions :as extensions])
-  (:import [java.util UUID]
-           [org.apache.curator.test TestingServer]))
-


Remove unused namespace. Thanks Eastwood!

--- src/open_company/config.clj
+++ src/open_company/config.clj
@@ -2,7 +2,6 @@
   "Namespace for the configuration parameters."
   (:require [clojure.walk :refer (keywordize-keys)]
             [environ.core :refer (env)]
-            [cheshire.core :as json]
             [taoensso.timbre :as timbre]
             [taoensso.timbre.appenders.core :as appenders]))


working for Testcase 0

working for Testcase 0


adding some inst metadata for synth-controller testing

--- src/overtone/inst/synth.clj
+++ src/overtone/inst/synth.clj
@@ -1,36 +1,43 @@
 (ns overtone.inst.synth
   (:use [overtone.sc gens envelope]
         [overtone.sc.machinery.ugen.fn-gen]
+        [overtone.music pitch]
         [overtone.studio rig]))

 (definst ticker [freq 880]
   (* (env-gen (perc 0.001 0.01) :action FREE)
      (sin-osc freq)))

-(definst ping [note {:default 60 :min 0 :max 120 :step 1}
-               a    {:default 0.2 :min 0.001 :max 1 :step 0.001}
-               b    {:default 0.2 :min 0.001 :max 1 :step 0.001}]
+(definst ping [note {:default 72 :min 0 :max 120 :step 1}
+               a    {:default 0.02 :min 0.001 :max 1 :step 0.001}
+               b    {:default 0.3 :min 0.001 :max 1 :step 0.001}]
   (let [snd (sin-osc (midicps note))
         env (env-gen (perc a b) :action FREE)]
-    (* env snd)))
-
-(definst tb303 [note 60 wave 1
-                cutoff 100 r 0.9
-                attack 0.101 decay 1.8 sustain 0.2 release 0.2
-                env 200 gate 0 vol 0.8]
+    (* 0.1 env snd)))
+
+(definst tb303 [note {:default 60 :min 0 :max 120 :step 1}
+                wave {:default 1 :min 0 :max 2 :step 1}
+                r {:default 0.8 :min 0.01 :max 0.99 :step 0.01}
+                attack {:default 0.01 :min 0.001 :max 4 :step 0.001}
+                decay {:default 0.1 :min 0.001 :max 4 :step 0.001}
+                sustain {:default 0.6 :min 0.001 :max 0.99 :step 0.001}
+                release {:default 0.01 :min 0.001 :max 4 :step 0.001}
+                cutoff {:default 100 :min 1 :max 20000 :step 1}
+                env-amount {:default 0.01 :min 0.001 :max 4 :step 0.001}]
   (let [freq       (midicps note)
         freqs      [freq (* 1.01 freq)]
         vol-env    (env-gen (adsr attack decay sustain release)
                             (line:kr 1 0 (+ attack decay release))
                             :action FREE)
         fil-env    (env-gen (perc))
-        fil-cutoff (+ cutoff (* env fil-env))
-        waves     [(* vol-env (saw freqs))
-                   (* vol-env [(pulse (first freqs) 0.5)
-                               (lf-tri (second freqs))])]
-        selector   (select wave (apply + waves))
+        fil-cutoff (+ cutoff (* env-amount fil-env))
+        waves     (* vol-env
+                     [(saw freqs)
+                      (pulse freqs 0.5)
+                      (lf-tri freqs)])
+        selector   (select wave waves)
         filt       (rlpf selector fil-cutoff r)]
-    filt))
+    (* 0.5 filt)))

 (definst mooger
   [note 60 amp 0.8
@@ -64,7 +71,7 @@
         echo       (comb-n reverb 0.4 0.3 0.5)]
     (* amp echo)))

-(definst pad [note 60 t 10 amt 0.3 amp 0.8 a 0.4 d 0.5 s 0.8 r 2]
+(definst pad [note 60 t 10 amt 0.3 amp 0.1 a 0.4 d 0.5 s 0.8 r 2]
   (let [freq       (midicps note)
         lfo        (+ 2 (* 0.01 (sin-osc:kr 5 (rand 1.5))))
         src        (apply + (saw [freq (* freq lfo)]))
@@ -106,12 +113,44 @@
         bounced (free-verb sliced 0.8 0.9 0.2)]
     (* env bounced)))

+
+; B3 modeled a church organ using additive synthesis of 9 sin oscillators
+; * Octave under root
+; *	Fifth over root
+; * Root
+; * Octave over root
+; * Octave and a fifth over root
+; * Two octaves over root
+; * Two octaves and a major third over root
+; * Two octaves and a fifth over root
+; * Three octaves over root
+; Work in progress...  just getting started
+(definst b3
+  [note 60 a 0.01 d 3 s 1 r 0.01]
+  (let [freq (midicps note)
+        waves (sin-osc [(* 0.5 freq)
+                        freq
+                        (* (/ 3 2) freq)
+                        (* 2 freq)
+                        (* freq 2 (/ 3 2))
+                        (* freq 2 2)
+                        (* freq 2 2 (/ 5 4))
+                        (* freq 2 2 (/ 3 2))
+                        (* freq 2 2 2)])
+        snd (apply + waves)
+        env (env-gen (adsr a d s r) :action FREE)]
+    (* env snd 0.1)))
+
 ; Experimenting with Karplus Strong synthesis...
-(definst ks1 [note 60 amp 0.8 dur 2 decay 30 coef 0.3 gate 1]
+(definst ks1 [note {:default 60 :min 10 :max 120 :step 1}
+              amp  {:default 0.8 :min 0.01 :max 0.99 :step 0.01}
+              dur  {:default 2 :min 0.1 :max 4 :step 0.1}
+              decay {:default 30 :min 1 :max 50 :step 1}
+              coef {:default 0.3 :min 0.01 :max 2 :step 0.01}]
   (let [freq (midicps note)
         noize (* 0.8 (white-noise))
         dly (/ 1.0 freq)
-        plk   (pluck noize gate (/ 1.0 freq) dly
+        plk   (pluck noize 1 (/ 1.0 freq) dly
                      decay
                      coef)
         dist (distort plk)


Fix report of board update is not respecting the schema.

--- src/oc/storage/api/boards.clj
+++ src/oc/storage/api/boards.clj
@@ -5,6 +5,7 @@
             [clojure.set :as clj-set]
             [compojure.core :as compojure :refer (ANY OPTIONS POST)]
             [liberator.core :refer (defresource by-method)]
+            [schema.core :as schema]
             [oc.lib.schema :as lib-schema]
             [oc.lib.slugify :as slugify]
             [oc.lib.db.pool :as pool]
@@ -118,12 +119,12 @@
     (let [valid-access-update? (valid-board-access-update? (:premium? ctx) (get-in org [:content-visibility :disallow-public-board])
                                                            `(:access original-board) (:access updating-board))
           updated-board (merge original-board (board-res/clean updating-board))
-          valid-updated-board? (lib-schema/valid? common-res/Board updated-board)]
+          not-valid-board-update? (schema/check common-res/Board updated-board)]
       (cond (not valid-access-update?)
             [false, {:reason :board-access-not-allowed}]
-            (not valid-updated-board?)
+            not-valid-board-update?
             [false, {:board-update (api-common/rep updated-board)
-                     :reason (api-common/rep valid-updated-board?)}]
+                     :reason (api-common/rep not-valid-board-update?)}]
             :else
             {:existing-org (api-common/rep org)
              :existing-board (api-common/rep original-board)


Corrections to bbbpin ns

Corrections to bbbpin ns

--- src/strange_coop/bbbpin.clj
+++ src/strange_coop/bbbpin.clj
@@ -143,7 +143,7 @@
     (mock-gpio header pin direction)
     (let [g (GPIO. header pin direction)]
       (init! g)
-      g))
+      g)))

 (defn on? [gp]
@@ -199,7 +199,7 @@

 (defn set-mock-val!
   [mock-ain new-value]
-  (reset! (:value mock-ain) value)
+  (reset! (:value mock-ain) new-value)
   mock-ain)

 (defn mock-ain [pin]


add button functions

add button functions

--- input.clj
+++ input.clj
@@ -23,6 +23,15 @@

 (defn key-up? [k]
 	(Input/GetKeyUp (kcode* k)))
+
+(defn button? [s]
+  (Input/GetButton s))
+
+(defn button-up? [s]
+  (Input/GetButtonUp s))
+
+(defn button-down? [s]
+  (Input/GetButtonDown s))

 (defmacro route [f & more]
 	(let [pairs (partition 2 more)]


Add load-spec & run-spec, better doc for find-spec

--- src/main/clojure/com/stuartsierra/lazytest.clj
+++ src/main/clojure/com/stuartsierra/lazytest.clj
@@ -347,43 +347,76 @@
   [x] (satisfies? TestInvokable x))

 (defn find-spec
-  "Finds and returns a spec object for a namespace, var, collection,
-  or symbol.  If x is a symbol, attempts to reload the namespace named
-  by the symbol."
+  "Finds and returns a spec for x.
+
+  If x is a ...
+
+    Var/namespace with :spec metadata: recurses on that;
+
+    Symbol: recurses on namespace with that name
+    (must be loaded already, see load-spec);
+
+    Namespace: recurses on all Vars in the namespace;
+
+    Collection: recurses on all elements;
+
+    Spec object: returns it.
+
+  otherwise returns nil."
   [x]
   (cond (spec? x) x
+
+        (:spec (meta x))
+        (find-spec (:spec (meta x)))
+
+        (symbol? x)
+        (find-spec (find-ns x))
+
+        (instance? clojure.lang.Namespace x)
+        ;; Omit the *1/*2/*3 REPL vars, in case they are specs:
+        (when-let [s (find-spec (filter #(not (#{#'*1 #'*2 #'*3} %))
+                                        (vals (ns-interns x))))]
+          (vary-meta s assoc
+                     :name (ns-name x)
+                     :comment (str "Generated from all Vars in namespace "
+                                   (ns-name x) " by find-spec.")))
+
+        (var? x)
+        (let [value (try (var-get x) (catch Exception e nil))]
+          (if (spec? value)
+            value
+            (let [m (meta x)]
+              (when-let [t (:test m)]
+                (SimpleAssertion t {:comment (str "Generated from :test metadata on "
+                                                  x " by find-spec.")
+                                    :generator `find-spec
+                                    :name (:name m)
+                                    :ns (:ns m)
+                                    :file (:file m)
+                                    :line (:line m)}
+                                 nil)))))

         (coll? x)
         (let [xs (filter identity (map find-spec x))]
           (if (seq xs)
             (SimpleContainer (vec xs)
-                             {:doc "Generated from collection by find-spec."
-                              :generator `find-spec}
+                             {:generator `find-spec
+                              :comment "Generated from collection by find-spec."}
                              nil)))

-        (instance? clojure.lang.Namespace x)
-        (if-let [t (:spec (meta x))]
-          (find-spec t)
-          ;; Omit the *1/*2/*3 REPL vars, in case they are specs:
-          (find-spec (filter #(not (#{#'*1 #'*2 #'*3} %))
-                             (vals (ns-interns x)))))
-
-        (var? x)
-        (let [m (meta x)]
-          (if-let [t (:spec m)]
-            (find-spec t)
-            (if-let [t (:test m)]
-              (SimpleAssertion t {:doc "Generated from :test function by find-spec."
-                                  :generator `find-spec
-                                  :name (:name m)
-                                  :ns (:ns m)
-                                  :file (:file m)
-                                  :line (:line m)}
-                               nil)
-              (let [v (try (var-get x) (catch Exception e nil))]
-                (when (spec? v) v)))))
-
-        (symbol? x)
-        (find-spec (find-ns x))
-
         :else nil))
+
+(defn load-spec
+  "Like find-spec but loads namespaces with require.  options will be
+  passed to require, such as :reload, or :reload-all.  Returns the
+  spec or nil if none found."
+  [sym & options]
+  (if (symbol? sym)
+    (do (apply require sym options) (load-spec sym))
+    (find-spec sym)))
+
+(defn run-spec
+  "Like load-spec but executes the specs once they are found."
+  [sym & options]
+  (when-let [s (apply load-spec sym options)]
+    (s)))


Add doc strings to 'describe' and 'it', ensure :tags becomes a set

--- src/main/clojure/com/stuartsierra/lazytest.clj
+++ src/main/clojure/com/stuartsierra/lazytest.clj
@@ -70,13 +70,39 @@
     `(def ~name (with-meta (context ~bindings ~@body)
                   '~(standard-metadata &form docstring name)))))

-(defmacro describe [& args]
+(defmacro describe
+  "Creates a description, a group of runnable examples, in the current
+  namespace.  Arguments, in order, are:
+
+    1. symbol: (optional) name of the Var that this group describes
+    2. docstring: (optional) a documentation string for this group
+    3. options: (optional) keyword-value pairs, see below
+    4. body: any number of examples, see the 'it' macro
+
+  Options are keyword-value pairs. Any options not specified here
+  become metadata on the group.
+
+    :given [name context, ...]
+
+       The :given option is followed by a vector of name-value pairs
+       that will become locals in each of the examples.  The value in
+       each pair is a context created with defcontext, the name will
+       be bound to the state returned by that context's 'before'
+       function.  Argument destructuring is supported as with 'let'.
+
+    :tags [keywords ...]
+
+       The :tags option is followed by a vector of keywords, which
+       will become tags on the group."
+  [& args]
   (let [[sym args] (get-arg symbol? args)
 	[doc args] (get-arg string? args)
 	[opts body] (get-options args)
 	contexts (seconds (:given opts))
+	tags (set (:tags opts))
 	metadata (merge (standard-metadata &form doc sym)
-			(dissoc opts :given))]
+			{:tags tags}
+			(dissoc opts :given :tags))]
     `(wrap-context ~(:given opts)
       (let [~(with-meta (gensym) {::in-describe true}) nil
 	    body# (vector ~@body)
@@ -87,10 +113,28 @@
 	  new-group#
 	  (add-group *ns* new-group#))))))

-(defmacro it [& args]
+(defmacro it
+  "Creates a test example within the body of the 'describe' macro.
+  Arguments are a documentation string (optional), followed
+  options (see below), followed by the code implementing the example.
+  The example code must return logical true to indicate success, false
+  or nil to indicate failure. A thrown exception also indicates
+  failure.
+
+  Options are keyword-value pairs. Any options not specified here
+  become metadata on the example.
+
+    :tags [keywords ...]
+
+       The :tags option is followed by a vector of keywords, which
+       will become tags on the example."
+  [& args]
   (let [[doc args] (get-arg string? args)
 	[opts body] (get-options args)
-	metadata (merge (standard-metadata &form doc) opts)]
+	tags (set (:tags opts))
+	metadata (merge (standard-metadata &form doc sym)
+			{:tags tags}
+			(dissoc opts :tags))]
     `(with-meta (fn ~(find-local-args &env) ~@body)
        '~metadata)))


Add a function to merge DataScript schemas and detect conflicts

--- src/main/workflo/macros/entity/datascript.cljc
+++ src/main/workflo/macros/entity/datascript.cljc
@@ -26,3 +26,34 @@
                 (assoc attr-name aschema))))
           {}
           (es/entity-schema entity)))
+
+(defn merge-attr-schema
+  "\"Merges\" two schemas for an attribute with the same name
+   by throwing an exception if they are different and the
+   first is not nil, and otherwise picking the second."
+  [[attr-name prev-schema] [_ next-schema]]
+  (if (nil? prev-schema)
+    next-schema
+    (if (= prev-schema next-schema)
+      next-schema
+      (let [err-msg (str "Conflicting schemas for attribute \""
+                         attr-name "\": "
+                         (pr-str prev-schema) " != "
+                         (pr-str next-schema))]
+        (throw #?(:cljs (js/Error. err-msg)
+                  :clj  (Exception. err-msg)))))))
+
+(defn merge-schemas
+  "Merge multiple DataScript schemas so that there are no
+   conflicting attributes. The default behavior is to throw
+   an exception if two schemas for the same attribute are
+   different."
+  ([schemas]
+   (merge-schemas schemas merge-attr-schema))
+  ([schemas merge-fn]
+   (reduce (fn [ret [attr-name attr-schema]]
+             (update ret attr-name
+                     (fn [existing-schema]
+                       (merge-fn [attr-name existing-schema]
+                                 [attr-name attr-schema]))))
+           {} (apply concat schemas))))


adding a user's email grants them access

--- src-cljs/frontend/components/overlay.cljs
+++ src-cljs/frontend/components/overlay.cljs
@@ -251,7 +251,7 @@
             "This document is private."]
            [:p.make
             "It's only visible to users with access."
-            " Email a teammate and notify them to request access."]
+            " Add your teammate's email to grant them access."]
            [:form.menu-invite-form.make
             {:on-submit #(do (cast! :permission-grant-submitted)
                            false)


Move entire Results section below 2nd testimonial.

--- src-cljs/frontend/components/stories.cljs
+++ src-cljs/frontend/components/stories.cljs
@@ -111,11 +111,7 @@
        [:p "CircleCI integrates natively with GitHub, which Shopify was already using, so set up time was minimal; it only took a few minutes to follow the rest of their repos on CircleCI and to invite the rest of their team members. Once their tests were running, they started optimizing their containers and parallelization from within the CircleCI app so that their test suite would run as quickly as possible. Once they had the tests running for all their projects, the next step was setting up Continuous Deployment."]
        [:p "CD has always been a core part of the engineering culture at Shopify, so getting deployment set up with CircleCI was essential. To streamline their CD process, Shopify used the CircleCI API to build a custom 'Ship It' tool that allows any developer to deploy with the press of a button, as long as they have a green build on CircleCI. All they had to do to build this was verify that the pull request in question returned \"outcome\" : \"success\" from the CircleCI API after merging with master, and then allow the developer to deploy."]
        [:p "This same functionality can also be accomplished without using the API by putting the deployment script directly into the circle.yml file."]
-
-       shared/stories-procedure
-
-       [:h2 "Results"]
-       [:p "Today, 1 year after initially switching to CircleCI, Shopify has scaled their engineering team to 130 team members who on average merge 300 pull requests and deploy 100 times per week. Thanks to CircleCI, they've managed to maintain their agile and efficient development process, with new projects being added effortlessly and everyone working off of a master branch (rather than having to maintain production and development branches). Their test suite runs faster than it ever did with their previous solution, and now that developers don't have to run tests on their local machine they can work on other projects while CircleCI runs their tests in the background. Shopify also uses CircleCI along with Capistrano to continuously deploy their application for anything from a small bug fix, to a package upgrade, to a new feature."]]]
+       shared/stories-procedure]]

      [:div.outer-section.outer-section-condensed
       common/language-background
@@ -131,6 +127,8 @@

      [:div.outer-section
       [:section.container
+       [:h2 "Results"]
+       [:p "Today, 1 year after initially switching to CircleCI, Shopify has scaled their engineering team to 130 team members who on average merge 300 pull requests and deploy 100 times per week. Thanks to CircleCI, they've managed to maintain their agile and efficient development process, with new projects being added effortlessly and everyone working off of a master branch (rather than having to maintain production and development branches). Their test suite runs faster than it ever did with their previous solution, and now that developers don't have to run tests on their local machine they can work on other projects while CircleCI runs their tests in the background. Shopify also uses CircleCI along with Capistrano to continuously deploy their application for anything from a small bug fix, to a package upgrade, to a new feature."]
        [:p "The Shopify team no longer has to worry about scaling their testing infrastructure, maintaining their test stack, or monitoring their deployments. They focus on building products that bring value to their customers while relying on CircleCI to ensure that they are able to get those products to market quickly and reliably."]]]

      (om/build story-cta "shopify")]))


Polished intro text, added images

Polished intro text, added images

--- src/ui/relevance/display.cljs
+++ src/ui/relevance/display.cljs
@@ -208,29 +208,45 @@
     ))

 (defn div-intro []
-  [:div {:class "col-sm-10 col-sm-offset-1"}
-   [:div {:class "page-header"}
-    [:h1 "Introduction"]]
-
-   [:h2 "Thanks for installing Relevance."]
-   [:p "I'm a tab-aholic. I normally do a search, start opening the tabs that seem interesting, and then as I flip through them, I end up opening even more links on tabs as they seem relevant."]
-   [:p "Next thing I know I have a huge mess of tabs, and it's hard to remember which one I've read, or which one is more relevant."]
-   [:p "I wrote Relevance to help manage that."]
-   [:p "When you install Relevance, it'll keep track of the pages you actually read, and how long you spend reading them. This information is kept completely private, on your local browser. As you open tabs, its knowledge of what's important to you grows, and when you activate it by pressing the button, the tabs  for your current window are ordered depending on how long you have spent reading them."]
-   [:p "This ordering creates a natural arrangement where the tabs you have spent the longest on, which are expected to be the most relevant, are placed first, and the ones you haven't read at all are shunted to the end."]
-   [:p "I've found this very useful in organizing what I should be focusing on."]
-   [:h2 "Preview software"]
-   [:p "Relevance is a software preview, and I'll be happy to hear your comments. If you have any suggestions on what you think might make Relevance better, "
-    [:a {:href "https://twitter.com/intent/tweet?text=Hey%20@argesric%20about%20&hashtags=relevance" :target "_blank"}
-     "please reach out on Twitter"]
-    "."
-    ]
-   [:h2 "Experimental StartPage integration"]
-   [:p "Ever ran into a situation where you re-do a search, but can't remember which ones were the most important links?"]
-   [:p "This version of Relevance has a pre-release integration with "
-    [:a {:href "https://startpage.com" :target "_blank"} "StartPage"]
-    ". After you run a search, it'll look at the results on your current page and re-prioritize the links shown to bring to the front those you have spent the longest reading."]
-   [:p "Every search engine behaves differently, so if there's enough interest, I could extend this integration to others as well."]
+  [:div
+   [:div {:class "page-header col-sm-10 col-sm-offset-1"}
+    [:h1 "Welcome!"]]
+   [:div {:class "col-sm-10 col-sm-offset-1"}
+    [:h2 "Thanks for installing Relevance"]
+    [:p "I'm a tab-aholic. I normally do a search, start opening the tabs that seem interesting, and then as I flip through them, I end up opening even more links on tabs as they seem relevant."]
+    [:p "Next thing I know I have a huge mess of tabs, and it's hard to remember which one I've read, or which one is more relevant."]
+    [:p "I wrote Relevance to help manage that."]
+    [:p "When you install Relevance, it'll keep track of the pages you actually read, and how long you spend reading them. This information is kept completely private, on your local browser. As you open tabs, its knowledge of what's important to you grows, and when you activate it by pressing the button, the tabs  for your current window are ordered depending on how long you have spent reading them."]
+    [:p "This ordering creates a natural arrangement where the tabs you have spent the longest on, which are expected to be the most relevant, are placed first, and the ones you haven't read at all are shunted to the end."]
+    [:p "I've found this very useful in organizing what I should be focusing on."]]
+   [:div {:class "col-sm-10 col-sm-offset-1"}
+    [:h2 "Preview software"]
+    [:p "Relevance is a software preview, and I'll be happy to hear your comments. If you have any suggestions on what you think might make Relevance better, "
+     [:a {:href "https://twitter.com/intent/tweet?text=Hey%20@argesric%20about%20&hashtags=relevance" :target "_blank"}
+      "please reach out on Twitter"]
+     " or "
+     [:a {:href "http://numergent.com/#contact"} "through our site"]
+     "."]]
+   [:div {:class "col-sm-10 col-sm-offset-1"}
+    [:h2 "Experimental StartPage integration"]
+    [:p "Ever ran into a situation where you re-do a search, but can't remember which ones were the most important links?"]
+    [:p "This version of Relevance has an experimental integration with "
+     [:a {:href "https://startpage.com" :target "_blank"} "StartPage"]
+     ". After you run a search, it'll look at the results on your current page and re-prioritize the links shown to bring to the front those you have spent the longest reading."]
+    [:p "Every search engine behaves differently, so if there's enough interest, I could extend this integration to others as well."]]
+   [:div
+    [:div {:class "col-sm-6"}
+     [:div {:class "col-sm-12"}
+      [:strong "Before"]]
+     [:div {:class "col-sm-12"}
+      [:img {:src "http://numergent.com/images/relevance/relevance-clojure chrome before.png"}]]
+     ]
+    [:div {:class "col-sm-6"}
+     [:div {:class "col-sm-12"}
+      [:strong "After"]]
+     [:div {:class "col-sm-12"}
+      [:img {:src "http://numergent.com/images/relevance/relevance-clojure chrome after.png"}]]
+     ]]
    ]
   )


Return 404 for non existing ships.

Return 404 for non existing ships.

--- src/viewer/controller/web.clj
+++ src/viewer/controller/web.clj
@@ -11,9 +11,10 @@
 (defn parse-xml-filename [fn]
   (rest (re-find xml-filename-pattern fn)))

-(defn xml-response [content]
+(defn xml-response [filename content]
   {:status 200
-   :headers {"Content-Type" "application/xml"}
+   :headers {"Content-Type" "application/xml"
+             "Content-Disposition" (format "attachment; filename=\"%s\"" filename)}
    :body content})

 ;;; ["/user/:id", :id #"[0-9]+"]
@@ -21,11 +22,12 @@
   (GET ["/masteries/:typeid", :typeid #"[0-9]+"] [typeid]
        (mastery-view/render (ship/ship-info (read-string typeid))
                             (mastery/all (read-string typeid))))
-  (GET ["/masteries/:shipname", :shipname #"[a-zA-Z ]+"] [shipname]
+  (GET "/masteries/:shipname" [shipname]
        (let [ship-info (ship/ship-info shipname)]
-         (mastery-view/render ship-info
-                              (mastery/all (:typeid ship-info)))))
+         (when ship-info
+           (mastery-view/render ship-info
+                                (mastery/all (:typeid ship-info))))))
   (GET "/masteries/xml/:filename" [filename]
        (let [[ship level] (parse-xml-filename filename)]
-         (xml-response (with-out-str (xml/emit-element (mastery/as-xml ship level)))))))
+         (xml-response filename (with-out-str (xml/emit-element (mastery/as-xml ship level)))))))


use gen/let instead of gen/fmap

use gen/let instead of gen/fmap

--- test/unit/todos.cljs
+++ test/unit/todos.cljs
@@ -96,8 +96,9 @@

              (if-let [available-ids (keys (:todos test-model))]
                (gen/one-of [(gen/return [:on-update-field "some-title"])
-                            (gen/fmap #(-> [:on-toggle %])
-                                      (gen/elements available-ids))])
+                            (gen/let
+                              [id (gen/elements available-ids)]
+                              [:on-toggle id])])
                (gen/return [:on-update-field "some-title"]))))

          ; given the handled signal and updated models checks if they are in expected state


adding a bit more start up prompt echoing

--- src/anyviz/core.clj
+++ src/anyviz/core.clj
@@ -16,6 +16,8 @@

 (defn read-conf [file]
   (json/parse-string (slurp (or file resource-conf)) true))
+
+(defn print-message [& msg] (apply println msg))

 (defn query-turbine [params]
   (let [query (t/create-query-from-params params)
@@ -39,9 +41,10 @@
     (-> #'routes handler/site reload/wrap-reload)))

 (defn -main [& [conf-file]]
+  (println  "starting any-viz...")
   (let [conf (read-conf conf-file)
         app (app-routes conf)
         port @g/server-port]
     (g/initialize-atoms conf)
     (run-server app {:port port :join? false})
-    (println "up and running on port:" port)))+    (print-message "any-viz up and running on port:" port "\npress Ctl+C to exit")))


Add replace and page call to example-b

Add replace and page call to example-b

--- src/aurora/ast.cljs
+++ src/aurora/ast.cljs
@@ -155,7 +155,7 @@
 (def example-b
   {"example_b" {:type :notebook
                 :id "example_b"
-               :pages ["root"]}
+                :pages ["root" "vec"]}
    "root" {:type :page
            :id "root"
            :args ["x"]
@@ -176,10 +176,24 @@
                                   :ref {:type :ref/js :js "cljs.core._"}
                                   :args [{:type :ref/id :id "a"} {:type :ref/id :id "b"}]}}
                         {:type :match/branch
-                         :pattern [{:type :match/bind :id "y" :pattern {:type :match/any}} "foo"]
+                         :pattern {"vec" {:type :match/bind :id "y" :pattern {:type :match/any}}}
                          :guards []
-                         :action {:type :constant
-                                  :data {:type :ref/id
-                                         :id "y"}}}]}})
+                         :action {:type :call
+                                  :ref {:type :ref/id :id "vec"}
+                                  :args [{:type :ref/id :id "y"}]}}]}
+   "vec" {:type :page
+          :id "vec"
+          :args ["y"]
+          :steps ["vec_result"]}
+   "vec_result" {:id "vec_result"
+                 :type :match
+                 :arg {:type :ref/id :id "y"}
+                 :branches [{:type :match/branch
+                             :pattern [{:type :match/bind :id "z" :pattern {:type :match/any}} "foo"]
+                             :guards []
+                             :action {:type :call
+                                      :ref {:type :ref/id :id "replace"}
+                                      :args [{:type :ref/id :id "z"}
+                                             "more foo!"]}}]}})

 (notebook! example-b (get example-b "example_b"))


added even/odd check to generete protocol based upon incoming port number

--- src/casper/core.clj
+++ src/casper/core.clj
@@ -84,7 +84,7 @@

              { :status http-status-created
                :header plain-text
-               :body (str "http://" server ":" port "/secret/" my-key )
+               :body (str (if (even? port) "http" "https") "://" server ":" port "/secret/" my-key )
              }
           )
           {:status http-status-bad-request


Fixed a reference to the events namespace

--- src/cia/handler.clj
+++ src/cia/handler.clj
@@ -18,6 +18,7 @@
             [cia.schemas.vocabularies :refer [ObservableType]]
             [cia.schemas.verdict :refer [Verdict]]
             [cia.events.schemas :refer [ModelEventBase]]
+            [cia.events :refer [recent-events]]
             [cia.store :refer :all]
             [ring.middleware.format :refer [wrap-restful-format]]
             [ring.util.http-response :refer :all]
@@ -387,7 +388,7 @@
       (GET "/log" []
         :return [ModelEventBase]
         :summary "Recent Event log"
-        (ok (e/recent-events))))
+        (ok (recent-events))))

     (GET "/:observable_type/:observable_value/judgements" []


might fix the  build, but probably not :/

--- test/clj/conference_rating/functional_test.clj
+++ test/clj/conference_rating/functional_test.clj
@@ -66,11 +66,20 @@
 (defn not-contains? [x coll]
   (not (some #{x} coll)))

+(defn search-for-and-navigate-to-conference [search-string]
+  (click "conference-voices-brand")
+  (wait-for "page-conference-list")
+  (taxi/click ".tt-input")
+  (taxi/send-keys ".tt-input" search-string)
+  (wait-for "conference-suggestion-template")
+  (click "conference-suggestion-template")
+  (wait-for "page-conference-detail"))
+
 (deftest ^:functional basic-journey-test
-  (let [conference-name (str "some unique conference name" (UUID/randomUUID))
-        conference-series (str "some unique series" (UUID/randomUUID))
-        conference-link "www.some-link.org"
-        conference-description "some really fancy description with a new line.\nAnd here is the new line. Wohooo!"
+  (let [conference-series (str "some unique series" (UUID/randomUUID))
+        past-conference-name (str "some unique conference name" (UUID/randomUUID))
+        past-conference-link "www.some-link.org"
+        past-conference-description "some really fancy description with a new line.\nAnd here is the new line. Wohooo!"
         future-conference-name (str "some other unique conference name" (UUID/randomUUID))]

     ; open conference voices home page
@@ -85,9 +94,9 @@
       ; adds past conference
       (wait-for "page-add-conference")
       (fill-input {"input-conference-series"      conference-series
-                   "input-conference-name"        conference-name
-                   "input-conference-link"        conference-link
-                   "input-conference-description" conference-description})
+                   "input-conference-name"        past-conference-name
+                   "input-conference-link"        past-conference-link
+                   "input-conference-description" past-conference-description})
       (fill-past-date "date-conference-from")
       (fill-past-date "date-conference-to")
       (click "button-create-conference")
@@ -95,10 +104,10 @@
       ; detail page of the newly added conference
       (wait-for "page-conference-detail")
       (is (= conference-series (s/lower-case (text "text-conference-series")))) ; different chromedrivers treat css transform differently
-      (is (= conference-name (text "text-conference-name")))
+      (is (= past-conference-name (text "text-conference-name")))
       (is (not-empty (text "text-conference-from-to-dates")))
-      (is (= conference-link (text "text-conference-link")))
-      (is (= conference-description (text "text-conference-description")))
+      (is (= past-conference-link (text "text-conference-link")))
+      (is (= past-conference-description (text "text-conference-description")))
       (is (= "This conference has not been rated yet. Be the first one to give it your voice!" (text "no-ratings-info")))

       ; adds future conference series
@@ -118,15 +127,8 @@
       (is (= future-conference-name (s/lower-case (text "text-conference-name"))))
       (is (= "This conference has not started yet and no conference of this series has been rated yet. Come back later!" (text "no-ratings-info")))

-      ;go back to conferecne list page
-      (click "conference-voices-brand")
-      (wait-for "page-conference-list")
-
-      ;search for newly created past conference
-      (taxi/click ".tt-input")
-      (taxi/send-keys ".tt-input" conference-name)
-      (wait-for "conference-suggestion-template")
-      (click "conference-suggestion-template")
+      ;search for and navigate to newly created past conference
+      (search-for-and-navigate-to-conference past-conference-name)

       ; add rating to newly created past conference
       (click "button-add-new-rating")
@@ -138,31 +140,16 @@
       (wait-for "page-conference-detail")
       (taxi/wait-until #(= "1" (text "text-icon-panel-number")))

-      ;go back to conferecne list page
-      (click "conference-voices-brand")
-      (wait-for "page-conference-list")
-
       ; searches for and navigates to the future conference of the series
-      (taxi/click ".tt-input")
-      (taxi/send-keys ".tt-input" future-conference-name)
-      (wait-for "conference-suggestion-template")
-      (click "conference-suggestion-template")
+      (search-for-and-navigate-to-conference future-conference-name)

       ; checks that the rating is also visible to the future conference of the same series
-      (wait-for "page-conference-detail")
       (is (= conference-series (s/lower-case (text "text-conference-series")))) ; different chromedrivers treat css transform differently
       (is (= future-conference-name (s/lower-case (text "text-conference-name"))))
       (is (= (str "Note: This ratings are aggregated from ratings of previous " conference-series " conferences.") (text "aggregated-ratings-info")))

-      ;go back to conferecne list page
-      (click "conference-voices-brand")
-      (wait-for "page-conference-list")
-
-      ;search for newly created past conference
-      (taxi/click ".tt-input")
-      (taxi/send-keys ".tt-input" conference-name)
-      (wait-for "conference-suggestion-template")
-      (click "conference-suggestion-template")
+      ;search for and navigate to newly created past conference
+      (search-for-and-navigate-to-conference past-conference-name)

       ; edits past conference
       (wait-for "page-conference-detail")
@@ -181,13 +168,10 @@

       ; back to the conference list page and checks that conference is gone
       (wait-for "page-conference-list")
-      (is (not-contains? conference-name (texts "text-conference-name")))
+      (is (not-contains? past-conference-name (texts "text-conference-name")))

       ; searches for and navigates to the future conference of the series
-      (taxi/click ".tt-input")
-      (taxi/send-keys ".tt-input" future-conference-name)
-      (wait-for "conference-suggestion-template")
-      (click "conference-suggestion-template")
+      (search-for-and-navigate-to-conference future-conference-name)

       ; checks that future conference does not have aggregated ratings anymore
       (wait-for "page-conference-detail")


(PDB-4934) Add unit test for write database connection pools.

--- test/puppetlabs/puppetdb/cli/services_test.clj
+++ test/puppetlabs/puppetdb/cli/services_test.clj
@@ -548,7 +548,7 @@
                         (set (get-temporal-partitions "resource_events")))))))))))))

 (deftest initialize-db
-  (testing "use connection user for database connections"
+  (testing "when establishing migration database connections"
     (let [con-mig-user "conn-migration-user-value"
           mig-pass     "migrator-password-value"
           user         "user-value"
@@ -562,10 +562,22 @@
                           (throw (Exception.
                                    "everything ok exception")))]
       (with-redefs [jdbc/make-connection-pool validation-fn]
-        (testing "should use connection user"
+        (testing "should use connection migrator user"
           (is (thrown-with-msg?
                 Exception #"everything ok exception"
                 (init-with-db "test-db" {:connection-migrator-username con-mig-user
                                          :migrator-password            mig-pass
                                          :user                         user
                                          :password                     pass}))))))))
+
+(deftest initialize-write-dbs
+  (testing "when establishing write database connections"
+    (let [connection-username "conn-user-value"
+          databases {"default-database" , {:connection-username connection-username}}
+          validation-fn (fn [options metrics-registry]
+                          (is (= connection-username (:user options)))
+                          )
+          ]
+      (with-redefs [jdbc/pooled-datasource validation-fn]
+        (testing "should use connection user"
+          (init-write-dbs databases))))))


Removed print

Removed print

--- src/wombats/handlers/auth.clj
+++ src/wombats/handlers/auth.clj
@@ -92,8 +92,6 @@
            web-client-redirect (remove-slash (get-in request [:headers "referer"]))
            failed-callback (redirect-home context web-client-redirect)]

-       (prn web-client-redirect)
-
        (if (= state signing-secret)
          (let [access-token @(get-access-token {:client_id client-id
                                                 :client_secret client-secret


test/riemann/xymon_test.clj: updated test file according to previous commits

--- test/riemann/xymon_test.clj
+++ test/riemann/xymon_test.clj
@@ -6,7 +6,7 @@

 (logging/init)

-(deftest ^:xymon-format format-line-test
+(deftest ^:xymon-format event->status-test
   (let [pairs [[{}
                 "status . unknown \n"]
                [{:host "foo" :service "bar"}
@@ -28,7 +28,7 @@
                [{:host "example.com" :service "some.metric rate" :state "ok"}
                 "status example,com.some_metric_rate ok \n"]]]
     (doseq [[event line] pairs]
-      (is (= line (format-line event))))))
+      (is (= line (event->status event))))))

 (deftest ^:xymon ^:integration xymon-test
          (let [k (xymon nil)]


Added a couple of long lasting acceptance scenarios

--- test/civs/acceptance_test.clj
+++ test/civs/acceptance_test.clj
@@ -53,8 +53,8 @@
           g (reduce (fn [g _] (turn g)) g0 (repeat nturns :_))
           final-pop (game-total-pop g)]
       (when verbose-acceptance-tests
-        (println (.toString biome) " scenario: initial population " start-pop)
-        (println (.toString biome) " scenario: final population "   final-pop))
+        (println (.toString biome) "scenario: initial population" start-pop)
+        (println (.toString biome) "scenario: final population"   final-pop "after" nturns "turns"))
       (is (> final-pop (* start-pop min-factor)))
       (is (< final-pop (* start-pop max-factor))))))

@@ -76,3 +76,9 @@
 ; We do not want to drop too drammatically and it should not increase too much
 (deftest test-population-in-a-jungle
   (check-biome com.github.lands.Biome/JUNGLE 0.9 1.7 30 10))
+
+(deftest test-long-lasting-population-in-grassland
+  (check-biome com.github.lands.Biome/GRASSLAND 2.0 1000.0 50 100))
+
+(deftest test-long-lasting-population-in-savanna
+  (check-biome com.github.lands.Biome/SAVANNA 0.8 10.0 50 100))


await kafka shutdown to minimise errors reported in logs

--- test/clj_kafka/test/utils.clj
+++ test/clj_kafka/test/utils.clj
@@ -69,5 +69,6 @@
            (wait-until-initialised kafka# topic#))
          (try ~@body
               (finally (do (.shutdown kafka#)
+                           (.awaitShutdown kafka#)
                            (.shutdown zk#)
                            (FileUtils/deleteDirectory (file (tmp-dir)))))))))


Add a failing test for equality between fn calls

--- test/desdemona/query_test.clj
+++ test/desdemona/query_test.clj
@@ -23,7 +23,16 @@
                   [:identifier "x"]]
                  [:ipv4-address "10" "0" "0" "1"]]]
          (#'q/infix-parser "ip(x) = 10.0.0.1"))
-      "equality between fn call and IP address literal"))
+      "equality between fn call and IP address literal")
+  (is (= [:expr [:eq
+                 [:fn-call
+                  [:identifier "ip"]
+                  [:identifier "x"]]
+                 [:fn-call
+                  [:identifier "ip"]
+                  [:identifier "y"]]]]
+         (#'q/infix-parser "ip(x) = ip(y)"))
+      "equality between two fn calls"))

 (deftest infix->dsl-tests
   (is (= '(= (:ip x) "10.0.0.1")


refine before-validation

refine before-validation

--- src/clj/clj_money/models/transactions.clj
+++ src/clj/clj_money/models/transactions.clj
@@ -6,6 +6,7 @@
             [clojure.tools.logging :as log]
             [clj-time.core :as t]
             [clj-money.util :refer [pprint-and-return
+                                    pprint-and-return-l
                                     ensure-local-date]]
             [clj-money.coercion :as coercion]
             [clj-money.validation :as validation]
@@ -187,14 +188,14 @@
   "Performs operations required before validation"
   [transaction]
   (-> transaction
+      expand-simplified-items
       (coercion/coerce coercion-rules)
-      expand-simplified-items
       (update-in [:items] (fn [items]
                             (->> items
-                                 (map #(assoc % :transaction-date
-                                                (:transaction-date transaction)
-                                                :original-transaction-date
-                                                (:original-transaction-date transaction)))
+                                 (map #(merge % (select-keys
+                                                  transaction
+                                                  [:transaction-date
+                                                   :origin-transaction-date])))
                                  (map before-item-validation))))))

 (defn- after-validation


CEO-202 Remove sorting

CEO-202 Remove sorting

--- src/clj/collect_earth_online/db/plots.clj
+++ src/clj/collect_earth_online/db/plots.clj
@@ -91,27 +91,27 @@
                           "natural"    (concat (call-sql "select_unanalyzed_plots" project-id user-id admin-mode?)
                                                (call-sql "select_analyzed_plots" project-id user-id admin-mode?))
                           [])
-        sorted-plots    (sort-by first (group-by :visible_id proj-plots))
+        grouped-plots    (group-by :visible_id proj-plots)
         plots-info      (case direction
                           "next"     (or (some (fn [[plot-id plots]]
                                                  (and (> plot-id visible-id)
                                                       plots))
-                                               sorted-plots)
-                                         (->> sorted-plots
+                                               grouped-plots)
+                                         (->> grouped-plots
                                               (first)
                                               (second)))
-                          "previous" (or (->> sorted-plots
+                          "previous" (or (->> grouped-plots
                                               (sort-by first #(compare %2 %1))
                                               (some (fn [[plot-id plots]]
                                                       (and (< plot-id visible-id)
                                                            plots))))
-                                         (->> sorted-plots
+                                         (->> grouped-plots
                                               (last)
                                               (second)))
                           "id"       (some (fn [[plot-id plots]]
                                              (and (= plot-id visible-id)
                                                   plots))
-                                           sorted-plots))]
+                                           grouped-plots))]
     (if plots-info
       (do
         (unlock-plots user-id)


Fix react-key warnings on stop search results

--- src/cljs/gtfve/components/side_panel.cljs
+++ src/cljs/gtfve/components/side_panel.cljs
@@ -26,34 +26,52 @@
          (when active? "active")
          (when in? "in")]))

+(defn stop-search-result [data owner]
+  (reify
+    om/IDisplayName (display-name [_] "Stop Search Result")
+    om/IRender
+    (render [_]
+      (html
+       [:a.list-group-item
+        {:href "#"
+         :on-click #(do
+                      (raise! owner [:stops-search-result-clicked {:stop data}])
+                      (.preventDefault %))}
+        [:h5.list-group-item-heading (:stop/name data)]
+        [:p.list-group-item-text (str (:stop/latitude data)
+                                      "/"
+                                      (:stop/longitude data))]]))))
+
 (defn stop-search-results [{:keys [data query loading?]} owner]
   (reify
     om/IDisplayName (display-name [_] "Stop Search Results")
     om/IRender
     (render [_]
       (html
-       (cond
-         loading? [:div
-                   [:p.label.label-primary "Loading ..."]
-                   [:div.progress.progress-striped.active
-                    [:div.progress-bar {:style {:width "100%"}}]]]
-         (empty? query) nil
-         (empty? data) [:div.alert.alert-danger
-                        [:p "No stops found matching "
-                         [:i query]]]
-         :else (into [:div.list-group]
-                     (map (fn [stop]
-                            [:a.list-group-item
-                             {:react-key (:db/id stop)
-                              :href "#"
-                              :on-click #(do
-                                           (raise! owner [:stops-search-result-clicked {:stop stop}])
-                                           (.preventDefault %))}
-                             [:h5.list-group-item-heading (:stop/name stop)]
-                             [:p.list-group-item-text (str (:stop/latitude stop)
-                                                           "/"
-                                                           (:stop/longitude stop))]])
-                          data)))))))
+       (if loading?
+         [:div
+          [:p.label.label-primary "Loading ..."]
+          [:div.progress.progress-striped.active
+           [:div.progress-bar {:style {:width "100%"}}]]]
+         (if (empty? query)
+           nil
+           (if (empty? data)
+             [:div.alert.alert-danger
+              [:p "No stops found matching "
+               [:i query]]]
+             (into [:div.list-group]
+                   (om/build-all stop-search-result data {:key :db/id})))))
+       #_(cond ;; cond causes react-key warnings
+           loading? [:div
+                     [:p.label.label-primary "Loading ..."]
+                     [:div.progress.progress-striped.active
+                      [:div.progress-bar {:style {:width "100%"}}]]]
+           (empty? query) nil
+           (empty? data) [:div.alert.alert-danger
+                          [:p "No stops found matching "
+                           [:i query]]]
+           :else (into [:div.list-group]
+                       (om/build-all stop-search-result data {:key :db/id})))))))

 (defn stop-panel [{:keys [tab ui data active? in?]} owner]
   (reify


Share project object.

Share project object.

--- src/cljs/hatnik/web/client/z_actions.cljs
+++ src/cljs/hatnik/web/client/z_actions.cljs
@@ -29,10 +29,11 @@
     (.modal ($ :#iModalProjectMenu) "hide")))

 (defn send-new-project-request [name]
-  (if (s/check schm/Project {:name name
-                             :type "regular"})
-    (msg/danger default-error-message)
-    (u/ajax "/api/projects" "POST" {:name name} #(create-new-project-callback name %))))
+  (let [project {:name name
+                 :type "regular"}]
+    (if (s/check schm/Project project)
+      (msg/danger default-error-message)
+      (u/ajax "/api/projects" "POST" project #(create-new-project-callback name %)))))

 (defn create-new-action-callback [data response]
   (when (= "ok" (:result response))


Make linters happy

Make linters happy

--- src/icecap/rest.clj
+++ src/icecap/rest.clj
@@ -42,9 +42,13 @@
 (defroutes routes
   (context "/v0/caps" {store :store kdf :kdf scheme :scheme}
            (POST "/" {plan :body-params :as request}
-                 (let [{cap :cap} (<!! (create-cap plan :store store :kdf kdf :scheme scheme))
+                 (let [{cap :cap} (<!! (create-cap plan
+                                                   :store store
+                                                   :kdf kdf
+                                                   :scheme scheme))
                        encoded-cap (safebase64-encode cap)
-                       url (str "http://" (:server-name request) ":" (:port request)
+                       url (str "http://"
+                                (:server-name request) ":" (:port request)
                                 (:uri request) "/" encoded-cap)]
                    {:body {:cap encoded-cap :url url}}))
            (context "/:encoded-cap" [encoded-cap]


Export to XML

Export to XML

--- src/emender_jenkins/metadata_exporter.clj
+++ src/emender_jenkins/metadata_exporter.clj
@@ -28,6 +28,12 @@
     (for [column columns]
     (-> (clojure.string/replace column " " "_")
         keyword)))
+
+(defn column->xml-key
+    [columns]
+    (for [column columns]
+    (-> (clojure.string/replace column " " "_")
+        clojure.string/lower-case)))

 (defn mix-columns-with-data
     [columns data function]
@@ -76,6 +82,18 @@
     (-> (mix-columns-with-data columns data column->keyword)
         data->edn))

+(defn export2xml
+    [columns data]
+    (with-out-str
+        (xml/emit {:tag "jobs" :content
+            (for [item data]
+                {:tag :job-metadata
+                 :attrs   {:name (first item)}
+                 :content
+                     (for [z (zipmap (column->xml-key columns) item)]
+                         {:tag (key z) :content [(str (val z))]}
+                         )})})))
+
 (defn export
     [columns data output-format]
     (case output-format
@@ -83,5 +101,5 @@
         :edn   (export2edn columns data)
         :csv   (export2csv columns data)
         :txt   (export2txt columns data)
-        :xml   nil))
+        :xml   (export2xml columns data)))


Doseq again

Doseq again

--- src/korhal/core.clj
+++ src/korhal/core.clj
@@ -58,7 +58,7 @@
         (swap-keys (.state this) :morphed-drone true))))

   ;; collect minerals
-  (for [unit (.getMyUnits (:api @(.state this)))]
+  (doseq [unit (.getMyUnits (:api @(.state this)))]
     (when (= (.getTypeID unit) (.getID jnibwapi.types.UnitType$UnitTypes/Zerg_Drone))
       (when (and (.isIdle unit) (not (= (.getID unit) (:pool-drone @(.state this)))))
         (let [mineral? (fn [unit] (= (.getTypeID unit) (.getID jnibwapi.types.UnitType$UnitTypes/Resource_Mineral_Field)))


Solved 5.7

Solved 5.7

--- src/fpinscala/strictness_and_laziness.clj
+++ src/fpinscala/strictness_and_laziness.clj
@@ -80,7 +80,7 @@
       (stream-cons value (my-take-while-fpins f (rest s))))))
 ;-----------------------------------------------------------------------

-;auxiliary - direct translation from book
+;auxiliary - direct translation from book - WARNING! IT IS NOT REALLY LAZY as I am currently not sure how to mimic named/lazy params
 (defn fold-right [z f s]
   (let [[h & t] s]
     (if h
@@ -129,3 +129,26 @@
 ;fpins
 ;conceptually the same - woo-hoo :)
 ;-----------------------------------------------------------------------
+
+;5.7
+;mine
+(defn map-fr
+  "map via f-r"
+  [f s]
+  (fold-right '() #(conj %2 (f %)) s))
+(defn filter-fr
+  "filter via f-r"
+  [p s]
+  (fold-right '() #(if (p %) (conj %2 %) %2) s))
+(defn append-fr
+  "append via f-r"
+  [sl sr]
+  (fold-right sr #(conj %2 %) sl))
+(defn flat-map-fr
+  "flatMap via f-r"
+  [f s]
+  (fold-right '() #(append-fr (f %) %2) s))
+;fpins
+;all conceptually the same with exception that I simply translated flat-map by accident :)
+;furthermore I have had incorrect order due to argument swapping
+;-----------------------------------------------------------------------


I need an easy way to produce a rollbar stack

--- frontend/core.cljs
+++ frontend/core.cljs
@@ -273,6 +273,10 @@
 (defn ^:export toggle-admin []
   (swap! debug-state update-in [:current-user :admin] not))

+(defn ^:export explode []
+  (swallow-errors
+    (assoc [] :deliberate :exception)))
+
 (defn ^:export set-ab-test
   "Debug function for setting ab-tests, call from the js console as frontend.core.set_ab_test('new_test', false)"
   [test-name value]


DM + RS | 153 | Add test to check that token expiry time is set correctly

--- test/stonecutter/test/jwt.clj
+++ test/stonecutter/test/jwt.clj
@@ -19,16 +19,26 @@
     {:sub (.getSubject claims-set)
      :iss (.getIssuer claims-set)
      :aud (.getAudience claims-set)
+     :iat (-> claims-set .getIssuedAt .getValue)
+     :exp (-> claims-set .getExpirationTime .getValue)
      :email (.getClaimValue claims-set "email")}))

-(fact "id tokens can be generated and signed"
-      (let [rsa-key-pair (doto (RsaJwkGenerator/generateJwk 2048)
-                           (.setKeyId  "k1"))
-            id-token-generator (jwt/create-generator rsa-key-pair)
-            id-token (id-token-generator iss sub aud token-lifetime-minutes email)]
-        (:sub (decode rsa-key-pair aud id-token)) => sub
-        (:iss (decode rsa-key-pair aud id-token)) => iss
-        (:aud (decode rsa-key-pair aud id-token)) => [aud]
-        (:email (decode rsa-key-pair aud id-token)) => email))
+(facts "about generating id tokens"
+       (let [rsa-key-pair (doto (RsaJwkGenerator/generateJwk 2048)
+                            (.setKeyId  "k1"))
+             id-token-generator (jwt/create-generator rsa-key-pair)
+             id-token (id-token-generator iss sub aud token-lifetime-minutes email)]
+         (fact "id tokens can be generated and signed"
+               (:sub (decode rsa-key-pair aud id-token)) => sub
+               (:iss (decode rsa-key-pair aud id-token)) => iss
+               (:aud (decode rsa-key-pair aud id-token)) => [aud]
+               (:email (decode rsa-key-pair aud id-token)) => email)
+
+         (fact "token expiry time is set correctly, based on token lifetime in minutes"
+               (let [decoded-token (decode rsa-key-pair aud id-token)
+                     issued-at (:iat decoded-token)
+                     expiry (:exp decoded-token)
+                     token-lifetime-in-seconds (* 60 token-lifetime-minutes)]
+                 (- expiry issued-at) => token-lifetime-in-seconds))))


Fix the result-binding in compiler

Fix the result-binding in compiler

When destructuring and a result binding was used, the compiler
incorrectly assigned the result-binding from the implicit 'this
binding (which didn't exist).

--- src/main/clojure/clara/rules/compiler.clj
+++ src/main/clojure/clara/rules/compiler.clj
@@ -195,7 +195,7 @@
                            '?__env__)

         ;; Initial bindings used in the return of the compiled condition expresion.
-        initial-bindings (if result-binding {result-binding 'this}  {})]
+        initial-bindings (if result-binding {result-binding '?__fact__}  {})]

     `(fn [~(if (symbol? type)
              (with-meta


handler.clj: don't assert :response_body_bytes key

Handler still works with just :response_body_base64

--- src/org/altlaw/extract/scrape/handler.clj
+++ src/org/altlaw/extract/scrape/handler.clj
@@ -12,7 +12,6 @@
 (defn run-scrapers [download]
   (assert (map? download))
   (assert (contains? download :request_uri))
-  (assert (contains? download :response_body_bytes))
   (map ruby/convert-jruby
        (ruby/eval-jruby "$handler.parse(Download.from_map($download))"
                         {:download (walk/stringify-keys download)


(PDB-5022) benchmark/close-buf: avoid eastwood complaint via fn

--- src/puppetlabs/puppetdb/cli/benchmark.clj
+++ src/puppetlabs/puppetdb/cli/benchmark.clj
@@ -352,6 +352,15 @@

 (def benchmark-shutdown-timeout 5000)

+(defn go-delete-dir-or-report [storage-dir]
+  ;; This function only exists to work around an eastwood complaint
+  ;; seen when the body was inline in the caller:
+  ;;
+  ;;   Exception thrown during phase :analyze+eval of linting namespace ...
+  ;;   Local name 'G__35008' has been given a type tag 'null' here:
+  ;;   nil
+  (go (delete-dir-or-report storage-dir)))
+
 (deftype TempFileBuffer [storage-dir q]
   Buffer
   (full? [this] false)
@@ -373,7 +382,7 @@
     (println-err (trs "Cleaning up temp files from {0}"
                       (pr-str (str storage-dir))))
     (async/alt!!
-      (go (delete-dir-or-report storage-dir))
+      (go-delete-dir-or-report storage-dir)
       (println-err (trs "Finished cleaning up temp files"))

       (async/timeout benchmark-shutdown-timeout)


Updated Kudos address to reflect latest contract

Signed-off-by: Julien Eluard <c768e13f1ba4c3ebed2909a1fc1e4b50bb021a2f@gmail.com>

--- src/status_im/utils/ethereum/tokens.cljs
+++ src/status_im/utils/ethereum/tokens.cljs
@@ -453,7 +453,7 @@
                    {:symbol  :KDO
                     :nft?    true
                     :name    "KudosToken"
-                    :address "0x56c72cda0b04fc39a25d0b6a64fa258fad46d664"}])
+                    :address "0x2aea4add166ebf38b63d09a75de1a7b94aa24163"}])
    :testnet
    (resolve-icons :testnet
                   [{:name     "Status Test Token"


Add force, conversions and typical

Add force, conversions and typical

--- src/test_utils/fracture_diagnostics.cljc
+++ src/test_utils/fracture_diagnostics.cljc
@@ -4,6 +4,7 @@

 (def physical-quantities [:densty
                           :energy
+                          :force
                           :length
                           :mass
                           :pressure
@@ -18,6 +19,7 @@
 (defn rand-unit [physical-quantity]
   (let [quantity-units-map {:density                [:lb-per-cu-ft :kg-per-m3]
                             :energy                 [:ft-lb :J]
+                            :force                  [:lbf :N]
                             :length                 [:ft :m]
                             :mass                   [:lb :kg]
                             :pressure               [:psi :kPa]
@@ -29,6 +31,7 @@

 (def rand-density-unit (rand-unit :density))
 (def rand-energy-unit (rand-unit :energy))
+(def rand-force-unit (rand-unit :force))
 (def rand-length-unit (rand-unit :length))
 (def rand-mass-unit (rand-unit :mass))
 (def rand-pressure-unit (rand-unit :pressure))
@@ -40,6 +43,7 @@
 (defn convert-units-f [from to]
   (let [factors   {[:lb-per-cu-ft :kg-per-m3] 16.0185
                    [:ft-lb :J]                1.35582
+                   [:lbf :N]                  4.44822
                    [:m :ft]                   3.28084
                    [:kg :lb]                  2.20462262185
                    [:psi :kPa]                6.894757293168361
@@ -50,6 +54,8 @@
                    [:kg-per-m3 :lb-per-cu-ft] #(/ % (factors [:lb-per-cu-ft :kg-per-m3]))
                    [:ft-lb :J]                #(* % (factors [:ft-lb :J]))
                    [:J :ft-lb]                #(/ % (factors [:ft-lb :J]))
+                   [:lbf :N]                  #(* % (factors [:lbf :N]))
+                   [:N :lbf]                  #(/ % (factors [:lbf :N]))
                    [:ft :m]                   #(/ % (factors [:m :ft]))
                    [:m :ft]                   #(* % (factors [:m :ft]))
                    [:lb :kg]                  #(/ % (factors [:kg :lb]))
@@ -559,3 +565,19 @@
    (condp = energy-unit
      :ft-lb [:ft-lb (tuc/draw-normal 4.340741e10 1.443922e10)]
      :J     [:J (tuc/draw-normal 14670.972535 5275.739520)])))
+
+(defn typical-force
+  ([] (typical-force (rand-force-unit)))
+  ([force-unit]
+   ;; Retrieved from http://www.excoresources.com/appalachia/ and
+   ;; https://en.wikipedia.org/wiki/Casing_string on 28-Dec-2020.
+   (let [typical-casing-outer-diameter-inches (+ 5 (/ 1 2))
+         typical-casing-pipe-witdth-inches    0.545
+         typical-casing-inner-diameter-inches (- typical-casing-outer-diameter-inches
+                                                 typical-casing-pipe-witdth-inches)
+         typical-casing-area-sq-inches        (* 2 Math/PI (/ typical-casing-inner-diameter-inches 2))
+         typical-pressure-psi                 (typical-surface-treating-pressure :psi)
+         typical-force-lbf                    (* typical-pressure-psi typical-casing-area-sq-inches)]
+     (condp = force-unit
+       :lbf [typical-force-lbf force-unit]
+       :N   [((convert-units-f :lbf :N) typical-force-lbf) force-unit]))))


hard.physics/range-hits fn

hard.physics/range-hits fn

--- physics.clj
+++ physics.clj
@@ -31,6 +31,9 @@
 (defn hits [^Vector3 a ^Vector3 b]
   (map #(aget hit-buff %) (range (hit* a b))))

+(defn range-hits [^Vector3 a ^Vector3 b ^System.Double len]
+  (map #(aget hit-buff %) (range (hit* a b len))))
+
 #_(reduce v3+ (map #(.point %)  (hits (v3) (v3 0 -1 0))))

 (defn gravity [] (Physics/gravity))


Report fatal error on bad CSV

Report fatal error on bad CSV

It used to crash the processing and not report why.

--- src/vip/data_processor/validation/csv.clj
+++ src/vip/data_processor/validation/csv.clj
@@ -57,59 +57,62 @@
   (if-let [file-to-load (find-input-file ctx filename)]
     (do
       (log/info "Loading" filename)
-      (with-open [in-file (util/bom-safe-reader file-to-load :encoding "UTF-8")]
-        (let [headers (->> in-file
-                           read-one-line
-                           (map #(clojure.string/replace % #"\W" "")))
-              headers-count (count headers)
-              sql-table (get-in ctx [:tables table])
-              column-names (map :name columns)
-              required-header-names (->> columns
-                                         (filter :required)
-                                         (map :name))
-              extraneous-headers (seq (set/difference (set headers) (set column-names)))
-              transforms (apply comp (data-spec/translation-fns columns))
-              format-rules (data-spec/create-format-rules (:data-specs ctx) filename columns)
-              ctx (if extraneous-headers
-                    (assoc-in ctx [:warnings table :global :extraneous-headers]
-                              extraneous-headers)
-                    ctx)
-              line-number (atom 1)]
-          (if (empty? (set/intersection (set headers) (set column-names)))
-            (assoc-in ctx [:critical table :global :no-header] ["No header row"])
-            (if-let [missing-headers (seq (set/difference (set required-header-names) (set headers)))]
-              (assoc-in ctx [:critical table :global :missing-headers] missing-headers)
-              (reduce (fn [ctx chunk]
-                        (if (seq chunk)
-                          (let [ctx (reduce (fn [ctx row]
-                                              (swap! line-number inc)
-                                              (let [row-map (zipmap headers row)
-                                                    row-count (count row)
-                                                    ctx (data-spec/apply-format-rules format-rules ctx row-map @line-number)]
-                                                (if (= headers-count row-count)
-                                                  ctx
-                                                  (assoc-in ctx [:critical table @line-number :number-of-values]
-                                                            [(str "Expected " headers-count
-                                                                  " values, found " row-count)]))))
-                                            ctx chunk)
-                                chunk-values (map (comp transforms #(select-keys % column-names) (partial zipmap headers)) chunk)
-                                chunk-values (if (= "postgresql" (get-in sql-table [:db :options :subprotocol]))
-                                               (->> chunk-values
-                                                    (data-spec/coerce-rows columns)
-                                                    (map #(assoc % "results_id" (:import-id ctx))))
-                                               chunk-values)]
-                            (try
-                              (korma/insert sql-table (korma/values chunk-values))
-                              ctx
-                              (catch java.sql.SQLException e
-                                (let [message (.getMessage e)]
-                                  (if (re-find #"UNIQUE constraint failed: (\w+).id" message)
-                                    (db.util/retry-chunk-without-dupe-ids ctx sql-table chunk-values)
-                                    (assoc-in ctx [:fatal (:name sql-table) @line-number :unknown-sql-error]
-                                              [message]))))))
-                          ctx))
-                      ctx (db.util/chunk-rows (csv/read-csv in-file)
-                                              sqlite/statement-parameter-limit)))))))
+      (try
+        (with-open [in-file (util/bom-safe-reader file-to-load :encoding "UTF-8")]
+          (let [headers (->> in-file
+                             read-one-line
+                             (map #(clojure.string/replace % #"\W" "")))
+                headers-count (count headers)
+                sql-table (get-in ctx [:tables table])
+                column-names (map :name columns)
+                required-header-names (->> columns
+                                           (filter :required)
+                                           (map :name))
+                extraneous-headers (seq (set/difference (set headers) (set column-names)))
+                transforms (apply comp (data-spec/translation-fns columns))
+                format-rules (data-spec/create-format-rules (:data-specs ctx) filename columns)
+                ctx (if extraneous-headers
+                      (assoc-in ctx [:warnings table :global :extraneous-headers]
+                                extraneous-headers)
+                      ctx)
+                line-number (atom 1)]
+            (if (empty? (set/intersection (set headers) (set column-names)))
+              (assoc-in ctx [:critical table :global :no-header] ["No header row"])
+              (if-let [missing-headers (seq (set/difference (set required-header-names) (set headers)))]
+                (assoc-in ctx [:critical table :global :missing-headers] missing-headers)
+                (reduce (fn [ctx chunk]
+                          (if (seq chunk)
+                            (let [ctx (reduce (fn [ctx row]
+                                                (swap! line-number inc)
+                                                (let [row-map (zipmap headers row)
+                                                      row-count (count row)
+                                                      ctx (data-spec/apply-format-rules format-rules ctx row-map @line-number)]
+                                                  (if (= headers-count row-count)
+                                                    ctx
+                                                    (assoc-in ctx [:critical table @line-number :number-of-values]
+                                                              [(str "Expected " headers-count
+                                                                    " values, found " row-count)]))))
+                                              ctx chunk)
+                                  chunk-values (map (comp transforms #(select-keys % column-names) (partial zipmap headers)) chunk)
+                                  chunk-values (if (= "postgresql" (get-in sql-table [:db :options :subprotocol]))
+                                                 (->> chunk-values
+                                                      (data-spec/coerce-rows columns)
+                                                      (map #(assoc % "results_id" (:import-id ctx))))
+                                                 chunk-values)]
+                              (try
+                                (korma/insert sql-table (korma/values chunk-values))
+                                ctx
+                                (catch java.sql.SQLException e
+                                  (let [message (.getMessage e)]
+                                    (if (re-find #"UNIQUE constraint failed: (\w+).id" message)
+                                      (db.util/retry-chunk-without-dupe-ids ctx sql-table chunk-values)
+                                      (assoc-in ctx [:fatal (:name sql-table) @line-number :unknown-sql-error]
+                                                [message]))))))
+                            ctx))
+                        ctx (db.util/chunk-rows (csv/read-csv in-file)
+                                                sqlite/statement-parameter-limit))))))
+        (catch java.lang.Exception e
+          (update-in ctx [:fatal filename :global :csv-error] conj (.getMessage e)))))
     ctx))

 (defn-traced load-csvs [ctx]


at least log an error when delete-file fails

I could fix the issue by forcing an out of memory error since that also
forces garbage collection. But I'm not ready for that yet...

see #117 and #138

--- boot/pod/src/boot/file.clj
+++ boot/pod/src/boot/file.clj
@@ -29,9 +29,16 @@
 (defmacro guard [& exprs]
   `(try (do ~@exprs) (catch Throwable _#)))

+(defn delete-file
+  [f]
+  (try
+    (io/delete-file f)
+    (catch Exception err
+      (println "ERROR deleting" f err))))
+
 (defn clean! [& files]
   (doseq [f files]
-    (doall (->> f io/file file-seq (keep file?) (map #(io/delete-file % true))))))
+    (doall (->> f io/file file-seq (keep file?) (map delete-file)))))

 (defn empty-dir!
   [& dirs]
@@ -40,14 +47,14 @@
              (mapcat (comp rest file-seq))
              (group-by (memfn isFile)))
         to-rm (concat files (reverse dirs'))]
-    (doseq [f to-rm] (io/delete-file f true))))
+    (doseq [f to-rm] (delete-file f))))

 (defn delete-empty-subdirs!
   [dir]
   (let [empty-dir? #(and (.isDirectory %) (empty? (.list %)))
         subdirs    (->> dir io/file file-seq (filter (memfn isDirectory)))]
     (doseq [f (reverse subdirs)]
-      (when (empty-dir? f) (io/delete-file f true)))))
+      (when (empty-dir? f) (delete-file f)))))

 (defn- contains-files?
   [dir]
@@ -161,7 +168,7 @@
         after  (apply tree-for srcs)]
     (doseq [[op p x] (patch pred before after)]
       (case op
-        :rm (io/delete-file x true)
+        :rm (delete-file x)
         :cp (copy-with-lastmod x (io/file dest p))))))

 (defn watcher! [pred & dirs]


into-atom! functino

into-atom! functino

--- browser/cljs/settings.cljs
+++ browser/cljs/settings.cljs
@@ -3,21 +3,6 @@
           [mediakeys.browser.rx :only [from-async multi-sub]])
     (:require [rx-cljs.observable :as rx]))

-
-; (def print #(.log js/console %))
-; (subscribe modifiers print)
-
-;TODO! how to set what u need to set
-; when a modifier comes in, check to see if u should set something
-; if so, check to see if the text is ONLY MODIFIERS OR NOTHING if it is,
-; then u can append the modifier to the string and pop it back into settings
-;
-; when a "character" (not actually characters, necesarily) comes in
-; check to see if there's one or more modifiers as the text. if YES
-; append this character, send shit 2 the server, (also want a socket interface to make
-; setting accurate anyhow), then reset changing and any other UI stuff to nil
-
-; both of those^ scenarios are if changing has been set by change-setting!

 (def changing (atom nil))
@@ -36,11 +21,26 @@
                 (when (not (nil? callback))
                     (callback which new-text))))))

-(def mods (from-async modifiers))
+; (def print #(.log js/console %))
+; (subscribe modifiers print)

-(def mods1 (multi-sub mods #(.log js/console %)))
+;TODO! how to set what u need to set
+; when a modifier comes in, check to see if u should set something
+; if so, check to see if the text is ONLY MODIFIERS OR NOTHING if it is,
+; then u can append the modifier to the string and pop it back into settings
+;
+; when a "character" (not actually characters, necesarily) comes in
+; check to see if there's one or more modifiers as the text. if YES
+; append this character, send shit 2 the server, (also want a socket interface to make
+; setting accurate anyhow), then reset changing and any other UI stuff to nil

-(rx/subscribe (rx/map mods1 #(str % " yoyoyo")) #(.log js/console %) )
+; both of those^ scenarios are if changing has been set by change-setting!
+
+(-> modifiers
+    from-async
+    (multi-sub #(.log js/console %))
+    (rx/map #(str % "!!!!!!!"))
+    (rx/subscribe #(.log js/console %)))
 ; (subscribe modifiers (with-append))

 (subscribe characters
@@ -49,10 +49,4 @@
             (reset! changing nil))))

 (defn change-setting! [settings button]
-    (let [action (keyword button)]
-        (.log js/console button)
-        (swap! settings assoc action "enter a new key combination")
-        (reset! changing {
-                :settings settings
-                :which action
-            })))
+    (let [action (keyword button)]))


CMR-4495 - Only cascade delete svc assn if the latest rev-id is passed.

--- metadata-db-app/src/cmr/metadata_db/services/concept_service.clj
+++ metadata-db-app/src/cmr/metadata_db/services/concept_service.clj
@@ -304,6 +304,12 @@
                           msg/concept-with-concept-id-and-rev-id-does-not-exist
                           concept-id
                           revision-id)))))
+
+(defn latest-revision?
+  "Given a concept-id and a revision-id, perform a check whether the
+  revision-id represents the most recent revision of the concept."
+  [context concept-id revision-id]
+  (= revision-id (:revision-id (get-concept context concept-id))))

 (defn split-concept-id-revision-id-tuples
   "Divides up concept-id-revision-id-tuples by provider and concept type."
@@ -654,11 +660,13 @@

 (defmethod force-delete-cascading-events :service
   [context concept-type concept-id revision-id]
-  ;; delete the related service associations
-  (delete-associations context concept-type concept-id revision-id :service-association)
-  ;; Do not queue the concept revision deletion event for now.
-  ; (ingest-events/publish-concept-revision-delete-msg context concept-id revision-id)
-  )
+  (when (latest-revision? context concept-id revision-id)
+    ;; delete the related service associations
+    (delete-associations
+     context concept-type concept-id revision-id :service-association)
+      ;; Do not queue the concept revision deletion event for now.
+      (ingest-events/publish-concept-revision-delete-msg
+       context concept-id revision-id)))

 (defmethod force-delete-cascading-events :default
   [context concept-type concept-id revision-id]


[#188] Remove clojure.test-clojure.test since the expected outcome is that it errors and fails

--- priv/examples/run_tests.clj
+++ priv/examples/run_tests.clj
@@ -2,7 +2,7 @@
   (:require [clojure.string :as str]
             clojure.test))

-(defn require-ns [root path]
+(defn- path->symbol [root path]
   (let [path (if root
                (subs path (count root))
                path)
@@ -11,15 +11,20 @@
                     (str/replace #"/" ".")
                     (str/replace #"_" "-"))
         ns-symbol (symbol ns-name)]
-    (require ns-symbol)
     ns-symbol))
+
+(def ignore-nss #{'clojure.test-clojure.test})

 (defn -main [& [test-dir root]]
   (when test-dir
     (let [paths (->> (file-seq test-dir)
                      (filter (complement filelib/is_dir.1)))
-          namespaces (mapv (partial require-ns root) paths)
-          result (apply clojure.test/run-tests namespaces)]
+          ns-symbols (->> paths
+                          (map (partial path->symbol root))
+                          (filter (comp not ignore-nss))
+                          doall)
+          _ (doseq [ns-symbol ns-symbols] (require ns-symbol))
+          result (apply clojure.test/run-tests ns-symbols)]
       (when (or (pos? (:error result))
                 (pos? (:fail result)))
         (throw result)))))


Add more figwheel configs

Add more figwheel configs

--- project.clj
+++ project.clj
@@ -40,7 +40,9 @@
                                    :main comic-reader.main
                                    :optimizations :advanced
                                    :pretty-print false}}]}
-  :figwheel {:nrepl-port 7888}
+  :figwheel {:http-server-root "public"
+             :css-dirs ["resources/public/css"] ;; watch and update CSS
+             :nrepl-port 7888}

   :main ^:skip-aot comic-reader.core
   :target-path "target/%s"


Version 0.2.5-SNAPSHOT

Version 0.2.5-SNAPSHOT

--- project.clj
+++ project.clj
@@ -1,4 +1,4 @@
-(defproject soy-clj "0.2.4"
+(defproject soy-clj "0.2.5-SNAPSHOT"
   :description "An idiomatic Clojure wrapper for Google's Closure templating system."
   :url "https://github.com/codahale/soy-clj"
   :license {:name "Eclipse Public License"


Version 1.2.1

Version 1.2.1

--- project.clj
+++ project.clj
@@ -1,4 +1,4 @@
-(defproject puppetlabs/pcp-client "1.2.1-SNAPSHOT"
+(defproject puppetlabs/pcp-client "1.2.1"
   :description "client library for PCP"
   :url "https://github.com/puppetlabs/clj-pcp-client"
   :license {:name "Apache License, Version 2.0"


lein-release plugin: preparing 0.6.1 release

--- project.clj
+++ project.clj
@@ -1,7 +1,7 @@
 (def tk-version "0.4.3")
 (def ks-version "0.7.2")

-(defproject puppetlabs/trapperkeeper-webserver-jetty9 "0.6.1-SNAPSHOT"
+(defproject puppetlabs/trapperkeeper-webserver-jetty9 "0.6.1"
   :description "We are trapperkeeper.  We are one."
   ;; Abort when version ranges or version conflicts are detected in
   ;; dependencies. Also supports :warn to simply emit warnings.


updates server deps

updates server deps

--- project.clj
+++ project.clj
@@ -3,12 +3,12 @@
   :url "https://github.com/build-canaries/nevergreen"
   :dependencies [[org.clojure/clojure "1.9.0"]
                  [ring "1.6.3" :exclusions [org.eclipse.jetty/jetty-server]]
-                 [org.eclipse.jetty/jetty-server "9.4.12.RC0"]
+                 [org.eclipse.jetty/jetty-server "9.4.12.RC2"]
                  [compojure "1.6.1"]
                  [environ "1.1.0"]
                  [cheshire "5.8.0"]
                  [clj-cctray "1.0.0"]
-                 [clj-http "3.9.0"]
+                 [clj-http "3.9.1"]
                  [ring-curl "0.3.1"]
                  [ring/ring-json "0.4.0"]
                  [ring/ring-defaults "0.3.2"]
@@ -34,10 +34,10 @@
                                          [com.livingsocial/lein-dependency-check "1.0.2"]]
                           :dependencies [[midje "1.9.2"]
                                          [clj-webdriver/clj-webdriver "0.7.2" :exclusions [org.mortbay.jetty/jetty]]
-                                         [org.seleniumhq.selenium/selenium-java "3.13.0" :exclusions [org.eclipse.jetty/jetty-io
+                                         [org.seleniumhq.selenium/selenium-java "3.14.0" :exclusions [org.eclipse.jetty/jetty-io
                                                                                commons-logging]]
-                                         [io.github.bonigarcia/webdrivermanager "2.2.4" :exclusions [org.apache.commons/commons-lang3]]
-                                         [org.seleniumhq.selenium/htmlunit-driver "2.31.0" :exclusions [org.eclipse.jetty/jetty-io
+                                         [io.github.bonigarcia/webdrivermanager "2.2.5" :exclusions [org.apache.commons/commons-lang3]]
+                                         [org.seleniumhq.selenium/htmlunit-driver "2.32.1" :exclusions [org.eclipse.jetty/jetty-io
                                                                                org.eclipse.jetty/jetty-http]]
                                          [ring/ring-mock "0.3.2"]]}
              :unit       {:jvm-opts ["-Dlogback.configurationFile=./test/logback-unit.xml"]}


Version 0.0.7

Version 0.0.7

--- project.clj
+++ project.clj
@@ -1,4 +1,4 @@
-(defproject day8.re-frame/async-flow-fx "0.0.7-SNAPSHOT"
+(defproject day8.re-frame/async-flow-fx "0.0.7"
   :description  "A re-frame effects handler for coordinating the kind of async control flow which often happens on app startup."
   :url          "https://github.com/Day8/re-frame-async-flow-fx.git"
   :license      {:name "MIT"}


fixed uberjar name

fixed uberjar name

--- project.clj
+++ project.clj
@@ -14,6 +14,7 @@
   :main touhou-barrage-fighters.core
   :source-paths ["src-clj"]
   :uberjar-name "touhou-barrage-fighters-standalone.jar"
+  :min-lein-version "2.0.0"
   :cljsbuild {
     :builds [{
       ;clj/cljsで共有するソースコードのパスを設定


update project info

update project info

--- project.clj
+++ project.clj
@@ -1,11 +1,11 @@
-(defproject signalcollect "0.1.0-SNAPSHOT"
-  :description  "Signal/Collect inspired graph computations"
-  :url          "https://github.com/postspectacular/sc-dev"
+(defproject thi.ng/fabric "0.1.0-SNAPSHOT"
+  :description  "Signal/Collect inspired compute graph"
+  :url          "http://thi.ng/fabric"
   :license      {:name "Apache Software License 2.0"
                  :url "http://www.apache.org/licenses/LICENSE-2.0"
                  :distribution :repo}
   :scm          {:name "git"
-                 :url "git@github.com:postspectacular/sc-dev.git"}
+                 :url "https://github.com/thi-ng/fabric"}

   :min-lein-vesion "2.4.0"


Version 0.0.19

Version 0.0.19

--- project.clj
+++ project.clj
@@ -1,4 +1,4 @@
-(defproject pe-fp-core "0.0.19-SNAPSHOT"
+(defproject pe-fp-core "0.0.19"
   :description "A Clojure library encapsulating the various domain objects associated with the fuel purchase application."
   :url "https://github.com/evanspa/pe-fp-core"
   :license {:name "MIT"


Added devices table.

Added devices table.

Missed it the last time.