repl connected to eventing

repl connected to eventing

--- src/overtone/app/repl.clj
+++ src/overtone/app/repl.clj
@@ -1,272 +1,87 @@
 (ns overtone.app.repl
   (:gen-class)
-  (:import
-   (javax.swing JFrame JEditorPane JScrollPane JPanel JTextField SwingUtilities JButton)
-   (java.awt Toolkit EventQueue Dimension Point)
-   (java.awt Dimension Color Font RenderingHints Point BasicStroke)
-     )

-  (comment :import
+  (:import
    (java.io StringReader PushbackReader OutputStreamWriter PrintWriter)
    (java.util.concurrent LinkedBlockingQueue)
-   (jsyntaxpane DefaultSyntaxKit)
-   (javax.swing.text.BadLocationException)
-   (javax.swing.text.DefaultStyledDocument)
-   (java.awt Dimension BorderLayout))
+   (clojure.lang IDeref))
+
+  (:require [clojure.main :as r])
+
+  (:use clojure.contrib.seq-utils)
+  (:use [clojure.stacktrace :only (e)])
+
+  (:use overtone.core.event))

-  (:import
-   java.awt.event.ActionEvent
-   java.awt.event.KeyEvent
-   javax.swing.AbstractAction
-   javax.swing.JFrame
-   javax.swing.JTextField
-   javax.swing.KeyStroke
-   javax.swing.text.AttributeSet
-   javax.swing.text.BadLocationException
-   javax.swing.text.DefaultStyledDocument)
-
-  (:use [hiredman.hydra :only [hydra]])
-  (:require [clj_repl.core :as r]))
+(defn outputstream-with-cb [cb]
+  (let [buffer (StringBuffer.)]
+    (proxy [java.io.OutputStream IDeref] []
+      (deref [] buffer)
+      (flush []
+             (when (< 0 (.length buffer))
+               (let [sb (.toString buffer)]
+                 (cb sb)
+                 (.setLength buffer 0))))
+      (close [] (.flush this))
+      (write
+       ([i] (.append buffer (char i)))
+       ([buf off len]
+          (doseq [i (take len (drop off buf))]
+            (.append buffer (char i))))))))

-;; Swing macros
+(defmacro capture-out-write [cb & body]
+  `(binding [`~*out* (PrintWriter. (OutputStreamWriter. (outputstream-with-cb ~cb)))]
+     ~@body))
+
 (comment
-(defmacro EDT
-  "runs body on the Event-Dispatch-Thread (Swing)"
-  [& body]
-  `(SwingUtilities/invokeLater (fn [] ~@body)))
-
-(defmacro action-performed [component event & body]
-  `(. ~component addActionListener
-      (proxy [java.awt.event.ActionListener] []
-        (actionPerformed [~event] ~@body))))
-
-(defn -main []
-  (EDT
-   (let [frame      (JFrame.)
-         content    (.getContentPane frame)
-         editor     (JEditorPane.)
-         scroll     (JScrollPane. editor)
-         panel      (JPanel.)
-         prompt     (JTextField.)
-         text-field (JTextField.)
-
-         toolbar    (JPanel.)
-         tb-init    (JButton. "1. init")
-         tb-boot    (JButton. "2. boot")
-         tb-quit    (JButton. "5. quit")
-         tb-mn      (JButton. "4. make noise")
-         tb-slog    (JButton. "3. server log")
-         queue      (hydra)]
-
-     (DefaultSyntaxKit/initKit)
-
-     (doto tb-init
-       (action-performed event (do
-                                 (r/send-to-repl queue "(use 'overtone.live)(refer-ugens)")
-                                 (r/send-to-repl queue "(refer-ugens)")
-                                 (EDT (let [ doc (.getDocument editor)
-                                            length (.getLength doc)]
-                                        (.insertString doc length ";; Make sure jackd is started" nil)))
-                                 )))
-
-     (doto tb-boot
-       (action-performed event (r/send-to-repl queue "(boot)")))
-
-     (doto tb-quit
-       (action-performed event (r/send-to-repl queue "(quit)")))
-
-     (doto tb-mn
-       (action-performed event (do
-
-                                 (r/send-to-repl queue "(defsynth foo (sin-osc 440))")
-                                 (r/send-to-repl queue "(foo)")
-
-                                 )))
-
-     (doto tb-slog
-       (action-performed event (do
-                                 (r/send-to-repl queue "(print-server-log)")
-                                 (EDT (let [ doc (.getDocument editor)
-                                            length (.getLength doc)]
-                                        (.insertString doc length ";; No errors ? Now connect your jack ports and start transport and get ready to make some noise !" nil)))
-                                 )))
-
-     (doto toolbar
-       (.add tb-init)
-       (.add tb-boot)
-       (.add tb-slog)
-       (.add tb-mn)
-       (.add tb-quit))
-
-     (doto queue
-       (r/start-repl-thread (fn [q itm] (EDT
-                                         (let [ doc (.getDocument editor)
-                                               length (.getLength doc)]
-                                           (.insertString doc length itm nil))))
-
-                            (fn [q ns] (EDT
-                                        (.setText prompt (str ns))))))
-
-     (doto prompt
-       (.setEditable false)
-       (.setPreferredSize (Dimension. 150 20)))
-
-     (doto text-field
-       (action-performed event
-                         (EDT
-                          (r/send-to-repl queue (.getText text-field))
-                          (.setText text-field "")))
-       (.setPreferredSize (Dimension. 300 20)))
-
-     (doto panel
-       (.setPreferredSize (Dimension. 300 30))
-       (.add prompt)
-       (.add text-field)
-       (.doLayout))
-
-     (doto editor
-       (.setContentType "text/clojure")
-       (.setEditable false))
-
-     (doto content
-       (.setLayout  (BorderLayout.))
-       (.add scroll (BorderLayout/CENTER))
-       (.add panel  (BorderLayout/SOUTH))
-       (.add toolbar (BorderLayout/NORTH)))
-
-     (doto frame
-       (.pack)
-       (.setVisible true)
-       (.setDefaultCloseOperation JFrame/EXIT_ON_CLOSE))
-
-     (doto text-field
-       (.requestFocus)))))
-)
-
-(def #^{:doc "balanced pairs"}
-     pairs '((\( \))
-             (\[ \])
-             (\" \")
-             (\{ \})))
-
-(defn balanced?
-  "are all the pairs balanced in this string?"
-  [string]
-  ((comp not some)
-   false?
-   (map
-    (fn [pair] (-> pair set (filter string) count (mod 2) zero?))
-    pairs)))
-
-(def prompt "hello ")1
-(defn get-prompt-length [] (.length prompt))
-
-(defn make-prompt-doc []
-  (proxy [DefaultStyledDocument] []
-    (insertString [offs str a] (if (> offs (- (get-prompt-length) 1))
-                                 (.insertString (.getSuperClass this) offs str a)))
-    (remove [offs len] (if (> offs (- (get-prompt-length) 1))
-                         (let [buffer (- offs (get-prompt-length))]
-                           (.remove (.getSuperClass this) offs (if (< buffer 0) buffer len)))))))
+  (def temp (ref ""))
+  (capture-out-write #(dosync (ref-set temp (str "from callback: " %))) (println "hiiii"))
+  (println @temp))

-(def prompt-doc (make-prompt-doc))

