implement retry on error

implement retry on error

--- clj-tcp/src/clj_tcp/client.clj
+++ clj-tcp/src/clj_tcp/client.clj
@@ -1,22 +1,30 @@
 (ns clj-tcp.client
    (:require [clojure.tools.logging :refer [info error]]
              [clj-tcp.codec :refer [byte-decoder byte-encoder buffer->bytes]]
-             [clojure.core.async :refer [chan >!! go >! <! <!! thread]])
+             [clojure.core.async :refer [chan >!! go >! <! <!! thread timeout]])
    (:import
             [java.net InetSocketAddress]
-            [java.util.concurrent Future]
+            [java.util.concurrent.atomic AtomicInteger]
             [io.netty.util CharsetUtil]
             [io.netty.buffer Unpooled ByteBuf ByteBufUtil]
-            [io.netty.channel SimpleChannelInboundHandler ChannelHandler ChannelInboundHandlerAdapter ChannelInitializer ChannelInitializer ChannelHandlerContext ChannelFutureListener]
+            [io.netty.channel SimpleChannelInboundHandler ChannelPipeline ChannelFuture Channel ChannelHandler ChannelInboundHandlerAdapter ChannelInitializer ChannelInitializer ChannelHandlerContext ChannelFutureListener]
             [io.netty.channel.nio NioEventLoopGroup]
-            [io.netty.util.concurrent GenericFutureListener]
+            [io.netty.util.concurrent GenericFutureListener Future EventExecutorGroup]
             [io.netty.bootstrap Bootstrap]
             [io.netty.channel.socket.nio NioSocketChannel]))

-(defrecord Client [group channel-f write-ch read-ch error-ch])
+(defrecord Client [group channel-f write-ch read-ch error-ch ^AtomicInteger reconnect-count])
+
+
+(defrecord Reconnected [^Client client cause])
+(defrecord Pause [time])
+(defrecord Stop [])
+(defrecord Poison [])
+(defrecord FailedWrite [v])
+

 (defn close-client [{:keys [group channel-f]}]
-  (-> channel-f .channel .closeFuture .sync))
+  (-> ^ChannelFuture channel-f ^Channel .channel .closeFuture))

 (defn close-all [{:keys [group] :as conf}]
   (close-client conf)
@@ -27,7 +35,6 @@
   (proxy [SimpleChannelInboundHandler]
     []
     (channelActive [^ChannelHandlerContext ctx]
-      (info "active")
       ;(.writeAndFlush ctx (Unpooled/copiedBuffer "Netty Rocks1" CharsetUtil/UTF_8))
       )
     (channelRead0 [^ChannelHandlerContext ctx ^ByteBuf in]
@@ -36,6 +43,7 @@
       (>!! read-ch (buffer->bytes in))
       )
     (exceptionCaught [^ChannelHandlerContext ctx cause]
+      (error "Client-handler exception caught " cause)
       (error cause (>!! [cause ctx]) )
       (.close ctx))))

@@ -43,24 +51,30 @@
   (let [group (NioEventLoopGroup.)]
 	  (proxy [ChannelInitializer]
 	    []
-	    (initChannel [ch]
+	    (initChannel [^Channel ch]
         (try
 	        ;add the last default read handler that will send all read objects to the read-ch blocking if full
-          (-> ch (.pipeline) (.addLast group (into-array ChannelHandler [(client-handler conf)])))
+          (-> ch  ^ChannelPipeline (.pipeline) (.addLast ^EventExecutorGroup group (into-array ChannelHandler [(client-handler conf)])))
          ;add any extra handlers e.g. for encoding or deconding
           (if handlers
-            (-> ch (.pipeline) (.addLast group (into-array ChannelHandler (map #(%) handlers)))))
+            (-> ch  ^ChannelPipeline (.pipeline) (.addLast group (into-array ChannelHandler (map #(%) handlers)))))
          (catch Exception e (do
-                              (error e e)
-                              (go (>! error-ch [e nil])))))
+                              (error (str "channel initializer error " e) e)
+                              (go (>! error-ch [e nil]))
+                              )))
 	      ))))

 (defn exception-listener [v {:keys [error-ch]}]
+  "Returns a GenericFutureListener instance
+   that on completion checks the Future, if any exception
+   an error is sent to the error-ch"
   (reify GenericFutureListener
     (operationComplete [this f]
-       (if-let [o (.get ^Future f)]
-         (if (instance? Throwable o)
-           (go (>! error-ch [o v])))))))
+       (if (not (.isSuccess ^Future f))
+         (if-let [cause (.cause ^Future f)]
+               (do (error "operation complete cause " cause)
+                   (go (>! error-ch [cause (->FailedWrite v)])))
+           )))))

 (defn close-listener [^Client client {:keys [error-ch]}]
   "Close a client after a write operation has been completed"
@@ -70,8 +84,9 @@
                (try
                   (close-client client)
                   (catch Exception e (do
-                                       (error e e)
-                                       (>!! error-ch [e nil]))))))))
+                                       (error (str "Close listener error " e)  e)
+                                       (>!! error-ch [e nil])
+                                       )))))))

 (defn write! [{:keys [write-ch]} v]
@@ -89,50 +104,58 @@

 (defn- do-write [^Client client ^bytes v close-after-write {:keys [error-ch] :as conf}]
-  (info "client " client)
+  "Writes to the channel, this operation is non blocking and a exception listener is added to the write's ChannelFuture
+   to send any errors to the error-ch"
   (try
-     (let [ch-f (-> client :channel-f (.channel) (.writeAndFlush v) (.addListener (exception-listener v conf)))]
+    (do
+     (let [ch-f (-> client ^ChannelFuture (:channel-f) ^Channel (.channel) ^ChannelFuture (.writeAndFlush v) (.addListener ^ChannelFutureListener (exception-listener v conf)))]
        (if close-after-write
-         (.addListener ch-f (close-listener client conf))))
-
+         (.addListener ch-f ^ChannelFutureListener (close-listener client conf)))))
      (catch Exception e (do
-                          (error e e)
-                          (>!! error-ch [e v])))))
+                          (error (str "Error in do-write " e) e)
+                          (>!! error-ch [e v])
+                          ))))

 (defn start-client [host port {:keys [group read-ch error-ch write-ch handlers] :as conf
                                  :or {group (NioEventLoopGroup.) read-ch (chan 100) error-ch (chan 100) write-ch (chan 100)}}]
+  "Start a Client instance with read-ch, write-ch and error-ch"
   (try
   (let [g (if group group (NioEventLoopGroup.))
         b (Bootstrap.)]
     (-> b (.group g)
-      (.channel NioSocketChannel)
-      (.remoteAddress (InetSocketAddress. host port))
-      (.handler (client-channel-initializer conf)))
+      ^Bootstrap (.channel NioSocketChannel)
+      ^Bootstrap (.remoteAddress (InetSocketAddress. host port))
+      ^Bootstrap (.handler ^ChannelInitializer (client-channel-initializer conf)))
     (let [ch-f (.connect b)]
       (.sync ch-f)
-      (->Client g ch-f write-ch read-ch error-ch)))
+      (->Client g ch-f write-ch read-ch error-ch (AtomicInteger.))))
   (catch Exception e (do
-                       (error e e)
-                       (>!! error-ch [e nil])))))
+                       (error (str "Error starting client " e) e)
+                       (>!! error-ch [e nil])
+                       ))))

 (defn read-print-ch [n ch]
   (go
-    (while true
-      (let [c (<! ch)]
-         (info n " = " (String. c))))))
-
-(defn read-print-error [{:keys [error-ch]}]
-  (read-print-ch "error" error-ch))
+    (loop [ch1 ch]
+      (let [c (<! ch1)]
+         (if (instance? Reconnected c)
+           (do
+             ;(info "Reconnected " (:cause c) " ch1 " ch1 " new ch " (-> c :client :read-ch))
+             (recur (-> c :client :read-ch)))
+           (do
+             (info n " = " c)
+             (recur ch1)))))))

 (defn read-print-in [{:keys [read-ch]}]
   (read-print-ch "read" read-ch))

 (defn client [host port {:keys [handlers
+                                  retry-limit
                                   write-buff read-buff error-buff
                                   write-timeout read-timeout]
-                           :or {handlers [byte-encoder]
+                           :or {handlers [byte-encoder] retry-limit 10
                                 write-buff 100 read-buff 100 error-buff 1000 reuse-client false write-timeout 1500 read-timeout 1500} }]
   (let [ write-ch (chan write-buff)
          read-ch (chan read-buff)
@@ -140,16 +163,85 @@
          g (NioEventLoopGroup.)
          conf {:group g :write-ch write-ch :read-ch read-ch :error-ch error-ch :handlers handlers}
          client (start-client host port conf) ]
+
+    ;async read off error-ch
     (go
-      (try
-	      (while true
-	        (if-let [v (<! write-ch)]
-            (do
-	            (do-write client v false conf))))
-       (catch Exception e (do
-                            (error e e)
-                            (go (>! error-ch [e nil]))))))
-    client))
+      (loop [local-client client]
+        (let [[v o] (<! error-ch)]
+          (error "read error from error-ch " v)
+
+          (if (instance? Poison v)
+            (if local-client (close-client local-client)) ;poinson pill end loop
+          (do
+            ;on error, pause writing, and close client
+	          (>! write-ch (->Pause 1000))
+            (close-client local-client)
+
+           (let [c
+                 (loop [acc 0] ;reconnect in loop
+				            (if (>= acc retry-limit)
+				              (do
+                        ;if limit reached send poinson to all channels and call close all on client, end loop
+				                (error "Retry limit reached, closing all channels and connections")
+				                (go (>! write-ch (->Poison) ))
+				                (go (>! read-ch (->Poison) ))
+				                (go (>! error-ch (->Poison) ))
+				                (close-all local-client)
+			                  nil
+				              )
+					            (let [v1
+                             (try
+									              (let [c (start-client host port conf)
+									                    reconnected (->Reconnected c v)]
+				                          ;if connected, send Reconnected instance to all channels and return c, this c is assigned to the loop using recur
+											                (.getAndIncrement ^AtomicInteger (:reconnect-count c))
+											                (>! read-ch reconnected)
+											                (>! write-ch reconnected)
+									                    c)
+									              (catch Exception e (do
+									                                   (error (str "Error while doing retry " e) e)
+                                                     e ;return exception to v, due to a bug in core async http://dev.clojure.org/jira/browse/ASYNC-48, we cannot recur here
+				                                             )))]
+                            (if (instance? Exception v1) ;if v is an exception recur
+                              (recur (inc acc))
+                              v1) ;else return the value (this is c, the connection)
+                            )))]
+
+                      (if (instance? FailedWrite o)
+                        (do
+                            (info "retry failed write: ")
+                            (<! (timeout 500))
+                            (>! write-ch (:v o))))
+
+                      (recur c))
+
+	          )))))
+
+
+
+     ;async read off write-ch
+     (go
+	      (loop [local-client client]
+           (let [v (<! write-ch)]
+		          (if (instance? Stop v) nil ;if stop exit loop
+		             (do
+                   (try
+                      (cond (instance? Reconnected v) (do (recur (:client v))) ;if reconnect recur with the new client
+					             (instance? Pause v) (do (<! (timeout (:time v))) (recur local-client)) ;if pause, wait :time millis, then recur loop
+					             :else
+				                (do ;else write the value to the client channel
+                           (if (> (.get ^AtomicInteger (:reconnect-count local-client)) 0) (.set ^AtomicInteger (:reconnect-count local-client) 0))
+						               (do-write local-client v false conf)))
+							        (catch Exception e (do ;send any exception to the error-ch
+								                            (error "!!!!! Error while writing " e)
+								                            (go (>! error-ch [e nil]))
+                                    )))
+                      (if (not (instance? Stop v))
+                         (recur local-client)) ;if not stop recur loop
+                      )))))
+
+
+		    client))


