Dependency upgrade

Dependency upgrade

--- project.clj
+++ project.clj
@@ -8,7 +8,7 @@
             ]
   :profiles {:dev {:source-paths ["dev"]
                    :dependencies
-                   [[org.clojure/tools.namespace "0.2.4"]
+                   [[org.clojure/tools.namespace "0.2.5"]
                     [org.clojure/java.classpath "0.2.2"]
                     [midje "1.6.3" :exclusions [org.clojure/clojure]]
                     ]
@@ -21,7 +21,7 @@
                  [org.clojure/tools.trace "0.7.8"]

                  ;; logging
-                 [org.clojure/tools.logging "0.2.6"
+                 [org.clojure/tools.logging "0.3.0"
                   :exclusions
                   [log4j/log4j
                    commons-logging/commons-logging
@@ -31,27 +31,28 @@
                  [org.slf4j/log4j-over-slf4j "1.7.7"]

                  ;; database
-                 [org.clojure/java.jdbc "0.3.3"]
+                 [org.clojure/java.jdbc "0.3.5"]
                  [java-jdbc/dsl "0.1.0"]
                  [honeysql "0.4.3"]
                  [org.postgresql/postgresql "9.3-1100-jdbc41"]
-                 [com.zaxxer/HikariCP "1.3.8"]
+                 ;; com.zaxxer/HikariCP-java6 works on java7
+                 [com.zaxxer/HikariCP "2.0.1"]
                  [ragtime/ragtime.core "0.3.7"]
                  [ragtime/ragtime.sql "0.3.7"]
                  ;; database test
-                 [com.h2database/h2 "1.4.178"]
+                 [com.h2database/h2 "1.4.181"]

                  ;; web, rest
-                 [org.clojure/data.json "0.2.4"]
-                 [ring/ring-devel "1.2.2"]
-                 [ring/ring-core "1.2.2"]
+                 [org.clojure/data.json "0.2.5"]
+                 [ring/ring-devel "1.3.0"]
+                 [ring/ring-core "1.3.0"]
                  [ring/ring-json "0.3.1"]
                  [compojure "1.1.8"]
                  ;; 2.1.17/2.1.18 have perf problems, https://github.com/http-kit/http-kit/issues/148
                  ;; 2.1.17 and earlier have https://github.com/http-kit/http-kit/issues/127
                  [http-kit "2.1.18"]
                  [cheshire "5.3.1"]
-                 [ring-cors "0.1.2"]
+                 [ring-cors "0.1.4"]
                  [javax.servlet/servlet-api "2.5"]

                  ;; structure
@@ -65,14 +66,14 @@
                  ;; api
                  [org.clojars.runa/clj-schema "0.9.4"]

-                 [metosin/compojure-api "0.11.4"]
-                 [metosin/ring-swagger-ui "2.0.16-2"]
+                 [metosin/compojure-api "0.14.0"]
+                 [metosin/ring-swagger-ui "2.0.17"]

-                 [prismatic/schema "0.2.2"]
-                 [prismatic/plumbing "0.3.0"]
+                 [prismatic/schema "0.2.6"]
+                 [prismatic/plumbing "0.3.3"]

                  ;; util
-                 [clj-time "0.7.0"]
+                 [clj-time "0.8.0"]
                  [org.clojure/tools.cli "0.3.1"]
                  [slingshot "0.10.3"]
                  ]


whitespace.

whitespace.

--- project.clj
+++ project.clj
@@ -5,6 +5,12 @@
   :url "https://genome-cancer.ucsc.edu"
   :license {:name "Apache License Version 2.0"
             :url "http://www.eclipse.org/legal/epl-v10.html"}
+  :repl-options  {
+                  ;; If nREPL takes too long to load it may timeout,
+                  ;; increase this to wait longer before timing out.
+                  ;; Defaults to 30000 (30 seconds)
+                  :timeout 12000000
+                  }
   :profiles {:dev {:dependencies
                    [[org.jumpmind.symmetric.schemaspy/schemaspy "5.0.0"]]}
              :uberjar {:omit-source true :aot [mikera.vectorz.core]}}
@@ -31,17 +37,17 @@
                  [com.h2database/h2 "1.3.175"]
                  [filevents "0.1.0"]
                  [clj-http "0.9.1"]
-                 [org.clojure/core.cache  "0.6.3"]
-                 [ch.qos.logback/logback-classic  "1.1.1"]
-                 [org.clojure/tools.logging  "0.3.0"]
-                 [org.clojure/test.check  "0.5.9"]
-                 [com.google.code.gson/gson  "2.2.4"]
-                 [less-awful-ssl  "1.0.0"]
+                 [org.clojure/core.cache "0.6.3"]
+                 [ch.qos.logback/logback-classic "1.1.1"]
+                 [org.clojure/tools.logging "0.3.0"]
+                 [org.clojure/test.check "0.5.9"]
+                 [com.google.code.gson/gson "2.2.4"]
+                 [less-awful-ssl "1.0.0"]
                  [org.clojure/core.match "0.3.0-alpha4"]
                  [org.clojure/math.combinatorics "0.1.1"]
-                 [com.taoensso/timbre  "3.2.0"]]
+                 [com.taoensso/timbre "3.2.0"]]
   :java-source-paths ["src-java"]
-  :target-path  "target/%s"
+  :target-path "target/%s"
   :clean-targets [:target-path :compile-path "build"]
   :aliases {"uberdoc" ["do" ["alldocs"] ["clientsrc"] ["docinstall"] ["uberwrap"]]
             ; XXX this is a bit raw
@@ -71,12 +77,12 @@
   :javac-options ["-target" "1.6" "-source" "1.6"]
   :aot [cavm.core cavm.h2-binary cavm.h2-unpack-rows cavm.conn-customizer]
   :global-vars {*warn-on-reflection* true}
-  :plugins [[lein-sphinx  "1.0.1"]
-            [codox  "0.8.10"]
-            [lein-shell  "0.4.0"]
-            [lein-hiera  "0.8.0"]]
+  :plugins [[lein-sphinx "1.0.1"]
+            [codox "0.8.10"]
+            [lein-shell "0.4.0"]
+            [lein-hiera "0.8.0"]]
   :sphinx {:setting-values {:version ~version
-                            :project ~(str  "UCSC Xena Server " version)}}
+                            :project ~(str "UCSC Xena Server " version)}}
   :codox {:output-dir "doc/_build/implementation"}
   :hiera {:ignore-ns #{cavm.h2-query}
           :cluster-depth 1


Version 0.3.24

Version 0.3.24

--- project.clj
+++ project.clj
@@ -1,4 +1,4 @@
-(defproject puppetlabs/lein-ezbake "0.3.24-SNAPSHOT"
+(defproject puppetlabs/lein-ezbake "0.3.24"
   :description "A system for building packages for trapperkeeper-based applications"
   :url "https://github.com/puppetlabs/ezbake"
   :license {:name "Apache License 2.0"


Add sonartype snapshot repo, as [org.clojure/core.rrb-vector "0.0.9"] throws ArrayOutOfBoundsException whereas 0.0.10-SNAPSHOT doesn't

--- project.clj
+++ project.clj
@@ -17,4 +17,5 @@
   :cljsbuild {
     :builds [{:source-paths ["target/generated"], :id "main", :jar true}]}
   :min-lein-version "2.3.2"
-  :global-vars {*warn-on-reflection* true})
+  :global-vars {*warn-on-reflection* true}
+  :repositories {"sonartype snapshots" "https://oss.sonatype.org/content/repositories/snapshots"})


Update Selmer.

Update Selmer.

--- project.clj
+++ project.clj
@@ -24,7 +24,7 @@
                  [com.climate/claypoole "1.1.2"]
                  [org.clojars.brunchboy/protobuf "0.8.3"]
                  [ola-clojure "0.1.4"]
-                 [selmer "1.0.0"]
+                 [selmer "1.0.2"]
                  [com.evocomputing/colors "1.0.3"]
                  [environ "1.0.2"]
                  [camel-snake-kebab "0.3.2"]


whitespace, testing jenkins GH hook

whitespace, testing jenkins GH hook

--- project.clj
+++ project.clj
@@ -15,5 +15,6 @@
                  "snapshots" {:url "s3p://maven.yieldbot.com/snapshots/"
                               :username :env :passphrase :env}})

+
 (cemerick.pomegranate.aether/register-wagon-factory!
  "s3p" #(eval '(org.springframework.aws.maven.PrivateS3Wagon.)))


Version 0.3.8

Version 0.3.8

--- project.clj
+++ project.clj
@@ -1,4 +1,4 @@
-(defproject fentontravers/websocket-client "0.3.8-SNAPSHOT"
+(defproject fentontravers/websocket-client "0.3.8"
   :description "WebSocket Client Library"
   :url "https://github.com/ftravers/websocket-client"
   :license {:name "Eclipse Public License"


Upgrade to 0.9.10-beta1.

Upgrade to 0.9.10-beta1.

--- project.clj
+++ project.clj
@@ -1,10 +1,10 @@
-(defproject workshop "0.9.9"
+(defproject workshop "0.9.10-beta1"
   :license {:name "Eclipse Public License"
             :url "http://www.eclipse.org/legal/epl-v10.html"}
   :dependencies [[org.clojure/clojure "1.8.0"]
                  [org.clojure/core.async "0.2.374"]
                  ^{:voom {:repo "git@github.com:onyx-platform/onyx.git" :branch "master"}}
-                 [org.onyxplatform/onyx "0.9.9"]
+                 [org.onyxplatform/onyx "0.9.10-beta1"]
                  [org.slf4j/slf4j-api "1.7.12"]
                  [org.slf4j/slf4j-nop "1.7.12"]]
   :profiles {:dev {:dependencies [[org.clojure/tools.namespace "0.2.10"]


Bump version to 4.4.1-SNAPSHOT

Bump version to 4.4.1-SNAPSHOT

--- project.clj
+++ project.clj
@@ -1,4 +1,4 @@
-(def pdb-version "4.4.0")
+(def pdb-version "4.4.1-SNAPSHOT")
 (def puppetserver-version "2.7.2")
 (def clj-parent-version "0.6.0")


bump version

bump version

--- project.clj
+++ project.clj
@@ -1,4 +1,4 @@
-(defproject tailrecursion/boot "0.1.0-SNAPSHOT"
+(defproject tailrecursion/boot "0.1.0"
   :description "A dependency setup/build tool for Clojure."
   :url "https://github.com/tailrecursion/boot"
   :license {:name "Eclipse Public License"


Version 1.2.5-SNAPSHOT

Version 1.2.5-SNAPSHOT

--- project.clj
+++ project.clj
@@ -1,4 +1,4 @@
-(defproject puppetlabs/jdbc-util "1.2.4"
+(defproject puppetlabs/jdbc-util "1.2.5-SNAPSHOT"
   :description "Common JDBC helpers for use in Puppet Labs projects"
   :url "https://github.com/puppetlabs/jdbc-util"


Update dev-dependencies

Update dev-dependencies

--- project.clj
+++ project.clj
@@ -1,6 +1,7 @@
-(defproject redis-clojure "1.0-SNAPSHOT"
+(defproject redis-clojure "1.0.3-SNAPSHOT"
   :description "A library for the Redis protocol"
   :url "http://github.com/ragnard/redis-clojure"
   :dependencies [[org.clojure/clojure "1.1.0"]
                  [org.clojure/clojure-contrib "1.1.0"]]
-  :dev-dependencies [[org.clojure/swank-clojure "1.0"]])
+  :dev-dependencies [[swank-clojure "1.2.1"]
+                     [lein-clojars "0.5.0"]])


Update kitchensink dependency to released 0.1.0 version

--- project.clj
+++ project.clj
@@ -30,7 +30,7 @@
                  [metrics-clojure "0.7.0" :exclusions [org.clojure/clojure org.slf4j/slf4j-api]]
                  [clj-time "0.5.1"]
                  [org.clojure/java.jmx "0.2.0"]
-                 ; Filesystem utilities
+                 ;; Filesystem utilities
                  [fs "1.1.2"]
                  ;; Version information
                  [trptcolin/versioneer "0.1.0"]
@@ -77,11 +77,4 @@
   :jar-exclusions [#"leiningen/"]

   :aot [com.puppetlabs.puppetdb.core]
-  :main com.puppetlabs.puppetdb.core
-
-  ;; TODO: this will go away as soon as kitchensink is published to clojars
-  ;;  (before this PR is merged)
-  :repositories [["releases" "http://nexus.delivery.puppetlabs.net/content/repositories/releases/"]
-                 ["snapshots" "http://nexus.delivery.puppetlabs.net/content/repositories/snapshots/"]]
-
-  )
+  :main com.puppetlabs.puppetdb.core)


wrap prod build to avoid cluttering the root namespace

--- project.clj
+++ project.clj
@@ -21,6 +21,6 @@
                 :optimizations :advanced
                 :externs ["libs/interact.js" "react/externs/react.js"]
                 :pretty-print false
-                :output-wrapper false
+                :output-wrapper true
                 :closure-warnings {:externs-validation :off
                                    :non-standard-jsdoc :off}}}}})


change version of dynamic kafka spout

change version of dynamic kafka spout

--- project.clj
+++ project.clj
@@ -1,4 +1,4 @@
-(defproject storm/storm-kafka "0.7.3-SNAPSHOT"
+(defproject storm/storm-kafka "0.7.3-dynamic-SNAPSHOT"
   :source-path "src/clj"
   :java-source-path "src/jvm"
   :javac-options {:debug "true" :fork "true"}


dep navigator

dep navigator

--- project.clj
+++ project.clj
@@ -14,6 +14,9 @@
                   :exclusions [hiccup org.clojure/tools.reader
                                compojure ring/ring-core commons-codec
                                com.datomic/datomic-free]]
+                 ^{:voom {:repo "https://github.com/vlacs/navigator"}}
+                 [org.vlacs/navigator "0.1.0-20140410_082313-g18713ff"
+                  :exclusions [com.datomic/datomic-free]]
                  [http-kit "2.1.16"]
                  #_[ring "1.2.1"]
                  [liberator "0.11.0"]


lein-release plugin: preparing 0.4.3 release

--- project.clj
+++ project.clj
@@ -1,6 +1,6 @@
 (def ks-version "0.7.2")

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


:check-types working again

:check-types working again

also complain less if a FS resource overrides a JAR resource

--- src/main/shadow/cljs/build.clj
+++ src/main/shadow/cljs/build.clj
@@ -1254,11 +1254,16 @@
     ;; do not merge files that are already present from a different source path
     (when-let [existing (get-in state [:sources name])]
       (not (is-same-resource? src existing)))
-    (do (log state
-          {:type :duplicate-resource
-           :name name
-           :path-use (get-in state [:sources name :source-path])
-           :path-ignore (:source-path src)})
+
+    (do (when (not (and (not (get-in state [:sources name :from-jar]))
+                        (:from-jar src)))
+          ;; don't complain if we have a file from the fs and the conflict is from the jar
+          ;; assume thats an intentional override
+          (log state
+            {:type :duplicate-resource
+             :name name
+             :path-use (get-in state [:sources name :source-path])
+             :path-ignore (:source-path src)}))
         state)

     ;; now we need to handle conflicts for cljc/cljs files
@@ -1474,7 +1479,7 @@
   [state]
   (cond-> state
     (nil? (:compiler-env state))
-    (assoc :compiler-env @(env/default-compiler-env state))))
+    (assoc :compiler-env @(env/default-compiler-env (:compiler-options state)))))

 (defn finalize-config
   "should be called AFTER all resources have been discovered (ie. after find-resources...)"
@@ -2425,6 +2430,59 @@
 ;; added by default in init-state
 (defn closure-add-replace-constants-pass [cc ^CompilerOptions co state]
   (.addCustomPass co CustomPassExecutionTime/BEFORE_CHECKS (ReplaceCLJSConstants. cc)))
+
+(defn closure-register-cljs-protocol-properties
+  "this is needed to make :check-types work
+
+   It registers all known CLJS protocols with the Closure TypeRegistry
+   each method is as a property on Object since most of the time Closure doesn't know the proper type
+   and annotating everything seems unlikely.
+
+   The property on Object doesn't hurt and won't hinder renaming (as opposed to externs)"
+  [cc co {:keys [compiler-env build-sources] :as state}]
+  (when (contains? #{:warning :error} (get-in state [:compiler-options :closure-warnings :check-types]))
+    (let [type-reg
+          (.getTypeRegistry cc)
+
+          obj-type
+          (.getType type-reg "Object")]
+
+      ;; some general properties
+      (doseq [prop
+              ["cljs$lang$protocol_mask$partition$"
+               "cljs$lang$macro"
+               "cljs$lang$test"]]
+        (.registerPropertyOnType type-reg prop obj-type))
+
+      ;; find all protocols and register the protocol method properties
+      (doseq [ana-ns (vals (::ana/namespaces compiler-env))
+              :let [{:keys [defs]} ana-ns]
+              def (vals defs)
+              :when (-> def :meta :protocol-symbol)]
+
+        (let [{:keys [name meta]} def
+              {:keys [protocol-info]} meta
+
+              prefix
+              (str (cljs-comp/protocol-prefix name))]
+
+          ;; the marker prop
+          ;; some.prototype.cljs$core$ISeq$ = cljs.core.PROTOCOL_SENTINEL;
+          (.registerPropertyOnType type-reg prefix obj-type)
+
+          (doseq [[meth-name meth-sigs] (:methods protocol-info)
+                  :let [munged-name (cljs-comp/munge meth-name)]
+                  meth-sig meth-sigs]
+
+            (let [arity
+                  (count meth-sig)
+
+                  prop
+                  (str prefix munged-name "$arity$" arity)]
+
+              ;; register each arity some.prototype.cljs$core$ISeq$_seq$arity$1
+              (.registerPropertyOnType type-reg prop obj-type)
+              )))))))

 (defn read-variable-map [{:keys [cache-dir] :as state} name]
   (let [map-file (io/file cache-dir name)]
@@ -3244,7 +3302,7 @@
         :elide-asserts false

         :closure-warnings
-        {:check-types :off}}
+        {:check-types :warning}}

        :closure-defines
        {"goog.DEBUG" false
@@ -3295,6 +3353,7 @@
        :logger
        stdout-log}

+      (add-closure-configurator closure-register-cljs-protocol-properties)
       (add-closure-configurator closure-add-replace-constants-pass)
       (add-closure-configurator closure-add-variable-maps)
       ))


Added ->long function and clarified docstrings for casting helpers

--- src/semantic_csv/core.clj
+++ src/semantic_csv/core.clj
@@ -310,17 +310,22 @@
 ;; These functions can be imported and used in your `:cast-fns` specification

 (defn ->int
-  "Translating string into integers"
+  "Translate to int from string or other numeric"
   [string]
   (Integer/parseInt string))

+(defn ->long
+  "Translating to long from string or other numeric"
+  [string]
+  (Long/parseLong string))
+
 (defn ->float
-  "Translate into float"
+  "Translate to float from string or other numeric"
   [string]
   (Float/parseFloat string))

 (defn ->double
-  "Translate into double"
+  "Translate to double from string or other numeric"
   [string]
   (Double/parseDouble string))


(maint) Update namespace for jruby-lock-timeout

Throwing the jruby-lock-timeout exception was refactored into its own method in
a different namespace (in jruby-utils) so this updates it.

--- src/clj/puppetlabs/services/puppet_admin/puppet_admin_core.clj
+++ src/clj/puppetlabs/services/puppet_admin/puppet_admin_core.clj
@@ -60,7 +60,7 @@
     ; 204 No Content on success
     {:status 204}
     ; If a lock timeout occurs return a 503 Service Unavailable
-    (catch [:kind :puppetlabs.services.jruby-pool-manager.impl.jruby-agents/jruby-lock-timeout] e
+    (catch [:kind :puppetlabs.services.jruby-pool-manager.impl.jruby-internal/jruby-lock-timeout] e
       (log/error (:msg e))
       (-> (rr/response (:msg e))
           (rr/status 503)


add reporting via clojure.test integration (fixes gh-2)

--- src/simple_check/core.clj
+++ src/simple_check/core.clj
@@ -1,5 +1,6 @@
 (ns simple-check.core
-  (:require [simple-check.generators :as gen]))
+  (:require [simple-check.generators :as gen]
+            [clojure.test :as ct]))

 (defn- run-test
   [property args]
@@ -9,28 +10,22 @@
                  (catch Throwable t t))]
     [result vars]))

-(declare shrink-loop)
+(declare shrink-loop failure report-trial)

 (defn quick-check
   [num-tests property-fun & args]
   (loop [so-far 0]
-    (if (= so-far num-tests)
-      {:result true :num-tests so-far}
+    (if (== so-far num-tests)
+      (do
+        (report-trial property-fun so-far num-tests)
+        {:result true :num-tests so-far})
       (let [[result vars] (run-test property-fun args)]
         (cond
-          (instance? Throwable result) {:result result
-                                        :num-tests so-far
-                                        :fail (vec vars)
-                                        :shrunk (shrink-loop property-fun
-                                                             (gen/tuple args)
-                                                             (vec vars))}
-          result (recur (inc so-far))
-          :default {:result false
-                    :num-tests so-far
-                    :fail (vec vars)
-                    :shrunk (shrink-loop property-fun
-                                         (gen/tuple args)
-                                         (vec vars))})))))
+          (instance? Throwable result) (failure property-fun result so-far args vars)
+          result (do
+                   (report-trial property-fun so-far num-tests)
+                   (recur (inc so-far)))
+          :default (failure property-fun result so-far args vars))))))

 (defmacro forall [bindings expr]
   `(let [~@bindings]
@@ -77,5 +72,106 @@
                 (recur tail head (inc total-nodes-visited) depth false)
                 (recur children head (inc total-nodes-visited) (inc depth) true)))))))))

+(defn- report-trial
+  [property-fun so-far num-tests]
+  (ct/report {:type ::trial
+              ::property property-fun
+              ::trial [so-far num-tests]}))
+
+(defn- failure
+  [property-fun result trial-number args failing-params]
+  ;; TODO this is wrong, makes it impossible to clojure.test quickchecks that
+  ;; should fail...
+  #_(ct/report (if (instance? Throwable result)
+               {:type :error
+                :message (.getMessage result)
+                :actual result}
+               {:type :fail
+                :expected true
+                :actual result}))
+  (ct/report {:type ::shrinking
+              ::property property-fun
+              ::params (vec failing-params)})
+  (let [ret {:result result
+             :num-tests trial-number
+             :fail (vec failing-params)}]
+    (assoc ret :shrunk (shrink-loop property-fun
+                                    (gen/tuple args)
+                                    (vec failing-params)))))
+
+;; clojure.test reporting -----------------------------------------------------
+
+(def ^:dynamic *report-trials*
+  "Controls whether property trials should be reported via clojure.test/report.
+  Valid values include:
+
+  * false - no reporting of trials (default)
+  * a function - will be passed a clojure.test/report-style map containing
+      :simple-check.core/property and :simple-check.core/trial slots
+  * true - provides quickcheck-style trial reporting (dots) via
+      `trial-report-dots`
+
+  (Note that all reporting requires running `quick-check` within the scope of a
+  clojure.test run (via `test-ns`, `test-all-vars`, etc.)
+
+  Reporting functions offered by simple-check include `trial-report-dots` and
+  `trial-report-periodic` (which prints more verbose trial progress information
+  every `*trial-report-period*` milliseconds."
+  false)
+(def ^:dynamic *report-shrinking*
+  "If true, a verbose report of the property being tested, the
+  failing return value, and the arguments provoking that failure is emitted
+  prior to the start of the shrinking search."
+  false)
+(def ^:dynamic *trial-report-period*
+  "Milliseconds between reports emitted by `trial-report-periodic`."
+  10000)
+
+(def ^:private last-trial-report (atom 0))
+
+(let [begin-test-var-method (get-method ct/report :begin-test-var)]
+  (defmethod ct/report :begin-test-var [m]
+    (reset! last-trial-report (System/currentTimeMillis))
+    (when begin-test-var-method (begin-test-var-method m))))
+
+(defn- get-property-name
+  [{property-fun ::property :as report-map}]
+  (or (-> property-fun meta :name) (ct/testing-vars-str report-map)))
+
+(defn trial-report-periodic
+  "Intended to be bound as the value of `*report-trials*`; will emit a verbose
+  status every `*trial-report-period*` milliseconds, like this one:
+
+  Passing trial 3286 / 5000 for (your-test-var-name-here) (:)"
+  [m]
+  (let [t (System/currentTimeMillis)]
+    (when (> (- t *trial-report-period*) @last-trial-report)
+      (ct/with-test-out
+        (println "Passing trial" (-> m ::trial first) "/" (-> m ::trial second)
+                 "for" (get-property-name m)))
+      (reset! last-trial-report t))))
+
+(defn trial-report-dots
+  "Intended to be bound as the value of `*report-trials*`; will emit a single
+  dot every 1000 trials reported."
+  [{[so-far total] ::trial}]
+  (when (pos? so-far)
+    (when (zero? (mod so-far 1000))
+      (print ".")
+      (flush))
+    (when (== so-far total) (println))))
+
+(defmethod ct/report ::trial [m]
+  (when-let [trial-report-fn (and *report-trials*
+                                  (if (true? *report-trials*)
+                                    trial-report-dots
+                                    *report-trials*))]
+    (trial-report-fn m)))
+
+(defmethod ct/report ::shrinking [m]
+  (when *report-shrinking*
+    (ct/with-test-out
+      (println "Shrinking" (get-property-name m) "starting with parameters" (::params m)))))
+
 ;; Generators -----------------------------------------------------------------


factoring draw methods

factoring draw methods

--- src-cljs/jasons_game/ui.cljs
+++ src-cljs/jasons_game/ui.cljs
@@ -60,6 +60,12 @@
   (s/pop-matrix)
   (s/pop-style))

+(defn draw-shape [vertices]
+  (s/begin-shape)
+  (doseq [vertex vertices]
+    (apply s/vertex vertex))
+  (s/end-shape))
+
 (def cursor-size 10)
 (defn draw-cursor [x y]
   (draw :cursor x y
@@ -67,25 +73,24 @@
           (s/line (- cursor-size) 0, cursor-size 0)
           (s/line 0 (- cursor-size), 0 cursor-size))))

-(def offset 10)
-(def point-width 20)
-(def point-height 40)
+(def speech-balloon-properties {:offset 10
+                                :point-width 20
+                                :point-height 40})
 (defn draw-speech-balloon [speech x y]
-  (let [balloon-width (+ (s/text-width speech) 40)
+  (let [p speech-balloon-properties
+        balloon-width (+ (s/text-width speech) 40)
         balloon-height (+ (s/text-ascent) (s/text-descent) 40)]
     (draw :speech-balloon x y
           (fn []
-            (s/translate (- (/ balloon-width 2)) (- (+ offset point-height balloon-height)))
+            (s/translate (- (/ balloon-width 2)) (- (+ (p :offset) (p :point-height) balloon-height)))

-            (s/begin-shape)
-            (s/vertex 0 0)
-            (s/vertex balloon-width 0)
-            (s/vertex balloon-width balloon-height)
-            (s/vertex (+ (/ balloon-width 2) point-width) balloon-height)
-            (s/vertex (/ balloon-width 2) (+ balloon-height point-height))
-            (s/vertex (/ balloon-width 2) balloon-height)
-            (s/vertex 0 balloon-height)
-            (s/end-shape)
+            (draw-shape [[0 0]
+                         [balloon-width 0]
+                         [balloon-width balloon-height]
+                         [(+ (/ balloon-width 2) (p :point-width)) balloon-height]
+                         [(/ balloon-width 2) (+ balloon-height (p :point-height))]
+                         [(/ balloon-width 2) balloon-height]
+                         [0 balloon-height]])

             (set-style :words)
             (s/text speech 20 (+ 20 (s/text-ascent)))))))


Modify Inciseable and add extension to Parse.

--- src/incise/parsers/core.clj
+++ src/incise/parsers/core.clj
@@ -1,26 +1,24 @@
 (ns incise.parsers.core
   (:require [incise.layouts.core :as layout]
-            [incise.config :refer [config]]
+            [incise.config :as conf]
+            [incise.parsers.helpers :refer [extension]]
+            [clj-time.core :as tm]
+            [clojure.java.io :refer [file]]
             [clojure.string :as s])
   (:import [java.io File]))

-(defprotocol Inciseable
-  ^String (rubbing [this] "Creates a more temporary String representation of
-                           this.")
-  ^File (incise [this] "Creates a more permanent File representing this."))
-
 (defrecord Parse [^String title
+                  ^String extension
                   ^String content
                   ^String date
                   ^String layout
                   ^clojure.lang.Seqable tags
-                  ^String category]
-  Inciseable
-  (rubbing [this]
-    ((layout/get (:layout this)) @config this))
-  (incise [this]
-    (spit "somewhere" (.rubbing this))
-    (File. "somewhere")))
+                  ^String category])
+
+(defprotocol Inciseable
+  ^Parse (parse [this] "Creates a more temporary String representation of
+                        this.")
+  ^File (incise [this ^Parse parse layout] "Write the appropriate file."))

 (def parsers
   "An atom containing a mapping of extensions (strings) to parse functions. A


Layout manager #41

Layout manager #41

--- flatguicore/src/flatgui/layout.clj
+++ flatguicore/src/flatgui/layout.clj
@@ -15,7 +15,7 @@
   (:import (java.util.regex Pattern)))

-(def gap 0.125)
+(def gap 0.0625)

 (def component-min-size (m/defpoint 0.375 0.375))

@@ -131,7 +131,7 @@
       (let [stretch-space (- 1.0 stable-pref-total)
             _ (println "stretch-space" stretch-space)
             index-range (range 0 (count dir))
-            ws (map #(if (stretches? %) (do (println "sw" (:stch-weight %)) (* (:stch-weight %) stretch-space)) (sfn (:pref %))) dir)
+            ws (map #(if (stretches? %) (* (:stch-weight %) stretch-space) (sfn (:pref %))) dir)
             xs (map #(reduce + (take % ws)) index-range)]
            ;; y and h are here temporarily
            ;; instead of :x and :w there should be variables (params)
@@ -150,7 +150,7 @@
   (if-let [coord-map (get-property [] :coord-map)]
     (if-let [coord ((:id component) coord-map)]
       (let [ps (get-property [] :clip-size)]
-        (m/translation (* (:x coord) (m/x ps)) (* (:y coord (m/y ps)))))
+        (m/translation (+ gap (* (:x coord) (m/x ps))) (+ gap (* (:y coord (m/y ps))))))
       old-position-matrix)
     old-position-matrix))

@@ -158,7 +158,7 @@
   (if-let [coord-map (get-property [] :coord-map)]
     (if-let [coord ((:id component) coord-map)]
       (let [ps (get-property [] :clip-size)]
-        (m/defpoint (* (:w coord) (m/x ps)) (* (:h coord (m/y ps)))))
+        (m/defpoint (- (* (:w coord) (m/x ps)) gap gap) (- (* (:h coord (m/y ps))) gap gap)))
       old-clip-size)
     old-clip-size))


Made /status URL a development mode only thing (worried about Tomcat's memory warnings)

--- 2-collectors/clojure-collector/src/snowplow/clojure_collector/core.clj
+++ 2-collectors/clojure-collector/src/snowplow/clojure_collector/core.clj
@@ -42,7 +42,7 @@
   (GET "/i"           {c :cookies} (send-cookie-etc' c))
   (GET "/ice.png"     {c :cookies} (send-cookie-etc' c)) ; legacy name for i
   (GET "/healthcheck" request responses/send-200)
-  ;GET "/status"      from expose-metrics-as-json
+  ;GET "/status"      from expose-metrics-as-json, only in development env
   ;HEAD "/"           from beanstalk.clj
   (compojure.route/not-found  responses/send-404))

@@ -56,5 +56,5 @@
    (mware/wrap-if config/production?  mware/wrap-failsafe)
    (mware/wrap-request-logging)
    (mware/wrap-exception-logging)
-   (expose-metrics-as-json "/status")
-   (instrument)))+   (mware/wrap-if config/development? expose-metrics-as-json "/status")
+   (mware/wrap-if config/development? instrument)))


dev mode

dev mode

--- Clojure-Websockets/MainApp/src/clj/birdwatch/http/markup.clj
+++ Clojure-Websockets/MainApp/src/clj/birdwatch/http/markup.clj
@@ -14,9 +14,11 @@
                  ga('create', " analytics-id ", 'auto');
                  ga('send', 'pageview');")])

+(def dev? (get (System/getenv) "DEV" false))
+
 (defn index-page-fn
   "Renders Index page."
-  [dev?]
+  [_req]
   (html
     [:html {:lang "en"}
      [:head


cruft removal;

cruft removal;

--- src/mustached_hipster/core.clj
+++ src/mustached_hipster/core.clj
@@ -4,9 +4,7 @@
 (require 'clojure.string)

 (defn -main
-  [url]
-  ;; work around dangerous default behaviour in Clojure
-  (alter-var-root #'*read-eval* (constantly false))
-  ;(print (:body (clj-http.client/get "http://nrk.no/nordlandsbanen/")))
-  ;(print (:body (clj-http.client/get "http://nrk.no/nordlandsbanen/media/js/videoPlayer.js")))
-  (print (:body (clj-http.client/get url))))
+   [url]
+   ;; work around dangerous default behaviour in Clojure
+   (alter-var-root #'*read-eval* (constantly false))
+   (print (:body (clj-http.client/get url))))


Rebuild utils/response around ring.utils.response

--- src/io/aviso/rook/utils.clj
+++ src/io/aviso/rook/utils.clj
@@ -4,6 +4,7 @@
     (java.util UUID)
     (javax.servlet.http HttpServletResponse))
   (:require
+    [ring.util.response :as r]
     [clojure.pprint :as pprint]))

 (defn new-uuid
@@ -14,8 +15,10 @@

 (defn response
   "Construct Ring response for success or other status."
-  ([body] (response HttpServletResponse/SC_OK body))
-  ([status body] {:status status :body body}))
+  ([body] (r/response body))
+  ([status body] (->
+                   (response body)
+                   (r/status status))))

 (defn pretty-print
   "Pretty-prints the supplied object to a returned string."
@@ -28,5 +31,5 @@
   "Prints the object more briefly, with limits on level and length."
   [object]
   (binding [*print-level* 4
-                     *print-length* 5] (pretty-print object)))
+            *print-length* 5] (pretty-print object)))


Change text and position; toggle discuss when saving a reference

--- src/discuss/tooltip.cljs
+++ src/discuss/tooltip.cljs
@@ -63,11 +63,11 @@
                (vlib/logo)
                (vlib/safe-space) " | " (vlib/safe-space)
                (dom/span #js {:className "pointer"
-                              :onClick   clipboard/add-selection}
+                              :onClick   (fn [] (clipboard/add-selection) (sidebar/show))}
                          (vlib/fa-icon "fa-bookmark-o")
                          " Save")
                (vlib/safe-space) "  " (vlib/safe-space)
                (dom/span #js {:className "pointer"
                               :onClick   sidebar/show}
                          (vlib/fa-icon "fa-comment")
-                         " Discuss")))))+                         " Show Discuss")))))


Port 'vector' (just the helper func) to shin, for fun.

--- lib/shin/cljs/shin.core.cljs
+++ lib/shin/cljs/shin.core.cljs
@@ -69,8 +69,7 @@
             (do
               (.set hamt i (aget args i) h)
               (recur (inc i)))))))))
-
-(set! shin/vector vector)
+(set! shin/vector vector) ;; dat workaround.

 (def name shin/name)
 (def nil? shin/nil?)


Fix nippy round trip issues

Fix nippy round trip issues

--- src/onyx/compression/nippy.clj
+++ src/onyx/compression/nippy.clj
@@ -35,14 +35,12 @@
                                                   (.readUTF data-input))]
                      (clojure.lang.ExceptionInfo. str ex cause)))

-(defrecord NippyOpts [v1-compatibility? compressor encryptor password no-header?])
-
 (def messaging-compress-opts
-  (map->NippyOpts {:v1-compatibility? false
-                   :compressor nil
-                   :encryptor nil
-                   :password nil
-                   :no-header? true}))
+  {:v1-compatibility? false
+   :compressor nil
+   :encryptor nil
+   :password nil
+   :no-header? true})

 (defn messaging-compress [x]
   (nippy/freeze x messaging-compress-opts))
@@ -58,7 +56,7 @@
 (defn zookeeper-compress [x]
   (nippy/freeze x zookeeper-compress-opts))

-(def zookeeper-decompress-opts (map->NippyOpts {:v1-compatibility? false}))
+(def zookeeper-decompress-opts {:v1-compatibility? false})

 (defn zookeeper-decompress [x]
   (nippy/thaw x zookeeper-decompress-opts))
@@ -66,19 +64,19 @@
 (defn window-log-compress [x]
   (nippy/freeze x {}))

-(def window-log-decompress-opts (map->NippyOpts {:v1-compatibility? false}))
+(def window-log-decompress-opts {:v1-compatibility? false})

 (defn window-log-decompress [x]
   (nippy/thaw x window-log-decompress-opts))

 (def localdb-compress-opts
-  (map->NippyOpts {:v1-compatibility? false :compressor nil :encryptor nil :password nil}))
+  {:v1-compatibility? false :compressor nil :encryptor nil :password nil})

 (defn localdb-compress [x]
   (nippy/freeze x localdb-compress-opts))

 (def local-db-decompress-opts
-  (map->NippyOpts {:v1-compatibility? false :compressor nil :encryptor nil :password nil}))
+  {:v1-compatibility? false :compressor nil :encryptor nil :password nil})

 (defn localdb-decompress [x]
   (nippy/thaw x local-db-decompress-opts))


Change async error reporting mechanism

Change async error reporting mechanism

--- src/onyx/plugin/bookkeeper.clj
+++ src/onyx/plugin/bookkeeper.clj
@@ -176,7 +176,7 @@
             (default-value :bookkeeper/ledger-end-id Double/POSITIVE_INFINITY)
             (default-value :bookkeeper/no-recovery-empty-read-back-off 500)
             (default-value :checkpoint/key task-id))
-        {:keys [read-ch shutdown-ch commit-ch]} pipeline
+        {:keys [read-ch shutdown-ch commit-ch error]} pipeline
         ;; decrement because we are going to store this as a checkpoint and then inc after recover
         checkpoint-key (:checkpoint/key defaulted-task-map)
         _ (set-starting-offset! log task-map checkpoint-key (dec ledger-start-id))
@@ -200,7 +200,7 @@
                           (if (= exit :finished)
                             (>!! read-ch (t/input (random-uuid) :done))))
                         (catch Exception e
-                          (>!! read-ch (t/input (random-uuid) e))
+                          (reset! error e)
                           (fatal e "BookKeeper plugin: error reading."))))]
     {:bookkeeper/read-ch read-ch
      :bookkeeper/shutdown-ch shutdown-ch
@@ -222,7 +222,7 @@

 (defrecord BookKeeperLogInput
   [log task-id max-pending batch-size batch-timeout pending-messages drained?
-   top-index top-acked-index pending-indexes read-ch commit-ch shutdown-ch]
+   top-index top-acked-index pending-indexes error read-ch commit-ch shutdown-ch]
   p-ext/Pipeline
   (write-batch
     [this event]
@@ -230,6 +230,8 @@

   (read-batch
     [_ event]
+    (when @error
+      (throw @error))
     (let [pending (count @pending-messages)
           max-segments (min (- max-pending pending) batch-size)
           timeout-ch (timeout batch-timeout)
@@ -240,8 +242,6 @@
       (doseq [m batch]
         (let [message (:message m)]
           (info "Read message in batch" message)
-          (when (instance? java.lang.Throwable message)
-            (throw message))

           (when-not (= message :done)
             (swap! top-index max (:entry-id message))
@@ -287,6 +287,7 @@
         batch-size (:onyx/batch-size task-map)
         batch-timeout (or (:onyx/batch-timeout task-map) (:onyx/batch-timeout defaults))
         read-ch (chan (or (:bookkeeper/read-buffer task-map) 1000))
+        error (atom nil)
         commit-ch (chan (sliding-buffer 1))
         shutdown-ch (chan 1)
         top-id (atom -1)
@@ -301,6 +302,7 @@
                           top-id
                           top-acked-id
                           pending-indexes
+                          error
                           read-ch
                           commit-ch
                           shutdown-ch)))


some function declaration simplified

some function declaration simplified

--- src/leiningen/fore_prob.clj
+++ src/leiningen/fore_prob.clj
@@ -49,12 +49,14 @@

 (defn- expand-prob-tests
   "expand a problem’s tests string"
-  [prob tests]
-  (->>
-   (map #(cs/replace % #"\b__\b" (str prob "-solution")) tests)
-   (map #(cs/replace % #"\r\n" "\n"))
-   (map #(str (indent) "(is " % ")")) ; wrap tests in 'is calls
-   (cs/join "\n")))
+  [prob]
+  (let [prob-fn (str (prob->fn prob) "-solution")]
+    (->>
+      (prob :tests)
+      (map #(cs/replace % #"\b__\b" prob-fn))
+      (map #(cs/replace % #"\r\n" "\n"))
+      (map #(str (indent) "(is " % ")")) ; wrap tests in 'is calls
+      (cs/join "\n"))))

 ;; == Files handling ==

@@ -79,38 +81,39 @@
   "return the content of the main tests file of the current project, stripped
    out of any 'replace-me' placeholder test"
   [project]
-  (cs/replace (slurp (tests-path)) #"(?m)^\(deftest replace-me[^)]+\)+$" ""))
+  (cs/replace
+    (slurp (tests-path project))
+    #"(?m)^\(deftest replace-me[^)]+\)+$" ""))

 (defn- get-src
   "return the content of the main source file of the current project"
   [project]
-  (slurp (src-path)))
+  (slurp (src-path project)))

 (defn- has-problem-tests?
   "test if the current project has tests for a given problem"
-  [tests problem]
-  (boolean (re-find (re-pattern (str "\\(" (prob->fn problem) "\\b")) tests)))
+  [tests probfn]
+  (boolean (re-find (re-pattern (str "\\(" probfn "\\b")) tests)))

 (defn- has-problem-src?
-  "test if the current project has the function for a given problem"
-  [src problem]
-  (boolean (re-find (re-pattern (str "\\(defn " (prob->fn problem))) src)))
+  "test if the current project has a given function"
+  [src probfn]
+  (boolean (re-find (re-pattern (str "\\(defn " probfn "\\b")) src)))

 (defn- write-problem-tests
   "write tests for a given problem in the current project"
   [project existing-tests prob]
-  (spit
-    (tests-path)
-    (str existing-tests
-         (mk-template
-           (cons "\n\n" test-template)
-           {:prob-fn prob
-            :tests (expand-prob-tests prob (prob :tests))}))))
+  (spit (tests-path project)
+        (str existing-tests
+             (mk-template
+               (cons "\n\n" test-template)
+               {:prob-fn prob
+                :tests (expand-prob-tests prob)}))))

 (defn- write-problem-src
   "add a function for a given problem in the current project"
   [project prob]
-  (spit (src-path)
+  (spit (src-path project)
         (mk-template
           (cons "\n\n" solution-template)
           {:prob-fn prob
@@ -120,12 +123,13 @@
 (defn- write-prob
   "write a problem source and tests"
   [project prob]
-  (let [tests (get-tests project)
-        src   (get-src   project)]
-    (if-not (has-problem-tests? tests prob)
+  (let [tests  (get-tests project)
+        src    (get-src   project)
+        probfn (prob->fn prob)]
+    (if-not (has-problem-tests? tests probfn)
       (write-problem-tests project tests prob)
       (println "tests already exist, skipping."))
-    (if-not (has-problem-src? src prob)
+    (if-not (has-problem-src? src probfn)
       (write-problem-src project prob)
       (println "source already exist, skipping."))))


cleaned up test

cleaned up test

--- pigpen-cascading/src/test/clojure/pigpen/cascading_test.clj
+++ pigpen-cascading/src/test/clojure/pigpen/cascading_test.clj
@@ -6,26 +6,24 @@
   (:require [pigpen.extensions.test :refer [test-diff pigsym-zero pigsym-inc]]
             [pigpen.cascading.core :as pig]))

-(comment test-taps
-         (println (command->flowdef '{:type     :load
-                                      :id       load0
-                                      :location "some/path"
-                                      :storage  {:type :storage
-                                                 :func "text"
-                                                 :args []}
-                                      :fields   [a b c]
-                                      :opts     {:type :load-opts}}
-                                    {}))
-         (is (= 1 1)))
+(def input1 "/tmp/input1")
+(def input2 "/tmp/input2")
+(def output "/tmp/output")

-(comment test-load-text
-         (let [load-cmd (load-text "the/location")]
-           (println "load-cmd:" load-cmd)
-           (println (command->flowdef load-cmd {}))))
+(defn setup [fn]
+  (.delete (FileSystem/get (Configuration.)) (Path. output) true)
+  (fn))
+
+(clojure.test/use-fixtures :each setup)
+
+(defn write-input [path objs]
+  (spit path (clojure.string/join (map prn-str objs))))
+
+(defn read-output [path]
+  (map load-string (clojure.string/split (slurp (str path "/part-00000")) #"\n")))

 (deftest test-simple-flow
-  (spit "/tmp/input" "1\t2\tfoo\n4\t5\tbar")
-  (.delete (FileSystem/get (Configuration.)) (Path. "/tmp/output") true)
+  (write-input input1 [["1" "2" "foo"] ["4" "5" "bar"]])
   (letfn
       [(func [data]
              (->> data
@@ -36,28 +34,27 @@
                                 (< sum 5)))))
        (query [input-file output-file]
               (->>
-                (load-tsv input-file)
+                (load-clj input-file)
                 (func)
                 (store-clj output-file)))]
-    (let [flow (generate-flow (query "/tmp/input" "/tmp/output"))]
-      (println flow)
+    (let [flow (generate-flow (query input1 output))]
       (.complete flow))
-    (println "results:\n" (slurp "/tmp/output/part-00000"))))
+    (is (= [{:name "foo", :sum 3}] (read-output output)))))

 (comment test-cogroup
-  (spit "/tmp/input1" "{:a 1 :b 2}\n {:a 1 :b 3}\n {:a 2 :b 4}")
-  (spit "/tmp/input2" "{:c 1 :d \"foo\"}\n {:c 2 :d \"bar\"}\n {:c 2 :d \"baz\"}")
-  (.delete (FileSystem/get (Configuration.)) (Path. "/tmp/output") true)
-  (let [left (load-clj "/tmp/input1")
-        right (load-clj "/tmp/input2")
-        command (pig/cogroup [(left :on :a)
-                              (right :on :c)]
-                              (fn [k l r] [k (map :b l) (map :d r)]))
-        command (store-clj "/tmp/output" command)
-        baked (pigpen.oven/bake :cascading command)]
-    (clojure.pprint/pprint (preprocess-commands baked))
-    (commands->flow baked)
-    (.complete (generate-flow command))
-    (println "results:\n" (slurp "/tmp/output/part-00000"))))
+         (spit "/tmp/input1" "{:a 1 :b 2}\n {:a 1 :b 3}\n {:a 2 :b 4}")
+         (spit "/tmp/input2" "{:c 1 :d \"foo\"}\n {:c 2 :d \"bar\"}\n {:c 2 :d \"baz\"}")
+         (.delete (FileSystem/get (Configuration.)) (Path. "/tmp/output") true)
+         (let [left (load-clj "/tmp/input1")
+               right (load-clj "/tmp/input2")
+               command (pig/cogroup [(left :on :a)
+                                     (right :on :c)]
+                                    (fn [k l r] [k (map :b l) (map :d r)]))
+               command (store-clj "/tmp/output" command)
+               baked (pigpen.oven/bake :cascading command)]
+           (clojure.pprint/pprint (preprocess-commands baked))
+           (commands->flow baked)
+           (.complete (generate-flow command))
+           (println "results:\n" (slurp "/tmp/output/part-00000"))))

 (run-tests 'pigpen.cascading-test)


core.async refactor

core.async refactor

--- src/kushana/core.cljc
+++ src/kushana/core.cljc
@@ -97,28 +97,33 @@
     out))

 #?(:cljs
-  (defn update-js-loop [eng scene-ch]
-    (let [js-obj-atom (atom {})
-          js-scene-atom (atom nil)
-          update  (update-js! eng js-obj-atom)
-          diffn   (δscene latest-id)
-          diff-ch (chan)
-          diff    (go-loop [last-scene {:scene-graph {}}]
-                    (let [next-scene (<! scene-ch)
-                          next-diff  (diffn last-scene next-scene)]
-                      (>! diff-ch next-diff)
-                      (recur next-scene)))]
-      (go-loop [js-obj-graph {}]
-        (let [next-diff (<! diff-ch)
-              next-js-graph (update js-obj-graph next-diff)]
-          (reset! js-scene-atom next-js-graph)
-          (recur next-js-graph)))
-      js-scene-atom)))
+   (defn diff-loop [scene-ch]
+     (let [diffn   (δscene latest-id)
+           diff-ch (chan)]
+       (go-loop [last-scene {:scene-graph {}}]
+         (let [next-scene (<! scene-ch)
+               next-diff  (diffn last-scene next-scene)]
+           (>! diff-ch next-diff)
+           (recur next-scene)))
+       diff-ch)))
+
+#?(:cljs
+   (defn update-js-loop [eng diff-ch]
+     (let [js-obj-atom   (atom {})
+           js-scene-atom (atom nil)
+           update        (update-js! eng js-obj-atom)]
+       (go-loop [js-obj-graph {}]
+         (let [next-diff (<! diff-ch)
+               next-js-graph (update js-obj-graph next-diff)]
+           (reset! js-scene-atom next-js-graph)
+           (recur next-js-graph)))
+       js-scene-atom)))

 #?(:cljs
    (defn js-eng [scene-ch options]
-     (let [eng (impl/engine options)]
-       (impl/draw! eng (update-js-loop eng scene-ch))))
+     (let [eng     (impl/engine options)
+           diff-ch (diff-loop scene-ch)]
+       (impl/draw! eng (update-js-loop eng diff-ch))))
    :clj
    (defn physics-eng [scene-chan] nil))


UI: only 10 pagination items; reformatting

--- Clojure-Websockets/MainApp/src/cljs/birdwatch/ui.cljs
+++ Clojure-Websockets/MainApp/src/cljs/birdwatch/ui.cljs
@@ -78,9 +78,10 @@
 (defn pag-items
   "function creating pagination items"
   [app page-change-chan]
-  (map #(dom/li #js {:className (if (= % (:page app)) "active" "") :onClick (fn [e] (put! page-change-chan %))}
-                (dom/a nil %))
-       (take 25 (range 1 (Math/floor (/ (:count app) (:n app)))))))
+  (map #(dom/li nil
+                (dom/a #js {:className (if (= % (:page app)) "pure-button pure-button-active" "pure-button")
+                            :onClick (fn [e] (put! page-change-chan %))} %))
+       (take 10 (range 1 (Math/floor (/ (:count app) (:n app)))))))

 (defn pagination-view
   "rendering pagination list"
@@ -88,16 +89,16 @@
   (reify
     om/IInitState
     (init-state [_]
-      {:page-change (chan)})
+                {:page-change (chan)})
     om/IWillMount
     (will-mount [_]
-      (let [page-change (om/get-state owner :page-change)]
-        (go (loop []
-          (let [page (<! page-change)]
-            (om/update! app :page page)
-            (recur))))))
+                (let [page-change (om/get-state owner :page-change)]
+                  (go (loop []
+                        (let [page (<! page-change)]
+                          (om/update! app :page page)
+                          (recur))))))
     om/IRenderState
     (render-state [this {:keys [page-change]}]
-                  (apply dom/ul #js {:className "pagination-mini"}
-                         (flatten [(dom/li nil (dom/a nil "Page"))
+                  (apply dom/ul #js {:className "pure-paginator"}
+                         (flatten [(dom/li nil (dom/a #js {:className "pure-button"} "Page"))
                                    (pag-items app page-change)])))))


Run the stage's act method

Run the stage's act method

--- src/play_clj/core_graphics.clj
+++ src/play_clj/core_graphics.clj
@@ -183,7 +183,7 @@
   (when camera
     (.setCamera renderer camera)
     (.setViewport renderer (. camera viewportWidth) (. camera viewportHeight)))
-  (.draw renderer))
+  (doto renderer .act .draw))

 (defn render!
   ([{:keys [renderer] :as screen}]


second worker

second worker

--- worker/src/worker/core.cljs
+++ worker/src/worker/core.cljs
@@ -1,6 +1,7 @@
 (ns worker.core
   (:require [cljs.js]
-            [worker.worker :as w]))
+            [worker.worker :as w])
+  (:require-macros [worker.macros :as wm]))

 (def tm 1000)
 (defn sleep [msec]
@@ -17,8 +18,20 @@
   {:time tm
     :prnt 100})

+(defn ^:export wrk2 []
+  (enable-console-print!)
+  (println (* 2 tm))
+  (sleep (* 3 tm))
+  (println "test")
+  {:time tm
+    :prnt 100})
+
 (defn ^:export main []
   (enable-console-print!)
   (println "work1..")
-  (w/do-some `wrk)
+;;  (println (w/js-func-name wrk))
+;;  (wm/do-some 1)
+    (w/do-some (meta (var wrk)))
+;;  (println "work2..")
+;;  (w/do-some `wrk2)
   )


Add comment to explain import for keyword namespace

--- src/main/cawala/api/read.clj
+++ src/main/cawala/api/read.clj
@@ -2,6 +2,8 @@
   (:require [com.wsscode.pathom.connect :as pc]
             #_[com.wsscode.pathom.core :as p]
             [taoensso.timbre :as timbre]
+            ;; this dependency is just for namespaced keys I'm getting the db
+            ;; from the parser environment.
             [cawala.api.db :as db]
             [clojure.core.async :as a]))


Group URLs into their channel groups.

Group URLs into their channel groups.

--- src/uuuurrrrllll/core.clj
+++ src/uuuurrrrllll/core.clj
@@ -17,30 +17,55 @@
                  (char c))))

 (defn gen-short-url [n]
-  (clojure.string/join
-   (take n (repeatedly #(rand-nth char-seq)))))
+  (->> #(rand-nth char-seq)
+       repeatedly
+       (take n)
+       clojure.string/join))

-(defn add-url! [url]
+(defn add-entry! [body]
   (let [short-url (gen-short-url 10)]
-    (kv/store bucket short-url url)
+    (kv/store bucket short-url body
+              :content-type "application/json"
+              :indexes {:all #{"all"}})
     short-url))

-(defn get-url [short]
-  (if-let [value (-> (kv/fetch-one bucket short)
-                     :result
-                     :value)]
-    (String. value)
-    nil))
+(defn read-entry [entry]
+  (-> entry
+      :result
+      :value))
+
+(defn get-entry [short]
+  (read-entry (kv/fetch-one bucket short)))
+
+(defn merge-urls [grouped-urls]
+  (for [[k v] grouped-urls]
+    [k (map :url v)]))
+
+(defn get-all-entries []
+  (let [keys (wb/keys-in bucket)]
+    (->> "all"
+         (kv/index-query bucket :all)
+         (pmap get-entry)
+         (group-by :channel)
+         (merge-urls))))

 (defn handle-post [request]
-  (if-let [url (get-in request [:body "url"])]
-    {:status 201 :body {:short (add-url! url)}}
-    {:status 400}))
+  (let [body    (:body request)
+        url     (body "url")
+        channel (body "channel")
+        nick    (body "nick")
+        body    {:url     url
+                 :channel channel
+                 :nick    nick}]
+    (if (every? (complement nil?) [url channel nick])
+      {:status 201 :body {:short (add-entry! body)}}
+      {:status 400})))

 (defn handle-get [request]
   (if-let [url (-> request
                    (get-in [:params :url])
-                   (get-url))]
+                   (get-entry)
+                   :url)]
     {:status 301 :headers {"location" url}}
     {:status 404}))

@@ -48,9 +73,11 @@
   {:status 200
    :body (html [:body
                 [:ul
-                 (for [k (seq (wb/keys-in bucket))]
-                   (let [v (escape-html (get-url k))]
-                     [:li [:a {:href v} v]]))]])})
+                 (for [[channel urls] (get-all-entries)]
+                   [:li channel
+                    [:ul (for [url urls]
+                           (let [v (escape-html url)]
+                             [:li [:a {:href v} v]]))]])]])})

 (defroutes app
   (POST "/" request


Refactoring de la solution en Clojure au puzzle "Temperatures" de CodinGame

--- clojure/codingame/practice/easy/temperatures/src/temperatures/core.clj
+++ clojure/codingame/practice/easy/temperatures/src/temperatures/core.clj
@@ -1,44 +1,40 @@
-(require 'clojure.string)

 (ns temperatures.core
   (:gen-class))

-; Auto-generated code below aims at helping you parse
-; the standard input according to the problem statement.
+(require '[clojure.string :as string])
+
+(defn by-first-asc-and-second-desc [x y]
+  (compare [(first x) (second y)]
+           [(first y) (second x)]))

 (defn -main [& args]
   (let [n (read) _ (read-line) temps (read-line)]
     ; n: the number of temperatures to analyse
     ; temps: the n temperatures expressed as integers ranging from -273 to 5526
-    (if (clojure.string/blank? temps) (println "0")
-                  (let [temp-list (sort (map #(Integer/parseInt %) (clojure.string/split temps #" ")))
-                        abs-temp-list (map #(Math/abs %) temp-list)
-                        sorted-abs-temp-list (sort (map #(Math/abs %) temp-list))
-                        temp-tuples-list (sort-by first (map vector abs-temp-list temp-list))
-                        temp-map (into (sorted-map) (zipmap abs-temp-list temp-list))]
+    (if (string/blank? temps) (println "0")
+        (let [temp-list (sort (map #(Integer/parseInt %) (clojure.string/split temps #" ")))
+              abs-temp-list (map #(Math/abs %) temp-list)
+              sorted-abs-temp-list (sort abs-temp-list)
+              temp-tuples-list (sort by-first-asc-and-second-desc (zipmap abs-temp-list temp-list))]

-                    ; (binding [*out* *err*]
-                    ;   (println "Debug messages..."))
-                    (binding [*out* *err*]
-                      (println "n : " (str n)))
+          (binding [*out* *err*]
+            (println "n : " (str n)))

-                    (binding [*out* *err*]
-                      (println "temperatures : " temps))
+          (binding [*out* *err*]
+            (println "temperatures : " temps))

-                    (binding [*out* *err*]
-                      (println "abs-temp-list : " (str abs-temp-list)))
+          (binding [*out* *err*]
+            (println "abs-temp-list : " (string/join " " abs-temp-list)))

-                    (binding [*out* *err*]
-                      (println "temp-list : " (str temp-list)))
+          (binding [*out* *err*]
+            (println "temp-list : " (string/join " " temp-list)))

-                    (binding [*out* *err*]
-                      (println "temp-tuples-list : " (str (seq temp-tuples-list))))
+          (binding [*out* *err*]
+            (println "temp-tuples-list : " (string/join " " temp-tuples-list)))

-                    (binding [*out* *err*]
-                      (println "temp-map : " (str (seq temp-map))))
+          (binding [*out* *err*]
+            (println (str (second (first temp-tuples-list)))))

-                    (binding [*out* *err*]
-                      (println (str (nth (first temp-tuples-list) 1))))
+          (println (str (second (first temp-tuples-list))))))))

-                    (println (get temp-map (first sorted-abs-temp-list)))))))
-


Make KStreams-related components idempotent

--- clstreams/src/clstreams/kstreams/component.clj
+++ clstreams/src/clstreams/kstreams/component.clj
@@ -14,14 +14,18 @@
   component/Lifecycle

   (start [component]
-    (assoc component
-           :config config
-           :topic-name topic-name
-           :producer (KafkaProducer. (config->props config))))
+    (if producer
+      component
+      (assoc component
+             :config config
+             :topic-name topic-name
+             :producer (KafkaProducer. (config->props config)))))

   (stop [component]
-    (.close producer)
-    (assoc component :producer nil)))
+    (if producer
+      (do (.close producer)
+          (assoc component :producer nil))
+      component)))

 (defn new-producer [topic-name config]
   (map->Producer {:config config :topic-name topic-name}))
@@ -35,15 +39,19 @@
   component/Lifecycle

   (start [component]
-    (let [streams (KafkaStreams. builder (StreamsConfig. config))]
-      (log/info "Starting topology")
-      (.start streams)
-      (assoc component :kstreams streams)))
+    (if kstreams
+      component
+      (let [streams (KafkaStreams. builder (StreamsConfig. config))]
+        (log/info "Starting topology")
+        (.start streams)
+        (assoc component :kstreams streams))))

   (stop [component]
-    (log/info "Stopping topology")
-    (.close kstreams)
-    (assoc component :kstreams nil)))
+    (if kstreams
+      (do (log/info "Stopping topology")
+          (.close kstreams)
+          (assoc component :kstreams nil))
+      component)))

 (defn new-topology [config builder]
   (map->Topology {:config config :builder builder}))


(SERVER-1772) Fixup cli-defaults.sh path

--- src/puppetlabs/ezbake/core.clj
+++ src/puppetlabs/ezbake/core.clj
@@ -39,7 +39,7 @@
 (def build-scripts-prefix "ext/build-scripts/")
 (def terminus-prefix "puppet/")
 (def additional-uberjar-checkouts-dir "target/uberjars")
-(def cli-defaults-filename "ext/cli_defaults/cli-defaults.sh.erb")
+(def cli-defaults-filename (str shared-cli-defaults-prefix "cli-defaults.sh.erb"))

 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
 ;;; Schemas


Remove unused route

Remove unused route

--- src/formlogic/routes.clj
+++ src/formlogic/routes.clj
@@ -53,7 +53,6 @@
   (POST "/login" [email password :as req] (controllers/login email password req))
   (GET "/register" [] (views/register-page))
   (POST "/register" [email] (controllers/register email))
-  (GET "/latex" [] (views/latex-page))
   (POST "/latex" [formula] (controllers/parse-logic-formula formula))
   (wrap-routes #'user-routes handlers/wrap-user-session-check)
   (route/not-found views/not-found-page))


Speed up lens/pos

Speed up lens/pos

Get rid of nested lens compositions and instead apply `lens/>>`
only once at the end.

--- src/active/clojure/lens.cljc
+++ src/active/clojure/lens.cljc
@@ -200,14 +200,13 @@

 (defn pos
   "A lens over the nth element in a collection. Note that when shoving a
-  new value nils may be added before the given position, if the collection is smaller."
+  new value `nil`s may be added before the given position, if the collection is smaller."
   [n]
   (assert (number? n))
   (assert (>= n 0))
-  ;; there are probably more efficient implementations:
-  (if (= n 0)
-    head
-    (>> tail (pos (- n 1)))))
+  (apply >>
+         (conj (vec (repeat n tail))
+               head)))

 (def ^{:doc "A lens that views a sequence as a set."}
   as-set


add step to testpipeline

add step to testpipeline

--- backend/test/lambdaui/testpipeline/simple_pipeline.clj
+++ backend/test/lambdaui/testpipeline/simple_pipeline.clj
@@ -48,6 +48,14 @@
                                        different-status))
                       a-lot-output)
                  )
+     (step/alias "i have substeps"
+                      (run (step/alias "2-parallel-step" (in-parallel a-lot-output a-lot-output))
+                           (step/alias "2-parallel-step" (in-parallel a-lot-output a-lot-output))
+                           (step/alias "i have more substeps"
+                                       (run a-lot-output
+                                            different-status))
+                           a-lot-output)
+                      )
      (step/alias "2-parallel-step" (in-parallel a-lot-output a-lot-output))
      (step/alias "3-parallel-steps" (in-parallel
                                       (step/alias "double-long" (run long-running-task-20s long-running-task-20s))


Adding a command to close all tabs

Adding a command to close all tabs

--- src/lt/objs/tabs.cljs
+++ src/lt/objs/tabs.cljs
@@ -558,6 +558,13 @@
                           (object/raise ts :tab.close)))
                       )})

+(cmd/command {:command :tabs.close-all
+              :desc "Tab: Close all tabs"
+              :exec (fn []
+                      (let [objs (ctx/->obj :tabset)]
+                        (doseq [obj (@objs :objs)]
+                          (object/raise obj :close))))})
+
 (cmd/command {:command :tabs.goto
               :hidden true
               :desc "Tab: Goto tab # or :last"


[#248] Projections tryout

[#248] Projections tryout

--- api/src/clojure/org/akvo/flow_api/datastore/stats.clj
+++ api/src/clojure/org/akvo/flow_api/datastore/stats.clj
@@ -46,7 +46,7 @@
                                     ;; TODO:
                                     ;; Recover projections when index is up
                                     ;; https://github.com/akvo/akvo-flow/issues/3932
-                                    #_#_:projections {"value" String
+                                    :projections {"value" String
                                                   "surveyInstanceId" Long}}
                                    {})))))


update game / stats constants

update game / stats constants

--- src/wombats/constants.clj
+++ src/wombats/constants.clj
@@ -48,6 +48,7 @@
    :stats/smoke-bombs-thrown 0
    :stats/shots-fired 0
    :stats/shots-hit 0
+   :stats/have-been-shot 0
    :stats/wombats-destroyed 0
    :stats/zakano-destroyed 0
    :stats/wombats-shot 0
@@ -57,6 +58,12 @@
    :stats/wood-barriers-shot 0
    :stats/steel-barriers-shot 0
    :stats/deaths 0
+   :stats/deaths-by-shot 0
+   :stats/deaths-by-wood-barrier-collision 0
+   :stats/deaths-by-steel-barrier-collision 0
+   :stats/deaths-by-wombat-collision 0
+   :stats/deaths-by-zakano-collision 0
+   :stats/deaths-by-poison 0
    :stats/wood-barrier-collisions 0
    :stats/steel-barrier-collisions 0
    :stats/zakano-collisions 0


Rewrite partitions when family config changes.

--- src/merkle_db/partition.clj
+++ src/merkle_db/partition.clj
@@ -240,7 +240,9 @@
     (< (::record/count part) half-full)
       [nil (tablet/from-records (read-all store part nil))]

-    (< limit (::record/count part))
+    (or (< limit (::record/count part))
+        (not= (::record/families part)
+              (::record/families params)))
       [(partition-records store params (read-all store part nil)) nil]

     :else


Show remaining time to watch

Show remaining time to watch

--- src/popup/ygq/popup/ui.cljs
+++ src/popup/ygq/popup/ui.cljs
@@ -19,6 +19,9 @@
 (defn update-tab-url [url]
   (cjs/call js/window ["chrome" "tabs" "update"] {:url url}))

+(defn cs [component class-name]
+  (get (css/get-classnames component) (keyword class-name)))
+
 (defmethod mutate 'auth/token-received [{:keys [state]} _ {:keys [token]}]
   {:action (fn []
              (swap! state assoc :app/user-token token))})
@@ -94,6 +97,23 @@
 (s/fdef duration-str
         :args (s/cat :duration ::duration)
         :ret (s/and string? #(re-find #"^(\d{2}:)?\d{2}:\d{2}$" %)))
+
+(defn duration->seconds [duration]
+  (if-let [[h m s] (some->> (re-find #"(?:(\d+)H)?(?:(\d+)M)(?:(\d+)S)?$" duration)
+                            next)]
+    (let [h (js/parseInt (or h 0))
+          m (js/parseInt (or m 0))
+          s (js/parseInt (or s 0))]
+      (+ (* h 3600) (* m 60) s))
+    0))
+
+(defn seconds->duration [seconds]
+  (let [h     (js/Math.floor (/ seconds 3600))
+        m     (mod (js/Math.floor (/ seconds 60)) 60)
+        parts (cond-> []
+                (> h 0) (conj (str h " hours"))
+                (> m 0) (conj (str m " minutes")))]
+    (str/join " and " parts)))

 (om/defui ^:once QueuedVideo
   static uc/InitialAppState
@@ -186,11 +206,11 @@
             (if-not watched?
               (dom/a #js {:className video-action
                           :href      "#"
-                          :onClick   (pd #(om/transact! this `[(video/mark-watched {::video/id ~id})]))}
+                          :onClick   (pd #(om/transact! this `[(video/mark-watched {::video/id ~id}) :video/queue]))}
                 (icon "ok"))
               (dom/a #js {:className video-action
                           :href      "#"
-                          :onClick   (pd #(om/transact! this `[(video/mark-unwatched {::video/id ~id})]))}
+                          :onClick   (pd #(om/transact! this `[(video/mark-unwatched {::video/id ~id} :video/queue)]))}
                 (icon "repeat")))))))))

 (def queued-video (om/factory QueuedVideo))
