Uncomment out translation test

Uncomment out translation test

--- system-int-test/test/cmr/system_int_test/ingest/translation_test.clj
+++ system-int-test/test/cmr/system_int_test/ingest/translation_test.clj
@@ -1,98 +1,98 @@
-; (ns cmr.system-int-test.ingest.translation-test
-;   (:require [clojure.test :refer :all]
-;             [cmr.system-int-test.utils.ingest-util :as ingest]
-;             [cmr.umm-spec.models.collection :as umm-c]
-;             [cmr.umm-spec.models.common :as umm-cmn]
-;             [clj-time.core :as t]
-;             [cmr.umm-spec.core :as umm-spec]
-;             [cmr.common.mime-types :as mt]
-;             [cmr.umm-spec.test.expected-conversion :as expected-conversion]))
+(ns cmr.system-int-test.ingest.translation-test
+  (:require [clojure.test :refer :all]
+            [cmr.system-int-test.utils.ingest-util :as ingest]
+            [cmr.umm-spec.models.collection :as umm-c]
+            [cmr.umm-spec.models.common :as umm-cmn]
+            [clj-time.core :as t]
+            [cmr.umm-spec.core :as umm-spec]
+            [cmr.common.mime-types :as mt]
+            [cmr.umm-spec.test.expected-conversion :as expected-conversion]))

-; (def example-record
-;   "This is the minimum valid UMM."
-;   (umm-c/map->UMM-C
-;     {:DataLineage [(umm-cmn/map->LineageType
-;                      {:Scope "METADATA"})]
-;      :MetadataStandard (umm-cmn/map->MetadataStandardType
-;                          {:Name "UMM"
-;                           :Version "1.0"})
-;      :Platform [(umm-cmn/map->PlatformType
-;                   {:ShortName "Platform"
-;                    :Instruments [(umm-cmn/map->InstrumentType {:ShortName "Instrument"})]})]
-;      :ProcessingLevel (umm-c/map->ProcessingLevelType {})
-;      :RelatedUrl [(umm-cmn/map->RelatedUrlType {:URL ["http://google.com"]})]
-;      :ResponsibleOrganization [(umm-cmn/map->ResponsibilityType {:Role "RESOURCEPROVIDER"
-;                                                                  :Party (umm-cmn/map->PartyType {})})]
-;      :ScienceKeyword [(umm-cmn/map->ScienceKeywordType {:Category "cat" :Topic "top" :Term "ter"})]
-;      :SpatialExtent [(umm-cmn/map->SpatialExtentType {:GranuleSpatialRepresentation "NO_SPATIAL"})]
+(def example-record
+  "This is the minimum valid UMM."
+  (umm-c/map->UMM-C
+    {:DataLineage [(umm-cmn/map->LineageType
+                     {:Scope "METADATA"})]
+     :MetadataStandard (umm-cmn/map->MetadataStandardType
+                         {:Name "UMM"
+                          :Version "1.0"})
+     :Platform [(umm-cmn/map->PlatformType
+                  {:ShortName "Platform"
+                   :Instruments [(umm-cmn/map->InstrumentType {:ShortName "Instrument"})]})]
+     :ProcessingLevel (umm-c/map->ProcessingLevelType {})
+     :RelatedUrl [(umm-cmn/map->RelatedUrlType {:URL ["http://google.com"]})]
+     :ResponsibleOrganization [(umm-cmn/map->ResponsibilityType {:Role "RESOURCEPROVIDER"
+                                                                 :Party (umm-cmn/map->PartyType {})})]
+     :ScienceKeyword [(umm-cmn/map->ScienceKeywordType {:Category "cat" :Topic "top" :Term "ter"})]
+     :SpatialExtent [(umm-cmn/map->SpatialExtentType {:GranuleSpatialRepresentation "NO_SPATIAL"})]

-;      :EntryId (umm-cmn/map->EntryIdType {:Id "short_V1"})
-;      :EntryTitle "The entry title V5"
-;      :Abstract "A very abstract collection"
-;      :TemporalExtent [(umm-cmn/map->TemporalExtentType {})]}))
+     :EntryId (umm-cmn/map->EntryIdType {:Id "short_V1"})
+     :EntryTitle "The entry title V5"
+     :Abstract "A very abstract collection"
+     :TemporalExtent [(umm-cmn/map->TemporalExtentType {})]}))

-; (def valid-formats
-;   [:umm-json
-;    :iso-smap
-;    :iso19115
-;    :dif
-;    :dif10
-;    :echo10])
+(def valid-formats
+  [:umm-json
+   :iso-smap
+   :iso19115
+   :dif
+   :dif10
+   :echo10])

-; (defn assert-translate-failure
-;   [error-regex & args]
-;   (let [{:keys [status body]} (apply ingest/translate-metadata args)]
-;     (is (= 400 status))
-;     (is (re-find error-regex body))))
+(defn assert-translate-failure
+  [error-regex & args]
+  (let [{:keys [status body]} (apply ingest/translate-metadata args)]
+    (is (= 400 status))
+    (is (re-find error-regex body))))

-; (deftest translate-metadata
-;   (doseq [input-format valid-formats
-;           output-format valid-formats]
-;     (testing (format "Translating %s to %s" (name input-format) (name output-format))
-;       (let [input-str (umm-spec/generate-metadata :collection input-format example-record)
-;             input-correction (expected-conversion/metadata-format->expected-conversion input-format)
-;             output-correction (expected-conversion/metadata-format->expected-conversion output-format)
-;             expected (-> example-record input-correction output-correction)
-;             {:keys [status headers body]} (ingest/translate-metadata :collection input-format input-str output-format)
-;             content-type (:content-type headers)]
-;         (is (= 200 status))
-;         (is (= (mt/format->mime-type output-format) content-type))
-;         (is (= expected (umm-spec/parse-metadata :collection output-format body))))))
+(deftest translate-metadata
+  (doseq [input-format valid-formats
+          output-format valid-formats]
+    (testing (format "Translating %s to %s" (name input-format) (name output-format))
+      (let [input-str (umm-spec/generate-metadata :collection input-format example-record)
+            input-correction (expected-conversion/metadata-format->expected-conversion input-format)
+            output-correction (expected-conversion/metadata-format->expected-conversion output-format)
+            expected (-> example-record input-correction output-correction)
+            {:keys [status headers body]} (ingest/translate-metadata :collection input-format input-str output-format)
+            content-type (:content-type headers)]
+        (is (= 200 status))
+        (is (= (mt/format->mime-type output-format) content-type))
+        (is (= expected (umm-spec/parse-metadata :collection output-format body))))))

-;   (testing "Failure cases"
-;     (testing "unsupported input format"
-;       (assert-translate-failure
-;         #"The mime types specified in the content-type header \[application/xml\] are not supported"
-;         :collection :xml "notread" :umm-json))
+  (testing "Failure cases"
+    (testing "unsupported input format"
+      (assert-translate-failure
+        #"The mime types specified in the content-type header \[application/xml\] are not supported"
+        :collection :xml "notread" :umm-json))

-;     (testing "not specified input format"
-;       (assert-translate-failure
-;         #"The mime types specified in the content-type header \[\] are not supported"
-;         :collection nil "notread" :umm-json))
+    (testing "not specified input format"
+      (assert-translate-failure
+        #"The mime types specified in the content-type header \[\] are not supported"
+        :collection nil "notread" :umm-json))

-;     (testing "unsupported output format"
-;       (assert-translate-failure
-;         #"The mime types specified in the accept header \[application/xml\] are not supported"
-;         :collection :echo10 "notread" :xml))
+    (testing "unsupported output format"
+      (assert-translate-failure
+        #"The mime types specified in the accept header \[application/xml\] are not supported"
+        :collection :echo10 "notread" :xml))

-;     (testing "not specified output format"
-;       (assert-translate-failure
-;         #"The mime types specified in the accept header \[\] are not supported"
-;         :collection :echo10 "notread" nil))
+    (testing "not specified output format"
+      (assert-translate-failure
+        #"The mime types specified in the accept header \[\] are not supported"
+        :collection :echo10 "notread" nil))

-;     (testing "invalid metadata"
-;       (testing "bad xml"
-;         (assert-translate-failure
-;           #"Cannot find the declaration of element 'this'"
-;           :collection :echo10 "<this> is not good XML</this>" :umm-json))
+    (testing "invalid metadata"
+      (testing "bad xml"
+        (assert-translate-failure
+          #"Cannot find the declaration of element 'this'"
+          :collection :echo10 "<this> is not good XML</this>" :umm-json))

-;       (testing "wrong xml format"
-;         (assert-translate-failure
-;           #"Invalid content was found starting with element 'Version'"
-;           :collection :dif (umm-spec/generate-metadata :collection :dif10 example-record) :umm-json))
+      (testing "wrong xml format"
+        (assert-translate-failure
+          #"Invalid content was found starting with element 'Version'"
+          :collection :dif (umm-spec/generate-metadata :collection :dif10 example-record) :umm-json))

-;       (testing "bad json"
-;         (assert-translate-failure #"object has missing required properties"
-;                                   :collection :umm-json "{}" :echo10)))))
+      (testing "bad json"
+        (assert-translate-failure #"object has missing required properties"
+                                  :collection :umm-json "{}" :echo10)))))


Add support for decoding counter columns

--- systems/cassandra-node/src/containium/systems/cassandra/embedded.clj
+++ systems/cassandra-node/src/containium/systems/cassandra/embedded.clj
@@ -18,6 +18,7 @@
            [org.apache.cassandra.cql3.statements ParsedStatement$Prepared]
            [org.apache.cassandra.service CassandraDaemon QueryState]
            [org.apache.cassandra.transport.messages ResultMessage$Rows]
+           [org.apache.cassandra.serializers LongSerializer]
            [java.util List Map Set UUID Date]
            [java.net InetAddress]
            [java.nio CharBuffer ByteBuffer]
@@ -60,7 +61,19 @@
       (->> (for [[^ColumnSpecification meta ^ByteBuffer column] (zipmap metas row)
                  :let [^AbstractType type (.type meta)
                        ^String name (.. meta name toString)]]
-             [(if keywordize? (keyword name) #_else name) (clojurify (.compose type column))])
+             [(if keywordize? (keyword name) #_else name)
+              (cond
+                (nil? column)
+                nil
+
+                (not (and (.isCounter type) (<= (.limit column) 8)))
+                (clojurify (.compose type column))
+
+                ;; Taken from org.apache.cassandra.hadoop.pigCassandraStorage:
+                ;; "treat counters like longs, specifically CCT.compose is not what we need"
+                :else
+                (. (LongSerializer/instance) (deserialize column)))
+             ])
            (into {})))))


Compojure - Address Book (Chapter 2, fixing tests).