adds integration test for fallback across mixed service mapping (#1489)

--- waiter/integration/waiter/token_request_test.clj
+++ waiter/integration/waiter/token_request_test.clj
@@ -2321,3 +2321,59 @@
               (delete-token-and-assert waiter-url token-2)))
           (finally
             (delete-token-and-assert waiter-url token-1)))))))
+
+(deftest ^:parallel ^:integration-slow ^:resource-heavy test-service-mapping-fallback-support
+  (testing-using-waiter-url
+    (let [{:keys [cookies]} (make-request waiter-url "/waiter-auth")
+          fallback-period-secs 30
+          current-user (retrieve-username)]
+      (doseq [[mapping-old mapping-new] [["legacy" "exclusive"] ["exclusive" "legacy"]]]
+        (testing (str "fallback from " mapping-new " to " mapping-old)
+          (let [service-name (rand-name)
+                token (create-token-name waiter-url ".")
+                basic-service-description (-> (kitchen-request-headers :prefix "")
+                                            (assoc :fallback-period-secs fallback-period-secs
+                                                   :name (str service-name "-v1")
+                                                   :permitted-user "*"
+                                                   :run-as-user current-user
+                                                   :service-mapping mapping-old
+                                                   :version "v1"))
+                request-headers {:x-waiter-token token}]
+            (try
+              (let [token-description-1 (assoc basic-service-description :token token)
+                    post-response (post-token waiter-url token-description-1)
+                    _ (assert-response-status post-response http-200-ok)
+                    response-1 (make-request-with-debug-info request-headers #(make-request waiter-url "/environment" :headers %))
+                    service-id-1 (:service-id response-1)
+                    env-token-old (when (= "exclusive" mapping-old) token)]
+                (assert-response-status response-1 http-200-ok)
+                (is (some? service-id-1))
+                (assert-service-mapping-response waiter-url service-id-1 (-> response-1 :body str) env-token-old)
+                (with-service-cleanup
+                  service-id-1
+                  (assert-service-healthy-on-all-routers waiter-url service-id-1 cookies)
+                  (let [service-description-2 (assoc basic-service-description
+                                                :cmd (kitchen-cmd (str "-p $PORT0 --start-up-sleep-ms 5000"))
+                                                :name (str service-name "-v2")
+                                                :service-mapping mapping-new
+                                                :version "v2")
+                        token-description-2 (assoc service-description-2 :token token)
+                        post-response (post-token waiter-url token-description-2)
+                        _ (assert-response-status post-response http-200-ok)
+                        response-2 (make-request-with-debug-info request-headers #(make-request waiter-url "/environment" :headers %))
+                        service-id-2 (:service-id response-2)]
+                    (assert-response-status response-2 http-200-ok)
+                    ;; fallback to service-id-1
+                    (is (= service-id-1 service-id-2))
+                    (assert-service-mapping-response waiter-url service-id-2 (-> response-2 :body str) env-token-old)
+                    (let [no-fallback-request-headers (assoc request-headers :x-waiter-fallback-period-secs 0)
+                          response-3 (make-request-with-debug-info no-fallback-request-headers #(make-request waiter-url "/environment" :headers %))
+                          service-id-3 (:service-id response-3)
+                          env-token-new (when (= "exclusive" mapping-new) token)]
+                      (with-service-cleanup
+                        service-id-3
+                        (assert-response-status response-3 http-200-ok)
+                        (is (not= service-id-1 service-id-3))
+                        (assert-service-mapping-response waiter-url service-id-3 (-> response-3 :body str) env-token-new))))))
+              (finally
+                (delete-token-and-assert waiter-url token)))))))))


use wrap-routes

use wrap-routes

--- resources/clj/new/closp/src/clj/components/handler.clj
+++ resources/clj/new/closp/src/clj/components/handler.clj
@@ -37,17 +37,17 @@
 ; use different middleware for rest api
 ;(defn wrap-api [route db dev?]
 ;  (let [handler (-> route
-;                    (wrap-json-response)
-;                    (add-locale dev?)
-;                    (wrap-custom-authorization db)
-;                    (wrap-json-body {:keywords? true :bigdecimals? true}))]
+;                    (wrap-routes wrap-json-response)
+;                    (wrap-routes add-locale dev?)
+;                    (wrap-routes wrap-custom-authorization db)
+;                    (wrap-routes wrap-json-body {:keywords? true :bigdecimals? true}))]
 ;    (if dev? (wrap-reload handler) handler)))

 (defn wrap-base [route dev?]
   (let [handler (-> route
-                    (add-locale dev?)
-                    (wrap-access-rules {:rules auth/rules})
-                    (wrap-authorization auth/auth-backend)
+                    (wrap-routes add-locale dev?)
+                    (wrap-routes wrap-access-rules {:rules auth/rules})
+                    (wrap-routes wrap-authorization auth/auth-backend)
                     (wrap-defaults site-defaults))]
     (if dev? (wrap-reload handler) handler)))


Optimise debouncing by checking if a debounce is already scheduled

This lets us avoid making 100s of calls to set and cancel the timeout
on every debounce call. The tradeoff is accuracy of debounce time,
but that is not important to us here.

--- src/re_frame/trace.cljc
+++ src/re_frame/trace.cljc
@@ -24,6 +24,7 @@

 (def trace-cbs (atom {}))
 (defonce traces (atom []))
+(defonce next-delivery (atom 0))

 (defn register-trace-cb
   "Registers a tracing callback function which will receive a collection of one or more traces.
@@ -47,11 +48,25 @@
    :child-of  (or child-of (:id *current-trace*))
    :start     (interop/now)})

+;; On debouncing
+;;
+;; We debounce delivering traces to registered cbs so that
+;; we can deliver them in batches. This aids us in efficiency
+;; but also importantly lets us avoid slowing down the host
+;; application by running any trace code in the critical path.
+;;
+;; We add a lightweight check on top of goog.functions/debounce
+;; to avoid constant setting and cancelling of timeouts. This
+;; means that we will deliver traces between 10-50 ms from the
+;; last trace being created, which still achieves our goals.
+
+(def debounce-time 50)
+
 (defn debounce [f interval]
   #?(:cljs (goog.functions/debounce f interval)
      :clj  (f)))

-(def run-tracing-callbacks!
+(def schedule-debounce
   (debounce
     (fn tracing-cb-debounced []
       (doseq [[k cb] @trace-cbs]
@@ -61,8 +76,21 @@
              #?(:cljs (catch :default e
                         (console :error "Error thrown from trace cb" k "while storing" @traces e)))))
       (reset! traces []))
-    50))
+    debounce-time))

+(defn run-tracing-callbacks! [now]
+  ;; Optimised debounce, we only re-debounce
+  ;; if we are close to delivery time
+  ;; to avoid constant setting and cancelling
+  ;; timeouts.
+
+  ;; If we are within 10 ms of next delivery
+  (when (< (- @next-delivery 10) now)
+    (schedule-debounce)
+    ;; The next-delivery time is not perfectly accurate
+    ;; as scheduling the debounce takes some time, but
+    ;; it's good enough for our purposes here.
+    (reset! next-delivery (+ now debounce-time))))

 (macros/deftime
   (defmacro finish-trace [trace]
@@ -72,7 +100,7 @@
           (swap! traces conj (assoc ~trace
                                :duration duration#
                                :end (interop/now)))
-          (run-tracing-callbacks!))))
+          (run-tracing-callbacks! end#))))

  (defmacro with-trace
      "Create a trace inside the scope of the with-trace macro


+todo

+todo

--- src/rex/ext/cursor.cljs
+++ src/rex/ext/cursor.cljs
@@ -10,6 +10,10 @@

   (zoom-in [this feature])

+  ;; TODO:
+  ;; get rid of update-state, get-state
+  ;; store must provide explicit interface for reducers
+  ;; for example with get-value(key), set-value(key,value) semantics
   (update-state [this state new-local-state])

   (get-state [this state]))


hipchat: provide a default from field and do not leak server params. fixes #643

--- src/riemann/hipchat.clj
+++ src/riemann/hipchat.clj
@@ -32,8 +32,8 @@

 (defn- format-event [{:keys [message] :as conf} event]
   "Creates an event suitable for posting to hipchat."
-  (merge {:color (message-colour event)}
-         conf
+  (merge {:color (message-colour event) :from "riemann"}
+         (-> conf (dissoc :server) (dissoc :room_id))
          (when-not message
            {:message (format-message (flatten [event]))})))


Fix npc rendering

Fix npc rendering

--- src/robinson/render.clj
+++ src/robinson/render.clj
@@ -815,15 +815,15 @@
           pos (-> state :world :player :pos)
           get-cell (memoize (fn [x y] (get-cell state x y)))]
       (doall (map (fn [npc]
-                    (let [x       (- (-> npc :pos :x)
-                                     (-> state :world :viewport :pos :x))
-                          y       (- (-> npc :pos :y)
-                                     (-> state :world :viewport :pos :x))
+                    (let [x       (-> npc :pos :x)
+                          y       (-> npc :pos :y)
+                          vx      (- x (-> state :world :viewport :pos :x))
+                          vy      (- y (-> state :world :viewport :pos :y))
                           visible
                                   (and (not (farther-than?
                                               pos
                                               {:x x :y y}
-                                              3))
+                                              5))
                                        (visible? get-cell
                                                  cell-blocking?
                                                  (pos :x)
@@ -833,8 +833,8 @@
                       ;(debug "npc@" x y "visible?" visible)
                       (when visible
                         (apply put-string screen
-                                            (-> npc :pos :x)
-                                            (-> npc :pos :y)
+                                            vx
+                                            vy
                                             (case (get npc :race)
                                               :rat       ["r"]
                                               :spider    ["S"]


Tiny changes, tests still pass.  Remarkably.

--- src/zprint/zprint.cljc
+++ src/zprint/zprint.cljc
@@ -3792,7 +3792,7 @@
   explicit newline.  If not-first? is truthy, then don't put a
   newline before the first element."
   [ind coll not-first? respect-nl?]
-  #_(prn "precede-w-nl: (count coll)" (count coll) "not-first?" not-first?)
+  #_(prn "precede-w-nl: (count coll)" (count coll) "not-first?" not-first? "respect-nl?" respect-nl?)
   (loop [coll coll
          ind-seq (if (coll? ind) ind (vector ind))
          out (transient [])
@@ -3826,7 +3826,7 @@
             comment? (if respect-nl? nil
 	    (or (= last-what :comment) (= last-what :comment-inline)))] ; i132
         #_(prn "precede-w-nl: element:" element
-               "comment?:" comment?)
+               "comment?:" comment? "added-nl?:" added-nl?)
         (recur (next coll)
                ; Move along ind-seq until we reach the last one, then just
                ; keep using the last one.
@@ -3971,7 +3971,7 @@
                         nil #_(or (= (nth (last style-vec) 2) :comment)
                             (= (nth (last style-vec) 2) :comment-inline)))
 			    ; i132
-                  (do #_(println "******************") 1)
+                  (do (println "******************") 1)
                   0)
                 #_0 ;newline-count
                 )))))))
@@ -4052,7 +4052,7 @@
           r-str-vec (rstr-vec options (+ indent ind) zloc r-str)]
       (if (empty? pair-seq)
         (concat-no-nil l-str-vec r-str-vec)
-        (let [_ (dbg options
+        (let [_ (dbg-pr options
                      "fzprint-map*:" (zstring zloc)
                      "ind:" ind
                      "comma?" comma?


Fixed setTrustStore method name

Fixed setTrustStore method name

--- ring-jetty-adapter/src/ring/adapter/jetty.clj
+++ ring-jetty-adapter/src/ring/adapter/jetty.clj
@@ -27,7 +27,7 @@
     (.setKeyStorePath context (options :keystore))
     (.setKeyStorePassword context (options :key-password))
     (when (options :truststore)
-      (.setTruststore context (options :truststore)))
+      (.setTrustStore context (options :truststore)))
     (when (options :trust-password)
       (.setTrustPassword context (options :trust-password)))
     (case (options :client-auth)


Add the content-type of an attached file when inlining mail

--- systems/mail/src/containium/systems/mail.clj
+++ systems/mail/src/containium/systems/mail.clj
@@ -10,8 +10,10 @@
             [postal.core :as postal]
             [clojure.xml :as xml]
             [clojure.zip :as zip]
-            [clojure.java.io :as io :refer (resource)])
-  (:import [java.io ByteArrayInputStream]))
+            [clojure.java.io :as io :refer (resource as-file)])
+  (:import [java.io ByteArrayInputStream FileInputStream BufferedInputStream File]
+           [java.nio.file Files]
+           [java.net URLConnection]))
 (refer-logging)

@@ -55,6 +57,12 @@
         (Postal. logger config)))))

