Made test OS independent.

Made test OS independent.

--- test/blutwurst/core_test.clj
+++ test/blutwurst/core_test.clj
@@ -74,7 +74,7 @@
     (with-redefs-fn {#'core/exit-with-code (fn [c] c)}
     #(let [output (with-out-str (core/-main "app.jar" "--darby-ogill-and-the-little-people" "sputnik"))]
       (pprint output)
-      (is (= "Unknown option: \"--darby-ogill-and-the-little-people\"\n" output))
+      (is (= "Unknown option: \"--darby-ogill-and-the-little-people\"" (string/trim output)))
       )))

   (testing "End to end flow."


Don't return the string "null" as the body for JSON when no body was provided.

--- src/posthere/pretty_print.clj
+++ src/posthere/pretty_print.clj
@@ -115,7 +115,9 @@
   (pretty-print
     request
     json?
-    (fn [] (generate-string (parse-string (:body request)) {:pretty true}))
+    (fn [] (if (nil? (:body request))
+                  nil
+                  (generate-string (parse-string (:body request)) {:pretty true})))
     json-encoded))

 (defn pretty-print-xml


fix utils tests

fix utils tests


Fix to taxi angelic

Fix to taxi angelic

--- src/exp/taxi.clj
+++ src/exp/taxi.clj
@@ -110,12 +110,12 @@
                               (let [cx (env/get-var s ['atx])
                                     cy (env/get-var s ['aty])]
                                 {(env/set-var (env/set-var s ['atx] dx) ['aty] dy)
-                                 (- 0 (abs (- dx sx)) (abs (- dy sy)))}))
+                                 (- 0 (util/abs (- dx cx)) (util/abs (- dy cy)))}))
                             (pessimistic-map [s]
                               (let [cx (env/get-var s ['atx])
                                     cy (env/get-var s ['aty])]
                                 {(env/set-var (env/set-var s ['atx] dx) ['aty] dy)
-                                 (- 0 (abs (- dx sx)) (abs (- dy sy)))})))
+                                 (- 0 (util/abs (- dx cx)) (util/abs (- dy cy)))})))

 (deftype ServeHLA [env pass]
   env/Action                (action-name [] ['serve pass])


put gangway's publish! fn in system

put gangway's publish! fn in system

--- src/galleon.clj
+++ src/galleon.clj
@@ -7,7 +7,8 @@
             [clojure.edn]
             [gangway.util :as gw-util]
             [gangway.worker :as gw-worker]
-            [datomic-schematode.core :as schematode])
+            [datomic-schematode.core :as schematode]
+            [gangway.publish :as gw-publish])
   (:import (java.io File)))

 (def default-config-path "/etc/galleon.edn")
@@ -21,7 +22,8 @@

 (defn load-system-config
   [path]
-  {:datomic-url "datomic:mem://galleon-test"}
+  {:datomic-url "datomic:mem://galleon-test"
+   :publish-fn gw-publish/publish!}
   #_(if (file-exists? path)
     (clojure.edn/read-string (slurp path))
     (throw (Exception. (str "Config file missing: " path)))))


Removed duplicated require causing build error with shadow-build

--- src/re_frame/interceptor.cljc
+++ src/re_frame/interceptor.cljc
@@ -1,8 +1,7 @@
 (ns re-frame.interceptor
   (:require
-    [re-frame.interop :refer [ratom?]]
     [re-frame.loggers :refer [console]]
-    [re-frame.interop :refer [empty-queue debug-enabled?]]))
+    [re-frame.interop :refer [ratom? empty-queue debug-enabled?]]))

 (def mandatory-interceptor-keys #{:id :after :before})


Explicitly shut down TCP threadpools.

Explicitly shut down TCP threadpools.

--- src/riemann/transport/tcp.clj
+++ src/riemann/transport/tcp.clj
@@ -85,10 +85,12 @@
   (start! [this]
           (locking this
             (when-not @killer
-              (let [bootstrap (ServerBootstrap.
+              (let [boss-pool (Executors/newCachedThreadPool)
+                    worker-pool (Executors/newCachedThreadPool)
+                    bootstrap (ServerBootstrap.
                                 (NioServerSocketChannelFactory.
-                                  (Executors/newCachedThreadPool)
-                                  (Executors/newCachedThreadPool)))
+                                  boss-pool
+                                  worker-pool))
                     all-channels (DefaultChannelGroup.
                                    (str "tcp-server " host ":" port))
                     cpf (channel-pipeline-factory
@@ -116,6 +118,8 @@
                         (fn []
                           (-> all-channels .close .awaitUninterruptibly)
                           (.releaseExternalResources bootstrap)
+                          (.shutdown worker-pool)
+                          (.shutdown boss-pool)
                           (info "TCP server" host port "shut down")))))))

   (stop! [this]


fixes else clauses to condp (#531)

fixes else clauses to condp (#531)

--- waiter/src/waiter/curator.clj
+++ waiter/src/waiter/curator.clj
@@ -47,7 +47,7 @@
   (condp = serializer
     :nippy (nippy/freeze data)
     :none data
-    :else (throw (ex-info "Unknown serializer" {:serializer serializer}))))
+    (throw (ex-info "Unknown serializer" {:serializer serializer}))))

 (defn deserialize
   [serializer data]
@@ -61,7 +61,7 @@
                                (-> (ex-data e)
                                    (update-in [:opts :password] (fn [password] (when password "***"))))))))
     :none data
-    :else (throw (ex-info "Unknown serializer" {:serializer serializer}))))
+    (throw (ex-info "Unknown serializer" {:serializer serializer}))))

 (defn create-path
   ([^CuratorFramework curator path & {:keys [mode noop-on-exists? create-parent-zknodes?]


fixed test namespace problem

fixed test namespace problem

--- dev/cljs/user.cljs
+++ dev/cljs/user.cljs
@@ -10,7 +10,6 @@
 (defn run-all-tests []
   (run-tests
     'smooth-test.async-spec
-    'smooth-test.behavior-spec
     ))

 (defn on-load []


better naming

better naming

--- src-cljs/cljsbuild_ui/pages/main.cljs
+++ src-cljs/cljsbuild_ui/pages/main.cljs
@@ -220,6 +220,12 @@
 (defn- letter? [s]
   (and (string? s)
        (.test #"[a-zA-Z]" s)))
+
+;; if dir is "C:\" on Windows, we don't need the extra path separator
+(defn- print-dir [dir]
+  (str dir
+       (when (not= (last dir) path-separator)
+          path-separator)))

 ;;------------------------------------------------------------------------------
 ;; State-effecting
@@ -702,7 +708,7 @@
 (sablono/defhtml modal-overlay [click-fn]
   [:div.modal-overlay-120d3 {:on-click click-fn}])

-(sablono/defhtml new-project-step-1 []
+(sablono/defhtml new-or-existing-project []
   [:div.modal-body-fe4db
     [:div.modal-chunk-2041a
       [:button.big-btn-a5d18 {:on-click click-new-project-btn}
@@ -717,12 +723,6 @@
     [:div.modal-bottom-050c3
       [:span.bottom-link-7d8d7 {:on-click close-add-project-modal}
         "cancel"]]])
-
-;; if dir is "C:\" on Windows, we don't need the extra path separator
-(defn- print-dir [dir]
-  (str dir
-       (when (not= (last dir) path-separator)
-          path-separator)))

 (sablono/defhtml new-project-form [app-state]
   [:div.modal-body-fe4db
@@ -750,11 +750,11 @@
       [:span.bottom-link-7d8d7 {:on-click click-go-back-btn}
         "go back"]]])

-(sablono/defhtml new-project-step-3 [app-state]
+(sablono/defhtml creating-new-project [modal-state]
   [:div.modal-body-fe4db
     [:div.modal-chunk-2041a.creating-6d31a
       [:i.fa.fa-gear.fa-spin.icon-e70fb]
-      "Creating project " [:strong (:new-project-name app-state)]]])
+      "Creating project " [:strong (:new-project-name modal-state)]]])

 ;; TODO: implement this, GitHub Issue #46
 ; (sablono/defhtml new-project-step-4 []
@@ -819,30 +819,36 @@
                                      :prj-key prj-key))))
             (:builds-order prj))]])))

-;; TODO: need to extract only the keys we need for the modal form
-(quiescent/defcomponent NewProjectForm [app-state]
+(quiescent/defcomponent NewProjectForm [modal-state]
   (quiescent/on-mount
-    (new-project-form app-state)
+    (new-project-form modal-state)
     on-mount-new-project-form))

-(quiescent/defcomponent NewProjectModal [app-state]
-  (let [current-step (:new-project-step app-state)]
+(quiescent/defcomponent AddProjectModal [modal-state]
+  (let [current-step (:new-project-step modal-state)]
     (case current-step
-      1 (new-project-step-1)
-      2 (NewProjectForm app-state)
-      3 (new-project-step-3 app-state)
+      1 (new-or-existing-project)
+      2 (NewProjectForm modal-state)
+      3 (creating-new-project modal-state)
       nil)))

 (quiescent/defcomponent SettingsModal [app-state]
   (sablono/html
     [:div.modal-body-fe4db "Settings menu!"]))
+
+(def new-project-modal-keys
+  "These are all the keys we need in order to build the Add Project modal."
+  #{:new-project-dir
+    :new-project-error
+    :new-project-name
+    :new-project-step })

 (quiescent/defcomponent AppRoot [app-state]
   (sablono/html
     [:div
       (when (:add-project-modal-showing? app-state)
         (list (modal-overlay click-add-project-modal-overlay)
-              (NewProjectModal app-state)))
+              (AddProjectModal (select-keys app-state new-project-modal-keys))))
       (when (:settings-modal-showing? app-state)
         (list (modal-overlay click-settings-modal-overlay)
               (SettingsModal app-state)))


track clicking twitter link

track clicking twitter link

--- src-cljs/frontend/components/app.cljs
+++ src-cljs/frontend/components/app.cljs
@@ -4,6 +4,7 @@
             [clojure.set :as set]
             [clojure.string :as str]
             [datascript :as d]
+            [frontend.analytics :as analytics]
             [frontend.async :refer [put!]]
             [frontend.auth :as auth]
             [frontend.components.aside :as aside]
@@ -193,6 +194,7 @@
                    [:button.info-okay {:on-click #(cast! :overlay-info-toggled)}
                     "Okay, sounds good."]
                    [:a.info-twitter {:href "https://twitter.com/prcrsr_app"
+                                     :on-click #(analytics/track "Twitter link clicked" {:location "info overlay"})
                                      :title "Keep track of our changes on Twitter."
                                      :target "_blank"}
                     "What should we add next?"]]]


Fixed NullPointerException for comet messages with nulls in them

--- lib/compojure/cometd/cometd.clj
+++ lib/compojure/cometd/cometd.clj
@@ -1,6 +1,6 @@
 ;; compojure.cometd
 ;;
-;; An interface to Jetty's cometd implementation
+;; An interface to Jetty's cometd implementation.

 (ns compojure.cometd
   (:use    (compojure control
@@ -170,18 +170,24 @@
   ([client from channel message]
     (.deliver client from channel (clj->java message) nil)))

+(defn- seqable?
+  "Can x be turned into a Clojure sequence?"
+  [x]
+  (or (instance? Collection x)
+      (and x (.isArray (class x)))))
+
 (defn- java->clj
   "Turn a standard Java object into its equivalent Clojure data structure."
   [data]
   (cond
-    (or (instance? Collection data) (.isArray (class data)))
-      (vec (map java->clj data))
     (instance? Map data)
       (apply hash-map
         (mapcat
           #(list (keyword (java->clj (.getKey %)))
                  (java->clj (.getValue %)))
           data))
+    (seqable? data)
+      (vec (map java->clj data))
     otherwise
       data))


Fix render when permalink doesn't contain filename

--- src/io/perun.clj
+++ src/io/perun.clj
@@ -224,13 +224,16 @@
         options (merge +render-defaults+ *opts*)]
     (boot/with-pre-wrap fileset
       (let [pod   (pods fileset)
-            files (vals (get-perun-meta fileset))]
-        (doseq [file files]
+            files (get-perun-meta fileset)]
+        (doseq [[filename file] files]
           (let [html          (render-in-pod pod renderer file)
                 page-filepath (perun/create-filepath
                                 (:out-dir options)
-                                (or (perun/url-to-path (:permalink file))
-                                    (str (:filename file) ".html")))]
+                                ; If permalink ends in slash, append index.html to filepath
+                                (or (some-> (:permalink file)
+                                            (.replaceAll "/$" "/index.html")
+                                            perun/url-to-path)
+                                    filename))]
             (perun/create-file tmp page-filepath html)))
         (u/info "Render all pages\n")
         (commit fileset tmp)))))


minor formatting

minor formatting