@@ -285,6 +305,10 @@
                                  :padding       "5px"
                                  :align-items   "baseline"}]

+                    [:.main-container {:display "flex"
+                                       :flex-direction "column"
+                                       :height "100vh"}]
+
                     [:.action-title {:font-weight "bold"
                                      :font-size   "27px"
                                      :margin-left "10px"}]
@@ -306,7 +330,17 @@
                                   :padding        "8px"
                                   :font-weight    "bold"
                                   :text-transform "uppercase"}]
-                    [:.menu-item-active {:background "#ffce8c"}]])
+                    [:.menu-item-active {:background "#ffce8c"}]
+                    [:.remaining-bar {:background    "#fff"
+                                      :border-bottom "2px solid #000"
+                                      :font-weight   "bold"
+                                      :font-size     "12px"
+                                      :text-align    "center"
+                                      :padding       "8px 0"}]
+                    [:.view-area {:flex       "1"
+                                  :overflow   "auto"
+                                  :width      "100vw"
+                                  :overflow-x "hidden"}]])
   (include-children [_] [MainViewLink
                          QueuedVideo
                          CategoryGroup])
@@ -331,9 +365,9 @@
   Object
   (render [this]
     (let [{:keys [ui/react-key video/queue channel/list ui/main-view]} (om/props this)
-          {:keys [main-row action-title reload-button video-chooser]} (css/get-classnames Root)]
+          {:keys [main-row action-title reload-button video-chooser remaining-bar]} (css/get-classnames Root)]
       (dom/div #js {:key react-key}
-        (dom/div nil
+        (dom/div #js {:className (cs Root "main-container")}
           (dom/div #js {:className main-row}
             (dom/div #js {:className action-title} "Youtube Gmail Queue")
             (dom/div #js {:className "flex-space"})
@@ -351,16 +385,26 @@
             (center-text "No videos left to watch.")

             :else
-            (dom/div nil
-              (dom/div #js {:className video-chooser}
-                (main-view-link #:ui{:label     "Latest Uploads"
-                                     :main-view ::main-view.latest
-                                     :component this})
-                (main-view-link #:ui{:label     "Channels"
-                                     :main-view ::main-view.channels
-                                     :component this}))
-              (case main-view
-                ::main-view.latest (mapv queued-video queue)
-                ::main-view.channels (mapv category-group list)))))))))
+            [(dom/div #js {:className video-chooser :key "view-selector"}
+               (main-view-link #:ui{:label     "Latest Uploads"
+                                    :main-view ::main-view.latest
+                                    :component this})
+               (main-view-link #:ui{:label     "Channels"
+                                    :main-view ::main-view.channels
+                                    :component this}))
+             (dom/div #js {:className remaining-bar :key "remaining"}
+               (->> queue
+                    (remove ::video/watched?)
+                    (map (comp duration->seconds ::video/duration ::video/content-details))
+                    (reduce +)
+                    (seconds->duration))
+               " left to watch")
+             (dom/div #js {:key "view" :className (cs Root "view-area")}
+               (case main-view
+                 ::main-view.latest (mapv queued-video queue)
+                 ::main-view.channels (mapv category-group list)))]))))))

 (css/upsert-css "ygq" Root)