+(defn- file-content-type
+  [^File file]
+  (with-open [stream (-> file FileInputStream. BufferedInputStream.)]
+    (URLConnection/guessContentTypeFromStream stream)))
+
+
 (defn- make-inline
   [html-str src-root src-map]
   (let [src-root (str src-root (when-not (= (last src-root) \/) "/"))]
@@ -68,10 +76,12 @@
           (if (= :img (:tag node))
             (let [cid (str (gensym "img-"))
                   src (-> node :attrs :src)
-                  content (or (get src-map src) (resource (str src-root src)))]
+                  content (as-file (or (get src-map src) (resource (str src-root src))))
+                  content-type (file-content-type content)]
               (recur (zip/next (zip/edit loc assoc-in [:attrs :src] (str "cid:" cid)))
                      (cond-> contents
-                             content (conj {:type :inline, :content content, :content-id cid}))))
+                             content (conj {:type :inline, :content content, :content-id cid
+                                            :content-type content-type}))))
             (recur (zip/next loc) contents)))))))


Add logging to starting and stopping test HTTP-Kit.

--- systems/ring/src/containium/systems/ring.clj
+++ systems/ring/src/containium/systems/ring.clj
@@ -153,7 +153,10 @@
     (Exception. "Cannot be used on a test HTTP-Kit implementation."))

   Stoppable
-  (stop [_] (stop-fn)))
+  (stop [_]
+    (println "Stopping test HTTP-Kit server...")
+    (stop-fn)
+    (println "Stopped test HTTP-Kit server.")))

 (defn test-http-kit
@@ -163,6 +166,8 @@
   [handler]
   (reify Startable
     (start [_ systems]
-      (let [config (require-system Config systems)
+      (let [config (get-config (require-system Config systems) :http-kit)
+            _ (println "Starting test HTTP-Kit, using config" config "...")
             stop-fn (run-server handler (get-config config :http-kit))]
+        (println "Started test HTTP-Kit.")
         (TestHttpKit. stop-fn)))))


Use (comment ...) for commenting out new UTF-8 filename test

--- ring-core/test/ring/util/test/response.clj
+++ ring-core/test/ring/util/test/response.clj
@@ -110,19 +110,18 @@
       (is (= (slurp (:body resp))
              "Hello World\n"))))

-  ;; This test requires the ability to have file names in the source
-  ;; tree with non-ASCII characters in them encoded as UTF-8.  That
-  ;; may be platform-specific.  Comment out for now.
-
-  ;; If this fails on Mac OS X, try again with the command line:
-  ;; LC_CTYPE="UTF-8" lein test
-;;  (testing "resource is a file with UTF-8 characters in path"
-;;    (let [resp (resource-response "/ring/assets/abcíe.txt")]
-;;      (is (= (:body resp)
-;;             (.getAbsoluteFile (File. "test/ring/assets/abcíe.txt"))))
-;;      (is (.contains (slurp (:body resp))
-;;                     "UTF-8"))))
-  )
+  (comment
+    ;; This test requires the ability to have file names in the source
+    ;; tree with non-ASCII characters in them encoded as UTF-8.  That
+    ;; may be platform-specific.  Comment out for now.
+
+    ;; If this fails on Mac OS X, try again with the command line:
+    ;; LC_CTYPE="UTF-8" lein test
+    (testing "resource is a file with UTF-8 characters in path"
+      (let [resp (resource-response "/ring/assets/abcíe.txt")]
+        (is (= (:body resp)
+               (.getAbsoluteFile (File. "test/ring/assets/abcíe.txt"))))
+        (is (.contains (slurp (:body resp)) "UTF-8"))))))

 (deftest test-file-response
   (testing "response map"


Removing test that that isn't worthwhile.

--- test/cmr/indexer/test/data/elasticsearch.clj
+++ test/cmr/indexer/test/data/elasticsearch.clj
@@ -1,109 +0,0 @@
-(ns cmr.indexer.test.data.elasticsearch
-  "Tests for elasticsearch in data layer"
-  (:require [clojure.test :refer :all]
-            [clj-time.core :as t]
-            [cmr.indexer.data.elasticsearch :as es]
-            [cmr.indexer.data.concepts.collection]))
-
-(deftest concept->elastic-doc-test
-  (let [short-name "MINIMAL"
-        long-name "LONG-NAME"
-        version-id "1"
-        dataset-id "A minimal valid collection V 1"
-        provider-id "PROV1"
-        concept-id "C1234-PROV1"
-        processing-level-id "1B"
-        collection-data-type "NEAR_REAL_TIME"
-        concept {:concept-id concept-id
-                 :provider-id provider-id
-                 :format "application/echo10+xml"}
-        platforms [{:short-name "PLATFORM ONE"
-                    :long-name "dummy"
-                    :type "Dummy"
-                    :instruments [{:short-name "SAR"
-                                   :sensors [{:short-name "DAR"}
-                                             {:short-name "TAR"}]}
-                                  {:short-name "MAR"}]}
-                   {:short-name "PLATFORM TWO"
-                    :long-name "dummy"
-                    :type "Dummy"
-                    :instruments [{:short-name "DAR"
-                                   :sensors [{:short-name "WAR"}]}]}]
-        projects [{:short-name "ESI"
-                   :long-name "dummy"}
-                  {:short-name "EVI"
-                   :long-name "dummy"}
-                  {:short-name "EPI"
-                   :long-name "dummy"}]
-        orgs [{:type :processing-center :org-name "SEDAC PC"}
-              {:type :archive-center :org-name "SEDAC AC"}]
-        umm-concept {:entry-id "MINIMAL_1"
-                     :entry-title dataset-id
-                     :summary "Summary of collection"
-                     :product {:short-name short-name
-                               :long-name long-name
-                               :version-id version-id
-                               :processing-level-id processing-level-id
-                               :collection-data-type collection-data-type}
-                     :revision-date  nil
-                     :temporal {:range-date-times [{:beginning-date-time (t/date-time 1996 2 24 22 20 41)
-                                                    :ending-date-time (t/date-time 1997 3 25 23 23 43 123)}]}
-                     :platforms platforms
-                     :projects projects
-                     :two-d-coordinate-systems [{:name "FOO"}
-                                                {:name "Bar"}]
-                     :spatial-keywords ["New York" "Washington DC"]
-                     :organizations orgs
-                     :data-provider-timestamps {:update-time (t/date-time 2014 2 24 22 20 56)}
-                     :spatial-coverage {:spatial-representation :cartesian}
-                     :associated-difs ["DIF-100" "DIF-101"]}
-        expected {:concept-id concept-id
-                  :entry-id "MINIMAL_1"
-                  :entry-id.lowercase "minimal_1"
-                  :entry-title dataset-id
-                  :entry-title.lowercase "a minimal valid collection v 1"
-                  :provider-id provider-id
-                  :provider-id.lowercase "prov1"
-                  :short-name short-name
-                  :short-name.lowercase "minimal"
-                  :version-id version-id
-                  :version-id.lowercase "1"
-                  :revision-date  nil
-                  :processing-level-id "1B"
-                  :processing-level-id.lowercase "1b"
-                  :collection-data-type "NEAR_REAL_TIME"
-                  :collection-data-type.lowercase "near_real_time"
-                  :start-date "1996-02-24T22:20:41.000Z"
-                  :end-date "1997-03-25T23:23:43.123Z"
-                  :platform-sn ["PLATFORM ONE" "PLATFORM TWO"]
-                  :platform-sn.lowercase ["platform one" "platform two"]
-                  :instrument-sn ["SAR" "MAR" "DAR"]
-                  :instrument-sn.lowercase ["sar" "mar" "dar"]
-                  :sensor-sn ["DAR" "TAR" "WAR"]
-                  :sensor-sn.lowercase ["dar" "tar" "war"]
-                  :project-sn ["ESI" "EVI" "EPI"]
-                  :project-sn.lowercase ["esi" "evi" "epi"]
-                  :archive-center ["SEDAC AC"]
-                  :archive-center.lowercase ["sedac ac"]
-                  :spatial-keyword ["New York" "Washington DC"]
-                  :spatial-keyword.lowercase ["new york" "washington dc"]
-                  :attributes []
-                  :science-keywords []
-                  :two-d-coord-name ["FOO" "Bar"]
-                  :two-d-coord-name.lowercase  ["foo" "bar"]
-                  :downloadable false
-                  :browsable false
-                  :atom-links []
-                  :summary "Summary of collection"
-                  :original-format "ECHO10"
-                  :coordinate-system "CARTESIAN"
-                  :update-time "2014-02-24T22:20:56.000Z"
-                  :associated-difs ["DIF-100" "DIF-101"]
-                  :associated-difs.lowercase ["dif-100" "dif-101"]
-                  :keyword  "dc foo bar new york of dummy a minimal valid collection v 1 ac two summary of collection long collection 1b new minimal v sedac ac summary name york washington dc real valid platform two a time platform one one 1 sedac near_real_time washington platform long-name near"
-                  :project-ln.lowercase ["dummy" "dummy" "dummy"]
-                  :platform-ln.lowercase ["dummy" "dummy"]
-                  :long-name.lowercase "long-name"}
-        actual (es/concept->elastic-doc nil concept umm-concept)]
-    (is (= expected actual))))
-


remove debug

remove debug

--- pathdb/src/systems/casemgr/utils/pathdb/core.cljs
+++ pathdb/src/systems/casemgr/utils/pathdb/core.cljs
@@ -13,7 +13,7 @@

 (enable-console-print!)

-(println "<-----------------Start of core")
+;(println "<-----------------Start of core")

 ;; define your app data so that it doesn't get over-written on reload


fixed subscriptions leak

fixed subscriptions leak

Signed-off-by: andrey <b713972e59b8e606e23253c4a13e948139fea4d1@gmail.com>

--- src/status_im/subs.cljs
+++ src/status_im/subs.cljs
@@ -456,7 +456,7 @@
  :disconnected?
  :<- [:peers-count]
  :<- [:waku/v2-flag]
- (fn [peers-count wakuv2-flag]
+ (fn [[peers-count wakuv2-flag]]
    ;; TODO Right now wakuv2 module in status-go
    ;; does not report peer counts properly,
    ;; so we always assume that we're connected


Revert "hide /projects page behind LD flag"

This reverts commit aca4cd56bce59b410619529a3c0e82fe3880af72.

--- src-cljs/frontend/controllers/navigation.cljs
+++ src-cljs/frontend/controllers/navigation.cljs
@@ -286,10 +286,7 @@

 (defmethod post-navigated-to! :projects
   [history-imp navigation-point _ previous-state current-state]
-  (set-page-title! "Projects")
-  (when-not (feature/enabled? :projects-page)
-    (let [nav-ch (get-in current-state [:comms :nav])]
-      (routes/open-to-outer! nav-ch :error {:status 401}))))
+  (set-page-title! "Projects"))

 (defmethod navigated-to :build-insights
   [history-imp navigation-point args state]


First pass at multiplexing mapper.

First pass at multiplexing mapper.

--- src/clojure/parkour/mapreduce/input/multiplex.clj
+++ src/clojure/parkour/mapreduce/input/multiplex.clj
@@ -7,7 +7,8 @@
            [org.apache.hadoop.conf Configuration]
            [org.apache.hadoop.io Text]
            [org.apache.hadoop.io.serializer SerializationFactory]
-           [org.apache.hadoop.mapreduce Job InputFormat InputSplit]
+           [org.apache.hadoop.mapreduce InputFormat InputSplit Job]
+           [org.apache.hadoop.mapreduce Mapper Mapper$Context]
            [parkour.hadoop.interfaces IInputFormat IInputSplit]
            [parkour.hadoop.input
               MultiplexInputFormat MultiplexInputSplit MultiplexRecordReader]))
@@ -89,3 +90,18 @@
             context (mr/tac job (.getTaskAttemptID context))]
         (MultiplexRecordReader.
          (.createRecordReader ^InputFormat inform split context))))))
