Clarify how args are passed around in run and junction-steps #162

--- test/clj/lambdacd/steps/control_flow_test.clj
+++ test/clj/lambdacd/steps/control_flow_test.clj
@@ -22,6 +22,9 @@
 (defn some-step-returning-cwd [{cwd :cwd} & _]
   {:given-cwd cwd :status :success})

+(defn some-step-returning-its-args [args ctx]
+  {:status :success :args args})
+
 (defn some-step-taking-100ms [arg & _]
   (Thread/sleep 100)
   {:foo :bar :status :success})
@@ -193,6 +196,19 @@
   (testing "that it stops after the first failure"
     (is (map-containing {:outputs { [1 0 0] {:status :success} [2 0 0] {:status :failure}} :status :failure}
                         ((run some-successful-step some-failing-step some-other-step) {} (some-ctx-with :step-id [0 0])))))
+  (testing "that it pipes its args ito the first step"
+    (is (map-containing {:outputs {[1 0 0] {:status :success :args {:initial :args}}}}
+                        ((run some-step-returning-its-args)
+                          {:initial :args} (some-ctx-with :step-id [0 0])))))
+  (testing "that it pipes the initial arguments as well as the result of the previous step into subsequent steps"
+    (is (map-containing {:outputs {[1 0 0] {:status :success :the-number 42}
+                                   [2 0 0] {:status :success :args {:initial :args
+                                                                    :status :success
+                                                                    :the-number 42
+                                                                    :global nil}}}}
+                        ((run some-step-that-returns-42
+                              some-step-returning-its-args)
+                          {:initial :args} (some-ctx-with :step-id [0 0])))))
   (testing "that it kills all children if it is killed"
     (let [is-killed (atom true)
           ctx       (some-ctx-with :is-killed is-killed
@@ -291,6 +307,17 @@
   (testing "that it executes the failure-step if the condition is a failure"
     (is (map-containing {:outputs {[3 0 0] {:status :success :message :bar}}}
                         ((junction some-failing-step some-step-that-returns-foo some-step-that-returns-bar) {} (some-ctx-with :step-id [0 0])))))
+  (testing "that branches receive the junctions arguments"
+    (is (map-containing {:outputs {[2 0 0] {:status :success
+                                            :args {:some :arg}}}}
+                        ((junction some-successful-step
+                                   some-step-returning-its-args
+                                   some-step-that-returns-bar) {:some :arg} (some-ctx-with :step-id [0 0]))))
+    (is (map-containing {:outputs {[3 0 0] {:status :success
+                                            :args {:some :arg}}}}
+                        ((junction some-failing-step
+                                   some-step-that-returns-foo
+                                   some-step-returning-its-args) {:some :arg} (some-ctx-with :step-id [0 0])))))
   (testing "that it kills all children if it is killed"
     (let [is-killed (atom true)
           ctx       (some-ctx-with :is-killed is-killed


Update comments in android-java project.clj

--- src/clojure/leiningen/new/android_java/project.clj
+++ src/clojure/leiningen/new/android_java/project.clj
@@ -1,6 +1,5 @@
 (defproject {{raw-name}} "0.1.0-SNAPSHOT"
   :description "FIXME: write description"
-  ;:resource-paths ["libs/android-support-v13.jar"]
   :java-source-paths ["src" "gen"]
   :java-only true
   :profiles {:dev {:android {:aot :all-with-unused}}
@@ -16,7 +15,41 @@
             ;; here or in your ~/.lein/profiles.clj file.
             ;; :sdk-path "/home/user/path/to/android-sdk/"

-            ;; Uncomment this if dexer fails with OutOfMemoryException
+            ;; Specify this if your project is a library.
+            ;; :library false
+
+            ;; Uncomment this if dexer fails with OutOfMemoryException.
             ;; :force-dex-optimize true

+            ;; Options to pass to dx executable, former is for general
+            ;; java-related options and later is for 'dex task'-specific options.
+            ;; :dex-opts ["-JXmx4096M"]
+            ;; :dex-aux-opts ["--num-threads=2"]
+
+            ;; Proguard config for "droid create-obfuscated-dex" task.
+            ;; :proguard-conf-path "proguard.cfg"
+            ;; :proguard-opts ["-printseeds"]
+
+            ;; Uncomment this line to be able to use Google API.
+            ;; :use-google-api true
+
+            ;; Use this property to add project dependencies.
+            ;; :project-dependencies [ "/path/to/library/project" ]
+
+            ;; Sequence of external jars or class folders to include
+            ;; into project, e.g. android-support-v4.jar
+            ;; :external-classes-paths ["<sdk-home>/extras/android/support/v4/android-support-v4.jar"
+            ;;                          "path/to/classfiles/"]
+
+            ;; sequence of paths where native libraries may be found for packaging
+            ;; :native-libraries-paths ["libs"]
+
+            ;; Minimum supported version could be specified as well,
+            ;; its meaning is similar to that in AndroidManifest.xml.
+            ;; :min-version "10"
+
+            ;; Sequence of namespaces that should not be compiled.
+            ;:aot-exclude-ns ["clojure.parallel" "clojure.core.reducers"]
+
+            ;; Target version affects api used for compilation.
             :target-version "15"})


Update to ClojureScript 1.9.521

Update to ClojureScript 1.9.521

--- planck-cljs/project.clj
+++ planck-cljs/project.clj
@@ -1,6 +1,6 @@
 (defproject planck "0.1.0"
   :profiles {:dev
-             {:dependencies [[org.clojure/clojurescript "1.9.518"]
+             {:dependencies [[org.clojure/clojurescript "1.9.521"]
                              [org.clojure/test.check "0.9.0"]
                              [tubular "1.0.0"]]
               :source-paths ["dev"]}
@@ -9,7 +9,7 @@
              :build-commit
              {}}
   :dependencies [[org.clojure/clojure "1.8.0"]
-                 [org.clojure/clojurescript "1.9.518"]
+                 [org.clojure/clojurescript "1.9.521"]
                  [org.clojure/test.check "0.9.0"]
                  [org.clojure/tools.reader "1.0.0-beta4"]
                  [tailrecursion/cljson "1.0.7"]


Update lein plugins.

Update lein plugins.

--- .lein/profiles.clj
+++ .lein/profiles.clj
@@ -1,19 +1,18 @@
 {:user {:dependencies [[clj-stacktrace "0.2.5"]
-                       [spyscope "0.1.0"]]
-        :plugins [
-                  ;[lein-tarsier "0.9.4-SNAPSHOT"]
-                  ;[lein-swank "1.4.4"]
-                  [lein-difftest "1.3.7"]
+                       [spyscope "0.1.0"]
+                       [nrepl-transcript "0.1.0"]
+                       [limit-break "0.1.0-SNAPSHOT"]]
+        :plugins [[lein-difftest "1.3.7"]
                   [lein-clojars "0.9.1"]
-                  ;[jark/jark-server "0.4.0"]
                   [lein-pprint "1.1.1"]
-                  [lein-ring "0.7.5"]
-                  [slamhound "1.3.0"]
+                  [lein-ring "0.8.0"]
+                  [slamhound "1.3.1"]
                   [lein-cljsbuild "0.1.9"]
                   [lein-deps-tree "0.1.2"]
-                  ;[lein-autodoc "0.9.0"]
                   [lein-marginalia "0.7.1"]]
-        :repl-options {:timeout 120000}
+        :repl-options {:timeout 120000
+                       :nrepl-middleware
+                       [nrepl-transcript.file/wrap-file-transcript]}
         :injections [(let [orig (ns-resolve (doto 'clojure.stacktrace require)
                                             'print-cause-trace)
                            new (ns-resolve (doto 'clj-stacktrace.repl require)


Fixed archive sorting

Fixed archive sorting

--- src/leiningen/new/cryogen/src/cryogen/compiler.clj
+++ src/leiningen/new/cryogen/src/cryogen/compiler.clj
@@ -61,13 +61,17 @@
       (merge
         (update-in page-meta [:layout] #(str (name %) ".html"))
         {:file-name file-name
-         :content content
-         :toc (if (:toc page-meta) (generate-toc content))}
+         :content   content
+         :toc       (if (:toc page-meta) (generate-toc content))}
         (if is-post?
-          {:date          (parse-post-date file-name)
-           :archive-group (.format (java.text.SimpleDateFormat. "yyyy MMMM" (java.util.Locale. "en")) (parse-post-date file-name))
-           :uri           (post-uri file-name config)
-           :tags          (set (:tags page-meta))}
+          (let [date (parse-post-date file-name)
+                archive-fmt (java.text.SimpleDateFormat. "yyyy MMMM" (java.util.Locale. "en"))
+                formatted-group (.format archive-fmt date)]
+            {:date                    date
+             :formatted-archive-group formatted-group
+             :parsed-archive-group    (.parse archive-fmt formatted-group)
+             :uri                     (post-uri file-name config)
+             :tags                    (set (:tags page-meta))})
           {:uri        (page-uri file-name config)
            :page-index (:page-index page-meta)})))))

@@ -92,9 +96,14 @@

 (defn group-for-archive [posts]
   (->> posts
-       (map #(select-keys % [:archive-group :title :uri :date]))
-       (group-by :archive-group)
-       (map (fn [[group posts]] {:group group :posts posts}))))
+       (map #(select-keys % [:title :uri :date :formatted-archive-group :parsed-archive-group]))
+       (group-by :formatted-archive-group)
+       (map (fn [[group posts]]
+              {:group         group
+               :parsed-group (:parsed-archive-group (get posts 0))
+               :posts         (map #(select-keys % [:title :uri :date]) posts)}))
+       (sort-by :parsed-group)
+       reverse))

 (defn tag-info [{:keys [blog-prefix tag-root]} tag]
   {:name (name tag)
@@ -181,7 +190,7 @@
       config
       {:page-root (root-path :page-root config)
        :post-root (root-path :post-root config)
-       :tag-root (root-path :tag-root config)})))
+       :tag-root  (root-path :tag-root config)})))

 (defn compile-assets []
   (println (green "compiling assets..."))


abstracting json

abstracting json

--- src/ophion/core.clj
+++ src/ophion/core.clj
@@ -28,6 +28,10 @@
 ;;   (Logger/ROOT_LOGGER_NAME))
 ;;  Level/INFO)

+(defn read-json
+  [body]
+  (json/parse-stream (InputStreamReader. body) keyword))
+
 (defn append-newline
   [s]
   (str s "\n"))
@@ -72,7 +76,7 @@

 (defn vertex-query-handler
   [graph search cache request]
-  (let [raw-query (json/parse-stream (InputStreamReader. (:body request)) keyword)
+  (let [raw-query (read-json (:body request))
         ;; query (query/delabelize raw-query)
         _ (log/info (mapv identity (query/delabelize raw-query)))
         ;; out (check-query-cache graph search cache query)
@@ -122,7 +126,7 @@

 (defn save-query-handler
   [graph search mongo request]
-  (let [query (json/parse-stream (InputStreamReader. (:body request)) keyword)
+  (let [query (read-json (:body request))
         relevant (select-keys query [:user :key :focus :path :query :current])]
     (log/info query)
     (store/store-query {:graph graph :search search} mongo relevant)
@@ -139,7 +143,7 @@

 (defn query-comparison-handler
   [mongo request]
-  (let [queries (json/parse-stream (InputStreamReader. (:body request)) keyword)
+  (let [queries (read-json (:body request))
         comparison (store/query-comparison mongo (:queries queries))]
     (log/info "queries" queries)
     {:status 200
@@ -250,7 +254,7 @@
         schema (protograph/graph-structure protograph)
         mongo (mongo/connect! (get config :mongo))
         routes (polaris/build-routes (ophion-routes graph search schema mongo))
-        router (resource/wrap-resource (polaris/router routes) "public")
+        router (polaris/router routes) "public"
         app (-> router
                 (resource/wrap-resource "public")
                 (keyword/wrap-keyword-params)


CMR-5106 Fixes granule acl conditions.

CMR-5106 Fixes granule acl conditions.

--- search-app/src/cmr/search/services/acls/granule_acls.clj
+++ search-app/src/cmr/search/services/acls/granule_acls.clj
@@ -152,7 +152,6 @@
         (gc/or-conds [concept-ids-cond entry-titles-cond])
         (or concept-ids-cond entry-titles-cond)))))

-
 (defn collection-identifier->query-condition
   "Converts an acl collection identifier to an query condition. Switches implementations based
   on whether the user's query contained collection ids. This implementation assumes the query-coll-ids
@@ -165,9 +164,12 @@
             access-value-cond (some-> (access-value->query-condition access-value)
                                       q/->CollectionQueryCondition)
             temporal-cond (some-> temporal temporal->query-condition q/->CollectionQueryCondition)]
-
         ;; If there's no entry title condition the other conditions must be scoped by provider
-        (gc/and-conds (remove nil? [(or entry-titles-cond colls-in-prov-cond)
+        ;; In anycase we want to use concept ids instead of entry-titles, because entry-titles can and
+        ;; do frequently change, so to prevent temporary loss of permissions concept ids are used
+        ;; when present.  There really shouldn't be a case where entry-tiles exist and concept-ids do
+        ;; not.
+        (gc/and-conds (remove nil? [(or colls-in-prov-cond entry-titles-cond)
                                     access-value-cond
                                     temporal-cond])))
       ;; No other collection info provided so every collection in provider is possible


Add clojure.pprint/pprint alias

Add clojure.pprint/pprint alias

--- etc/scratch.clj
+++ etc/scratch.clj
@@ -2,6 +2,7 @@
   (:require [clojure.test :as test]
             [clojure.repl :as repl]
             [eftest.runner :as eftest]
+            clojure.pprint
             [clojure.tools.namespace.find :as ns.find]
             [clojure.tools.namespace.repl :as ns.repl]
             [clojure.java.io :as io])
@@ -17,10 +18,12 @@
 (scratch/time+ \"tag\"  (some expr)) - like time, but better
 (scratch/refresh) - refresh all namespaces
 (scrtach/refresh-all) - refresh all project + dep namespaces
+(scratch/pp) alias for clojure.pprint/pprint
 (scratch/list-ns) - find all namespaces in SRC"))

 (def refresh ns.repl/refresh)
 (def refresh-all ns.repl/refresh-all)
+(def pp clojure.pprint/pprint)

 (defn list-ns
   "Return list of symbols of namespaces found in src dir"


For #64, reduce deeply nested list comprehension by splitting logic into a separate function.

--- src/main/clojure/clara/rules/compiler.clj
+++ src/main/clojure/clara/rules/compiler.clj
@@ -477,28 +477,37 @@
    :default 0
    ))

+(defn- get-conds
+  "Returns a sequence of [condition environment] tuples and their corresponding productions."
+  [production]
+
+  (let [lhs-expression (into [:and] (:lhs production)) ; Add implied and.
+        expression  (to-dnf lhs-expression)
+        disjunctions (if (= :or (first expression))
+                       (rest expression)
+                       [expression])]
+
+    (for [disjunction disjunctions
+
+          :let [conditions (if (and (vector? disjunction)
+                                    (= :and (first disjunction)))
+                             (rest disjunction)
+                             [disjunction])
+
+                ;; Sort conditions, see the condition-comp function for the reason.
+                sorted-conditions (sort condition-comp conditions)
+
+                ;; Attach the conditions environment. TODO: narrow environment to those used?
+                conditions-with-env (for [condition sorted-conditions]
+                                      [condition (:env production)])]]
+
+      [conditions-with-env production])))
+
+
 (sm/defn to-beta-tree :- [schema/BetaNode]
   "Convert a sequence of rules and/or queries into a beta tree. Returns each root."
   [productions :- [schema/Production]]
-  (let [conditions (for [production productions
-                         :let [lhs-expression (into [:and] (:lhs production)) ; Add implied and.
-                               expression  (to-dnf lhs-expression)]
-                         disjunction (if (= :or (first expression))
-                                       (rest expression)
-                                       [expression])
-                         :let [conditions (if (and (vector? disjunction)
-                                                   (= :and (first disjunction)))
-                                            (rest disjunction)
-                                            [disjunction])
-
-                               ;; Sort conditions, see the condition-comp function for the reason.
-                               sorted-conditions (sort condition-comp conditions)
-
-                               ;; Attach the conditions environment. TODO: narrow environment to those used?
-                               conditions-with-env (for [condition sorted-conditions]
-                                                     [condition (:env production)])]]
-
-                     [conditions-with-env production])
+  (let [conditions (mapcat get-conds productions)

         raw-roots (reduce
                    (fn [beta-roots [conditions production]]


error out on top-level cond-splice

error out on top-level cond-splice

--- src/main/clojure/clojure/tools/reader.clj
+++ src/main/clojure/clojure/tools/reader.clj
@@ -175,20 +175,22 @@
 (defonce ^:private READ_EOF (Object.))
 (defonce ^:private READ_FINISHED (Object.))

+(def ^:dynamic *read-delim* false)
 (defn- ^PersistentVector read-delimited
   "Reads and returns a collection ended with delim"
   [delim rdr opts pending-forms]
   (let [[start-line start-column] (starting-line-col-info rdr)
         delim (char delim)]
-    (loop [a (transient [])]
-      (let [form (read* rdr false READ_EOF delim opts pending-forms)]
-        (if (identical? form READ_FINISHED)
-          (persistent! a)
-          (if (identical? form READ_EOF)
-            (reader-error rdr "EOF while reading"
-                          (when start-line
-                            (str ", starting at line " start-line " and column " start-column)))
-            (recur (conj! a form))))))))
+    (binding [*read-delim* true]
+      (loop [a (transient [])]
+        (let [form (read* rdr false READ_EOF delim opts pending-forms)]
+          (if (identical? form READ_FINISHED)
+            (persistent! a)
+            (if (identical? form READ_EOF)
+              (reader-error rdr "EOF while reading"
+                            (when start-line
+                              (str ", starting at line " start-line " and column " start-column)))
+              (recur (conj! a form)))))))))

 (defn- read-list
   "Read in a list, including its location if the reader is an indexing reader"
@@ -487,6 +489,9 @@
   (if-let [ch (read-char rdr)]
     (let [splicing (= ch \@)
           ch (if splicing (read-char rdr) ch)]
+      (when splicing
+        (when-not *read-delim*
+          (reader-error rdr "cond-splice not in list")))
       (if-let [ch (if (whitespace? ch) (read-past whitespace? rdr) ch)]
         (if (not= ch \()
           (throw (RuntimeException. "read-cond body must be a list"))
@@ -689,7 +694,7 @@
                :else (resolve-symbol form)))))

     (unquote? form) (second form)
-    (unquote-splicing? form) (throw (IllegalStateException. "splice not in list"))
+    (unquote-splicing? form) (throw (IllegalStateException. "unquote-splice not in list"))

     (coll? form)
     (cond


Clarify d/<connect.

Clarify d/<connect.

--- test/datomish/api.cljc
+++ test/datomish/api.cljc
@@ -20,14 +20,9 @@
 (defn <connect [uri]
   ;; Eventually, URI.  For now, just a plain path (no file://).
   (go-pair
-    (->
-      (sqlite/<sqlite-connection uri)
-      (<?)
-
-      (db-factory/<db-with-sqlite-connection)
-      (<?)
-
-      (transact/connection-with-db))))
+    (let [conn (<? (sqlite/<sqlite-connection uri))
+          db (<? (db-factory/<db-with-sqlite-connection conn))]
+      (transact/connection-with-db db))))

 (def <transact! transact/<transact!)


fixes the build | fs / sg

fixes the build | fs / sg

--- src/cljs/conference_rating/add_conference_page/add_conference_page.cljs
+++ src/cljs/conference_rating/add_conference_page/add_conference_page.cljs
@@ -103,7 +103,9 @@
       [:div {:class "row"}
        [:div {:class "col-lg-2"}]
        [:div {:class "col-lg-8"}
-        [:form {:on-submit #(on-click-function doc)}
+        [:form {:on-submit #(do
+                             (on-click-function doc)
+                             false)}
          [:div {:class "add-conference-form-container bg-light"}
           [forms/bind-fields (conference-form-template doc) doc]
           [:input {:type "submit"


wip on scrolling

wip on scrolling

--- frontend/controllers/post_controls.cljs
+++ frontend/controllers/post_controls.cljs
@@ -1,13 +1,18 @@
 (ns frontend.controllers.post-controls
   (:require [cljs.core.async :as async :refer [>! <! alts! chan sliding-buffer put! close!]]
             [clojure.string :as string]
+            [dommy.core :as dommy]
             [frontend.controllers.api :as api]
+            goog.dom
+            goog.dom.classes
             [goog.string :as gstring]
             goog.string.format
+            goog.style
             [frontend.intercom :as intercom]
             [frontend.utils.vcs-url :as vcs-url]
             [frontend.utils :as utils :refer [mlog]])
-  (:require-macros [frontend.utils :refer [inspect]]))
+  (:require-macros [frontend.utils :refer [inspect]]
+                   [dommy.macros :refer [node sel sel1]]))

 (defmulti post-control-event!
   (fn [target message args previous-state current-state] message))
@@ -95,4 +100,31 @@

 (defmethod post-control-event! :container-selected
   [target message container-id previous-state current-state]
-  (assoc-in state [:current-build :current-container-id] container-id))
+  (when-not (= (get-in previous-state [:current-build :current-container-id])
+               container-id)
+    (let [parent (sel1 target "#container_parent")
+          width (.-width (goog.style/getSize parent))
+          new-scroll-left (+ (.-scrollLeft parent)
+                             (.-x (goog.style.getPosition (sel1 target (str "#container_" container-id)))))
+          new-scroll-left (* width container-id)]
+      (println "new scroll left" new-scroll-left)
+      (set! (.-scrollLeft parent) new-scroll-left))))
+
+(defmethod post-control-event! :container-parent-scroll
+  [target message _ previous-state current-state]
+  (let [controls-ch (get-in current-state [:comms :controls])
+        current-container-id (get-in current-state [:current-build :current-container-id])
+        parent (sel1 target "#container_parent")
+        container-width (.-width (goog.style/getSize parent))
+        parent-scroll-left (.-scrollLeft parent)
+        parent-scroll-ratio (/ parent-scroll-left container-width)
+        current-selected-container-scroll-left (* container-width current-container-id)
+        ;; if we're scrolling left, then we want the container whose rightmost portion is showing
+        ;; if we're scrolling right, then we want the container whose leftmost portion is showing
+        new-scrolled-container-id (if (> parent-scroll-left current-selected-container-scroll-left)
+                                    (js/Math.ceil parent-scroll-ratio)
+                                    (js/Math.floor parent-scroll-ratio))]
+    ;; This is kind of dangerous, we could end up with an infinite loop. Might want to
+    ;; do a swap here (or find a better way to structure this!)
+    (when-not (= new-scrolled-container-id current-container-id)
+      (put! controls-ch [:container-selected new-scrolled-container-id]))))


add renderer option to applet config docstring

--- src/quil/applet.clj
+++ src/quil/applet.clj
@@ -135,13 +135,14 @@
 (defn applet
   "Create and start a new visualisation applet.

-  :size           - a vector of width, height and optional renderer
-                    (one of :p2d, :java2d, :opengl, :pdf or :dxf). i.e.
-                    [500 300] or [400 600 :opengl].
-                    Defaults to [500 300].
-
   :title          - a string which will be displayed at the top of
                     the applet window.
+
+  :size           - a vector of width and height. Defaults to
+                    [500 300].
+
+  :renderer       - The renderer to use. (one of :p2d, :java2d,
+                    :opengl, :pdf or :dxf). Defaults to :java2d.

   :setup          - a fn to be called once when setting the applet up.


Multiline regex

Multiline regex

--- src/atom_finder/classifier/macro-operator-precedence.clj
+++ src/atom_finder/classifier/macro-operator-precedence.clj
@@ -116,7 +116,7 @@
 (s/defn expansion-args-tree
   "Take the arguments to a macro and parse them into ASTs"
   [exp :- IASTPreprocessorMacroExpansion]
-  (let [arg-expr (some->> exp str (re-find #"\w+\((.*)\)") second parse-frag-clean)]
+  (let [arg-expr (some->> exp str (re-find #"(?s)\w+\((.*)\)") second parse-frag-clean)]
     (when arg-expr
       (if (instance? IASTExpressionList arg-expr)
         (children arg-expr)


figwheel.main: config printing

figwheel.main: config printing

--- figwheel-main/src/figwheel/main.cljc
+++ figwheel-main/src/figwheel/main.cljc
@@ -290,6 +290,12 @@

 (declare serve update-config)

+(defn print-conf [cfg]
+  (println "---------------------- Figwheel options ----------------------")
+  (pprint (::config cfg))
+  (println "---------------------- Compiler options ----------------------")
+  (pprint (:options cfg)))
+
 (defn serve-main-opt [repl-env-fn args b-cfg]
   (let [{:keys [::config repl-env-options repl-options] :as cfg}
         (-> b-cfg
@@ -300,8 +306,11 @@
                       "
index.html not found
"))
         {:keys [pprint-config]} config
         repl-env (apply repl-env-fn (mapcat identity repl-env-options))]
+    (log/trace "Verbose config:" (with-out-str (pprint cfg)))
     (if pprint-config
-      (clojure.pprint/pprint cfg)
+      (do
+        (log/info ":pprint-config true - printing config:")
+        (print-conf cfg))
       (serve {:repl-env repl-env
               :repl-options repl-options
               :join? true}))))
@@ -881,8 +890,11 @@
     (binding [*base-config* cfg
               *config* b-cfg]
       (cljs.env/with-compiler-env cenv
+        (log/trace "Verbose config:" (with-out-str (pprint b-cfg)))
         (if pprint-config
-          (do (clojure.pprint/pprint b-cfg) b-cfg)
+          (do
+            (log/info ":pprint-config true - printing config:")
+            (print-conf b-cfg))
           (binding [cljs.repl/*repl-env* repl-env
                     figwheel.core/*config* (select-keys config [:hot-reload-cljs])]
             (let [fw-mode? (figwheel-mode? b-cfg)]
@@ -892,7 +904,7 @@
                                                 ::start-figwheel-options
                                                 config))
                 (doseq [init-fn (::initializers b-cfg)] (init-fn))
-                (log/debug "Figwheel.core config:" (pr-str figwheel.core/*config*))
+                (log/trace "Figwheel.core config:" (pr-str figwheel.core/*config*))
                 (figwheel.core/start*)
                 (cond
                   (= mode :repl)


Add content tests

Add content tests

--- test/io/perun_test.clj
+++ test/io/perun_test.clj
@@ -2,6 +2,7 @@
   (:require [boot.core :as boot :refer [deftask]]
             [boot.test :as boot-test :refer [deftesttask]]
             [clojure.java.io :as io]
+            [clojure.string :as str]
             [clojure.test :refer [deftest testing is]]
             [io.perun :as p]
             [io.perun.meta :as pm])
@@ -121,53 +122,100 @@
   [data]
   (str "<body>" (:content (:entry data)) "</body>"))

-(deftesttask markdown-test []
-  (comp (p/collection :renderer 'io.perun-test/render) ;; test #77, collection works without input files
-
-        (add-txt-file :path "2017-01-01-test.md" :content md-content)
+(deftesttask default-tests []
+  (comp (add-txt-file :path "2017-01-01-test.md" :content md-content)
         (boot/with-pre-wrap fileset
           (pm/set-global-meta fileset {:base-url "http://example.com/"
                                        :site-title "Test Title"
                                        :description "Test Desc"}))
         (p/markdown)
-        (content-test :path "2017-01-01-test.html" :content parsed-md)
-        (value-test :path "2017-01-01-test.md" :value-fn #(meta= % :parsed parsed-md))
+        (testing "markdown"
+          (content-test :path "2017-01-01-test.html" :content parsed-md)
+          (value-test :path "2017-01-01-test.md" :value-fn #(meta= % :parsed parsed-md)))

         (p/ttr)
-        (value-test :path "2017-01-01-test.html" :value-fn #(meta= % :ttr 1))
+        (testing "ttr"
+          (value-test :path "2017-01-01-test.html" :value-fn #(meta= % :ttr 1)))

         (p/word-count)
-        (value-test :path "2017-01-01-test.html" :value-fn #(meta= % :word-count 18))
+        (testing "word-count"
+          (value-test :path "2017-01-01-test.html" :value-fn #(meta= % :word-count 18)))

         (p/gravatar :source-key :email :target-key :gravatar)
-        (value-test :path "2017-01-01-test.html" :value-fn #(meta= % :gravatar "http://www.gravatar.com/avatar/a1a361f6c96acb1e31ad4b3bbf7aa444"))
+        (testing "gravatar"
+          (value-test :path "2017-01-01-test.html"
+                      :value-fn
+                      #(meta= % :gravatar "http://www.gravatar.com/avatar/a1a361f6c96acb1e31ad4b3bbf7aa444")))

         (p/build-date)
-        (key-test :path "2017-01-01-test.html" :key :date-build)
+        (testing "build-date"
+          (key-test :path "2017-01-01-test.html" :key :date-build))

         (p/slug)
-        (value-test :path "2017-01-01-test.html" :value-fn #(meta= % :slug "test"))
+        (testing "slug"
+          (value-test :path "2017-01-01-test.html" :value-fn #(meta= % :slug "test")))

         (p/permalink)
-        (value-test :path "2017-01-01-test.html" :value-fn #(meta= % :permalink "/test/index.html"))
+        (testing "permalink"
+          (value-test :path "2017-01-01-test.html" :value-fn #(meta= % :permalink "/test/index.html")))

         (p/canonical-url)
-        (value-test :path "2017-01-01-test.html" :value-fn #(meta= % :canonical-url "http://example.com/test/index.html"))
+        (testing "canonical-url"
+          (value-test :path "2017-01-01-test.html"
+                      :value-fn #(meta= % :canonical-url "http://example.com/test/index.html")))

         (p/sitemap)
-        (file-exists? :path "public/sitemap.xml")
+        (testing "sitemap"
+          (file-exists? :path "public/sitemap.xml"))

         (p/rss)
-        (file-exists? :path "public/feed.rss")
+        (testing "rss"
+          (file-exists? :path "public/feed.rss"))

         (p/atom-feed)
-        (file-exists? :path "public/atom.xml")
+        (testing "atom-feed"
+          (file-exists? :path "public/atom.xml"))

         (p/render :renderer 'io.perun-test/render)

         (add-txt-file :path "test.js" :content js-content)
         (p/inject-scripts :scripts #{"test.js"})
-        (content-test :path "public/test/index.html" :content (str "<script>" js-content "</script>"))
+        (testing "inject-scripts"
+          (content-test :path "public/test/index.html" :content (str "<script>" js-content "</script>")))

         (p/draft)
-        (file-exists? :path "2017-01-01-test.html" :negate? true)))
+        (testing "draft"
+          (file-exists? :path "2017-01-01-test.html" :negate? true))))
+
+(deftesttask content-tests []
+  (comp (testing "Collection works without input files" ;; #77
+          (p/collection :renderer 'io.perun-test/render))
+
+        (add-txt-file :path "test.md" :content md-content)
+        (p/markdown) ;; render once
+
+        (add-txt-file :path "test.md" :content (str/replace md-content #"Hello" "Salutations"))
+        (p/markdown)
+        (testing "detecting content changes"
+          (content-test :path "test.html" :content "Salutations"))
+
+        (add-txt-file :path "test.md" :content (str/replace md-content #"draft: true" "draft: false"))
+        (p/markdown)
+        (testing "detecting metadata changes"
+          (value-test :path "test.html" :value-fn #(meta= % :draft false)))
+
+        (add-txt-file :path "test.md" :content (str/replace md-content #"draft: true" "draft: true\nfoo: bar"))
+        (p/markdown)
+        (testing "detecting metadata additions"
+          (value-test :path "test.html" :value-fn #(meta= % :foo "bar")))
+
+        (add-txt-file :path "test.md" :content md-content)
+        (p/markdown)
+        (testing "detecting metadata deletions"
+          (value-test :path "test.html" :value-fn #(meta= % :foo nil)))
+
+        (add-txt-file :path "test2.md" :content md-content)
+        (p/markdown)
+        (testing "detecting new files"
+          (content-test :path "test2.html" :content parsed-md)
+          (value-test :path "test2.md" :value-fn #(meta= % :parsed parsed-md)))))


fixed typo fn

fixed typo fn

--- desktop/src-common/con_world/screen-main.clj
+++ desktop/src-common/con_world/screen-main.clj
@@ -93,7 +93,7 @@
              (let [[screen entities] (may-spawn-enemy screen entities)]

                (when debug-physics?
-                 (draw-phisics-bodies screen))
+                 (draw-physics-bodies screen))

                (if (player-dead? entities)


Prevent namespace collisions in the future.

--- support/clojure-test-support/src/main/clojure/immutant/test/helpers.clj
+++ support/clojure-test-support/src/main/clojure/immutant/test/helpers.clj
@@ -31,12 +31,12 @@
 (defmethod assert-expr 'not-thrown? [msg form]
   ;; (is (not-thrown? c expr))
   ;; Asserts that evaluating expr does not throw an exception of class c.
-  (let [klass (second form)
-        body (nthnext form 2)]
-    `(try ~@body
+  (let [klass# (second form)
+        body# (nthnext form 2)]
+    `(try ~@body#
           (do-report {:type :pass, :message ~msg,
                    :expected '~form, :actual '~form})
-          (catch ~klass e#
+          (catch ~klass# e#
             (do-report {:type :fail, :message ~msg,
                      :expected '~form, :actual e#})
             e#))))
@@ -44,6 +44,6 @@
 (defmacro deftest-pending
   [name & body]
    ;; borrowed from http://techbehindtech.com/2010/06/01/marking-tests-as-pending-in-clojure/
-   (let [message (str "\n========\nPENDING: " name "\n========\n")]
+   (let [message# (str "\n========\nPENDING: " name "\n========\n")]
      `(deftest ~name
-        (println ~message))))
+        (println ~message#))))


resolved merge conflict

resolved merge conflict

--- integration/dda/pallet/dda_managed_vm/app/instantiate_existing.clj
+++ integration/dda/pallet/dda_managed_vm/app/instantiate_existing.clj
@@ -25,12 +25,6 @@
     [dda.pallet.dda-managed-vm.app :as app]
     [dda.pallet.dda-managed-vm.app.external-config :as ext-config]))

-<<<<<<< HEAD
-(defn hallo []
- (app/app-configuration (ext-config/user-config) (ext-config/vm-config)))
-
-=======
->>>>>>> 067163df0a6529598c1f020f626965a62454db21
 (def ssh-pub-key
   (user-env/read-ssh-pub-key-to-config))


[#2438] Add and adapt tests

[#2438] Add and adapt tests

--- backend/test/akvo/lumen/lib/transformation_test.clj
+++ backend/test/akvo/lumen/lib/transformation_test.clj
@@ -74,7 +74,7 @@
 (defn async-tx-apply [{:keys [tenant-conn] :as deps} dataset-id command]
   (let [[tag {:keys [jobExecutionId datasetId]} :as res] (transformation/apply deps dataset-id command)
         [job _] (retry-job-execution tenant-conn jobExecutionId true)]
-    (conj res (:status job))))
+    (conj res (:status job) job)))

 (defn latest-data [dataset-id]
   (let [table-name (:table-name
@@ -129,7 +129,7 @@

 (deftest ^:functional test-transformations
   (testing "Transformation application"
-    (is (= [::lib/bad-request {:message "Dataset not found"} nil]
+    (is (= [::lib/bad-request {:message "Dataset not found"} nil nil]
            (async-tx-apply {:tenant-conn *tenant-conn*} "Not-valid-id" []))))
   (testing "Valid log"
     (let [dataset-id (import-file *tenant-conn* *error-tracker* {:name "Transformation Test"
@@ -370,6 +370,17 @@
               {:rnum 2 :c1 "b" :c2 3.0 :c3 nil}
               {:rnum 3 :c1 nil :c2 4.0 :c3 5.0}])))

+    (testing "js references a non existent row"
+      (let [[_ _ status job] (apply-transformation {:type :transformation
+                                       :transformation
+                                       (gen-transformation "core/derive"
+                                                           {::transformation.derive.s/newColumnTitle "Derived 1"
+                                                            ::transformation.derive.s/code "row['oops'].toUpperCase()"
+                                                            ::transformation.derive.s/newColumnType "text"
+                                                            ::transformation.engine.s/onError "leave-empty"})})]
+        (is (= status "FAILED"))
+        (is (= (:error-message job) "Failed to transform: Column 'oops' doesn't exist."))))
+
     (testing "Basic text transform"
       (apply-transformation {:type :transformation
                              :transformation
@@ -432,7 +443,7 @@
                                            :transformation
                                            (gen-transformation "core/derive"
                                                                {::transformation.derive.s/newColumnTitle "Derived 6"
-                                                                ::transformation.derive.s/code "new Date()"
+                                                                ::transformation.derive.s/code "new Date().getTime()+row.bar"
                                                                 ::transformation.derive.s/newColumnType "date"
                                                                 ::transformation.engine.s/onError "fail"})})]
         (is (= tag ::lib/ok))


Adapt to beicon 3.x.y changes.

Adapt to beicon 3.x.y changes.

--- src/potok/core.cljs
+++ src/potok/core.cljs
@@ -92,9 +92,8 @@
   (js/console.error error)
   (rx/throw error))

-(enable-console-print!)
-
 (def ^:private noop (constantly nil))
+(def ^:private max-safe-integer js/Number.MAX_SAFE_INTEGER)

 ;; --- Public API

@@ -127,19 +126,19 @@
            state-sm (->> (rx/filter update? input-sb)
                          (rx/scan (partial process-update input-sb) state)
                          (rx/catch handle-error)
-                         (rx/retry 1024))
+                         (rx/retry max-safe-integer))
            watch-sm (->> (rx/filter watch? input-sb)
-                         (rx/with-latest-from vector state-sb)
+                         (rx/with-latest vector state-sb)
                          (rx/flat-map (partial process-watch input-sb))
                          (rx/catch handle-error)
-                         (rx/retry 1024))
+                         (rx/retry max-safe-integer))
            effct-sm (->> (rx/filter effect? input-sb)
-                         (rx/with-latest-from vector state-sb)
+                         (rx/with-latest vector state-sb)
                          (rx/do (partial handle-effect input-sb))
                          (rx/catch handle-error)
-                         (rx/retry 1024))
-           subs     (rx/subscribe state-sm state-sb)
-           subw     (rx/subscribe watch-sm input-sb)
+                         (rx/retry max-safe-integer))
+           subs     (rx/subscribe-with state-sm state-sb)
+           subw     (rx/subscribe-with watch-sm input-sb)
            sube     (rx/subscribe effct-sm noop)
            stoped?  (volatile! false)]
        (specify! state-sb
@@ -153,12 +152,12 @@
                 (rx/map identity)
                 (rx/share)))

-         Object
-         (close [_]
+         rx/ICancellable
+         (-cancel [_]
            (vreset! stoped? true)
-           (.unsubscribe subs)
-           (.unsubscribe subw)
-           (.unsubscribe sube)
+           (rx/cancel! subs)
+           (rx/cancel! subw)
+           (rx/cancel! sube)
            (rx/end! input-sb)))))))

 (defn emit!


Remove deprecated expect-eval-actual-first macro :new:

--- test/metabase/test/util.clj
+++ test/metabase/test/util.clj
@@ -62,27 +62,7 @@
       form))

-;; By default `expect` evaluates EXPECTED first. This isn't always what we want; for example, sometime API tests affect the DB
-;; and we'd like to check the results.
-(defmacro ^:deprecated -doexpect [e a]
-  `(let [a# (try ~a (catch java.lang.Throwable t# t#))
-         e# (try ~e (catch java.lang.Throwable t# t#))]
-     (report
-      (try (compare-expr e# a# '~e '~a)
-           (catch java.lang.Throwable e2#
-             (compare-expr e2# a# '~e '~a))))))
-
-(defmacro ^:deprecated expect-eval-actual-first
-  "Identical to `expect` but evaluates `actual` first (instead of evaluating `expected` first).
-   DEPRECATED: You shouldn't need to use this when writing new tests. `expect-with-temp` should be used instead, as it handles cleaning up after itself."
-  {:style/indent 0}
-  [expected actual]
-  (let [fn-name (gensym)]
-    `(def ~(vary-meta fn-name assoc :expectation true)
-       (fn [] (-doexpect ~expected ~actual)))))
-
-
-;; ## random-name
+;;; random-name
 (let [random-uppercase-letter (partial rand-nth (mapv char (range (int \A) (inc (int \Z)))))]
   (defn random-name
     "Generate a random string of 20 uppercase letters."


Finish renaming upstream <-> downstream in the client tests

--- test/picard/test/client.clj
+++ test/picard/test/client.clj
@@ -70,12 +70,12 @@
    [{:path-info          "/"
      :request-method     "GET"
      "transfer-encoding" "chunked"} :chunked]
-   (fn [upstream evt val]
+   (fn [downstream evt val]
      (enqueue ch2 [evt val])
      (when (= :connected evt)
-       (upstream :body "Foo!")
-       (upstream :body "Bar!")
-       (upstream :done nil))))
+       (downstream :body "Foo!")
+       (downstream :body "Bar!")
+       (downstream :done nil))))

   (is (next-msgs-for
        ch1
@@ -127,12 +127,12 @@
      "transfer-encoding" "chunked"
      "connection"        "close"}
     :chunked]
-   (fn [upstream-fn evt val]
+   (fn [downstream evt val]
      (enqueue ch2 [evt val])
      (when (= :connected evt)
-       (upstream-fn :body "HELLO")
-       (upstream-fn :body "WORLD")
-       (upstream-fn :done nil))))
+       (downstream :body "HELLO")
+       (downstream :body "WORLD")
+       (downstream :done nil))))

   (is (next-msgs-for
        ch2
@@ -153,17 +153,17 @@
         (downstream :body "World")
         (downstream :done nil))))

-  (let [upstream
+  (let [downstream
         (client/request
          ["Localhost" 4040]
          [{:path-info      "/"
            :request-method "GET"
            "connection"    "close"}]
-         (fn [upstream evt val]
+         (fn [downstream evt val]
            (enqueue ch2 [evt val])
            (when (= evt :response)
-             (upstream :pause nil))))]
-    (receive ch3 (fn [_] (upstream :resume nil))))
+             (downstream :pause nil))))]
+    (receive ch3 (fn [_] (downstream :resume nil))))

   (is (next-msgs-for
        ch2
@@ -194,13 +194,13 @@
        :request-method     "POST"
        "transfer-encoding" "chunked"
        "connection"        "close"} :chunked]
-     (fn [upstream-fn evt val]
+     (fn [downstream evt val]
        (enqueue ch2 [evt val])
        (when (= :connected evt)
-         (bg-while @latch (upstream-fn :body "HAMMER TIME!")))
+         (bg-while @latch (downstream :body "HAMMER TIME!")))
        (when (= :pause evt) (toggle! latch))
        (when (= :resume evt)
-         (upstream-fn :done nil))))
+         (downstream :done nil))))

     (is (next-msgs-for
          ch2
@@ -217,13 +217,12 @@
 (defcoretest issuing-immediate-abort
   [_ ch]
   :hello-world
-  (let [upstream
-        (client/request
-         ["localhost" 4040]
-         [{:path-info      "/"
-           :request-method "POST"} nil]
-         (fn [_ evt val]
-           (enqueue ch [evt val])))]
+  (let [upstream (client/request
+                  ["localhost" 4040]
+                  [{:path-info      "/"
+                    :request-method "POST"} nil]
+                  (fn [_ evt val]
+                    (enqueue ch [evt val])))]
     (upstream :abort nil))

   (is (not-receiving-messages))
@@ -247,14 +246,14 @@
          :response
          [200 {"content-length" "5" "connection" "close"} "Hello"]))))

-  (let [upstream
+  (let [downstream
         (client/request
          ["Localhost" 4040]
          [{:path-info       "/"
            :request-method  "POST"
            "content-length" "5"
            "expect"         "100-continue"} :chunked]
-         (fn [upstream evt val]
+         (fn [downstream evt val]
            (enqueue ch2 [evt val])))]

     (is (next-msgs-for
@@ -268,8 +267,8 @@
     (is (no-msgs-for ch1))
     (is (no-msgs-for ch2))

-    (upstream :body "Hello")
-    (upstream :done nil)
+    (downstream :body "Hello")
+    (downstream :done nil)

     (is (next-msgs-for
          ch1
@@ -391,9 +390,9 @@
    ["localhost" 4040]
    [{:path-info "/"
      :request-method "GET"}]
-   (fn [upstream evt val]
+   (fn [downstream evt val]
      (enqueue ch2 [evt val])
-     (upstream :abort nil)))
+     (downstream :abort nil)))

   (is (next-msgs-for
        ch2


I wrote this test.

I wrote this test.

--- test/picard/test/server.clj
+++ test/picard/test/server.clj
@@ -427,6 +427,4 @@
   (is (not-receiving-messages)))

 ;; TODO: Missing tests
-;; * What happens if the client sends a 100-continue but no content-length
-;;   or transfer-encoding headers
 ;; * Handling various 100 Continue edge cases


Fix typo

Fix typo

--- scheduler/src/cook/mesos/scheduler.clj
+++ scheduler/src/cook/mesos/scheduler.clj
@@ -856,14 +856,14 @@
    :interval-minutes specifies the frequency of killing
    :timout-hours specifies the timeout hours for lingering tasks"
   [conn driver config]
-  (let [{interval-minutes :timeout-interval-minutes
-         max-timeout-hours :max-timeout-hours
-         default-timeout-hours :default-timeout-hours
-         timeout-hours :timout-hours}
+  (let [{:keys [timeout-interval-minutes
+                max-timeout-hours
+                default-timeout-hours
+                timeout-hours]}
         (merge {:timeout-interval-minutes 10
                 :timeout-hours (* 2 24)}
                config)]
-    (chime-at (periodic/periodic-seq (time/now) (time/minutes interval-minutes))
+    (chime-at (periodic/periodic-seq (time/now) (time/minutes timeout-interval-minutes))
               (fn [now]
                 (let [db (d/db conn)
                       ;; These defaults are for backwards compatibility


stuff

stuff

--- src/tailrecursion/boot/middleware/pom.clj
+++ src/tailrecursion/boot/middleware/pom.clj
@@ -6,9 +6,6 @@
   (:import
    [org.apache.maven.model Model Repository Dependency Exclusion]
    org.apache.maven.model.io.xpp3.MavenXpp3Writer))
-
-(defn contains-every? [coll ks]
-  (every? identity (map contains? (repeat coll) ks)))

 (defmacro dotoseq [obj seq-exprs & body]
   `(let [o# ~obj]
@@ -37,7 +34,6 @@
                          (doto (Exclusion.) (.setGroupId group) (.setArtifactId artifact))))))))

 (defn ^Model build-model [boot pom]
-  {:pre [(contains-every? pom [:project :version])]}
   (let [{:keys [repositories dependencies directories]} boot
         {:keys [project version description]} pom
         [group artifact] (extract-ids project)]
@@ -48,12 +44,14 @@
       (set-repositories! repositories)
       (set-dependencies! dependencies))))

-(defn make-pom [env]
-  (let [{:keys [boot pom]} env]
-    (if pom
-      (let [model (build-model boot pom)]
-        {:model model
-         :xml (with-out-str (.write (MavenXpp3Writer.) *out* model))}))))
+(defn contains-every? [coll ks]
+  (every? identity (map contains? (repeat coll) ks)))
+
+(defn make-pom [{:keys [boot pom]}]
+  {:pre [(contains-every? pom [:project :version])]}
+  (let [model (build-model boot pom)]
+    {:model model
+     :xml (with-out-str (.write (MavenXpp3Writer.) *out* model))}))

 (defn wrap-pom [handler & options]
   #(handler (merge-with merge % (if (:pom %) {:pom (make-pom %)}))))


Editor indents wrapped lines (good for JSON)

--- frontend/src-editor/editor/views/editor.cljs
+++ frontend/src-editor/editor/views/editor.cljs
@@ -115,16 +115,33 @@
                       :on-click (fn [_] (set-codemirror-value! new-value) (om/refresh! owner))}
               "discard my changes"))))))
   (did-mount [_]
-    (set! *codemirror* (js/CodeMirror (om/get-node owner "host")
-                         #js {:mode              #js {:name "javascript" :json true}
-                              :value             (get-in data [:editor :editor-content] "")
-                              :matchBrackets     true
-                              :autoCloseBrackets true
-                              :styleActiveLine   true
-                              :lint              true
-                              :smartIndent       true
-                              :lineNumbers       true
-                              :lineWrapping      true
-                              :foldGutter        true
-                              :gutters           #js ["CodeMirror-linenumbers", "CodeMirror-foldgutter"]
-                              :viewportMargin:   Infinity}))))+    (let [editor (js/CodeMirror (om/get-node owner "host")
+                   #js {:mode              #js {:name "javascript" :json true}
+                        :value             (get-in data [:editor :editor-content] "")
+                        :matchBrackets     true
+                        :autoCloseBrackets true
+                        :styleActiveLine   true
+                        :lint              true
+                        :smartIndent       true
+                        :lineNumbers       true
+                        :lineWrapping      true
+                        :foldGutter        true
+                        :gutters           #js ["CodeMirror-linenumbers", "CodeMirror-foldgutter"]
+                        :viewportMargin:   Infinity})
+          charWidth (.defaultCharWidth editor)
+          basePadding 4]
+      (.on editor "renderLine" (fn [cm, line, elt]
+                                 ; following code implements fancy indentation for wrapping text of json values
+                                 ; see https://codemirror.net/demo/indentwrap.html
+                                 (let [re-length (fn [re s]
+                                                   (let [re (js/RegExp. re "g")]
+                                                     (if-let [m (.exec re s)]
+                                                       (count (aget m 0))
+                                                       0)))
+                                       text (.-text line)
+                                       base-off (* (.countColumn js/CodeMirror text nil (.getOption cm "tabSize")) charWidth)
+                                       val-open-quote-pos (re-length "\".*\"\\: \"" text)
+                                       val-open-quote-offset (+ base-off (* val-open-quote-pos charWidth))]
+                                   (aset elt "style" "textIndent" (str "-" val-open-quote-offset "px"))
+                                   (aset elt "style" "paddingLeft" (str (+ basePadding val-open-quote-offset) "px")))))
+      (set! *codemirror* editor))))


Added tests for another form of multiple parameters that is supported.

--- test/cmr/opendap/tests/system/rest/app/ous/params_v2.clj
+++ test/cmr/opendap/tests/system/rest/app/ous/params_v2.clj
@@ -55,6 +55,20 @@
       (is (= 200 (:status response)))
       (is (= ["https://acdisc.gesdisc.eosdis.nasa.gov/opendap/Aqua_AIRS_Level3/AIRX3STD.006/2002/AIRS.2002.09.04.L3.RetStd001.v6.0.9.0.G13208020620.hdf.nc?CH4_VMR_A_ct,CH4_VMR_A_max,Latitude,Longitude"
               "https://f5eil01.edn.ecs.nasa.gov/opendap/DEV01/user//FS2/AIRS/AIRX3STD.006/2016.07.01/AIRS.2016.07.01.L3.RetStd001.v6.0.31.0.G16187132305.hdf.nc?CH4_VMR_A_ct,CH4_VMR_A_max,Latitude,Longitude"]
+             (util/parse-response response)))))
+  (testing "GET with repeated variables ..."
+    (let [collection-id "C1200187767-EDF_OPS"
+          response @(httpc/get
+                     (format (str "http://localhost:%s"
+                                  "/opendap/ous/collection/%s"
+                                  "?variables=V1200241812-EDF_OPS&"
+                                  "variables=V1200241813-EDF_OPS")
+                             (test-system/http-port)
+                             collection-id)
+                     (request/add-token-header {} (util/get-sit-token)))]
+      (is (= 200 (:status response)))
+      (is (= ["https://acdisc.gesdisc.eosdis.nasa.gov/opendap/Aqua_AIRS_Level3/AIRX3STD.006/2002/AIRS.2002.09.04.L3.RetStd001.v6.0.9.0.G13208020620.hdf.nc?CH4_VMR_A_ct,CH4_VMR_A_max,Latitude,Longitude"
+              "https://f5eil01.edn.ecs.nasa.gov/opendap/DEV01/user//FS2/AIRS/AIRX3STD.006/2016.07.01/AIRS.2016.07.01.L3.RetStd001.v6.0.31.0.G16187132305.hdf.nc?CH4_VMR_A_ct,CH4_VMR_A_max,Latitude,Longitude"]
              (util/parse-response response))))))

 (deftest collection-GET-variables-array
@@ -110,6 +124,20 @@
                      (format (str "http://localhost:%s"
                                   "/opendap/ous/collection/%s"
                                   "?granules=G1200187775-EDF_OPS,G1200245955-EDF_OPS")
+                             (test-system/http-port)
+                             collection-id)
+                     (request/add-token-header {} (util/get-sit-token)))]
+      (is (= 200 (:status response)))
+      (is (= ["https://acdisc.gesdisc.eosdis.nasa.gov/opendap/Aqua_AIRS_Level3/AIRX3STD.006/2002/AIRS.2002.09.04.L3.RetStd001.v6.0.9.0.G13208020620.hdf.nc"
+              "https://f5eil01.edn.ecs.nasa.gov/opendap/DEV01/user//FS2/AIRS/AIRX3STD.006/2016.07.01/AIRS.2016.07.01.L3.RetStd001.v6.0.31.0.G16187132305.hdf.nc"]
+             (util/parse-response response)))))
+  (testing "GET with repeated granules ..."
+    (let [collection-id "C1200187767-EDF_OPS"
+          response @(httpc/get
+                     (format (str "http://localhost:%s"
+                                  "/opendap/ous/collection/%s"
+                                  "?granules=G1200187775-EDF_OPS&"
+                                  "granules=G1200245955-EDF_OPS")
                              (test-system/http-port)
                              collection-id)
                      (request/add-token-header {} (util/get-sit-token)))]


fix tests that broke by using processable? more

--- test/open_company/integration/company/company_create.clj
+++ test/open_company/integration/company/company_create.clj
@@ -67,14 +67,14 @@
   ;; -------------------
   (facts "about creating companies"

-    (fact "missing fields cause 400"
+    (fact "missing fields cause 422"
       (let [payload  {:name "hello"}
             response (mock/api-request :post "/companies" {:body payload})]
-        (:status response) => 400))
-    (fact "superflous fields cause 400"
+        (:status response) => 422))
+    (fact "superflous fields cause 422"
       (let [payload  {:bogus "xx" :name "hello" :description "x"}
             response (mock/api-request :post "/companies" {:body payload})]
-        (:status response) => 400))
+        (:status response) => 422))

     (fact "company can be created with name and description"
       (let [payload  {:name "Hello World" :description "x"}
@@ -96,10 +96,10 @@
           (:status response) => 422)))

     (facts "sections"
-      (fact "unknown sections cause 400"
+      (fact "unknown sections cause 422"
        (let [payload  {:name "hello" :description "x" :unknown-section {}}
               response (mock/api-request :post "/companies" {:body payload})]
-         (:status response) => 400))
+         (:status response) => 422))
       (facts "known user supplied sections"
         (let [diversity {:title "Diversity" :description "Diversity yay!" :body "TBD" :section-name "diversity"}
               payload  {:name "Diverse Co" :description "x" :diversity diversity}


Fix typos

Fix typos

--- src/worker/core.clj
+++ src/worker/core.clj
@@ -27,10 +27,10 @@
       (json/read-str :key-fn keyword)))

 (defn rand-between
-  "Genartes random int between a (inclusive)
+  "Generates random int between a (inclusive)
   and b (exclusive)"
   [a b]
-  (+ a  (rand (- b a))))
+  (+ a (rand (- b a))))

 (defn print-job-info
   "Prints info"


Use named schemes in coercion mapping keys

This helps maintenance by reducing duplication.

--- src/yada/schema.clj
+++ src/yada/schema.clj
@@ -271,9 +271,12 @@
 (s/defschema Authorization
   {(s/optional-key :authorization) s/Any})

+(s/defschema RealmValue
+  (merge AuthSchemes Authorization NamespacedEntries))
+
 (s/defschema Realms
   {(s/optional-key :realms)
-   {Realm (merge AuthSchemes Authorization NamespacedEntries)}})
+   {Realm RealmValue}})

 (s/defschema Cors
   {(s/optional-key :allow-origin) (s/conditional fn? (s/=> (s/conditional ifn? #{s/Str} :else s/Str) Context) :else StringSet)
@@ -283,18 +286,25 @@
    (s/optional-key :allow-methods) (s/conditional fn? ContextFunction :else Keywords)
    (s/optional-key :allow-headers) (s/conditional fn? ContextFunction :else Strings)})

+(s/defschema AccessControlValue
+  (merge Realms Cors NamespacedEntries))
+
 (s/defschema AccessControl
-  {(s/optional-key :access-control) (merge Realms Cors NamespacedEntries)})
-
-;; Here is some very tricky code, caused by the necessity to compose a
-;; couple of these 'data macros'. The realm shorthand has to allow the
-;; scheme short-hand to 'carry over', which makes it difficult to find
-;; an approach that preserves schema integrity while decoupling the
-;; data macros from each other. For an explanation of data macros, see
+  {(s/optional-key :access-control) AccessControlValue})
+
+;; Here is some tricky code, caused by the necessity to compose the
+;; 'data macros'. The realm short-hand has to rewrite the data, which
+;; may include the scheme in short or long form, which makes it
+;; difficult to find an approach that preserves schema integrity while
+;; decoupling the data macros from each other. The consequence is that
+;; these mappings have some intimate knowledge of each other's
+;; structure, but the trade-off of more difficult maintenance is
+;; deemed worth it for the value to the user of being able to use
+;; short-hands. For an explanation of data macros, see
 ;; https://blog.juxt.pro/posts/data-macros.html

 (def SingleRealmMapping
-  {(merge Realms Cors NamespacedEntries)
+  {AccessControlValue
    (fn [x]
      (if-let [realm (:realm x)]
        (-> x
@@ -306,7 +316,7 @@
        x))})

 (def SingleSchemeMapping
-  {(merge AuthSchemes Authorization NamespacedEntries)
+  {RealmValue
    (fn [x]
      (if (:verify x)
        (-> x
@@ -380,12 +390,3 @@
    :known-methods {s/Keyword s/Any}
    :interceptor-chain [(s/=> Context Context)]
    (s/optional-key :path-info?) s/Bool})
-
-
-(def r (resource-coercer
-     {:access-control {:realm "default"
-                       :scheme "Basic"
-                       :verify identity
-                       :authorization {:roles/methods {:get :admin}}
-                       :allow-origin "*"}}))
-


use org and repo in routes instead of org-id and repo-id

--- frontend/routes.cljs
+++ frontend/routes.cljs
@@ -22,9 +22,9 @@
       (add-watch app listener-id sentinel))))

 (defn open-build-inspector!
-  [app nav-ch org-id repo-id build-num]
-  (let [project-name (str org-id "/" repo-id)]
-    (put! nav-ch [:build [project-name build-num org-id repo-id]])))
+  [app nav-ch org repo build-num]
+  (let [project-name (str org "/" repo)]
+    (put! nav-ch [:build [project-name build-num org repo]])))

 (defn open-to-dashboard! [nav-ch & [args]]
   (put! nav-ch [:dashboard args]))
@@ -33,20 +33,20 @@
   (put! nav-ch [:add-projects]))

 ;; XXX validate subpage, send to 404
-(defn open-to-project-settings! [nav-ch org-id repo-id subpage]
-  (let [project-name (str org-id "/" repo-id)]
+(defn open-to-project-settings! [nav-ch org repo subpage]
+  (let [project-name (str org "/" repo)]
     (put! nav-ch [:project-settings {:project-name project-name
                                      :subpage subpage
-                                     :org org-id
-                                     :repo repo-id}])))
+                                     :org org
+                                     :repo repo}])))

 ;; XXX validate subpage, send to 404
 (defn open-to-org-settings!
-  ([nav-ch org-id]
-   (open-to-org-settings! nav-ch org-id :projects))
-  ([nav-ch org-id subpage]
+  ([nav-ch org]
+   (open-to-org-settings! nav-ch org :projects))
+  ([nav-ch org subpage]
    (put! nav-ch [:org-settings {:subpage subpage
-                                :org-name org-id}])))
+                                :org-name org}])))

 (defn define-routes! [app]
   (let [nav-ch (get-in @app [:comms :nav])]
@@ -57,22 +57,21 @@
     (defroute v1-project-branch-dashboard "/gh/:org/:repo/tree/:branch" {:as params}
       (open-to-dashboard! nav-ch params))
     (defroute v1-inspect-build #"/gh/([^/]+)/([^/]+)/(\d+)"
-      [org-id repo-id build-num]
-      (open-build-inspector! app nav-ch org-id repo-id (js/parseInt build-num)))
-    (defroute v1-project-settings "/gh/:org-id/:repo-id/edit"
-      [org-id repo-id]
-      (open-to-project-settings! nav-ch org-id repo-id nil))
-    (defroute v1-project-settings-subpage "/gh/:org-id/:repo-id/edit#:subpage"
-      [org-id repo-id subpage]
-      (open-to-project-settings! nav-ch org-id repo-id (keyword subpage)))
-    (defroute v1-org-settings "/gh/organizations/:org-id/settings"
-      [org-id]
-      (open-to-org-settings! nav-ch org-id))
-    (defroute v1-org-settings-subpage "/gh/organizations/:org-id/settings#:subpage"
-      [org-id subpage]
-      (open-to-org-settings! nav-ch org-id (keyword subpage)))
+      [org repo build-num]
+      (open-build-inspector! app nav-ch org repo (js/parseInt build-num)))
+    (defroute v1-project-settings "/gh/:org/:repo/edit"
+      [org repo]
+      (open-to-project-settings! nav-ch org repo nil))
+    (defroute v1-project-settings-subpage "/gh/:org/:repo/edit#:subpage"
+      [org repo subpage]
+      (open-to-project-settings! nav-ch org repo (keyword subpage)))
+    (defroute v1-org-settings "/gh/organizations/:org/settings"
+      [org]
+      (open-to-org-settings! nav-ch org))
+    (defroute v1-org-settings-subpage "/gh/organizations/:org/settings#:subpage"
+      [org subpage]
+      (open-to-org-settings! nav-ch org (keyword subpage)))
     (defroute v1-add-projects "/add-projects" []
       (open-to-add-projects! nav-ch))
-    (defroute v1-root "/"
-      [org-id repo-id build-num]
+    (defroute v1-root "/" []
       (open-to-dashboard! nav-ch))))


user 0.0.0.0 as connect ip for compatibility issues

--- frontend/src/cruncher/config.cljs
+++ frontend/src/cruncher/config.cljs
@@ -1,6 +1,6 @@
 (ns cruncher.config)

-(def api {:host "http://localhost:5000/"
+(def api {:host "http://0.0.0.0:5000/"
           :init "api/init/"
           :base "api/"
           :login "api/login"


process real time log entry

process real time log entry

processes it, but what happens on server crash???

--- src/webapp/framework/server/systemfns.clj
+++ src/webapp/framework/server/systemfns.clj
@@ -2,6 +2,7 @@

   [:require [clojure.string :as string]]
   [:use [korma.db]]
+  [:use [clojure.core.async :only [go <! >!]]]
   [:require [korma.core]]
   [:use [webapp-config.settings]]
   [:use [webapp.framework.server.encrypt]]
@@ -830,8 +831,10 @@
 (defn next-realtime-id [] (swap! realtime-counter inc))

 (def my-pool (mk-pool))
-(every 10000 (fn []
-              (let [sql (str "update coils_realtime_log"
+(every 1000 (fn []
+              (let [next-id   (next-realtime-id)
+
+                    sql (str "update coils_realtime_log"
                             "      set record_status = 'PROCESSING',"
                             "          realtime_jvm_id = ? "
                             "where "
@@ -841,11 +844,29 @@
                             "                    coils_realtime_log"
                             "              WHERE "
                             "                   record_status='WAITING' LIMIT 1 ) "
-                    )]
+                    )
+
+                    get-realtime-log-entry (str "select * from coils_realtime_log "
+                                                "WHERE "
+                                                "realtime_jvm_id = ?")
+                    ]
                      (do
-                        (println "Checking pool!" )
-                        (korma.core/exec-raw [sql [(next-realtime-id)]])
+                        (korma.core/exec-raw [sql [next-id]] [])
+                        (let [realtime-log-entry-list
+                              (korma.core/exec-raw [get-realtime-log-entry [next-id]] :results)
+                              realtime-log-entry (first realtime-log-entry-list)
+                              ]
+                          (if realtime-log-entry
+                            (>! server-side-record-changes  realtime-log-entry))
+                          )
                  ))) my-pool )

+
+
+( go
+  (loop []
+        (let [realtime-log-entry   (<! server-side-record-changes)]
+                             (println realtime-log-entry  )
+(recur))))


Capitalize Atom and Volatile. Handle Namespace.

--- lein-light-nrepl/src/lighttable/nrepl/eval.clj
+++ lein-light-nrepl/src/lighttable/nrepl/eval.clj
@@ -70,10 +70,12 @@
      (nil? res) "nil"
      (false? res) "false"
      (and (instance? clojure.lang.Atom res)
-          (:result opts)) (str "atom<" @res ">")
+          (:result opts)) (str "Atom<" @res ">")
      (and (instance? clojure.lang.Volatile res)
-          (:result opts)) (str "volatile<" @res ">")
+          (:result opts)) (str "Volatile<" @res ">")
      (instance? clojure.lang.IType res) (pprint->string res)
+     (instance? clojure.lang.Namespace res)
+     (str "Namespace<" res ">")
      ;(is-non-clojure? res) (str res)
      (and (string? res) (:verbatim opts)) res
      :else (pprint->string res))))


remove println

remove println

Signed-off-by: Chris Granger <5654cde260ae99bc4d30054171b8bcd902efd19a@gmail.com>

--- lein-light-nrepl/src/lighttable/nrepl/eval.clj
+++ lein-light-nrepl/src/lighttable/nrepl/eval.clj
@@ -15,7 +15,6 @@

 (defn try-read [rdr]
   (when rdr
-    (println "READING")
     (reader/read rdr false nil)))

 (defn lined-read [string]


Remove debug on drawing streams.

Remove debug on drawing streams.

--- frontend/src/uxbox/main/data/workspace/drawing.cljs
+++ frontend/src/uxbox/main/data/workspace/drawing.cljs
@@ -58,7 +58,6 @@
         (->> stream
              (rx/filter #(= % ::uev/interrupt))
              (rx/take 1)
-             (rx/pr-log (str "STOPED DRAWING " id))
              (rx/map (fn [_] #(update % :workspace dissoc :drawing-lock))))
         (rx/empty))))


extending page_helpers_test

extending page_helpers_test

--- test/compojure/html/page_helpers_test.clj
+++ test/compojure/html/page_helpers_test.clj
@@ -2,36 +2,46 @@
   (:use compojure.html.page-helpers
         clojure.contrib.test-is))

-(deftest test-doctype-html4
-  (is (= (doctype :html4)
-         (str "<!DOCTYPE html PUBLIC \"-//W3C//DTD HTML 4.01//EN\" "
-              "\"http://www.w3.org/TR/html4/strict.dtd\">\n"))))
-
-(deftest test-doctype-xhtml-strict
-  (is (= (doctype :xhtml-strict)
-         (str "<!DOCTYPE html PUBLIC \"-//W3C//DTD XHTML 1.0 Strict//EN\" "
+(deftest test-doctype
+  (testing "html4"
+    (is (= (doctype :html4)
+           (str "<!DOCTYPE html PUBLIC \"-//W3C//DTD HTML 4.01//EN\" "
+                "\"http://www.w3.org/TR/html4/strict.dtd\">\n"))))
+  (testing "xhtml-strict"
+    (is (= (doctype :xhtml-strict)
+           (str "<!DOCTYPE html PUBLIC \"-//W3C//DTD XHTML 1.0 Strict//EN\" "
               "\"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd\">\n"))))
-
-(deftest test-doctype-html5
-	(is (= (doctype :html5)
-			  (str "<!DOCTYPE html>"))))
-
-(deftest test-doctype-xhtml-transitional
-  (is (= (doctype :xhtml-transitional)
-         (str  "<!DOCTYPE html PUBLIC \"-//W3C//DTD XHTML 1.0 Transitional//EN\" "
-               "\"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd\">\n"))))
+  (testing "html5"
+    (is (= (doctype :html5)
+           (str "<!DOCTYPE html>"))))
+  (testing "xhtml-transitional"
+    (is (= (doctype :xhtml-transitional)
+           (str  "<!DOCTYPE html PUBLIC \"-//W3C//DTD XHTML 1.0 Transitional//EN\" "
+                 "\"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd\">\n")))))

 (deftest test-xhtml-tag
   (is (= (xhtml-tag "test")
          [:html {:xmlns "http://www.w3.org/1999/xhtml", "xml:lang" "test", :lang "test"} nil])))

 (deftest test-include-js
-  (is (= (include-js "foo.js")
-         '([:script {:type "text/javascript", :src "foo.js"}]))))
+  (testing "one"
+    (is (= (include-js "foo.js")
+           '([:script {:type "text/javascript", :src "foo.js"}]))))
+  (testing "many"
+    (is (= (include-js "foo.js" "bar.js" "baz.js")
+           '([:script {:type "text/javascript", :src "foo.js"}]
+             [:script {:type "text/javascript", :src "bar.js"}]
+             [:script {:type "text/javascript", :src "baz.js"}])))))

 (deftest test-include-css
-  (is (= (include-css "foo.css")
-         '([:link {:type "text/css" :href "foo.css" :rel "stylesheet"}]))))
+  (testing "one"
+    (is (= (include-css "foo.css")
+           '([:link {:type "text/css" :href "foo.css" :rel "stylesheet"}]))))
+  (testing "many"
+    (is (= (include-css "foo.css" "bar.css" "baz.css")
+           '([:link {:type "text/css", :href "foo.css", :rel "stylesheet"}]
+             [:link {:type "text/css", :href "bar.css", :rel "stylesheet"}]
+             [:link {:type "text/css", :href "baz.css", :rel "stylesheet"}])))))

 (deftest test-javascript-tag
   (is (= (javascript-tag "alert('hi');")


Moves test further along.

Moves test further along.

--- test/onyx/coordinator/multi_peer_test.clj
+++ test/onyx/coordinator/multi_peer_test.clj
@@ -21,6 +21,7 @@

             sync-spy-a (chan 1)
             sync-spy-b (chan 1)
+            ack-ch-spy (chan 2)
             offer-ch-spy (chan 1)

             catalog [{:onyx/name :in
@@ -40,6 +41,7 @@
                       :hornetq/queue-name "out-queue"}]
             workflow {:in {:inc :out}}]

+        (tap (:ack-mult coordinator) ack-ch-spy)
         (tap (:offer-mult coordinator) offer-ch-spy)

         (extensions/write-place sync peer-node-a payload-node-a)
@@ -64,7 +66,14 @@
                 payload-b (extensions/read-place sync payload-node-b)]
             (is (not (nil? payload-a)))
             (is (not (nil? payload-b)))
-            (is (not= payload-a payload-b))))))
+            (is (not= payload-a payload-b))
+
+            (extensions/touch-place sync (:ack (:nodes payload-a)))
+            (extensions/touch-place sync (:ack (:nodes payload-b)))
+
+            (<!! ack-ch-spy)
+            (<!! ack-ch-spy)))))
+
     {:eviction-delay 50000}))

 (run-tests 'onyx.coordinator.multi-peer-test)


Expanded comment on challenge 4-2

Expanded comment on challenge 4-2

Challenge 4-2 could use some clarification. Given a student hasn’t really
had to modify lifecycle hooks up until now, a longer note on how the
return values for the lifecycle handlers are used could help them figure
out the expectations for this challenge.

--- test/workshop/jobs/challenge_4_2_test.clj
+++ test/workshop/jobs/challenge_4_2_test.clj
@@ -10,6 +10,12 @@
 ;; In this challenge, you're going to reference an atom defined
 ;; in the corresponding source file and use it in
 ;; the :before-task-start lifecycle hook.
+;;
+;; Remember that lifecycle hooks return maps, like the
+;; `writer-lifecycle` hooks did on the previous examples. The
+;; elements from the map you return will be merged with those being
+;; passed on the event to other lifecycle handlers.
+;;
 ;; After each batch is processed, find the maximum value
 ;; that we saw in the :identity task. After the task is finished,
 ;; we'll query the atom to find the maximum value.


Dont log slack hook because logs can be public

--- src/clj/runbld/notifications/slack.clj
+++ src/clj/runbld/notifications/slack.clj
@@ -20,7 +20,7 @@
         js    (mustache/render-string tmpl (assoc ctx :color color))
         hook  (-> opts :slack :hook)]
     (when hook
-      ((opts :logger) "SLACK:" hook)
+      ((opts :logger) "NOTIFYING SLACK")
       (http/post hook
                  {:body js}))))


Refactoring

Refactoring

--- src/cljs/hacker_agent/hacker-base.cljs
+++ src/cljs/hacker_agent/hacker-base.cljs
@@ -8,13 +8,13 @@

 (defonce root (js/Firebase. url))

-(defn- walk-root [r keys]
+(defn- walk-root [r & keys]
   (let [[k & ks] keys]
     (if ks
       (recur (.child r (clojure.core/name k)) ks)
       (.child r (clojure.core/name k)))))

-(def top-stories (walk-root root [:topstories]))
+(def top-stories (walk-root root :topstories))

 (def ^:dynamic closer-root nil)

@@ -45,7 +45,7 @@
                   new-closers))))))

 (defn- id->fbref [id]
-  (walk-root root [:item (str id)]))
+  (walk-root root :item (str id)))

 (defn- fb->chan
   ([fbref]
@@ -109,18 +109,15 @@
 (defn r-item-binder [f]
   (fn [data path msg]
     (let [[event key val] msg
-          child-path (conj path key)]
+          child-path (conj path key)
+          add-change-fn #(do
+                           (swap! data assoc-in child-path val)
+                           (when (= key :kids)
+                             (doseq [id val]
+                               (f id))))]
       (case event
-        :child_added (do
-                       (swap! data assoc-in child-path val)
-                       (when (= key :kids)
-                         (doseq [id val]
-                           (f id))))
-        :child_changed (do
-                         (swap! data assoc-in child-path val)
-                         (when (= key :kids)
-                           (doseq [id val]
-                             (f id))))
+        :child_added (add-change-fn)
+        :child_changed (add-change-fn)
         :child_removed (swap! data update-in path dissoc key)
         (.log js/console (clj->js [event key val]))))))


GAWB-1206: more clean up

GAWB-1206: more clean up

--- src/cljs/main/broadfcui/endpoints.cljs
+++ src/cljs/main/broadfcui/endpoints.cljs
@@ -173,11 +173,6 @@
                                     "Output 3" "workspace.f0o"}
                           :prerequisites {"unused 1" "Predicate 1"
                                           "unused 2" "Predicate 2"}}}})
-
-(defn rename-workspace-method-config [workspace-id config]
-  {:path (str "/workspaces/" (ws-path workspace-id)
-           "/method_configs/" (config "namespace") "/" (config "name") "/rename")
-   :method :post})

 (defn delete-workspace-method-config [workspace-id config]
   {:path (str "/workspaces/" (ws-path workspace-id)


Change the order of the functions on context ns.

--- src/clojure/catacumba/impl/context.clj
+++ src/clojure/catacumba/impl/context.clj
@@ -37,18 +37,6 @@
                         :request (.getRequest context')
                         :response (.getResponse context')}))

-(defn delegate
-  "Delegate handling to the next handler in line.
-
-  This function accept an additiona parameter for
-  pass context parameters to the next handlers, and
-  that can be obtained with `context-params`
-  function."
-  ([^DefaultContext context] (delegate context {}))
-  ([^DefaultContext context data]
-   (let [^Context ctx (:catacumba/context context)
-         ^Registry reg (Registries/just (ContextData. data))]
-     (.next ctx reg))))

 (defn context-params
   "Get the current context params.
@@ -63,6 +51,22 @@
         (:payload cdata))
       (catch ratpack.registry.NotInRegistryException e
         {}))))
+
+(defn delegate
+  "Delegate handling to the next handler in line.
+
+  This function accept an additiona parameter for
+  pass context parameters to the next handlers, and
+  that can be obtained with `context-params`
+  function."
+  ([^DefaultContext context]
+   (let [^Context ctx (:catacumba/context context)]
+     (.next ctx)))
+  ([^DefaultContext context data]
+   (let [^Context ctx (:catacumba/context context)
+         previous (context-params context)
+         ^Registry reg (Registries/just (ContextData. (merge previous data)))]
+     (.next ctx reg))))

 (defn public-address
   "Get the current public address as URI instance.


Support setting the port number during instantiation.

--- src/cmr/http/kit/components/server.clj
+++ src/cmr/http/kit/components/server.clj
@@ -10,7 +10,7 @@
 ;;;   Component Lifecycle Implementation   ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

-(defrecord HTTPD [])
+(defrecord HTTPD [port])

 (defn start
   "The `entry-point` in configuration needs to be of the form
@@ -30,11 +30,13 @@
   `cmr.http.kit.components.config`."
   [this]
   (log/info "Starting httpd component ...")
-  (let [port (config/http-port this)
+  (let [port (or (:port this)
+                 (config/http-port this))
         entry-point (config/http-entry-point-fn this)
         server (server/run-server (entry-point this)
                                   {:port port})]
     (log/trace "Entry point:" entry-point)
+    (log/trace "System data:" (into {} this))
     (log/debugf "HTTPD is listening on port %s" port)
     (log/debug "Started httpd component.")
     (assoc this :server server)))
@@ -60,5 +62,7 @@

 (defn create-component
   ""
-  []
-  (map->HTTPD {}))
+  ([]
+    (map->HTTPD {}))
+  ([port]
+    (map->HTTPD {:port port})))


(PDB-3302) Test fail-back in db_fallback test

--- test/puppetlabs/puppetdb/integration/db_resilience/db_fallback.clj
+++ test/puppetlabs/puppetdb/integration/db_resilience/db_fallback.clj
@@ -11,12 +11,17 @@
               ps (int/run-puppet-server [pdb1 pdb2] {})]

     (testing "Agent run against pdb1"
-      (int/run-puppet ps pdb1 "notify { 'hello, world!': }")
-      (is (= 1 (count (int/pql-query pdb1 "nodes {}")))))
+      (int/run-puppet ps pdb1 "notify { 'initial': }")
+      (is (= 1 (count (int/pql-query pdb1 "resources { title='initial' }"))))
+      (is (= 0 (count (int/pql-query pdb2 "resources { title='initial' }")))))

     (testing "Fallback to pdb2"
       (tk-app/stop (:app pdb1))
-      (is (= 0 (count (int/pql-query pdb2 "nodes {}"))))
+      (int/run-puppet ps pdb2 "notify { 'fallback': }")
+      (is (= 1 (count (int/pql-query pdb2 "resources { title='fallback' }")))))

-      (int/run-puppet ps pdb2 "notify { 'hello, world!': }")
-      (is (= 1 (count (int/pql-query pdb2 "nodes {}")))))))
+    (testing "Restore pdb1"
+      (tk-app/start (:app pdb1))
+      (int/run-puppet ps pdb1 "notify { 'restored': }")
+      (is (= 1 (count (int/pql-query pdb1 "resources { title='restored' }"))))
+      (is (= 0 (count (int/pql-query pdb2 "resources { title='restored' }")))))))


tweaks to the figwheel sidecar config

tweaks to the figwheel sidecar config

--- src/leiningen/new/chestnut/env/dev/clj/chestnut/dev.clj
+++ src/leiningen/new/chestnut/env/dev/clj/chestnut/dev.clj
@@ -23,11 +23,13 @@

 (defn start-figwheel []
   (let [server (fig/start-server { :css-dirs ["resources/public/css"] })
-        config {:builds [{:source-paths ["env/dev/cljs" "src/cljs"]
-                          :compiler {:output-to     "resources/public/js/app.js"
-                                     :output-dir    "resources/public/js/out"
-                                     :source-map    "resources/public/js/out.js.map"
-                                     :preamble      ["react/react.min.js"]}}]
+        config {:builds [{:id "dev"
+                          :source-paths ["env/dev/cljs" "src/cljs"]
+                          :compiler {:output-to            "resources/public/js/app.js"
+                                     :output-dir           "resources/public/js/out"
+                                     :source-map           "resources/public/js/out.js.map"
+                                     :source-map-timestamp true
+                                     :preamble             ["react/react.min.js"]}}]
                 :figwheel-server server}]
     (fig-auto/autobuild* config)))
 {{#less?}}


Update dependencies for re-frame-10x and re-frisk


Pre-conditions for modular bidi's path-for

--- modules/bidi/src/modular/bidi.clj
+++ modules/bidi/src/modular/bidi.clj
@@ -110,9 +110,12 @@
        (s/validate new-router-schema)
        map->Router))

-(defn path-for
+(s/defn path-for :- s/Str
   "Convenience function wrapping bidi's path-for"
-  [router target & args]
+  [router :- (s/pred (partial instance? Router))
+   target :- s/Keyword
+   & args]
+  (assert (satisfies? Router router) "Router argument must satisfy")
   (apply bidi/path-for (:routes router) target args))

 ;; ------  TODO Router needs to display all possible routes available,


a no-position version of the crawler added

--- src/crawler/dom.clj
+++ src/crawler/dom.clj
@@ -390,6 +390,21 @@
      (range
       (count path))))))

+(defn path->xpath-no-position
+  [path]
+  (clojure.string/join
+   "/"
+   (cons
+    "/"
+    (map
+     (fn [i]
+       (let [[tag class pos] (nth path i)]
+         (if class
+           (format "%s[contains(@class, '%s')]" tag class)
+           (format "%s" tag))))
+     (range
+      (count path))))))
+
 (defn generate-xpath
   "Generates an xpath for a set of nodes by incoporating
    position information"
@@ -398,6 +413,29 @@
    (fn [[path a-node]]
      [(path->xpath path positions) a-node])
    nodes))
+
+(defn xpaths-hrefs-tokens-no-position
+  "Grouped only on element position and classes.
+   No position information used in the XPath generated"
+  ([processed-body url]
+     (xpaths-hrefs-tokens-no-position processed-body url (set [])))
+
+  ([processed-body url blacklist]
+     (let [nodes-paths (page-nodes-hrefs-text processed-body
+                                              url
+                                              blacklist)
+
+           xpaths-nodes-paths (map
+                               (fn [[path an-info]]
+                                 [(path->xpath-no-position path) an-info])
+                               nodes-paths)]
+       (reduce
+        (fn [acc [xpath an-info]]
+          (merge-with concat
+                      acc
+                      {xpath [an-info]}))
+        {}
+        xpaths-nodes-paths))))

 (defn xpaths-hrefs-tokens
   "Utilize an initial class-based grouping.


home needs to have a non-empty url

home needs to have a non-empty url

Otherwise, clicking to home from a another screen, e.g. #/types, causes
the existing url to hang around when home is loaded

--- pedestal-app/app/src/semtag_web/history.cljs
+++ pedestal-app/app/src/semtag_web/history.cljs
@@ -8,7 +8,8 @@
 ;; -----------
 (def routes "Maps screens to relative paths"
   {:types "#/types"
-   :tag-stats "#/tag-stats"})
+   :tag-stats "#/tag-stats"
+   :home "#/"})

 (def default-route :home)


CMR-1801: James called me out on newlines

--- indexer-app/src/cmr/indexer/data/concepts/collection.clj
+++ indexer-app/src/cmr/indexer/data/concepts/collection.clj
@@ -160,7 +160,6 @@
             :coordinate-system (when spatial-representation
                                  (csk/->SCREAMING_SNAKE_CASE_STRING spatial-representation))

-
             ;; fields added to support keyword searches
             :keyword (k/create-keywords-field concept-id collection
                                               {:platform-long-names platform-long-names


CMR-3844: Added refer to defconfig.

CMR-3844: Added refer to defconfig.

--- metadata-db-app/src/cmr/metadata_db/system.clj
+++ metadata-db-app/src/cmr/metadata_db/system.clj
@@ -8,7 +8,7 @@
    [cmr.common-app.api.health :as common-health]
    [cmr.common-app.services.jvm-info :as jvm-info]
    [cmr.common.api.web-server :as web]
-   [cmr.common.config :as cfg]
+   [cmr.common.config :as cfg :refer [defconfig]]
    [cmr.common.jobs :as jobs]
    [cmr.common.lifecycle :as lifecycle]
    [cmr.common.log :as log :refer [debug info warn error]]


fix closed and retry logic

fix closed and retry logic

--- clj-tcp/src/clj_tcp/client.clj
+++ clj-tcp/src/clj_tcp/client.clj
@@ -34,8 +34,8 @@
   (close-client conf)
   (if group
     (-> group .shutdownGracefully .sync))
-  (if (not closed)
-    (.set ^AtomicBoolean closed true)))
+  (prn "Close all !!!!!!!!! " (hash (closed)))
+   (.set ^AtomicBoolean closed true))

 (defn client-handler [{:keys [group read-ch internal-error-ch write-ch]}]
@@ -142,8 +142,11 @@
                           ))))

-(defn start-client [host port {:keys [group read-ch internal-error-ch error-ch write-ch handlers] :as conf
-                                 :or {group (NioEventLoopGroup.)
+(defn start-client
+  ([host port {:keys [group read-ch internal-error-ch error-ch write-ch handlers reconnect-count closed] :as conf
+                                 :or {group (NioEventLoopGroup.)
+                                      reconnect-count (AtomicInteger. (int 0))
+                                      closed (AtomicBoolean. false)
                                       read-ch (chan 100) internal-error-ch (chan 100) error-ch (chan 100) write-ch (chan 100)}}]
   "Start a Client instance with read-ch, write-ch and internal-error-ch"
   (try
@@ -155,12 +158,12 @@
       ^Bootstrap (.handler ^ChannelInitializer (client-channel-initializer conf)))
     (let [ch-f (.connect b)]
       (.sync ch-f)
-      (->Client g ch-f write-ch read-ch internal-error-ch error-ch (AtomicInteger.) (AtomicBoolean. false))))
+      (->Client g ch-f write-ch read-ch internal-error-ch error-ch reconnect-count closed)))
   (catch Exception e (do
                        (.printStackTrace e)
                        (error (str "Error starting client " e) e)
                        (>!! internal-error-ch [e nil])
-                       ))))
+                       )))))

 (defn read-print-ch [n ch]
   (go
@@ -194,7 +197,8 @@
          internal-error-ch (chan error-buff)
          error-ch (chan error-buff)
          g (NioEventLoopGroup.)
-         conf {:group g :write-ch write-ch :read-ch read-ch :internal-error-ch internal-error-ch :error-ch error-ch :handlers handlers}
+         conf {:group g :write-ch write-ch :read-ch read-ch :internal-error-ch internal-error-ch :error-ch error-ch :handlers handlers
+               :reconnect-count (AtomicInteger.) :closed (AtomicBoolean. false)}
          client (start-client host port conf) ]

     (if (not client)
@@ -207,14 +211,20 @@
     (go
       (loop [local-client client]
         (let [[v o] (<! internal-error-ch)
-              reconnected-count (.get ^AtomicInteger (:reconnect-count client))
+              reconnect-count (.get ^AtomicInteger (:reconnect-count local-client))
               ]
-          (error "read error from internal-error-ch " v)
+          (error "read error from internal-error-ch " v " reconnect count " reconnect-count)
+          (prn "is closed " (:closed local-client) " hash " (hash (:closed local-client)))
           (if (> reconnect-count retry-limit) ;check reconnect count
              (do ;if the same connection has been reconnected too many times close
                (write-poison local-client)
-               (close-all local-client)
-               (>! error-ch [v o]) ;send the error channel
+               (try
+                   (close-all local-client)
+                   (catch Exception (.printStackTrace e)))
+
+               (.set ^AtomicBoolean (:closed local-client) true)
+               (go (>! error-ch [v o])) ;send the error channel
+
                )
              (do
 		          (if (instance? Poison v)
@@ -242,7 +252,8 @@
 											              (let [c (start-client host port conf)
 											                    reconnected (->Reconnected c v)]
 						                              ;if connected, send Reconnected instance to all channels and return c, this c is assigned to the loop using recur
-													                (.addAndGet ^AtomicInteger (:reconnect-count c) (int reconnected-count))
+                                          (.addAndGet ^AtomicInteger (:reconnect-count c) (int (inc reconnect-count)))
+
 													                (>! read-ch reconnected)
 													                (>! write-ch reconnected)
 											                    c)
@@ -274,14 +285,14 @@
 		          (if (instance? Stop v) nil ;if stop exit loop
 		             (do
                    (try
-                      (cond (instance? Reconnected v) (do (recur (:client v))) ;if reconnect recur with the new client
+                      (cond (instance? Reconnected v) (do
+                                                        (prn "Writer received reconnected " (:client v))
+                                                        (recur (:client v))) ;if reconnect recur with the new client
 					             (instance? Pause v) (do (<! (timeout (:time v))) (recur local-client)) ;if pause, wait :time millis, then recur loop
 					             :else
 				                (do ;else write the value to the client channel
+						               (do-write local-client v false conf)))

-						               (do-write local-client v false conf)))
-                           (if (> (.get ^AtomicInteger (:reconnect-count local-client)) 0) (.set ^AtomicInteger (:reconnect-count local-client) 0))
-
 							        (catch Exception e (do ;send any exception to the internal-error-ch
 								                            (error "!!!!! Error while writing " e)
 								                            (go (>! internal-error-ch [e nil]))


Use transient in get-file-by-path

Use transient in get-file-by-path

--- src/extremo/db.cljs
+++ src/extremo/db.cljs
@@ -13,14 +13,15 @@
       (.catch #(js/console.error "Something went wrong opening repo: " %))))

 (defn get-file-by-path [filepath]
-  (-> (open-repo)
-      (.then #(.getCommit % "d909ade91aae7970a34ba91e800493f9bac7d473"))
-      (.then #(js/Promise.all [(.getEntry % filepath) {:date (.date %)}]))
-      (.then #(js/Promise.all
-                [(.getBlob (first %))
-                 (assoc (second %) :name (.name (first %)) :sha (.sha (first %)))]))
-      (.then #(assoc (second %) :rawsize (.rawsize (first %))
-                                 :blob (.toString (first %))))))
+  (let [rv (transient {})]
+    (-> (open-repo)
+        (.then #(.getMasterCommit % "d909ade91aae7970a34ba91e800493f9bac7d473"))
+        (.then #(do (assoc! rv :date (.date %))
+                    (.getEntry % filepath)))
+        (.then #(do (assoc! rv :name (.name %) :sha (.sha %))
+                    (.getBlob %)))
+        (.then #(persistent! ( assoc! rv :rawsize (.rawsize %)
+                                         :blob (.toString %)))))))

 (-> (get-file-by-path "test.md")
     (.then #(js/console.log (clj->js %)))


to prevent realization of a lazy-seq, remove warning that uses (count)

--- src/babel/generate.cljc
+++ src/babel/generate.cljc
@@ -111,18 +111,8 @@
              (fn [parent]
                (log/trace (str "lightning-bolts: parent: " (:rule parent) " over lexical heads."))
                (let [subset (get-lexemes language-model (get-in parent [:head] :top))]
-                 (let [result
-                       (map #(assoc-in parent [:head] %)
-                            (shufflefn subset))]
-                   (if (and (not (empty? subset)) (empty? result)
-                            (> (count subset)
-                               50))
-                     ;; log/warn because it's very expensive to run
-                     ;; over/overh: for every candidate, both parent
-                     ;; and candidate head must be copied.
-                     (log/warn (str "tried: " (count subset) " lexical candidates with spec:"
-                                    (strip-refs spec) " and all of them failed as heads of parent:" (get-in parent [:rule]))))
-                   result)))
+                 (map #(assoc-in parent [:head] %)
+                      (shufflefn subset))))
              (filter #(= false
                          (get-in % [:head :phrasal] false))
                      parents)))


added a param

added a param

--- src/babel/generate.cljc
+++ src/babel/generate.cljc
@@ -92,7 +92,7 @@
                                (rest comp-paths)
                                (rest bolts-at-paths)
                                depth max-depth top-bolt truncate? take-n)
-                   ((fn [comp-paths]
+                   ((fn [comp-paths bolts-at-paths]
                       (let [path (first comp-paths)
                             bolts-at (first bolts-at-paths)]
                         (flatten
@@ -104,7 +104,7 @@
                                             (if truncate? (truncate with-added-complement [path] model)
                                                 with-added-complement))))))
                                 bolts-at))))
-                    comp-paths)))))))))
+                    comp-paths bolts-at-paths)))))))))

 (defn add-bolt-at [top-bolt bolt path bolt-at model depth max-depth truncate? & [take-n]]
   (mapfn #(do-defaults % model)


restrict transitive rule: do not apply if [:synsem :subcat :3] exists

--- src/babel/lexiconfn.clj
+++ src/babel/lexiconfn.clj
@@ -587,8 +587,13 @@
   (cond (and (= (get-in lexical-entry [:synsem :cat]) :verb)
              (not (nil? (get-in lexical-entry [:synsem :sem :obj])))
              (not (= (get-in lexical-entry [:synsem :sem :obj]) :unspec))
+
              ;; do not apply rule if (:subcat :2) is explicitly empty.
-             (not (= '() (get-in lexical-entry [:synsem :subcat :2]))))
+             (not (= '() (get-in lexical-entry [:synsem :subcat :2])))
+
+             ;; do not apply rule if there is :3.
+             (= :none (get-in lexical-entry [:synsem :subcat :3] :none)))
+
         (unifyc
          lexical-entry
          transitive-but-object-cat-not-set)
@@ -747,24 +752,26 @@
                                 (fn [rule]
                                   ;; check for return value of (apply rule (list lexical-entry)):
                                   ;; if not list, make it a list.
-                                  (let [result (rule lexical-entry)]
-                                    (if (and (not (fail? lexical-entry)) (fail? result))
-                                      (do (log/warn (str "unify-type lexical rule: " rule " caused lexical-entry: "
-                                                         (dissoc (strip-refs lexical-entry) :serialized)
-                                                         " to fail; fail path was: " (fail-path result)))
-                                          result)
+                                  (let [debug (log/debug "applying rule: " rule " to lexical entry: " (strip-refs lexical-entry))
+                                        result (rule lexical-entry)]
+                                    (if (fail? result)
+                                      (let [message
+                                            (str "rule: " rule " caused lexical entry: " (strip-refs lexical-entry) " to fail.")]
+                                        (log/error message)
+                                        (throw (Exception. message)))
                                       (do
+                                        (log/debug (str "rule: " rule " was ok."))
                                         result))))
                                 rules))
                 result (if (not (fail? result))
-                         (reduce merge  (map (fn [rule]
-                                               (let [result (rule result)]
-                                                 (if (fail? result)
-                                                   (do (log/error (str "merge-type lexical rule: " rule " caused lexical-entry: " lexical-entry
-                                                                       " to fail; fail path was: " (fail-path result)))
-                                                       :fail)
-                                                   result)))
-                                             modifying-rules))
+                         (reduce merge (map (fn [rule]
+                                              (let [result (rule result)]
+                                                (if (fail? result)
+                                                  (do (log/error (str "merge-type lexical rule: " rule " caused lexical-entry: " lexical-entry
+                                                                      " to fail; fail path was: " (fail-path result)))
+                                                      :fail)
+                                                  result)))
+                                            modifying-rules))
                            :fail)]
             (if (fail? result)
               (do
@@ -909,4 +916,3 @@
                                          (get-in map2 [first-fail-key])))
           (if (not (nil? first-fail-key))
             [first-fail-key]))))))
-


Fixed comment typo.

Fixed comment typo.

--- src/bencode/decoder.clj
+++ src/bencode/decoder.clj
@@ -31,7 +31,7 @@
         [(apply str data) rem]))))

 (defn- invalid-number?
-  "Returns whether digits reprents an invalid number according to the spec."
+  "Returns whether digits represents an invalid number according to the spec."
   [digits]
   (or (empty? digits)
       (and (> (count digits) 1) (= \0 (first digits)))))