-(defn  doc-gettext [] (.getText (.getSuperClass prompt-doc) (- (.getLength prompt-doc) (get-prompt-length))))
-
-(defn doc-set-prompt [new-prompt]
-  (try
-   (let [length (.getLength prompt-doc)]
-     (if (> 0 length) (.remove (.getSuperClass prompt-doc) 0 length)))))
-
-(defn make-prompt-replace-action []
-  (proxy [AbstractAction] []
-    (actionPerformed [e]
-                     (try
-                      (def prompt (str (.getText prompt-doc) " >") )))))
-
-(defn repl-window []
-  (let [frame      (JFrame.)
-        content    (.getContentPane frame)
-
-        history     (JTextField. prompt-doc "" 20)
-        history-scroll (JScrollPane. history (JScrollPane/VERTICAL_SCROLLBAR_NEVER) (JScrollPane/HORIZONTAL_SCROLLBAR_NEVER))
-
-        prompt     (JTextField.)
-
-        input (JEditorPane.)
-        input-scroll (JScrollPane. input (JScrollPane/VERTICAL_SCROLLBAR_NEVER) (JScrollPane/HORIZONTAL_SCROLLBAR_NEVER))
-
-        panel      (JPanel.)
-        queue      (hydra)
-
-        print      (fn [m] (EDT
-                            (let [ doc (.getDocument history)
-                                  length (.getLength doc)]
-                              (.insertString doc length m nil))))
-
-        send       (fn [m] (do (r/send-to-repl queue m)
-                               (print m)))
-
-        cls-input  (fn [] (EDT (.setText input "")))
-
-        ]
-
-    (DefaultSyntaxKit/initKit)
-
-    (doc-set-prompt prompt)
-
-    (doto queue
-      (r/start-repl-thread (fn [q itm] (print itm))
-                           (fn [q ns] (EDT
-                                       (.setText prompt (str ns))))))
-
-    (doto prompt
-      (.setEditable true)
-      (.setPreferredSize (Dimension. 150 20)))
-
-    (doto input  ;       (.setContentType "text/clojure")
-      (.setPreferredSize (Dimension. 400 150))
-      (.setFont (Font. "SansSerif" (Font/PLAIN) 20))
-      (.setBackground (Color. 200 200 200 )))
-
-;    (doto (.getKeymap input)
-;      (.addActionForKeyStroke
-;       (javax.swing.KeyStroke/getKeyStroke (java.awt.event.KeyEvent/VK_ENTER) 0)
-;       (proxy [javax.swing.AbstractAction] [] (actionPerformed [evt]  (let [text (.getText input)]
-;                                                                        (if (and (not (empty? text))
-;                                                                                (balanced? text))
-;                                                                          (do (send text)
-;                                                                              (cls-input)
-;                                                                              (.requestFocus input))))))))
-
-    (doto panel
-      (.setLayout (BorderLayout.))
-      (.add prompt (BorderLayout/NORTH))
-      (.add input-scroll (BorderLayout/CENTER))
-      (.doLayout))
-
-    (doto history                     ;       (.setContentType "text/clojure")
-      (.setEditable true)
-      )
-
-    (.put (.getActionMap history) "NewPrompt" (make-prompt-replace-action))
-    (.put (.getInputMap history) (KeyStroke/getKeyStroke (KeyEvent/VK_ENTER) 0) "NewPrompt")
-
-    (doto content
-      (.setLayout  (BorderLayout.))
-      (.add history-scroll (BorderLayout/CENTER))
-      (.add panel  (BorderLayout/SOUTH)))
-
-    (doto frame ;(.setDefaultCloseOperation JFrame/EXIT_ON_CLOSE)
-      (.pack)
-      (.setVisible true))
-
-    (do
-      (send "(in-ns 'user)"))
-
-    (doto input
-      (.requestFocus))))
+(defn start-repl-thread [] (future (try
+                                 (capture-out-write #(event ::repl-print :text %)
+                                                    (let [read-q (LinkedBlockingQueue.)
+                                                          exit (ref false)]
+
+                                                      (on ::repl-write #(.put read-q (PushbackReader. (StringReader. (:text %)))))
+                                                      (on ::repl-exit #((dosync (ref-set exit true))
+                                                                        (Thread/sleep 300)
+                                                                        (event ::repl-write :text "(println \"exit hack\")")))
+
+                                                      (clojure.main/repl
+                                                       :init (fn [] (event ::repl-ready))
+                                                       :caught (fn [x]
+                                                                 (binding [*e x] (e))
+                                                                 (.flush *out*)
+                                                                 (println ""))
+                                                       :need-prompt (constantly true)
+                                                       :prompt #(do (event ::repl-prompt :text (str (ns-name *ns*))))
+                                                       :read (fn [a b]
+                                                               (if @exit
+                                                                 b
+                                                                 (binding [*in* (.take read-q)]
+                                                                   (r/repl-read a b))))))
+
+                                                    (event ::repl-exited))
+                                 (catch Exception e
+                                   (event ::repl-exception :text (pr-str e))))))

 (comment
-  (-main))
+
+  (start-repl-thread)
+
+  (on ::repl-exception #(println (str "exception: " (:text %))))
+  (on ::repl-prompt #(println (str "prompt: " (:text %))))
+  (on ::repl-print #(println (str "print: " (:text %))))
+
+  (on ::repl-exited #(println "repl exited"))
+
+  (event ::repl-ready #(println "repl ready"))
+  (event ::repl-exit)
+
+  (event ::repl-write :text "(println \"hello world\")"))
+
+;(defn repl []
+;  )


Namespace synth names. Fixes #153

Namespace synth names. Fixes #153

--- src/overtone/sc/synth.clj
+++ src/overtone/sc/synth.clj
@@ -569,6 +569,7 @@
   (let [[s-name s-form] (name-with-attributes s-name s-form)
         _               (when (not (symbol? s-name))
                           (throw (IllegalArgumentException. (str "You need to specify a name for your synth using a symbol"))))
+        s-name          (symbol (str (ns-name *ns*) "/" s-name))
         params          (first s-form)
         params          (parse-params params)
         ugen-form       (concat '(do) (next s-form))


Added height, width, and frame-count functions.

--- src/rosado/processing.clj
+++ src/rosado/processing.clj
@@ -360,7 +360,11 @@
 ;; $$focusGained
 ;; $$focusLost

+(defn frame-count [] (.frameCount *applet*))
+
 (defn framerate [new-rate] (.frameRate *applet* (float new-rate)))
+
+(def frame-rate frame-rate)

 (defn frustum
   [l r b t near far]
@@ -376,6 +380,8 @@

 ;; $$handleDraw
 ;; $$hex
+
+(defn height [] (.getHeight *applet*))

 (defn hint [which] (.hint *applet* (int which)))

@@ -826,6 +832,8 @@

 ;; utility functions. clj-processing specific

+(defn width [] (.getWidth *applet*))
+
 (defmacro with-translation
   "Berforms body with translation, restores current transformation on exit."
   [translation-vector & body]


Add shrunk result to returned value

Add shrunk result to returned value

Now you can see both what the original failure and the most shrunk
failure returned.

--- src/simple_check/core.clj
+++ src/simple_check/core.clj
@@ -61,18 +61,21 @@
      ~expr))

 (defn- smallest-shrink
-  [total-nodes-visited depth smallest-args]
+  [total-nodes-visited depth smallest-args smallest-result]
   {:total-nodes-visited total-nodes-visited
    :depth depth
+   :result smallest-result
    :smallest smallest-args})

 (defn- safe-apply-props
   [prop args]
   (try (apply prop args)
-    (catch Throwable t
-      ; assuming that this `t` is of the same type that was
-      ; originally thrown in quick-check...
-      false)))
+    (catch Throwable t t)))
+
+(defn not-falsey-or-exception?
+  "True if the value is not falsy or an exception"
+  [value]
+  (and value (not (instance? Throwable value))))

 (defn- shrink-loop
   "Shrinking a value produces a sequence of smaller values of the same type.
@@ -86,28 +89,32 @@
   * If a node fails the property, search it's children
   The value returned is the left-most failing example at the depth where a
   passing example was found."
-  [prop failing]
+  [prop failing failing-result]
   (let [shrinks-this-depth (gen/shrink failing)]
     (loop [nodes shrinks-this-depth
            f failing
+           result failing-result
            total-nodes-visited 0
-           depth 0
-           can-set-new-best? true]
+           depth 0]
       ; TODO why does this cause failures? (or (empty? nodes) (>= total-nodes-visited 10000))
       (if (empty? nodes)
-        (smallest-shrink total-nodes-visited depth f)
+        (smallest-shrink total-nodes-visited depth f failing-result)
         (let [[head & tail] nodes]
-          (if (safe-apply-props prop head)
-            ;; this node passed the test, so now try testing it's right-siblings
-            (recur tail f (inc total-nodes-visited) depth can-set-new-best?)
-            ;; this node failed the test, so check if it has children,
-            ;; if so, traverse down them. If not, save this as the best example
-            ;; seen now and then look at the right-siblings
-            ;; children
-            (let [children (gen/shrink head)]
-              (if (empty? children)
-                (recur tail head (inc total-nodes-visited) depth false)
-                (recur children head (inc total-nodes-visited) (inc depth) true)))))))))
+          (let [head-result (safe-apply-props prop head)]
+            (if (not-falsey-or-exception? head-result)
+              ;; this node passed the test, so now try testing it's right-siblings
+              (recur tail f failing-result
+                     (inc total-nodes-visited) depth)
+              ;; this node failed the test, so check if it has children,
+              ;; if so, traverse down them. If not, save this as the best example
+              ;; seen now and then look at the right-siblings
+              ;; children
+              (let [children (gen/shrink head)]
+                (if (empty? children)
+                  (recur tail head head-result (inc total-nodes-visited)
+                         depth)
+                  (recur children head head-result (inc total-nodes-visited)
+                         (inc depth)))))))))))

 (defn- failure
   [property property-fun result trial-number size failing-params]
@@ -116,5 +123,5 @@
    :failing-size size
    :num-tests trial-number
    :fail (vec failing-params)
-   :shrunk (shrink-loop property-fun failing-params)})
+   :shrunk (shrink-loop property-fun failing-params result)})


improve formatting

improve formatting