+
+(defn mapper
+  [conf]
+  (fn [^Mapper$Context context]
+    (let [i (-> context .getInputSplit deref first)
+          subconf (-> context get-subconfs (get i))
+          rdiff (-> (doto (conf/clone context)
+                      (conf/merge! subconf))
+                    (conf/diff context))]
+      (try
+        (conf/merge! context subconf)
+        (let [mapper (->> context .getMapperClass (w/new-instance context))]
+          (.run ^Mapper mapper context))
+        (finally
+          (conf/merge! context rdiff))))))


Remove unneeded transaction

Remove unneeded transaction

--- src/com/puppetlabs/puppetdb/http/v2/resources.clj
+++ src/com/puppetlabs/puppetdb/http/v2/resources.clj
@@ -15,10 +15,9 @@
   If the query can't be parsed, a 400 is returned."
   [query query->sql db]
   (try
-    (let [[sql & params] (with-transacted-connection db
-                           (-> query
-                               (json/parse-string true)
-                               (query->sql)))]
+    (let [[sql & params] (-> query
+                             (json/parse-string true)
+                             (query->sql))]

       (-> (pl-http/streamed-response buffer
             (with-transacted-connection db


keep headlines about cljs

keep headlines about cljs

--- src/pc/views/blog/clojure_is_a_product_design_tool.clj
+++ src/pc/views/blog/clojure_is_a_product_design_tool.clj
@@ -163,7 +163,7 @@
          This lets me go from ideating to shipping in under 30 minutes."]]

     [:article
-     [:h3 "Every product designer should know about Clojure."]
+     [:h3 "Every product designer should know about ClojureScript."]
      [:p "I challenged myself to work outside my expertise, because I knew designing the same way everyday would dilute my passion."]
      [:p "My optimizations are individually subtle but they save me hours every week.
          I spend that time on more important things, like polish.


Fix wrong parsing time data on transit.

Fix wrong parsing time data on transit.

Regression introduced in previous commits.

--- src/uxbox/util/time.clj
+++ src/uxbox/util/time.clj
@@ -19,12 +19,12 @@
 (def ^:private write-handler
   (t/write-handler
    (constantly "m")
-   (fn [v] (.toEpochMilli v))
    (fn [v] (str (.toEpochMilli v)))))

 (def ^:private read-handler
   (t/read-handler
-   (fn [v] (Instant/ofEpochMilli v))))
+   (fn [v] (-> (Long/parseLong v)
+               (Instant/ofEpochMilli)))))

 (def +read-handlers+
   {"m" read-handler})


Makes pod-watch exception log INFO level (#1384)

* Makes pod-watch exception log INFO level

* Checks cause of exception to determine log level

--- scheduler/src/cook/kubernetes/api.clj
+++ scheduler/src/cook/kubernetes/api.clj
@@ -133,7 +133,10 @@
           (handle-watch-updates all-pods-atom watch get-pod-namespaced-key
                                 callbacks)
           (catch Exception e
-            (log/error e "Error during pod watch for compute cluster" compute-cluster-name))
+            (let [cause (.getCause e)]
+              (if (and cause (instance? java.net.SocketTimeoutException cause))
+                (log/info e "In" compute-cluster-name "compute cluster, pod watch timed out")
+                (log/error e "In" compute-cluster-name "compute cluster, error during pod watch"))))
           (finally
             (.close watch)
             (initialize-pod-watch api-client compute-cluster-name all-pods-atom cook-pod-callback)))))))


Use consistent naming for adding event listeners

Update one.repmax.exercises.view to use the same naming idiom employed
by the other views for adding event listeners.

--- src/app/cljs/one/repmax/exercises/view.cljs
+++ src/app/cljs/one/repmax/exercises/view.cljs
@@ -35,7 +35,7 @@
         content (d/by-id "content")]
     (d/swap-content! header (:exercises-header snippets))
     (d/swap-content! content (:exercises-content snippets))
-    (add-exercise-search-event-listener)
+    (add-event-listener-for-exercise-search)
     (render-exercise-list exercises)))

 (defn- render-exercise-list [exercises]
@@ -52,15 +52,15 @@
     (-> li (css/sel "span.list-item-label")
       (d/set-text! (:name exercise)))
     (-> li (d/single-node)
-      (add-exercise-click-event-listener exercise-id))
+      (add-event-listener-for-exercise-click exercise-id))
     li))