--- src/io/perun.clj
+++ src/io/perun.clj
@@ -338,13 +338,13 @@

 (deftask atom-feed
   "Generate Atom feed"
-  [f filename    FILENAME    str "generated Atom feed filename"
-   o target      OUTDIR      str "the output directory"
-   _ filterer    FILTER     code "filter function"
-   t title       TITLE       str "feed title"
-   s subtitle    SUBTITLE    str "feed subtitle"
-   p description DESCRIPTION str "feed description"
-   l link        LINK        str "feed link"]
+  [f filename    FILENAME    str  "generated Atom feed filename"
+   o target      OUTDIR      str  "the output directory"
+   _ filterer    FILTER      code "filter function"
+   t title       TITLE       str  "feed title"
+   s subtitle    SUBTITLE    str  "feed subtitle"
+   p description DESCRIPTION str  "feed description"
+   l link        LINK        str  "feed link"]
   (let [pod (create-pod atom-deps)
         tmp (boot/tmp-dir!)]
     (boot/with-pre-wrap fileset


Ring middleware: housekeeping

Ring middleware: housekeeping

--- src/taoensso/carmine/ring.clj
+++ src/taoensso/carmine/ring.clj
@@ -2,24 +2,16 @@
   "Carmine-backed Ring session store. Adapted from clj-redis-session."
   {:author "Peter Taoussanis"}
   (:require [ring.middleware.session.store :as session-store]
-            [taoensso.carmine :as car])
-  (:import  [java.util UUID]))
+            [taoensso.carmine :as car :refer (wcar)]))