--- src/babel/over.cljc
+++ src/babel/over.cljc
@@ -98,7 +98,7 @@
           (if (not (= true head-pre-checks))
             (log/warn (str "moreover-head: pre-check missed: fail-path-between "
                            "parent:'" (get-in parent [:rule]) "' and child with pred:"
-                           (get-in child [:rule] (get-in child [:synsem :sem :pred] :nopred)) ":"
+                           (get-in child [:rule] (get-in child [:synsem :sem :pred] :nopred)) " ; "
                            (let [{path :fail-path
                                   parent-value :val1
                                   head-value :val2} (fail-path parent {:head child})]


Fix nil passed to block/list as options map.

--- src/blocks/core.clj
+++ src/blocks/core.clj
@@ -205,7 +205,10 @@
   (let [allowed-keys #{:algorithm :after :limit}
         opts-map (cond
                    (empty? opts) nil
-                   (and (= 1 (count opts)) (map? (first opts))) (first opts)
+                   (and (= 1 (count opts))
+                        (or (map? (first opts))
+                            (nil? (first opts))))
+                     (first opts)
                    :else (apply hash-map opts))
         bad-opts (set/difference (set (keys opts-map)) allowed-keys)]
     (when (not-empty bad-opts)


Printing message to *out* so I can know when to go grab coffee

--- jvm-runner/test/codewars/runner/clojure_test.clj
+++ jvm-runner/test/codewars/runner/clojure_test.clj
@@ -86,6 +86,7 @@
     (with-in-str
       (json/generate-string
        {:language "clojure"
-        :solution "(Thread/sleep 50000)"})
+        :solution "(println \"...Sleeping deeply...\")
+                   (Thread/sleep 50000)"})
       (with-redefs [core/fail #(throw %)]
         (is (thrown? TimeoutException (-main)))))))


bind gif-building

bind gif-building

--- src/cellf/core.cljs
+++ src/cellf/core.cljs
@@ -241,7 +241,7 @@
         (.render)))))

-(defn modal [{:keys [stream media-error show-about? result-gif cells win-state grid-size] :as app}]
+(defn modal [{:keys [stream media-error show-about? result-gif cells win-state grid-size tick-ms gif-building?] :as app}]
   (let [winner?    (and cells (= cells win-state))
         no-stream? (not stream)]
     (dom/div #js {


Add help-cmd-entry-delimiter.

Add help-cmd-entry-delimiter.

--- src/cli4clj/cli.clj
+++ src/cli4clj/cli.clj
@@ -79,16 +79,19 @@
         (print-err (str "Invalid command: \"" arg "\". Please type \"help\" to get an overview of commands."))))))

 (defn create-cli-help-fn
-  [cmds]
+  [options]
   (fn []
-    (let [command-names (sort (keys cmds))]
+    (let [cmds (:cmds options)
+          command-names (sort (keys cmds))
+          cmd-entry-delimiter (:help-cmd-entry-delimiter options)]
       (doseq [c command-names]
         (if (map? (cmds c))
           (do
             (println (str (name c) "\t" (get-in cmds [c :short-info])))
             (when-let [li (get-in cmds [c :long-info])]
-              (println (str "\t" (get-in cmds [c :long-info])))))
-          (println (str (name c) "\tSee: " (name (cmds c)))))))))
+              (println (str "\t" li)))
+            (print cmd-entry-delimiter))
+          (println (str (name c) "\tSee: " (name (cmds c)) cmd-entry-delimiter)))))))

 (def cli-mandatory-default-options
   {:cmds {:exit {:fn (fn [] (System/exit 0))
@@ -112,6 +115,7 @@
           :q :exit}
    :eval-factory create-cli-eval-fn
    :help-factory create-cli-help-fn
+   :help-cmd-entry-delimiter "\n"
    :print cli-repl-print
    :print-err print-err-fn
    :prompt cli-repl-prompt
@@ -127,7 +131,7 @@
 (defn get-cli-opts
   [user-options]
   (let [merged-opts (merge-options cli-default-options user-options cli-mandatory-default-options)]
-    (assoc-in merged-opts [:cmds :help :fn] ((merged-opts :help-factory) (merged-opts :cmds)))))
+    (assoc-in merged-opts [:cmds :help :fn] ((merged-opts :help-factory) merged-opts))))

 (defn start-cli
   ([]


when returns nil if it doesn't match

when returns nil if it doesn't match

--- src/tile_game/solver.cljc
+++ src/tile_game/solver.cljc
@@ -59,7 +59,7 @@
 (defn solved-tiles [board]
   (let [solution (b/create-board (b/dimension board))]
     (take-while (comp not nil?)
-                (map #(if (= %1 %2) %1 nil) board solution))))
+                (map #(when (= %1 %2) %1) board solution))))

 (defn solve-tile [board tile]
   (let [solved (set (solved-tiles board))


Simplifying consistency tests of `exists' and `forall'

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

--- src/conexp/base.clj
+++ src/conexp/base.clj
@@ -506,9 +506,7 @@
   "Implements logical forall quantor. Bindings is of the form [var-1
   seq-1 var-2 seq-2 ...]. Returns boolean value."
   [bindings condition]
-  (when-not (let [c (count bindings)]
-              (and (<= 0 c)
-                   (zero? (mod c 2))))
+  (when-not (even? (count bindings))
     (illegal-argument "forall requires even number of bindings."))
   `(boolean ~(expand-bindings (map vec (partition 2 bindings)) condition)))

@@ -516,9 +514,7 @@
   "Implements logical exists quantor. Bindings is of the form [var-1
   seq-1 var-2 seq-2 ...]. Returns boolean value."
   [bindings condition]
-  (when-not (let [c (count bindings)]
-              (and (<= 0 c)
-                   (zero? (mod c 2))))
+  (when-not (even? (count bindings))
     (illegal-argument "exists requires even number of bindings."))
   `(not ~(expand-bindings (map vec (partition 2 bindings)) `(not ~condition))))


Fixed option def for underscores

Fixed option def for underscores

--- src/video_server/main.clj
+++ src/video_server/main.clj
@@ -89,9 +89,9 @@
     :default 720
     :parse-fn #(Integer/parseInt %)
     :validate [#{480 720 1080 2160} "The size must be 480, 720, 1080 or 2160"]]
-   ["-u" "--underscores" "Use underscores in generated filenames"
-    :default false
-    :flag true]
+   ["-u" "--underscores BOOL" "Use underscores in generated filenames"
+    :default "false"
+    :parse-fn #(Boolean/parseBoolean %)]
    [nil "--log-level LEVEL" "Override the default logging level"
     :parse-fn log-level
     :validate [identity "The log level must be one of ALL, TRACE, DEBUG, INFO, WARN, ERROR or OFF"]]


fix daw pixel bug

fix daw pixel bug

--- src/curve/core.cljs
+++ src/curve/core.cljs
@@ -28,7 +28,7 @@

 (defn draw-pixel [image data x y r g b & a]
   (println "draw-pixel" x y r g b (first a))
-  (let [offset (+ (* x 4) (* y (.-height image) 4))]
+  (let [offset (+ (* x 4) (* y (.-width image) 4))]
     (aset data offset r)
     (aset data (+ offset 1) g)
     (aset data (+ offset 2) b)
@@ -72,7 +72,7 @@
         (draw-pixel-color image data y x color)
         (draw-pixel-color image data x y color))
       (let [error (- error dy)]
-        (println "error" error)
+        ;(println "error" error)
         (if (< error 0)
           (recur image data x1 y1 x2 y2 dx dy (+ error dx) (+ x 1) (+ y ystep) ystep color steep)
               (recur image data x1 y1 x2 y2 dx dy error (+ x 1) y ystep color steep))))))
@@ -97,7 +97,8 @@
         image (.createImageData ctx canvas-width canvas-height)
         data (.-data image)]
     ;(draw-pixel image data 0 0 0 0 0) ;test
-    ;(draw-pixel-color image data 20 20 [255 0 0]) ;test
+    ;(run! (fn [x] (draw-pixel-color image data 0 x [255 0 0])) (range 30 600 1))
+    ;(draw-pixel-color image data 200 200 [255 0 0]) ;test
     (draw-line image data 30 30 200 200 [0 0 0])
     (.putImageData ctx image 0 0)))


Freezing Actions development, still not working. Will probably be removed before official release.

--- lambdalf-lib/src/main/clojure/alfresco/seq.clj
+++ lambdalf-lib/src/main/clojure/alfresco/seq.clj
@@ -3,7 +3,7 @@
             [alfresco.model :as m]
             [alfresco.auth :as a]))

-(defn ts
+(defn to-seq
   "Returns a lazy seq of the nodes representing the repository branch
 having the given root. Uses the currently authenticated user to realize
 the seq."


Add fps option to defgame.

Add fps option to defgame.

--- src/ezglib/game.clj
+++ src/ezglib/game.clj
@@ -3,16 +3,22 @@
 (defmacro defgame
   "Defs an ezglib game."
   [name & {:keys [width height element element-id game-id modes mode canvas
-                 assets on-load load-update start-on-load? preload]}]
+                 assets on-load load-update start-on-load? preload fps]}]
   (let [pre (if preload `(~preload) `(fn [] nil))
         onld (if on-load
                (if start-on-load?
-                 '(fn []
-                    (~on-load)
-                    (ezglib.game/main-loop! ~name))
+                 (if fps
+                   '(fn []
+                     (~on-load)
+                     (ezglib.game/main-loop! ~name ~fps))
+                   '(fn []
+                     (~on-load)
+                     (ezglib.game/main-loop! ~name)))
                  on-load)
                (if start-on-load?
-                 `(fn [] (ezglib.game/main-loop! ~name))
+                 (if fps
+                   `(fn [] (ezglib.game/main-loop! ~name ~fps))
+                   `(fn [] (ezglib.game/main-loop! ~name)))
                  `(fn [] nil)))
         ast (if assets
               `(ezglib.asset/load!


[#3] Match eastwood files to repo projects.

--- src/gbu/webhook.clj
+++ src/gbu/webhook.clj
@@ -1,5 +1,6 @@
 (ns gbu.webhook
   (:require [clojure.data.json :as json]
+            [clojure.java.io :as io]
             popen)
   (:import java.io.File))

@@ -17,37 +18,58 @@
   [url sha]
   (let [path       (make-tmp-dir)
         clone      (popen/popen ["git" "clone" url path] :redirect true :dir ".")
+        _          (println "Cloning" url "to" path "...")
         _          (popen/join clone)
         checkout   (popen/popen ["git" "checkout" sha] :redirect true :dir path)
+        _          (println "Checking out" sha "...")
         _          (popen/join checkout)]
     path))

 (defn- run-eastwood
   [path]
   (let [lein      (popen/popen ["lein" "eastwood" "{:results-file true}"] :redirect true :dir path)
+        _          (println "Running eastwood...")
         code      (popen/join lein)]
     (when-not (zero? code)
       (let [results-txt (slurp (str path "/eastwood-results.txt"))]
         (read-string (str "[" results-txt "]"))))))

+(defn- find-file [files ends-with]
+  (->> files
+    (filter #(.endsWith (.getCanonicalPath %) ends-with))
+    first))
+
+(defn- relative-to-project
+  [dir file]
+  (-> file
+    .getCanonicalPath
+    (.replaceAll (str ".*/" dir "/") "")))
+
+(defn- result-full-path
+  [files project-dir {path :file :as result}]
+  (if-let [file (find-file files path)]
+    (assoc result :file (relative-to-project project-dir file))
+    result))
+
 (defn- handle-pull-req
+  "Clones the repo and checks out the PR's latest sha.
+Does a best effort to match the path returned by eastwood to
+a file in the project."
   [pr-event]
   (let [pull-req  (:pull_request pr-event)
         sha       (get-in pull-req [:head :sha])
-        repo      (:repo pull-req)
+        repo      (get-in pull-req [:head :repo])
         url       (:clone_url repo)
-        path      (clone-repo url sha)
-        result    (run-eastwood path)]
-    ()))
+        dirname   (clone-repo url sha)
+        results   (run-eastwood dirname)]
+    (when results
+      (let [files   (file-seq (io/file dirname))
+            results (map (partial result-full-path files dirname) results)]
+
+        results))))

 (defmulti handle-event ^:private
   (fn [event-type _] (keywordize event-type)))
-
-(defn run
-  [event-type event-raw]
-  (let [event (and (seq event-raw)
-                   (json/read-str event-raw))]
-    (handle-event event-type event)))

 (defmethod handle-event :ping
   [_ event]
@@ -58,4 +80,13 @@
   [_ event]
   (future (handle-pull-req event))
   {:status 200
-   :body "Your PR is being processed..."})+   :body "Your PR is being processed..."})
+
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+;; API
+
+(defn run
+  [event-type event-raw]
+  (let [event (and (seq event-raw)
+                   (json/read-str event-raw :key-fn keyword))]
+    (handle-event event-type event)))


rewrite adjectives : [:pred] -> [:mod :pred]

--- src/babel/english/lexicon.cljc
+++ src/babel/english/lexicon.cljc
@@ -273,7 +273,7 @@
    "black"
    (unify adjective
           {:synsem {:cat :adjective
-                    :sem {:pred :nero
+                    :sem {:mod {:pred :black}
                           :comparative false
                           :physical-object true
                           :human false}}})
@@ -1327,7 +1327,7 @@
    "red"
    (unify adjective
           {:synsem {:cat :adjective
-                    :sem {:pred :rosso
+                    :sem {:mod {:pred :rosso}
                           :comparative false
                           :physical-object true
                           :human false}}})
@@ -1523,7 +1523,7 @@
           subject-agr (atom :top)]
       (unify adjective
              {:synsem {:cat :adjective
-                       :sem {:pred :alto
+                       :sem {:mod {:pred :alto}
                              :comparative false
                              :arg1 subject-sem
                              :human true}


fix typo

fix typo

--- src/babel/english/lexicon.cljc
+++ src/babel/english/lexicon.cljc
@@ -703,7 +703,7 @@
                     :sem {:pred :fill}}}

    "find" {:synsem {:cat :verb
-                     :sem {:pred :break }}
+                     :sem {:pred :find}}
                      :english {:past "found"}}


+coffee,+salad

+coffee,+salad

--- src/babel/english/lexicon.cljc
+++ src/babel/english/lexicon.cljc
@@ -459,6 +459,9 @@
    "close" {:synsem {:cat :verb
                      :sem {:pred :close}}}

+   "coffee" {:synsem {:cat :noun
+                      :sem {:pred :coffee}}}
+
    "come" {:synsem {:cat :verb
                     :sem {:pred :come
                           :subj {:animate true}}}
@@ -1577,6 +1580,9 @@
                                  :sem of
                                  :subcat '()}}}})]

+   "salad" {:synsem {:cat :noun
+                     :sem {:pred :salad}}}
+
    "say" {:english {:past "said"}
           :synsem {:cat :verb
                    :sem {:pred :say}}}


pred from avere to have

pred from avere to have

--- src/babel/italiano/lexicon.clj
+++ src/babel/italiano/lexicon.clj
@@ -295,7 +295,7 @@
        transitive
        avere-common
        {:note "avere (possess)"
-        :synsem {:sem {:pred :avere
+        :synsem {:sem {:pred :have
                        :activity false
                        :discrete false
                        :subj {:human true}
@@ -308,7 +308,7 @@
        verb-subjective
        intransitive-unspecified-obj
        {:note "avere (possess): unspecified object"
-        :synsem {:sem {:pred :avere
+        :synsem {:sem {:pred :have
                        :activity false
                        :discrete false
                        :subj {:human true}}}})


Removed unnecessary call to open-domain as load-domain calls it internally and returns the result.

--- src/clj/elephantdb/service.clj
+++ src/clj/elephantdb/service.clj
@@ -77,9 +77,6 @@
                      remote-path
                      (domain/host-shards (domains-info domain))))
       ;; use cached domain from local-dir (no update needed)
-      (open-domain local-config
-                   (str (path local-dir domain))
-                   (domain/host-shards (domains-info domain)))
       )))

 (defn sync-data-updated [domains-info global-config local-config]


Add descriptive docstrings to some http functions.

--- src/clojure/catacumba/http.clj
+++ src/clojure/catacumba/http.clj
@@ -30,55 +30,159 @@
   ([body headers] (response body 100 headers)))

 (defn ok
+  "HTTP 200 OK
+  Should be used to indicate nonspecific success. Must not be used to
+  communicate errors in the response body.
+
+  In most cases, 200 is the code the client hopes to see. It indicates that
+  the REST API successfully carried out whatever action the client requested,
+  and that no more specific code in the 2xx series is appropriate. Unlike
+  the 204 status code, a 200 response should include a response body."
   ([body] (response body 200))
   ([body headers] (response body 200 headers)))

 (defn created
+  "HTTP 201 Created
+  Must be used to indicate successful resource creation.
+
+  A REST API responds with the 201 status code whenever a collection creates,
+  or a store adds, a new resource at the client's request. There may also be
+  times when a new resource is created as a result of some controller action,
+  in which case 201 would also be an appropriate response."
   ([location] (response "" 201 {:location location}))
   ([location body] (response body 201 {:location location}))
   ([location body headers] (response body 201 (merge headers {:location location}))))

 (defn accepted
+  "HTTP 202 Accepted
+  Must be used to indicate successful start of an asynchronous action.
+
+  A 202 response indicates that the client's request will be handled
+  asynchronously. This response status code tells the client that the request
+  appears valid, but it still may have problems once it's finally processed.
+  A 202 response is typically used for actions that take a long while to
+  process."
   ([body] (response body 202))
   ([body headers] (response body 202 headers)))

 (defn no-content
+  "HTTP 204 No Content
+  Should be used when the response body is intentionally empty.
+
+  The 204 status code is usually sent out in response to a PUT, POST, or
+  DELETE request, when the REST API declines to send back any status message
+  or representation in the response message's body. An API may also send 204
+  in conjunction with a GET request to indicate that the requested resource
+  exists, but has no state representation to include in the body."
   ([] (response "" 204))
   ([headers] (response "" 204 headers)))

 (defn moved-permanently
+  "301 Moved Permanently
+  Should be used to relocate resources.
+
+  The 301 status code indicates that the REST API's resource model has been
+  significantly redesigned and a new permanent URI has been assigned to the
+  client's requested resource. The REST API should specify the new URI in
+  the response's Location header."
   ([location] (response "" 301 {:location location}))
   ([location body] (response body 301 {:location location}))
   ([location body headers] (response body 301 (merge headers {:location location}))))

 (defn found
+  "HTTP 302 Found
+  Should not be used.
+
+  The intended semantics of the 302 response code have been misunderstood
+  by programmers and incorrectly implemented in programs since version 1.0
+  of the HTTP protocol.
+  The confusion centers on whether it is appropriate for a client to always
+  automatically issue a follow-up GET request to the URI in response's
+  Location header, regardless of the original request's method. For the
+  record, the intent of 302 is that this automatic redirect behavior only
+  applies if the client's original request used either the GET or HEAD
+  method.
+
+  To clear things up, HTTP 1.1 introduced status codes 303 (\"See Other\")
+  and 307 (\"Temporary Redirect\"), either of which should be used
+  instead of 302."
   ([location] (response "" 302 {:location location}))
   ([location body] (response body 302 {:location location}))
   ([location body headers] (response body 302 (merge headers {:location location}))))

 (defn see-other
+  "HTTP 303 See Other
+  Should be used to refer the client to a different URI.
+
+  A 303 response indicates that a controller resource has finished its work,
+  but instead of sending a potentially unwanted response body, it sends the
+  client the URI of a response resource. This can be the URI of a temporary
+  status message, or the URI to some already existing, more permanent,
+  resource.
+  Generally speaking, the 303 status code allows a REST API to send a
+  reference to a resource without forcing the client to download its state.
+  Instead, the client may send a GET request to the value of the Location
+  header."
   ([location] (response "" 303 {:location location}))
   ([location body] (response body 303 {:location location}))
   ([location body headers] (response body 303 (merge headers {:location location}))))

 (defn temporary-redirect
+  "HTTP 307 Temporary Redirect
+  Should be used to tell clients to resubmit the request to another URI.
+
+  HTTP/1.1 introduced the 307 status code to reiterate the originally
+  intended semantics of the 302 (\"Found\") status code. A 307 response
+  indicates that the REST API is not going to process the client's request.
+  Instead, the client should resubmit the request to the URI specified by
+  the response message's Location header.
+
+  A REST API can use this status code to assign a temporary URI to the
+  client's requested resource. For example, a 307 response can be used to
+  shift a client request over to another host."
   ([location] (response "" 307 {:location location}))
   ([location body] (response body 307 {:location location}))
   ([location body headers] (response body 307 (merge headers {:location location}))))

 (defn bad-request
+  "HTTP 400 Bad Request
+  May be used to indicate nonspecific failure.
+
+  400 is the generic client-side error status, used when no other 4xx error
+  code is appropriate."
   ([body] (response body 400))
   ([body headers] (response body 400 headers)))

 (defn unauthorized
+  "HTTP 401 Unauthorized
+  Must be used when there is a problem with the client credentials.
+
+  A 401 error response indicates that the client tried to operate on a
+  protected resource without providing the proper authorization. It may have
+  provided the wrong credentials or none at all."
   ([body] (response body 401))
   ([body headers] (response body 401 headers)))

 (defn forbidden
+  "HTTP 403 Forbidden
+  Should be used to forbid access regardless of authorization state.
+
+  A 403 error response indicates that the client's request is formed
+  correctly, but the REST API refuses to honor it. A 403 response is not a
+  case of insufficient client credentials; that would be 401 (\"Unauthorized\").
+  REST APIs use 403 to enforce application-level permissions. For example, a
+  client may be authorized to interact with some, but not all of a REST API's
+  resources. If the client attempts a resource interaction that is outside of
+  its permitted scope, the REST API should respond with 403."
   ([body] (response body 403))
   ([body headers] (response body 403 headers)))

 (defn not-found
+  "HTTP 404 Not Found
+  Must be used when a client's URI cannot be mapped to a resource.
+
+  The 404 error status code indicates that the REST API can't map the
+  client's URI to a resource."
   ([body] (response body 404))
   ([body headers] (response body 404 headers)))


Don't read project.clj multiple times during build commands

--- src/clojure/nightcode/lein.clj
+++ src/clojure/nightcode/lein.clj
@@ -30,13 +30,6 @@

 ; utilities

-(defn java-project-map?
-  [project]
-  (or (:java-only project)
-      (= (count (:source-paths project)) 0)
-      (clojure.set/subset? (set (:source-paths project))
-                           (set (:java-source-paths project)))))
-
 (defn read-file
   [path]
   (let [length (.length (io/file path))]
@@ -98,13 +91,16 @@
   (or (.exists (io/file path "AndroidManifest.xml"))
       (.exists (io/file path "AndroidManifest.template.xml"))))

-(defn ios-project?
-  [path]
-  (.exists (io/file path "Info.plist.xml")))
+(defn java-project-map?
+  [project]
+  (or (:java-only project)
+      (= (count (:source-paths project)) 0)
+      (clojure.set/subset? (set (:source-paths project))
+                           (set (:java-source-paths project)))))

 (defn java-project?
   [path]
-  (some-> path read-project-clj java-project-map?))
+  (-> path read-project-clj java-project-map?))

 (defn clojurescript-project?
   [path]
@@ -118,16 +114,19 @@
   [path]
   (-> path read-project-clj :clr some?))

+(defn ring-project-map?
+  [project]
+  (let [{:keys [ring main]} project]
+    (and (some? ring) (nil? main))))
+
 (defn ring-project?
   [path]
-  (let [{:keys [ring main]} (read-project-clj path)]
-    (and (some? ring) (nil? main))))
+  (-> path read-project-clj ring-project-map?))

 (defn valid-project?
   [path]
-  (and (not (ios-project? path))
-       (or (not (android-project? path))
-           (not (sandbox/get-dir)))))
+  (not (and (sandbox/get-dir)
+            (android-project? path))))

 ; start/stop thread/processes

@@ -201,15 +200,13 @@
     (android-project? path)
     (some-> (read-android-project project)
             (leiningen.droid/doall []))
-    (ios-project? path)
-    nil
-    (clr-project? path)
+    (:clr project)
     (leiningen.clr/clr project "run")
-    (ring-project? path)
+    (ring-project-map? project)
     (leiningen.ring/ring project "server")
     :else
     (do
-      (when (clojurescript-project? path)
+      (when (:cljsbuild project)
         (leiningen.cljsbuild/cljsbuild project "once"))
       (leiningen.run/run project))))

@@ -221,7 +218,7 @@
       (doseq [cmd ["deploy" "repl"]]
         (leiningen.droid/execute-subtask project cmd [])
         (Thread/sleep 10000)))
-    (clr-project? path)
+    (:clr project)
     (leiningen.clr/clr project "repl")
     :else
     (leiningen.repl/repl project)))
@@ -234,11 +231,9 @@
             read-android-project
             (assoc-in [:android :build-type] :release)
             leiningen.droid/doall)
-    (ios-project? path)
-    nil
-    (clr-project? path)
+    (:clr project)
     (leiningen.clr/clr project "compile")
-    (gwt-project? path)
+    (:gwt project)
     (leiningen.gwt/gwt project "compile")
     :else
     (leiningen.uberjar/uberjar project)))
@@ -251,7 +246,7 @@
                              (if (:cljsbuild project) "check-cljs" "check"))
       (catch Exception _)))
   (cond
-    (clr-project? path)
+    (:clr project)
     (leiningen.clr/clr project "test")
     :else
     (leiningen.test/test project)))
@@ -259,7 +254,7 @@
 (defn clean-project-task
   [path project]
   (cond
-    (clr-project? path)
+    (:clr project)
     (leiningen.clr/clr project "clean")
     :else
     (leiningen.clean/clean project)))


Packages should be sorted by its names

Packages should be sorted by its names

--- src/clouseau/text_renderer.clj
+++ src/clouseau/text_renderer.clj
@@ -40,7 +40,7 @@

 (defn render-package-descriptions
     [package-descriptions]
-    (for [p package-descriptions]
+    (for [p (into (sorted-map) package-descriptions)]
         (str "[" (key p) "]\n"
                  (val p) "\n\n")))


don't give react a clojure map

don't give react a clojure map

--- src/hyper/terse.clj
+++ src/hyper/terse.clj
@@ -66,7 +66,7 @@
   (let [forms (html-recur body)]
     `~(if (= 1 (count forms))
           (first forms)
-          (concat ['om.dom/div {}] forms))))
+          (concat ['om.dom/div (js-obj)] forms))))

 '(fun stuff)


[#1142] Set gradient color to max when only one shape on map

--- backend/src/akvo/lumen/lib/visualisation/map_config.clj
+++ backend/src/akvo/lumen/lib/visualisation/map_config.clj
@@ -184,7 +184,7 @@
                     'hsl(%s, 75%%, ',
                     100 - floor(
                       CASE
-                        WHEN (select max(aggregation) from temp_table)::decimal=(select min(aggregation) from temp_table)::decimal THEN 0
+                        WHEN (select max(aggregation) from temp_table)::decimal=(select min(aggregation) from temp_table)::decimal THEN 50
                         ELSE
                           (
                             (aggregation::decimal - (select min(aggregation) from temp_table)::decimal) /


Remove extraneous println

Remove extraneous println

--- src/async_ring/core.clj
+++ src/async_ring/core.clj
@@ -148,7 +148,6 @@
               (let [value (async/alt!
                             resp-chan ([resp] resp)
                             error-chan ([e] {::error e}))
-                    _ (println "result was" value)
                     result (post-process value)]
                 (if result
                   (async/>! (:async-response req) result)


looking for source of eagerness in (defn generate-all)

--- src/babel/generate.cljc
+++ src/babel/generate.cljc
@@ -11,7 +11,7 @@

 ;; during generation, will not decend deeper than this when creating a tree:
 ;; TODO: should also be possible to override per-language.
-(def ^:const max-total-depth 10)
+(def ^:const max-total-depth 2)

 ;; use map or pmap.
 (def ^:const mapfn map)
@@ -43,11 +43,11 @@
   (let [depth (or depth 0)
         truncate truncate
         max-depth (or max-depth max-total-depth)]
-    (log/debug (str "generate-all:" depth "/" max-depth ":         " (strip-refs spec)))
+    (log/trace (str "generate-all:" depth "/" max-depth ":         " (strip-refs spec)))
     (->>
      (lightning-bolts model spec depth max-depth)
      (filter not-fail?)
-     (map (fn [bolt]
+     (map (fn [bolt] ;; create a map of paths within the bolt to possible complements in the bolt.
             (assoc
              (comp-paths-to-complements bolt (find-comp-paths bolt) model depth max-depth)
              [] [bolt])))
@@ -71,7 +71,7 @@
             (do-defaults expression model)))
      (filter not-fail?)
      (map (fn [final]
-            (log/info (str "final: " ((:morph-ps model) final)))
+            (log/trace (str "final: " ((:morph-ps model) final)))
             final)))))

 (defn generate
@@ -169,7 +169,7 @@
 (defn comp-path-to-complements
   "return a lazy sequence of bolts for all possible complements that can be added to the end of the _path_ within _bolt_."
   [bolt path model depth max-depth]
-  (log/debug (str "comp-path-to-complements:" depth "/" max-depth ":" ((:morph-ps model) bolt) "@" path))
+  (log/trace (str "comp-path-to-complements:" depth "/" max-depth ":" ((:morph-ps model) bolt) "@" path))
   (let [spec (get-in bolt path)
         lexemes (shufflefn (get-lexemes model spec))
         bolts-at (if (< depth max-depth)


decrease total depth to study non-laziness of generation

--- src/babel/generate.cljc
+++ src/babel/generate.cljc
@@ -15,8 +15,8 @@
                                         deserialize serialize
                                         )]))

-;; during generation, will not search deeper than this:
-(def ^:const max-total-depth 6)
+;; during generation, will not decend deeper than this when creating a tree:
+(def ^:const max-total-depth 2)

 ;; use map or pmap.
 (def ^:const mapfn map)


Rename label to app-db

Rename label to app-db

--- src/day8/re_frame/trace/app_db.cljs
+++ src/day8/re_frame/trace/app_db.cljs
@@ -15,6 +15,18 @@
        (map #(str/split % #":"))
        (reduce (fn [acc [property value]]
                  (assoc acc (keyword property) value)) {})))
+
+(def config {:well-known-types #{"cljs.core/Keyword"}
+
+             :render-bools     false
+             :render-strings   false
+             :render-numbers   false
+             :render-keywords  false
+             :render-symbols   false
+             :render-instances false
+             :render-types     false
+             :render-functions false
+             })

 (declare jsonml->hiccup)

@@ -74,7 +86,7 @@
             (and @expanded?
               (or (string? data)
                   (number? data)))  [:div {:style {:margin "10px 0"}} data]
-            @expanded?              (jsonml->hiccup (cljs-devtools/header-api-call data)))]])))
+            @expanded?              (jsonml->hiccup (cljs-devtools/header-api-call data config :extra)))]])))

 (defn render-state  [data]
   (let [subtree-input  (r/atom "")
@@ -113,4 +125,4 @@
                                  [:span.subtree-button-string
                                    (str path)]]]]])
                 @subtree-paths))]
-          [subtree @data [:span.label "app-state"]]]])))
+          [subtree @data [:span.label "app-db"]]]])))


A couple of tests which touched Redis had snuck in

--- test/exploud/web_test.clj
+++ test/exploud/web_test.clj
@@ -342,6 +342,7 @@
                                                                                :user "user"}))
       => (contains {:status 200})
       (provided
+       (deployments/locked?) => false
        (util/generate-id) => "id"
        (deployments/begin {:application "application"
                            :environment "environment"
@@ -361,6 +362,7 @@
                                                                                :user nil}))
       => (contains {:status 200})
       (provided
+       (deployments/locked?) => false
        (util/generate-id) => "id"
        (deployments/begin {:application "application"
                            :environment "environment"
@@ -378,6 +380,7 @@
                                                                                :user "user"}))
       => (contains {:status 200})
       (provided
+       (deployments/locked?) => false
        (deployments/undo {:application "application"
                           :environment "environment"
                           :message "message"
@@ -391,6 +394,7 @@
                                                                                :user "user"}))
       => (contains {:status 200})
       (provided
+       (deployments/locked?) => false
        (util/generate-id) => "id"
        (deployments/rollback {:application "application"
                               :environment "environment"
@@ -431,12 +435,14 @@
       (request :post "/1.x/applications/application/environment/resume")
       => (contains {:status 409})
       (provided
+       (deployments/locked?) => false
        (deployments/paused? {:application "application" :environment "environment" :region "eu-west-1"}) => false))

 (fact "that attempting to resume a deployment which is paused gives a 200"
       (request :post "/1.x/applications/application/environment/resume")
       => (contains {:status 200})
       (provided
+       (deployments/locked?) => false
        (deployments/paused? {:application "application" :environment "environment" :region "eu-west-1"}) => true
        (deployments/resume {:application "application" :environment "environment" :region "eu-west-1"}) => anything))


Extract do-post fn for json posts

Extract do-post fn for json posts

--- src/discuss/communication/main.cljs
+++ src/discuss/communication/main.cljs
@@ -5,7 +5,8 @@
             [discuss.references.integration :as rint]
             [discuss.communication.lib :as comlib]
             [discuss.components.search.statements :as search]
-            [discuss.utils.logging :as log]))
+            [discuss.utils.logging :as log]
+            [discuss.config :as config]))

 ;; Handler
 (defn process-url-handler
@@ -19,19 +20,21 @@

 ;;;; POST functions
+(defn- do-post [request-url body handler error-handler headers]
+  (log/info (str "Posting " body " to " request-url))
+  (POST request-url
+        {:body            (lib/clj->json body)
+         :handler         handler
+         :error-handler   error-handler
+         :format          :json
+         :response-format :json
+         :headers         headers
+         :keywords?       true}))
+
 (defn post-json
   "Wrapper to prepare a POST request. Sending and receiving JSON."
   ([url body handler headers]
-   (let [request-url (comlib/make-url url)]
-     (log/info (str "Posting " body " to " request-url))
-     (POST request-url
-           {:body            (lib/clj->json body)
-            :handler         handler
-            :error-handler   comlib/error-handler
-            :format          :json
-            :response-format :json
-            :headers         headers
-            :keywords?       true})))
+   (do-post (comlib/make-url url) body handler comlib/error-handler headers))
   ([url body handler]
    (post-json url body handler {"Content-Type" "application/json"}))
   ([url body]
@@ -74,6 +77,23 @@
       (post-json url body process-url-handler headers))
     (log/error ":api/last-call is empty, cannot post statement to empty URL.")))

+(defn after-eden-post-handler []
+  (lib/change-view-next! :eden/overview))
+
+(defn post-eden-argument
+  "Post an Argument directly to EDEN for later usage."
+  [{:keys [premise conclusion reference search/selected]}]
+  (let [request-url (str (lib/host-eden) (:add/argument config/eden))
+        headers {"Content-Type" "application/json"}
+        handler after-eden-post-handler
+        author (lib/get-nickname)
+        body {:premise premise
+              :conclusion (if (nil? selected) conclusion (:text selected))
+              :author-id 42
+              :reference reference
+              :link-type :support}]
+    (do-post request-url body handler comlib/error-handler headers)))
+

 ;;;; Get things started!
 (defn init-with-references!


Update error displaying

Update error displaying

--- src/discuss/communication/main.cljs
+++ src/discuss/communication/main.cljs
@@ -34,9 +34,10 @@
 ;;;; Handlers
 (defn error-handler
   "Generic error handler for ajax requests."
-  [{:keys [status status-text]}]
+  [{:keys [status status-text response]}]
+  (cond
+    (= 400 status) (lib/error-msg! (:error (:location (first (:errors response))))))
   (.log js/console (str "I feel a disturbance in the Force... " status " " status-text))
-  (lib/error-msg! (str status " " status-text))
   (lib/loading? false))

 (defn success-handler-next-view


update tests to generate a new token, add it to datomic, and use the generated token

--- test/gangway/web_test.clj
+++ test/gangway/web_test.clj
@@ -4,8 +4,12 @@
             [immutant.messaging :as msg]
             [immutant.util]
             [clojure.data.json :as json]
+            [galleon]
+            [gangway.auth :as gw-auth]
             [gangway.util :as gw-util]
             [gangway.web :as gw-web]))
+
+(def token (:token (gw-auth/add-queue-token! "Testing" 3 (:db-conn galleon/system))))

 (def invalid-message
   (json/json-str
@@ -29,7 +33,7 @@
 (deftest remote-http-test-malformed
   (let [result (http/post
                 (format "%s/gangway/in/showevidence" (immutant.util/app-uri))
-                {:headers {"Authorization" "Token T0_V&(1AZ#U1$X3EXQL@K!OJ568G4&3DL55!5MU16E#E6TY%KV!3O1QB&L2!QSXT"}
+                {:headers {"Authorization" (format "Token %s" token)}
                  :body invalid-message
                  :throw-exceptions false})]
     (testing "malformed request (missing a required field)"
@@ -38,7 +42,7 @@
 (deftest remote-http-test-success
   (let [result (http/post
                 (format "%s/gangway/in/showevidence" (immutant.util/app-uri))
-                {:headers {"Authorization" "Token T0_V&(1AZ#U1$X3EXQL@K!OJ568G4&3DL55!5MU16E#E6TY%KV!3O1QB&L2!QSXT"}
+                {:headers {"Authorization" (format "Token %s" token)}
                  :body valid-message
                  :throw-exceptions false})]
     (testing "successful request"
@@ -47,7 +51,7 @@
 (deftest remote-http-test-authentication-incorrect-token
   (let [result (http/post
                 (format "%s/gangway/in/showevidence" (immutant.util/app-uri))
-                {:headers {"Authorization" "Token thistokenisinvalid"}
+                {:headers {"Authorization" "Token thisisnotavalidtoken"}
                  :body valid-message
                  :throw-exceptions false})]
     (testing "incorrect authentication token"


update

update

--- src/jepsen/tidb.clj
+++ src/jepsen/tidb.clj
@@ -42,6 +42,12 @@
           (c/exec :tar :xzf "tso-server.tar.gz")
           (c/exec :chmod :+x "tso-server")
           (c/exec :mv :-f "tso-server" "/root")
+
+          (info node "installing interpreter")
+          (c/exec :tar :xzf "interpreter.tar.gz")
+          (c/exec :chmod :+x "interpreter")
+          (c/exec :mv :-f "interpreter" "/root")
+
           (info node "installing themis")
           (c/exec :cp :-f "themis-coprocessor-1.0-SNAPSHOT-jar-with-dependencies.jar" "/root/hbase/lib")
           (c/exec :cp :-f "hbase-site.xml" "/root/hbase/conf")
@@ -127,7 +133,9 @@
             :--
             (str "-L=error")
             (str "-P=3306")
-            (str "-lease=1")
+            ; use a very large lease to prevent crash when network partition.
+            ; so we must create all schemas before test.
+            (str "-lease=3600")
             (str "-store=hbase")
             (c/lit (str "-path=\"" store-path "\""))
             :> tidb-log
@@ -148,7 +156,7 @@
   [node]
   (c/su
     (info node "starting hbase")
-    (meh (c/exec :mkdir :-p "/tmp/hbase"))))
+    (c/exec :mkdir :-p "/tmp/hbase")
     (meh (c/exec "/root/hbase/bin/start-hbase.sh"))))

 (defn stop-hbase!
@@ -157,13 +165,32 @@
   (c/su
     (info node "stopping hbase")
     ; call stop-hbase.sh is very slow, so here we kill java forcely.
-    (meh (cu/grepkill "java"))
+    (cu/grepkill "java")
+    (Thread/sleep 2000)
     ; (meh (c/exec "/root/hbase/bin/stop-hbase.sh"))
-    (meh (c/exec :rm :-rf "/root/hbase/logs/*"))
-    (meh (c/exec :rm :-rf "/var/lib/hbase/*"))
-    (meh (c/exec :rm :-rf "/tmp/hbase/*"))
+    ;(meh (c/exec :rm :-rf "/var/lib/hbase/"))
+    ;(meh (c/exec :rm :-rf "/root/hbase/logs/"))
+    (meh (c/exec :rm :-rf "/tmp/hbase/"))
     )
   (info node "hbase stopped"))
+
+(defn eval!
+  "Evals a sql string from the command line."
+  [s]
+  (c/exec :echo s | "/root/interpreter"
+          :-lease 0
+          :-store "hbase"
+          (c/lit (str "-dbpath=\"" store-path "\""))
+          :> "/var/log/interpreter.log"))
+
+(defn setup-db!
+  "Initialize TiDB database."
+  [node]
+  (info node "begin to setup tidb database.")
+  (eval! (str "create table if not exists dirty
+              (id     int not null primary key,
+              x       bigint not null);")))
+

 (defn db
   "Sets up and tears down TiDB"
@@ -173,15 +200,15 @@
             (install-tidb! node)

             (when (= node :n1)
-              ;(install-hbase! node)
+              (install-hbase! node)
               (start-hbase! node)
               (start-tso-server! node)
-              (Thread/sleep 5000))
+              (Thread/sleep 10000)
+              (setup-db! node))

             (jepsen/synchronize test)
             (start-tidb-server! node)

-            (Thread/sleep 1000)
             (jepsen/synchronize test)
             (info node "set up"))

@@ -189,7 +216,7 @@
                (stop-tidb-server! node)
                (when (= node :n1)
                  (stop-tso-server! node)
-                 ; (stop-hbase! node)
+                 (stop-hbase! node)
                  )
                (info node "tore down"))))

@@ -267,11 +294,6 @@
   (setup! [this test node]
           (j/with-db-connection
             [c (conn-spec node)]
-            ; Create table
-            (j/execute! c ["create table if not exists dirty
-                           (id      int not null primary key,
-                           x       bigint not null)"])
-            ; Create rows
             (dotimes [i n]
               (try
                 (with-txn-retries


Work on implementing total metrics iterator

--- src/beehive/metrics.clj
+++ src/beehive/metrics.clj
@@ -45,7 +45,7 @@
     (counter-to-map m)))

 (deftype SingleIterator
-  [start-millis iterator-start-millis func ^:unsynchronized-mutable is-realized?]
+  [start-millis iterator-start-millis metrics func ^:unsynchronized-mutable is-realized?]
   Iterator
   (next [this]
     (if is-realized?
@@ -53,7 +53,7 @@
       (do (set! is-realized? true)
           {:start-millis start-millis
            :end-millis iterator-start-millis
-           :counts (func)})))
+           :counts (func metrics)})))
   (hasNext [this]
     (not is-realized?))
   (remove [_]
@@ -73,15 +73,14 @@
     (throw (UnsupportedOperationException. "remove"))))

-(defn decorate1 [^Metrics precipice-metrics]
+(defn decorate1 [{:keys [start-millis precipice-metrics]}]
   (let [current-millis (System/currentTimeMillis)]
     (if (instance? Rolling precipice-metrics)
       (->MetricIterator
         current-millis
         counter-to-map
         (.intervals ^Rolling precipice-metrics))
-      ;; TODO: Figure out start millis
-      (->SingleIterator 0 current-millis switcher false))))
+      (->SingleIterator start-millis current-millis precipice-metrics switcher false))))

 (defprotocol CountsView


Try a different kind of true?

Try a different kind of true?

--- src/caesium/binding.clj
+++ src/caesium/binding.clj
@@ -225,7 +225,7 @@
 (def ^Sodium sodium
   "The sodium library singleton instance."
   (-> (LibraryLoader/create Sodium)
-      (.option LibraryOption/IgnoreError true)
+      (.option LibraryOption/IgnoreError Boolean/TRUE)
       (.load "sodium")))

 (assert (#{0 1} (.sodium_init sodium)))


Document sodium instance

Document sodium instance

--- src/caesium/binding.clj
+++ src/caesium/binding.clj
@@ -47,6 +47,7 @@
     ^long ^{LongLong {}} msglen]))

 (def ^Sodium sodium
+  "The sodium library singleton instance."
   (let [loader (LibraryLoader/create Sodium)]
     (.load loader "sodium")))


Updating for spatial refactoring.

Updating for spatial refactoring.

--- src/cmr/search/results_handlers/atom_spatial_results_handler.clj
+++ src/cmr/search/results_handlers/atom_spatial_results_handler.clj
@@ -4,7 +4,7 @@
             [cmr.spatial.polygon :as poly]
             [cmr.spatial.point :as p]
             [cmr.spatial.mbr :as m]
-            [cmr.spatial.ring :as r]
+            [cmr.spatial.geodetic-ring :as gr]
             [cmr.spatial.line :as l]
             [clojure.string :as str]))

@@ -54,7 +54,7 @@
     (x/element :georss:box {} (shape->string mbr)))

-  cmr.spatial.ring.Ring
+  cmr.spatial.geodetic_ring.GeodeticRing
   (shape->string
     [ring]
     (points-map->points-str ring))


Fix 'follow project' buttons and add a little copy.

--- frontend/components/add_projects.cljs
+++ frontend/components/add_projects.cljs
@@ -97,7 +97,7 @@
             should-build? (repo-model/should-do-first-follower-build? repo)]
         (html
          (cond (repo-model/can-follow? repo)
-               [:li.repo-follow {:class (when should-build? "repo-1stfollow")}
+               [:li.repo-follow
                 [:div.proj-name
                  [:span {:title (str (vcs-url/project-name (:vcs_url repo))
                                      (when (:fork repo) " (forked)"))}
@@ -110,6 +110,9 @@
                                                                                :type type)])
                                           (when should-build?
                                             (om/set-state! owner :building? true)))
+                           :title (if should-build?
+                                    "This project has never been built by CircleCI before. Clicking will cause CircleCI to start building the project."
+                                    "This project has been built by CircleCI before. Clicking will cause builds for this project to show up for you in the UI.")
                            :data-spinner true}
                   (if should-build? "Build project" "Watch project")])]


try out two different ways of waiting for an API call to complete

--- frontend/components/add_projects.cljs
+++ frontend/components/add_projects.cljs
@@ -11,7 +11,8 @@
             [sablono.core :as html :refer-macros [html]]
             [clojure.string :as string]
             [goog.string :as gstring]
-            [goog.string.format]))
+            [goog.string.format])
+  (:require-macros [cljs.core.async.macros :as am :refer [go go-loop alt!]]))

 (defn missing-scopes-notice [current-scopes missing-scopes]
   [:div
@@ -64,6 +65,42 @@
      "Get started by selecting your GitHub username or organization on the left."]
     [:li "Choose a repo you want to test and we'll do the rest!"]]])

+(defn start-first-build-after-follow
+  "Starts first build by tapping the API channel and starting a build when we successfully follow"
+  [repo-id controls-ch api-ch]
+  (let [api-tap (chan (sliding-buffer 10))
+        timeout (async/timeout 30000)]
+    (async/tap (async/mult api-ch) api-tap)
+    (go-loop []
+             (alt! api-tap ([v]
+                              (condp = v
+                                [:followed-repo :success repo-id]
+                                (do (put! controls-ch [:start-first-build {:repo-id repo-id}])
+                                    (close! api-tap))
+
+                                [:followed-repo :failed repo-id] (close! api-tap)
+
+                                nil (println "not recurring on closed channel")
+
+                                (recur)))
+
+                   timeout (do (close! api-tap)
+                               (print "gave up on first build after 30 seconds"))))))
+
+(defn start-first-build-after-follow-watcher
+  "Starts first build by watching app-state noticing when we successfully follow"
+  [app repo-id controls-ch]
+  (let [listener-id (utils/uuid)]
+    (add-watch app listener-id (fn [_ _ _ new-state]
+                                 (when (->> new-state
+                                            :current-repos
+                                            (filter #(= repo-id (repo-model/id %)))
+                                            first
+                                            :following)
+                                   (remove-watch app listener-id)
+                                   (put! controls-ch [:start-first-build {:repo-id repo-id}]))))
+    (js/setTimeout #(remove-watch app listener-id) 30000)))
+
 (defn repo-item [data owner opts]
   (reify
     om/IRender
@@ -71,17 +108,21 @@
       (let [repo (:repo data)
             repo-id (repo-model/id repo)
             controls-ch (:controls-ch data)
-            settings (:settings data)]
+            api-ch (:api-ch data)
+            settings (:settings data)
+            should-build? (repo-model/should-do-first-follower-build? repo)]
         (html
          (cond (repo-model/can-follow? repo)
-               [:li.repo-follow {:class (when (repo-model/should-do-first-follower-build? repo) "repo-1stfollow")}
+               [:li.repo-follow {:class (when should-build? "repo-1stfollow")}
                 [:div.proj-name
                  [:span {:title (str (vcs-url/project-name (:vcs_url repo))
                                      (when (:fork repo) " (forked)"))}
                   (:name repo)]
                  (when (:fork repo)
                    [:span.forked (str " (" (vcs-url/org-name (:vcs_url repo)) ")")])]
-                [:button {:on-click #(put! controls-ch [:followed-repo repo-id])
+                [:button {:on-click #(do (when should-build?
+                                           (start-first-build-after-follow repo-id controls-ch api-ch))
+                                         (put! controls-ch [:followed-repo repo-id]))
                           ;; XXX implement data-spinner
                           :data-spinner "true"}
                  [:span "Follow"]]]
@@ -147,10 +188,11 @@
         (html
          [:div.repo-filter
           [:i.fa.fa-search]
-          [:input.unobtrusive-search.input-large {:placeholder "Filter repos..."
-                                                  :type "search"
-                                                  :value repo-filter-string
-                                                  :onChange #(put! controls-ch [:edit-repo-filter-string (.. % -target -value)])}]])))))
+          [:input.unobtrusive-search.input-large
+           {:placeholder "Filter repos..."
+            :type "search"
+            :value repo-filter-string
+            :onChange #(put! controls-ch [:edit-repo-filter-string (.. % -target -value)])}]])))))

 (defn main [data owner opts]
   (reify
@@ -158,6 +200,7 @@
     (render [_]
       (let [user (:current-user data)
             controls-ch (:controls-ch data)
+            api-ch (:api-ch data)
             settings (:settings data)
             repos (:repos data)
             repo-filter-string (get-in settings [:add-projects :repo-filter-string])]
@@ -177,6 +220,7 @@
                                             repos)]
                  (map (fn [repo] (om/build repo-item {:repo repo
                                                       :controls-ch controls-ch
+                                                      :api-ch api-ch
                                                       :settings settings}))
                       filtered-repos))]))
           invite-modal])))))
@@ -187,6 +231,7 @@
     (render [_]
       (let [user (:current-user data)
             controls-ch (get-in data [:comms :controls])
+            api-ch (get-in data [:comms :api])
             settings (:settings data)]
         (html
          ;; XXX flashes
@@ -210,5 +255,6 @@
            (om/build main {:user user
                            :repos (:current-repos data)
                            :controls-ch controls-ch
+                           :api-ch api-ch
                            :settings settings})]
           [:div.sidebar]])))))


Genericize bottom section

Genericize bottom section

--- frontend/components/integrations.cljs
+++ frontend/components/integrations.cljs
@@ -167,8 +167,10 @@
                       {:title "Watch how to get started in minutes"
                        :text [:span "This video shows step-by-step how to configure CircleCI to test your application and deploy to Heroku, and how CircleCI keeps defects from getting into production. "
                     "See our docs for a " [:a {:href "/docs/continuous-deployment-with-heroku#part-2-multiple-environments"} "followup video"] " showing how to setup a more robust continuous delivery pipeline with staging and prod environments."]
-                       :graphic [:div {:dangerouslySetInnerHTML {:__html ""}}]}]}
-   :saucelabs {:hero {:header [:span "Test with " [:img {:src (utils/cdn-path "/img/outer/integrations/sauce.png") :style {:width "300px"}}] " on CircleCI"]
+                       :graphic [:div {:dangerouslySetInnerHTML {:__html ""}}]}]
+            :bottom-header "Ready for world-class continuous delivery?"
+            :secondary-cta [:span "Want more information? See our " [:a {:href "/docs/continuous-deployment-with-heroku"} "complete documentation"] " on deploying to Heroku."]}
+   :saucelabs {:hero {:header [:span "Test with " [:img {:src (utils/cdn-path "/img/outer/integrations/sauce.png") :style {:width ""}}] " on CircleCI"]
                       :text "Test with as many browsers as you want, in parallel."}}})

 (defrender integration [app owner]
@@ -196,6 +198,6 @@
                    [:h2 (:title bullet)]
                    [:p (:text bullet)]]])]
                [:div.bottom-section
-                [:h2 "Ready for world-class continuous delivery?"]
+                [:h2 (:bottom-header data)]
                 [:a {:role "button"} "Sign up for Free"]
-                [:p "Want more information? See our " [:a {:href "/docs/continuous-deployment-with-heroku"} "complete documentation"] " on deploying to Heroku."]]])))))
+                [:p (:secondary-cta data)]]])))))


Genericize hero

Genericize hero

--- frontend/components/integrations.cljs
+++ frontend/components/integrations.cljs
@@ -152,45 +152,53 @@
                         [:a {:href "/security" :title "Security"} "Learn how."]]]]]
                     ]]]])))))

+(def integration-data
+  {:heroku {:hero {:header [:span "Deploy to " [:img {:src (utils/cdn-path "img/outer/integrations/heroku-icon.svg") :alt "Heroku" :style {:vertical-align "-35%"}}] " from CircleCI"]
+                   :text "Experience a simple, modern continuous delivery workflow now."}
+            :bullets [{:title nil
+                       :content nil
+                       :graphic nil}]}})
+
 (defrender integration [app owner]
   (let [integration (get-in app [:navigation-data :integration])]
     (if (= integration :docker)
       (om/build docker app)
-      (html [:div#integrations.generic
-             [:div.top-section.heroku
-              [:div.line]
-              [:div.hero-wrapper
-               [:div.hero
-                [:div.integration-icon
-                 [:img {:src (utils/cdn-path "/img/outer/integrations/integration-icon.svg")}]]
-                [:div
-                 [:h1 "Deploy to " [:img {:src (utils/cdn-path "img/outer/integrations/heroku-icon.svg") :alt "Heroku" :style {:vertical-align "-35%"}}] " from CircleCI"]
-                 [:p "Experience a simple, modern continuous delivery workflow now."]]
-                [:a {:role "button"} "Sign up for CircleCI"]]]]
-             [:div.middle-section
-              [:div.bullet
-               [:div.content
-                [:h2 "Test before you deploy. Always."]
-                [:p "Heroku revolutionized the way developers think about deployment. Being able to deploy with a simple "
-                 [:code "git push heroku master"] " is an amazing thing. But setting up a proper continuous delivery workflow means automating every step of the process. With CircleCI whenever you push a commit to master, it will go through a complete continuous delivery pipeline. All of your tests will run with our blazing fast parallelism, and" [:em " only if they pass, "] "your code will be pushed to Heroku automatically."]]
-               [:div.graphic
-                [:img {:src (stefon/data-uri "/img/status-logos/success.svg")}]]]
-              [:div.bullet
-               [:div.graphic
-                [:div.console
-                 [:pre
-                  "deployment:\n  staging:\n    branch: " [:span.value "master"] "\n    heroku:\n      appname: " [:span.value "my-app"]]]]
-               [:div.content
-                [:h2 "Dead Simple Configuration"]
-                [:p "The deployment of your application is configured through just a few lines of YAML that are kept safe in your source code. All you need to do to deploy to Heroku from CircleCI is configure your Heroku credentials in our UI, add a simple config file like this one into your project, and make a push. You can also easily deploy different branches to different Heroku apps (e.g. one for staging and one for production)."]]]
-              [:div.bullet
-               [:div.content
-                [:h2 "Watch how to get started in minutes"]
-                [:p "This video shows step-by-step how to configure CircleCI to test your application and deploy to Heroku, and how CircleCI keeps defects from getting into production. "
-                 "See our docs for a " [:a {:href "/docs/continuous-deployment-with-heroku#part-2-multiple-environments"} "followup video"] " showing how to setup a more robust continuous delivery pipeline with staging and prod environments."]]
-               [:div.graphic
-                [:div {:dangerouslySetInnerHTML {:__html ""}}]]]]
-             [:div.bottom-section
-              [:h2 "Ready for world-class continuous delivery?"]
-              [:a {:role "button"} "Sign up for Free"]
-              [:p "Want more information? See our " [:a {:href "/docs/continuous-deployment-with-heroku"} "complete documentation"] " on deploying to Heroku."]]]))))
+      (let [data (get integration-data integration)]
+        (html [:div#integrations.generic
+               [:div.top-section {:class (name integration)}
+                [:div.line]
+                [:div.hero-wrapper
+                 [:div.hero
+                  [:div.integration-icon
+                   [:img {:src (utils/cdn-path "/img/outer/integrations/integration-icon.svg")}]]
+                  [:div
+                   [:h1 (get-in data [:hero :header])]
+                   [:p (get-in data [:hero :text])]]
+                  [:a {:role "button"} "Sign up for CircleCI"]]]]
+               [:div.middle-section
+                [:div.bullet
+                 [:div.content
+                  [:h2 "Test before you deploy. Always."]
+                  [:p "Heroku revolutionized the way developers think about deployment. Being able to deploy with a simple "
+                   [:code "git push heroku master"] " is an amazing thing. But setting up a proper continuous delivery workflow means automating every step of the process. With CircleCI whenever you push a commit to master, it will go through a complete continuous delivery pipeline. All of your tests will run with our blazing fast parallelism, and" [:em " only if they pass, "] "your code will be pushed to Heroku automatically."]]
+                 [:div.graphic
+                  [:img {:src (stefon/data-uri "/img/status-logos/success.svg")}]]]
+                [:div.bullet
+                 [:div.graphic
+                  [:div.console
+                   [:pre
+                    "deployment:\n  staging:\n    branch: " [:span.value "master"] "\n    heroku:\n      appname: " [:span.value "my-app"]]]]
+                 [:div.content
+                  [:h2 "Dead Simple Configuration"]
+                  [:p "The deployment of your application is configured through just a few lines of YAML that are kept safe in your source code. All you need to do to deploy to Heroku from CircleCI is configure your Heroku credentials in our UI, add a simple config file like this one into your project, and make a push. You can also easily deploy different branches to different Heroku apps (e.g. one for staging and one for production)."]]]
+                [:div.bullet
+                 [:div.content
+                  [:h2 "Watch how to get started in minutes"]
+                  [:p "This video shows step-by-step how to configure CircleCI to test your application and deploy to Heroku, and how CircleCI keeps defects from getting into production. "
+                   "See our docs for a " [:a {:href "/docs/continuous-deployment-with-heroku#part-2-multiple-environments"} "followup video"] " showing how to setup a more robust continuous delivery pipeline with staging and prod environments."]]
+                 [:div.graphic
+                  [:div {:dangerouslySetInnerHTML {:__html ""}}]]]]
+               [:div.bottom-section
+                [:h2 "Ready for world-class continuous delivery?"]
+                [:a {:role "button"} "Sign up for Free"]
+                [:p "Want more information? See our " [:a {:href "/docs/continuous-deployment-with-heroku"} "complete documentation"] " on deploying to Heroku."]]])))))


update libs/clojure in preparation for core.spec

--- build.boot
+++ build.boot
@@ -1,20 +1,20 @@
 (set-env!
  :resource-paths #{"resources"}
  :source-paths #{"src" "cljs"}
- :dependencies '[[org.clojure/clojure "1.8.0"]
+ :dependencies '[[org.clojure/clojure "1.9.0-alpha14"]
                  [com.cemerick/piggieback "0.2.1"]
                  [org.clojure/tools.nrepl "0.2.12"]
                  [weasel "0.7.0" :exclusions [org.clojure/clojurescript]]
                  [green-tags "0.3.0-alpha"]
                  [hiccup "1.0.5"]
                  [boot-deps "0.1.6"]
-                 [aleph "0.4.1"]
-                 [ring "1.5.0"  :exclusions [org.clojure/java.classpath]]
+                 [aleph "0.4.2-alpha10"]
+                 [ring "1.6.0-beta6"  :exclusions [org.clojure/java.classpath]]
                  [org.clojure/data.json "0.2.6"]
-                 [org.clojure/clojurescript "1.9.229"]
-                 [org.clojure/core.async "0.2.391"]
-                 [org.omcljs/om "1.0.0-alpha44"]
-                 [sablono "0.7.4"]
+                 [org.clojure/clojurescript "1.9.293"]
+                 [org.clojure/core.async "0.2.395"]
+                 [org.omcljs/om "1.0.0-alpha47"]
+                 [sablono "0.7.6"]
                  [juxt/dirwatch "0.2.3"]])

 (require '[sledge.boot-build :refer :all])


removed secretary dependency

removed secretary dependency


updated deps

updated deps

--- build.boot
+++ build.boot
@@ -4,9 +4,9 @@
   :dependencies '[[hiccup "1.0.5"]
                   [perun "0.1.3-SNAPSHOT"]
                   [hashobject/boot-s3 "0.1.2-SNAPSHOT"]
-                  [clj-time "0.9.0"]
-                  [pandeiro/boot-http "0.6.3-SNAPSHOT"]
-                  [org.martinklepsch/boot-gzip "0.1.1"]])
+                  [clj-time "0.11.0"]
+                  [pandeiro/boot-http "0.6.3"]
+                  [org.martinklepsch/boot-gzip "0.1.2"]])

 (require '[io.perun :refer :all]
          '[blog.hashobject.views.index :as index-view]


Correct project metadata

Correct project metadata

--- build.boot
+++ build.boot
@@ -11,9 +11,9 @@
 (task-options!
  pom {:project     project
       :version     version
-      :description "FIXME: write description"
-      :url         "http://example/FIXME"
-      :scm         {:url "https://github.com/yourname/parse-names"}
+      :description ""
+      :url         "http://github.com/bensu/parse-names"
+      :scm         {:url "https://github.com/bensu/parse-names"}
       :license     {"Eclipse Public License"
                     "http://www.eclipse.org/legal/epl-v10.html"}})


Start 2.5.11-SNAPSHOT

Start 2.5.11-SNAPSHOT

--- build.boot
+++ build.boot
@@ -37,7 +37,7 @@
 (task-options!
   sift {:include #{#"\.jar$"}}
   pom {:project 'nightcode
-       :version "2.5.10"
+       :version "2.5.11-SNAPSHOT"
        :description "An IDE for Clojure"
        :url "https://github.com/oakes/Nightcode"
        :license {"Public Domain" "http://unlicense.org/UNLICENSE"}}


Get rid of unused functions.

Get rid of unused functions.

--- src/fhofherr/simple/engine/jobs.clj
+++ src/fhofherr/simple/engine/jobs.clj
@@ -47,6 +47,12 @@
                     (- $ 1)))]
     exec-id))

+(defn get-job-execution
+  "Obtain the job execution with id `exec-id` from the job descriptor
+  `job-desc`. Return `nil` if no execution with `exec-id` exists."
+  [job-desc exec-id]
+  (get @(:executions job-desc) exec-id))
+
 (defn alter-job-execution!
   "Apply the function `f` to the execution with id `exec-id` in the job
   descriptor's vector of executions. Replace the old value by the job
@@ -57,14 +63,12 @@
                   {:post [(job-ex/job-execution? %)]}
                   (apply f exec args))
         new-exec (-> job-desc
-                     (:executions)
-                     (deref)
-                     (get exec-id)
+                     (get-job-execution exec-id)
                      (apply-f))]
     (dosync
-      (as-> job-desc $
-        (:executions $)
-        (alter $ assoc exec-id new-exec))))
+      (-> job-desc
+          (:executions)
+          (alter assoc exec-id new-exec))))
   job-desc)

 (defn execute-job!
@@ -108,43 +112,25 @@
     (schedule-job-execution! job-desc exec-id)
     exec-id))

-(defn get-job-execution
-  "Obtain the job execution with id `exec-id` from the job descriptor
-  `job-desc`. Return `nil` if no execution with `exec-id` exists."
-  [job-desc exec-id]
-  (get @(:executions job-desc) exec-id))
-
-(defn get-last-execution
+(defn get-last-executed-execution
   "Obtain the last executed job execution from `job-desc`. Return `nil`
   if no job has been executed yet."
   [job-desc]
   (get-job-execution job-desc @(:executor job-desc)))

-(defn- apply-to-last-execution
-  "Apply the function `f` to the last job execution of `job-desc`. Return
-  whatever `f` returns. If `job-desc` has no executions and `else` is given
-  return `else`. If `else` is not given and there are no job executions for
-  `job-desc` return `nil`."
+(defn- query-last-executed-execution
   [job-desc f & [else]]
-  (if-let [last-exec (get-last-execution job-desc)]
+  (if-let [last-exec (get-last-executed-execution job-desc)]
     (f last-exec)
     else))

-(defn- apply-to-new-executions
-  "Apply the function `f` to a vector of all of `job-desc`'s job executions
-  whose id is higher than the id of the last executed job execution. The vector
-  passed to `f` may be empty."
-  [job-desc f]
-  (let [execs @(:executions job-desc)
-        start-id @(:executor job-desc)]
-    (as-> execs $
-      (subvec $ (if (< start-id 0) 0 start-id))
-      (f $))))
-
 (defn failed?
+  "Check if the last executed job execution of `job-desc` failed."
   [job-desc]
-  (apply-to-last-execution job-desc #(-> % (:context) (ex-ctx/failed?))))
+  (query-last-executed-execution job-desc
+                                 #(-> % (:context) (ex-ctx/failed?))))

 (defn successful?
+  "Check if the last executed job execution of `job-desc` was successful."
   [job-desc]
-  (apply-to-last-execution job-desc #(-> % (:context) (ex-ctx/successful?))))
+  (query-last-executed-execution job-desc #(-> % (:context) (ex-ctx/successful?))))


Update words.clj

Update words.clj

--- src/iyye/subcon/knowledge/words.clj
+++ src/iyye/subcon/knowledge/words.clj
@@ -59,12 +59,13 @@
 (def time-start (persistence/current-time-to-string))
 (defn get-supertypes [atype]
   "gets types: self, type, immidiate parents"               ; FIXME Yumzia:0 get all parents
-  (when (not (= :UNKNOWN atype))
+  (if (not (:UNKNOWN atype))
     (let [rels (:Relations atype)]
       (conj (for [supertype rels :when (:super (:Data supertype))]
               {:Name (:super (:Data supertype)) :Predicate (:Predicate supertype)})
               {:Name "type" :Predicate (->Iyye_ModalPredicate :IYE :AXIOM time-start :ALWAYS)}
-              {:Name (:Name (:atom atype)) :Predicate (->Iyye_ModalPredicate :IYE :AXIOM time-start :ALWAYS)}))))
+              {:Name (:Name (:atom atype)) :Predicate (->Iyye_ModalPredicate :IYE :AXIOM time-start :ALWAYS)}))
+    {:UNKNOWN (:UNKNOWN atype)}))

 (defn create-iyye-instance [values])

@@ -86,7 +87,7 @@
   "returns a list of found atoms with supplied name"
   (let [builtin-types
         (for [word (vals @builtins) :when (= (:Name (:atom word)) name)] word)]
-    (if (empty? builtin-types) (list :UNKNOWN) builtin-types)))
+    (if (empty? builtin-types) (list {:UNKNOWN name}) builtin-types)))

 (defn get-iyye-types [name]
   (get-iyye-atoms name noun-words))
@@ -110,7 +111,7 @@
             pairs (map vector act-params params-types)
             ok (every? true? (for [cur pairs]
                                (if (= :UNKNOWN (first cur))
-                                 (empty? (second cur))
+                                 (if (:UNKNOWN (second cur)) true false)
                                  (some true?
                                        (map #(= (first cur) %) (map :Name (second cur)))))))]
     ok))))  ; FIXME Yumzya context aware compare


CLJS-1338: NPE in confirm-var-exists if suffix is ".."

--- src/main/clojure/cljs/analyzer.cljc
+++ src/main/clojure/cljs/analyzer.cljc
@@ -556,9 +556,10 @@
      (confirm-var-exists env prefix suffix warn)))
   ([env prefix suffix missing-fn]
     (let [sufstr     (str suffix)
-          suffix-str (if (and (not (identical? ".." sufstr)) ;; leave cljs.core$macros/.. alone
-                           #?(:clj  (re-find #"\." sufstr)
-                              :cljs ^boolean (.test #"\." sufstr)))
+          suffix-str (if (and #?(:clj  (not= ".." sufstr)
+                                 :cljs (not (identical? ".." sufstr))) ;; leave cljs.core$macros/.. alone
+                              #?(:clj  (re-find #"\." sufstr)
+                                 :cljs ^boolean (.test #"\." sufstr)))
                        (first (string/split sufstr #"\."))
                        suffix)
           suffix     (symbol suffix-str)]


drop old version

drop old version

Signed-off-by: Yen-Chin Lee <082d453d72dce940e12089a4ad48b97cfe1f3ec4@gmail.com>

--- src/emulator_chip8/opcode.cljc
+++ src/emulator_chip8/opcode.cljc
@@ -51,25 +51,9 @@
   )
 ;;)

-(comment
-  (defn make-handler-sets
-    "Create possible opcode set for opcode-list"
-    [opcode]
-    ;; TODO: cljs lack format
-    (let [code (format "%04X" opcode)
-          ZNNN (format "%SNNN" (subs code 0 1))
-          ZXNN (format "%SXNN" (subs code 0 1))
-          ZXYN (format "%SXYN" (subs code 0 1))
-          ZXYZ (format "%SXY%S" (subs code 0 1) (subs code 3 4))
-          ZXZZ (format "%SX%S"  (subs code 0 1) (subs code 2 4))]
-      (->> (list code ZNNN ZXNN ZXZZ ZXYN ZXYZ)
-           (map keyword)
-           (set)))) )
-
 (defn make-handler-sets
   "Create possible opcode set for opcode-list"
   [opcode]
-  ;; TODO: cljs lack format
   (let [code (cl-format nil "~4,'0x" opcode)
         ZNNN (cl-format nil "~ANNN" (subs code 0 1))
         ZXNN (cl-format nil "~AXNN" (subs code 0 1))
@@ -80,25 +64,10 @@
          (map keyword)
          (set))))

-(comment
-  (defn make-handler-args
-    "Parse the code to find how many VX, VY, NNN, NN, N
-  and create argument lists."
-    [opcode]
-    ;; TODO: cljs lack format
-    (let [code (format "%04X" opcode)]
-      {:NNN (read-string (subs code 1 4))
-       :NN  (read-string (subs code 2 4))
-       :N   (read-string (subs code 3 4))
-       :VX  (read-string (subs code 1 2))
-       :VY  (read-string (subs code 2 3))})))
-
-
 (defn make-handler-args
   "Parse the code to find how many VX, VY, NNN, NN, N
   and create argument lists."
   [opcode]
-  ;; TODO: cljs lack format
   (let [code (cl-format nil "~4,'0x" opcode)]
     {:NNN (read-string (subs code 1 4))
      :NN  (read-string (subs code 2 4))


Don't throw errors, just log them

Don't throw errors, just log them

This allows the rest of the read to happen even when a key is missing.

--- src-cljs/frontend/send/resolve.cljs
+++ src-cljs/frontend/send/resolve.cljs
@@ -1,8 +1,15 @@
 (ns frontend.send.resolve
   (:require [cljs.core.async :as async :refer [chan close! put!]]
             [cljs.core.async.impl.protocols :as async-impl]
+            [goog.log :as glog]
             [om.next :as om]
-            [promesa.core :as p :include-macros true]))
+            [promesa.core :as p :include-macros true])
+  (:import goog.debug.Console))
+
+(defonce *logger*
+  (when ^boolean goog.DEBUG
+    (.setCapturing (Console.) true)
+    (glog/getLogger "frontend.send.resolve")))

 (defn- read-port? [x]
   (implements? async-impl/ReadPort x))
@@ -41,6 +48,7 @@
                          (chan 1 (comp
                                   (map #(get % read-from-key))
                                   (map #(hash-map (:key ast) %)))))
-            (throw (ex-info (str "Unknown key " read-from-key)
-                            {:key read-from-key}))))))
+            (do
+              (glog/error *logger* (str "No resolver found for key " read-from-key))
+              (doto (chan) (close!)))))))
      channel)))


Inbox: Clarify meaning of 'open' button

Inbox: Clarify meaning of 'open' button

--- src-cljs/pepa/workflows/inbox2.cljs
+++ src-cljs/pepa/workflows/inbox2.cljs
@@ -314,7 +314,7 @@
                                               copy?)))}
      [:header nil]
      [:.center
-      "Drag pages here or press \"Open\" to open a document"
+      "Drag pages here or press \"Open\" to open an existing document"
       [:button {:on-click (fn [e]
                             (ui/cancel-event e)
                             (let [current-columns (current-columns state)]


Standards comment added

Standards comment added

--- adapter-db/src/adapter_db/core.clj
+++ adapter-db/src/adapter_db/core.clj
@@ -116,7 +116,7 @@
     ; TODO better reuse db-handle with-db-connection
     ; TODO this true/flase flag hack sucks, fix it
     (jdbc/get-connection url) nil
-    (catch Exception e (warn e) {:hell "o"})))
+    (catch Exception e (warn e) {:hell "TODO proper error and success returns"})))

 (defn get-query