-(defn- add-exercise-click-event-listener [node exercise-id]
+(defn- add-event-listener-for-exercise-click [node exercise-id]
   (event/listen node
                 event-type/CLICK
                 #(dispatch/fire :action {:action :new-set/new, :exercise-id exercise-id})))

-(defn- add-exercise-search-event-listener []
+(defn- add-event-listener-for-exercise-search []
   (let [field (d/by-id "search-input")]
     (event/listen field
                   event-type/KEYUP


Testing hasPackageLevelAccess

Testing hasPackageLevelAccess

--- test/app/test/core.clj
+++ test/app/test/core.clj
@@ -72,6 +72,14 @@
   (let [t (parseType "ASimplePublicFinalClass")]
     (is (= 17 (getModifiers t)))))

+(deftest hasPackageLevelAccess?_Positive
+  (let [t (parseType "ASimpleClass")]
+    (is (hasPackageLevelAccess? t))))
+
+(deftest hasPackageLevelAccess?_Negative
+  (let [t (parseType "ASimplePublicFinalClass")]
+    (is (not (hasPackageLevelAccess? t)))))
+
 ; ============================================
 ; Other FIXME organize!
 ; ============================================


メソッドごとに分割。

メソッドごとに分割。

--- src/webexample/core.clj
+++ src/webexample/core.clj
@@ -5,7 +5,7 @@
             [immutant.web]
             [immutant.transactions]
             [immutant.transactions.jdbc]
-            [compojure.core :refer [defroutes routes ANY]]
+            [compojure.core :refer [defroutes routes ANY GET POST PUT DELETE]]
             [compojure.route]
             [liberator.core :refer [resource]]
             [yesql.core :refer [defqueries]])
@@ -24,30 +24,43 @@
 (defqueries "data/task.sql")

 (defroutes task-service
-  (ANY "/task" {:keys [request-method db body]}
-       (let [data (when (= request-method :post) (as-json body :key-fn keyword))
-             new-id (when (= request-method :post)
-                      (let [r (next-task-id db)]
-                        (or (:newid (first r)) 0)))]
-         (resource
-           :allowed-methods [:get :post]
-           :malformed? (and (= request-method :post) (nil? data))
-           :available-media-types ["application/json"]
-           :handle-ok (list-tasks db)
-           :handle-malformed (pr-str data)
-           :post! (fn [ctx] (new-task! db new-id (:title data)))
-           :handle-created {:id new-id})))
+  (GET "/task" {:keys [db]}
+    (resource
+      :allowed-methods [:get]
+      :available-media-types ["application/json"]
+      :handle-ok (list-tasks db)))

-  (ANY "/task/:id" [id :as {:keys [request-method db body]}]
-       (let [data (when (= request-method :put) (as-json body :key-fn keyword))]
-         (resource
-           :allowed-methods [:get :put :delete]
-           :available-media-types ["application/json"]
-           :malformed? (and (= request-method :put) (nil? data))
-           :handle-ok (fn [_] (first (get-task db)))
-           :put!  (fn [_] (update-task! db (:title data) id))
-           :new? false
-           :delete! (fn [_] (delete-task! db id))))))
+  (POST "/task" {:keys [db body]}
+    (let [data (as-json body :key-fn keyword)
+          new-id (or (:newid (first (next-task-id db))) 0)]
+      (resource
+        :allowed-methods [:post]
+        :available-media-types ["application/json"]
+        :malformed? (nil? (:title data))
+        :handle-malformed (pr-str data)
+        :post! (fn [_] (new-task! db new-id (:title data)))
+        :handle-created {:id new-id})))
+
+  (GET "/task/:id" [id :as {:keys [db]}]
+    (resource
+      :allowed-methods [:get]
+      :available-media-types ["application/json"]
+      :handle-ok (fn [_] (first (get-task db)))))
+
+  (PUT "/task/:id" [id :as {:keys [db body]}]
+    (let [data (as-json body :key-fn keyword)]
+      (resource
+        :allowed-methods [:put]
+        :available-media-types ["application/json"]
+        :malformed? (nil? (:title data))
+        :put! (fn [_] (update-task! db (:title data) id))
+        :new? false)))
+
+  (DELETE "/task/:id" [id :as {:keys [db]}]
+    (resource
+      :allowed-methods [:delete]
+      :available-media-types ["application/json"]
+      :delete! (fn [_] (delete-task! db id)))))

 ;;; configuration


Avoid ever printing "/" for media-type

Avoid ever printing "/" for media-type

--- src/yada/media_type.clj
+++ src/yada/media_type.clj
@@ -10,7 +10,7 @@

 (defrecord MediaTypeMap [type subtype parameters quality])

-(defn media-type [mt] (when mt (str (:type mt) "/" (:subtype mt))))
+(defn media-type [mt] (when (:type mt) (str (:type mt) "/" (:subtype mt))))

 (def media-type-pattern
   (re-pattern (str "(" http-token ")"


Add metric for time spent storing reports

--- src/com/puppetlabs/puppetdb/scf/storage.clj
+++ src/com/puppetlabs/puppetdb/scf/storage.clj
@@ -190,6 +190,8 @@
                                (float (utils/quotient dupes (+ dupes new)))))

    :replace-facts     (timer [ns-str "default" "replace-facts-time"])
+
+   :store-report      (timer [ns-str "default" "store-report-time"])
    })

 (defn db-serialize
@@ -647,15 +649,15 @@
         ;; in the validation functions).
         resource-event-rows (map #(report/resource-event-to-sql % report-id)
                                   (:resource-events report))]
-    ;; TODO: metrics?
-    (sql/transaction
-      (sql/insert-record :reports
-        { :id (:id report)
-          :puppet_version (:puppet-version report)
-          :certname (:certname report)
-          :report_format (:report-format report)
-          :configuration_version (:configuration-version report)
-          :start_time (to-timestamp (:start-time report))
-          :end_time (to-timestamp (:end-time report))
-          :receive_time (to-timestamp timestamp)})
-      (apply sql/insert-records :resource_events resource-event-rows))))
+    (time! (:store-report metrics)
+      (sql/transaction
+        (sql/insert-record :reports
+          { :id (:id report)
+            :puppet_version (:puppet-version report)
+            :certname (:certname report)
+            :report_format (:report-format report)
+            :configuration_version (:configuration-version report)
+            :start_time (to-timestamp (:start-time report))
+            :end_time (to-timestamp (:end-time report))
+            :receive_time (to-timestamp timestamp)})
+        (apply sql/insert-records :resource_events resource-event-rows)))))


clojure naming

clojure naming