--- clojure/address-book/test/address_book/core/address_book_tests.clj
+++ clojure/address-book/test/address_book/core/address_book_tests.clj
@@ -9,7 +9,7 @@
   (fact "Test GET"
     (let [response (app (mock/request :get "/"))]
       (:status response) => 200
-      (:body response) => (contians "Example GET")))
+      (:body response) => (contains "Example GET")))

   (fact "Test POST"
     (let [response (app (mock/request :post "/post" {:example-post "Some data"}))]


CMR-2427: Translating to umm+json is using incorrect case for SpatialCoverageTypeEnum.

--- umm-spec-lib/src/cmr/umm_spec/xml_to_umm_mappings/echo10/spatial.clj
+++ umm-spec-lib/src/cmr/umm_spec/xml_to_umm_mappings/echo10/spatial.clj
@@ -1,6 +1,7 @@
 (ns cmr.umm-spec.xml-to-umm-mappings.echo10.spatial
   "Defines mappings from ECHO10 XML spatial elements into UMM records"
-  (:require [cmr.umm-spec.simple-xpath :refer [select text]]
+  (:require [clojure.string :as str]
+            [cmr.umm-spec.simple-xpath :refer [select text]]
             [cmr.umm-spec.xml.parse :refer :all]
             [cmr.umm-spec.util :as u]))

@@ -44,7 +45,8 @@
   "Returns UMM-C spatial map from ECHO10 XML document."
   [doc]
   (let [[spatial] (select doc "/Collection/Spatial")]
-    {:SpatialCoverageType          (value-of spatial "SpatialCoverageType")
+    {:SpatialCoverageType          (when-let [sct (value-of spatial "SpatialCoverageType")]
+                                     (str/upper-case sct))
      :GranuleSpatialRepresentation (value-of spatial "GranuleSpatialRepresentation")
      :HorizontalSpatialDomain      (let [[horiz] (select spatial "HorizontalSpatialDomain")]
                                      {:ZoneIdentifier (value-of horiz "ZoneIdentifier")


[#2534] Increase timeout on exporter call [backend]

--- backend/src/akvo/lumen/lib/export.clj
+++ backend/src/akvo/lumen/lib/export.clj
@@ -3,7 +3,7 @@
             [clojure.tools.logging :as log]
             [akvo.lumen.http.client :as http.client]))

-(def http-client-req-defaults (http.client/req-opts 60000))
+(def http-client-req-defaults (http.client/req-opts 120000))

 (defmacro time*
   "Evaluates expr and prints the time it took.  Returns the value of


Added proxy-mouse-listener helper function

--- src/conexp/contrib/gui/editors/util.clj
+++ src/conexp/contrib/gui/editors/util.clj
@@ -14,7 +14,8 @@
       TreeSelectionModel]
     [java.util Vector]
     [java.awt Toolkit Dimension]
-    [java.awt.event KeyEvent ActionEvent ActionListener]
+    [java.awt.event KeyEvent ActionEvent ActionListener MouseEvent
+      MouseListener InputEvent]
     [java.awt.datatransfer DataFlavor StringSelection]
     [javax.swing.event TreeSelectionListener TableModelListener]
     [javax.swing.table DefaultTableModel])
@@ -23,7 +24,8 @@
     conexp.util
     conexp.util.hookable
     conexp.util.multimethods
-    [clojure.contrib.string :only (join split-lines split)]))
+    [clojure.contrib.string :only (join split-lines split)]
+    [clojure.set :only (union)]))

 ;; set polymorphism-namespace
 (def- *poly-ns* 'conexp.polymorphisms)
@@ -92,6 +94,12 @@
   [array]
   (seq array))

+(defmacro when-mask
+  "Takes two bitmasks and checks whether their bitwise-and is not 0,
+   if so, calls all other expressions in an implicit do."
+  [bit-mask-1 bit-mask-2 & exprs]
+  `(when (not= 0 (bit-and ~bit-mask-1 ~bit-mask-2) ~@exprs)))
+

 ;;;
 ;;; java & swing utils
@@ -153,6 +161,51 @@
     object   _object identifying the resource"
   [object]
   (UIManager/getIcon object))
+
+;;
+;; mouse-click-interface-helpers
+;;
+
+(defn proxy-mouse-listener
+  "Returns a proxy class that will implement the MouseListener
+   interface and call the given 1-ary functions accordingly.
+   The passed parameter will be a map mapping :button, :modifiers and
+   :position according to the event information.
+
+   Parameters:
+     pressed   _mouse button down event
+     released  _mouse button up event
+     entered   _mouse enters widget
+     exited    _mouse exits widget
+     clicked   _mouse button clicked"
+  [pressed released entered exited clicked]
+  (let [ translate-button {MouseEvent/NOBUTTON 0
+                           MouseEvent/BUTTON1  1
+                           MouseEvent/BUTTON2  2
+                           MouseEvent/BUTTON3  3}
+         translate-modifier (fn [m]
+                              (union
+                                (when-mask m InputEvent/ALT_DOWN_MASK #{:alt})
+                                (when-mask m InputEvent/ALT_GRAPH_DOWN_MASK #{:alt-gr})
+                                (when-mask m InputEvent/CTRL_DOWN_MASK #{:control})
+                                (when-mask m InputEvent/SHIFT_DOWN_MASK #{:shift})
+                                (when-mask m InputEvent/META_DOWN_MASK #{:meta})))
+         translate-event (fn [event]
+                           {:button (translate-button (.getButton event))
+                            :modifiers (translate-modifier (.getModifiers event))
+                            :position [(.getX event) (.getY event)]})]
+
+    (proxy [MouseListener] []
+      (mousePressed [event]
+        (with-swing-threads* (pressed (translate-event event))))
+      (mouseReleased [event]
+        (with-swing-threads* (released (translate-event event))))
+      (mouseEntered [event]
+        (with-swing-threads* (entered (translate-event event))))
+      (mouseExited [event]
+        (with-swing-threads* (exited (translate-event event))))
+      (mouseClicked [event]
+        (with-swing-threads* (clicked (translate-event event)))))))

 ;;
@@ -961,7 +1014,7 @@
                                       :vert JToolBar/VERTICAL}
                                       orientation))
          scrollpane (JScrollPane. toolbar
-                      JScrollPane/VERTICAL_SCROLLBAR_AS_NEEDED
+                      JScrollPane/VERTICAL_SCROLLBAR_ALWAYS
                       JScrollPane/HORIZONTAL_SCROLLBAR_NEVER)
          widget (toolbar-control. scrollpane toolbar) ]
     (apply-exprs widget setup)


Implemented interval scale

Implemented interval scale

--- src/conexp/fca/many_valued_contexts.clj
+++ src/conexp/fca/many_valued_contexts.clj
@@ -265,6 +265,31 @@
   (assert (= 2 (count values)))
   (nominal-scale values))

+(defn interval-scale
+  "Returns the interval scale on the set values. Note that values must
+  be ordered (e.g. vector or list), because otherwise the result will
+  be arbitrary"
+  ([values]
+    (interval-scale values values < >=))
+
+  ([values others]
+    (interval-scale values others < >=))
+
+  ([values others < >=]
+      (let [pairs (partition 2 1 others)
+            last-other (last others)
+            atts  (map #(str "[" (first %) ", " (second %) ")") pairs)
+            inz   (set-of
+                      [g (str "[" (first m) ", " (second m) ")")]
+                      [g values,
+                       m pairs
+                       :when (and (< g (second m)) (>= g (first m)))
+                       ])
+            ]
+
+            (make-context values atts inz)))
+  )
+
 ;;;

 (defmacro scale-mv-context-with


Bumped deps versions.

Bumped deps versions.

--- lambda-blog/project.clj
+++ lambda-blog/project.clj
@@ -4,9 +4,9 @@
   :license {:name "MIT License"
             :url "http://www.opensource.org/licenses/mit-license.php"}
   :dependencies [[clj-time "0.11.0"]
-                 [com.taoensso/timbre "4.2.1"]
+                 [com.taoensso/timbre "4.3.0"]
                  [commons-validator "1.5.0"]
-                 [markdown-clj "0.9.85"]
+                 [markdown-clj "0.9.86"]
                  [me.raynes/fs "1.4.6"]
                  [me.xuender/unidecode "0.0.7"]
                  [org.clojure/clojure "1.7.0"]


:bug: Retrieve complete information for files in dashboard search

--- backend/src/uxbox/services/queries/files.clj
+++ backend/src/uxbox/services/queries/files.clj
@@ -55,10 +55,17 @@
              ppr.is_owner = true or
              ppr.can_edit = true)
    )
-   select file.*
+   select distinct
+          file.*,
+          array_agg(page.id) over pages_w as pages,
+          first_value(page.data) over pages_w as data
      from file
     inner join projects as pr on (file.project_id = pr.id)
+     left join page on (file.id = page.file_id)
     where file.name ilike ('%' || $3 || '%')
+   window pages_w as (partition by file.id order by page.created_at
+                      range between unbounded preceding
+                                and unbounded following)
     order by file.created_at asc")

 (s/def ::search-files


correct config spec docs for reload-cli

correct config spec docs for reload-cli

--- sidecar/src/figwheel_sidecar/schemas/config.clj
+++ sidecar/src/figwheel_sidecar/schemas/config.clj
@@ -346,9 +346,6 @@
 and then marks any cljs namespaces that depend on the clj file for
 recompilation and then notifies the figwheel client that these
 namespaces have changed.
-
-If there is no macro in the clj/cljc namespace figwheel marks all cljs files
-for recompilation.

 If you want to disable this behavior:


dead code

dead code

--- test/cljc/reitit/chain.clj
+++ test/cljc/reitit/chain.clj
@@ -1,382 +0,0 @@
-; Copyright 2013 Relevance, Inc.
-; Copyright 2014-2016 Cognitect, Inc.
-
-; The use and distribution terms for this software are covered by the
-; Eclipse Public License 1.0 (http://opensource.org/licenses/eclipse-1.0)
-; which can be found in the file epl-v10.html at the root of this distribution.
-;
-; By using this software in any fashion, you are agreeing to be bound by
-; the terms of this license.
-;
-; You must not remove this notice, or any other, from this software.
-
-(comment
-(ns reitit.chain
-  "Interceptor pattern. Executes a chain of Interceptor functions on a
-  common \"context\" map, maintaining a virtual \"stack\", with error
-  handling and support for asynchronous execution."
-  (:refer-clojure :exclude (name))
-  (:require [clojure.core.async :as async :refer [<! go]]
-            [io.pedestal.log :as log]
-            [io.pedestal.interceptor :as interceptor])
-  (:import java.util.concurrent.atomic.AtomicLong))
-
-(defrecord Context [execution-id stack queue terminators supressed async-info rebind])
-
-(declare execute)
-(declare execute-only)
-
-(defn- channel? [c] (instance? clojure.core.async.impl.protocols.Channel c))
-
-;; This is used for printing out interceptors within debug messages
-(defn- name [interceptor]
-  (:name interceptor (pr-str interceptor)))
-
-(defn- throwable->ex-info [^Throwable t execution-id interceptor stage]
-  (let [iname (name interceptor)
-        throwable-str (pr-str (type t))]
-    (ex-info (str throwable-str " in Interceptor " iname " - " (.getMessage t))
-             (merge {:execution-id execution-id
-                     :stage stage
-                     :interceptor iname
-                     :exception-type (keyword throwable-str)
-                     :exception t}
-                    (ex-data t))
-             t)))
-
-(defn- try-f
-  "If f is not nil, invokes it on context. If f throws an exception,
-  assoc's it on to context as :error."
-  [context interceptor stage]
-  (let [execution-id (:execution-id context)]
-    (if-let [f (stage interceptor)]
-      (try (log/debug :interceptor (name interceptor)
-                      :stage stage
-                      :execution-id execution-id
-                      :fn f)
-           (f context)
-           (catch Throwable t
-             (log/debug :throw t :execution-id execution-id)
-             (assoc context :error (throwable->ex-info t execution-id interceptor stage))))
-      (do (log/trace :interceptor (name interceptor)
-                     :skipped? true
-                     :stage stage
-                     :execution-id execution-id)
-          context))))
-
-(defn- try-error
-  "If error-fn is not nil, invokes it on context and the current :error
-  from context."
-  [context interceptor]
-  (let [execution-id (:execution-id context)]
-    (if-let [error-fn (:error interceptor)]
-      (let [ex (:error context)
-            stage :error]
-        (log/debug :interceptor (name interceptor)
-                   :stage :error
-                   :execution-id execution-id)
-        (try (error-fn (assoc context :error nil) ex)
-             (catch Throwable t
-               (if (identical? (type t) (type (:exception ex)))
-                 (do (log/debug :rethrow t :execution-id execution-id)
-                     context)
-                 (do (log/debug :throw t :suppressed (:exception-type ex) :execution-id execution-id)
-                     (-> context
-                         (assoc :error (throwable->ex-info t execution-id interceptor :error))
-                         (update :suppressed conj ex)))))))
-      (do (log/trace :interceptor (name interceptor)
-                     :skipped? true
-                     :stage :error
-                     :execution-id execution-id)
-          context))))
-
-(defn- check-terminators
-  "Invokes each predicate in :terminators on context. If any predicate
-  returns true, removes :queue from context."
-  [context]
-  (if (some #(% context) (:terminators context))
-    (let [execution-id (:execution-id context)]
-      (log/debug :in 'check-terminators
-                 :terminate? true
-                 :execution-id execution-id)
-      (assoc context :queue nil))
-    context))
-
-(defn- prepare-for-async
-  "Call all of the :enter-async functions in a context. The purpose of these
-  functions is to ready backing servlets or any other machinery for preparing
-  an asynchronous response."
-  [{:keys [enter-async] :as context}]
-  (doseq [enter-async-fn enter-async]
-    (enter-async-fn context)))
-
-(defn- go-async
-  "When presented with a channel as the return value of an enter function,
-  wait for the channel to return a new-context (via a go block). When a new
-  context is received, restart execution of the interceptor chain with that
-  context.
-  This function is non-blocking, returning nil immediately (a signal to halt
-  further execution on this thread)."
-  ([old-context context-channel]
-   (prepare-for-async old-context)
-   (go
-     (if-let [new-context (<! context-channel)]
-       (execute new-context)
-       (execute (assoc (assoc old-context :queue nil :async-info nil)
-                  :stack (get-in old-context [:async-info :stack])
-                  :error (ex-info "Async Interceptor closed Context Channel before delivering a Context"
-                                  {:execution-id (:execution-id old-context)
-                                   :stage (get-in old-context [:async-info :stage])
-                                   :interceptor (name (get-in old-context [:async-info :interceptor]))
-                                   :exception-type :PedestalChainAsyncPrematureClose})))))
-   nil)
-  ([old-context context-channel interceptor-key]
-   (prepare-for-async old-context)
-   (go
-     (if-let [new-context (<! context-channel)]
-       (execute-only new-context interceptor-key)
-       (execute-only (assoc (assoc old-context :queue nil :async-info nil)
-                       :stack (get-in old-context [:async-info :stack])
-                       :error (ex-info "Async Interceptor closed Context Channel before delivering a Context"
-                                       {:execution-id (:execution-id old-context)
-                                        :stage (get-in old-context [:async-info :stage])
-                                        :interceptor (name (get-in old-context [:async-info :interceptor]))
-                                        :exception-type :PedestalChainAsyncPrematureClose}))
-                     interceptor-key)))
-   nil))
-
-(defn- process-all-with-binding
-  "Invokes `interceptor-key` functions of all Interceptors on the execution
-  :queue of context, saves them on the :stack of context.
-  Returns updated context.
-  By default, `interceptor-key` is :enter"
-  ([context]
-   (process-all-with-binding context :enter))
-  ([context interceptor-key]
-   (log/debug :in 'process-all :handling interceptor-key :execution-id (:execution-id context))
-   (loop [context context]
-     (let [queue (:queue context)
-           stack (:stack context)]
-       (log/trace :context context)
-       (if (empty? queue)
-         context
-         (let [interceptor (peek queue)
-               old-context context
-               new-queue (pop queue)
-               ;; conj on nil returns a list, acts like a stack:
-               new-stack (conj stack interceptor)
-               context (-> context
-                           (assoc :queue new-queue)
-                           (assoc :stack new-stack)
-                           (try-f interceptor interceptor-key))]
-           (cond
-             (channel? context) (go-async (assoc old-context
-                                            :async-info {:interceptor interceptor
-                                                         :stage interceptor-key
-                                                         :stack new-stack})
-                                          context)
-             (:error context) (assoc context :queue nil)
-             (not= (:bindings context) (:bindings old-context)) (assoc context :rebind true)
-             true (recur (check-terminators context)))))))))
-
-(defn- process-all
-  [context interceptor-key]
-  ;; If we're processing leave handlers, reverse the queue
-  (let [context (if (= interceptor-key :leave) (update context :queue reverse) context)
-        context (with-bindings (or (:bindings context)
-                                   {})
-                  (process-all-with-binding context interceptor-key))]
-    (if (:rebind context)
-      (recur (assoc context :rebind nil) interceptor-key)
-      context)))
-
-(defn- process-any-errors-with-binding
-  "Unwinds the context by invoking :error functions of Interceptors on
-  the :stack of context, but **only** if there is an :error present in the context."
-  [context]
-  (log/debug :in 'process-any-errors :execution-id (:execution-id context))
-  (loop [context context]
-    (let [stack (:stack context)]
-      (log/trace :context context)
-      (if (empty? stack)
-        context
-        (let [interceptor (peek stack)
-              pre-bindings (:bindings context)
-              old-context context
-              context (assoc context :stack (pop stack))
-              context (if (:error context)
-                        (try-error context interceptor)
-                        context)]
-          (cond
-            (channel? context) (go-async old-context context)
-            (not= (:bindings context) pre-bindings) (assoc context :rebind true)
-            true (recur context)))))))
-
-(defn- process-any-errors
-  "Establish the bindings present in `context` as thread local
-  bindings, and then invoke process-any-errors-with-binding.
-  Conditionally re-establish bindings if a change in bindings is made by an
-  interceptor."
-  [context]
-  (let [context (with-bindings (or (:bindings context) {})
-                  (process-any-errors-with-binding context))]
-    (if (:rebind context)
-      (recur (assoc context :rebind nil))
-      context)))
-
-(defn- enter-all
-  "Establish the bindings present in `context` as thread local
-  bindings, and then invoke enter-all-with-binding. Conditionally
-  re-establish bindings if a change in bindings is made by an
-  interceptor."
-  [context]
-  (process-all context :enter))
-
-(defn- leave-all-with-binding
-  "Unwinds the context by invoking :leave functions of Interceptors on
-  the :stack of context. Returns updated context."
-  [context]
-  (log/debug :in 'leave-all :execution-id (:execution-id context))
-  (loop [context context]
-    (let [stack (:stack context)]
-      (log/trace :context context)
-      (if (empty? stack)
-        context
-        (let [interceptor (peek stack)
-              pre-bindings (:bindings context)
-              old-context context
-              context (assoc context :stack (pop stack))
-              context (if (:error context)
-                        (try-error context interceptor)
-                        (try-f context interceptor :leave))]
-          (cond
-            (channel? context) (go-async old-context context)
-            (not= (:bindings context) pre-bindings) (assoc context :rebind true)
-            true (recur context)))))))
-
-(defn- leave-all
-  "Establish the bindings present in `context` as thread local
-  bindings, and then invoke leave-all-with-binding. Conditionally
-  re-establish bindings if a change in bindings is made by an
-  interceptor."
-  [context]
-  (let [context (with-bindings (or (:bindings context) {})
-                  (leave-all-with-binding context))]
-    (if (:rebind context)
-      (recur (assoc context :rebind nil))
-      context)))
-
-(defn enqueue
-  "Adds interceptors to the end of context's execution queue. Creates
-  the queue if necessary. Returns updated context."
-  [context interceptors]
-  {:pre (every? interceptor/interceptor? interceptors)}
-  (log/trace :enqueue (map name interceptors) :context context)
-  (update context :queue
-          (fnil into clojure.lang.PersistentQueue/EMPTY)
-          interceptors))
-
-(defn enqueue*
-  "Like 'enqueue' but vararg.
-  If the last argument is a sequence of interceptors,
-  they're unpacked and to added to the context's execution queue."
-  [context & interceptors-and-seq]
-  (if (seq? (last interceptors-and-seq))
-    (enqueue context (apply list* interceptors-and-seq))
-    (enqueue context interceptors-and-seq)))
-
-(defn terminate
-  "Removes all remaining interceptors from context's execution queue.
-  This effectively short-circuits execution of Interceptors' :enter
-  functions and begins executing the :leave functions."
-  [context]
-  (log/trace :in 'terminate :context context)
-  (assoc context :queue nil))
-
-(defn terminate-when
-  "Adds pred as a terminating condition of the context. pred is a
-  function that takes a context as its argument. It will be invoked
-  after every Interceptor's :enter function. If pred returns logical
-  true, execution will stop at that Interceptor."
-  [context pred]
-  (update context :terminators conj pred))
-
-(def ^:private ^AtomicLong execution-id (AtomicLong.))
-
-(defn- begin [context]
-  (if (:execution-id context)
-    context
-    (let [execution-id (.incrementAndGet execution-id)]
-      (log/debug :in 'begin :execution-id execution-id)
-      (log/trace :context context)
-      (assoc context :execution-id execution-id))))
-
-(defn- end [context]
-  (if (:execution-id context)
-    (do
-      (log/debug :in 'end :execution-id (:execution-id context) :context-keys (keys context))
-      (log/trace :context context)
-      (assoc context :stack nil :execution-id nil))
-    context))
-
-(defn execute-only
-  "Like `execute`, but only processes the interceptors in a single direction,
-  using `interceptor-key` (i.e. :enter, :leave) to determine which functions
-  to call.
-  ---
-  Executes a queue of Interceptors attached to the context. Context
-  must be a map, Interceptors are added with 'enqueue'.
-  An Interceptor Record has keys :enter, :leave, and :error.
-  The value of each key is a function; missing
-  keys or nil values are ignored. When executing a context, all
-  the `interceptor-key` functions are invoked in order. As this happens, the
-  Interceptors are pushed on to a stack."
-  ([context interceptor-key]
-   (let [context (some-> context
-                         map->Context
-                         begin
-                         (process-all interceptor-key)
-                         terminate
-                         process-any-errors
-                         end)]
-     (if-let [ex (:error context)]
-       (throw ex)
-       context)))
-  ([context interceptor-key interceptors]
-   (execute-only (enqueue context interceptors) interceptor-key)))
-
-(defn execute
-  "Executes a queue of Interceptors attached to the context. Context
-  must be a map, Interceptors are added with 'enqueue'.
-  An Interceptor is a map or map-like object with the keys :enter,
-  :leave, and :error. The value of each key is a function; missing
-  keys or nil values are ignored. When executing a context, first all
-  the :enter functions are invoked in order. As this happens, the
-  Interceptors are pushed on to a stack.
-  When execution reaches the end of the queue, it begins popping
-  Interceptors off the stack and calling their :leave functions.
-  Therefore :leave functions are called in the opposite order from
-  :enter functions.
-  Both the :enter and :leave functions are called on a single
-  argument, the context map, and return an updated context.
-  If any Interceptor function throws an exception, execution stops and
-  begins popping Interceptors off the stack and calling their :error
-  functions. The :error function takes two arguments: the context and
-  an exception. It may either handle the exception, in which case the
-  execution continues with the next :leave function on the stack; or
-  re-throw the exception, passing control to the :error function on
-  the stack. If the exception reaches the end of the stack without
-  being handled, execute will throw it."
-  ([context]
-   (let [context (some-> context
-                         begin
-                         enter-all
-                         terminate
-                         leave-all
-                         end)]
-     (if-let [ex (:error context)]
-       (throw ex)
-       context)))
-  ([context interceptors]
-   (execute (enqueue context interceptors))))
-)


Adjust height

Adjust height

--- src/dactyl_keyboard/dactyl-manuform.clj
+++ src/dactyl_keyboard/dactyl-manuform.clj
@@ -122,7 +122,7 @@
                           (translate column-offset))]
     (->> placed-shape
          (rotate (/ π 12) [0 1 0])
-         (translate [0 0 25]))))
+         (translate [0 0 23]))))

 (def key-holes
   (apply union
@@ -196,7 +196,7 @@
 ;;;;;;;;;;;;
 ;; Thumbs ;;
 ;;;;;;;;;;;;
-(def thumborigin [-23 -34 48])
+(def thumborigin [-23 -34 46])

 (defn deg2rad [degrees]
   (* (/ degrees 180) pi))
@@ -408,11 +408,9 @@
    (for [y (range 0 3)] (key-wall-brace 0 y -1 0 web-post-tl 0 y       -1 0 web-post-bl))
    (for [y (range 1 3)] (key-wall-brace 0 (dec y) -1 0 web-post-bl 0 y -1 0 web-post-tl))
    ; front wall
-  ;  (key-wall-brace 2 3 0 -1 web-post-bl 2 3 0 -1 web-post-br)
    (key-wall-brace 3 3 0 -1 web-post-bl 3 3 0.5 -1 web-post-br)
    (key-wall-brace 4 2 0 -1 web-post-bl 4 2 0 -1 web-post-br)
    (key-wall-brace 5 2 0 -1 web-post-bl 5 2 0 -1 web-post-br)
-  ;  (key-wall-brace 2 3 0 -1 web-post-br 3 3 0 -1 web-post-bl)
    (key-wall-brace 3 3 0.5 -1 web-post-br 4 2 1 -1 web-post-bl)
    (key-wall-brace 4 2 0 -1 web-post-br 5 2 0 -1 web-post-bl)
    ; thumb walls
@@ -430,14 +428,8 @@
    (wall-brace thumb-mr-place  0 -1 web-post-bl thumb-br-place  0 -1 web-post-br)
    (wall-brace thumb-ml-place  0  1 web-post-tl thumb-bl-place  0  1 web-post-tr)
    (wall-brace thumb-bl-place -1  0 web-post-bl thumb-br-place -1  0 web-post-tl)
-
    (wall-brace thumb-ml-place  0  1 web-post-tr thumb-tl-place -2.5  0 thumb-post-tl)
    (wall-brace thumb-tl-place -1  0 thumb-post-tl (partial key-place 0 2) -1  0 web-post-bl)
-  ;  (wall-brace thumb-ml-place  0  1 web-post-tr thumb-tl-place  0  1 web-post-tl)
-  ;  (wall-brace thumb-tl-place  0  1 thumb-post-tl (partial key-place 0 2)  0  1 web-post-bl)
-  ;  (wall-brace thumb-tl-place  0  1 web-post-tl thumb-tl-place  0  1 thumb-post-tl)
-  ;  (wall-brace thumb-tl-place  0  1 thumb-post-tl (partial key-place 0 2)  0  1 web-post-bl)
-  ;  (wall-brace thumb-tl-place  0  1 web-post-tl thumb-tl-place  0  1 thumb-post-tl)

    (wall-brace thumb-tr-place  0 -1 thumb-post-br (partial key-place 3 3)  0 -1 web-post-bl)
   ))


[#2964] Remove empty option value on not null

 regexp_split_to_array('opt1|opt2|', '\|') => {opt1, opt2, ''}
 array_remove(regexp_split_to_array('opt1|opt2|', '\|'), '') => {opt1, opt2}

--- backend/src/akvo/lumen/lib/aggregation/commons.clj
+++ backend/src/akvo/lumen/lib/aggregation/commons.clj
@@ -49,7 +49,7 @@

 (defn sql-option-bucket-column [bucket-column]
   (if (= "option" (:type bucket-column))
-    (format "unnest(regexp_split_to_array(%1$s,'\\|'))" (:columnName bucket-column))
+    (format "unnest(array_remove(regexp_split_to_array(%1$s,'\\|'), ''))" (:columnName bucket-column))
     (:columnName bucket-column)))

 (defn data-groups-sql-template


adding default value for z coord if it is not provided (#207)

--- server/src/spacon/components/location/db.clj
+++ server/src/spacon/components/location/db.clj
@@ -34,7 +34,7 @@
   [loc]
   (let [x (get-in loc [:geometry :coordinates 0])
         y (get-in loc [:geometry :coordinates 1])
-        z (get-in loc [:geometry :coordinates 2])
+        z (get-in loc [:geometry :coordinates 2] 0)
         p (jeom/point (jeom/c x y z))
         did (get-in loc [:metadata :client])]
     (upsert p did)))


Add test for `mime-type`

Add test for `mime-type`

--- test/io/perun_test.clj
+++ test/io/perun_test.clj
@@ -184,7 +184,7 @@
         (testing "slug"
           (value-test :path "public/test.html"
                       :value-fn #(meta= %1 %2 :slug "test")
-                      :msg "`:slug` should move a file"))
+                      :msg "`slug` should move a file"))

         (p/permalink)
         (testing "permalink"
@@ -194,7 +194,15 @@
         (testing "canonical-url"
           (value-test :path "public/test/index.html"
                       :value-fn #(meta= %1 %2 :canonical-url "http://example.com/test/")
-                      :msg "`canonical-url` should be implicitly set"))
+                      :msg "`:canonical-url` should be implicitly set"))
+
+        (p/mime-type)
+        (testing "mime-type"
+          (value-test :path "public/test/index.html"
+                      :value-fn #(and (meta= %1 %2 :mime-type "text/html")
+                                      (meta= %1 %2 :file-type "text"))
+                      :msg "`mime-type` should be set `:mime-type` and `:file-type` metadata"))
+
         (p/sitemap)
         (testing "sitemap"
           (file-exists? :path "public/sitemap.xml"


Fix edge case where schema could be generated with a non-Datomic type. Code cleanup.

--- src/provisdom/spectomic/core.cljc
+++ src/provisdom/spectomic/core.cljc
@@ -18,13 +18,19 @@
    java.net.URI         :db.type/uri
    clojure.lang.Keyword :db.type/keyword})

+(def datomic-types (conj (set (vals class->datomic-type)) :db.type/bytes :db.type/ref))
+
+(defn datomic-type?
+  [x]
+  "Returns true if `x` is a datomic type."
+  (some? (datomic-types x)))
+
 (defn- obj->datomic-type
   [obj]
   (let [t (type obj)]
     (cond
       (contains? class->datomic-type t) (class->datomic-type t)
       (map? obj) :db.type/ref
-      (coll? obj) :coll
       (nil? obj) nil
       (= (Class/forName "[B") (.getClass obj)) :db.type/bytes
       :else (type obj))))
@@ -34,7 +40,11 @@
   [samples]
   (into #{}
         (comp
-          (map obj->datomic-type)
+          (map (fn [sample]
+                 (if (or (sequential? sample) (set? sample))
+                   ::cardinality-many
+                   (obj->datomic-type sample))))
+          ;; we need to remove nils for the cases where a spec is nilable.
           (filter some?))
         samples))

@@ -54,22 +64,25 @@
         types (sample-types samples)]
     ;; Makes sure we are getting consistent types from the generator. If types are inconsistent then schema
     ;; generation is unclear.
-    (if (> (count types) 1)
-      (throw (ex-info "Spec resolves to multiple types." {:spec spec :types types}))
-      (if (empty? types)
-        (throw (ex-info "No matching Datomic types." {:spec spec}))
-        (let [t (first types)]
-          (if (= t :coll)
-            (let [collection-types (sample-types (mapcat identity samples))]
-              (cond
-                (> (count collection-types) 1)
-                (throw (ex-info "Spec collection contains multiple types." {:spec spec :types collection-types}))
-                (= :coll (first collection-types))
-                (throw (ex-info "Cannot create schema for a collection of collections." {:spec spec}))
-                :else {:db/valueType   (first collection-types)
-                       :db/cardinality :db.cardinality/many}))
-            {:db/valueType   t
-             :db/cardinality :db.cardinality/one}))))))
+    (cond
+      (> (count types) 1) (throw (ex-info "Spec resolves to multiple types." {:spec spec :types types}))
+      (empty? types) (throw (ex-info "No matching Datomic types." {:spec spec}))
+      :else
+      (let [t (first types)]
+        (cond
+          (= t ::cardinality-many) (let [collection-types (sample-types (mapcat identity samples))]
+                                     (cond
+                                       (> (count collection-types) 1)
+                                       (throw (ex-info "Spec collection contains multiple types."
+                                                       {:spec spec :types collection-types}))
+                                       (= ::cardinality-many (first collection-types))
+                                       (throw (ex-info "Cannot create schema for a collection of collections."
+                                                       {:spec spec}))
+                                       :else {:db/valueType   (first collection-types)
+                                              :db/cardinality :db.cardinality/many}))
+          (datomic-type? t) {:db/valueType   t
+                             :db/cardinality :db.cardinality/one}
+          :else (throw (ex-info "Invalid Datomic type." {:spec spec :type t})))))))

 (defn- spec-and-data
   [s]


AW + FM | 270 | fixed bug in masthead where sign out button was always shown

--- src/objective8/front_end/templates/page_furniture.clj
+++ src/objective8/front_end/templates/page_furniture.clj
@@ -57,7 +57,7 @@
            [:.clj-username] (html/content (:username user))))

 (defn masthead [{:keys [user] :as context}]
-  (if user
+  (if (:username user)
     (masthead-signed-in context)
     (masthead-signed-out context)))


(PE-16150) Restore old pool.clj api

(PE-16150) Restore old pool.clj api

For easier migration.

--- src/puppetlabs/jdbc_util/pool.clj
+++ src/puppetlabs/jdbc_util/pool.clj
@@ -77,74 +77,83 @@
   init-fn (with the connection as argument) before returning any connections to
   the application. Accepts a timeout in ms that's used when dereferencing the
   future and by the status check. The datasource should have
-  initialization-fail-fast set before being created or this is pointless."
-  [^HikariDataSource datasource {:keys [migration-db migration-dir]} init-fn timeout]
-  (when-not (.getHealthCheckRegistry datasource)
-    (.setHealthCheckRegistry datasource (HealthCheckRegistry.)))
-  (let [init-error (atom nil)
-        pool-future
-        (future
-          (loop []
-            (if-let [result
-                     (try
-                       ;; Try to get a connection to make sure the db is ready
-                       (.close (.getConnection datasource))
-                       (try
-                         (migration/migrate migration-db migration-dir)
-                         (catch Exception e
-                           (reset! init-error e)
-                           (log/errorf e (trs "{0} - An error was encountered during database migration."
-                                              (:subname migration-db "unknown")))))
-                       (try
-                         (init-fn {:datasource datasource})
-                         (catch Exception e
-                           (reset! init-error e)
-                           (log/errorf e (trs "{0} - An error was encountered during initialization."
-                                              (.getPoolName datasource)))))
-                       datasource
-                       (catch SQLTransientException e
-                         (log/warnf e (trs "{0} - Error while attempting to connect to database, retrying."
-                                           (.getPoolName datasource)))
-                         nil))]
-              result
-              (recur))))]
-    (reify
-      DataSource
-      (getConnection [this]
-        (.getConnection (or (deref pool-future timeout nil)
-                            (throw (SQLTransientConnectionException. (tru "Timeout waiting for the database pool to become ready."))))))
-      (getConnection [this username password]
-        (.getConnection (or (deref pool-future timeout nil)
-                            (throw (SQLTransientConnectionException. (tru "Timeout waiting for the database pool to become ready."))))
-                        username
-                        password))
+  initialization-fail-fast set before being created or this is pointless.

-      Closeable
-      (close [this]
-        (.close datasource))
+  migration-opts is a map of:
+    :migration-dir, the path to the migratus migration directory on the classpath
+    :migration-db, the connection map for the db used for migrations

-      PoolStatus
-      (status [this]
-        (if (realized? pool-future)
-          (let [connectivity-check (str (.getPoolName datasource)
-                                        ".pool.ConnectivityCheck")
-                health-result (.runHealthCheck
-                               (.getHealthCheckRegistry datasource)
-                               connectivity-check)
-                healthy? (and (.isHealthy health-result)
-                              (nil? @init-error))
-                messages (remove nil? [(some->> @init-error
-                                                (.getMessage)
-                                                (tru "Initialization resulted in an error: {0}"))
-                                       (.getMessage health-result)])]
-            (cond-> {:state (if healthy?
-                              :ready
-                              :error)}
-              (not healthy?) (merge {:messages messages})))
-          {:state :starting}))
+  If migration-opts is nil or not passed, the migration step is skipped."
+  ([^HikariDataSource datasource init-fn timeout]
+   (wrap-with-delayed-init datasource nil init-fn timeout))
+  ([^HikariDataSource datasource migration-opts init-fn timeout]
+   (when-not (.getHealthCheckRegistry datasource)
+     (.setHealthCheckRegistry datasource (HealthCheckRegistry.)))
+   (let [init-error (atom nil)
+         pool-future
+         (future
+           (loop []
+             (if-let [result
+                      (try
+                        ;; Try to get a connection to make sure the db is ready
+                        (.close (.getConnection datasource))
+                        (when-let [{:keys [migration-db migration-dir]} migration-opts]
+                          (try
+                            (migration/migrate migration-db migration-dir)
+                            (catch Exception e
+                              (reset! init-error e)
+                              (log/errorf e (trs "{0} - An error was encountered during database migration."
+                                                 (:subname migration-db "unknown"))))))
+                        (try
+                          (init-fn {:datasource datasource})
+                          (catch Exception e
+                            (reset! init-error e)
+                            (log/errorf e (trs "{0} - An error was encountered during initialization."
+                                               (.getPoolName datasource)))))
+                        datasource
+                        (catch SQLTransientException e
+                          (log/warnf e (trs "{0} - Error while attempting to connect to database, retrying."
+                                            (.getPoolName datasource)))
+                          nil))]
+               result
+               (recur))))]
+     (reify
+       DataSource
+       (getConnection [this]
+         (.getConnection (or (deref pool-future timeout nil)
+                             (throw (SQLTransientConnectionException. (tru "Timeout waiting for the database pool to become ready."))))))
+       (getConnection [this username password]
+         (.getConnection (or (deref pool-future timeout nil)
+                             (throw (SQLTransientConnectionException. (tru "Timeout waiting for the database pool to become ready."))))
+                         username
+                         password))

-      (init-error [this]
-        @init-error))))
+       Closeable
+       (close [this]
+         (.close datasource))
+
+       PoolStatus
+       (status [this]
+         (if (realized? pool-future)
+           (let [connectivity-check (str (.getPoolName datasource)
+                                         ".pool.ConnectivityCheck")
+                 health-result (.runHealthCheck
+                                (.getHealthCheckRegistry datasource)
+                                connectivity-check)
+                 healthy? (and (.isHealthy health-result)
+                               (nil? @init-error))
+                 messages (remove nil? [(some->> @init-error
+                                                 (.getMessage)
+                                                 (tru "Initialization resulted in an error: {0}"))
+                                        (.getMessage health-result)])]
+             (cond-> {:state (if healthy?
+                               :ready
+                               :error)}
+               (not healthy?) (merge {:messages messages})))
+           {:state :starting}))
+
+       (init-error [this]
+         @init-error)))))

 (defn connection-pool-with-delayed-init
   "Create a connection pool that loops trying to get a connection, and then runs
@@ -152,7 +161,9 @@
   the application. Accepts a timeout in ms that's used when deferencing the
   future. This overrides the value of initialization-fail-fast and always sets
   it to false. "
-  [^HikariConfig config migration-options init-fn timeout]
-  (let [datasource (HikariDataSource. config)]
-    (.setInitializationFailFast config false)
-    (wrap-with-delayed-init datasource migration-options init-fn timeout)))
+  ([^HikariConfig config init-fn timeout]
+   (connection-pool-with-delayed-init config nil init-fn timeout))
+  ([^HikariConfig config migration-options init-fn timeout]
+   (let [datasource (HikariDataSource. config)]
+     (.setInitializationFailFast config false)
+     (wrap-with-delayed-init datasource migration-options init-fn timeout))))


Fix cases

Fix cases

--- src-cljs/frontend/components/pieces/topbar.cljs
+++ src-cljs/frontend/components/pieces/topbar.cljs
@@ -85,11 +85,11 @@
                [:li
                    ;; FIXME: NEED TO ADD QUICK START PAGE
                   [:a {:href "/quick-start"}
-                   "Quick Start"]]
+                   "Quick start"]]
                [:li
                  [:a.has-icon {:href "/build-insights"
                                :aria-label "System Status"}
-                  "System Status" [:i.material-icons.status.operational "grain"]]]]] ;; blur_on leak_add network_check
+                  "System status" [:i.material-icons.status.operational "grain"]]]]] ;; blur_on leak_add network_check

              [:li.dropdown.user-menu
@@ -99,7 +99,7 @@
                 :aria-expanded "false"}
                [:img.gravatar {:src (gh-utils/make-avatar-url user :size 60)}]]
               [:ul.dropdown-menu.pull-right.animated.slideInDown
-               [:li [:a {:href "/account"} "User Settings"]]
+               [:li [:a {:href "/account"} "User settings"]]
                (when (:admin user)
                  [:li [:a {:href "/admin"} "Admin"]])
                [:li [:a {:href "/logout/"} "Logout"]]]]]


fix test driver

fix test driver

--- test/nml/core_test.clj
+++ test/nml/core_test.clj
@@ -3,7 +3,7 @@
             [nml.core :refer :all]))

-(let [tree (nml-tree "test/nml/nl")]
+(let [tree (nml-tree (slurp "test/nml/nl"))]

   (deftest get-string
     (is (= (nml-get tree "na" "C0") "'foo'"                                         ))


Исправление бублика

Исправление бублика

--- radiolamp-6P3S/src/r6p3s/cpt/d3/chart_pie.cljs
+++ radiolamp-6P3S/src/r6p3s/cpt/d3/chart_pie.cljs
@@ -49,12 +49,12 @@
          :chart-pano-id (rc/uniq-id "chart-pano")
          :chart-pano    nil})

-      ;; om/IDidMount
-      ;; (did-mount [_]
-      ;;   (let [{:keys [chart-pano-id]} (om/get-state own)]
-      ;;     (println "OM: chart-pie -> did-mount")
-      ;;     (let [svg-pano (.select js/d3 (str "#" chart-pano-id))]
-      ;;       (om/set-state! own :chart-pano svg-pano))))
+      om/IDidMount
+      (did-mount [_]
+        (let [{:keys [chart-pano-id]} (om/get-state own)]
+          (println "OM: chart-pie -> did-mount")
+          (let [svg-pano (.select js/d3 (str "#" chart-pano-id))]
+            (om/set-state! own :chart-pano svg-pano))))

       om/IDidUpdate


Fixed user agent tests.

Fixed user agent tests.

--- scripts/test/hxgm30/agent/script/util_test.clj
+++ scripts/test/hxgm30/agent/script/util_test.clj
@@ -34,13 +34,13 @@
     (is (= "Enjoy!" (util/get-last-line test-data)))))

 (deftest test-user-agent
-  (is (= "hexagram30/agent 0.6.0-SNAPSHOT (https://github.com/hexagram30/agent)"
+  (is (= "hexagram30/agent 0.6.1-SNAPSHOT (https://github.com/hexagram30/agent)"
          util/user-agent)))

 (deftest test-ua-headers
   (is (= {:headers
           {"User-Agent"
-           "hexagram30/agent 0.6.0-SNAPSHOT (https://github.com/hexagram30/agent)"}}
+           "hexagram30/agent 0.6.1-SNAPSHOT (https://github.com/hexagram30/agent)"}}
          util/ua-headers)))

 (deftest test-remove-spaces-and-newlines


Use LD to control OSX builds

Use LD to control OSX builds

--- src-cljs/frontend/components/build_head.cljs
+++ src-cljs/frontend/components/build_head.cljs
@@ -665,6 +665,14 @@
                  (when show-all-commits?
                    (om/build-all commit-line bottom-commits))))])])))))

+(defn- show-ssh-button?
+  "Always show the SSH button on Linux builds.
+  Only show the SSH button on OSX builds if the Launch Darkly flag is enabled.
+  https://en.wikipedia.org/wiki/Truth_table#Logical_implication
+  osx -> launch-darkly"
+  [project]
+  (or (not (project-model/feature-enabled? project :osx))
+      (feature/enabled? :ios-ssh-builds)))

 (def tab-tag :li.build-info-tab)
 (def tab-link :a.tab-link)
@@ -719,9 +727,8 @@
                                                        :stop (or (:start_time build) (:stop_time build))})
                    ")"])]])

-            ;; XXX Temporarily remove the ssh info for OSX builds
             (when (and (has-scope :write-settings data)
-                       (not (project-model/feature-enabled? project :osx)))
+                       (show-ssh-button? project))
               [tab-tag {:class (when (= :ssh-info selected-tab) "active")}
                [tab-link {:href "#ssh-info"}
                 "Debug via SSH"]])
@@ -982,8 +989,7 @@
            [:ul.dropdown-menu.pull-right
             [:li
              [:a {:on-click (action-for :without_cache)} (text-for :without_cache)]]
-            ;; XXX Temporarily remove the ssh button for OSX builds
-            (when (not (project-model/feature-enabled? project :osx))
+            (when (show-ssh-button? project)
               [:li
                [:a {:on-click (action-for :with_ssh)} (text-for :with_ssh)]])]]])))))


queued times are ms

queued times are ms

--- src-cljs/frontend/components/build_head.cljs
+++ src-cljs/frontend/components/build_head.cljs
@@ -29,11 +29,11 @@

 (defn show-additional-containers-offer? [plan build]
   (when (and plan build)
-    (let [usage-queued-secs (/ (build-model/usage-queued-time build))
-          run-queued-secs (/ (build-model/run-queued-time build))]
+    (let [usage-queued-ms (build-model/usage-queued-time build)
+          run-queued-ms (build-model/run-queued-time build)]
       ;; more than 10 seconds waiting for other builds, and
       ;; less than 10 seconds waiting for additional containers (our fault)
-      (< run-queued-secs 10 usage-queued-secs))))
+      (< run-queued-ms 10000 usage-queued-ms))))

 (defn additional-containers-offer [plan build]
   [:p#additional_containers_offer


refine with-partitioning and tran item select

--- src/clj_money/models/storage/sql_storage.clj
+++ src/clj_money/models/storage/sql_storage.clj
@@ -260,6 +260,12 @@
   (when (and sort-exp (sequential? sort-exp))
     (= :desc (second sort-exp))))

+
+(defn- limit-reached?
+  [records {:keys [limit]}]
+  (and limit
+       (<= limit (count records))))
+
 ; TODO: maybe extract the sql parts and move this to the partitioning namespace?
 (defmacro with-partitioning
   [exec-fn table-name d-range options bindings & body]
@@ -276,8 +282,7 @@
           (reduce (fn [records# table#]
                     (let [found-records# (~exec-fn (sql-fn# table#))
                           updated-records# (concat records# found-records#)]
-                      (if (and (= 1 (:limit ~options))
-                               (seq updated-records#))
+                      (if (limit-reached? updated-records# ~options)
                         (reduced updated-records#)
                         updated-records#)))
                   []))))
@@ -893,9 +898,11 @@
                          (h/left-join [:reconciliations :r] [:= :r.id :i.reconciliation_id])
                          (adjust-select options)
                          (h/where (map->where criteria {:prefix "i"}))
-                         (append-sort (merge
-                                        {:sort [:i.transaction_date :i.index]}
-                                        options))
+                         (append-sort (if (:count options)
+                                           options
+                                           (merge
+                                             {:sort [:i.transaction_date :i.index]}
+                                             options)))
                          (append-limit options)))]
         (if (:count options)
           (-> result first vals first)


point to correct public directory

point to correct public directory

--- server/src/gratefulplace/middleware/routes.clj
+++ server/src/gratefulplace/middleware/routes.clj
@@ -11,5 +11,5 @@
                 ~@handlers)))

 (defroutes routes
-  (compojure.route/files "/" {:root "public"})
+  (compojure.route/files "/" {:root "../public"})
   (compojure.route/not-found "Sorry, there's nothing here."))


router no longer blocks when queue is full

If we can't enqueue the request an error is returned rigth
way. Previously the router would get blocked.

Also improving the logging, writing more information about is being
done and how much time it is taking to complete the request.

--- src/blackbox/src/leela/blackbox/czmq/router.clj
+++ src/blackbox/src/leela/blackbox/czmq/router.clj
@@ -23,26 +23,30 @@
 (defn make-queue [size]
   (java.util.concurrent.LinkedBlockingQueue. size))

-(defn enqueue [fh queue]
-  (let [[peer [blank & msg]] (split-with #(not (empty? %)) (z/recvmulti fh))]
+(defn enqueue [fh queue worker]
+  (let [[peer [blank & msg]] (split-with #(not (empty? %)) (z/recvmulti fh))
+        time                 (System/currentTimeMillis)]
     (when (empty? blank)
-      (.put queue [peer msg]))))
+      (when-not (.offer queue [time peer msg])
+        (do
+          (warn "queue full, dropping request")
+          (z/sendmulti fh (concat peer (cons "" (:onerr worker)))))))))

-(defn routing-loop [ifh ofh queue]
+(defn routing-loop [ifh ofh queue worker]
   (let [[ifh-info ofh-info] (z/poll -1 [ifh [ZMQ$Poller/POLLIN] ofh [ZMQ$Poller/POLLIN]])]
     (when (.isReadable ifh-info)
-      (enqueue ifh queue))
+      (enqueue ifh queue worker))
     (when (.isReadable ofh-info)
       (z/sendmulti ifh (z/recvmulti ofh)))))

-(defn evaluate [worker [peer msg]]
+(defn evaluate [worker [time peer msg]]
   (try
     (let [reply ((:onjob worker) msg)]
-      (debug (format "REQUEST/DONE: %s ~> %s" (pr-str (map f/bytes-to-str-unsafe msg)) (pr-str reply)))
+      (info (format "DONE %s [%d ms]" (pr-str (map f/bytes-to-str-unsafe (take 2 msg))) (- (System/currentTimeMillis) time)))
       (concat peer (cons "" reply)))
     (catch Exception e
       (let [reply (:onerr worker)]
-        (error e (format "REQUEST/FAIL: %s ~> %s" (pr-str (map f/bytes-to-str-unsafe msg)) (pr-str reply)))
+        (error e (format "FAIL %s" (pr-str (map f/bytes-to-str-unsafe (take 2 msg)))))
         (concat peer (cons "" reply))))))

 (defn run-worker [ctx endpoint queue worker]
@@ -50,7 +54,7 @@
     (trace (format "ENTER:run-worker %s" endpoint))
     (.connect (z/setup-socket fh) endpoint)
     (f/forever
-     (let [item (.poll queue 1 s)]
+     (let [item (.take queue)]
        (when item (z/sendmulti fh (evaluate worker item)))))))

 (defn fork-worker [ctx endpoint queue worker]
@@ -66,7 +70,7 @@
       (.bind (z/setup-socket ofh) ipcendpoint)
       (.bind (z/setup-socket ifh) (:endpoint cfg))
       (dotimes [_ (:capabilities cfg)] (fork-worker ctx ipcendpoint queue worker))
-      (f/supervise (routing-loop ifh ofh queue))))
+      (f/supervise (routing-loop ifh ofh queue worker))))
   (trace "EXIT:router-start1"))

 (defmacro router-start [ctx worker cfg]


Use into instead of concat in engine.events

Gets a small speed boost for avoiding the lazy seq if we are always
going to realize the seq anyway.

--- src/cljs/chocolatier/engine/systems/events.cljs
+++ src/cljs/chocolatier/engine/systems/events.cljs
@@ -20,9 +20,9 @@

 (defn subscribe
-  "Subscribe to the given event.
+  "Subscribe to the given event.

-   Multiple subscribe calls with the same event-id component-id entity-id
+   Multiple subscribe calls with the same event-id component-id entity-id
    are idempotent.

    Example:
@@ -54,7 +54,7 @@
    - [:s1] matches all results in the :s2 and :s3 key"
   [state selectors]
   (when (seq selectors)
-    (let [result (get-in state (concat [:state :events :queue] selectors))]
+    (let [result (get-in state (into [:state :events :queue] selectors))]
       (if (map? result)
         (mapcat #(get-events state (conj selectors %)) (keys result))
         result))))
@@ -86,7 +86,7 @@
   [state msg & selectors]
   (let [event (apply mk-event msg selectors)]
     (valid-event? event)
-    (update-in state (concat [:state :events :queue] selectors) conj event)))
+    (update-in state (into [:state :events :queue] selectors) conj event)))

 (defn emit-events
   "Emits a collection of events at the same time. Returns update game state."


--- test/toucan/test_setup.clj
+++ test/toucan/test_setup.clj
@@ -9,6 +9,9 @@
                                 [venue :refer [Venue]])
             [toucan.util.test :as u])
   (:import java.sql.Timestamp))
+
+;; Don't run unit tests whenever JVM shuts down
+(expectations/disable-run-on-shutdown)

 ;;; Basic Setup


fix rand-int arity

fix rand-int arity

--- cljs-admin/tourneybot_admin/core.cljs
+++ cljs-admin/tourneybot_admin/core.cljs
@@ -778,7 +778,7 @@
                           :password-valid? false)
   (if in-dev-mode?
     ;; simulate the API call
-    (js/setTimeout check-password-success (rand-int 200 400))
+    (js/setTimeout check-password-success (+ 200 (rand-int 200)))
     ;; else make the actual API call
     (let [password (:password @page-state)]
       (check-password password check-password-success check-password-error))))


Docstrings and conditions for sorting functions

--- src/com/puppetlabs/puppetdb/query/resources.clj
+++ src/com/puppetlabs/puppetdb/query/resources.clj
@@ -70,8 +70,10 @@
 (def v3-query->sql
   (partial query->sql resource-operators-v3))

-(defn- aggregate-resource-parameters
-  "TODO docs & conditions"
+(defn- consolidate-resource-params
+  "Given the raw query results from the database, consolidate all the resource
+  parameters for each resource and put them into a hash on each resource keyed
+  at `:parameters`."
   [query-results]
   (let [metadata_cols [:certname :resource :type :title :tags :exported :file :line]
         metadata      (apply juxt metadata_cols)
@@ -83,20 +85,28 @@
                              [(:name param) (json/parse-string (:value param))])))))))

 (defn- build-comp-fn
-  "TODO docs & conditions"
+  "Given a resource field and order direction, return a comparator
+  function that takes two resources and sorts them in ascending or
+  descending order based on the values of the provided field."
   [{:keys [field order]}]
   {:pre  [(keyword? field)
           (or (= order "ASC")
               (= order "DESC")
-              (nil? order))]}
+              (nil? order))]
+   :post [(fn? %)]}
   (fn [x y]
     (if (or (= order "ASC") (nil? order))
       (compare (x field) (y field))
       (compare (y field) (x field)))))

 (defn- combine-comp-fns
-  "TODO docs & conditions"
+  "Given two comparator functions, return a comparator function that
+  delegates to the first comparator, and if the result is equal, then
+  delegates to the second comparator."
   [comp-fn1 comp-fn2]
+  {:pre  [(fn? comp-fn1)
+          (fn? comp-fn2)]
+   :post [(fn? %)]}
   (fn [x y]
     (let [val1 (comp-fn1 x y)]
       (if (= val1 0)
@@ -104,8 +114,14 @@
         val1))))

 (defn- sort-on-order-by
-  "TODO docs & conditions"
+  "Sort the results of the query based on the order by clauses."
   [query-results order-bys]
+  {:pre  [(vector? query-results)
+          (vector? order-bys)
+          (every? map? order-bys)]
+   :post [(vector? %)
+          (= (count %)
+             (count query-results))]}
   (let [order-bys  (mapv #(update-in % [:field] keyword) order-bys)
         comp-fns   (map build-comp-fn order-bys)
         final-comp (reduce combine-comp-fns comp-fns)
@@ -113,12 +129,18 @@
     (vec sorted)))

 (defn- post-process-results
-  "TODO docs & conditions"
+  "Given the results of the query and the optional order-by paging clauses,
+  consolidate the results into a form appropriate for returning to the user
+  and sort them based on the order-by clauses, if there are any."
   [query-results {:keys [order-by]}]
-  (let [aggregated-results (aggregate-resource-parameters query-results)]
+  {:pre  [(vector? query-results)
+          ((some-fn nil? vector?) order-by)
+          (every? map? order-by)]
+   :post [(vector? %)]}
+  (let [consolidated-results (consolidate-resource-params query-results)]
     (if (empty? order-by)
-      aggregated-results
-      (sort-on-order-by aggregated-results order-by))))
+      consolidated-results
+      (sort-on-order-by consolidated-results order-by))))

 (defn limited-query-resources
   "Take a limit, a map of paging options, and a map of SQL queries as


fix :require usage

fix :require usage

--- test/puppetlabs/trapperkeeper/testutils/bootstrap.clj
+++ test/puppetlabs/trapperkeeper/testutils/bootstrap.clj
@@ -1,6 +1,5 @@
 (ns puppetlabs.trapperkeeper.testutils.bootstrap
   (:require [puppetlabs.trapperkeeper.core :as trapperkeeper]
-            [puppetlabs.trapperkeeper.core :refer [parse-cli-args!]]
             [puppetlabs.trapperkeeper.bootstrap :as bootstrap]))

 (def empty-config "./test-resources/config/empty.ini")
@@ -22,7 +21,7 @@
   [services other-args]
   (let [cli-data (->
                    (conj other-args "--config" empty-config)
-                   (parse-cli-args!))]
+                   (trapperkeeper/parse-cli-args!))]
     (trapperkeeper/bootstrap* services cli-data)))

 (defn parse-and-bootstrap


test self-host higher order invoke

test self-host higher order invoke

--- src/test/cljs/self_host/test.cljs
+++ src/test/cljs/self_host/test.cljs
@@ -69,7 +69,7 @@

 (deftest test-eval-str
   (async done
-    (let [l (latch 3 done)]
+    (let [l (latch 4 done)]
       (cljs/eval-str st "(+ 1 1)" nil
         {:eval node-eval}
         (fn [{:keys [error value]}]
@@ -91,6 +91,14 @@
         (fn [{:keys [error value]}]
           (is (nil? error))
           (is (fn? value))
+          (inc! l)))
+      (cljs/eval-str st "((fn [a b] (+ a b)) 1 2)" nil
+        {:eval node-eval
+         :context :expr
+         :def-emits-var true}
+        (fn [{:keys [error value]}]
+          (is (nil? error))
+          (is (== 3))
           (inc! l))))))

 (defn -main [& args]


pretty_printer component has been updated

--- utils/src/clj/hellhound/components/pretty_printer.clj
+++ utils/src/clj/hellhound/components/pretty_printer.clj
@@ -1,9 +1,10 @@
 (ns hellhound.components.pretty-printer
   (:require
+   [hellhound.logger :as logger]
    [hellhound.component :refer [deftransform]]))

 (deftransform printer
   [component v]
-  (println "PrettyPrinter --------------------------------------------")
+  (logger/debug "PrettyPrinter-START: -----------------------------------------")
   (clojure.pprint/pprint v)
-  (println))
+  (logger/debug "PrettyPrinter-END: -------------------------------------------"))


Sort repos in a more useful order.

Sort repos in a more useful order.

--- src-cljs/frontend/components/add_projects.cljs
+++ src-cljs/frontend/components/add_projects.cljs
@@ -216,7 +216,7 @@
                           (or show-forks (not (:fork repo)))
                           (= (:username repo) selected-login )
                           (gstring/caseInsensitiveContains (:name repo) repo-filter-string)))
-              filtered-repos (->> repos (filter display?) (sort-by :updated_at))]
+              filtered-repos (->> repos (filter display?) (sort-by :pushed_at) (reverse))]
           [:div (om/build repo-filter settings)
            (if (empty? filtered-repos)
              (if loading-repos?


fix cross-vcs piggieback link on org settings page

--- src-cljs/frontend/components/org_settings.cljs
+++ src-cljs/frontend/components/org_settings.cljs
@@ -1237,7 +1237,7 @@
    (html
     (let [org-name (get-in app state/org-name-path)
           vcs_type (get-in app state/org-vcs_type-path)
-          plan (get-in app state/org-plan-path)
+          {plan-org :org :as plan} (get-in app state/org-plan-path)
           plan-total (pm/stripe-cost plan)
           linux-container-cost (pm/linux-per-container-cost plan)
           price (-> plan :paid :template :price)
@@ -1248,9 +1248,9 @@
        [:div.explanation
         (when piggiebacked?
           [:p "This organization's projects will build under "
-           [:a {:href (routes/v1-org-settings-path {:org (:org_name plan)
-                                                    :vcs_type vcs_type})}
-            (:org_name plan) "'s plan."]])
+           [:a {:href (routes/v1-org-settings-path {:org (:name plan-org)
+                                                    :vcs_type (:vcs_type plan-org)})}
+            (:name plan-org) "'s plan."]])
         [:h2 "Linux"]
         (cond (> containers 1)
               [:p (str "All Linux builds will be distributed across " containers " containers.")]


change label for name on credit card

change label for name on credit card

--- src-cljs/frontend/components/org_settings.cljs
+++ src-cljs/frontend/components/org_settings.cljs
@@ -853,7 +853,7 @@
                 (om/build table/table
                           {:rows [card]
                            :key-fn (constantly "card")
-                           :columns [{:header "Name"
+                           :columns [{:header "Name on Credit Card"
                                       :cell-fn #(:name % "N/A")}
                                      {:header "Card type"
                                       :cell-fn #(:type % "N/A")}


Clean up the sample for more generality

Clean up the sample for more generality

--- 2017/clojure-blocking-async/src/clojure_blocking_async/http_client.clj
+++ 2017/clojure-blocking-async/src/clojure_blocking_async/http_client.clj
@@ -10,12 +10,12 @@

 (def url-template "https://github.com/eliben/pycparser/pull/%d")

-(defn blocking-http-get [url]
-  (clj-http.client/get url))
+(defn blocking-get-page [i]
+  (clj-http.client/get (format url-template i)))

 (defn verify
   []
-  (let [r (blocking-http-get (format url-template 22))]
+  (let [r (blocking-get-page 22)]
     (time
      (clojure.string/includes? (:body r) "integer typedefs"))))

@@ -32,20 +32,16 @@
 (defn go-blocking-generator
   [c start n]
   (doseq [i (range start (+ start n))]
-    (async/go (async/>! c
-                        (blocking-http-get
-                         (format url-template i))))))
+    (async/go (async/>! c (blocking-get-page i)))))

 (defn thread-blocking-generator
   [c start n]
   (doseq [i (range start (+ start n))]
-    (async/thread (async/>!! c
-                             (blocking-http-get
-                              (format url-template i))))))
+    (async/thread (async/>!! c (blocking-get-page i)))))

-;(def start 10)
-;(def num-results 20)
+(def start 10)
+(def num-results 20)
 ;(time (count (get-multiple go-blocking-generator 10 num-results)))
-;(time (count (get-multiple thread-blocking-generator start num-results)))
+(time (count (get-multiple thread-blocking-generator start num-results)))

 (prn (verify))


(maint) Use join on `id` for nodes-query with reports

This commit changes the nodes query to use a "regular" left join from
certnames to reports using the `latest_report_id` instead of using an
`in` expression.

--- src/puppetlabs/puppetdb/query_eng/engine.clj
+++ src/puppetlabs/puppetdb/query_eng/engine.clj
@@ -120,10 +120,7 @@
                                        [:= :certnames.certname :fs.certname]

                                        :reports
-                                       [:and
-                                        [:= :certnames.certname :reports.certname]
-                                        [:in :reports.id {:select [:latest_report_id]
-                                                          :from [:certnames]}]]
+                                       [:= :certnames.latest_report_id :reports.id]

                                        [:environments :catalog_environment]
                                        [:= :catalog_environment.id :catalogs.environment_id]


fix clojurescript puzzle

fix clojurescript puzzle

--- cljs/puzzle/src/view.cljs
+++ cljs/puzzle/src/view.cljs
@@ -65,7 +65,7 @@
 (defn switch-class! [$elem klass switch]
   ((if switch jq/add-class jq/remove-class) $elem klass))

-(defn update-fen-links! [fen]
+(defn update-fen-links! [fen $puzzle]
   (doseq [link ($ :a.fen_link $puzzle)]
     (let [href1 (jq/attr ($ link) :href)
           href2 (clojure.string/replace href1 #"fen=[^#]*(#.+)?$" #(str "fen=" fen %2))]
@@ -102,7 +102,7 @@
           (switch-class! $last :disabled is-last)
           (.position chessboard fen animate)
           (.load core/chess fen)
-          (update-fen-links! fen)
+          (update-fen-links! fen $puzzle)
           (core/color-move! $puzzle move)
           (<! (timeout (+ 50 animation-delay)))
           (let [[browse ch] (alts! [browse-chan continue-chan])]


download-tsv link available on initial tab load

--- src/cljs/org/broadinstitute/firecloud_ui/page/workspace/data/tab.cljs
+++ src/cljs/org/broadinstitute/firecloud_ui/page/workspace/data/tab.cljs
@@ -58,7 +58,7 @@
     :toolbar (fn [built-in]
                [:div {}
                 [:div {:style {:float "left"}} built-in]
-                (when-let [selected-entity-type (:selected-entity-type @state)]
+                (when-let [selected-entity-type (or (:selected-entity-type @state) (:initial-entity-type @state) (first (:entity-types @state)))]
                   [:a {:style {:textDecoration "none" :float "left" :margin "7px 0 0 1em"}
                        :href (str "/service/api/workspaces/" (:namespace (:workspace-id props)) "/"
                                (:name (:workspace-id props)) "/" selected-entity-type "/tsv")


ugly but working.

ugly but working.

--- clojure/phone-number/phone.clj
+++ clojure/phone-number/phone.clj
@@ -34,4 +34,10 @@
   (re-find #"\d{3}" (number num)))

 (defn pretty-print
-  [num])
+  [num]
+  (let [parts
+        (drop 1 (first (re-seq #"(\d{3})(\d{3})(\d{4})"
+                               (number num))))]
+    (str "(" (first parts) ") "
+         (nth parts 1) "-"
+         (nth parts 2))))


Re-enable router

Re-enable router

--- common/clojure/nightweb/router.clj
+++ common/clojure/nightweb/router.clj
@@ -9,7 +9,7 @@
             [nightweb.torrents-dht :as dht]
             [nightweb.users :as users]))

-(def ^:const enable-router? false) ; if false, I2P won't boot
+(def ^:const enable-router? true) ; if false, I2P won't boot
 (def is-first-boot? (atom false))

 (defn start-router


fixing dependencies for example project

fixing dependencies for example project

--- example/project.clj
+++ example/project.clj
@@ -28,7 +28,8 @@
                        :zk-seed           "seeds.zk/run"}}

   :profiles {:dev
-             {:joplin
+             {:dependencies [[com.h2database/h2 "1.3.171"]]
+              :joplin
               {:databases    {:dt-dev        {:type :dt, :url ~(str "datomic:free://" TARGET-HOST ":4334/test")}
                               :sql-dev       {:type :sql, :url "jdbc:h2:file:dev"}
                               :sql-dev-extra {:type :sql, :migration-table "ragtime_migrations_extra", :url "jdbc:h2:file:dev"}}


Less config for the test

Less config for the test

--- test/clj/reitit/pedestal_test.clj
+++ test/clj/reitit/pedestal_test.clj
@@ -33,11 +33,7 @@
                     {:interceptors [{:name :nop} (exception/exception-interceptor)]}
                     ["/ok" (fn [_] {:status 200, :body "ok"})]
                     ["/fail" (fn [_] (throw (ex-info "kosh" {})))]]))
-        service (-> {:env :dev
-                     :io.pedestal.http/type :jetty
-                     :io.pedestal.http/port 3000
-                     :io.pedestal.http/join? false
-                     :io.pedestal.http/request-logger nil
+        service (-> {:io.pedestal.http/request-logger nil
                      :io.pedestal.http/routes []}
                     (io.pedestal.http/default-interceptors)
                     (pedestal/replace-last-interceptor router)


New tests: test-bool->string-1 and test-bool->string-2

--- test/clj_flotr/generator_test.clj
+++ test/clj_flotr/generator_test.clj
@@ -38,3 +38,24 @@
     (testing "Test if bool->string function exists"
         (is (function? bool->string))))

+;
+; Unit tests
+;
+
+(deftest test-bool->string-1
+    (testing "Test the function bool->string"
+        (are [x y] (= x y)
+            "false" (bool->string false)
+            "false" (bool->string nil))))
+
+(deftest test-bool->string-2
+    (testing "Test the function bool->string"
+        (are [x y] (= x y)
+            "true" (bool->string true)
+            "true" (bool->string 42)
+            "true" (bool->string "foobar")
+            "true" (bool->string '())
+            "true" (bool->string [])
+            "true" (bool->string {})
+            "true" (bool->string #{}))))
+


PLD: update tests

PLD: update tests

--- test/hatti/views/record_test.cljs
+++ test/hatti/views/record_test.cljs
@@ -53,7 +53,7 @@
                                                         {:expand-meta? true}})
         expand-meta #(sel1 % :.expand-meta)]
     (testing "Submission XX title is present"
-      (is (re-matches #".*Submission 1.*" (dommy/text (sel1 s :h4)))))
+      (is (re-matches #".*ID: 0.*" (dommy/text (sel1 s :h4)))))
     (testing "Each Question / Answer pair is rendered"
       (is (every? (->> (sel s :span.answer) (map dommy/text) set)
                   qstn-answers))
@@ -103,8 +103,8 @@
         tbl-el (submission-container :table d gps-form owner)
         submission-time (get d "_submission_time")]
     (testing "Submission XX title is present for both"
-      (is (re-find #"Submission 1" (dommy/text (sel1 map-el :h4))))
-      (is (re-find #"Submission 1" (dommy/text (sel1 tbl-el :h4)))))
+      (is (re-find #"ID: 0" (dommy/text (sel1 map-el :h4))))
+      (is (re-find #"ID: 0" (dommy/text (sel1 tbl-el :h4)))))
     (testing "Map has a div.info-scroll, table has a table"
       (is (sel1 map-el :div.info-scroll))
       (is (sel1 tbl-el :table)))


1.3 rejects =>'stuff. Need => 'stuff

1.3 rejects =>'stuff. Need => 'stuff

--- test/midje/ideas/t_background.clj
+++ test/midje/ideas/t_background.clj
@@ -97,7 +97,7 @@
  "mixtures"
  (prerequisites-to-fakes
   '[ (f 1) => 2 (before :checks (swap! test-atom (constantly 0))) (f 2) => 3 ])
- =>'[ (midje.semi-sweet/fake (f 1) => 2 :background :background
+ => '[ (midje.semi-sweet/fake (f 1) => 2 :background :background
                                         :times (range 0))
       (before :checks (swap! test-atom (constantly 0)))
       (midje.semi-sweet/fake (f 2) => 3 :background :background


change id

change id

--- src/clj/dokkaa_builder/pages.clj
+++ src/clj/dokkaa_builder/pages.clj
@@ -15,4 +15,4 @@

 (defn index []
   (layout
-   [:div {:id "my-app"}]))
+   [:div {:id "app"}]))


Can use Paige Piper to shuffle only now.

--- src/clj/game/cards-resources.clj
+++ src/clj/game/cards-resources.clj
@@ -368,8 +368,7 @@
    (let [pphelper (fn [card cards]
                     (let [num (count cards)]
                       {:optional
-                       {:req (req (> num 0))
-                        :prompt (str "Use Paige Piper to trash copies of " (:title card) "?")
+                       {:prompt (str "Use Paige Piper to trash copies of " (:title card) "?")
                         :yes-ability {:prompt "How many would you like to trash?"
                                       :choices {:number (req num)}
                                       :msg "shuffle their Stack"


Class and style props in collection component

--- src/cljs/re_form/collection.cljs
+++ src/cljs/re_form/collection.cljs
@@ -1,6 +1,7 @@
 (ns re-form.collection
   (:require [reagent.core :as c]
             [re-frame.core :as rf]
+            [re-form.core :as re-form]
             [re-form.context :as ctx]))

 (defn- drop-idx [v idx]
@@ -33,10 +34,11 @@
 (defn del-button [props & body]
   (into [ctx/get-context props del-button*] body))

-(defn- collection* [{:keys [form-name path new-item-value] :as props} & body]
+(defn- collection* [{:keys [form-name path new-item-value class style] :as props} & body]
   (let [array (rf/subscribe [:re-form/input-value form-name path])]
     (fn [props & body]
-      [:div.collection
+      [:div.collection {:class (re-form/process-class class)
+                        :style style}
        (doall
         (for [[idx item] (map-indexed (fn [idx itm] [idx itm]) @array)]
           [:div.collection-item {:key idx}


Error can be anything

Error can be anything

--- src/com/wsscode/pathom/core.cljc
+++ src/com/wsscode/pathom/core.cljc
@@ -40,8 +40,7 @@
            :ret ::reader))

 (s/def ::error
-  (s/spec #?(:clj  #(instance? Throwable %)
-             :cljs #(instance? js/Error %))
+  (s/spec any?
     :gen #(s/gen #{(ex-info "Generated sample error" {:some "data"})})))

 (s/def ::errors (s/map-of vector? any?))


Add async and parallel parser sugars

Add async and parallel parser sugars

--- src/com/wsscode/pathom/sugar.clj
+++ src/com/wsscode/pathom/sugar.clj
@@ -20,6 +20,42 @@
                   p/error-handler-plugin
                   p/trace-plugin]}))

+(defn connect-async-parser
+  "Create a standard connect parser using the async parser.
+
+  Just like the serial parser, but supports waiting for core.async channels
+  in responses. The most common usage of this one is in ClojureScript land, where
+  most of the IO needs to be async."
+  [register]
+  (p/async-parser
+    {::p/env     {::p/reader               [p/map-reader
+                                            pc/async-reader2
+                                            pc/open-ident-reader
+                                            p/env-placeholder-reader]
+                  ::p/placeholder-prefixes #{">"}}
+     ::p/mutate  pc/mutate-async
+     ::p/plugins [(pc/connect-plugin {::pc/register register})
+                  p/error-handler-plugin
+                  p/trace-plugin]}))
+
+(defn connect-parallel-parser
+  "Create a standard connect parser using the parallel parser.
+
+  This is recommended if you have a lot of different information sources that
+  are IO bound. This parser can handle things in parallel, but adds extra overhead
+  to processing, use it in case your system has good parallelism opportunities."
+  [register]
+  (p/parallel-parser
+    {::p/env     {::p/reader               [p/map-reader
+                                            pc/parallel-reader
+                                            pc/open-ident-reader
+                                            p/env-placeholder-reader]
+                  ::p/placeholder-prefixes #{">"}}
+     ::p/mutate  pc/mutate-async
+     ::p/plugins [(pc/connect-plugin {::pc/register register})
+                  p/error-handler-plugin
+                  p/trace-plugin]}))
+
 (defn context-parser
   "Transforms the signature of a regular parser to one that takes
   some initial context to run the query. This returns a fn with


redesign secret create form

redesign secret create form

--- src/cljs/swarmpit/component/secret/create.cljs
+++ src/cljs/swarmpit/component/secret/create.cljs
@@ -29,7 +29,9 @@
      :key             "name"
      :variant         "outlined"
      :defaultValue    value
+     :margin          "normal"
      :required        true
+     :helperText      "Specify secret name"
      :InputLabelProps {:shrink true}
      :onChange        #(state/update-value [:secretName] (-> % .-target .-value) state/form-value-cursor)}))

@@ -43,6 +45,7 @@
      :required        true
      :multiline       true
      :disabled        true
+     :margin          "normal"
      :InputProps      {:style {:padding 0}}
      :InputLabelProps {:shrink true}
      :value           value}))
@@ -98,30 +101,27 @@
         [:div.Swarmpit-form
          [:div.Swarmpit-form-context
           (comp/container
-            {:style {:padding 0
-                     :margin  0}}
-            (common/form-title "Create secret" "Blob of data, such as a password or SSH private key")
-
-
-
-
-
-            (comp/grid
-              {:container true
-               :spacing   2}
-              (comp/grid
-                {:item true
-                 :xs   12}
-                (form-name secretName))
-              (comp/grid
-                {:item true
-                 :xs   12}
-                (form-data data)))
-            (html
-              [:div.Swarmpit-form-buttons
-               (composite/progress-button
-                 "Create"
-                 create-secret-handler
-                 processing?)]))
-
-          ]]))))
+            {:maxWidth "md"}
+            (comp/card
+              {:className "Swarmpit-form-card Swarmpit-fcard"}
+              (comp/box
+                {:className "Swarmpit-fcard-header"}
+                (comp/typography
+                  {:className "Swarmpit-fcard-header-title"
+                   :variant   "h6"
+                   :component "div"}
+                  "Create secret"))
+              (comp/card-content
+                {}
+                (comp/typography
+                  {:variant   "body2"
+                   :className "Swarmpit-fcard-message"}
+                  "Blob of data, such as a password or SSH private key")
+                (form-name secretName)
+                (form-data data)
+                (html
+                  [:div.Swarmpit-form-buttons
+                   (composite/progress-button
+                     "Create"
+                     create-secret-handler
+                     processing?)]))))]]))))


Remove union root example

Remove union root example

--- workspaces/src/com/wsscode/pathom/workspaces/connect/union_query.cljs
+++ workspaces/src/com/wsscode/pathom/workspaces/connect/union_query.cljs
@@ -62,14 +62,6 @@
                           :address/id [:address/id :address/street :address/number]}}]}
   (fn [_ _]
     {::items (->> entities-db vals (sort-by eid) vec)}))
-
-(defresolver `union-root
-  {::pc/input  #{:entity/id}
-   ::pc/output {:friend/id  [:friend/id :friend/name]
-                :place/id   [:place/id :place/title]
-                :address/id [:address/id :address/street :address/number]}}
-  (fn [_ {:entity/keys [id]}]
-    (get entities-db id)))

 (def places
   {2 {:place/id 2 :place/title "The Strip" :place/location "Las Vegas"}})


Add wrapper for text-center

Add wrapper for text-center

--- src/discuss/utils/bootstrap.cljs
+++ src/discuss/utils/bootstrap.cljs
@@ -23,6 +23,8 @@
   "Create dom element of a bootstrap default small button."
   [fn & strs] (button fn "btn-default btn-sm" strs))

+
+;;;; Wrapper
 (defn panel-wrapper
   "Wrap content into bootstrap's panel class."
   [& content]
@@ -34,4 +36,10 @@
   "Wrap content into bootstrap callout."
   [& content]
   (dom/div #js {:className "bs-callout bs-callout-info"}
+           content))
+
+(defn center
+  "Use text-center to align text."
+  [& content]
+  (dom/div #js {:className "text-center"}
            content))


Fixed failing forma->cdm test due to incorrect sample gadm-src


If the job is enabled, disabled, or started, reaload results and statuses

--- src/emender_jenkins/rest_api.clj
+++ src/emender_jenkins/rest_api.clj
@@ -110,6 +110,7 @@
             (-> (jenkins-api/start-job (config/get-jenkins-url request)
                                        (config/get-jenkins-auth request)
                                        job-name)
+                (reload-job-list request)
                 (send-response request))
             (-> (job-does-not-exist-response job-name "start")
                 (send-response request)))))
@@ -121,6 +122,7 @@
             (-> (jenkins-api/enable-job (config/get-jenkins-url request)
                                         (config/get-jenkins-auth request)
                                         job-name)
+                (reload-job-list request)
                 (send-response request))
             (-> (job-does-not-exist-response job-name "enable")
                 (send-response request)))))
@@ -132,6 +134,7 @@
             (-> (jenkins-api/disable-job (config/get-jenkins-url request)
                                          (config/get-jenkins-auth request)
                                          job-name)
+                (reload-job-list request)
                 (send-response request))
             (-> (job-does-not-exist-response job-name "enable")
                 (send-response request)))))