+
+(comment
+  )


Print retry count in peer

Print retry count in peer

--- src/onyx_benchmark/peer.clj
+++ src/onyx_benchmark/peer.clj
@@ -44,7 +44,7 @@
                 _ (reset! counter 0)
                 retry-cnt @retry-counter
                 _ (reset! retry-counter 0)]
-            (info "-> " cnt " <-")
+            (info "-> " cnt ", retries: " retry-cnt " <-")
             (r/send-event client {:service "onyx-retry" :state "ok" :metric retry-cnt :tags ["benchmark"]})
             (r/send-event client {:service "onyx" :state "ok" :metric cnt :tags ["benchmark"]}))
           (recur))


Checkpoint

Checkpoint

Signed-off-by: Gregory Haskins <640d9fe47775e6723f0355b7315e38f7d98d3539@gmail.com>

--- src/obcc/build/interface.clj
+++ src/obcc/build/interface.clj
@@ -109,6 +109,11 @@
   (let [msgs (->> ast (map (fn [[fqname ast]] (buildmessages fqname ast))) flatten)]
     (into {} (map #(vector (.name %) %) msgs))))

+;;-----------------------------------------------------------------
+;; generate protobuf output - compiles the interfaces into a
+;; protobuf specification, suitable for writing to a file or
+;; passing to protoc
+;;-----------------------------------------------------------------
 (defn generateproto [path config]
   (let [asts (compileall path config)
         messages (buildallmessages asts)
@@ -118,6 +123,10 @@
     (.add template "messages" messages)
     (.render template)))

+;;-----------------------------------------------------------------
+;; compile - generates a protobuf specification and writes it to
+;; the default location in the build area
+;;-----------------------------------------------------------------
 (defn compile [path config]
   (let [protobuf (generateproto path config)
         protopath (io/file path "build/proto/project.proto")]


Fix handling of publications in gc-publications

--- src/onyx/messaging/aeron.clj
+++ src/onyx/messaging/aeron.clj
@@ -190,7 +190,7 @@

 ;; FIXME: gc'ing publications could be racy if a publication is grabbed
 ;; just as it is being gc'd - though it is unlikely
-(defn gc-publications [publications connections opts]
+(defn gc-publications [publications opts]
   (let [interval (arg-or-default :onyx.messaging/peer-link-gc-interval opts)
         idle (arg-or-default :onyx.messaging/peer-link-idle-timeout opts)]
     (loop []
@@ -202,10 +202,10 @@
                              (filter (fn [[k v]] (>= (- t ^long @(:last-used v)) idle))
                                      snapshot))]
           (doseq [k to-remove]
-            (let [pub (:publication (snapshot k))
-                  conn (@connections k)]
+            (let [pub-manager (:publication (snapshot k))
+                  pub (:publication pub-manager)
+                  conn (:connection pub-manager)]
               (swap! publications dissoc k)
-              (swap! connections dissoc k)
               (.close ^Publication pub)
               (.close ^Aeron conn))))
         (catch InterruptedException e
@@ -214,7 +214,7 @@
           (fatal e)))
       (recur))))

-(defrecord AeronPeerGroup [opts publications connections subscribers subscriber-count compress-f decompress-f send-idle-strategy]
+(defrecord AeronPeerGroup [opts publications subscribers subscriber-count compress-f decompress-f send-idle-strategy]
   component/Lifecycle
   (start [component]
     (taoensso.timbre/info "Starting Aeron Peer Group")
@@ -236,12 +236,11 @@
           decompress-f (or (:onyx.messaging/decompress-fn opts) decompress)
           virtual-peers (atom (pm/vpeer-manager))
           publications (atom {})
-          connections (atom {})
           subscriber-count (arg-or-default :onyx.messaging.aeron/subscriber-count opts)
           subscribers (mapv (fn [stream-id]
                               (start-subscriber! bind-addr port stream-id virtual-peers decompress-f receive-idle-strategy))
                             (range subscriber-count))
-          pub-gc-thread (future (gc-publications publications connections opts))]
+          pub-gc-thread (future (gc-publications publications opts))]
       (assoc component
              :pub-gc-thread pub-gc-thread
              :bind-addr bind-addr
@@ -251,7 +250,6 @@
              :media-driver-context media-driver-context
              :media-driver media-driver
              :publications publications
-             :connections connections
              :virtual-peers virtual-peers
              :compress-f compress-f
              :decompress-f decompress-f
@@ -260,7 +258,7 @@
              :subscriber-count subscriber-count
              :subscribers subscribers)))

-  (stop [{:keys [media-driver media-driver-context subscribers publications connections] :as component}]
+  (stop [{:keys [media-driver media-driver-context subscribers publications] :as component}]
     (taoensso.timbre/info "Stopping Aeron Peer Group")
     (future-cancel (:pub-gc-thread component))
     (doseq [subscriber subscribers]


Fixes demonic off-by-one error.

Fixes demonic off-by-one error.

[ci skip]

--- src/onyx/messaging/aeron.clj
+++ src/onyx/messaging/aeron.clj
@@ -269,14 +269,14 @@

 (defn handle-message
   [result-state message-counter task-id src-peer-id [low high :as ticket] buffer offset length header]
-  (let [this-msg-index (get @message-counter src-peer-id 0)]
+  (let [this-msg-index (inc (get @message-counter src-peer-id -1))]
     (let [ba (byte-array length)
           _ (.getBytes buffer offset ba)
           res (messaging-decompress ba)]
       (if (and (= (:src-peer-id res) src-peer-id)
                (= (:dst-task-id res) task-id))
         (cond (< this-msg-index low)
-              (do (swap! message-counter assoc src-peer-id (inc this-msg-index))
+              (do (swap! message-counter assoc src-peer-id this-msg-index)
                   ControlledFragmentHandler$Action/CONTINUE)

               (> this-msg-index high)
@@ -284,12 +284,12 @@

               (instance? onyx.types.Barrier res)
               (do (swap! result-state conj (assoc res :msg-id this-msg-index))
-                  (swap! message-counter assoc src-peer-id (inc this-msg-index))
+                  (swap! message-counter assoc src-peer-id this-msg-index)
                   ControlledFragmentHandler$Action/BREAK)

               (instance? onyx.types.Leaf res)
               (do (swap! result-state conj res)
-                  (swap! message-counter assoc src-peer-id (inc this-msg-index))
+                  (swap! message-counter assoc src-peer-id this-msg-index)
                   ControlledFragmentHandler$Action/CONTINUE)

               :else (throw (ex-info "Failed to handle incoming Aeron message"


Schema check will catch this missing key upstream.

--- src/onyx/messaging/aeron.clj
+++ src/onyx/messaging/aeron.clj
@@ -176,10 +176,6 @@
                                     (catch Throwable e (fatal e))))]
     {:conn conn :subscription subscription :subscriber-fut subscriber-fut}))

-(defn opts->port [opts]
-  (or (:onyx.messaging/peer-port opts)
-      (throw (ex-info "Peer port (:onyx.messaging/peer-port) is not defined" opts))))
-
 (defrecord AeronPeerGroup [opts publication-group subscribers subscriber-count compress-f decompress-f send-idle-strategy]
   component/Lifecycle
   (start [component]
@@ -192,7 +188,7 @@

           bind-addr (common/bind-addr opts)
           external-addr (common/external-addr opts)
-          port (opts->port opts)
+          port (:onyx.messaging/peer-port opts)
           external-channel (aeron-channel external-addr port)
           poll-idle-strategy-config (arg-or-default :onyx.messaging.aeron/poll-idle-strategy opts)
           offer-idle-strategy-config (arg-or-default :onyx.messaging.aeron/offer-idle-strategy opts)


Support inline unions on graphql

Support inline unions on graphql

--- src-docs/com/wsscode/pathom/book/graphql/edn_converter.cljs
+++ src-docs/com/wsscode/pathom/book/graphql/edn_converter.cljs
@@ -84,7 +84,7 @@
                                                                [:entity/id
                                                                 (:user/name {::gql/on :app/User})
                                                                 {(:activity/user {::gql/on :app/User})
-                                                                 [:user/name]}]}]
+                                                                 [:user/email]}]}]
                                         "Recursive queries" [{:type
                                                               [:kind :name {:ofType 3}]}]
                                         "Mutation"          [{(users/create {:user/id 123 :user/name "Foo"})


steal: subject must be animate

steal: subject must be animate

--- src/babel/english/lexicon.cljc
+++ src/babel/english/lexicon.cljc
@@ -1672,7 +1672,8 @@

    "steal" {:synsem {:cat :verb
                      :sem {:pred :steal}
-                     :subcat {:2 {:cat :noun
+                     :subcat {:1 {:sem {:animate true}}
+                              :2 {:cat :noun
                                   :sem {:physical-object true
                                         :human false
                                         :place false}}}}


Spawn multiple threads on the server to cut down on the need for client concurrency. Also support /gendata for increasing heapsize.

--- src/org/scode/httpgctest.clj
+++ src/org/scode/httpgctest.clj
@@ -17,14 +17,26 @@

 (defn serve-gengarbage [request]
   (do
-    (gen-recursive-garbage 50 [])
+    (doseq [future (doall (for [i (range 10)] (future (gen-recursive-garbage 50 []))))]
+      @future)
     {:status 200
      :headers {}
      :body "Garbage all around."}))

+(def data (ref ["data"]))
+
+(defn serve-gendata [request]
+  (dosync
+   (alter data #(concat %1 (repeat (count %1) "data"))))
+  {:status 200
+   :headers {}
+   :body (str "size is now " (count @data))})
+
 (defroutes greeter
   (GET "/gengarbage"
-       serve-gengarbage))
+       serve-gengarbage)
+  (GET "/gendata"
+       serve-gendata))

 (defn -main [& args]
   (run-server {:port 9191}


Create env-* duplicates of all env-gen helper fns to make it easier to find them.

--- src/overtone/sc/envelope.clj
+++ src/overtone/sc/envelope.clj
@@ -134,7 +134,14 @@
               (concat [(first levels) (count durations) release-node loop-node]
                       (interleave (rest levels) durations shape-ids curve-ids))))))

-(defunk triangle
+(defmacro defunk-env [fn-name docstring args & body]
+  `(do
+
+     (defunk ~(symbol (str "env-" fn-name)) ~docstring ~args ~@body)
+     (defunk ~fn-name ~docstring ~args ~@body)
+     ))
+
+(defunk-env triangle
   "Create a triangle envelope description array suitable for use with the
   env-gen ugen"
   [dur 1 level 1]
@@ -142,34 +149,34 @@
     (let [dur (* dur 0.5)]
       (envelope [0 level 0] [dur dur]))))

-(defunk sine
+(defunk-env sine
   "Create a sine envelope description suitable for use with the env-gen ugen"
   [dur 1 level 1]
   (with-overloaded-ugens
     (let [dur (* dur 0.5)]
       (envelope [0 level 0] [dur dur] :sine))))

-(defunk perc
+(defunk-env perc
   "Create a percussive envelope description suitable for use with the env-gen
   ugen"
   [attack 0.01 release 1 level 1 curve -4]
   (with-overloaded-ugens
     (envelope [0 level 0] [attack release] curve)))

-(defunk lin-env
+(defunk-env lin
   "Create a trapezoidal envelope description suitable for use with the env-gen
   ugen"
   [attack 0.01 sustain 1 release 1 level 1 curve :linear]
   (with-overloaded-ugens
     (envelope [0 level level 0] [attack sustain release] curve)))

-(defunk cutoff
+(defunk-env cutoff
   "Create a cutoff envelope description suitable for use with the env-gen ugen"
   [release 0.1 level 1 curve :linear]
   (with-overloaded-ugens
     (envelope [level 0] [release] curve 0)))

-(defunk dadsr
+(defunk-env dadsr
   "Create a delayed attack decay sustain release envelope suitable for use with
   the env-gen ugen"
   [delay-t 0.1
@@ -180,7 +187,7 @@
       (map #(+ %1 bias) [0 0 level (* level sustain) 0])
       [delay-t attack decay release] curve)))

-(defunk adsr
+(defunk-env adsr
   "Create an attack decay sustain release envelope
   suitable for use as the envelope parameter of the
   env-gen ugen.
@@ -225,7 +232,7 @@
       (map #(+ %1 bias) [0 level (* level sustain) 0])
       [attack decay release] curve 2)))

-(defunk asr
+(defunk-env asr
   "Create an attack sustain release envelope sutable for use with the env-gen
   ugen"
   [attack 0.01 sustain 1 release 1 curve -4]


transforming the ed variable into a function taking a file-name as an argument, this way enabling compilation without existing_data.json

--- src/bitfondue/migrations.clj
+++ src/bitfondue/migrations.clj
@@ -23,9 +23,11 @@
   (repl/rollback (load-config)))

-;; migrate the existing data into the new database
-;; parse the json line entries into a collection of maps
-(def ed (with-open [rdr (clojure.java.io/reader "existing_data.json")]
-          (doall (->> rdr
-                      line-seq
-                      (map #(parse-string % true))))))
+;; Migrate the existing data into the new database
+(defn parse-json-line-items
+  "Parses the current .json line item file into a collection of maps"
+  [file-name]
+  (with-open [rdr (clojure.java.io/reader file-name)]
+    (doall (->> rdr
+                line-seq
+                (map #(parse-string % true))))))


vp-aux-phrasal-complement: essere=false

vp-aux-phrasal-complement: essere=false

--- src/babel/italiano/grammar.cljc
+++ src/babel/italiano/grammar.cljc
@@ -407,7 +407,8 @@
                               root-is-comp-root
                               {:rule "vp-aux-phrasal-complement"
                                :head {:phrasal false
-                                      :synsem {:aux true
+                                      :synsem {:essere false
+                                               :aux true
                                                :sem {:obj {:top :top}}}}
                                :comp {:phrasal true}
                                :synsem {:aux true


Improve performance of function

Improve performance of function

--- src/play_clj/core_render.clj
+++ src/play_clj/core_render.clj
@@ -25,7 +25,7 @@
   (if (isa? (type layer) MapLayer)
     layer
     (->> (tiled-map-layers screen)
-         (filter #(= layer (.getName ^MapLayer %)))
+         (drop-while #(not= layer (.getName ^MapLayer %)))
          first)))

 (defn tiled-map-layer-name


slightly bigger

slightly bigger

--- src/clj/just_married/css.clj
+++ src/clj/just_married/css.clj
@@ -113,7 +113,7 @@
    [:.timeline__time {:padding-right "10px"
                       :font-weight "bolder"}]

-   [:.timeline__icon {:width "20px"
+   [:.timeline__icon {:width "22px"
                       :padding-right "5px"}]

    [:ul {:list-style "none"}]


Remove obsolete persistence module (it should be rewrited from scratch)

--- src/clj/pfrt/persistence.clj
+++ src/clj/pfrt/persistence.clj
@@ -1,24 +0,0 @@
-(ns pfrt.persistence
-  (:require [jdbc]
-            [pfrt.util :as util])
-  (:gen-class))
-
-(def dbspec {:subprotocol "h2" :subname "file:p0rnstats.h2.db"})
-
-(defn bootstrap
-  []
-  (let [sql (str "CREATE TABLE IF NOT EXISTS stats ("
-                 "  data text, "
-                 "  created_at timestamp default now());")]
-    (jdbc/with-connection dbspec conn
-      (jdbc/with-transaction conn
-        (jdbc/execute! sql)))))
-
-
-(defn persist
-  [dataref]
-  (let [data  (deref dataref)
-        sql   "INSERT INTO stats (data) VALUES (?);"]
-    (jdbc/with-connection dbspec conn
-      (jdbc/with-transaction conn
-        (jdbc/execute-prepared! sql [(util/json-dumps data)])))))


Caching for heroku on file responses

Caching for heroku on file responses

--- src/clj_crud/system/ring.clj
+++ src/clj_crud/system/ring.clj
@@ -92,6 +92,17 @@
                     keyword-params/wrap-keyword-params
                     params/wrap-params
                     (resource/wrap-resource "/")
+                    ;; add Cache-Control:public, max-age=31536000 to
+                    ;; files, to improve heroku performance, should be
+                    ;; in wrap-resource
+                    ((fn [handler]
+                       (fn wrap-cache-control [req]
+                         (let [res (handler req)]
+                           (info "File res: " res)
+                           (if (and (= :get (:request-method req))
+                                    (instance? java.io.File (:body res)))
+                             (assoc-in res [:headers "Cache-Control"] "public, max-age=31536000")
+                             res)))))
                     file-info/wrap-file-info
                     content-type/wrap-content-type
                     wrap-accept-uri


refine validation error reporting

refine validation error reporting

--- src/clj_money/validation.clj
+++ src/clj_money/validation.clj
@@ -39,7 +39,7 @@
       (assoc validated ::errors (->> errors
                                      (group-by first)
                                      (map (fn [[k tuples]]
-                                            [k (map second tuples)]))
+                                            [k (map second tuples)])) ; TODO don't double wrap vectors in lists
                                      (into {})))
       validated)))

@@ -66,7 +66,11 @@
   "Accepts a tuple containg an attribute key and a schema
   violation expresion and returns a human-friendly message"
   [[attr-key expr]]
-  [attr-key (str (humanize attr-key) " " (friendly-message expr))])
+  (let [humanized (if (vector? expr)
+                    (vec (map #(when %
+                                 (into {} (map full-humanized-message %))) expr))
+                    (str (humanize attr-key) " " (friendly-message expr)))]
+    [attr-key humanized]))

 (defn apply-schema
   "A rule function that coerces and applies a schema to a model"
@@ -75,12 +79,13 @@
                                 (coerce/first-matcher [int-matcher
                                                        nil-matcher
                                                        coerce/json-coercion-matcher]))
-        result (coercer model)]
+        result (coercer model)
+        errors (if (schema-utils/error? result)
+               (vec (map full-humanized-message
+                         (schema-utils/error-val result)))
+               [])]
     {:model (dissoc result :error)
-     :errors (if (schema-utils/error? result)
-               (map full-humanized-message
-                    (schema-utils/error-val result))
-               [])}))
+     :errors errors}))

 (defn has-error?
   "Returns true if the specified model contains validation errors"
@@ -103,4 +108,4 @@
     (get-in model (concat [::errors] attr-keys))
     (->> (get model ::errors)
          (mapcat second)
-         (into []))))
+         vec)))


rework nav for current entity

rework nav for current entity

--- src/clj_money/web/shared.clj
+++ src/clj_money/web/shared.clj
@@ -1,11 +1,14 @@
 (ns clj-money.web.shared
   (:require [clojure.tools.logging :as log]
             [clojure.set :as set]
+            [clojure.string :as string]
+            [environ.core :refer [env]]
             [hiccup.core :refer :all]
             [hiccup.page :refer :all]
             [clojure.string :as s]
             [cemerick.friend :as friend]
-            [clj-money.models.users :as users])
+            [clj-money.models.users :as users]
+            [clj-money.models.entities :as entities])
   (:use clj-money.inflection))

 (defn glyph-link
@@ -36,10 +39,48 @@
                                    (s/join " " (glyph-button-css options)))
                             (dissoc :size :level))))

+(defn- authenticated-user-nav
+  "Renders the top level navigation for the authenticated user"
+  [user entity]
+  (html
+    [:li
+     [:a {:href "#"} (users/full-name user)]]
+    [:li.dropdown {:role "presentation"}
+     [:a.dropdown-toggle {:href (str "/entities/" (:id entity) "/accounts")
+                          :data-toggle "dropdown"
+                          :role "button"
+                          :aria-haspopup "true"
+                          :aria-expanded "false"}
+      (:name entity)
+      [:span.caret]]
+     [:ul.dropdown-menu
+      (let [other-entities (remove #(= (:id %) (:id entity)) (entities/select (env :db) (:id user)))]
+        (when (seq other-entities)
+          (concat
+            (map #(vector :li
+                          [:a {:href (str "/entities/" (:id %) "/accounts")}
+                           (:name %)])
+                 other-entities)
+            [[:li.divider {:role "separator"}]])))
+      [:li
+       [:a {:href "/entities"} "Manage entities"]]]]
+    [:li
+     (glyph-link :log-out "/logout" {:title "Click here to sign out."
+                                     :data-method :post})]))
+
+(defn- unauthenticated-nav
+  "Renders the top level navigation for a non-authenticated user"
+  []
+  (html
+    [:li
+     [:a {:href "/signup"} "Sign up"]]
+    [:li
+     (glyph-link :log-in "/login" {:title "Click here to sign in."})]))
+
 ; TODO Wrap this up in a sharable library
-(defn bootstrap-nav
+(defn- bootstrap-nav
   "Renders the site navigation using the structure for twitter bootstrap"
-  [items]
+  [items user entity]
   [:nav.navbar.navbar-default
    [:div.container
     [:div.navbar-header
@@ -61,27 +102,28 @@
            items)]
      [:div.navbar-right
       [:ul.nav.navbar-nav.navbar-right
-       (if-let [user (friend/current-authentication)]
-         (html
-           [:li
-            [:a {:href "#"} (users/full-name user)]]
-           [:li
-            (glyph-link :log-out "/logout" {:title "Click here to sign out."
-                                            :data-method :post})])
-         (html
-           [:li
-            [:a {:href "/signup"} "Sign up"]]
-           [:li
-            (glyph-link :log-in "/login" {:title "Click here to sign in."})]))]]]]])
+       (if user
+         (authenticated-user-nav user entity)
+         (unauthenticated-nav))]]]]])
+
+(def item-templates
+  [{:url "/entities/:entity-id/accounts"     :caption "Accounts"}
+   {:url "/entities/:entity-id/transactions" :caption "Transactions"}
+   {:url "/entities/:entity-idcommodities"  :caption "Commodities"}])

 (defn primary-nav
   "Renders the site primary navigation"
-  []
-  (let [user (friend/current-authentication)
-        items [{:url "/entities"     :caption "Entities"}
-               {:url "/transactions" :caption "Transactions"}
-               {:url "/commodities"  :caption "Commodities"}]]
-    (bootstrap-nav items)))
+  [entity]
+  (if-let [user (friend/current-authentication)]
+    (if-let [entity (or entity (first (entities/select (env :db) (:id user))))]
+      (let [items (->> item-templates
+                       (map (fn [item]
+                              (update-in item
+                                         [:url]
+                                         #(string/replace % ":entity-id" (str (:id entity)))))))]
+        (bootstrap-nav items user entity))
+      (bootstrap-nav [] user nil))
+    (bootstrap-nav [] nil nil)))

 (defn render-alerts
   "Renders notifications as HTML"
@@ -114,13 +156,13 @@
       "<!-- jQuery -->"
       [:script {:src "/js/jquery-3.1.0.min.js"}]
       [:script {:src "/js/jquery-startup.js"}]
+      [:script {:src "/js/bootstrap.min.js"}]

       "<!-- Bootstrap core CSS -->"
       [:link {:rel "stylesheet" :href "/css/bootstrap.min.css"}]
-      [:link {:rel "stylesheet" :href "/css/bootstrap-theme.min.css"}]
-      [:script  {:src "https://ajax.googleapis.com/ajax/libs/jquery/1.11.3/jquery.min.js"}]]
+      [:link {:rel "stylesheet" :href "/css/bootstrap-theme.min.css"}]]
      [:body
-      (primary-nav)
+      (primary-nav (:entity options))
       [:div.container {:style "margin-top: 2em;"}
        (html
          [:h1#page-title page-title]


remove trace output

remove trace output

--- src/cljs/clj_money/data.cljs
+++ src/cljs/clj_money/data.cljs
@@ -20,9 +20,6 @@

 (defn- get-models
   [path success-fn]
-
-  (.log js/console "get-models " path)
-
   (go (let [response (<! (http/get path {:headers {"Content-Type" "application/json"
                                                    "Accept" "application/json"}}))]
         (if (= 200 (:status response))
@@ -60,7 +57,4 @@

 (defn get-commodities
   [entity-id success-fn]
-
-  (.log js/console "get-commodities " entity-id)
-
   (get-models (path :entities entity-id :commodities) success-fn))


prompt login instead of register when auth required

--- src/cljs/netrunner/auth.cljs
+++ src/cljs/netrunner/auth.cljs
@@ -18,7 +18,7 @@
 (defn authenticated [f]
   (if-let [user (:user @app-state)]
     (f user)
-    (.modal (js/$ "#register-form") "show")))
+    (.modal (js/$ "#login-form") "show")))

 (defn logged-menu [user owner]
   (om/component