Refactor the router

Refactor the router

--- src/clj/picard/http/router.clj
+++ src/clj/picard/http/router.clj
@@ -7,12 +7,19 @@
 (def GLOB        #"(.*?)")
 (def PLACEHOLDER #"^(:|\*)([a-z0-9*+!-+?]+)$")

-(defprotocol Route
-  (^{:private true} route [this state dn method path hdrs body]))
+(defn- not-found
+  "Basic endpoint that responds with a 404 not found"
+  [dn]
+  (fn [evt val]
+    (when (= :request evt)
+      (dn :response [404 {"content-length" "9"} (buffer "Not found")]))))
+
+(defprotocol Dispatchable
+  (^{:private true} dispatch [this state dn method path hdrs body]))

 (extend-type Object
-  Route
-  (route [this state dn method path hdrs body]
+  Dispatchable
+  (dispatch [this state dn method path hdrs body]
     (let [upstream (this dn)]
       (reset! state upstream)
       (upstream :request [hdrs body])
@@ -25,76 +32,70 @@
       (list match)
       match)))

-(defn- placeholder
-  [s]
-  (when-let [p (second (re-find PLACEHOLDER s))]
-    (keyword p)))
+(defrecord Route [method pattern segments names target]
+  Dispatchable
+  (dispatch [this state dn method path hdrs body]
+    (if-let [pattern (.pattern this)]
+      (when (or (nil? (.method this)) (= method (.method this)))
+        (when-let [[matched & vals] (re-match pattern path)]
+          (let [path (subs path (count matched))
+                hdrs (assoc hdrs
+                       :params      (zipmap (.names this) vals)
+                       :path-info   path
+                       :script-name matched)]
+            (dispatch (.target this) state dn method path hdrs body))))
+      (throw (Exception. "Route is not finalized")))))
+
+(defn- compile-pattern
+  [segments]
+  (loop [[segment & more] segments compiled "^"]
+    (if segment
+      (recur more (str compiled "/+" segment))
+      (re-pattern (str compiled "/*$")))))
+
+(defn- finalize
+  [route]
+  (cond
+   (instance? Route route)
+   (assoc route :pattern (compile-pattern (.segments route)))
+
+   (coll? route)
+   (map finalize (flatten route))
+
+   :else
+   route))

 (defn- parse
-  [path]
-  (map
-   (fn [segment]
-     (if-let [[_ type name :as match] (re-find PLACEHOLDER segment)]
-       (if (= ":" type)
-         {:pattern CAPTURE :name (keyword name)}
-         {:pattern GLOB    :name (keyword name)})
-       {:pattern segment}))
-   (re-seq SEGMENT path)))
-
-(defn- finalize-path
-  [{pattern :pattern :as path}]
-  (assoc path :pattern (re-pattern (str "^" pattern "/*$"))))
-
-(defn- compile-path
-  [segments]
-  (finalize-path
-   (reduce
-    (fn [{:keys [pattern names]} {p :pattern name :name}]
-      {:pattern (str pattern "/+" p)
-       :names   (if name (conj names name) names)})
-    {:pattern "" :names []} segments)))
-
-(defn- compile-route
-  [expected-method {:keys [pattern names]} target]
-  (reify Route
-    (route [_ state dn method path hdrs body]
-      ;; Only match the method if there is a method requirement
-      (when (or (nil? expected-method) (= expected-method method))
-        ;; Match the path
-        (when-let [[matched & vals] (re-match pattern path)]
-          ;; There was a match, deconstruct the values
-          (let [params (zipmap names vals)
-                path   (subs path (count matched))
-                hdrs   (assoc hdrs
-                         :params      params
-                         :path-info   path
-                         :script-name matched)]
-            (route target state dn method path hdrs body)))))))
+  [base path]
+  (reduce
+   (fn [{:keys [segments names] :as base} segment]
+     (conj
+      base
+      (if-let [[_ type name :as match] (re-find PLACEHOLDER segment)]
+        {:segments (conj segments (if (= ":" type) CAPTURE GLOB))
+         :names    (conj names (keyword name))}
+        {:segments (conj segments segment) :names names})))
+   base (re-seq SEGMENT path)))

 (defn match
   ([path target] (match nil path target))
   ([method path target]
-     (compile-route method (compile-path (parse path)) target)))
-
-(defn- not-found
-  [dn]
-  (fn [evt val]
-    (when (= :request evt)
-      (dn :response [404 {"content-length" "9"} (buffer "Not found")]))))
+     (map->Route
+      (parse
+       {:method method :segments [] :names [] :target target}
+       path))))

 (defn- handle-request
   [state routes dn [{path :path-info method :request-method :as hdrs} body]]
   (loop [[r & more] routes]
-    (when-not (route r state dn method path hdrs body)
+    (when-not (dispatch r state dn method path hdrs body)
       (if more
-        (recur more)
-        (let [upstream (not-found dn)]
-          (reset! state upstream)
-          (upstream :request [hdrs body]))))))
+        (recur more)))))

+;; Probably should add a cascade feature
 (defn routing
   [& routes]
-  (let [routes (flatten routes)]
+  (let [routes (finalize (conj (vec routes) not-found))]
     (fn [dn]
       (let [state (atom nil)]
         (fn [evt val]
@@ -105,34 +106,3 @@
             (if-let [upstream @state]
               (upstream evt val)
               (throw (Exception. "Invalid state")))))))))
-
-;; (defn zomg
-;;   []
-;;   (fn [dn]
-;;     (routing
-;;      (with-scope "/namespace"
-;;        (GET "/zomg" some-app)
-;;        (GET "/"     other-app)))))
-
-;; (defroutes zomg)
-
-;; (map "/socket.io" my-socketio-app)
-
-;; (defroutes my-app
-;;   (GET "/socket.io" zomg))
-
-;; (defroute :GET "/"
-;;   [hdrs body]
-;;   )
-
-;; (def routes
-;;   (map-routes
-;;    (fn [map]
-;;      (map :GET  "/" some-app)
-;;      (map :POST "/" some-other))))
-
-;; (defn socketio
-;;   [opts]
-;;   (routing
-;;    (GET  "/:version/:transport/:sid" (connection opts))
-;;    (POST "/:version" (handshake opts))))


old core

old core

--- src/clj_hypergraph_db/core.clj
+++ src/clj_hypergraph_db/core.clj
@@ -77,28 +77,7 @@
                   extent-config (evaluate extent-config-namespace extent-config-file)
                   extent-model (apply-resolved-function "create-model" extent-model-namespace extent-config input-model)]
               (apply-resolved-function "load-input-data" extent-persistance-namespace extent-model input-access)))))