--- src/frontend/cljs/alibi/entry_page_state.cljs
+++ src/frontend/cljs/alibi/entry_page_state.cljs
@@ -30,11 +30,11 @@
 (def form-selected-task #(get-in % [:selected-task]))
 (def form-selected-task-id #(get-in % [:selected-task :task-id]))
 (def form-selected-project-id #(get-in % [:selected-task :project-id]))
-(def form-start-time #(get-in % [:post-entry-form :startTime]))
-(def form-end-time #(get-in % [:post-entry-form :endTime]))
+(def form-start-time #(get-in % [:post-entry-form :start-time]))
+(def form-end-time #(get-in % [:post-entry-form :end-time]))
 (def form-entry-id #(get-in % [:post-entry-form :entry-id]))
 (def form-comment #(get-in % [:post-entry-form :comment]))
-(def form-billable? #(get-in % [:post-entry-form :isBillable]))
+(def form-billable? #(get-in % [:post-entry-form :billable?]))
 (def form-submitted? #(get-in % [:submitted?]))
 (def form-form-at-submit-time #(get-in % [:form-at-submit-time]))

@@ -43,10 +43,10 @@
     {:selected-task {:task-id (:task-id entry)
                      :project-id (:project-id entry)}
      :selected-date {:date (unix->date-str (:from entry))}
-     :post-entry-form {:isBillable (:billable? entry)
+     :post-entry-form {:billable? (:billable? entry)
                        :comment (:comment entry)
-                       :startTime (unix->time-str (:from entry))
-                       :endTime (unix->time-str (:till entry))
+                       :start-time (unix->time-str (:from entry))
+                       :end-time (unix->time-str (:till entry))
                        :entry-id (:entry-id entry)}}))

 (defn form->data-entry [form]
@@ -84,8 +84,8 @@

 (defn form-get-editing-entry [form]
   (let [form (-> form
-                 (update-in [:post-entry-form :startTime] expand-time)
-                 (update-in [:post-entry-form :endTime] expand-time))]
+                 (update-in [:post-entry-form :start-time] expand-time)
+                 (update-in [:post-entry-form :end-time] expand-time))]
     (when-not (seq (form-validate-form form))
       (form->data-entry form))))

@@ -153,9 +153,9 @@
                           :submitted? false
                           :form-at-submit-time nil
                           :selected-task {}
-                          :post-entry-form {:startTime ""
-                                            :endTime ""
-                                            :isBillable false
+                          :post-entry-form {:start-time ""
+                                            :end-time ""
+                                            :billable? false
                                             :comment ""
                                             :entry-id "new"})

@@ -166,13 +166,13 @@
     :change-comment (assoc-in prev-state [:form :post-entry-form :comment]
                               (:comment payload))

-    :change-start-time (assoc-in prev-state [:form :post-entry-form :startTime]
+    :change-start-time (assoc-in prev-state [:form :post-entry-form :start-time]
                                  (:start-time payload))

-    :change-end-time (assoc-in prev-state [:form :post-entry-form :endTime]
+    :change-end-time (assoc-in prev-state [:form :post-entry-form :end-time]
                                (:end-time payload))

-    :change-billable? (assoc-in prev-state [:form :post-entry-form :isBillable]
+    :change-billable? (assoc-in prev-state [:form :post-entry-form :billable?]
                                 (:billable? payload))

     prev-state))


The vis data structure has actxs and want-chs.

--- src/cbfg/core.cljs
+++ src/cbfg/core.cljs
@@ -44,11 +44,13 @@
   {"ago"
    {:beg (fn [vis actx args]
            (let [[child-actx] args]
-             (swap! vis #(assoc-in % [:actxs child-actx]
-                                   {:parent actx :want-chs {}}))))
+             (swap! vis #(assoc-in % (concat [:actxs] (rest child-actx))
+                                   {:children {} :want-chs {}}))
+             (swap! vis #(assoc-in % [:want-chs child-actx] {}))))
     :end (fn [vis actx args]
            (let [[child-actx result] args]
-             (swap! vis #(dissoc-in % [:actxs child-actx]))))}
+             (swap! vis #(dissoc-in % (concat [:actxs] (rest child-actx))))
+             (swap! vis #(dissoc-in % [:want-chs child-actx]))))}
    "aclose"
    {:beg (fn [vis actx args]
            (let [[ch] args] 1))
@@ -57,17 +59,17 @@
    "atake"
    {:beg (fn [vis actx args]
            (let [[ch] args]
-             (swap! vis #(assoc-in % [:actxs actx :want-chs ch] :take))))
+             (swap! vis #(assoc-in % [:want-chs actx ch] :take))))
     :end (fn [vis actx args]
            (let [[ch result] args]
-             (swap! vis #(dissoc-in % [:actxs actx :want-chs ch]))))}
+             (swap! vis #(dissoc-in % [:want-chs actx ch]))))}
    "aput"
    {:beg (fn [vis actx args]
            (let [[ch msg] args]
-             (swap! vis #(assoc-in % [:actxs actx :want-chs ch] :put))))
+             (swap! vis #(assoc-in % [:want-chs actx ch] :put))))
     :end (fn [vis actx args]
            (let [[ch msg result] args]
-             (swap! vis #(dissoc-in % [:actxs actx :want-chs ch]))))}
+             (swap! vis #(dissoc-in % [:want-chs actx ch]))))}
    "aalts"
    {:beg (fn [vis actx args]
            (let [[chs] args] 1))
@@ -75,7 +77,7 @@
            (let [[chs result] args] 2))}})

 (defn vis-init [cmds cmd-handlers]
-  (let [vis (atom {:actxs {} :chs {}})
+  (let [vis (atom {:actxs {} :want-chs {}})
         max-inflight (atom 10)
         event-delay (atom 0)
         event-ch (chan)
@@ -89,8 +91,8 @@
       (let [[actx event] (<! event-ch)
             [verb step & args] event
             vis-event-handler (get (get vis-event-handlers verb) step)]
-        (println num-events event (vis-event-handler vis actx args) args)
-        (set-el-innerHTML "event" [num-events event])
+        (vis-event-handler vis actx args)
+        (set-el-innerHTML "event" [num-events @vis])
         (set-el-innerHTML "vis"
                           (str "<circle cx='"
                                (mod num-events 500)


forever -> ostinato to match Arom's phrasing.

--- src/african_polyphony_and_polyrhythm/talk.clj
+++ src/african_polyphony_and_polyrhythm/talk.clj
@@ -115,10 +115,10 @@
 ;;;;;;;;;;;;;;;;;;

 (defn clapping-music []
-  (let [forever (comp rand-variations list)
+  (let [ostinato #(rand-variations [%])
         african-bell-pattern (rhythm [1/8 1/8 1/4 1/8 1/4 1/4 1/8 1/4])]
-    (->> african-bell-pattern forever (all :part :mother)
-         (canon #(->> % (take 32) (then (rhythm [1/8])) forever (all :part :child))))))
+    (->> african-bell-pattern ostinato (all :part :mother)
+         (canon #(->> % (take 32) (then (rhythm [1/8])) ostinato (all :part :child))))))

 (comment
   (->> (clapping-music)


stop repl reconnect attempts if worker isn't running

output will be stale once it starts running again anyways.

--- src/main/shadow/cljs/devtools/client/browser.cljs
+++ src/main/shadow/cljs/devtools/client/browser.cljs
@@ -313,12 +313,12 @@
     nil

     :client/stale
-    (do
-      (vreset! stale-client-detected true)
-      (vreset! close-reason-ref "Stale Client! You are not using the latest compilation output!"))
+    (do (vreset! stale-client-detected true)
+        (vreset! close-reason-ref "Stale Client! You are not using the latest compilation output!"))

     :client/no-worker
-    (vreset! close-reason-ref (str "watch for build \"" env/build-id "\" not running"))
+    (do (vreset! stale-client-detected true)
+        (vreset! close-reason-ref (str "watch for build \"" env/build-id "\" not running")))

     :custom-msg
     (env/publish! (:payload msg))


Add clojurescript slide

Add clojurescript slide

--- src/cljs/devcards/conway/devcards/slides.cljs
+++ src/cljs/devcards/conway/devcards/slides.cljs
@@ -10,23 +10,27 @@
                                               "Originally from the Basque Country, 5 years in Norway"
                                               "Working with Clojure + Clojurescript for the last 8 months (so much fun!)"
                                               "Daily tools: AWS, Terraform, Ansible, Kafka, Gerrit, and many more!"]}
-                         {:title "OM" :items ["React Wrapper in cljs. Even faster than React! Immutable data structures"
+                         {:title "Clojurescript" :items ["Clojure for the browser"
+                                                         "Immutable data structures"
+                                                         "Functional"
+                                                         "Namespaces"
+                                                         "Great community (Clojurians slack channel,...)"
+                                                         "React Wrappers: OM, Reagent, Quiescent,..."]}
+                         {:title "OM" :items ["React Wrapper in cljs. Even faster than React! Reference equality check"
                                               "Application state is stored in a global atom"
                                               "Components are functions from app state to DOM elements"
                                               "Cursors. Only render if necessary."
                                               "OM/React components lifecycle (IWillMount, IRender, IDidUpdate,...)"
-                                              "Reusable components"]}
+                                              "Components are reusable"]}
                          {:title "Conway's Game of Life"
-                          :items ["Zero-player game, where its evolution is determined by its initial state, requiring no further input. Possible to create patterns."
-                                  "A cell will die, or become alive, depending on the state of its neighbors in the previous generation."
-                                  "Show me sOMe code! (conway.core)"]
+                          :items []
                           :extra-component slides/slide1-extra
-                          :extra {:state {:game-state #{[-1 -1] [0 -1] [1 -1]
-                                                        [-2 0] [-1 0] [0 0]}
+                          :extra {:state {:game-state #{[-1 0] [-1 1]
+                                                        [0 -1] [0 0] [1 0]}
                                           :old-state #{}}
-                                  :opts {:opts {:cell-size 20
-                                                :grid {:x 4 :y 4}
-                                                :speed-ms 1000}}}}
+                                  :opts {:opts {:cell-size 10
+                                                :grid {:x 40 :y 40}
+                                                :speed-ms 500}}}}
                          {:title "Figwheel" :items ["Live reloading (cljs + css)"
                                                     "How does it work?"
                                                     "Show Figwheel in action!"


Fixed test failures.

Fixed test failures.

--- src/cmr/system_int_test/utils/search_util.clj
+++ src/cmr/system_int_test/utils/search_util.clj
@@ -299,7 +299,10 @@
 (defn- parse-refs-response
   "Parse the find-refs response based on expected format and retruns the parsed result"
   [concept-type params options]
-  (let [{:keys [echo-compatible include-facets]} params
+  (let [;; params is not a map for catalog-rest style tests,
+        ;; we cannot destructing params as a map for the next two lines.
+        echo-compatible (:echo-compatible params)
+        include-facets (:include-facets params)
         response (find-concepts-in-format "application/xml" concept-type params options)]
     (if (and echo-compatible include-facets)
       (parse-echo-facets-response response)


Indent

Indent

--- src-cljs/frontend/components/insights.cljs
+++ src-cljs/frontend/components/insights.cljs
@@ -268,10 +268,10 @@
                            :src (-> latest-build build/status-icon common/icon-path)})]
            [:span.project-name
             (if (feature/enabled? :insights-dashboard)
-            [:a {:href (routes/v1-insights-dashboard {:org (:username project)
-                                                      :repo (:reponame project)})}
-             (formatted-project-name project)]
-             (formatted-project-name project))]
+              [:a {:href (routes/v1-insights-dashboard {:org (:username project)
+                                                        :repo (:reponame project)})}
+               (formatted-project-name project)]
+              (formatted-project-name project))]
            [:div.github-icon
             [:a {:href (:vcs_url project)}
              [:i.octicon.octicon-mark-github]]]


check if document.hostname is empty before using it

can be empty in electron

fixes #277

--- src/main/shadow/cljs/devtools/client/env.cljs
+++ src/main/shadow/cljs/devtools/client/env.cljs
@@ -30,7 +30,7 @@
 (goog-define ignore-warnings false)

 (defn get-repl-host []
-  (if (and use-document-host js/goog.global.document)
+  (if (and use-document-host js/goog.global.document (seq js/goog.global.document.hostname))
     js/document.location.hostname
     repl-host))


normalize :node-module-dir to support relative paths properly

eg. "../"

this would otherwise bail and complain about files being
outside the project since it wasn't properly detected and being
an npm file where this is actually allowed

fixes #489

--- src/main/shadow/cljs/devtools/server/util.clj
+++ src/main/shadow/cljs/devtools/server/util.clj
@@ -13,7 +13,7 @@
     [shadow.cljs.devtools.server.runtime :as runtime]
     [clojure.set :as set]
     [clojure.core.async.impl.protocols :as async-prot])
-  (:import (java.io Writer InputStreamReader BufferedReader IOException ByteArrayOutputStream ByteArrayInputStream PrintWriter)
+  (:import (java.io Writer InputStreamReader BufferedReader IOException ByteArrayOutputStream ByteArrayInputStream PrintWriter File)
            [java.net SocketException]
            [java.util List]))

@@ -54,6 +54,16 @@
         (build-log/log* build-log/stdout state evt)
         ))))

+;; .getCanonicalFile also resolves symlinks which we want to keep
+;; and File itself doesn't have a way to only remove .. or . placeholders otherwise
+;; so going to path and back immediately to avoid having to deal with non-normalized
+;; paths later on
+(defn normalize-file [^File file]
+  (-> file
+      (.toPath)
+      (.normalize)
+      (.toFile)))
+
 (defn new-build
   [{:keys [build-id] :or {build-id :custom} :as build-config} mode opts]
   (let [{:keys [npm classpath cache-root build-executor babel config] :as runtime}
@@ -67,21 +77,25 @@

         node-modules-dir
         (when-let [nmd (get-in build-config [:js-options :node-modules-dir])]
-          (let [nmdf (io/file nmd)]
-            (cond
-              (and (str/ends-with? nmd "node_modules")
-                   (.exists nmdf))
-              (.getAbsoluteFile nmdf)
-
-              (.exists (io/file nmdf "node_modules"))
-              (-> (io/file nmdf "node_modules")
-                  (.getAbsoluteFile))
-
-              (.exists nmdf)
-              (.getAbsoluteFile nmdf)
-
-              :else
-              (throw (ex-info "invalid :node-modules-dir" {:node-modules-dir nmd})))))
+          (let [nmdf (io/file nmd)
+                abs-file
+                (cond
+                  (and (str/ends-with? nmd "node_modules")
+                       (.exists nmdf))
+                  (.getAbsoluteFile nmdf)
+
+                  (.exists (io/file nmdf "node_modules"))
+                  (-> (io/file nmdf "node_modules")
+                      (.getAbsoluteFile))
+
+                  (.exists nmdf)
+                  (.getAbsoluteFile nmdf)
+
+                  :else
+                  (throw (ex-info "invalid :node-modules-dir" {:node-modules-dir nmd})))]
+
+            ;; :node-modules-dir can be a relative path like "./foo" or "../"
+            (normalize-file abs-file)))

         ;; FIXME: this should not happen here. move to more appropriate place
         ;; somewhere in build targets maybe


Initial work on function based URL generation

--- src/engulf/formulas/http_benchmark_runner.clj
+++ src/engulf/formulas/http_benchmark_runner.clj
@@ -31,6 +31,28 @@

   (map #(assoc % :keep-alive? keep-alive?)
        (markov/corpus-chain corpus) ))
+
+(defn fn-req-seq
+  [forms-str]
+  (letfn [(check-fn [val]
+            (when (not (ifn? val))
+              (throw (Exception.
+                      (str  "User script '" val
+                            "' did not return an fn!"))))
+            val)
+          (generator [forms]
+            (let [cur-ns *ns*
+                  script-ns (create-ns 'engulf.user-script-ns)]
+              (try
+                (in-ns (ns-name script-ns))
+                (eval  '(clojure.core/refer 'clojure.core))
+                (check-fn (eval forms))
+                (finally
+                 (in-ns (ns-name cur-ns))
+                 (remove-ns (ns-name script-ns))))))
+          (lazify [script-fn]
+            (lazy-seq (cons (script-fn) (lazify script-fn))))]
+    (lazify (generator (read-string forms-str)))))

 (defn simple-req-seq
   [{target :target}]


remove some redundant code

remove some redundant code

--- src/frontend/cljs/alibi/activity_graphic.cljs
+++ src/frontend/cljs/alibi/activity_graphic.cljs
@@ -699,23 +699,16 @@
           (aset el "style" "top" (px (- top (:height rect))))
           (aset el "className" "tooltip top fade in"))))))

-(defn merge-entries [merge-on to-merge]
-  (let [ids (set (map :entry-id to-merge))]
-    (concat (remove #(get ids (:entry-id %)) merge-on) to-merge)))
-
 (defn render-graphic
   [{:keys [dispatch!
            project-data
-           additional-entries
            selected-entry] :as state}]
   ;(log "project-data %o" project-data)
   (when (seq project-data)
-    (let [union-records (merge-entries (:data project-data)
-                                       additional-entries)
-          svg (render-svg
+    (let [svg (render-svg
                 dispatch!
                 (:selected-date project-data)
-                (init-data union-records)
+                (init-data (:data project-data))
                 #(dispatch! (actions/change-entry-page-date %))
                 {:selected-entry selected-entry})


reverted the revert

reverted the revert

--- src/mafia_votecount/scraper/team_liquid.clj
+++ src/mafia_votecount/scraper/team_liquid.clj
@@ -153,7 +153,7 @@

 (defn- cycle-changes [indexed hosts]
   (filter #(and (is-host? % hosts) (is-cycle-change? (:message (val %))))
-          (rest indexed)))
+          indexed))

 (defn- dec-or-nil [num]
   (if (nil? num)


Add diff to nested output

Add diff to nested output

--- src/main/clojure/lazytest/report/nested.clj
+++ src/main/clojure/lazytest/report/nested.clj
@@ -4,7 +4,8 @@
 	lazytest.results
 	lazytest.test-case
 	clojure.pprint
-	[clojure.stacktrace :only (print-cause-trace)]))
+	[clojure.stacktrace :only (print-cause-trace)]
+	[clojure.data :only (diff)]))

 (defn- identifier [result]
   (let [m (meta (:source result))]
@@ -66,15 +67,34 @@

 ;;; Failures

+(defn- print-equality-failed [a b]
+  (let [[a b same] (diff a b)]
+    (println (colorize "Only in first argument:" :cyan))
+    (pprint a)
+    (println (colorize "Only in second argument:" :cyan))
+    (pprint b)
+    (println (colorize "The same in both:" :cyan))
+    (pprint same)))
+
+(defn- print-evaluated-arguments [reason]
+  (println (colorize "Evaluated arguments:" :cyan))
+  (doseq [arg (rest (:evaluated reason))]
+    (print "* ")
+    (pprint arg)))
+
 (defn- print-expectation-failed [err]
   (let [reason (. err reason)]
     (println "at" (:file reason) "line" (:line reason))
-    (println "Expression:" (:form reason))
-    (println "Result:" (pr-str (:result reason)))
+    (println (colorize "Expression:" :cyan))
+    (pprint (:form reason))
+    (println (colorize "Result:" :cyan))
+    (pprint (:result reason))
     (when (:evaluated reason)
-      (println "Evaluated arguments:")
-      (pprint (zipmap (rest (:form reason)) (rest (:evaluated reason)))))
-    (println "Local bindings:")
+      (print-evaluated-arguments reason)
+      (when (and (= = (first (:evaluated reason)))
+		 (= 3 (count (:evaluated reason))))
+	(apply print-equality-failed (rest (:evaluated reason)))))
+    (println (colorize "Local bindings:" :cyan))
     (pprint (:locals reason))))

 (defn- report-test-case-failure [result docs]


Fix for https://github.com/swarmpit/swarmpit/issues/156

--- src/clj/swarmpit/docker/mapper/inbound.clj
+++ src/clj/swarmpit/docker/mapper/inbound.clj
@@ -146,7 +146,7 @@
   [service-spec]
   (->> (get-in service-spec [:TaskTemplate :ContainerSpec :Env])
        (map (fn [p]
-              (let [variable (str/split p #"=")]
+              (let [variable (str/split p #"=" 2)]
                 {:name  (first variable)
                  :value (second variable)})))
        (into [])))


varname fix

varname fix

--- src/clojure/zensols/actioncli/resource.clj
+++ src/clojure/zensols/actioncli/resource.clj
@@ -36,9 +36,9 @@

   * **:create?** if `:file` then create the director(ies) on the
   file system, otherwise if `:dir` then create all parent directories"
-  ([key child-file & {:keys [create?] :or {:create? nil}}]
+  ([key child-file & {:keys [create] :or {:create nil}}]
    (let [path (io/file (resource-path key) child-file)]
-     (case create?
+     (case create
        :file (.mkdirs path)
        :dir (.mkdirs (.getParentFile path))
        :else)


recurring decimals...

recurring decimals...

--- src/clojureplayground/codingame_helper.clj
+++ src/clojureplayground/codingame_helper.clj
@@ -91,7 +91,7 @@
  {:i 22, :f 5, :t 6, :severed false}

 ; Recurring decimals puzzle
-(fn [n]
+#_(fn [n]
   (let [[l r] (clojure.string/split (str (.doubleValue (/ 1 n))) #"\.")]
     (if-let [ss (last
                   (flatten
@@ -112,4 +112,9 @@
       (cond
         (.contains r "E-") (println "0.")
         (clojure.string/starts-with? r "00")
-        (println (str l "." "(" r ")"))))))+        (println (str l "." "(" r ")"))))))
+
+;todo IDEA! 1428571428571428571428571428571429
+;go and build subseq 1 by 1 until you find that
+;string yielded by dropping subseq len of chars
+;begins with already built subseq...


I misread task, there are indices of exit gateways

--- src/clojureplayground/codingame_helper.clj
+++ src/clojureplayground/codingame_helper.clj
@@ -1,4 +1,5 @@
-(ns clojureplayground.codingame-helper)
+(ns clojureplayground.codingame-helper
+  (:gen-class))

 (defn direction [adj opp]
   (if (neg? adj)
@@ -18,22 +19,49 @@
   ((allowed-lines theta) (direction adj opp)))

 ;APU: Init Phase
-(let [inp ["00" "0."]
-      neighr (fn [x y row]
-               (let [nx (.indexOf row "0" (inc x))]
-                 (if (>= nx 0) [nx y] [-1 -1])))
-      neighb (fn [x y in]
-               (reduce (fn [[_ _ cnt] i]
-                         (if (= \0 (.charAt i x))
-                           (reduced [x cnt])
-                           [-1 -1 (inc cnt)])) [-1 -1 (inc y)] (drop (inc y) in)))]
-  (map #(clojure.string/join " " %)
-       (filter some?
-               (apply concat
-                      (map-indexed (fn [y row]
-                                     (map-indexed (fn [x c]
-                                                    (when (= c \0)
-                                                      (let [[x1 y1] (neighr x y row)
-                                                            [x2 y2] (neighb x y inp)] [x y x1 y1 x2 y2]))) row)) inp)))))
+#_(let [inp ["00" "0."]
+        neighr (fn [x y row]
+                 (let [nx (.indexOf row "0" (inc x))]
+                   (if (>= nx 0) [nx y] [-1 -1])))
+        neighb (fn [x y in]
+                 (reduce (fn [[_ _ cnt] i]
+                           (if (= \0 (.charAt i x))
+                             (reduced [x cnt])
+                             [-1 -1 (inc cnt)])) [-1 -1 (inc y)] (drop (inc y) in)))]
+    (map #(clojure.string/join " " %)
+         (filter some?
+                 (apply concat
+                        (map-indexed (fn [y row]
+                                       (map-indexed (fn [x c]
+                                                      (when (= c \0)
+                                                        (let [[x1 y1] (neighr x y row)
+                                                              [x2 y2] (neighb x y inp)] [x y x1 y1 x2 y2]))) row)) inp)))))
+
+; Auto-generated code below aims at helping you parse
+; the standard input according to the problem statement.
+
+(def s->i #(Integer/parseInt %))
+(def spws #(clojure.string/split % #"\s"))
+(defn node-to-cut [aloc links]
+  (if-let [fc (some #(let [{:keys [f t severed]} %]
+                      (when (and (= f aloc) (zero? t) (false? severed))
+                        %)) links)]
+    fc
+    (first (filter #(let [{:keys [f severed]} %]
+                     (and (= f aloc) (false? severed))) links))))
+
+(let [[_ L E] (map s->i (spws (read-line)))
+      [links egs] (split-at (* 2 L) (mapcat #(map s->i (spws %)) (repeatedly (+ E L) read-line)))
+      lks (vec
+            (map-indexed
+              #(let [[from to] %2]
+                {:i % :f from :t to :severed false})
+              (partition 2 links)))]
+  (println lks)
+  (loop [lks0 lks]
+    (let [SI (read) {:keys [i f t] :as fnd} (node-to-cut SI lks0)]
+      (println f t)
+      (recur (update-in lks0 [i :severed] #(identity %2) true)))))

+;(println (mapcat #(clojure.string/split % #"\s") (repeatedly 3 read-line)))


CMR-512: Added check to only process ECHO10 for now during bulk indexing.

--- src/cmr/indexer/services/index_service.clj
+++ src/cmr/indexer/services/index_service.clj
@@ -33,15 +33,21 @@
 (defn prepare-batch
   "Convert a batch of concepts into elastic docs for bulk indexing."
   [context concepts]
-  (map (fn [concept]
-         (let [umm-concept (parse-concept concept)
-               concept-id (:concept-id concept)
-               revision-id (:revision-id concept)
-               index-name (idx-set/get-concept-index-name context concept-id revision-id umm-concept)
-               type (name (concept->type concept))
-               elastic-doc (concept->elastic-doc context concept umm-concept)]
-           (merge elastic-doc {:_index index-name :_type type})))
-       concepts))
+  ;; we only handle ECHO10 format right now
+  (let [concepts (filter #(#{"ECHO10"} (:format %)) concepts)]
+    (map (fn [concept]
+           (let [umm-concept (parse-concept concept)
+                 _ (println (get-in umm-concept [:product :short-name]))
+                 _ (when (nil? (get-in umm-concept [:product :short-name]))
+                     (do (println "nil short-name:" umm-concept)
+                       (println concept)))
+                 concept-id (:concept-id concept)
+                 revision-id (:revision-id concept)
+                 index-name (idx-set/get-concept-index-name context concept-id revision-id umm-concept)
+                 type (name (concept->type concept))
+                 elastic-doc (concept->elastic-doc context concept umm-concept)]
+             (merge elastic-doc {:_index index-name :_type type})))
+         concepts)))

 (deftracefn bulk-index
   "Index many concepts at once using the elastic bulk api. The concepts to be indexed are passed


fix defalias-macro

fix defalias-macro

--- src/com/billpiel/mem_tracer/util/other.clj
+++ src/com/billpiel/mem_tracer/util/other.clj
@@ -42,8 +42,8 @@

 (defn qualify-sym
   [ns sym]
-  (symbol (name ns)
-          (name sym)))
+  (symbol (str ns)
+          (str sym)))

 (defn atom?
   [v]
@@ -132,18 +132,32 @@
                         (update-in [:doc] #(format "An alias for `%s`.\n%s"
                                                    (name '~source)
                                                    %))))))
+
 (defmacro defalias-macro
   [alias source]
-  `(do (defmacro ~alias [& body#] `(~'~source '~@body#))
-       (alter-meta! #'~alias merge
-                    (-> #'~source
-                        meta
-                        (select-keys [:arglists
-                                      :doc])
-                        (update-in [:doc] #(format "An alias for `%s`.\n%s"
-                                                   (name '~source)
-                                                   %))))
-       #'~alias))
+  (let [body-sym (gensym "body")
+        qualified-source (qualify-sym *ns* source)
+        source-meta (->> source
+                         (ns-resolve *ns*)
+                         meta)
+        arglists (:arglists source-meta)
+        forms (map (fn [args]
+                     `(~args
+                       (clojure.core/seq
+                        (clojure.core/concat
+                         (clojure.core/list '~qualified-source)
+                         ~args))))
+                   arglists)]
+    `(do (defmacro ~alias ~@forms)
+         (alter-meta! #'~alias merge
+                      (-> (var ~qualified-source)
+                          meta
+                          (select-keys [:arglists
+                                        :doc])
+                          (update-in [:doc] #(format "An alias for `%s`.\n%s"
+                                                     (name '~source)
+                                                     %))))
+         #'~alias)))

 (defn macro?
   [v]
@@ -191,12 +205,6 @@
   [& body]
   `(alter-meta! ~body assoc :source '~body))

-(src-in-meta
- defn fff
- [x] (-> x
-         inc
-         inc))
-
 (defn back-into
   [orig noob]


CLI parsing should stop at clj-run/run

CLI parsing should stop at clj-run/run

fixes #545

--- src/main/shadow/cljs/devtools/cli_opts.cljc
+++ src/main/shadow/cljs/devtools/cli_opts.cljc
@@ -154,14 +154,31 @@
               (parse-build-arg)
               ))))))

+(defn split-at-run [args]
+  (let [idx (or (.indexOf args "run")
+                (.indexOf args "clj-run"))]
+    (if (= -1 idx)
+      [args []]
+      [(subvec args 0 (inc idx))
+       (subvec args (inc idx))]
+      )))
+
+(comment
+  (prn (split-at-run ["a" "run" "b"])))
+
 (defn parse [args]
-  (let [parsed
-        (cli/parse-opts args cli-spec)]
-    (if (or (:errors parsed)
-            (get-in parsed [:options :help]))
+  (let [[args extra] (split-at-run (vec args))
+        parsed
+        (-> (cli/parse-opts args cli-spec)
+            (update :arguments into extra))]
+
+    (if (or (:errors parsed) (get-in parsed [:options :help]))
       parsed
       (parse-arguments parsed)
       )))
+
+(comment
+  (prn (parse ["run" "--foo" "--bar"])))

 (def cli-config
   {:aliases


Replaced 'cond' with simpler 'case'.

Replaced 'cond' with simpler 'case'.

--- src/app/interactive.clj
+++ src/app/interactive.clj
@@ -67,13 +67,13 @@
         (println "ERROR: " ast)
         (rp state))
       (let [command (ffirst ast)]
-        (cond
-          (= command :EXIT) (exit)
-          (= command :LIST) (list-loaded-classes state)
-          (= command :HELP) (help state)
-          (= command :LOAD) (load-classes ast)
-          (= command :MC) (mc-operation state)
-          :else (println "Command not implemented: " command))))))
+        (case command
+          :EXIT (exit)
+          :LIST (list-loaded-classes state)
+          :HELP (help state)
+          :LOAD (load-classes ast)
+          :MC (mc-operation state)
+          (println "Command not implemented: " command))))))

 (defn interactive [state]
   (do


[#13220] ENS warning is not shown for affected multiaccounts after upgrade

Signed-off-by: andrey <b713972e59b8e606e23253c4a13e948139fea4d1@gmail.com>

--- src/status_im/multiaccounts/login/core.cljs
+++ src/status_im/multiaccounts/login/core.cljs
@@ -143,13 +143,13 @@
   {:events [::initialize-wallet]}
   [{:keys [db] :as cofx} accounts tokens custom-tokens
    favourites scan-all-tokens? new-account?]
-  (check-invalid-ens cofx)
   (fx/merge
    cofx
    {:db                          (assoc db :multiaccount/accounts
                                         (rpc->accounts accounts))
     ;; NOTE: Local notifications should be enabled only after wallet was started
     ::enable-local-notifications nil}
+   (check-invalid-ens)
    (wallet/initialize-tokens tokens custom-tokens)
    (wallet/initialize-favourites favourites)
    (wallet/get-pending-transactions)


reduce amount of unification done if use-spec-cache? is true.

--- src/babel/generate.cljc
+++ src/babel/generate.cljc
@@ -14,7 +14,7 @@
 (def ^:const branch? #(let [result (= 0 (rand-int (+ % branching-factor)))]
                         (log/debug (str "branch at: " % "? => " result))
                         result))
-(def ^:const truncate? false)
+(def ^:const truncate? true)
 (def ^:const println? false)
 (def ^:const use-spec-cache? true)
 (declare gen)
@@ -54,7 +54,8 @@

 (defn matching-rules [spec model]
   (->> (:grammar model)
-       (filter #(not (= :fail (unify % spec))))))
+       (map #(unify % spec))
+       (filter #(not (= :fail %)))))

 (defn rules-for-spec [spec model]
   (if (not use-spec-cache?)
@@ -62,11 +63,10 @@
     (let [plain-spec (strip-refs spec)
           looked-up (get @(:rules-for-spec model) plain-spec ::none)]
       (if (not (= ::none looked-up))
-        (->> looked-up
-             (map #(unify % spec)))
+        looked-up
         (let [matching-rules (matching-rules spec model)]
-          (swap! (:rules-for-spec model) (fn [x] (assoc @(:rules-for-spec model) plain-spec matching-rules)))
-          (->> matching-rules (map #(unify % spec))))))))
+          (swap! (:rules-for-spec model) #(assoc % plain-spec matching-rules))
+          matching-rules)))))

 (defn parent-with-head
   "Return every possible tree of depth 1 from the given spec and model."


cleanup

cleanup

--- src/babel/generate.cljc
+++ src/babel/generate.cljc
@@ -30,10 +30,6 @@
 (declare generate-all)
 (declare path-to-map)
 (declare spec-info)
-
-;; {:synsem {:cat :noun,
-;;           :pronoun true,
-;;           :sem {:pred :cat}}

 (defn generate [spec language-model
                 & {:keys [max-total-depth truncate-children]


mongo fix, maybe

mongo fix, maybe

--- src/metabase/driver/mongo/query_processor.clj
+++ src/metabase/driver/mongo/query_processor.clj
@@ -308,12 +308,9 @@
     (memoize
      (fn [field-id]
        (let [{base-type :base_type, field-name :name, special-type :special_type} (sel :one [Field :base_type :name :special_type] :id field-id)]
-         (cond
-           (contains? #{:DateField :DateTimeField} base-type) u/parse-date-yyyy-mm-dd
-           (= special-type :timestamp_seconds)                u/date-yyyy-mm-dd->unix-timestamp
-           (and (= field-name "_id")
-                (= base-type  :UnknownField))                 ->ObjectId
-           :else                                              identity))))))
+         (if (and (= field-name "_id")
+                  (= base-type  :UnknownField)) ->ObjectId
+             identity))))))

 (defn- cast-value-if-needed
   "*  Convert dates (which come back as `YYYY-MM-DD` strings) to `java.util.Date`


Yield username only if token is valid

Yield username only if token is valid

--- src/obb_api/interceptors/auth_interceptor.clj
+++ src/obb_api/interceptors/auth_interceptor.clj
@@ -22,11 +22,6 @@
   [request]
   (request :auth))

-(defn username
-  "Gets the request's username"
-  [request]
-  (get-in request [:auth :claims :iss]))
-
 (defn- handle-token
   "Loads and stores the token"
   [context]
@@ -42,8 +37,16 @@

 (defn- valid-token?
   "Checks if the token is present and valid"
-  [context]
-  (= true (get-in context [:request :auth :valid])))
+  [context_or_request]
+  (or
+    (= true (get-in context_or_request [:request :auth :valid]))
+    (= true (get-in context_or_request [:auth :valid]))))
+
+(defn username
+  "Gets the request's username"
+  [request]
+  (when (valid-token? request)
+    (get-in request [:auth :claims :iss])))

 (interceptor/defbefore enforce
   "Enforces a request token"


parser, query->ast, ast->query

parser, query->ast, ast->query

--- src/cellophane/next.clj
+++ src/cellophane/next.clj
@@ -4,6 +4,7 @@
             [clojure.reflect :as reflect]
             [clojure.string :as str]
             [clojure.walk :as walk]
+            [om.next.impl.parser :as parser]
             [om.tempid :as tempid]
             [om.transit :as transit]))

@@ -34,17 +35,17 @@
   (-get-rendered-state [this] "Get the component's rendered local state")
   (-merge-pending-state! [this] "Get the component's pending local state"))

-(defn- dispatch
+(defn- class-dispatch
   "Helper function for implementing static `query` and `params` multimethods.
    Dispatches on the (component) class"
   [class] class)

-(defmulti class-query dispatch)
-
-(defmulti class-params dispatch)
+(defmulti class-query class-dispatch)
+
+(defmulti class-params class-dispatch)
 (defmethod class-params :default [_])

-(defmulti class-ident dispatch)
+(defmulti class-ident class-dispatch)

 ;; ===================================================================
 ;; React bridging (defui, factory, props, state)
@@ -410,6 +411,29 @@
     (ident c m)))

 ;; ===================================================================
+;; Parser
+
+(defn parser
+  "Create a parser. The argument is a map of two keys, :read and :mutate. Both
+   functions should have the signature (Env -> Key -> Params -> ParseResult)."
+  [{:keys [read mutate] :as opts}]
+  {:pre [(map? opts)]}
+  (parser/parser opts))
+
+(defn dispatch
+  "Helper function for implementing :read and :mutate as multimethods. Use this
+   as the dispatch-fn."
+  [_ key _] key)
+
+(defn query->ast
+  "Given a query expression convert it into an AST."
+  [query-expr]
+  (parser/query->ast query-expr))
+
+(defn ast->query [query-ast]
+  "Given an AST convert it back into a query expression."
+  (parser/ast->expr query-ast true))
+

 (defn tempid
   "Return a temporary id."


Fix the converter of fixedStep format

Fix the converter of fixedStep format

--- src/cljam/io/bigwig.clj
+++ src/cljam/io/bigwig.clj
@@ -400,13 +400,13 @@
   [is start item-step item-span item-count chrom rng]
   (reduce
    (fn [acc i]
-     (let [value (lsb/read-float is)]
-       (if (pos? (range-intersection rng {:start start, :end (+ start (* i item-step))}))
+     (let [value (lsb/read-float is)
+           cur-start (+ start (* i item-step))
+           cur-end (+ cur-start item-span)]
+       (if (pos? (range-intersection rng {:start cur-start :end cur-end}))
          (conj acc {:track {:line nil :format :fixed-step :chr chrom
                             :step item-step :span item-span}
-                    :chr chrom :value value
-                    :start (inc (+ start (* i item-step)))
-                    :end (+ (+ start (* i item-step)) item-span)})
+                    :chr chrom :value value :start (inc cur-start) :end cur-end})
          acc)))
    []
    (range item-count)))


Added function 'is-looping' from Processing API to quil. Documentation NOT added (aside from the docstring). Should it be 'is-looping?'?

--- src/cljc/quil/core.cljc
+++ src/cljc/quil/core.cljc
@@ -1869,6 +1869,19 @@

 (defn
   ^{:requires-bindings true
+    :processing-name "isLooping()"
+    :category "Environment"
+    :subcategory nil
+    :added "2.7.2"}
+  is-looping
+  "Returns whether the sketch is looping."
+  []
+  #?(:clj (.isLooping (ap/current-applet))
+     :cljs (.-__isLooping (ap/current-applet))))
+
+
+(defn
+  ^{:requires-bindings true
     :processing-name "frameRate()"
     :category "Environment"
     :subcategory nil