-(defn new-session-key [prefix] (str prefix ":" (UUID/randomUUID)))
-(defmacro wcar* [& body] `(car/wcar @~'conn-atom ~@body))
-
-(defprotocol ICarmineSessionStore (reset-conn [this conn]))
-
-(defrecord CarmineSessionStore [conn-atom prefix expiration]
-  ICarmineSessionStore (reset-conn [_ conn] (reset! conn-atom conn))
+(defrecord CarmineSessionStore [conn prefix ttl-secs]
   session-store/SessionStore
-  (read-session   [_ key] (or (when key (wcar* (car/get key))) {}))
-  (delete-session [_ key] (wcar* (car/del key)) nil)
+  (read-session   [_ key] (or (when key (wcar conn (car/get key))) {}))
+  (delete-session [_ key] (wcar conn (car/del key)) nil)
   (write-session  [_ key data]
-    (let [key (or key (new-session-key prefix))]
-      (if expiration
-        (wcar* (car/setex key expiration data))
-        (wcar* (car/set key data)))
+    (let [key (or key (str prefix ":" (java.util.UUID/randomUUID)))]
+      (wcar conn (if ttl-secs (car/setex key ttl-secs data)
+                              (car/set   key          data)))
       key)))

 (defn carmine-store
@@ -27,9 +19,9 @@
   to specify how long session data will survive after last write. When nil,
   sessions will never expire."
   [conn & [{:keys [key-prefix expiration-secs]
-            :or   {key-prefix       "carmine:session"
-                   expiration-secs  (str (* 60 60 24 30))}}]]
-  (->CarmineSessionStore (atom conn) key-prefix (str expiration-secs)))
+            :or   {key-prefix      "carmine:session"
+                   expiration-secs (* 60 60 24 30)}}]]
+  (->CarmineSessionStore conn key-prefix expiration-secs))

 (defn make-carmine-store ; 1.x backwards compatiblity
   "DEPRECATED. Use `carmine-store` instead."


refine budget permissions

refine budget permissions

--- src/clj_money/permissions/budgets.clj
+++ src/clj_money/permissions/budgets.clj
@@ -1,16 +1,15 @@
 (ns clj-money.permissions.budgets
   (:refer-clojure :exclude [update])
   (:require [clj-money.authorization :as authorization]
-            [clj-money.models.auth-helpers :refer [user-entity-ids
+            [clj-money.models.auth-helpers :refer [all-user-entity-ids
+                                                   user-granted-access?
                                                    user-owns-entity?]]
             [clj-money.models.budgets :as budgets]))

 (authorization/set-scope
   :budget
-  {:entity-id user-entity-ids})
+  {:entity-id all-user-entity-ids})

 (authorization/allow :budget user-owns-entity?)

-(authorization/allow :budget-item
-                     (fn [user resource _ {storage-spec :storage-spec :as context}]
-                       (user-owns-entity? user (budgets/find-by-id storage-spec (:budget-id resource)) context)))
+(authorization/allow :budget-item user-granted-access?)


wip docstring

wip docstring

--- src/cljc/commos/delta/compscribe.cljc
+++ src/cljc/commos/delta/compscribe.cljc
@@ -459,8 +459,9 @@
                            :mode :cache}))

 (defn compscriber
-  "Return a service that transforms subscriptions it makes at source,
-  an IStream implementation, so that they add up to one map.
+  "Return a service that makes, triggers and transforms subscriptions
+  at source, an IStream implementation, so that they add up to one
+  map.

   When making a subscription, specify endpoints you want to use and
   their desired nesting in spec so:


add Add button to imports/index

add Add button to imports/index

--- src/cljs/clj_money/views/imports.cljs
+++ src/cljs/clj_money/views/imports.cljs
@@ -45,7 +45,9 @@
       [:div.row
        [:div.col-md-6
         [:h1 "Imports"]
-        [import-table imports]]])))
+        [import-table imports]
+        (util/link-to "Add" "/imports/new" {:class "btn btn-primary"
+                                            :title "Click here to import a new entity from another system."}) ]])))

 (defn- append-dropped-files
   [event import-data]


Comment out success callouts

Comment out success callouts

--- src/discuss/components/clipboard.cljs
+++ src/discuss/components/clipboard.cljs
@@ -27,7 +27,7 @@
   [_ev]
   (let [clipboard-item (get-in @lib/app-state [:clipboard :current])]
     (lib/remove-class clipboard-item "bs-callout-info")
-    (lib/add-class clipboard-item "bs-callout-success")
+    #_(lib/add-class clipboard-item "bs-callout-success")
     (lib/update-state-item! :user :selection (fn [_] (.. clipboard-item -innerText)))))

 (defn allow-drop [ev]


bringing build up

bringing build up

--- src/district0x/server/api_server.cljs
+++ src/district0x/server/api_server.cljs
@@ -4,7 +4,7 @@
     [cljs.nodejs :as nodejs]
     [clojure.string :as string]
     [cognitect.transit :as transit]
-    [district0x.shared.utils as d0x-shared-utils :refer [collify parse-order-by-search-params]]
+    [district0x.shared.utils :as d0x-shared-utils :refer [collify parse-order-by-search-params]]
     [medley.core :as medley])
   (:require-macros [cljs.core.async.macros :refer [go]]))


fix assoc-in

fix assoc-in

--- src/main/clojure/cljs/core/macros.clj
+++ src/main/clojure/cljs/core/macros.clj
@@ -36,6 +36,6 @@
          (doall (map source-fn vars)))))

 (defmacro alias [[_ ns] [_ alias]]
-  (swap! env/*compiler* assoc-in [::namespaces (.getName *ns*) :requires]
-    alias ns)
+  (swap! env/*compiler* assoc-in
+    [::namespaces (.getName *ns*) :requires alias] ns)
   nil)


Correctly track allocation-version when GC'ing log.

--- src/onyx/api.clj
+++ src/onyx/api.clj
@@ -332,8 +332,7 @@

     (loop [replica (extensions/subscribe-to-log (:log client) ch)]
       (let [entry (<!! ch)
-            ;; FIXME, need version
-            new-replica (extensions/apply-log-entry entry replica)]
+            new-replica (extensions/apply-log-entry entry (assoc replica :version (:message-id entry)))]
         (if (and (= (:fn entry) :gc) (= (:id (:args entry)) id))
           (let [diff (extensions/replica-diff entry replica new-replica)]
             (extensions/fire-side-effects! entry replica new-replica diff {:id id :type :client :log (:log client)}))


whitespace

whitespace

--- src/babel/html.clj
+++ src/babel/html.clj
@@ -563,7 +563,6 @@
      (fn? arg)
      "λ"

-
      ;; TODO: should support objects of any otherwise-unsupported class: simply print out the classname in fixed-width font.
      (= (type arg) org.eclipse.jetty.server.HttpInput)
      "<tt>org.eclipse.jetty.server.HttpInput</tt>"


Add the ability to stop the router.

Add the ability to stop the router.

--- src/bide/core.cljs
+++ src/bide/core.cljs
@@ -163,11 +163,18 @@
                         (.setUseFragment true)
                         (.setEnabled true)))
             initial-token (-initial-token history)
-            initial-loc (-match initial-token)]
-        (e/listen history EventType.NAVIGATE -on-navigate)
+            initial-loc (-match initial-token)
+            lkey (e/listen history EventType.NAVIGATE -on-navigate)]
+
         (.replaceToken history initial-token)
         (apply on-navigate initial-loc)
+
         (specify! router
+          Object
+          (close [_]
+            (e/unlistenByKey lkey)
+            (.setEnabled history false))
+
           IRouter
           (-navigate [_ id params query]
             (when-let [path (resolve router id params query)]


Display want-chs.

Display want-chs.

--- src/cbfg/core.cljs
+++ src/cbfg/core.cljs
@@ -79,12 +79,23 @@

 (defn vis-html [vis actx]
   (if actx
-    ["
" (string/join ":" (last actx))
-     "
"
-     (map (fn [kv] ["
" (vis-html vis (first kv)) "
"])
-          (get-in vis [:actxs actx :children]))
-     "
"
-     "
"]
+    (let [d (get-in vis [:actxs actx])
+          children (:children d)
+          want-chs (:want-chs d)]
+      ["
" (string/join ":" (last actx))
+       "
"
+       (if (not-empty children)
+         ["
children...
"
+          (map (fn [kv] ["
" (vis-html vis (first kv)) "
"]) children)
+          "

"]
+         [])
+       (if (not-empty want-chs)
+         ["
waiting...
"
+          (map (fn [kv] ["
" (second kv) "
"]) want-chs)
+          "

"]
+         [])
+       "
"
+       "
"])
     "no actx"))

 (defn vis-init [cmds cmd-handlers]


[esm] only add module_loaded call for watch

not useful or required for compile

--- src/main/shadow/build/targets/esm.clj
+++ src/main/shadow/build/targets/esm.clj
@@ -252,7 +252,7 @@
             (spit js-file output)))))))

 (defn flush-unoptimized-module
-  [{:keys [build-modules] :as state}
+  [{:keys [worker-info build-modules] :as state}
    {:keys [module-id output-name exports prepend append sources depends-on] :as mod}]

   (let [target (data/output-file state output-name)]
@@ -295,7 +295,8 @@
                imports "\n"
                exports "\n"
                append "\n"
-               "shadow.cljs.devtools.client.env.module_loaded(\"" (name module-id) "\");")]
+               (when worker-info
+                 (str "shadow.cljs.devtools.client.env.module_loaded(\"" (name module-id) "\");")))]
       (io/make-parents target)
       (spit target out))


Clarify a minor error that occurs during recovery scenarios.


www/SearchResource.clj: use Solr highlighting for snippets

--- src/org/altlaw/www/SearchResource.clj
+++ src/org/altlaw/www/SearchResource.clj
@@ -22,6 +22,7 @@

 (defn log [this & args]
   (.. this getContext getLogger (info (apply str args))))
+

 ;;; PAGE NUMBERING

@@ -68,19 +69,25 @@

 ;;; RENDERING RESULTS

-(defn prepare-hit [doc]
-  (let [name (.getFieldValue doc "name")
+(defn get-snippets [highlights docid]
+  (when-let [h (get highlights (str docid))]
+    (get h "text")))
+
+(defn prepare-hit [highlights doc]
+  (let [docid (.getFieldValue doc "docid")
+        name (.getFieldValue doc "name")
         the-name (if (or (nil? name) (empty? name))
                    (str "Untitled #" (.getFieldValue doc "docid"))
                    name)]
-  {:docid (.getFieldValue doc "docid")
-   :url (format "/v1/cases/%s" (.getFieldValue doc "docid"))
+  {:docid docid
+   :url (format "/v1/cases/%s" docid)
    :size (when-let [size (.getFieldValue doc "size")]
            (int (Math/ceil (/ size 1024.0))))
    :date (date/format-long-date (.getFieldValue doc "date"))
    :court (courts/*court-names* (.getFieldValue doc "court"))
    :name (tmpl/h the-name)
-   :citations (map tmpl/h (.getFieldValues doc "citations"))}))
+   :citations (map tmpl/h (.getFieldValues doc "citations"))
+   :snippets (get-snippets highlights docid)}))

 (defn prepare-solr-results [solr-response]
   (let [docs (.getResults solr-response)]
@@ -89,7 +96,8 @@
      :total_hits (.getNumFound docs)
      :start_hit (if (zero? (.getNumFound docs)) 0 (inc (.getStart docs)))
      :end_hit (+ (.getStart docs) (count docs))
-     :hits (map prepare-hit docs)}))
+     :hits (map (partial prepare-hit (.getHighlighting solr-response))
+                docs)}))

 (defn html-exception-layout [data]
   (let [root-cause (loop [e (:exception data)]
@@ -262,6 +270,13 @@
 (defn apply-sort-options [solr-query this]
   (.setSortField solr-query (get-sort-field this) SolrQuery$ORDER/desc))

+(defn apply-highlight-options [solr-query]
+  (doto solr-query
+    (.setHighlight true)
+    (.setHighlightFragsize 120)
+    (.setHighlightRequireFieldMatch true)
+    (.setHighlightSnippets 3)))
+
 (defmulti get-solr-query (fn [this type] type))

 (defmethod get-solr-query :simple [this type]
@@ -270,7 +285,8 @@
       (log this "Preparing simple search for " (pr-str q))
       (doto (SolrQuery. q)
         (.setQueryType "dismax")
-        (apply-sort-options this)))))
+        (apply-sort-options this)
+        (apply-highlight-options)))))

 (defmethod get-solr-query :boolean [this type]
   (let [params (get-query-params this)]
@@ -278,7 +294,8 @@
       (log this "Preparing boolean search for " (pr-str q))
       (doto (SolrQuery. q)
         (.setQueryType "standard")
-        (apply-sort-options this)))))
+        (apply-sort-options this)
+        (apply-highlight-options)))))

 (defmethod get-solr-query :citation [this type]
   (let [params (get-query-params this)]


Refactor async-pipeline-go scenario.

Refactor async-pipeline-go scenario.

--- src/dsbdp/main.clj
+++ src/dsbdp/main.clj
@@ -246,23 +246,23 @@
                                 (println "Starting async-pipeline-go counting.")
                                 (async/go
                                   (loop []
-                                    (async/<! in-chan)
+                                    (async/<! out-chan)
                                     (.inc ^Counter out-cntr)
                                     (recur))))
-;          async-pipeline (if
-;                           (and
-;                             (.contains scenario "-async-pipeline")
-;                             (not (nil? in-data)))
-;                           (async/pipeline
-;                             8
-;                             out-chan
-;                             (fn [rf]
-;                               (fn ([] (rf))
-;                               ([result] (rf result))
-;                               ([result data]
-;                                 (let [ret (direct-proc-fn data)]
-;                                   (rf result (if (nil? ret) 1 ret))))))
-;                             in-chan))
+          async-pipeline (if
+                           (and
+                             (.contains scenario "-async-pipeline")
+                             (not (nil? in-data)))
+                           (async/pipeline
+                             8
+                             out-chan
+                             (fn [rf]
+                               (fn ([] (rf))
+                               ([result] (rf result))
+                               ([result data]
+                                 (let [ret (direct-proc-fn data)]
+                                   (rf result (if (nil? ret) 1 ret))))))
+                             in-chan))
           self-adaptivity-cfg (options :self-adaptivity-cfg)
           self-adaptivity-controller (if (not (nil? self-adaptivity-cfg))
                                        (create-self-adaptivity-controller


fix let binding error

fix let binding error

--- src/quiescent.cljs
+++ src/quiescent.cljs
@@ -82,9 +82,9 @@
         (wrapped-lifecycle-method (. f apply *component* args))))
     (let [react-component (.createClass js/React react-map)
           q-wrapper (fn [value & statics]
-                      (.createElement js/React react-component (assemble-props value statics)))
-          (when-some [displayName (.-displayName react-map)]
-            (set! (.-displayName q-wrapper) displayName))]
+                      (.createElement js/React react-component (assemble-props value statics)))]
+      (when-some [displayName (.-displayName react-map)]
+        (set! (.-displayName q-wrapper) displayName))
       (when-some [example (:exampleArg m)]
         (set! (.-exampleArg q-wrapper) example))
       (when-some [doc (:doc m)]


0.13.x uses .render not .renderComponent

--- src/quiescent.cljs
+++ src/quiescent.cljs
@@ -97,7 +97,7 @@
   "Given a ReactJS component, immediately render it, rooted to the
   specified DOM node."
   [component node]
-  (.renderComponent js/React component node))
+  (.render js/React component node))

 (defn set-state
   "Set the \"value\" key of a component's state."


bits of typography

bits of typography

--- src/resume/css.clj
+++ src/resume/css.clj
@@ -2,23 +2,35 @@
   (:require
    [cljss.core :as cljss]
    [cljss.units.length :as len]
-   [cljss.grid :as grid]))
+   [cljss.grid :as grid]
+   [cljss.parse]))

+(defmethod cljss.parse/consume-properties clojure.lang.IPersistentSet [[fst scd & rst] node]
+  (let [new-props (zipmap fst (repeat scd))]
+    (cljss.parse/consume-properties (cons new-props rst) node)))

 (def base-font-size 1)
-
+(def font-headings "\"Helvetica Neue\", Helvetica, Arial, sans-serif")
+(def font-text "Georgia, \"Times New Roman\", Times, serif")

 (cljss/defrules typo
   (cljss/css-comment "----- Typography -------------")

-  [:body :font-size (len/em 1.1)]
+
+  [:body
+     :font-size (len/em 1.1)
+     :font-family font-text]
+
+  [#{:h1 :h2 :h3 :h4 :h5} :font-family font-headings]
+
+

   [:h1
-       :font-size (len/em 2)
-       :text-align :center
+     :font-size (len/em 2)
+     :text-align :center

-       [:.p-summary
-            :font-size (len/em 0.666)]]
+   [:.p-summary
+      :font-size (len/em 0.666)]]

   [:h2 :font-size (len/em 1.5)]

@@ -129,17 +141,3 @@
   layout)

-
-
-
-(defn compile-rules []
-  (cljss/css all-rules))
-
-
-(defn make-rules []
-  (spit "out/style.css"
-        (compile-rules)))
-
-;(make-rules)
-
-


CMR-1195: Add unit tests for entry title constraint

--- metadata-db-app/test/cmr/metadata_db/test/services/concept_constraints.clj
+++ metadata-db-app/test/cmr/metadata_db/test/services/concept_constraints.clj
@@ -86,21 +86,25 @@

 (deftest entry-title-unique-constraint-test
-  ;;TODO TESTS
-  ;; other entry title that's deleted is ok
-  ;; other entry title used in another provider is ok
-  ;; other entry title reused not ok
-  ;; other entry title with same concept id and earlier revision id is ok
-  ;; no other entry titles is ok
-  ;; different entry titles is ok
-
   (let [test-concept (make-coll-concept "PROV1" "C1-PROV1" 5 {:entry-title "ET1"})
         is-valid (partial assert-valid cc/entry-title-unique-constraint test-concept)
         not-valid #(apply assert-invalid %1 cc/entry-title-unique-constraint test-concept %2)]

     (testing "valid cases"
       (testing "with empty database"
-        (is-valid)))
+        (is-valid))
+      (testing "another collection with entry title that is deleted is valid"
+        (let [other-tombstone (make-coll-tombstone "PROV1" "C2-PROV1" 2 {:entry-title "ET1"})]
+          (is-valid other-tombstone)))
+      (testing "another provider with the same entry title is valid "
+        (let [other-concept (make-coll-concept "PROV2" "C1-PROV1" 5 {:entry-title "ET1"})]
+          (is-valid other-concept)))
+      (testing "same concept id but earlier revision id is valid"
+        (let [other-concept (make-coll-concept "PROV1" "C1-PROV1" 4 {:entry-title "ET1"})]
+          (is-valid other-concept)))
+      (testing "different entry titles are valid"
+        (let [other-concept (make-coll-concept "PROV1" "C1-PROV1" 5 {:entry-title "ET2"})]
+          (is-valid other-concept))))

     (testing "invalid cases"
       (testing "same entry title"


add fn slam-in

add fn slam-in

--- src/hatch.clj
+++ src/hatch.clj
@@ -8,6 +8,15 @@
   "Slams two keywords together into one namespaced keyword"
   [ns n]
   (keyword (name ns) (name n)))
+
+(defn slam-in
+  "Slams a namespace on a key in a map"
+  [m ns k]
+  (if (nil? (k m))
+      m
+      (-> m
+          (assoc (slam ns k) (k m))
+          (dissoc k))))

 (defn prefix-keys
   "Prefix all keys in a map with prefix.


CMR-6318 restored test changed by mistake

--- system-int-test/test/cmr/system_int_test/search/autocomplete_collection_facet_search_test.clj
+++ system-int-test/test/cmr/system_int_test/search/autocomplete_collection_facet_search_test.clj
@@ -78,7 +78,7 @@
      (is (:CMR-Took headers))))

   (testing "entries return in descending score order"
-   (let [response (query->json-response-body "q=gulf")
+   (let [response (query->json-response-body "q=at")
          entries (response-body->entries response)
          a (first entries)
          b (second entries)]


str refactor

str refactor

--- build.boot
+++ build.boot
@@ -256,8 +256,9 @@
         (proc "lumo"
               "-c" (str "\"" (System/getProperty "fake.class.path") "\"")
               "-k" "lumo_cache"
-              "-e" (str "\"(require '[mikron.runtime.core :as mikron "
-                        ":refer [schema defschema pack unpack gen valid?]])\"")
+              "-e" (str "\""
+                        "(require '[mikron.runtime.core :as mikron :refer [schema defschema pack unpack gen valid?]])"
+                        "\"")
               "-r")))

 (deftask generate-docs


Remove slug task from `build` The result of this `:slug-fn` is the same as the file's existing `:slug`. `:short-filename` is now always the same value as `:slug`.

--- build.boot
+++ build.boot
@@ -33,9 +33,6 @@
     (comp (sass)
           (global-metadata)
           (markdown :options {:extensions {:smarts true}})
-          (slug
-            :slug-fn (fn [_ m]
-              (:short-filename m)))
           (permalink)
           (print-meta)
           (render :renderer 'io.perun.site/guide-page :filterer guide?)


Write to the target directory

Write to the target directory

--- build.boot
+++ build.boot
@@ -47,4 +47,5 @@
    (pom :project 'chili-dog-night
         :version "0.1.0")
    (uber)
-   (jar :main 'chili-dog-night.core)))
+   (jar :main 'chili-dog-night.core)
+   (target)))


Update eval-soup

Update eval-soup

--- build.boot
+++ build.boot
@@ -12,7 +12,7 @@
                   [leiningen "2.7.0" :exclusions [leiningen.search]]
                   [ring "1.4.0"]
                   [play-cljs/lein-template "0.6.4"]
-                  [eval-soup "1.0.2" :exclusions [org.clojure/core.async]]])
+                  [eval-soup "1.1.0" :exclusions [org.clojure/core.async]]])

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


version 0.3.1

version 0.3.1

--- build.boot
+++ build.boot
@@ -1,4 +1,4 @@
-(def +version+ "0.3.0")
+(def +version+ "0.3.1")

 (task-options!
   pom {:project     'combo


bump alda/core dev dep to 0.1.2

bump alda/core dev dep to 0.1.2

--- build.boot
+++ build.boot
@@ -5,7 +5,7 @@
                   [adzerk/boot-test      "1.1.2"  :scope "test"]
                   [str-to-argv           "0.1.0"  :scope "test"]
                   ; needed in order to run the "alda repl" command in dev
-                  [alda/core             "0.1.1"  :scope "test"]
+                  [alda/core             "0.1.2"  :scope "test"]
                   [alda/sound-engine-clj "0.1.0"  :scope "test"]
                   [alda/repl-clj         "0.1.0"  :scope "test"]


Specify the jar name to be server.jar

Specify the jar name to be server.jar

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

 (deftask test


Update build.boot indentation

Update build.boot indentation

--- build.boot
+++ build.boot
@@ -6,8 +6,8 @@
                   [adzerk/boot-test    "1.1.2"  :scope "test"]])

 (require
- '[adzerk.bootlaces :as deploy]
- '[adzerk.boot-test :as boot-test])
+  '[adzerk.bootlaces :as deploy]
+  '[adzerk.boot-test :as boot-test])

 (def +version+ "1.1.0-SNAPSHOT")

@@ -34,8 +34,8 @@

 (deftask test []
   (comp
-   (development)
-   (boot-test/test)))
+    (development)
+    (boot-test/test)))

 (deftask push-release []
   (comp


Release v0.0.2

Release v0.0.2

Mostly to see if clojars will allow this, because it has a 0.0.2-hash
release that really should have been a SNAPSHOT, but didn't work out
that way.

--- build.boot
+++ build.boot
@@ -1,4 +1,4 @@
-  (def project-name "com.frereth/cp")
+(def project-name "com.frereth/cp")

 (require '[clojure.java.shell :as sh])

@@ -40,7 +40,7 @@
       default-version)))

 (def project 'com.frereth/cp)
-(def version #_"0.0.2-SNAPSHOT" (deduce-version-from-git))
+(def version #_"0.0.2" (deduce-version-from-git))

 ;; TODO: Add a dependency on weald and refactor away the local copy
 ;; of shared.logging.


Update play-cljs template again

Update play-cljs template again

--- build.boot
+++ build.boot
@@ -14,7 +14,7 @@
                   [leiningen "2.8.1" :exclusions [leiningen.search]]
                   [ring "1.6.1"]
                   [hawk "0.2.11"]
-                  [play-cljs/lein-template "0.11.0"]
+                  [play-cljs/lein-template "0.11.0.1"]
                   [eval-soup "1.2.3" :exclusions [org.clojure/core.async]]
                   [org.eclipse.jgit/org.eclipse.jgit "4.6.0.201612231935-r"]]
   :repositories (conj (get-env :repositories)


Update to newest version of boot-junit

Update to newest version of boot-junit

Must explicitly specify junit as a test dependency now.

--- build.boot
+++ build.boot
@@ -1,7 +1,8 @@
 (set-env!
  :source-paths #{"src"}
- :dependencies '[[radicalzephyr/bootlaces "0.1.14"          :scope "test"]
-                 [radicalzephyr/boot-junit "0.2.0-SNAPSHOT" :scope "test"]
+ :dependencies '[[radicalzephyr/bootlaces  "0.1.14"         :scope "test"]
+                 [radicalzephyr/boot-junit "0.2.1-SNAPSHOT" :scope "test"]
+                 [junit                    "4.12"           :scope "test"]
                  [net.sf.jopt-simple/jopt-simple "4.9"]])

 (def +version+ "0.1.0-SNAPSHOT")


fix find-best-attr-set-test

fix find-best-attr-set-test

--- test/synthesis_crawlers/core_test.clj
+++ test/synthesis_crawlers/core_test.clj
@@ -215,12 +215,11 @@

 (deftest find-best-attr-set-test
   (testing "returns attributes found in pages"
-    (let [text (Jsoup/parse (slurp "dev-resources/synthesis_crawlers/find-reachable-attrs.html"))
-          inner-div (first (.select text "html > body > div > div"))
-          html (first (.select text "html"))
-          body (first (.select text "html > body"))
-          span (first (.select text "html > body > div > span"))
-          outer-div (first (.select text "html > body > div"))
+    (let [inner-div "html > body > div > div"
+          html "html"
+          body "html > body"
+          span "html > body > div > span"
+          outer-div "html > body > div"
           result (find-best-attr-set
                    {"http://foo.com" {:title [inner-div] :date [span] :body []}})]
       (is (= result


Starting to make happy namespace files

Starting to make happy namespace files

--- test/such/f_ns.clj
+++ test/such/f_ns.clj
@@ -2,6 +2,9 @@
   (:use midje.sweet)
   (:use such.types))

+(fact "a wow version of `find-ns`"
+  (fact "original works on symbols but not its own result"
+  (find-ns 'such.f-ns) => namespace?
+  (find-ns (find-ns 'such.f-ns)) => (throws)))
+

-(fact "find-ns"
-  (find-ns 'such.f-ns) => namespace?)


better handling of the list of processed sensors

--- dev/migrate.clj
+++ dev/migrate.clj
@@ -21,6 +21,11 @@
       (clojure.walk/stringify-keys (read-string metadata))
       nil)))

+(def processed-file "/tmp/processed_sensors.txt")
+
+(defn file-exists? [filename]
+  (.exists (clojure.java.io/as-file filename)))
+
 (defn migrate-reading-metadata
   "Works on a lazy sequence of all measurements for all sensors in the database and
   populates (new) reading_metadata with data coming from (old) metadata."
@@ -28,7 +33,9 @@
   (log/info "Migrating reading metadata.")
   (db/with-session [session (:hecuba-session store)]
     (let [all-sensors (db/execute session (hayt/select :sensors))
-          processed-sensors (clojure.string/split-lines (slurp "/tmp/processed_sensors.txt"))
+          processed-sensors (if (file-exists? processed-file)
+                                (map clojure.edn/read-string (clojure.string/split-lines (slurp processed-file)))
+                                [])
           sensors (remove (set processed-sensors) all-sensors)]
       (doseq [s sensors]
         (let [measurements (measurements/all-measurements store s)
@@ -37,7 +44,7 @@
           (when measurements-with-metadata
              (db/execute session
                          (misc/prepare-batch measurements-with-metadata))))
-        (spit "/tmp/processed_sensors.txt" s :append true))))
+        (spit "/tmp/processed_sensors.txt" (str s "\n") :append true))))
   (log/info "Finished migrating reading metadata."))

 (defn fill-sensor-bounds


changed tense names to english

changed tense names to english

--- babel/francais/morphology.clj
+++ babel/francais/morphology.clj
@@ -136,12 +136,12 @@
            (verbs/conditional word)

            (and
-            (= (get-in word '(:infl)) :futuro)
+            (= (get-in word '(:infl)) :future)
             (string? (get-in word '(:français))))
            (verbs/future word)

            (and
-            (= (get-in word '(:infl)) :imperfetto)
+            (= (get-in word '(:infl)) :imperfect)
             (string? (get-in word '(:français))))
            (verbs/imperfect word)

@@ -326,11 +326,11 @@
                                        lexemes)))
                            [
                             ;; 1. past-tense exceptions
-                            {:path [:français :passato]
+                            {:path [:français :past]
                              :merge-fn
                              (fn [val]
                                {:français {:infl :past
-                                           :français (get-in val [:français :passato] :nothing)}})}
+                                           :français (get-in val [:français :past] :nothing)}})}

                             ;; 2. present-tense exceptions
                             {:path [:français :present :1sing]


update lein colors

update lein colors

--- lein/profiles.clj
+++ lein/profiles.clj
@@ -5,4 +5,17 @@
   {:width 120
    :map-delimiter ","
    :extend-notation true
-   :print-color true}}}
+   :print-color true
+   :print-meta true
+   :color-scheme {:boolean [:yellow]
+                  :character [:bold :green]
+                  :class-delimiter [:bold :blue]
+                  :class-name [:blue]
+                  :delimiter [:cyan]
+                  :function-symbol [:blue]
+                  :keyword [:red]
+                  :nil [:yellow]
+                  :number [:yellow]
+                  :string [:green]
+                  :symbol nil
+                  :tag [:red]}}}}


compare the triplets working solution

compare the triplets working solution

--- src/hackerrank/compare_the_triplets.clj
+++ src/hackerrank/compare_the_triplets.clj
@@ -5,6 +5,15 @@

 ; https://www.hackerrank.com/challenges/compare-the-triplets

+
+(def alice (atom 0))
+(def bob (atom 0))
+
+;; https://clojuredocs.org/clojure.core/swap!
+;; https://clojuredocs.org/clojure.core/cond
+(defn score [a b]
+  (cond (= (compare a b) 1) (swap! alice inc)
+        (= (compare a b) -1) (swap! bob inc)))

 (let [a0_temp "5 6 7" ; (read-line)
       a0_t (split a0_temp #"\s+")
@@ -21,4 +30,10 @@
   ;; https://clojuredocs.org/clojure.string/join
   (println (join " " [a0 a1 a2]))
   (println (join " " [b0 b1 b2]))
+
+  (score a0 b0)
+  (score a1 b1)
+  (score a2 b2)
+
+  (println @alice " " @bob)
 )


Upgrade simple example lein-shadow to 0.1.7

--- examples/simple/project.clj
+++ examples/simple/project.clj
@@ -10,7 +10,7 @@
                  [re-frame                  "0.11.0-rc2"]]

   :plugins      [[day8/lein-git-inject "0.0.2"]
-                 [lein-shadow          "0.1.6"]]
+                 [lein-shadow          "0.1.7"]]

   :middleware   [leiningen.git-inject/middleware]


Added base64-decode-bytes function

Added base64-decode-bytes function

--- src/compojure/encodings.clj
+++ src/compojure/encodings.clj
@@ -34,11 +34,16 @@
   "Encode a string using base64."
   (base64-encode-bytes (.getBytes unencoded)))

+(defn base64-decode-bytes
+  "Decode a string using base64 into an array of bytes."
+  [encoded]
+  (Base64/decodeBase64 (.getBytes encoded)))
+
 (defn base64-decode
   "Decode a string using base64."
   [encoded]
-  (String. (Base64/decodeBase64 (.getBytes encoded))))
-
+  (String. (base64-decode-bytes encoded)))
+
 (defn marshal
   "Serialize a Clojure object in a base64-encoded string."
   [data]


fix lambda event source mapping typo and requrements (#187)

--- src/crucible/aws/lambda.clj
+++ src/crucible/aws/lambda.clj
@@ -65,13 +65,13 @@

 (s/def ::event-source-arn (spec-or-ref string?))

-(s/def ::starting-postition (spec-or-ref #{"TRIM_HORIZON" "LATEST"}))
+(s/def ::starting-position (spec-or-ref #{"TRIM_HORIZON" "LATEST"}))

 (s/def ::event-source-mapping (s/keys :req [::event-source-arn
-                                            ::function-name
-                                            ::starting-position]
+                                            ::function-name]
                                       :opt [::batch-size
-                                            ::enabled]))
+                                            ::enabled
+                                            ::starting-position]))

 (defresource event-source-mapping "AWS::Lambda::EventSourceMapping" ::event-source-mapping)


Update tools-deps to 1.11.0.1100

Update tools-deps to 1.11.0.1100


Remove openjdk-14 images; no longer supported

--- src/docker_clojure/core.clj
+++ src/docker_clojure/core.clj
@@ -33,7 +33,7 @@

 (def base-image "openjdk")

-(def jdk-versions #{8 11 14 15 16})
+(def jdk-versions #{8 11 15 16})

 ;; The default JDK version to use for tags that don't specify one; usually the latest LTS release
 (def default-jdk-version 11)
@@ -54,8 +54,6 @@
   #{{:jdk-version 8
      :distro      "alpine"}
     {:jdk-version 11
-     :distro      "alpine"}
-    {:jdk-version 14
      :distro      "alpine"}
     {:jdk-version 15
      :distro      "alpine"}})


man/woman items in street

man/woman items in street

--- src/house/rooms/street.cljc
+++ src/house/rooms/street.cljc
@@ -12,15 +12,14 @@
                          :default-go "I didn't want too go too far away from the house.")

               (room/add-item (item/make "street" "It was very quiet at the time.") "")
-
               (room/add-item (item/make ["window" "left window"]
                                         "Through the left window I saw a bedroom. There was a middle-aged man inside, reading a book."
                                         :look-in "Through the left window I saw a bedroom. There was a middle-aged man inside, reading a book.") "")
-
               (room/add-item (item/make ["window" "right window"]
                                         "I saw a bedroom through the right window. There was a woman on a sofa, knitting."
                                         :look-in "I saw a bedroom through the right window. There was a woman on a sofa, knitting.") "")
-
+              (room/add-item (item/make "man" "He was reading." :talk "He couldn't hear me.") "")
+              (room/add-item (item/make "woman" "She was knitting." :talk "She couldn't hear me.") "")
               (room/add-item (item/make "house"
                                         "One of those aristocratic buildings that could easily accommodate four families but was barely inhabited instead."
                                         :break "Why? The street door was open."


Do not log writing in parsers.html/html-parser.

--- src/incise/parsers/html.clj
+++ src/incise/parsers/html.clj
@@ -26,7 +26,6 @@
     (-> out-file
         (.getParentFile)
         (.mkdirs))
-    (info "Writing" (.getPath out-file))
     (spit out-file (Parse->string parse-data))
     out-file))


clean up stream-links*

clean up stream-links*

--- src/link_checker/render.clj
+++ src/link_checker/render.clj
@@ -76,8 +76,23 @@
               time
               (count links))))))

+(defn- check-links
+  [send-to links url options]
+  (swap! link-counts assoc (:client-id options) (count links))
+  (send-to "message"
+           (format "%s has %s links. Fetching data... "
+                   url (count links)))
+  (let [start-time (System/currentTimeMillis)
+        link-results (doall (pmap (partial fetch-link-and-send-row send-to url
+                                           (count links) (:client-id options))
+                                  links))]
+    (send-final-message send-to (calc-time start-time) link-results))
+  (send-to "end-message" (str "result?url=" url
+                              (if (empty? (:selector options)) ""
+                                (str "&selector=" (:selector options))))))
+
 (defn- stream-links*
-  "Sends 3 different sse events (message, results, end-message) depending on
+  "Sends 4 different sse events (message, results, end-message, error) depending on
 what part of the page it's updating."
   [send-event-fn sse-context url options]
   (let [send-to (partial send-event-fn sse-context)
@@ -85,19 +100,7 @@
     (if (and (seq selector) (not (valid-selector? selector)))
       (send-to "error" "Selector is invalid. Try again.")
       (if-let [links (url->links url (assoc options :selector selector))]
-        (do
-          (swap! link-counts assoc (:client-id options) (count links))
-          (send-to "message"
-                   (format "%s has %s links. Fetching data... "
-                           url (count links)))
-          (let [start-time (System/currentTimeMillis)
-                link-results (doall (pmap (partial fetch-link-and-send-row send-to url
-                                                   (count links) (:client-id options))
-                                         links))]
-           (send-final-message send-to (calc-time start-time) link-results))
-          (send-to "end-message" (str "result?url=" url
-                                      (if (seq (:selector options))
-                                        (str "&selector=" (:selector options)) ""))))
+        (check-links send-to links url options)
         (send-to "error" "Unable to fetch the given url.")))))

 (defn stream-links


Make slide-synth easier to understand

Make slide-synth easier to understand

--- src/literate_2048/core.cljs
+++ src/literate_2048/core.cljs
@@ -155,31 +155,39 @@
 ;; A line is a sequence that represents the flow of the tiles during a move. In
 ;; other words, is a row or a column of the board where the closest a square is
 ;; to edge of the board the tiles are sliding to, the sooner it appears in the
-;; sequence. With that in mind, the 'slide and synth' of a whole board can be
-;;  summarized as:
-
-;; - Obtaining the lines. Rows are partitions of 4 elements of our board
-;;   representation and columns are transposition of them. For the 'right' and
-;;   'up' move, the rows and columns need to be reversed to obtain the correct
-;;   line.
-;; - Slide and synth the lines.
-;; - Reassemble the resulting sequences, that is rows or columns possibly
-;;   reversed, back to our board representation.
+;; sequence.
+
+;; With all that in mind, to 'slide and synth' a whole board to the left can
+;; build a matrix from the original board representation. This matrix will be a
+;; vector of vectors, where each of the vectors are a row. Then we slide and
+;; synth every row, and finally flatten the matrix. For the other directions
+;; we'll need to transform the matrix before sliding and synthing every row
+;; (to build the lines) and perform the inverse transformation afterwards (to
+;; undo the effects of the first transformation and turn the lines back into
+;; rows):
+;;
+;; - right: flip the matrix vertically (reverse each row), before and after
+;;   sliding and synthesizing each row.
+;; - up: transpose the matrix vertically (turn columns into rows), before and
+;;   after.
+;; - down: rotate the matrix clockwise, slide and synth every row, and rotate
+;;   it counter-clockwise afterwards.

 (defn slide-synth
   "Returns the result of sliding and synthesizing the tiles of board in the
    given direction."
   [board direction]
-  (let [transpose #(apply map list %)
-        reverse-slide-synth-line (comp reverse slide-synth-line reverse)
-        rows (partition board-order board)
-        cols (transpose rows)]
-    (vec (flatten
-          (case direction
-            :left (map slide-synth-line rows)
-            :right (map reverse-slide-synth-line rows)
-            :up (->> cols (map slide-synth-line) transpose)
-            :down (->> cols (map reverse-slide-synth-line) transpose))))))
+  (let [m (partition board-order board)
+        m-slide-synth (partial map slide-synth-line)
+        m-vflip (partial map reverse)
+        m-transpose (partial apply map list)
+        m-rotate-cw (comp m-vflip m-transpose)
+        m-rotate-ccw (comp m-transpose m-vflip)]
+    (vec (flatten (case direction
+                    :left (m-slide-synth m)
+                    :right (-> m m-vflip m-slide-synth m-vflip)
+                    :up (-> m m-transpose m-slide-synth m-transpose)
+                    :down (-> m m-rotate-cw m-slide-synth m-rotate-ccw))))))

 ;; To complete a move, a tile is added when the board changes.


CMR-2812 Fixes sequential validation return value

--- common-lib/src/cmr/common/validations/core.clj
+++ common-lib/src/cmr/common/validations/core.clj
@@ -73,7 +73,7 @@
    (cond
      (sequential? validation) (reduce (fn [error-map v]
                                         (merge-with concat error-map (validate v key-path value)))
-                                      nil
+                                      {}
                                       validation)
      (map? validation) (reduce (fn [error-map [k v]]
                                  (merge error-map (validate v (conj key-path k) (get value k))))


updated dependencies

updated dependencies

--- src/leiningen/new/reagent.clj
+++ src/leiningen/new/reagent.clj
@@ -30,9 +30,9 @@

 (def lib-or-app-dependencies
   "Dependencies for development or as part of an app."
-  '[[org.clojure/clojurescript "0.0-2657" :scope "provided"]
-    [com.cemerick/piggieback "0.1.3"]
-    [weasel "0.4.2"]
+  '[[org.clojure/clojurescript "0.0-2665" :scope "provided"]
+    [com.cemerick/piggieback "0.1.4"]
+    [weasel "0.5.0"]
     [ring "1.3.2"]
     [ring/ring-defaults "0.1.3"]
     [prone "0.8.0"]


increased memory for n-ary interaction query

--- kabob-build/src/main/resources/edu/ucdenver/ccp/kabob/build/rules/temp/irefweb/irefweb.clj
+++ kabob-build/src/main/resources/edu/ucdenver/ccp/kabob/build/rules/temp/irefweb/irefweb.clj
@@ -231,5 +231,6 @@
           [?/protein1_sc {:ln (:sha-1 ?/interaction ?/protein1)
                           :ns "kbio" :prefix "P_"}])

-  :options {:magic-prefixes [["franzOption_clauseReorderer" "franz:identity"]]}
+  :options {:magic-prefixes [["franzOption_clauseReorderer" "franz:identity"]
+                             ["franzOption_memoryLimit" "franz:85g"]]}
   }


bytte namn på det

bytte namn på det

--- src/nettle/vfibers/core.clj
+++ src/nettle/vfibers/core.clj
@@ -199,12 +199,6 @@
     (make-node-recursive node-map x)
     x))

-(defn postwalk-vector []
-
-(defn accurate-postwalk [f x]
-  (f (cond
-       (vector? x) (postwalk-vector f x)
-

 (defn make-code [expr0]
   (let [[node-map expr] (make-map {} expr0)


Cleanup the exception handling in org list resource.

--- src/oc/storage/api/orgs.clj
+++ src/oc/storage/api/orgs.clj
@@ -349,6 +349,14 @@
                       conn (:user ctx)))}) ; don't allow non-team-admins to get stuck w/ no org

   ;; Validations
+  :malformed? (by-method {
+    :options false
+    :get (fn [ctx] (if-let* [ctx-params (keywordize-keys (-> ctx :request :params))
+                             team-id (:team-id ctx-params) ; org lookup is by team-id
+                             _team-id? (lib-schema/unique-id? team-id)]
+                     [false {:team-id team-id}]
+                     true))
+    :post (fn [ctx] (api-common/malformed-json? ctx))})
   :processable? (by-method {
     :options true
     :get true
@@ -358,11 +366,9 @@

   ;; Existentialism
   :exists? (by-method {
-             :get (fn [ctx] (if-let* [ctx-params (keywordize-keys (-> ctx :request :params))
-                                      team-id (:team-id ctx-params) ; org lookup is by team-id
-                                      _team-id? (lib-schema/unique-id? team-id)
+             :get (fn [ctx] (if-let* [team-id (:team-id ctx)
                                       orgs (org-res/list-orgs-by-team conn team-id [:logo-url :logo-width :logo-height])]
-                              {:existing-orgs (api-common/rep orgs)}
+                              (if (empty? orgs) false {:existing-orgs (api-common/rep orgs)})
                               false))})

   ;; Actions


Clean up.

Clean up.

--- src/onyx/sync/zookeeper.clj
+++ src/onyx/sync/zookeeper.clj
@@ -2,9 +2,9 @@
   (:require [clojure.data.fressian :as fressian]
             [com.stuartsierra.component :as component]
             [taoensso.timbre]
-            [onyx.extensions :as extensions]
             [zookeeper :as zk]
-            [zookeeper.util :as util])
+            [zookeeper.util :as util]
+            [onyx.extensions :as extensions])
   (:import [java.util UUID]
            [org.apache.curator.test TestingServer]))

@@ -17,91 +17,91 @@
   (str root-path "/" prefix))

 (defn peer-path [prefix]
-  (str root-path "/" prefix "/peer"))
+  (str (prefix-path prefix) "/peer"))

 (defn peer-state-path [prefix]
-  (str root-path "/" prefix "/peer-state"))
+  (str (prefix-path prefix) "/peer-state"))

 (defn pulse-path [prefix]
-  (str root-path "/" prefix "/pulse"))
+  (str (prefix-path prefix) "/pulse"))

 (defn payload-path [prefix]
-  (str root-path "/" prefix "/payload"))
+  (str (prefix-path prefix) "/payload"))

 (defn ack-path [prefix]
-  (str root-path "/" prefix "/ack"))
+  (str (prefix-path prefix) "/ack"))

 (defn exhaust-path [prefix]
-  (str root-path "/" prefix "/exhaust"))
+  (str (prefix-path prefix) "/exhaust"))

 (defn seal-path [prefix]
-  (str root-path "/" prefix "/seal"))
+  (str (prefix-path prefix) "/seal"))

 (defn completion-path [prefix]
-  (str root-path "/" prefix "/completion"))
+  (str (prefix-path prefix) "/completion"))

 (defn cooldown-path [prefix]
-  (str root-path "/" prefix "/cooldown"))
+  (str (prefix-path prefix) "/cooldown"))

 (defn status-path [prefix]
-  (str root-path "/" prefix "/status"))
+  (str (prefix-path prefix) "/status"))

 (defn catalog-path [prefix]
-  (str root-path "/" prefix "/catalog"))
+  (str (prefix-path prefix) "/catalog"))

 (defn workflow-path [prefix]
-  (str root-path "/" prefix "/workflow"))
+  (str (prefix-path prefix) "/workflow"))

 (defn shutdown-path [prefix]
-  (str root-path "/" prefix "/shutdown"))
+  (str (prefix-path prefix) "/shutdown"))

 (defn job-path [prefix]
-  (str root-path "/" prefix "/job"))
+  (str (prefix-path prefix) "/job"))

 (defn task-path [prefix subpath]
-  (str root-path "/" prefix "/task/" subpath))
+  (str (prefix-path prefix) "/task/" subpath))

 (defn plan-path [prefix]
-  (str root-path "/" prefix "/plan"))
+  (str (prefix-path prefix) "/plan"))

 (defn election-path [prefix]
-  (str root-path "/" prefix "/election"))
+  (str (prefix-path prefix) "/election"))

 (defn job-log-path [prefix]
-  (str root-path "/" prefix "/job-log"))
+  (str (prefix-path prefix) "/job-log"))

 (defn born-log-path [prefix]
-  (str root-path "/" prefix "/coordinator/born-log"))
+  (str (prefix-path prefix) "/coordinator/born-log"))

 (defn death-log-path [prefix]
-  (str root-path "/" prefix "/coordinator/death-log"))
+  (str (prefix-path prefix) "/coordinator/death-log"))

 (defn planning-log-path [prefix]
-  (str root-path "/" prefix "/coordinator/planning-log"))
+  (str (prefix-path prefix) "/coordinator/planning-log"))

 (defn ack-log-path [prefix]
-  (str root-path "/" prefix "/coordinator/ack-log"))
+  (str (prefix-path prefix) "/coordinator/ack-log"))

 (defn evict-log-path [prefix]
-  (str root-path "/" prefix "/coordinator/evict-log"))
+  (str (prefix-path prefix) "/coordinator/evict-log"))

 (defn offer-log-path [prefix]
-  (str root-path "/" prefix "/coordinator/offer-log"))
+  (str (prefix-path prefix) "/coordinator/offer-log"))

 (defn revoke-log-path [prefix]
-  (str root-path "/" prefix "/coordinator/revoke-log"))
+  (str (prefix-path prefix) "/coordinator/revoke-log"))

 (defn exhaust-log-path [prefix]
-  (str root-path "/" prefix "/coordinator/exhaust-log"))
+  (str (prefix-path prefix) "/coordinator/exhaust-log"))

 (defn seal-log-path [prefix]
-  (str root-path "/" prefix "/coordinator/seal-log"))
+  (str (prefix-path prefix) "/coordinator/seal-log"))

 (defn complete-log-path [prefix]
-  (str root-path "/" prefix "/coordinator/complete-log"))
+  (str (prefix-path prefix) "/coordinator/complete-log"))

 (defn shutdown-log-path [prefix]
-  (str root-path "/" prefix "/coordinator/shutdown-log"))
+  (str (prefix-path prefix) "/coordinator/shutdown-log"))

 (defrecord ZooKeeper [opts]
   component/Lifecycle
@@ -157,7 +157,7 @@
 (defn zookeeper [opts]
   (map->ZooKeeper {:opts opts}))

-(defn trailing-id [s]
+(defn leaf [s]
   (last (clojure.string/split s #"/")))

 (defn serialize-edn [x]
@@ -545,7 +545,7 @@
 (defmethod extensions/bucket-at [ZooKeeper :task]
   [sync _ subpath]
   (let [prefix (:onyx/id (:opts sync))
-        job-id (trailing-id subpath)
+        job-id (leaf subpath)
         children (or (zk/children (:conn sync) (task-path prefix job-id)) [])]
     (map #(str (task-path prefix job-id) "/" %) children)))

@@ -572,7 +572,7 @@
 (defmethod extensions/resolve-node [ZooKeeper :task]
   [sync _ job-node & more]
   (let [prefix (:onyx/id (:opts sync))]
-    (task-path prefix (trailing-id job-node))))
+    (task-path prefix (leaf job-node))))

 (defmethod extensions/children ZooKeeper
   [sync node]


Use clojures tag representation.

Use clojures tag representation.

--- src/replikativ/platform.clj
+++ src/replikativ/platform.clj
@@ -26,7 +26,9 @@
                "irecord"
                (proxy-super tag o)))
     (rep [o] (if (isa? (type o)  clojure.lang.IRecord)
-               (assoc (into {} o) :_gnd$tl (pr-str (type o)))
+               (assoc (into {} o) :_gnd$tl
+                      (let [[_ pre t] (re-find #"(.+)\.([^.]+)" (pr-str (type o)))]
+                        (str pre "/" t)))
                (proxy-super rep o)))))

@@ -35,7 +37,7 @@
    (fn [rep]
      (try
        (if (Class/forName (:_gnd$tl rep))
-         ((let [[_ pre t] (re-find #"(.+)\.([^.]+)" (:_gnd$tl rep))]
+         ((let [[_ pre t] (re-find #"(.+)/([^.]+)" (:_gnd$tl rep))]
             (resolve (symbol (str pre "/map->" t)))) (dissoc rep :_gnd$tl)))
        (catch Exception e
          (debug "Cannot deserialize record" (:_gnd$tl rep) e)


run kibit on test/model

run kibit on test/model

--- test/civs/model/core_test.clj
+++ test/civs/model/core_test.clj
@@ -17,10 +17,10 @@
 ; ###########################################################

 (deftest test-in?
-  (is (= true (in? [1 2 3] 1)))
-  (is (= false (in? [1 2 3] 4)))
-  (is (= true (in? (list 1 2 3) 1)))
-  (is (= false (in? (list 1 2 3) 4))))
+  (is (true? (in? [1 2 3] 1)))
+  (is (false? (in? [1 2 3] 4)))
+  (is (true? (in? (list 1 2 3) 1)))
+  (is (false? (in? (list 1 2 3) 4))))

 ; ###########################################################
 ;  Population
@@ -78,12 +78,12 @@
       (is (= initial-society (society ga gr))))))

 (deftest test-dead?
-  (is (= false (dead? (Group. nil nil nil (Population. 1 2 3 4 5) nil))))
-  (is (= true  (dead? (Group. nil nil nil (Population. 0 0 0 0 0) nil)))))
+  (is (false? (dead? (Group. nil nil nil (Population. 1 2 3 4 5) nil))))
+  (is (true?  (dead? (Group. nil nil nil (Population. 0 0 0 0 0) nil)))))

 (deftest test-alive?
-  (is (= true  (alive?  (Group. nil nil nil (Population. 1 2 3 4 5) nil))))
-  (is (= false (alive?  (Group. nil nil nil (Population. 0 0 0 0 0) nil)))))
+  (is (true?  (alive?  (Group. nil nil nil (Population. 1 2 3 4 5) nil))))
+  (is (false? (alive?  (Group. nil nil nil (Population. 0 0 0 0 0) nil)))))

 (deftest test-know?
   (consider-base-group
@@ -109,7 +109,7 @@
 (deftest test-get-language
   (consider-base-group
     (fn [ga gr]
-      (is (= nil (get-language ga gr))))))
+      (is (nil? (get-language ga gr))))))

 (deftest test-assoc-language
   (consider-base-group
@@ -183,20 +183,20 @@
   (let [g0 (create-game nil)
         g1 (:game (create-tribe g0 "name" {:x 15 :y 18} (Population. 1 2 3 4 5) initial-culture initial-society))
         g2 (:game (create-tribe g1 "name" {:x 15 :y 18} (Population. 0 1 2 0 0) initial-culture initial-society))]
-    (is (= 0 (game-total-pop g0)))
+    (is (zero? (game-total-pop g0)))
     (is (= 15 (game-total-pop g1)))
     (is (= 18 (game-total-pop g2)))))

 (deftest test-get-group
   (let [g0 (create-game nil)
         g1 (:game (create-tribe g0 "name" {:x 15 :y 18} (Population. 1 2 3 4 5) initial-culture initial-society))]
-    (is (= nil (get-group g0 1)))
+    (is (nil? (get-group g0 1)))
     (is (= (Group. 2 "name" {:x 15 :y 18} (Population. 1 2 3 4 5) 1) (get-group g1 2)))))

 (deftest test-get-settlement
   (let [g0 (create-game nil)
         g1 (:game (create-settlement g0 "name" {:x 15 :y 18} :123 10))]
-    (is (= nil (get-settlement g0 1)))
+    (is (nil? (get-settlement g0 1)))
     (is (= (Settlement. 1 "name" 10 {:x 15 :y 18} :123) (get-settlement g1 1)))))

 (deftest test-ghost-city
@@ -205,14 +205,14 @@
         {g2 :game s1 :settlement} (create-settlement g1 "name" {:x 15 :y 18} (.id gr1) 11)
         {g3 :game gr2 :group} (create-tribe g2 "name" {:x 15 :y 18} (Population. 0 0 0 0 0) initial-culture initial-society)
         {g4 :game s2 :settlement} (create-settlement g3 "name" {:x 15 :y 18} (.id gr2) 12)]
-    (is (= false (ghost-city? g2 (.id s1))))
-    (is (= true (ghost-city? g4 (.id s2))))))
+    (is (false? (ghost-city? g2 (.id s1))))
+    (is (true? (ghost-city? g4 (.id s2))))))

 (deftest test-n-groups-alive
   (let [g0 (create-game nil)
         g1 (:game (create-tribe g0 "name" {:x 15 :y 18} (Population. 1 2 3 4 5) initial-culture initial-society))
         g2 (:game (create-tribe g1 "name" {:x 15 :y 18} (Population. 0 0 0 0 0) initial-culture initial-society))]
-    (is (= 0 (n-groups-alive g0)))
+    (is (zero? (n-groups-alive g0)))
     (is (= 1 (n-groups-alive g1)))
     (is (= 1 (n-groups-alive g2)))))

@@ -229,8 +229,8 @@
         {g2 :game s1 :settlement} (create-settlement g1 "name" {:x 15 :y 18} (.id gr1) 20)
         {g3 :game gr2 :group} (create-tribe g2 "name" {:x 15 :y 18} (Population. 0 0 0 0 0) initial-culture initial-society)
         {g4 :game s2 :settlement} (create-settlement g3 "name" {:x 15 :y 18} (.id gr2) 21)]
-    (is (= 0 (n-ghost-cities g0)))
-    (is (= 0 (n-ghost-cities g2)))
+    (is (zero? (n-ghost-cities g0)))
+    (is (zero? (n-ghost-cities g2)))
     (is (= 1 (n-ghost-cities g4)))))

 (deftest test-assoc-and-use-language


Augment fs tests with other platforms, urlencoded chrs

--- test/grimoire/api/fs_test.clj
+++ test/grimoire/api/fs_test.clj
@@ -22,8 +22,15 @@
    "org.foo/a/1.0.1/clj/a.core"
    "org.foo/a/1.1.0/clj"
    "org.foo/a/1.1.0/clj/a.core"
+   "org.foo/a/1.1.0/clj/a.core/foo?"
    "org.foo/a/1.1.0/clj/a.core/foo"
-   "org.foo/a/1.1.0/clj/a.core/qux"
+   "org.foo/a/1.1.0/clj/a.core/qux!"
+   "org.foo/a/1.1.0/clj/a.core/qux."
+   "org.foo/a/1.1.0/pixi/a.core/qux."
+   "org.foo/a/1.1.0/cljs/a.core/qux."
+   "org.foo/a/1.1.0/cljclr/a.core/qux."
+   "org.foo/a/1.1.0/ox/a.core/qux."
+   "org.foo/a/1.1.0/toc/a.core/qux."
    "org.foo/a/1.1.0/clj/a.impl.clj"
    "org.foo/a/1.1.0/cljclr"
    "org.foo/a/1.1.0/cljs"
@@ -74,7 +81,7 @@
         platforms (-> test-config
                       (api/list-platforms p)
                       result)]
-    (is (= ["clj" "cljclr" "cljs"]
+    (is (= ["clj" "cljclr" "cljs" "ox" "pixi" "toc"]
            (sort (map t/thing->name platforms))))))

 (deftest list-ns-test
@@ -113,7 +120,7 @@
         defs (-> test-config
                  (api/list-defs ns)
                  result)]
-    (is (= ["foo" "qux"]
+    (is (= ["foo" "foo?" "qux" "qux!" "qux."]
            (sort (map t/thing->name defs))))))

 ;; Reading/Writing tests


Tighten up list-groups-test a bit

Tighten up list-groups-test a bit

--- test/grimoire/api/fs_test.clj
+++ test/grimoire/api/fs_test.clj
@@ -13,9 +13,8 @@
     :mode  :filesystem}})

 (deftest list-groups-test
-  (is (= (api/list-groups test-config)
-         (list {:type :group, :parent nil, :name "org.bar", :uri "org.bar"}
-               {:type :group, :parent nil, :name "org.foo", :uri "org.foo"}))))
+  (is (= (sort (map :name (api/list-groups test-config)))
+         ["org.bar" "org.foo"])))

 (deftest list-artifacts-test
   (let [g       (t/->Group "org.foo")


setup compojure-style request

setup compojure-style request

--- test/prometheus/core_test.clj
+++ test/prometheus/core_test.clj
@@ -13,7 +13,7 @@
 (deftest dump-metrics
   (let [registry (CollectorRegistry.)
         handler (prometheus/instrument-handler test-handler "test" registry)
-        response (handler (assoc (ring/request :get "/test") :compojure/route ["GET" "/test"]))
+        response (handler (assoc (ring/request :get "/test-path") :compojure/route ["GET" "/test-path"]))
         metrics (prometheus/dump-metrics registry)]
     (testing "handler returns delegate's response"
       (is (= {:status 200 :body "ok"} response)))
@@ -22,4 +22,4 @@
       (is (= TextFormat/CONTENT_TYPE_004 (get-in metrics [:headers "Content-Type"])))
       (is (.contains (:body metrics) "http_request_latency_seconds"))
       (is (.contains (:body metrics) "http_requests_total"))
-      (is (.contains (:body metrics) "/test")))))
+      (is (.contains (:body metrics) "/test-path")))))


add IWatchable protocol & implement for graph, update exec contexts to dynamically integrate graph changes, remove obsolete LoggedGraph

--- src/thi/ng/fabric/core.cljc
+++ src/thi/ng/fabric/core.cljc
@@ -14,7 +14,7 @@
         [clojure.core.reducers :as r]
         [cljs.core.async :as a :refer [chan close! <! >! alts! timeout]])]))

-;; #?(:clj (taoensso.timbre/set-level! :warn))
+#?(:clj (taoensso.timbre/set-level! :warn))

 ;; (warn :free-ram (.freeMemory (Runtime/getRuntime)))

@@ -39,6 +39,10 @@
   (vertex-for-id [_ id])
   (vertices [_])
   (add-edge! [_ src dest f opts]))
+
+(defprotocol IWatchable
+  (add-watch! [_ type id f])
+  (remove-watch! [_ type id]))

 (defprotocol IGraphExecutor
   (execute! [_])
@@ -183,7 +187,7 @@
                #(-> %
                     (update ::uncollected conj sig)
                     (assoc-in [::signal-map src] sig)))
-        (info (str id " ignoring unchanged signal: " (pr-str sig)))))
+        (debug id " ignoring unchanged signal: " (pr-str sig))))
     _))

 #?(:clj
@@ -203,25 +207,35 @@
     :in       (atom nil)
     :outs     (atom {})}))

-(defrecord InMemoryGraph [state]
+(defn notify-watches
+  [watches evt]
+  (loop [watches (vals (watches (first evt)))]
+    (when watches
+      ((first watches) evt)
+      (recur (next watches)))))
+
+(defrecord InMemoryGraph [state watches]
   IComputeGraph
   (add-vertex!
     [_ val vspec]
-    (-> state
-        (swap!
-         (fn [state]
-           (let [id (:next-id state)
-                 v  (vertex id val vspec)]
-             (-> state
-                 (update :next-id inc)
-                 (update :vertices assoc id v)
-                 (assoc  :curr-vertex v)))))
-        :curr-vertex))
+    (let [v (-> state
+                (swap!
+                 (fn [state]
+                   (let [id (:next-id state)
+                         v  (vertex id val vspec)]
+                     (-> state
+                         (update :next-id inc)
+                         (update :vertices assoc id v)
+                         (assoc  :curr-vertex v)))))
+                :curr-vertex)]
+      (notify-watches @watches [:add-vertex v])
+      v))
   (remove-vertex!
     [_ v]
     (when (get-in @state [:vertices (:id v)])
       (swap! state update :vertices dissoc (:id v))
       (disconnect-all! v)
+      (notify-watches @watches [:remove-vertex v])
       true))
   (vertex-for-id
     [_ id] (get-in @state [:vertices id]))
@@ -229,34 +243,27 @@
     [_] (-> @state :vertices vals))
   (add-edge!
     [_ src dest sig-fn opts]
-    (connect-to! src dest sig-fn opts)))
-
-(defrecord LoggedGraph [g log-chan]
-  IComputeGraph
-  (add-vertex!
-    [_ val vspec]
-    (let [v (add-vertex! g val vspec)]
-      (go (>! log-chan [:add-vertex (:id v) val]))
-      v))
-  (remove-vertex! [_ v]
-    (when (remove-vertex! g v)
-      (go (>! log-chan [:remove-vertex (:id v) @v]))
-      true))
-  (vertex-for-id
-    [_ id] (vertex-for-id g id))
-  (vertices
-    [_] (vertices g))
-  (add-edge!
-    [_ src dest f opts]
-    (connect-to! src dest f opts)
-    (go (>! log-chan [:add-edge (:id src) (:id dest) f opts]))))
+    (connect-to! src dest sig-fn opts)
+    (notify-watches @watches [:add-edge src dest sig-fn opts])
+    _)
+  IWatchable
+  (add-watch!
+    [_ type id f]
+    (info "adding watch" type id f)
+    (swap! watches assoc-in [type id] f)
+    _)
+  (remove-watch!
+    [_ type id]
+    (info "removing watch" type id)
+    (swap! watches update type dissoc id)
+    _))

 (defn compute-graph
-  [] (InMemoryGraph. (atom {:vertices {} :next-id 0})))
-
-(defn logged-compute-graph
-  ([log-chan] (LoggedGraph. (compute-graph) log-chan))
-  ([g log-chan] (LoggedGraph. g log-chan)))
+  [] (InMemoryGraph. (atom {:vertices {} :next-id 0}) (atom {})))
+
+#_(defn logged-compute-graph
+    ([log-chan] (LoggedGraph. (compute-graph) log-chan))
+    ([g log-chan] (LoggedGraph. g log-chan)))

 (defn eager-async-vertex-processor
   [{:keys [id] :as vertex} ctx]
@@ -293,6 +300,92 @@
   [type out colls sigs t0 & [opts]]
   (go (>! out (execution-result type colls sigs t0 opts))))

+(defn sync-signal-vertices
+  [vertices thresh]
+  (loop [sigs 0, verts vertices]
+    (if verts
+      (let [v (first verts)]
+        (if (should-signal? v thresh)
+          (do (debug (:id v) "signaling")
+              (signal! v sync-vertex-signal)
+              (recur (inc sigs) (next verts)))
+          (recur sigs (next verts))))
+      sigs)))
+
+(defn sync-collect-vertices
+  [vertices thresh]
+  (loop [colls 0, verts vertices]
+    (if verts
+      (let [v (first verts)]
+        (if (should-collect? v thresh)
+          (do (debug (:id v) "collecting")
+              (collect! v)
+              (recur (inc colls) (next verts)))
+          (recur colls (next verts))))
+      colls)))
+
+(defn parallel-sync-signal-vertices
+  [vertices thresh]
+  (r/fold
+   +
+   (fn
+     ([] 0)
+     ([acc v] (if (should-signal? v thresh) (do (signal! v sync-vertex-signal) (inc acc)) acc)))
+   vertices))
+
+(defn parallel-sync-collect-vertices
+  [vertices thresh]
+  (r/fold
+   +
+   (fn
+     ([] 0)
+     ([acc v] (if (should-collect? v thresh) (do (collect! v) (inc acc)) acc)))
+   vertices))
+
+(def default-sync-context-opts
+  {:collect-thresh 0
+   :signal-thresh  0
+   :max-iter       1e6
+   :signal-fn      sync-signal-vertices
+   :collect-fn     sync-collect-vertices})
+
+(defn sync-execution-context
+  [opts]
+  (let [ctx       (merge default-sync-context-opts opts)
+        g         (:graph ctx)
+        c-thresh  (:collect-thresh ctx)
+        s-thresh  (:signal-thresh ctx)
+        coll-fn   (:collect-fn ctx)
+        sig-fn    (:signal-fn ctx)
+        max-iter  (:max-iter ctx)
+        watch-id  (keyword (gensym))]
+    (reify
+      #?@(:clj
+           [clojure.lang.IDeref
+            (deref [_] ctx)]
+           :cljs
+           [IDeref
+            (-deref [_] ctx)])
+      IGraphExecutor
+      (stop! [_] (err/unsupported!))
+      (notify! [_ evt] (err/unsupported!))
+      (include-vertex! [_ v] (err/unsupported!))
+      (execute!
+        [_]
+        (add-watch! g :remove-vertex watch-id (fn [evt] (signal! (peek evt) sync-vertex-signal)))
+        (let [t0 (now)]
+          (loop [i 0, colls 0, sigs 0]
+            (if (<= i max-iter)
+              (let [verts (vertices g)
+                    sigs' (sig-fn verts s-thresh)
+                    colls' (coll-fn verts c-thresh)]
+                (if (and (pos? sigs') (pos? colls'))
+                  (recur (inc i) (long (+ colls colls')) (long (+ sigs sigs')))
+                  (do (remove-watch! g :remove-vertex watch-id)
+                      (execution-result :converged colls sigs t0 {:iterations i}))))
+              (do (remove-watch! g :remove-vertex watch-id)
+                  (execution-result :max-iter-reached colls sigs t0 {:iterations i})))))))))
+
 (defn stop-async-execution
   [bus vertices]
   (info "stopping execution context...")
@@ -312,12 +405,14 @@
   (let [ctx       (merge default-async-context-opts opts)
         bus       (vec (repeatedly (:bus-size ctx) chan))
         ctx       (assoc ctx :bus bus :result (or (:result ctx) (chan)))
+        g         (:graph ctx)
         processor (:processor ctx)
         c-thresh  (:collect-thresh ctx)
         s-thresh  (:signal-thresh ctx)
         max-ops   (:max-ops ctx)
         max-t     (:timeout ctx)
-        result    (:result ctx)]
+        result    (:result ctx)
+        watch-id  (keyword (gensym))]
     (reify
       #?@(:clj
            [clojure.lang.IDeref
@@ -328,23 +423,37 @@
       IGraphExecutor
       (stop!
         [_]
-        (stop-async-execution bus (vertices (:graph ctx)))
+        (stop-async-execution bus (vertices g))
+        (remove-watch! g :add-vertex watch-id)
+        (remove-watch! g :remove-vertex watch-id)
+        (remove-watch! g :add-edge watch-id)
         result)
       (notify! [_ evt]
         (go (>! (rand-nth bus) evt)))
       (include-vertex!
         [_ v]
+        (info "including vertex into async context" (:id v) @v)
         (processor v _)
+        (when (should-signal? v s-thresh)
+          (signal! v async-vertex-signal))
         (when (should-collect? v c-thresh)
           (collect! v))
-        (when (should-signal? v s-thresh)
-          (signal! v async-vertex-signal))
         _)
       (execute!
         [_]
         (let [t0 (now)]
+          (add-watch! g :add-vertex watch-id
+                      (fn [[__ v]]
+                        (info :ctx-add-vertex (:id v) @v)
+                        (processor v _)))
+          (add-watch! g :remove-vertex watch-id
+                      (fn [[__ v]] (signal! v async-vertex-signal)))
+          (add-watch! g :add-edge watch-id
+                      (fn [[__ src dest]]
+                        (info :ctx-add-edge (:id src) (:id dest))
+                        (signal! src async-vertex-signal)))
           (go
-            (run! #(include-vertex! _ %) (vertices (:graph ctx)))
+            (run! #(include-vertex! _ %) (vertices g))
             (loop [colls 0, sigs 0]
               (if (<= (+ colls sigs) max-ops)
                 (let [t (if max-t (timeout max-t))
@@ -370,84 +479,3 @@
                            :stopped result colls sigs t0)))))
                 (async-execution-result :max-ops-reached result colls sigs t0))))
           result)))))
-
-(defn sync-signal-vertices
-  [vertices thresh]
-  (loop [sigs 0, verts vertices]
-    (if verts
-      (let [v (first verts)]
-        (if (should-signal? v thresh)
-          (do (debug (:id v) "signaling")
-              (signal! v sync-vertex-signal)
-              (recur (inc sigs) (next verts)))
-          (recur sigs (next verts))))
-      sigs)))
-
-(defn sync-collect-vertices
-  [vertices thresh]
-  (loop [colls 0, verts vertices]
-    (if verts
-      (let [v (first verts)]
-        (if (should-collect? v thresh)
-          (do (debug (:id v) "collecting")
-              (collect! v)
-              (recur (inc colls) (next verts)))
-          (recur colls (next verts))))
-      colls)))
-
-(defn parallel-sync-signal-vertices
-  [vertices thresh]
-  (r/fold
-   +
-   (fn
-     ([] 0)
-     ([acc v] (if (should-signal? v thresh) (do (signal! v sync-vertex-signal) (inc acc)) acc)))
-   vertices))
-
-(defn parallel-sync-collect-vertices
-  [vertices thresh]
-  (r/fold
-   +
-   (fn
-     ([] 0)
-     ([acc v] (if (should-collect? v thresh) (do (collect! v) (inc acc)) acc)))
-   vertices))
-
-(def default-sync-context-opts
-  {:collect-thresh 0
-   :signal-thresh  0
-   :max-iter       1e6
-   :signal-fn      sync-signal-vertices
-   :collect-fn     sync-collect-vertices})
-
-(defn sync-execution-context
-  [opts]
-  (let [ctx       (merge default-sync-context-opts opts)
-        c-thresh  (:collect-thresh ctx)
-        s-thresh  (:signal-thresh ctx)
-        coll-fn   (:collect-fn ctx)
-        sig-fn    (:signal-fn ctx)
-        max-iter  (:max-iter ctx)]
-    (reify
-      #?@(:clj
-           [clojure.lang.IDeref
-            (deref [_] ctx)]
-           :cljs
-           [IDeref
-            (-deref [_] ctx)])
-      IGraphExecutor
-      (stop! [_] (err/unsupported!))
-      (notify! [_ evt] (err/unsupported!))
-      (include-vertex! [_ v] (err/unsupported!))
-      (execute!
-        [_]
-        (let [t0 (now)]
-          (loop [i 0, colls 0, sigs 0]
-            (if (<= i max-iter)
-              (let [verts (vertices (:graph ctx))
-                    sigs' (sig-fn verts s-thresh)
-                    colls' (coll-fn verts c-thresh)]
-                (if (and (pos? sigs') (pos? colls'))
-                  (recur (inc i) (long (+ colls colls')) (long (+ sigs sigs')))
-                  (execution-result :converged colls sigs t0 {:iterations i})))
-              (execution-result :max-iter-reached colls sigs t0 {:iterations i}))))))))


add giant lock around eval expressions

add giant lock around eval expressions

--- src/bzzz/queries/term_payload_clj_score.clj
+++ src/bzzz/queries/term_payload_clj_score.clj
@@ -24,16 +24,21 @@
     (.maximumWeightedCapacity b 1000)
     (.build b)))

+(def giant (Object.))
+
 (defn get-or-eval [expr]
   (if-let [v (.get ^java.util.Map expr-cache expr)]
     v
-    (let [t0 (time-ms)
-          evaluated-expr (eval (read-string expr))]
-      (index-stat/update-took-count index-stat/total
-                                    "eval"
-                                    (time-took t0))
-      (.put ^java.util.Map expr-cache expr evaluated-expr)
-      evaluated-expr)))
+    (locking giant
+      (if-let [v (.get ^java.util.Map expr-cache expr)]
+        v
+        (let [t0 (time-ms)
+              evaluated-expr (eval (read-string expr))]
+          (index-stat/update-took-count index-stat/total
+                                        "eval"
+                                        (time-took t0))
+          (.put ^java.util.Map expr-cache expr evaluated-expr)
+          evaluated-expr)))))

 (defn parse
   [generic input analyzer]


Add days-in-month to raw prodution data

Add days-in-month to raw prodution data

--- src/clj_simple_chart/ncs/raw_production.clj
+++ src/clj_simple_chart/ncs/raw_production.clj
@@ -99,6 +99,7 @@
                         (flatten)
                         (map #(assoc % :date (str (format "%04d-%02d" (:prfYear %) (:prfMonth %)))))
                         (map #(assoc % :date-int (+ (* 100 (:prfYear %)) (:prfMonth %))))
+                        (map #(assoc % :days-in-month (. (YearMonth/of (:prfYear %) (:prfMonth %)) lengthOfMonth)))
                         (map #(assoc % :prev-months (prev-12-months (:date %))))
                         (map #(assoc % :prfPrdLiquidsNetMillSm3 (reduce + 0 (mapv % [:prfPrdOilNetMillSm3 :prfPrdNGLNetMillSm3 :prfPrdCondensateNetMillSm3]))))
                         (sort-by :date)


(PE-1452) Explicitly check for nil

(PE-1452) Explicitly check for nil

--- src/com/puppetlabs/puppetdb/query/event.clj
+++ src/com/puppetlabs/puppetdb/query/event.clj
@@ -56,7 +56,7 @@
       ;; wrapped in a NOT(...) clause, so we have to be very explicit
       ;; about the NULL case.
       [(field :when #{"property" "message" "file" "line" "containing_class"})]
-      (if value
+      (if-not (nil? value)
         {:where (format "resource_events.%s = ? AND resource_events.%s IS NOT NULL" field field)
          :params [value] }
         {:where (format "resource_events.%s IS NULL" field)


Comment out redundant function

Comment out redundant function

--- src/yada/representation.clj
+++ src/yada/representation.clj
@@ -301,7 +301,7 @@
 ;; TODO: Might be able to remove this, because yada.resource now does
 ;; automatic coercions. However, still some requirement for checking bad
 ;; charsets, which could be moved into yada.resource now.
-(defn coerce-representations
+#_(defn coerce-representations
   "For performance reasons it is sensible to coerce the representations
   ahead of time, rather than on each request."
   [reps]


Log the vars that config is extracted from

--- src/yetibot/core/config.clj
+++ src/yetibot/core/config.clj
@@ -19,6 +19,16 @@
        vals
        (reduce merge)))

+
+(defn prefixed-env-vars
+  "Return a map of all env vars with known prefixes"
+  []
+  (into {} (filter (fn [[k v]]
+                     (some
+                       (fn [prefix] (.startsWith (name k) (name prefix)))
+                       config-prefixes))
+                   env)))
+
 (defn config-from-env-or-file
   "If a `CONFIG_PATH` env var is specified, load config from it.
    Otherwise, load config from env and explode it into nested maps."
@@ -26,12 +36,9 @@
   (merge-possible-prefixes
     (if-let [path (env :config-path)]
       (uc/load-edn! path)
-      (explode
-        (into {} (filter (fn [[k v]]
-                           (some
-                             (fn [prefix] (.startsWith (name k) (name prefix)))
-                             config-prefixes))
-                         env))))))
+      (let [env-vars (prefixed-env-vars)]
+        (info "Extracting config from:" \newline (with-out-str (pprint env-vars)))
+        (explode env-vars)))))

 (defonce ^:private config (atom (config-from-env-or-file)))


Counting generators of unit element

Counting generators of unit element

in the concept lattice of a given context.

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

--- src/conexp/contrib/experimental/moebius.clj
+++ src/conexp/contrib/experimental/moebius.clj
@@ -38,4 +38,31 @@

 ;;;

+(defn egen-unit-element
+  [ctx]
+  (let [ctx     (make-context (objects ctx)
+                              (difference (attributes ctx)
+                                          (set-of m | m (attributes ctx)
+                                                      :when (< 1 (count (context-attribute-closure ctx #{m}))))
+                                          (context-attribute-closure ctx #{}))
+                              (incidence ctx)),
+        intents (intents ctx)]
+    (loop [µ       {(first intents) 1},
+           intents (rest intents)]
+      (if-let [A (first intents)]
+        (let [µ (assoc µ A 0)]
+          (recur (reduce (fn [µ X]
+                           (assoc µ A (- (µ A) (µ X))))
+                         µ
+                         (all-closed-sets-in-family #(proper-subset? % A)
+                                                    (attributes ctx)
+                                                    #(context-attribute-closure ctx %)))
+                 (rest intents)))
+        (reduce (fn [sum [A µ-A]]
+                  (+ sum (* µ-A (expt 2 (count (aprime ctx A))))))
+                0
+                µ)))))
+
+;;;
+
 nil


define-ant-task and ant-task

define-ant-task and ant-task

--- lancet/ant/ant.clj
+++ lancet/ant/ant.clj
@@ -45,18 +45,22 @@
     ; (.addTask target task)
     task))

-(defn execute-ant-task [task-name]
-  (fn f [& args]
-    (let [props (if (map? (first args)) (first args) {})
-          task (instantiate-task ant-project task-name props)]
-      (.execute task))))
-
+;; temporarily removing tasks that collide with Clojure
 (def task-names
      (disj (set (map #(symbol (.getKey %)) (.getTaskDefinitions ant-project)))
 	   'import 'touch 'sync 'concat 'filter 'replace 'get 'apply))

-(defmacro define-ant-task [t]
-  `(def ~t (execute-ant-task ~(name t))))
+(defmacro ant-task [task-name & args]
+  (let [has-props? (map? (first args))
+	forms (if has-props? (rest args) args)
+	props (if has-props? (first args) {})]
+    `(let [task# (instantiate-task ant-project ~(name task-name) ~props)]
+       (doto task# ~@forms)
+       (~'.execute task#))))
+
+(defmacro define-ant-task [task-name]
+  `(defmacro ~task-name [& args#]
+     (concat (list 'ant-task '~task-name) args#)))

 (defmacro define-ant-tasks []
   `(do


add missing compiler env binding for REPL read resolve-symbol

--- src/main/shadow/cljs/repl.clj
+++ src/main/shadow/cljs/repl.clj
@@ -502,6 +502,12 @@
                     reader/*data-readers*
                     tags/*cljs-data-readers*

+                    ;; ana/resolve-symbol accesses the env
+                    ;; don't need with-compiler-env since it's read only and doesn't side effect
+                    ;; the compiler env like cljs.analyzer does
+                    env/*compiler*
+                    (atom (:compiler-env build-state))
+
                     reader/resolve-symbol
                     ana/resolve-symbol


fix filestore functionality tests

fix filestore functionality tests

--- test/konserve/core_test.clj
+++ test/konserve/core_test.clj
@@ -50,7 +50,7 @@
       (is (= (<!! (get-in store [:foo]))
              :bar))
       (is (= (<!! (list-keys store))
-             #{[:foo]}))
+             #{{:key :foo, :format :edn} {:key :binbar, :format :binary}}))
       (<!! (dissoc store :foo))
       (is (= (<!! (get-in store [:foo]))
              nil))
@@ -61,7 +61,7 @@
         (is (= @binbar (range 10))))

       (is (= (<!! (list-keys store))
-             #{})))))
+             #{{:key :binbar, :format :binary}})))))


[#674] Fix test mistakes

[#674] Fix test mistakes

--- backend/test/akvo/lumen/endpoint/collection_test.clj
+++ backend/test/akvo/lumen/endpoint/collection_test.clj
@@ -60,8 +60,8 @@
     (testing "Create an empty collection"
       (let [response (collection/create *tenant-conn* {"title" "col1"})]
         (is (= 201 (:status response)))
-        (is #{:id :title :modified :created :entities}
-            (-> response :body keys set))
+        (is (= #{:id :title :modified :created :entities}
+               (-> response :body keys set)))
         (is (= 409 (:status (collection/create *tenant-conn* {"title" "col1"}))))
         (is (= 400 (:status (collection/create *tenant-conn* {"title" nil}))))
         (is (= 400 (:status (collection/create *tenant-conn* {"title" (apply str (repeat 129 "a"))}))))))
@@ -75,7 +75,7 @@
       (let [id (-> (collection/create *tenant-conn* {"title" "col3" "entities" [ds2 vs2 db2]})
                    :body :id)
             coll (-> (collection/fetch *tenant-conn* id) :body)]
-        (is #{ds2 vs2 db2} (-> coll :entities set))))
+        (is (= #{ds2 vs2 db2} (-> coll :entities set)))))

     (testing "Update collection"
       (let [id (-> (collection/create *tenant-conn* {"title" "col4" "entities" [ds2 vs2 db2]})
@@ -106,4 +106,4 @@
         (dataset/delete *tenant-conn* ds1)
         (is (= #{ds2 vs2 db2}
                (-> (collection/fetch *tenant-conn* id)
-                   :body :entities set))) ))))
+                   :body :entities set)))))))


Updated scala-cas version

Updated scala-cas version

--- clj-cas/project.clj
+++ clj-cas/project.clj
@@ -1,9 +1,9 @@
-(defproject oph/clj-cas "0.6.1-SNAPSHOT"
+(defproject oph/clj-cas "0.6.2-SNAPSHOT"
   :description "oph clojure cas utilities"
   :url "http://example.com/FIXME"
   :license {:name "EUPL"
             :url "http://www.osor.eu/eupl/"}
   :plugins [[lein-modules "0.3.11"]]
-  :dependencies [[fi.vm.sade/scala-cas_2.12 "2.1.0-SNAPSHOT"]
+  :dependencies [[fi.vm.sade/scala-cas_2.12 "2.2.0-SNAPSHOT"]
                  [org.http4s/http4s-blaze-client_2.12 "0.16.6a"]]
 )


bug fix

bug fix

--- clj-tcp/project.clj
+++ clj-tcp/project.clj
@@ -1,4 +1,4 @@
-(defproject clj-tcp "0.2.5-SNAPSHOT"
+(defproject clj-tcp "0.2.6-SNAPSHOT"
   :description "Fast clojure tcp library based on netty"
   :url "https://github.com/gerritjvv/clj-tcp"
   :license {:name "Eclipse Public License"


Use Clojure 1.6.0

Use Clojure 1.6.0

--- clojure/project.clj
+++ clojure/project.clj
@@ -3,5 +3,5 @@
   :url "http://github.com/rabbitmq/rabbitmq-tutorial"
   :license {:name "Eclipse Public License"
             :url "http://www.eclipse.org/legal/epl-v10.html"}
-  :dependencies [[org.clojure/clojure     "1.5.1"]
+  :dependencies [[org.clojure/clojure     "1.6.0"]
                  [com.novemberain/langohr "2.7.1"]])


Fixing dependency

Fixing dependency

--- apoya-app/project.clj
+++ apoya-app/project.clj
@@ -11,7 +11,7 @@
                  [org.clojure/java.jmx "0.2.0"]
                  [ring/ring-core "1.2.0"]
                  [ring/ring-devel "1.2.0"]
-                 [fortress-ring-adapter "0.1.0-SNAPSHOT"]
+                 [org.clojars.iamedu/fortress-ring-adapter "0.1.0-SNAPSHOT"]
                  [compojure "1.1.6"]
                  [lib-noir "0.7.4"]
                  [bk/ring-gzip "0.1.1"]


Viewers are authors when the org is not on premium, they can see the same as before, but they can also post stuff.

--- src/oc/storage/api/access.clj
+++ src/oc/storage/api/access.clj
@@ -68,7 +68,9 @@
         role (cond admin?  :admin
                    member? :member
                    :else   :anonymous)
-        base-access {:role role :premium? premium?}]
+        base-access {:role role
+                     :premium? premium?}
+        premium-viewer-access (if premium? :viewer :author)]
     (cond
       ;; an admin of this org's team
       ((set admin) (:team-id org))
@@ -80,7 +82,7 @@

       ;; a team member of this org
       ((set teams) (:team-id org))
-      (merge base-access {:access-level :viewer})
+      (merge base-access {:access-level premium-viewer-access})

       ;; public access to orgs w/ at least 1 public board AND that allow public boards
       (and
@@ -122,21 +124,28 @@
         board-authors (set (:authors board))
         board-viewers (set (:viewers board))
         premium? (premium-org? org user)
-        member? ((set teams) (:team-id org))
+        org-member? ((set teams) (:team-id org))
         admin? ((set admin) (:team-id org))
-        role (cond admin?  :admin
-                   member? :member
-                   :else   :anonymous)
-        base-access {:role role :premium? premium?}]
+        role (cond admin?      :admin
+                   org-member? :member
+                   :else       :anonymous)
+        publisher-board-role (if (= (str board-res/publisher-board-slug-prefix user-id) (:slug board))
+                               :author
+                               :viewer)
+        base-access {:role     role
+                     :premium? premium?}
+        ;; viewer role is allowed only on premium
+        premium-viewer-role (if premium? :viewer :author)]
     (cond

       ;; a named author of this private board
-      (and (= board-access :private) (board-authors user-id))
+      (and (= board-access :private)
+           (board-authors user-id))
       (merge base-access {:access-level :author})

       (and (= board-access :team)
            (:publisher-board board))
-      (merge base-access {:access-level (if (= (str board-res/publisher-board-slug-prefix user-id) (:slug board)) :author :viewer)})
+      (merge base-access {:access-level publisher-board-role})

       ;; an admin of this org's team for this non-private board
       (and (not= board-access :private) ((set admin) (:team-id org)))
@@ -148,11 +157,11 @@

       ;; a named viewer of this board
       (and (= board-access :private) (board-viewers user-id))
-      (merge base-access {:access-level :viewer})
+      (merge base-access {:access-level premium-viewer-role})

       ;; a team member on a non-private board
       (and (not= board-access :private) ((set teams) (:team-id org)))
-      (merge base-access {:access-level :viewer})
+      (merge base-access {:access-level premium-viewer-role})

       ;; anyone else on a public board IF the org allows public boards
       (and (= board-access :public) (not (-> org :content-visibility :disallow-public-board)))
@@ -179,12 +188,17 @@
       access)))

 (defn allow-premium
+  "
+  Given an org slug and a user map, return an access level of :author or :viewer if the user is a team member
+  of a premium org, false otherwise.
+  "
   [conn org-slug user]
-  (let [access (access-level-for conn org-slug user)]
-    (if (or (= (:access-level access) :premium)
-            (not (:premium? access)))
-      false
-      access)))
+  (let [access (allow-members conn org-slug user)]
+    (if (and (:access-level access)
+             (not= (:access-level access) :public)
+             (:premium? access))
+      access
+      false)))

 (defn allow-authors
   "
@@ -196,6 +210,7 @@
   (let [access (access-level-for conn org-slug user)
         access-level (:access-level access)]
     (if (or (= access-level :author)
+            ;; Allow to fail existence check later
             (= access-level :does-not-exist))
       access
       false)))


Update default config

Update default config

--- src/overtone/config/store.clj
+++ src/overtone/config/store.clj
@@ -11,7 +11,9 @@

 (def CONFIG-DEFAULTS
   {:os (get-os)
-   :user-name (capitalize (system-user-name))})
+   :user-name (capitalize (system-user-name))
+   :server :internal
+   :sc-args []})

 (def config* (ref {}))
 (def live-config (partial live-file-store config*))