-      ;(doseq [[assocaition-name association] (:associations @model)]
-      ;  (println "######" assocaition-name)
-      ;  (let [assoc-iterator (iterator-create :association assocaition-name)
-      ;        assoc-instance (atom (iterator-next assoc-iterator))]
-      ;    (while @assoc-instance
-      ;      (doseq [role-name (keys (:roles association))]
-      ;        (println "###" role-name)
-      ;        (doseq [role-instance (get-instance-extensions @assoc-instance role-name)]
-      ;          (println role-instance)))
-      ;      (reset! assoc-instance (iterator-next assoc-iterator)))))
-      ;(println)
-      ;(println)
-      ;(println)
-      ;(let [class-iterator (iterator-create :class :UserDomain)
-      ;      class-instance (atom (iterator-next class-iterator))]
-      ;  (while @class-instance
-      ;    (println "######")
-      ;    (doseq [attribute-name (keys (:attributes (:UserDomain (:classes @model))))]
-      ;      (println "###" attribute-name)
-      ;      (doseq [ext (get-instance-exten )])
-      ;        )
-      ;    (reset! class-instance (iterator-next class-iterator))))
+
       (doseq [output-token (find-all-items-by-type run-config :output)]
         (let [output-config-file (read-string (str "(" (slurp (:filename output-token)) ")"))
               output-type (second (first output-config-file))


Add examples to styleguide

Add examples to styleguide

--- src/cljs/clojuredocs/main.cljs
+++ src/cljs/clojuredocs/main.cljs
@@ -200,8 +200,14 @@

 (wire-search text-chan app-state)

+(defn mk-delete-example [app-state]
+  (fn [ex-to-del]
+    (swap! app-state update-in [:examples]
+      (fn [exs]
+        (vec (remove #(= ex-to-del %) exs))))))
+
 (on-el-om
-  [:.examples-widget examples/$examples]
+  [:.examples-widget examples/$examples {:init-state {:delete-ex (mk-delete-example app-state)}}]
   [:.see-alsos-widget see-alsos/$see-alsos]
   [:.search-widget search/$quick-lookup {:init-state {:text-chan text-chan}}]
   [:.quick-search-widget search/$quick-search {:init-state {:text-chan text-chan}}]
@@ -217,6 +223,72 @@

 (def push-sels [:.mobile-push-wrapper :.mobile-nav-menu :.mobile-nav-bar])

+(def ex-ac-results
+  {:ac-results [{:type "function"
+                 :ns "clojure.core"
+                 :name "map"
+                 :doc "Returns a lazy sequence consisting of the result of applying f to the set of first items of each coll, followed by applying f to the set
+of second items in each coll, until any one of the colls is
+exhausted. Any remaining items in other colls are ignored. Function
+f should accept number-of-colls arguments."}
+                {:type "namespace"
+                 :name "clojure.core"
+                 :doc "Fundamental library of the Clojure language"}
+                {:type "page"
+                 :name "Getting Started"
+                 :desc "Where to go to get started with Clojure. Provides a host of information  con the language, core concepts, tutorials, books, and videos to help you learn Clojure."}]})
+
+(def ex-example-0
+  {:body "user=> (map #(vector (first %) (* 2 (second %)))
+            {:a 1 :b 2 :c 3})
+
+([:a 2] [:b 4] [:c 6])
+
+user=> (into {} *1)
+{:a 2, :b 4, :c 6}"
+   :author {:login "zk" :account-source "github" :avatar-url "https://avatars.githubusercontent.com/u/7194?v=2"}})
+
+
+(def ex-example-1
+  {:body "user=> (map #(vector (first %) (* 2 (second %)))
+            {:a 1 :b 2 :c 3})
+
+([:a 2] [:b 4] [:c 6])
+
+user=> (into {} *1)
+{:a 2, :b 4, :c 6}"
+   :author {:login "zk"
+            :account-source "github"
+            :avatar-url "https://avatars.githubusercontent.com/u/7194?v=2"}
+   :editors [{:login "masondesu"
+              :account-source "github"
+              :avatar-url "http://www.gravatar.com/avatar/091bc95204caaf52b0d299bd9ac59540?s=48&d=identicon"}
+             {:login "dakrone"
+              :account-source "github"
+              :avatar-url "http://www.gravatar.com/avatar/bcacd00a7f05c4772329cf9f446c7987?s=48&d=identicon"}]})
+
+
+(def ex-example-2
+  {:body "user=> (map #(vector (first %) (* 2 (second %)))
+            {:a 1 :b 2 :c 3})
+
+([:a 2] [:b 4] [:c 6])
+
+user=> (into {} *1)
+{:a 2, :b 4, :c 6}"
+   :user {:email "zachary.kim@gmail.com"}
+   :editors [{:email "foo@barrrrrrrrr.com"}
+             {:email "foo@barrrrrrrr.com"}
+             {:email "foo@barrrrrrr.com"}
+             {:email "foo@barrrrrr.com"}
+             {:email "foo@barrrrr.com"}
+             {:email "foo@barrrr.com"}
+             {:email "foo@barrr.com"}
+             {:email "foo@barr.com"}
+             {:email "foo@bar.com"}]})
+:var {:name "bar" :ns "foo"}
+
+
 (on-el
   :.btn.mobile-menu
   (fn [$el]
@@ -257,19 +329,7 @@
   (fn [$el]
     (om/root
       search/$quick-lookup
-      {:ac-results [{:type "function"
-                     :ns "clojure.core"
-                     :name "map"
-                     :doc "Returns a lazy sequence consisting of the result of applying f to the set of first items of each coll, followed by applying f to the set
-of second items in each coll, until any one of the colls is
-exhausted. Any remaining items in other colls are ignored. Function
-f should accept number-of-colls arguments."}
-                    {:type "namespace"
-                     :name "clojure.core"
-                     :doc "Fundamental library of the Clojure language"}
-                    {:type "page"
-                     :name "Getting Started"
-                     :desc "Where to go to get started with Clojure. Provides a host of information  con the language, core concepts, tutorials, books, and videos to help you learn Clojure."}]}
+      ex-ac-results
       {:target $el}))

   :.sg-quick-lookup-null-state
@@ -297,15 +357,7 @@
   (fn [$el]
     (om/root
       examples/$examples
-      {:examples [{:body "user=> (map #(vector (first %) (* 2 (second %)))
-            {:a 1 :b 2 :c 3})
-
-([:a 2] [:b 4] [:c 6])
-
-user=> (into {} *1)
-{:a 2, :b 4, :c 6}"
-                   :user {:email "zachary.kim@gmail.com"}
-                   :history [{:user {:email "zachary.kim@gmail.com"}}]}]
+      {:examples [ex-example-0]
        :var {:name "bar" :ns "foo"}}
       {:target $el}))

@@ -313,70 +365,82 @@
   (fn [$el]
     (om/root
       examples/$examples
-      {:examples [{:body "user=> (foo)"
-                   :user {:email "zachary.kim@gmail.com"}
-                   :history [{:user {:email "lee@writequit.org"}}
-                             {:user {:email "zachary.kim@gmail.com"}}]}
-                  {:body "user=> (map #(vector (first %) (* 2 (second %)))
-            {:a 1 :b 2 :c 3})
-
-([:a 2] [:b 4] [:c 6])
-
-user=> (into {} *1)
-{:a 2, :b 4, :c 6}"
-                   :user {:email "zachary.kim@gmail.com"}
-                   :history [{:user {:email "masondesu@gmail.com"}}
-                             {:user {:email "lee@writequit.org"}}
-                             {:user {:email "zachary.kim@gmail.com"}}]}
-                  {:body "user=> (map #(vector (first %) (* 2 (second %)))
-            {:a 1 :b 2 :c 3})
-
-([:a 2] [:b 4] [:c 6])
-
-user=> (into {} *1)
-{:a 2, :b 4, :c 6}"
-                   :user {:email "zachary.kim@gmail.com"}
-                   :history [{:user {:email "foo@barrrrrrr.com"}}
-                             {:user {:email "foo@barrrrrr.com"}}
-                             {:user {:email "foo@barrrrr.com"}}
-                             {:user {:email "foo@barrrr.com"}}
-                             {:user {:email "foo@barrr.com"}}
-                             {:user {:email "foo@barr.com"}}
-                             {:user {:email "foo@bar.com"}}
-                             {:user {:email "fickamanda@gmail.com"}}
-                             {:user {:email "brentdillingham@gmail.com"}}
-                             {:user {:email "masondesu@gmail.com"}}
-                             {:user {:email "lee@writequit.org"}}
-                             {:user {:email "zachary.kim@gmail.com"}}]}]
-       :var {:name "bar" :ns "foo"}}
+      {:examples [ex-example-0
+                  ex-example-1
+                  ex-example-2]}
       {:target $el}))

   :.sg-add-example
   (fn [$el]
     (om/root
       examples/$add
-      {}
-      {:target $el :init-state {:expanded? true}}))
+      {:editing? true}
+      {:target $el}))

   :.sg-add-example-loading
   (fn [$el]
     (om/root
       examples/$add
-      {}
+      {:editing? true :loading? true :body "(defn greet [name]\n  (println \"Hello\" name))"}
+      {:target $el}))
+
+  :.sg-add-example-errors
+  (fn [$el]
+    (om/root
+      examples/$add
+      {:editing? true :body "(defn greet [name]\n  (println \"Hello\" name))"}
       {:target $el
-       :init-state {:expanded? true
-                    :loading? true
-                    :text "(defn greet [name]\n  (println \"Hello\" name))"}}))
-
-  :.sg-add-example-errors
-  (fn [$el]
-    (om/root
-      examples/$add
-      {}
-      {:target $el
-       :init-state {:expanded? true
-                    :error-message "This is where error messages that apply to the whole form go. And here's some other text to show what happens with a very long error message."
-                    :text "(defn greet [name]\n  (println \"Hello\" name))"}}))
+       :init-state {:error-message "This is where error messages that apply to the whole form go. And here's some other text to show what happens with a very long error message."}}))
+
+  :.sg-edit-example
+  (fn [$el]
+    (om/root
+      examples/$example
+      (merge
+        ex-example-0
+        {:editing? true
+         :can-delete? true})
+      {:target $el}))
+
+  :.sg-delete-example
+  (fn [$el]
+    (om/root
+      examples/$example-meta
+      {:body "user=> (foo)"
+       :author {:login "zk" :account-source "github" :avatar-url "https://avatars.githubusercontent.com/u/7194?v=2"}
+       :history [{:author {:login "dakrone" :account-source "github" :avatar-url "https://avatars3.githubusercontent.com/u/19060?v=2&s=460"}}]
+       :can-delete? true}
+      {:target $el}))
+
+  :.sg-delete-example-confirm
+  (fn [$el]
+    (om/root
+      examples/$example-meta
+      {:body "user=> (foo)"
+       :author {:login "zk" :account-source "github" :avatar-url "https://avatars.githubusercontent.com/u/7194?v=2"}
+       :history [{:author {:login "dakrone" :account-source "github" :avatar-url "https://avatars3.githubusercontent.com/u/19060?v=2&s=460"}}]
+       :can-delete? true}
+      {:target $el :init-state {:delete-state :confirm}}))
+
+  :.sg-delete-example-loading
+  (fn [$el]
+    (om/root
+      examples/$example-meta
+      {:body "user=> (foo)"
+       :author {:login "zk" :account-source "github" :avatar-url "https://avatars.githubusercontent.com/u/7194?v=2"}
+       :history [{:author {:login "dakrone" :account-source "github" :avatar-url "https://avatars3.githubusercontent.com/u/19060?v=2&s=460"}}]
+       :can-delete? true}
+      {:target $el :init-state {:delete-state :loading}}))
+
+  :.sg-delete-example-error
+  (fn [$el]
+    (om/root
+      examples/$example-meta
+      {:body "user=> (foo)"
+       :author {:login "zk" :account-source "github" :avatar-url "https://avatars.githubusercontent.com/u/7194?v=2"}
+       :history [{:author {:login "dakrone" :account-source "github" :avatar-url "https://avatars3.githubusercontent.com/u/19060?v=2&s=460"}}]
+       :can-delete? true}
+      {:target $el :init-state {:delete-state :error}}))

   :.sg-notes-null-state
   (fn [$el]
@@ -432,7 +496,6 @@
     ;; ctrl-s to focus search input
     (when (and (.-ctrlKey e) (= 83 (.-keyCode e)))
       (doseq [$el (sel ".search input[name='query']")]
-        (prn $el)
         (.focus $el)))))

 (def tog (atom false))


fix repo cloner to checkout master and pull

--- src/cljs_api_gen/repo_cljs.clj
+++ src/cljs_api_gen/repo_cljs.clj
@@ -12,20 +12,21 @@
 (def ^:dynamic *clj-version*  "Clojure version string         (e.g. \"1.7.0-beta1\")" nil)
 (def ^:dynamic *clj-tag*      "Clojure version git tag        (e.g. \"clojure-1.7.0-beta1\"" nil)

-(defn clone-or-fetch!
+(defn clone-or-pull!
   [repo-url]
   (let [repo-name (base-name repo-url)
         repo-path (str repo-dir "/" repo-name)]
-    (if-not (exists? repo-path)
-      (sh "git" "clone" repo-url :dir repo-dir)
-      (sh "git" "fetch" :dir repo-path))))
+    (when-not (exists? repo-path)
+      (sh "git" "clone" repo-url :dir repo-dir))
+    (sh "git" "checkout" "master" :dir repo-dir)
+    (sh "git" "pull" :dir repo-path)))

 (defn clone-or-fetch-repos!
   []
   (when-not (exists? repo-dir)
     (mkdir repo-dir))
-  (clone-or-fetch! "https://github.com/clojure/clojurescript")
-  (clone-or-fetch! "https://github.com/clojure/clojure"))
+  (clone-or-pull! "https://github.com/clojure/clojurescript")
+  (clone-or-pull! "https://github.com/clojure/clojure"))

 (defn get-current-repo-tag
   [repo]


Fixing tests

Fixing tests

--- test/iroh/core/import_test.clj
+++ test/iroh/core/import_test.clj
@@ -10,7 +10,7 @@
   (with-out-str (clojure.repl/doc hash-without))
   => (str "-------------------------\n"
           "iroh.core.import-test/hash-without\n"
-          "([clojure.lang.IPersistentMap java.lang.Object])\n"
+          "[[clojure.lang.IPersistentMap java.lang.Object]]\n"
           "  \n"
           "member: clojure.lang.IPersistentMap/without\n"
           "type: clojure.lang.IPersistentMap\n"


Update util_test.clj

Update util_test.clj

--- test/swagger_gen/util_test.clj
+++ test/swagger_gen/util_test.clj
@@ -2,6 +2,11 @@
   (:require [clojure.test :refer :all]
             [swagger-gen.util :refer :all]))

+(deftest interpose-map-test
+  (testing "should concat values and comma separate"
+    (let [actual (interpose-map identity ", " ["foo", "bar", "baz"])]
+      (is (= actual "foo, bar, baz")))))
+
 (deftest test-camelize
   (testing "should convert snake_case to CamelCase"
     (is (= "fooBar" (camelize "foo_bar")))))


Fix database transaction scope for resources endpoint

Prior to this commit, the database transaction scope for
the `resources` endpoint did not encapsulate the `get-result-count`
call; this caused an error when handling requests that asked
for the count header.

--- src/com/puppetlabs/puppetdb/http/v3/resources.clj
+++ src/com/puppetlabs/puppetdb/http/v3/resources.clj
@@ -16,25 +16,30 @@
   If the query can't be parsed, a 400 is returned."
   [query paging-options db]
   (try
-    (let [{[sql & params] :results-query
-           count-query   :count-query} (with-transacted-connection db
-                                         (-> query
-                                           (json/parse-string true)
-                                             (r/v3-query->sql paging-options)))
-          result       (pl-http/streamed-response buffer
-                         (with-transacted-connection db
-                           (r/with-queried-resources sql params
-                             #(pl-http/stream-json % buffer))))
-          query-result (if count-query
-                         {:result result :count (get-result-count count-query)}
-                         {:result result})]
+    (let [query-result
+          (with-transacted-connection db
+            (let [{[sql & params] :results-query
+                   count-query    :count-query} (-> query
+                                                  (json/parse-string true)
+                                                  (r/v3-query->sql paging-options))
+                  result       (pl-http/streamed-response buffer
+                                 ; NOTE - we we don't have a transaction here,
+                                 ; then the outer transaction can end up being
+                                 ; closed *after* the stream has been opened but
+                                 ; before it's been read, causing a connection
+                                 ; error when the caller tries to read it.
+                                 (with-transacted-connection db
+                                   (r/with-queried-resources sql params
+                                     #(pl-http/stream-json % buffer))))]
+              (if count-query
+                {:result result :count (get-result-count count-query)}
+                {:result result})))]
       (-> (:result query-result)
           rr/response
           (add-headers (dissoc query-result :result))
           (rr/header "Content-Type" "application/json")
           (rr/charset "utf-8")
           (rr/status pl-http/status-ok)))
-
     (catch IllegalArgumentException e
       (pl-http/error-response e))
     (catch com.fasterxml.jackson.core.JsonParseException e


:method should always be a keyword

:method should always be a keyword

--- src/com/wsscode/pathom/diplomat/http/clj_http.clj
+++ src/com/wsscode/pathom/diplomat/http/clj_http.clj
@@ -8,7 +8,7 @@
   [{::http/keys [url content-type accept as body headers] :as req}]
   (let [q? (partial contains? req)]
     (cond-> {:url    url
-             :method (http/request-method req)}
+             :method (keyword (http/request-method req))}
             (q? ::http/headers) (assoc :headers headers)
             (q? ::http/content-type) (assoc :content-type (http/encode-type->header content-type))
             (q? ::http/accept) (assoc :accept (http/encode-type->header accept))


Add watchers

Add watchers

--- src/aurora/compiler.cljs
+++ src/aurora/compiler.cljs
@@ -202,7 +202,15 @@

 ;; runtime

-(defn run-index [index id state]
+(defn see [state watchers]
+  (dissoc
+   (reduce
+    (fn [state watcher] (watcher state))
+    state
+    watchers)
+   "output"))
+
+(defn tick [index id state watchers]
   (let [jsth (notebook->jsth index (get index id))
         source (jsth/expression->string jsth)
         _ (println "###################")
@@ -213,26 +221,41 @@
     (aset notebook "next_state" state)
     (aset notebook "stack" stack)
     (try
-      [(.value_root notebook state []) (.-next_state notebook) (aget stack 0)]
+      (.value_root notebook state [])
+      (let [next-state (.-next_state notebook)]
+        [(see next-state) next-state (aget stack 0)])
       (catch :default e
-        [e (.-next_state notebook) (aget stack 0)]))))
-
-(defn tick-example [index id state]
-  (second (run-index index id state)))
+        (let [next-state (.-next_state notebook)]
+          [e next-state (aget stack 0)])))))
+
+;; watchers
+
+(defn watch-timeout* [buffer state]
+  (doseq [{:strs [cursor timeout]} (get-in state ["output" "timeout"])]
+    (js/setTimeout (fn [] (swap! buffer conj cursor)) timeout))
+  (let [cursors @buffer] ;; this is only valid because js is single-threaded
+    (reset! buffer nil)
+    (reduce #(assoc-in %1 %2 "timeout") state cursors)))
+
+(defn watch-timeout []
+  (let [buffer (atom [])]
+    #(watch-timeout* buffer %)))
+
+;; examples

 (notebook->jsth ast/example-b (get ast/example-b "example_b"))

-(run-index ast/example-b "example_b" {"a" 1 "b" 2})
-(run-index ast/example-b "example_b" {"a" 1 "c" 2})
-(run-index ast/example-b "example_b" {"a" 1 "b" "foo"})
-(run-index ast/example-b "example_b" [1 "foo"])
-(run-index ast/example-b "example_b" [1 2])
-
-;; (run-index ast/example-c 0)
-;; (run-index ast/example-c 1)
-;; (run-index ast/example-c 7)
-;; (run-index ast/example-c 10)
-
-;; (run-index ast/example-d {"counter" 0})
-
-;; (run-index ast/example-e {"counter" 0 "started_" "false"})
+(tick ast/example-b "example_b" {"a" 1 "b" 2})
+(tick ast/example-b "example_b" {"a" 1 "c" 2})
+(tick ast/example-b "example_b" {"a" 1 "b" "foo"})
+(tick ast/example-b "example_b" {"vec" [1 "foo"]})
+(tick ast/example-b "example_b" {"vec" [1 2]})
+
+;; (tick ast/example-c 0)
+;; (tick ast/example-c 1)
+;; (tick ast/example-c 7)
+;; (tick ast/example-c 10)
+
+;; (tick ast/example-d {"counter" 0})
+
+;; (tick ast/example-e {"counter" 0 "started_" "false"})


Increase security for malsup so it works on https-based server.

--- src/com/okl/tokenmgr/views.clj
+++ src/com/okl/tokenmgr/views.clj
@@ -49,7 +49,7 @@
    [:title title]
    [:script {:src
              "https://ajax.googleapis.com/ajax/libs/jquery/1.4.3/jquery.min.js"}]
-   [:script {:src "http://malsup.github.com/jquery.form.js"}]
+   [:script {:src "https://malsup.github.com/jquery.form.js"}]
    [:link {:rel "stylesheet"
            :href "/slick-grid/slick.grid.css"
            :type "text/css"}]


Server runs, servlet routing doesn't

Server runs, servlet routing doesn't

--- src/compojure/http/servlet.clj
+++ src/compojure/http/servlet.clj
@@ -84,11 +84,11 @@
   HttpServletRequest instance."
   [[#^HttpServlet servlet, #^HttpServletRequest request] & body]
   `(let [~'context  (.getServletContext ~servlet)
-         ~'method   (.getMethod ~request)
-         ~'url      (.getURL    ~request)
+         ~'method   (.getMethod   ~request)
+         ~'url      (.getRequestURL ~request)
          ~'path     (.getPathInfo ~request)
-         ~'params   (get-params  ~request)
-         ~'headers  (get-headers ~request)
+         ~'params   (get-params   ~request)
+         ~'headers  (get-headers  ~request)
          ~'mimetype (partial context-mimetype ~'context)
          ~'session  (get-session ~request)
          ~'cookies  (get-cookies ~request)]
@@ -156,15 +156,15 @@
   [& routes]
   `(proxy [HttpServlet] []
      (service ~'[request response]
-       (http-service ~'[this request response]
+       (http-handler ~'[this request response]
          ~@routes))))

 (defmacro update-servlet
   "Update an existing servlet proxy with a new set of routes."
   [object & routes]
   `(update-proxy ~object
-     {"service" (fn [this request response]
-                  (http-service ~'[this request response]
+     {"service" (fn ~'[this request response]
+                  (http-handler ~'[this request response]
                     ~@routes))}))

 (defmacro defservlet
@@ -194,5 +194,5 @@
                            ["-" (cons prefix routes)])]
     `(defn ~(symbol (str prefix "service"))
      ~'[this request response]
-       (http-service ~'[this request response]
+       (http-handler ~'[this request response]
          ~@routes))))


fixing error wrapping for non slingshort exceptions

--- src/celestial/common.clj
+++ src/celestial/common.clj
@@ -65,7 +65,11 @@
    "Wraps validation error responses in the API layer"
    [& body]
   `(try+ ~@body
-    (catch (contains? ~'% :errors) e# (bad-req e#)))
+    (catch (and (map? ~'%) (contains? ~'% :errors)) e# (bad-req e#))
+    (catch Throwable e#
+      (error e#)
+      (bad-req "Error happend, please contact admin"))
+   )
   )

 (def version "0.3.7")


Return 20 latest items in API

Return 20 latest items in API

--- src/qcast/server.clj
+++ src/qcast/server.clj
@@ -87,7 +87,7 @@
 (defroutes api-routes
   "Routes for client API"
   (GET "/api/v1/presentations" []
-    (->> (cache/latest 10)
+    (->> (cache/latest 20)
          (map :data)
          (map #(dissoc % :slides :times :video :audio :pdf))
          respond))


cast PORT env to int

cast PORT env to int

--- src/clj/bulldog/core.clj
+++ src/clj/bulldog/core.clj
@@ -90,7 +90,10 @@
                      :store (<!! (new-mem-store)) #_(<!! (new-fs-store "data"))})]
     (create-routes @state)
     (-> state deref :store (-assoc-in [:articles] test-articles) <!!)
-    (swap! state assoc :server (run-server #'all-routes {:port (or (System/getenv "PORT") 8080)}))
+    (swap! state assoc :server (run-server #'all-routes
+                                           {:port (or
+                                                   (Integer/parseInt (System/getenv "PORT"))
+                                                   8080)}))
     state))

 (defn -main [& args]


add test-data

add test-data

--- src/clj/bulldog/core.clj
+++ src/clj/bulldog/core.clj
@@ -89,6 +89,7 @@
   (let [state (atom {:server nil
                      :store (<!! (new-mem-store)) #_(<!! (new-fs-store "data"))})]
     (create-routes @state)
+    (-> state deref :store (-assoc-in [:articles] test-articles) <!!)
     (swap! state assoc :server (run-server #'all-routes {:port 8080}))
     state))


Allow movement of pieces

Allow movement of pieces

--- src/cljs/chess/core.cljs
+++ src/cljs/chess/core.cljs
@@ -52,8 +52,14 @@
          om/IDidMount
          (did-mount [_]
            (go (while true
-                 (let [new-selection (<! click-chan)]
-                   (om/set-state! owner :selected new-selection)))))))
+                 (let [new-selection (<! click-chan)
+                       old-selection (om/get-state owner :selected)]
+                   (if old-selection
+                     (do
+                       (om/transact! app-state :board (fn [b] (board/move b old-selection new-selection)))
+                       (om/set-state! owner :selected nil))
+                     (if (board/in (deref board) new-selection)
+                       (om/set-state! owner :selected new-selection)))))))))
      app-state
      {:target (. js/document (getElementById "app"))})))


Experiment with meta-errors

Experiment with meta-errors

--- src/clojush/evaluate.clj
+++ src/clojush/evaluate.clj
@@ -760,7 +760,7 @@
                          (= e (max p1e p2e)) 4
                          :else 5)))
                 (vec (repeat (count (:errors ind)) 6)))
-              #_(if (and (:parent1-errors ind)
+              (if (and (:parent1-errors ind)
                        (:parent2-errors ind))
                 (if (or (= (:errors ind) (:parent1-errors ind))
                         (= (:errors ind) (:parent2-errors ind)))
@@ -1004,7 +1004,7 @@
                          (= e p1e) 3
                          :else 2)))
                 (vec (repeat (count (:errors ind)) 2)))
-              (if (:parent1-errors ind)
+              #_(if (:parent1-errors ind)
                 (vec (for [[e p1e] (mapv #(vector %1 %2)
                                          (:errors ind)
                                          (:parent1-errors ind))]


Rename :discounted-case-improvement-ratios to :discounted-case-improvements

--- src/clojush/evaluate.clj
+++ src/clojush/evaluate.clj
@@ -146,11 +146,11 @@
                                 (- 1 (/ (reduce + (mapv * improvements weights))
                                         (reduce + weights))))))
                           ;
-                          (= cat :discounted-case-improvement-ratios)
-                          (if (not (:print-history argmap))
-                            (throw
-                              (Exception.
-                                ":print-history must be true for :discounted-case-improvement-ratios"))
+                          (= cat :discounted-case-improvements)
+                          (if (not (:print-history argmap))
+                            (throw
+                              (Exception.
+                                ":print-history must be true for :discounted-case-improvements"))
                             (if (empty? (rest (:history ind)))
                               (vec (repeat (count (:errors ind)) 1000000))
                               (vec (for [case-history (apply map list (:history ind))]


added codemirror into dependencies

added codemirror into dependencies

--- build.boot
+++ build.boot
@@ -37,7 +37,8 @@
                  [cljsjs/enquire              "2.1.2-0"]
                  [com.cemerick/piggieback     "0.2.1"]
                  [binaryage/devtools          "0.4.1"]
-                 [day8/re-frame-tracer        "0.1.0-SNAPSHOT"]])
+                 [day8/re-frame-tracer        "0.1.0-SNAPSHOT"]
+                 [cljsjs/codemirror           "5.10.0-0"]])

 (require '[adzerk.boot-cljs             :refer [cljs]]
          '[adzerk.boot-reload           :refer [reload]]


Use merge-env! instead of set-env!

Use merge-env! instead of set-env!

--- build.boot
+++ build.boot
@@ -1,4 +1,4 @@
-(set-env!
+(merge-env!
   :resource-paths #{"src/main/cljc" "src/spec/cljc" "src/main/js/foreign"}
   :dependencies   '[[org.clojure/clojure         "1.9.0-alpha17"]
                     [org.clojure/clojurescript   "1.9.671"]
@@ -17,12 +17,10 @@
                     [com.cemerick/piggieback     "0.2.1"  :scope "test"]
                     [weasel                      "0.7.0"  :scope "test"]
                     [org.clojure/tools.nrepl     "0.2.13" :scope "test"]
-                    [nodisassemble               "0.1.3"  :scope "test"]])
-
-(merge-env!
-  :repositories [["clojars" {:url      "https://clojars.org/repo"
-                             :username (System/getenv "CLOJARS_USER")
-                             :password (System/getenv "CLOJARS_PASS")}]])
+                    [nodisassemble               "0.1.3"  :scope "test"]]
+  :repositories   [["clojars" {:url      "https://clojars.org/repo"
+                               :username (System/getenv "CLOJARS_USER")
+                               :password (System/getenv "CLOJARS_PASS")}]])

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


Add clairvoyant compile switch to dev builds

--- build.boot
+++ build.boot
@@ -152,7 +152,8 @@

 (deftask development []
   (set-env! :resource-paths #(conj %  "dev-resources"))
-  (task-options! cljs {:optimizations :none}
+  (task-options! cljs {:optimizations :none
+                       :compiler-options {:closure-defines {"clairvoyant.core.devmode" true}}}
                  reload {:on-jsload 'comic-reader.main/main})
   identity)


Correct source-paths, and put all deps in for server

--- build.boot
+++ build.boot
@@ -1,15 +1,17 @@
 (set-env!
- :source-paths #{"sass" "src" "resources"}
+ :source-paths #{"src" "resources"}
  :asset-paths #{"assets"}
  :dependencies '[[adzerk/boot-cljs "1.7.48-5" :scope "test"]
-                 [adzerk/boot-cljs-repl "0.2.0" :scope "test"]
+                 [adzerk/boot-cljs-repl "0.3.0" :scope "test"]
                  [adzerk/boot-reload "0.4.0" :scope "test"]
                  [deraen/boot-less "0.5.0"]
                  [org.clojure/clojure "1.8.0"]
                  [org.clojure/clojurescript "1.7.170"]
                  [org.clojure/core.async "0.2.374"]
                  [org.omcljs/om "1.0.0-alpha28"]
-                 [org.clojure/tools.nrepl "0.2.12"]])
+                 [org.clojure/tools.nrepl "0.2.12"]
+                 [com.cemerick/piggieback "0.2.1"  :scope "test"]
+                 [weasel                  "0.7.0"  :scope "test"]])

 (require '[adzerk.boot-cljs :refer [cljs]]
          '[adzerk.boot-cljs-repl :refer [cljs-repl start-repl]]
@@ -21,20 +23,40 @@
   "Override"
   []
   (set-env!
-   :dependencies '[[bidi "1.24.0"]]
-   :source-paths #{"dev" "src" "resources"})
+   :source-paths #(conj % "dev")
+   :dependencies '[;; Infrastructure
+                   [com.stuartsierra/component "0.3.1"]
+                   [reloaded.repl "0.2.1"]
+                   [prismatic/schema "1.0.4"]
+                   [org.clojure/core.async "0.2.374"]
+                   [org.clojure/tools.reader "0.10.0"]
+
+                   ;; Logging
+                   [org.clojure/tools.logging "0.3.1"]
+                   [org.slf4j/jcl-over-slf4j "1.7.13"]
+                   [org.slf4j/jul-to-slf4j "1.7.13"]
+                   [org.slf4j/log4j-over-slf4j "1.7.13"]
+                   [ch.qos.logback/logback-classic "1.1.3" :exclusions [org.slf4j/slf4j-api]]
+
+                   ;; Web
+                   [aleph "0.4.1-beta3"]
+                   [bidi "1.24.0"]
+                   [hiccup "1.0.5"]
+                   [org.omcljs/om "1.0.0-alpha28"]
+                   [yada "1.1.0-20160126.014942-13"]])
   (repl :init-ns 'user :server true))

 (deftask dev
   "Simple alias to run application in development mode"
   []
-  (set-env! :target-path "target/dev")
+  (set-env! :target-path "target/dev"
+            :source-paths #(conj % "sass"))
   (comp
    (watch)
    (speak)
    (less :source-map true)
    (reload :on-jsload 'edge.main/init)
-   (cljs-repl)
+   (cljs-repl :nrepl-opts {:init-ns 'user})
    (cljs :ids #{"edge"} :optimizations :none)
    (target :dir #{"target/dev"})))


dev: listen on port 3000

dev: listen on port 3000

--- build.boot
+++ build.boot
@@ -32,7 +32,7 @@
    (hoplon)
    (reload)
    (cljs)
-   (serve :port 4002)))
+   (serve)))

 (deftask prod
   "Build for production deployment."


Remove unnecessary dependencies

Remove unnecessary dependencies

--- build.boot
+++ build.boot
@@ -4,10 +4,8 @@
  :dependencies
  '[[org.clojure/clojure "1.8.0"]
    [org.clojure/clojurescript "1.9.36"]
-   [org.clojure/core.async "0.1.346.0-17112a-alpha"]
    [cljs-http "0.1.41"]
    [reagent "0.5.1"]
-   [bidi "2.0.9"]
    [kioo "0.4.2"]
    [com.taoensso/timbre "4.7.0"]
    [alandipert/storage-atom "1.2.4"]


Minor formatting change to run task

Minor formatting change to run task

--- build.boot
+++ build.boot
@@ -159,7 +159,8 @@
         (intern 'user 'system system)
         (assoc fileset :system system)))))

-(deftask run [p profile VAL kw "Profile"]
+(deftask run
+  [p profile VAL kw "Profile"]
   (comp
    (repl :server true
          :port (case profile :prod 5601 :beta 5602 5600)


Fix version number

Fix version number

--- build.boot
+++ build.boot
@@ -11,7 +11,7 @@
          '[adzerk.boot-cljs   :refer [cljs]]
          '[pandeiro.boot-http :refer [serve]])

-(def +version+ "2.1.2-SNAPSHOT")
+(def +version+ "2.1.2")

 (task-options!
   pom {:project     'adzerk/boot-cljs


bump deps, use `cljs-repl-env`

bump deps, use `cljs-repl-env`

--- build.boot
+++ build.boot
@@ -3,7 +3,7 @@
 (set-env!
  :source-paths    #{"src/main"}
  :resource-paths  #{"resources"}
- :dependencies '[[org.clojure/clojurescript   "1.9.76"         :scope "provided"]
+ :dependencies '[[org.clojure/clojurescript   "1.9.89"         :scope "provided"]
                  [org.omcljs/om               "1.0.0-alpha37"  :scope "provided"]
                  [com.ladderlife/cellophane   "0.3.2"          :scope "provided"]
                  [com.cognitect/transit-clj   "0.8.285"        :scope "test"]
@@ -11,7 +11,7 @@
                  [com.cemerick/piggieback     "0.2.1"          :scope "test"]
                  [pandeiro/boot-http          "0.7.3"          :scope "test"]
                  [adzerk/boot-cljs            "1.7.228-1"      :scope "test"]
-                 [adzerk/boot-cljs-repl       "0.3.0"          :scope "test"]
+                 [adzerk/boot-cljs-repl       "0.3.2"          :scope "test"]
                  [adzerk/boot-test            "1.1.1"          :scope "test"]
                  [crisptrutski/boot-cljs-test "0.2.2-SNAPSHOT" :scope "test"]
                  [adzerk/boot-reload          "0.4.8"          :scope "test"]
@@ -23,7 +23,7 @@

 (require
  '[adzerk.boot-cljs      :refer [cljs]]
- '[adzerk.boot-cljs-repl :as cr :refer [cljs-repl start-repl]]
+ '[adzerk.boot-cljs-repl :as cr :refer [cljs-repl-env start-repl]]
  '[adzerk.boot-reload    :refer [reload]]
  '[adzerk.boot-test :as bt-clj]
  '[adzerk.bootlaces      :refer [bootlaces! push-release]]
@@ -54,7 +54,7 @@
   (comp
     (serve)
     (watch)
-    (cljs-repl)
+    (cljs-repl-env)
     (reload)
     (speak)
     (cljs :source-map true


Fix formatting

Fix formatting

--- build.boot
+++ build.boot
@@ -1,6 +1,6 @@
 (set-env!
- :source-paths    #{"src/cljs"}
- :resource-paths  #{"resources"}
+ :source-paths #{"src/cljs"}
+ :resource-paths #{"resources"}
  :dependencies
  '[[org.clojure/clojure "1.8.0"]
    [org.clojure/clojurescript "1.9.36"]


Configure junit task with the correct package

--- build.boot
+++ build.boot
@@ -14,7 +14,7 @@
       :scm {:url "https://github.com/RadicalZephyr/http-server.git"}
       :licens {"MIT" "http://opensource.org/licenses/MIT"}}
  jar {:file "server.jar"}
- junit {:packages '#{net.zephyrizing.http_server}})
+ junit {:packages '#{net.zephyrizing.http_server_test}})

 (deftask test
   "Compile and run my jUnit tests."


Bump deps

Bump deps

--- build.boot
+++ build.boot
@@ -1,48 +1,50 @@
 (set-env!
-  :dependencies '[;; Core
-                 [org.clojure/clojure "1.8.0"]
-                 [org.clojure/core.async "0.2.374"]
-                 [org.clojure/tools.namespace "0.2.10"]
-                 [org.clojure/clojurescript "1.8.40"]
-                 [org.clojure/core.match "0.3.0-alpha4"]
+  :dependencies '[;; Core
+                 [org.clojure/clojure "1.8.0"]
+                 [org.clojure/core.async "0.2.385"]
+                 [org.clojure/tools.namespace "0.2.10"]
+                 ;[org.clojure/clojurescript "1.8.51"]
+                 [org.clojure/clojurescript "1.9.93"]
+                 [org.clojure/core.match "0.3.0-alpha4"]
+
+                 [com.datomic/datomic-free "0.9.5385"]
+                 [datascript "0.15.1"]
+
+                 [com.cognitect/transit-clj "0.8.285"]
+
+                 ;; Utils
+                 [com.stuartsierra/component "0.3.1"]
+                 [org.clojure/data.xml "0.0.8"]
+                 [org.clojure/data.zip "0.1.2"]
+                 [clj-time "0.12.0"]
+                 [prismatic/schema "1.1.2"]
+
+                 ;; Logging
+                 [com.taoensso/timbre "4.6.0"]
+
+                 ;; Web UI
+                 [org.omcljs/om "1.0.0-alpha40"]
+                 [com.taoensso/sente "1.9.0"]
+
+                 [http-kit "2.2.0"]
+
+                 [ring                      "1.5.0"]
+                 [ring/ring-defaults        "0.2.1"]
+                 [ring-transit "0.1.6"]
+
+                 [hiccup "1.0.5"]
+
+                 [compojure "1.5.1"]
+
+                 ; Code cleaness tools
+                 [repetition-hunter "1.0.0"]
+
+                 ;; Cljs
+                 [com.andrewmcveigh/cljs-time "0.4.0"]
+                 [cljs-http "0.1.41"]
+                 [com.cognitect/transit-cljs "0.8.239"]
+                 [alandipert/storage-atom "2.0.1"]]

-                 [com.datomic/datomic-free "0.9.5350"]
-                 [datascript "0.15.0"]
-
-                 [com.cognitect/transit-clj "0.8.285"]
-
-                 ;; Utils
-                 [com.stuartsierra/component "0.3.1"]
-                 [org.clojure/data.xml "0.0.8"]
-                 [org.clojure/data.zip "0.1.1"]
-                 [clj-time "0.11.0"]
-                 [prismatic/schema "1.1.1"]
-
-                 ;; Logging
-                 [com.taoensso/timbre "4.3.1"]
-
-                 ;; Web UI
-                 [org.omcljs/om "1.0.0-alpha32"]
-                 [com.taoensso/sente "1.8.1"]
-
-                 [http-kit "2.1.19"]
-
-                 [ring                      "1.4.0"]
-                 [ring/ring-defaults        "0.2.0"]
-                 [ring-transit "0.1.4"]
-
-                 [hiccup "1.0.5"]
-
-                 [compojure "1.5.0"]
-
-                 ; Code cleaness tools
-                 [repetition-hunter "1.0.0"]
-
-                 ;; Cljs
-                 [com.andrewmcveigh/cljs-time "0.4.0"]
-                 [cljs-http "0.1.40"]
-                 [com.cognitect/transit-cljs "0.8.237"]
-                 [alandipert/storage-atom "1.2.4"]]
   :source-paths #{"src/"})

 (task-options!


Update the `validation` integration test to include all metric types.

--- test/wonko/core_test.clj
+++ test/wonko/core_test.clj
@@ -98,16 +98,26 @@
           {:keys [events-topic alerts-topic]} (tu/create-topics)]

       (tu/init-client service-name events-topic alerts-topic)
+
       (client/counter :validation-metric {:first 5})
       (is (thrown? IllegalArgumentException (client/counter :validation-metric {:first 6 :second 7})))
+
+      (client/gauge :validation-metric {:first 5} 5)
+      (is (thrown? IllegalArgumentException (client/gauge :validation-metric {:first 6 :second 7} 6)))
+
+      (client/stream :validation-metric {:first 5} 5)
+      (is (thrown? IllegalArgumentException (client/stream :validation-metric {:first 6 :second 7} 6)))
+
+      (client/alert :validation-metric {:first 5})
+      (is (client/alert :validation-metric {:first 6 :second 7}))

       (let [consumed-events (atom [])
             thread-pool (consume/start {events-topic 1 alerts-topic 1}
                                        (fn [event]
                                          (process event)
                                          (swap! consumed-events conj event)))]
-        (tu/wait-for #(= 1 (count @consumed-events)) :interval 1 :timeout 3)
-        (is (= (count @consumed-events) 1))
+        (tu/wait-for #(= 4 (count @consumed-events)) :interval 1 :timeout 3)
+        (is (= (count @consumed-events) 4))

         (consume/stop thread-pool)
         (tu/delete-topics events-topic alerts-topic)))))


[#102] Rename replace ns from  to clje.user

--- priv/clojure/main.clj
+++ priv/clojure/main.clj
@@ -289,7 +289,7 @@
 (defn- initialize
   "Common initialize routine for repl, script, and null opts"
   [args inits]
-  (ns '$user)
+  (ns 'clje.user)
   (set! *command-line-args* args)
   (doseq [[opt arg] inits]
     ((init-dispatch opt) arg)))


CMR-1772: Addressed review comments.

CMR-1772: Addressed review comments.

--- system-int-test/test/cmr/system_int_test/virtual_product_test.clj
+++ system-int-test/test/cmr/system_int_test/virtual_product_test.clj
@@ -195,7 +195,8 @@
 (defn- assert-tombstones
   "Assert that the concepts with the given concept-ids and revision-id exist in mdb and are tombstones"
   [concept-ids revision-id]
-  (apply = true (map #(:deleted (ingest/get-concept % revision-id)) concept-ids)))
+  (doseq [concept-id concept-ids]
+    (is (:deleted (ingest/get-concept concept-id revision-id)))))

 ;; Verify that latest revision ids of virtual granules and the corresponding source granules
 ;; are in sync as various ingest operations are performed on the source granules
@@ -219,7 +220,7 @@
     ;; check revision ids are in sync after delete operations
     (ingest/delete-concept (d/item->concept ingest-result) {:revision-id 12})
     (index/wait-until-indexed)
-    (is (assert-tombstones vp-granule-ids 12))
+    (assert-tombstones vp-granule-ids 12)
     (ingest/delete-concept (d/item->concept ingest-result) {:revision-id 14})
     (index/wait-until-indexed)
-    (is (assert-tombstones vp-granule-ids 14))))
+    (assert-tombstones vp-granule-ids 14)))


Only warn for deprecated once; dbug print stack trace in verbose mode

--- boot/core/src/boot/core.clj
+++ boot/core/src/boot/core.clj
@@ -1,19 +1,20 @@
 (ns boot.core
   "The boot core API."
   (:require
-    [clojure.java.io             :as io]
-    [clojure.set                 :as set]
-    [clojure.walk                :as walk]
-    [clojure.repl                :as repl]
-    [clojure.string              :as string]
-    [boot.pod                    :as pod]
-    [boot.git                    :as git]
-    [boot.cli                    :as cli2]
-    [boot.file                   :as file]
-    [boot.tmpregistry            :as tmp]
-    [boot.tmpdir                 :as tmpd]
-    [boot.util                   :as util]
-    [boot.from.clojure.tools.cli :as cli])
+    [clojure.java.io              :as io]
+    [clojure.set                  :as set]
+    [clojure.walk                 :as walk]
+    [clojure.repl                 :as repl]
+    [clojure.string               :as string]
+    [boot.pod                     :as pod]
+    [boot.git                     :as git]
+    [boot.cli                     :as cli2]
+    [boot.file                    :as file]
+    [boot.tmpregistry             :as tmp]
+    [boot.tmpdir                  :as tmpd]
+    [boot.util                    :as util]
+    [boot.from.io.aviso.exception :as ex]
+    [boot.from.clojure.tools.cli  :as cli])
   (:import
     [boot App]
     [java.io File]
@@ -271,9 +272,12 @@
 ;; Tempdir and Fileset API ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

 (defmacro ^:private deprecate! [was is]
-  `(defn ^:deprecated ~was [& args#]
-     (util/warn "%s was deprecated, please use %s instead\n" '~was '~is)
-     (apply ~is args#)))
+  `(let [msg# (format "%s was deprecated, please use %s instead\n" '~was '~is)
+         warn# (delay (util/warn msg#))]
+     (defn ^:deprecated ~was [& args#]
+       @warn#
+       (util/dbug (ex/format-exception (Exception. msg#)))
+       (apply ~is args#))))

 (defn tmp-dir!
   "Creates a boot-managed temporary directory, returning a java.io.File."


fixed instantiate-aws

fixed instantiate-aws

--- integration/src/dda/pallet/dda_managed_ide/app/instantiate_aws.clj
+++ integration/src/dda/pallet/dda_managed_ide/app/instantiate_aws.clj
@@ -39,7 +39,7 @@

 (defn provisioning-spec [target-config domain-config count]
   (merge
-    (app/vm-group-spec
+    (app/dda-ide-group-spec
       (app/app-configuration domain-config))
     (cloud-target/node-spec "jem")
     {:count count}))


minor: update jar-async project.clj, #532


Make router state queryable (#341)

Make router state queryable (#341)

--- waiter/src/waiter/state.clj
+++ waiter/src/waiter/state.clj
@@ -1150,9 +1150,11 @@
    for modifying this data for the router."
   [scheduler-state-chan router-chan router-id exit-chan service-id->service-description-fn deployment-error-config]
   (let [state-chan (async/chan)
-        router-state-push-chan (au/latest-chan)]
+        router-state-push-chan (au/latest-chan)
+        query-chan (async/chan)]
     {:state-chan state-chan
      :router-state-push-mult (async/mult router-state-push-chan)
+     :query-chan query-chan
      :go-chan
      (async/go
        (try
@@ -1269,6 +1271,11 @@
                                new-state)
                              (recur loop-state' remaining))))))

+                   query-chan
+                   ([response-chan]
+                    (async/put! response-chan current-state)
+                    current-state)
+
                    router-chan
                    ([data]
                      (cid/with-correlation-id


Updating the indexer test that uses elasticsearch to avoid break subsequent tests that rely on the elastisch global endpoint being set.

--- test/cmr/indexer/services/index_versions_test.clj
+++ test/cmr/indexer/services/index_versions_test.clj
@@ -50,7 +50,12 @@
 (defn server-setup
   "Fixture that starts an instance of elastic in the JVM runs the tests and then shuts it down."
   [f]
-  (let [http-port (:port test-config)
+
+  ;; When this test runs as part of dev-systems all tests it changes the global endpoint and breaks
+  ;; other tests that run after it. We keep track of the internal endpoint of the elastisch endpoint
+  ;; and set it back after the tests have completed.
+  (let [current-endpoint esr/*endpoint*
+        http-port (:port test-config)
         server (lifecycle/start (elastic-server/create-server http-port 9215) nil)]
     (esr/connect! (str "http://localhost:" http-port))

@@ -60,7 +65,8 @@
     (try
       (f)
       (finally
-        (lifecycle/stop server nil)))))
+        (lifecycle/stop server nil)
+        (alter-var-root (var esr/*endpoint*) (constantly current-endpoint))))))
 ;; Run once for the whole test suite
 (use-fixtures :once server-setup)

@@ -75,7 +81,6 @@
       (esi/delete "tests"))))
 ;; Run once for each test to clear out data.
 (use-fixtures :each index-setup)
-

 (deftest save-with-increment-versions-test


Add render with new name

Add render with new name

--- test/com/wsscode/pathom/connect/planner_test.cljc
+++ test/com/wsscode/pathom/connect/planner_test.cljc
@@ -23,7 +23,17 @@
    ::pcp/available-data     {}
    ::p/placeholder-prefixes #{">"}})

-(defn render-graph [{::pcp/keys [nodes root] :as graph} env]
+(defn find-next-file-name [prefix]
+  (loop [n         1
+         file-name (str prefix ".png")]
+    (let [file (io/file file-name)]
+      (if (.exists file)
+        (recur
+          (inc n)
+          (str prefix "-" n ".png"))
+        file-name))))
+
+(defn render-graph [{::pcp/keys [nodes root] :as graph} {::keys [file-name] :as env}]
   #?(:clj
      (if (not (System/getenv "PATHOM_TEST"))
        (let [edges (into []
@@ -46,9 +56,11 @@
                                                      :style "filled"
                                                      :color (if (= node-id root) "blue" "#F3F3F3")
                                                      :label (str
-                                                              (or (::pc/sym node)
-                                                                  (if (::pcp/run-and node) "AND")
-                                                                  (if (::pcp/run-or node) "OR")))}
+                                                              (or
+                                                                (::pcp/source-sym node)
+                                                                (::pc/sym node)
+                                                                (if (::pcp/run-and node) "AND")
+                                                                (if (::pcp/run-or node) "OR")))}
                                               (get-in env [::pc/index-resolvers (::pc/sym node) ::pc/dynamic-resolver?])
                                               (assoc
                                                 :fontcolor "white"
@@ -61,8 +73,11 @@
                                               (::pcp/run-or node)
                                               (assoc
                                                 :fillcolor "cyan"))))})]
-         (io/copy (tangle/dot->image dot "png") (io/file "out.png")))))
+         (io/copy (tangle/dot->image dot "png") (io/file (or file-name "out.png"))))))
   graph)
+
+(defn render-graph-next [out env]
+  (render-graph out (assoc env ::file-name (find-next-file-name "out"))))

 (defn compute-run-graph* [{::keys [out env]}]
   (pcp/compute-run-graph


Simplified the pre-post seperation code generated in build-contract

--- src/fogus/me/trammel.clj
+++ src/fogus/me/trammel.clj
@@ -103,48 +103,24 @@
     ([f x] {:pre [(foo x)] :post [(bar %)]} (f x))
   "
   [cnstr]
-  (println "FOO!")
   (let [[args pre-post-map] cnstr]
-    (list (into '[f] args)
-          (list 'let ['ret (list 'try
-                                 (list (list 'fn []
-                                             (select-keys pre-post-map [:pre])
-                                             (list* 'f (mapcat (fn [item]
-                                                                 (cond (symbol? item) [item]
-                                                                       (map? item) [(:as item)]
-                                                                       :else [item]))
-                                                               args))))
-                                 (list 'catch 'AssertionError 'pre
-                                       (list 'throw (list 'AssertionError. (list 'str "Pre-condition failure! " (list '.getMessage 'pre))))))]
-                (list 'try
-                      (list (list 'fn []
-                                  (select-keys pre-post-map [:post])
-                                  'ret
-                                  ))
-                      (list 'catch 'AssertionError 'post
-                            (list 'throw (list 'AssertionError. (list 'str "Post-condition failure! " (list '.getMessage 'post))))))))))
-
-(comment
-  (build-contract '[[x y] {:pre [(number? x)] :post [(pos? %)]}])
-
-  (defn foo [f n]
-    (let [ret (try
-                ((fn []
-                   {:pre [(number? n)]}
-                   (f n n)))
-                (catch AssertionError pre
-                  (throw (AssertionError. (str "Pre-condition failure! " (.getMessage pre))))))]
-      (try
-        ((fn []
-           {:post [(pos? %)]}
-           ret))
-        (catch AssertionError post
-          (throw (AssertionError. (str "Post-condition failure! " (.getMessage post))))))))
-
-  (foo + 1)
-  (foo + 'a)
-  (foo + -4)
-)
+    `(~(into '[f] args)
+      (let [ret# (try
+                   ((fn []
+                      ~(select-keys pre-post-map [:pre])
+                      ~(list* 'f (mapcat (fn [item]
+                                           (cond (symbol? item) [item]
+                                                 (map? item) [(:as item)]
+                                                 :else [item]))
+                                         args))))
+                   (catch AssertionError pre#
+                     (throw (AssertionError. (str "Pre-condition failure! " (.getMessage pre#))))))]
+        (try
+          ((fn []
+             ~(select-keys pre-post-map [:post])
+             ret#))
+          (catch AssertionError post#
+            (throw (AssertionError. (str "Post-condition failure! " (.getMessage post#))))))))))

 (defmacro contract
   "The base contract form returning a higher-order function that can then be partially
@@ -236,6 +212,20 @@
     `(defn ~name
        ~(if (:doc mdata) (:doc mdata) "")
        ~@body)))
+
+(comment
+  (defn foo [a b]
+    ((contract blah [a_ b_] [=> pos?])
+     (fn [a b] (+ a b))
+     a
+     b))
+
+  (let [con (contract blah [a_ b_] [=> pos?])]
+    (defn foo
+      "blah"
+      ([a]
+         (con ()))))
+  )

 (defmacro provide-contracts [& contracts]
   (let [fn-names  (map first contracts)
@@ -319,15 +309,15 @@
   (defconstrainedtype Bar [a 4 b 8] [(every? pos? [a b])])
   (Bar? (new-Bar))

-(defn sqr [n]
-  (* n n))
-
-(provide-contracts
- [sqr "The constraining of sqr" [n] [number? (not= 0 n) => pos? number?]])
-
-(sqr 0)
-
- (positive-nums -1)
+  (defn sqr [n]
+    (* n n))
+
+  (provide-contracts
+   [sqr "The constraining of sqr" [n] [number? (not= 0 n) => pos? number?]])
+
+  (sqr 0)
+
+  (positive-nums -1)

   (type (new-Bar))


Add infor icon component when media-received equals false

--- src/hatti/ona/forms.cljs
+++ src/hatti/ona/forms.cljs
@@ -237,11 +237,29 @@
           ?"
             answer help-url error-message)))

+(defn infor-icon-component
+  "Returns an infor icon with a tooltip message"
+  [answer & {:keys [media-count total-media]}]
+  (format "%s
+
+
Total media files expected :  %s
+

+
Total media files received :  %s
+
"
+          answer total-media media-count))
+
 (defn format-answer
   "String representation for a particular field datapoint (answer).
    re-formatting depends on field type, eg. name->label substitution.
    Optional: compact? should be true if a short string needs to be returned."
-  [field answer & {:keys [language compact? label field-key media record-modal?]
+  [field answer & {:keys [language
+                          compact?
+                          label
+                          field-key
+                          media
+                          record-modal?
+                          media-count
+                          total-media]
                    :or {field-key :name record-modal? false}}]
   (cond
     (string/blank? answer) no-answer
@@ -310,7 +328,10 @@
             (if-let [currency (some->> label (re-find currency-regex))]
               (str currency (cl-format nil "~:d" answer))
               answer)
-            (format-multiline-answer answer))))
+            (if (= (str answer) "false")
+              (infor-icon-component answer :media-count media-count
+                                    :total-media total-media)
+              (format-multiline-answer answer)))))

 (defn relabel-meta-field
   "Try and produce a label for meta field if non-existent."


some work

some work

--- src/main/cawala/api/pathom.clj
+++ src/main/cawala/api/pathom.clj
@@ -23,3 +23,8 @@
                  p/error-handler-plugin
                  p/request-cache-plugin
                  p/trace-plugin]}))
+
+(comment
+  p/env-wrap-plugin
+
+  )


drop :cljs case for cljs.env/ensure macro

--- src/main/clojure/cljs/env.cljc
+++ src/main/clojure/cljs/env.cljc
@@ -70,6 +70,4 @@
           ~@body
           (finally
             (if (nil? val#)
-              (pop-thread-bindings))))))
-   :cljs
-   (def ensure identity))
+              (pop-thread-bindings)))))))


Add load-config to config.

Add load-config to config.

--- src/incise/config.clj
+++ src/incise/config.clj
@@ -1,7 +1,16 @@
 (ns incise.config
+  (:require [clojure.java.io :refer [reader file resource]]
+            [clojure.edn :as edn])
+  (:import [java.io PushbackReader])
   (:refer-clojure :exclude [assoc get]))

 (def ^:private config (atom {}))
+
+(defn load-config []
+  (when-let [config-file (file (resource "incise.edn"))]
+    (reset! config (edn/read (PushbackReader. (reader config-file))))))
+
+(load-config)

 (defn assoc [& args]
   (apply swap! config assoc args))


Change model? to check for records

Change model? to check for records

Calling values with a keyword is not always safe or free of side effects, since
model? is called on every loaded var we need to be more conservative.

--- src/toucan/models.clj
+++ src/toucan/models.clj
@@ -378,9 +378,11 @@
   ([model k v & more]
    (apply (resolve 'toucan.db/select-one) model k v more)))

-(def ^:const ^{:arglists '([model])} ^Boolean model?
+(defn model?
   "Is model a valid toucan model?"
-  ::model)
+  [model]
+  (and (record? model)
+       (::model model)))

 ;; We use the same record type (e.g., `DatabaseInstance`) for both the "model" (e.g., `Database`) and objects fetched
 ;; from the DB ("instances"). Model definitions have the key `::model` assoced so we can differentiate.


expect unique output from each test job

expect unique output from each test job

--- test/cu/web_test.clj
+++ test/cu/web_test.clj
@@ -72,12 +72,12 @@
                     (web-app (-> (request :delete "/logs") logged-in))
                     (create-git-repo repo-url
                                      {:pipeline
-                                      {:first-ls  {:repo   repo-url
-                                                   :script "ls"}
-                                       :downstream   {:second-ls   {:repo    repo-url
-                                                                    :script  "ls"}
-                                                      :hostname    {:repo    repo-url
-                                                                    :script  "hostname"}}}})
+                                      {:ls  {:repo   repo-url
+                                             :script "ls"}
+                                       :downstream   {:whoami     {:repo    repo-url
+                                                                   :script  "whoami"}
+                                                      :hostname   {:repo    repo-url
+                                                                   :script  "hostname"}}}})
                     (web-app (-> (request :post "/push") logged-in
                                  (body {:payload json-payload})))
                     (core/parser test-config)
@@ -88,8 +88,11 @@
                         :body
                         (split #"\n")))))

+(defn shell-output [command]
+  (trim-newline (:out (sh command))))
+
 (expect 3 (count log-output))
 (expect "cu.yml" (first log-output))
-(expect "cu.yml" (in (rest log-output)))
-(expect (trim-newline (:out (sh "hostname"))) (in (rest log-output)))
+(expect (shell-output "whoami") (in (rest log-output)))
+(expect (shell-output "hostname") (in (rest log-output)))


Revert spacing change.

Revert spacing change.

--- src/konserve/memory.cljc
+++ src/konserve/memory.cljc
@@ -42,11 +42,10 @@
   the read and write-handlers are dummy ones for compatibility."
   ([] (new-mem-store (atom {})))
   ([init-atom]
-   (go
-     (map->MemoryStore {:state init-atom
-                        :read-handlers (atom {})
-                        :write-handlers (atom {})
-                        :locks (atom {})}))))
+   (go (map->MemoryStore {:state init-atom
+                          :read-handlers (atom {})
+                          :write-handlers (atom {})
+                          :locks (atom {})}))))

 (comment


Destroy devtools-client along with parent browser - close #1975

When a browser tab was closed, it left behind its devtools-client object. This
caused a bug with the :clear-console command which would find these
dangling objects with a closed socket and raise an exception when trying
to send a message to it

--- src/lt/objs/browser.cljs
+++ src/lt/objs/browser.cljs
@@ -139,6 +139,7 @@
                   :triggers #{:close}
                   :reaction (fn [this]
                               (object/raise this :inactive)
+                              (object/destroy! (:devtools-client @this))
                               (object/destroy! this)))

 (behavior ::rem-client


`clojure.core/map` -> `cljs.core/map`

`clojure.core/map` -> `cljs.core/map`

--- src/main/om_css/dom.cljs
+++ src/main/om_css/dom.cljs
@@ -59,13 +59,14 @@

 (defn format-class-names [this-arg cns]
   (string/join " "
-    (cljs.core/map #(format-class-name this-arg %)
+    (cljs.core/map #(cond->> %
+                      (keyword? %) (format-class-name this-arg))
       (if (sequential? cns) cns [cns]))))

 (defn- format-attrs [this-arg attrs]
   "leaves :className unchanged, formats :class accordingly"
   (->> attrs
-    (clojure.core/map
+    (cljs.core/map
       (fn [[k v]]
         [(format-opt-key k)
          (if (= k :class)


Added compile-conexp to conexp.clj

Added compile-conexp to conexp.clj

to not to have conexp recompiled every time it is used.

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

--- conexp.clj
+++ conexp.clj
@@ -1,17 +1,17 @@
 (ns conexp
   (:use [clojure.contrib.ns-utils :only (immigrate)]))
+
+(defn compile-conexp []
+  (compile 'conexp.fca.contexts)
+  (compile 'conexp.fca.implications)
+  (compile 'conexp.fca.lattices)
+  (compile 'conexp.gui.repl))
+
+(compile-conexp)

 ; Use immigrate, so that all imports behave as if they were defined in here.
 ; Thus (use 'conexp) makes sense.

-(immigrate 'conexp.base)
-
-(compile 'conexp.fca.contexts)
-(compile 'conexp.fca.implications)
-(compile 'conexp.fca.lattices)
-
-(immigrate 'conexp.fca)
-
-(compile 'conexp.gui.repl)
-
-(immigrate 'conexp.gui)+(immigrate 'conexp.base
+	   'conexp.fca
+	   'conexp.gui)


func moved

func moved

--- src/webdriver/api.clj
+++ src/webdriver/api.clj
@@ -51,6 +51,9 @@
   (cond
     (char? text) [text]
     :else (vec text)))
+
+(defn parse-element [data]
+  (-> data first second))

 (defn b64-to-file [b64str filename]
   (with-open [out (io/output-stream filename)]
@@ -193,9 +196,6 @@
   (api server :post
        [:session (session-id session) :window :fullscreen]))

-(defn parse-element [data]
-  (-> data first second))
-
 ;; todo ff only
 (defn get-active-element [server session]
   "https://www.w3.org/TR/webdriver/#dfn-get-active-element"


core: not-every?

core: not-every?

--- data/core.clj
+++ data/core.clj
@@ -1292,3 +1292,11 @@
     (nil? (seq coll)) true
     (pred (first coll)) (recur pred (next coll))
     :else false))
+
+(def
+  ^{:tag Bool
+    :doc "Returns false if (pred x) is logical true for every x in
+         coll, else true."
+         :arglists '([pred coll])
+         :added "1.0"}
+  not-every? (comp not every?))


removed ugly workaround

removed ugly workaround

--- src/org/domaindrivenarchitecture/pallet/crate/managed_vm/basics.clj
+++ src/org/domaindrivenarchitecture/pallet/crate/managed_vm/basics.clj
@@ -31,15 +31,3 @@
   (actions/package "bash-completion")
   (actions/package "lsof")
   (actions/package "strace"))
-
-(defn workaround-user-ownership
-  "files in /home/user are created by root but should be owned by user"
-  [os-user-name]
-  (actions/exec
-       {:language :bash}
-       (stevedore/script
-         (str
-         "chown -R " ~os-user-name ":" ~os-user-name " /home/" ~os-user-name "/.anacron\n"
-         "chown -R " ~os-user-name ":" ~os-user-name " /home/" ~os-user-name "/.config\n"
-         "chown -R " ~os-user-name ":" ~os-user-name " /home/" ~os-user-name "/.ssh\n"))))
-


kept dispatch fn 'open' by using def-many-methods

--- src/midje/semi_sweet.clj
+++ src/midje/semi_sweet.clj
@@ -54,33 +54,27 @@
      :arrow '~arrow }
      (hash-map-duplicates-ok ~@overrides)))

-(letfn [(how-to-handle-check [_call-form_ arrow & _]
-          (get {=> :expect*
-                =not=> :expect*
-                =deny=> :expect*
-                =expands-to=> :expect-macro*
-                =future=> :report-future-fact} (name arrow)))]
+(defmulti ^{:private true} expect-expansion (fn [_call-form_ arrow & _]
+                                              (name arrow)))

-  (defmulti ^{:private true} expect-expansion how-to-handle-check))
-
-(defmethod expect-expansion :expect*
+(def-many-methods expect-expansion [=> =not=> =deny=>]
   [call-form arrow expected-result fakes overrides]
   `(let [check# (unprocessed-check ~call-form ~arrow ~expected-result ~overrides)]
      (midje.semi-sweet/*expect-checking-fn* check# ~fakes)))

-(defmethod expect-expansion :expect-macro*
+(defmethod expect-expansion =expands-to=>
   [call-form _arrow_ expected-result fakes overrides]
   (let [expanded-macro `(macroexpand-1 '~call-form)
         escaped-expected-result `(quote ~expected-result)]
     (expect-expansion expanded-macro => escaped-expected-result fakes overrides)))

-(defmethod expect-expansion :report-future-fact
-   [call-form arrow expected-result _fakes_ overrides]
-   `(let [check# (unprocessed-check ~call-form ~arrow ~expected-result ~overrides)]
-      (within-fact-context ~(str call-form)
-        (clojure.test/report {:type :future-fact
-                              :description @midje.internal-ideas.fact-context/nested-descriptions
-                              :position (:position check#)}))))
+(defmethod expect-expansion =future=>
+  [call-form arrow expected-result _fakes_ overrides]
+  `(let [check# (unprocessed-check ~call-form ~arrow ~expected-result ~overrides)]
+     (within-fact-context ~(str call-form)
+       (clojure.test/report {:type :future-fact
+                             :description @midje.internal-ideas.fact-context/nested-descriptions
+                             :position (:position check#)}))))

 ;;; Interface: unfinished


fix issue with Gorman drip

fix issue with Gorman drip

--- src/node/game/cards.cljs
+++ src/node/game/cards.cljs
@@ -483,8 +483,8 @@
    "Gorman Drip v1"
    {:abilities [{:cost [:click 1] :effect (effect (gain :credit (:counter card)) (trash card))
                  :msg (msg "gain " (:counter card) " [Credits]")}]
-    :events {:corp-click-credit {:effect (effect (add-prop card :counter 1))}
-             :corp-click-draw {:effect (effect (add-prop card :counter 1))}}}
+    :events {:corp-click-credit {:effect (effect (add-prop :runner card :counter 1))}
+             :corp-click-draw {:effect (effect (add-prop :runner card :counter 1))}}}

    "Government Contracts"
    {:abilities [{:cost [:click 2] :effect (effect (gain :credit 4)) :msg "gain 4 [Credits]"}]}


Fix topic URL generation.

Fix topic URL generation.

--- src/oc/email/content.clj
+++ src/oc/email/content.clj
@@ -178,7 +178,7 @@
 (defn- topic [snapshot topic-name topic]
   (let [company-slug (:company-slug snapshot)
         snapshot-slug (:slug snapshot)
-        topic-url (s/join "/" [config/web-url company-slug "updates" snapshot-slug topic-name "?src=email"])]
+        topic-url (s/join "/" [config/web-url company-slug "updates" snapshot-slug (str topic-name "?src=email")])]
     (if (:data topic)
       (data-topic snapshot topic-name topic topic-url)
       (content-topic snapshot topic-name topic topic-url))))


More readable json data.

More readable json data.

--- src/oc/email/content.clj
+++ src/oc/email/content.clj
@@ -368,21 +368,21 @@

 (defn- go-to-posts-script [data]
   [:script {:type "application/ld+json"}
-    "{"
-      "\"@context\": \"http://schema.org\","
-      "\"@type\": \"EmailMessage\","
-      "\"description\": \"" (digest-title (:org-name data) (weekly-digest? data)) "\","
-      "\"potentialAction\": {"
-        "\"@type\": \"ViewAction\","
-        "\"target\": \"" (get-digest-url data) "\","
-        "\"name\": \"Go to posts\""
-      "},"
-      "\"publisher\": {"
-        "\"@type\": \"Organization\","
-        "\"name\": \"Carrot\","
-        "\"url\": \"" config/web-url "\","
-      "}"
-    "}"])
+"{
+  \"@context\": \"http://schema.org\",
+  \"@type\": \"EmailMessage\",
+  \"description\": \"" (digest-title (:org-name data) (weekly-digest? data)) "\",
+  \"potentialAction\": {
+  \"@type\": \"ViewAction\",
+    \"target\": \"" (get-digest-url data) "\",
+    \"name\": \"Go to posts\"
+  },
+  \"publisher\": {
+    \"@type\": \"Organization\",
+    \"name\": \"Carrot\",
+    \"url\": \"" config/web-url "\",
+  }
+}"])

 (defn- digest-content [digest]
   (let [logo-url (:logo-url digest)


s/small/medium/

s/small/medium/

--- src/babel/italiano/writer.clj
+++ src/babel/italiano/writer.clj
@@ -10,16 +10,16 @@
 (require '[clojure.tools.logging :as log])
 (require '[dag_unify.core :refer (fail? get-in strip-refs unify)])

-(def small (grammar/small))  ;; TODO use medium consistently
+(def model (grammar/medium))

 (defn expression [spec]
-  (generate/generate small spec))  ;; TODO use medium consistently
+  (generate/generate model spec))

 (defn fo [spec]
   (morph/fo spec))

 (defn rewrite-lexicon []
-  (let [lexicon (:lexicon small)] ;; TODO use medium consistently
+  (let [lexicon (:lexicon model)]
     (write-lexicon "it" lexicon)))

 (declare generate-one-verb)
@@ -30,7 +30,7 @@
                     true (Integer. count))
         ;; subset of the lexicon: only verbs which are infinitives and that can be roots:
         ;; (i.e. those that have a specific (non- :top) value for [:synsem :sem :pred])
-        lexicon (:lexicon small) ;; TODO use medium consistently
+        lexicon (:lexicon model)
         lexemes
         (cond (nil? lexeme) (vals lexicon)
               (= "all" lexeme) (vals lexicon)


tests for info hiding

tests for info hiding

--- src/ontrail/exercise.clj
+++ src/ontrail/exercise.clj
@@ -93,6 +93,12 @@
   ([viewing-user rule page]
      (get-latest-ex-list viewing-user rule page {:lastModifiedDate -1})))

+(defn comment-hiding? [viewing-user ex]
+  (let [user (:user ex)]
+        (or (= "nobody" viewing-user)
+            (and (= "LauraIsabella" viewing-user) (= "Ursa Minor" (:user ex)))
+            (and (= "LauraIsabella" viewing-user) (= "Peppi" (:user ex))))))
+
 (defn get-ex
   ([viewing-user id]
      (.info logger (str "User " viewing-user " getting ex with id " id))
@@ -102,6 +108,6 @@
        (if (nil? exercise)
          {:error "No such id"}
          (let [ex (as-ex-result exercise)]
-           (if (= "nobody" viewing-user)
+           (if (comment-hiding? viewing-user ex)
              (dissoc ex :comments)
              ex))))))


Make client be able to submit a flexible number of jobs, and await completion of all jobs

--- src/onyx_jepsen/core.clj
+++ src/onyx_jepsen/core.clj
@@ -155,10 +155,23 @@
 (defn get-written-ledgers [onyx-client job-data onyx-id]
   (onyx.plugin.bookkeeper/read-ledgers-data (:log onyx-client)
                                             onyx-id
-                                            (:job-id @job-data)
-                                            (get-in @job-data [:task-ids :persist :id])))
-
-(defrecord WriteLogClient [client job-data ledger-handles ledger-handle ledger-ids onyx-client]
+                                            (:job-id job-data)
+                                            (get-in job-data [:task-ids :persist :id])))
+
+
+(defn close-ledger-handles [ledger-handles]
+  (mapv (fn [h]
+          (try (.close h)
+               (catch Throwable t
+                 (info "Error closing handle" t))))
+        ledger-handles))
+
+(defn await-jobs-completions [peer-config jobs-data]
+  (mapv (fn [job-data]
+          (onyx.api/await-job-completion peer-config (:job-id job-data)))
+        jobs-data))
+
+(defrecord WriteLogClient [client jobs-data ledger-handles ledger-handle ledger-ids onyx-client]
   client/Client
   (setup! [this test node]
     (let [client (bookkeeper-client)
@@ -172,7 +185,7 @@
     (let [zk-addr (:zookeeper/address env-config)
           onyx-id (:onyx/id env-config)]
       (case (:f op)
-        :read-peer-log (timeout 4000
+        :read-peer-log (timeout 1000000
                                 (assoc op :type :info :value :timed-out)
                                 (try
                                   (assoc op
@@ -185,13 +198,9 @@
                                                  (try
                                                    (assoc op
                                                           :type :ok
-                                                          :value (do
-                                                                   (mapv (fn [h]
-                                                                           (try (.close h)
-                                                                                (catch Throwable t
-                                                                                (info "Error closing handle" t))))
-                                                                         @ledger-handles)
-                                                                   (onyx.api/await-job-completion peer-config (:job-id @job-data))))
+                                                          :value (do (close-ledger-handles @ledger-handles)
+                                                                     (await-jobs-completions peer-config @jobs-data)
+                                                                     nil))
                                                    (catch Throwable t
                                                      (assoc op :type :info :value t))))
         :read-ledgers (timeout 1000000
@@ -199,7 +208,11 @@
                                (try
                                  (assoc op
                                         :type :ok
-                                        :value (mapv read-ledger-entries (get-written-ledgers onyx-client job-data onyx-id)))
+                                        ;; FIXME: mapcatting everything together for now
+                                        :value (mapv read-ledger-entries
+                                                     (mapcat (fn [job-data]
+                                                               (get-written-ledgers onyx-client job-data onyx-id))
+                                                             @jobs-data)))
                                  (catch Throwable t
                                    (assoc op :type :info :value t))))

@@ -217,12 +230,17 @@
                              (try
                                (assoc op
                                       :type :ok
-                                      :value (->> (simple-job/build-job 1
-                                                                        zk-addr
-                                                                        (onyx.log.zookeeper/ledgers-path onyx-id)
-                                                                        @ledger-ids)
-                                                  (onyx.api/submit-job peer-config)
-                                                  (reset! job-data)))
+                                      :value (let [ledgers (nth (partition-all (/ (count @ledger-ids)
+                                                                                (:n-jobs op))
+                                                                               @ledger-ids)
+                                                                (:job-num op))
+                                                   job-data (->> (simple-job/build-job (:params op)
+                                                                                zk-addr
+                                                                                (onyx.log.zookeeper/ledgers-path onyx-id)
+                                                                                ledgers)
+                                                                 (onyx.api/submit-job peer-config))]
+                                               (swap! jobs-data conj job-data)
+                                               job-data))
                                (catch Throwable t
                                  (assoc op :type :info :value t))))

@@ -238,8 +256,8 @@
   (teardown! [_ test]
     (.close client)))

-(defn write-log-client [job-data ledger-handles ledger-ids]
-  (->WriteLogClient nil job-data ledger-handles nil ledger-ids nil))
+(defn write-log-client [jobs-data ledger-handles ledger-ids]
+  (->WriteLogClient nil jobs-data ledger-handles nil ledger-ids nil))

 ;; Not actually used for anything currently
 (defrecord OnyxModel []
@@ -274,6 +292,16 @@
   []
   (gen/clients (gen/once {:type :invoke :f :close-ledgers-await-completion})))

+(defn submit-job-gen [n-jobs]
+  (->> (range n-jobs)
+       (map (fn [n]
+              {:type :invoke
+               :f :submit-job
+               :job-num n
+               :n-jobs n-jobs
+               :params {:batch-size 1}}))
+       gen/seq))
+
 (def os
   (reify os/OS
     (setup! [_ test node]
@@ -286,34 +314,43 @@
 (defn basic-test
   "A simple test of Onyx's safety."
   [version]
-  (merge tests/noop-test
-         {:os os
-          :db (setup version)
-          :client (write-log-client (atom nil) (atom []) (atom []))
-          :model (->OnyxModel) ;; Not actually used for anything currently
-          :checker (onyx-checker/->Checker peer-config (:n-peers peer-setup))
-          :generator (gen/phases
-                       (->> (onyx-gen/filter-new identity
-                                                 (onyx-gen/frequency [(adds)
-                                                                      ;(gen/once (gc-peer-logs))
-                                                                      (gen/once
-                                                                        (gen/each
-                                                                          {:type :invoke :f :submit-job}))]
-                                                                     [0.98
-                                                                      ;0.01
-                                                                      0.01]))
-                            (gen/stagger 1/10)
-                            ;(gen/delay 1)
-                            (gen/nemesis
-                              (gen/seq (cycle
-                                         [(gen/sleep 30)
-                                          {:type :info :f :start}
-                                          (gen/sleep 200)
-                                          {:type :info :f :stop}])))
-                            (gen/time-limit 4000))
-                       (close-await-completion-gen)
-                       (read-ledgers-gen)
-                       (read-peer-log-gen))
-          ;:nemesis (nemesis/partitioner (comp nemesis/bridge shuffle))
-          :nemesis (nemesis/partition-random-halves)
-          }))
+  ;; TODO, have map with test parameters in edn
+  (let [n-jobs 1]
+    (merge tests/noop-test
+           {:os os
+            :db (setup version)
+            :client (write-log-client (atom []) (atom []) (atom []))
+            :model (->OnyxModel) ;; Currently not actually used for anything
+            :checker (onyx-checker/->Checker peer-config (:n-peers peer-setup))
+            :generator (gen/phases
+                         (->> (onyx-gen/filter-new identity
+                                                   (onyx-gen/frequency [(adds)
+                                                                        (submit-job-gen n-jobs)
+                                                                        ;(gen/once (gc-peer-logs))
+                                                                        ]
+                                                                       [0.98
+                                                                        ;0.01
+                                                                        0.01]))
+                              (gen/stagger 1/10)
+                              ;(gen/delay 1)
+                              (gen/nemesis
+                                (gen/seq (cycle
+                                           [(gen/sleep 30)
+                                            {:type :info :f :start}
+                                            (gen/sleep 200)
+                                            {:type :info :f :stop}])))
+                              (gen/time-limit 14000))
+
+                         ;; Bring everything back at the end
+                         ;; This way we can test that the peers came back up
+                         (gen/nemesis (gen/once {:type :info :f :stop}))
+                         ;; Sleep for a while to give peers a chance to come back up
+                         ;; Should be enough time that curator backoff * max-retries is covered
+                         (gen/sleep 120)
+
+                         (close-await-completion-gen)
+                         (read-ledgers-gen)
+                         (read-peer-log-gen))
+            ;:nemesis (nemesis/partitioner (comp nemesis/bridge shuffle))
+            :nemesis (nemesis/partition-random-halves)
+            })))


Make page background a tad lighter

Make page background a tad lighter

--- src/braid/ui/styles/body.cljs
+++ src/braid/ui/styles/body.cljs
@@ -6,7 +6,7 @@
     :padding 0
     :font-family "\"Open Sans\", Helvetica, Arial, sans-serif"
     :font-size "12px"
-    :background "#eee"}
+    :background "#F2F2F2"}
    [:textarea :input
     {:font-family "inherit"
      :font-size "1em"}]])


Remove dead code

Remove dead code

--- src/catalog/layout/dtbook.clj
+++ src/catalog/layout/dtbook.clj
@@ -95,33 +95,7 @@
       [:p {:brl:class (format "jr_%s" (layout/year date))}]]]
     [:bodymatter
      [:level1 [:h1 "Editorial"] [:p "..."]]
-     (for [genre layout/braille-genres] (genre-entries genre items))]
-    ;; [:rearmatter
-    ;;  [:level1 [:h1 "Impressum"]
-    ;;   [:level2 [:h2 title]
-    ;;    [:p "Für Kundinnen und Kunden der SBS sowie für Interessenten"]
-    ;;    [:p "Erscheint kostenlos sechsmal jährlich und listet alle seit der letzten Ausgabe neu in die SBS aufgenommenen Braillebücher auf"]
-    ;;    [:p (str "Herausgeber: " creator)]
-    ;;    [:p "Abonnement: medienverlag@sbs.ch"]]
-    ;;   [:level2 [:h2 "Ausleihe und Verkauf"]
-    ;;    [:p creator]
-    ;;    [:p "Grubenstrasse 12"]
-    ;;    [:p "CH-8045 Zürich"]
-    ;;    [:p "Fon +41 43 333 32 32"]
-    ;;    [:p "Fax +41 43 333 32 33"]
-    ;;    [:p "www.sbs.ch"]
-    ;;    [:p "Ausleihe/Verkauf Privatpersonen: nutzerservice@sbs.ch"]
-    ;;    [:p "Verkauf Institutionen: medienverlag@sbs.ch"]]]
-    ;;  [:level1 [:h1 "Einführungsrabatt"]
-    ;;   [:p "Die in dieser Ausgabe vorgestellten Rucksackbücher können während zweier Monate mit einem Einführungsrabatt von 20% (ringgebunden ohne Deckel) bestellt werden. Danach gilt der in diesem Heft angegebene Buchhandelspreis (ringgebunden mit Deckel)."]]
-    ;;  [:level1 [:h1 "Abkürzungen"]
-    ;;   [:p
-    ;;    [:list {:type "pl"}
-    ;;     [:li "Bd. = Band, Bände"]
-    ;;     [:li "K = Kurzschrift"]
-    ;;     [:li "V = Vollschrift"]
-    ;;     [:li "wtz = weitzeilige Vollschrift"]]]]]
-    ]])
+     (for [genre layout/braille-genres] (genre-entries genre items))]]])

 (defn dtbook
   [items]


cleaned up namespace.

cleaned up namespace.

--- src/clj/forma/source/fire.clj
+++ src/clj/forma/source/fire.clj
@@ -1,6 +1,6 @@
 (ns forma.source.fire
   (:use cascalog.api
-        [forma.date-time :only (datetime->period current-period)]
+        [forma.date-time :only (datetime->period)]
         [clojure.string :only (split)]
         [forma.source.modis :only (latlon->modis
                                    hv->tilestring)])


fix HSJ typo, reformat Blackmail

fix HSJ typo, reformat Blackmail

--- src/clj/game/cards-events.clj
+++ src/clj/game/cards-events.clj
@@ -32,18 +32,14 @@
    "Blackmail"
    {:req (req (> (:bad-publicity corp) 0)) :prompt "Choose a server" :choices (req servers)
     :msg "prevent ICE from being rezzed during this run"
-    :effect (effect
-              (register-run-flag!
-                          card
-                          :can-rez
-                                   (fn [state side card]
-                                     (if (ice? card)
-                                       ( (constantly false) (system-msg state side (str "is prevented from rezzing ICE on this run by Blackmail")))
-                                       true
-                                       )
-                                     )
-                          )
-              (run target nil card))}
+    :effect (effect (register-run-flag!
+                      card
+                      :can-rez
+                      (fn [state side card]
+                        (if (ice? card)
+                          ((constantly false) (system-msg state side (str "is prevented from rezzing ICE on this run by Blackmail")))
+                          true)))
+                    (run target nil card))}

    "Bribery"
    {:prompt "How many [Credits]?" :choices :credit
@@ -265,14 +261,14 @@
                    :msg "force the Corp to trash 1 card from HQ at random"
                    :effect (effect (trash (first (shuffle (:hand corp)))))}}}

-   "High-stakes Job"
+   "High-Stakes Job"
    {:prompt "Choose a server"
     :choices (req (let [unrezzed-ice #(seq (filter (complement rezzed?) (:ices (second %))))
                         ok-servs (filter unrezzed-ice (get-in @state [:corp :servers]))]
                     (map (comp zone->name first) ok-servs)))
     :effect (effect (run target {:end-run {:req (req (:successful run)) :msg " gain 12 [Credits]"
                                            :effect (effect (gain :runner :credit 12))}} card))}
-
+
    "Hostage"
    {:prompt "Choose a Connection"
     :choices (req (cancellable (filter #(has-subtype? % "Connection") (:deck runner)) :sorted))


forgot query parameter wrapper

forgot query parameter wrapper

--- src/clj/hdfs_cleaner/core.clj
+++ src/clj/hdfs_cleaner/core.clj
@@ -8,6 +8,7 @@
             [manifold.deferred :as d]
             [cheshire.core :as json]
             [ring.util.response :refer [content-type]]
+            [ring.middleware.params :as params]
             [compojure.core :refer :all]
             [compojure.route :as route]
             [aleph.http :as http]
@@ -49,16 +50,18 @@
            (fn [response]
              (update response :headers dissoc "transfer-encoding"))))

-(defn app [req]
-  (log/debug {:type "request" :content req})
-  (d/chain
-    (-> req
-        (app-routes)
-        (d/catch
-          (fn [e]
-            (log/error e "Error on tracking")
-            (http-res/error 500 (.getMessage e)))))
-    encode-response-to-json))
+(def app
+  (params/wrap-params
+    (fn [req]
+      (log/debug {:type "request" :content req})
+      (d/chain
+        (-> req
+            (app-routes)
+            (d/catch
+              (fn [e]
+                (log/error e "Error on tracking")
+                (http-res/error 500 (.getMessage e)))))
+        encode-response-to-json))))

 (def ^:private ^:const aleph-config
   {:port 4050