Fixed excessive threads created by temp-file-store

--- ring-core/src/ring/middleware/multipart_params/temp_file.clj
+++ ring-core/src/ring/middleware/multipart_params/temp_file.clj
@@ -39,13 +39,13 @@
     :size         - the size in bytes of the uploaded data"
   ([] (temp-file-store {:expires-in 3600}))
   ([{:keys [expires-in]}]
-     (fn [item]
-       (let [file-set  (atom #{})
-             temp-file (make-temp-file file-set)]
-         (io/copy (:stream item) temp-file)
-         (when expires-in
-           (do-every expires-in
-             (remove-old-files file-set expires-in)))
-         (-> (select-keys item [:filename :content-type])
-             (assoc :tempfile temp-file
-                    :size (.length temp-file)))))))
+     (let [file-set (atom #{})]
+       (when expires-in
+         (do-every expires-in
+           (remove-old-files file-set expires-in)))
+       (fn [item]
+         (let [temp-file (make-temp-file file-set)]
+           (io/copy (:stream item) temp-file)
+           (-> (select-keys item [:filename :content-type])
+               (assoc :tempfile temp-file
+                      :size (.length temp-file))))))))


fix rebase conflict, keep autoload-hooks disabled

--- src/ctia/init.clj
+++ src/ctia/init.clj
@@ -95,7 +95,6 @@
                      :before-update-ro
                      :before-delete-ro]]
     #(h/add-hook! % event-hook/ESEventProducerHook))
-  (autoload-hooks!)
   ;; this is breaking everything
   ;;(autoload-hooks!)
   (h/init-hooks!)


Fix missing import.

Fix missing import.

--- clojure/src/advent2018/day1.clj
+++ clojure/src/advent2018/day1.clj
@@ -1,6 +1,7 @@
 (ns advent2018.day1
   "https://adventofcode.com/2018/day/1"
-  (:require [advent.core :refer [->lines ->numbers]]))
+  (:require [advent.core :refer [->lines ->numbers]]
+            [advent2018.core :refer [read-puzzle]]))

 (def puzzle (read-puzzle "day1" (comp ->numbers ->lines)))


Return event regardless.

Return event regardless.

--- src/onyx/peer/task_pipeline.clj
+++ src/onyx/peer/task_pipeline.clj
@@ -66,7 +66,8 @@

 (defn munge-complete-task [{:keys [sync completion-node tail-batch?] :as event}]
   (when tail-batch?
-    (extensions/touch-place sync completion-node)))
+    (extensions/touch-place sync completion-node))
+  event)

 (defn open-session-loop [read-ch kill-ch pipeline-data]
   (loop []


Four tests for db-interface module: status->int, dictionary-type->char, insert-word-into-dictionary, and add-new-word-into-dictionary

--- test/zg/db_interface_test.clj
+++ test/zg/db_interface_test.clj
@@ -23,3 +23,31 @@
     [function-name]
     (clojure.test/function? function-name))

+;
+; Tests for function existence
+;
+
+(deftest test-status->int-existence
+    "Check that the zg.db-interface/status->int definition exists."
+    (testing "if the zg.db-interface/status->int definition exists."
+        (is (callable? 'zg.db-interface/status->int))))
+
+
+(deftest test-dictionary-type->char-existence
+    "Check that the zg.db-interface/dictionary-type->char definition exists."
+    (testing "if the zg.db-interface/dictionary-type->char definition exists."
+        (is (callable? 'zg.db-interface/dictionary-type->char))))
+
+
+(deftest test-insert-word-into-dictionary-existence
+    "Check that the zg.db-interface/insert-word-into-dictionary definition exists."
+    (testing "if the zg.db-interface/insert-word-into-dictionary definition exists."
+        (is (callable? 'zg.db-interface/insert-word-into-dictionary))))
+
+
+(deftest test-add-new-word-into-dictionary-existence
+    "Check that the zg.db-interface/add-new-word-into-dictionary definition exists."
+    (testing "if the zg.db-interface/add-new-word-into-dictionary definition exists."
+        (is (callable? 'zg.db-interface/add-new-word-into-dictionary))))
+
+


dep version

dep version

--- template/project.clj
+++ template/project.clj
@@ -14,6 +14,7 @@
   :javac-options ["-Xlint:unchecked"]
   :jar-exclusions [#".gitignore"]
   :exclusions [org.slf4j/slf4j-log4j12
+               log4j/log4j
                ch.qos.logback/logback-classic]
   :dependencies [[org.clojure/clojure "1.8.0"]

@@ -21,7 +22,7 @@
                  [org.clojure/tools.logging "0.3.1"]

                  ;; command line
-                 [com.zensols.tools/actioncli "0.0.11"]]
+                 [com.zensols.tools/actioncli "0.0.12"]]
   :pom-plugins [[org.codehaus.mojo/appassembler-maven-plugin "1.6"
                  {:configuration ([:programs
                                    [:program


Kibana only internal

Kibana only internal

--- src/terraboot/elasticsearch.clj
+++ src/terraboot/elasticsearch.clj
@@ -26,7 +26,7 @@
                                                       :permissions "644"
                                                       :content (snippet "system-files/out-es.conf")}]}))

-(defn elasticsearch-cluster [name {:keys [vpc-name account-number azs default-ami] :as spec}]
+(defn elasticsearch-cluster [name {:keys [vpc-name account-number azs default-ami vpc-cidr-block] :as spec}]
   ;; http://docs.aws.amazon.com/elasticsearch-service/latest/developerguide/es-createupdatedomains.html#es-createdomain-configure-ebs
   ;; See for what instance-types and storage is possible
   (let [vpc-unique (fn [name] (str vpc-name "-" name))
@@ -115,6 +115,7 @@
                                                     :target "HTTP:80/status"
                                                     :timeout 5
                                                     :interval 30}
+                                     :internal true
                                      :subnets (mapv #(id-of "aws_subnet" (stringify vpc-name "-public-" %)) azs)
                                      :listeners [(elb-listener {:lb-port 443 :lb-protocol "https" :port 80 :protocol "http" :cert-name "StartMastodoncNet"})]
                                      :instances [(id-of "aws_instance" (vpc-unique "kibana"))]
@@ -167,10 +168,21 @@
              (route53_record "kibana" {:type "CNAME"
                                        :records [(output-of "aws_elb" "kibana" "dns_name")]})

-             (vpc-security-group "elb-kibana" {})
+             (vpc-security-group "elb-kibana" {}
+                                 {:port 80
+                                  :cidr_blocks [vpc-cidr-block]}
+                                 {:port 443
+                                  :cidr_blocks [vpc-cidr-block]})
              (vpc-security-group "allow-elb-kibana" {}
                                  {:port 80
+                                  :source_security_group_id (vpc-id-of "aws_security_group" "elb-kibana")}
+                                 {:port 443
                                   :source_security_group_id (vpc-id-of "aws_security_group" "elb-kibana")})
-             (vpc-security-group  "kibana" {})
+             (vpc-security-group  "kibana" {}
+                                  {:type "egress"
+                                   :from_port 0
+                                   :to_port 0
+                                   :protocol -1
+                                   :cidr_blocks [all-external]})

              ))))


remove policy for now because causes cycles

--- src/terraboot/elasticsearch.clj
+++ src/terraboot/elasticsearch.clj
@@ -7,9 +7,9 @@
 (def logstash-user-data (cloud-config {:package_update true
                                        :bootcmd ["echo oracle-java8-installer shared/accepted-oracle-license-v1-1 select true | /usr/bin/debconf-set-selections"
                                                  "wget -qO - https://packages.elastic.co/GPG-KEY-elasticsearch | apt-key add -" ]
-                                       :apt_mirror [{:source "deb ppa:webupd8team/java"}
-                                                    {:source "deb http://packages.elastic.co/logstash/2.3/debian stable main"
-                                                     :key (snippet "system-files/elasticsearch-apt.pem")                                                      }]
+                                       :apt_sources [{:source "deb http://ppa.launchpad.net/webupd8team/java/ubuntu trusty main"}
+                                                     {:source "deb http://packages.elastic.co/logstash/2.3/debian stable main"
+                                                      :key (snippet "system-files/elasticsearch-apt.pem")}]
                                        :packages ["oracle-java8-installer"
                                                   "oracle-java8-set-default"
                                                   "logstash"]
@@ -40,7 +40,7 @@
                                        "Condition"
                                        {
                                         "IpAddress"
-                                        {"aws:SourceIp" "$${allowed-ips}"}}}]}))
+                                        {"aws:SourceIp" ["$${allowed-ips}"]}}}]}))

 (defn elasticsearch-cluster [name {:keys [vpc-name account-number region azs default-ami vpc-cidr-block cert-name] :as spec}]
   ;; http://docs.aws.amazon.com/elasticsearch-service/latest/developerguide/es-createupdatedomains.html#es-createdomain-configure-ebs
@@ -54,15 +54,14 @@
                                            )]
     (merge-in
      (template-file (vpc-unique "elasticearch-policy")
-                    {:es-arn (str "arn:aws:es:" region ":" account-number ":domain/" vpc-name "-elasticsearch/*"),
-                     :allowed-ips  (concat
-                                    (mapv #(vpc-output-of "aws_eip" (stringify "public-" % "-nat") "public_ip") azs)
-                                    [(vpc-output-of "aws_eip" "logstash" "public_ip")])})
+                    (elasticsearch-policy)
+                    {:es-arn (str "arn:aws:es:" region ":" account-number ":domain/" vpc-name "-elasticsearch/*")
+                     :allowed-ips  (vpc-output-of "aws_eip" "logstash" "public_ip")})

      (vpc-resource "aws_elasticsearch_domain" name
                    {:domain_name (vpc-unique name)
                     :advanced_options { "rest.action.multi.allow_explicit_index" true}
-                    :access_policies (rendered-template-file (vpc-unique "elasticsearch-policy"))
+                    :access_policies ""#_(rendered-template-file (vpc-unique "elasticsearch-policy"))

                     :cluster_config {:instance_count 2,
                                      :instance_type "t2.small.elasticsearch"}


removed the heroku command line use and used git directly

--- src/dmgr/core.clj
+++ src/dmgr/core.clj
@@ -27,8 +27,6 @@
    :ssh-private-key (get-ssh-private-key app-name (:ssh-private-key opts))
    :access-key (get-access-key (:access-key opts))})

-
-
 (defn run
   "Run the shell commands with the correct environment variables returning exit status code"
   [app-path cmd]
@@ -46,8 +44,11 @@
   [{:keys [app-name github-repo-uri heroku-repo-uri] :as args}]
   {:fetch-and-reset  (format   "cd  %s /repo && git fetch && git reset --hard origin/master" app-name)
    :clone (format "cd %s  && git clone https://%s repo" app-name  github-repo-uri)
-   :push-to-heroku (format "cd %s/repo && heroku git:remote -a %s && git push heroku master" app-name app-name app-name  heroku-repo-uri)
+   ;;   :push-to-heroku (format "cd %s/repo && heroku git:remote -a %s && git push heroku master" app-name app-name app-name  heroku-repo-uri)
+   :push-to-heroku (format "cd %s/repo && git remote add heroku git@heroku.com:%s.git && git push heroku master"
+                           app-name app-name)
    :remove-staging-dir (format "rm -rf %s" app-name)})
+

 (defn prepare-staging-area
   "Create a staging area"


destroy on exit functionality

destroy on exit functionality

--- src/flax/core.clj
+++ src/flax/core.clj
@@ -413,9 +413,17 @@
                     (die
                       "The configuration must have a program property, which must be a path to a valid yaml document:"
                       (.getMessage e))))
-        config (assoc config :env (evaluate (:env config) config))]
-    (when-let [main (:main program)]
-      (pmap #(evaluate % config) main))))
+        config (assoc config :env (evaluate (:env config) config))
+        exit (when-let [main (:main program)]
+               (doall (pmap #(evaluate % config) main)))]
+    (doall
+      (pmap
+        (fn [[k n]]
+          (when (-> @(:node n) :options :destroy-on-exit true?)
+            (destroy n)))
+        @(-> config :node-manager :nodes)))
+    exit
+    ))

 (defn run
@@ -472,17 +480,17 @@
                               (remove #(-> % :exit :value nil?))
                               (filter #(and (-> % :throw)
                                             (-> % :exit :value zero? not))))
-                big-exit (count failures)]
+                num-failures (count failures)]
             (spit "target/logs/failures.json" (json/generate-string failures))
-            (log logger :info (str "Failures: " big-exit))
+            (log logger :info (str "Failures: " num-failures))
+            (log logger :info (str "Seed: " effective))

             ;; Allow time for agents to finish logging.
             (Thread/sleep 1000)
             ;; Kill the agents so the program exits without further delay.
             (shutdown-agents)

-            (System/exit big-exit)
-            )
+            num-failures)
           )))
     (catch java.io.FileNotFoundException fnfe
       (die "Resource could not be found:" (.getMessage fnfe)))


Removed dommy from test requires

Removed dommy from test requires

--- test/tests.cljs
+++ test/tests.cljs
@@ -2,7 +2,6 @@
   (:require [cljs.test :refer-macros [is testing deftest]]
             [cljs-react-test.simulate :as sim]
             [cljs-react-test.utils :as tu]
-            [dommy.core :as dommy :refer-macros [sel]]
             [om.core :as om :include-macros true]
             [om-semantic.dropdown :as d]))


In large screen mode show editor and app at same time

This is so that we can make building apps feel more interactive

--- idecode/myappshare/mainapp.cljs
+++ idecode/myappshare/mainapp.cljs
@@ -270,7 +270,6 @@
                  from appshare_applications where id = ? {:params [(read-ui app [:app-id])]}

                  (div {:style {:marginLeft "20px" :padding "5px"}}
-                      ;                      (span {:onClick #(go  (write-ui app [:mode] "editdata"))} "Data")
                       (cond
                         (= (read-ui app [:editor]) "text")
                         (span {:onClick #(go  (write-ui app [:editor] "blockly"))} "Text | ")
@@ -532,7 +531,7 @@
 ;       (div {} (str "app-id: " (read-ui app [:app-id])))

-       (div {:style {:display "inline-block" :width "100%" :height "800" :verticalAlign "top"}}
+       (div {:style {:display "inline-block" :width "100%" :height "100%" :verticalAlign "top"}}

             (cond

@@ -540,8 +539,8 @@
               (div {:style {}} (component browser-component app []))

-              (= (read-ui app [:mode]) "edit")
-              (div {:style {} } (component editor-component app []))
+              (or (and (= (read-ui app [:mode]) "view") (large-screen)) (= (read-ui app [:mode]) "edit"))
+              (div {:style {:display "inline-block"  :width "600px"} } (component editor-component app []))

               (= (read-ui app [:mode]) "editappglyph")
               (div {:style {} } (component edit-app-glyph-component app []))
@@ -555,14 +554,13 @@

               (= (read-ui app [:mode]) "account")
               (div {:style {} } (component your-account-component app []))
-
-
-              (= (read-ui app [:mode]) "editdata")
-              (div {:style {} } (component edit-data-component app []))
             )

-            (div {:style {:display (if (= (read-ui app [:mode]) "view") "" "none")}} (component  view-app-component  app [])))
+            (div {:style {:display (if
+                                     (or (= (read-ui app [:mode]) "view")
+                                         (and (= (read-ui app [:mode]) "edit") (large-screen)))
+                                     "inline-block" "none") :width "600px"} } (component  view-app-component  app [])))

        ))


Add comments to Clojure version

Add comments to Clojure version

--- clojure/src/biotool/core.clj
+++ clojure/src/biotool/core.clj
@@ -1,3 +1,21 @@
+;;; Module:      biotool.core
+;;; Description: Reads one or more FASTA files and computes various
+;;;              simple statistics about them. Intended as an example
+;;;              bioinformatics command line tool
+;;; Copyright:   (c) Bernie Pope, 2017
+;;; License:     MIT
+;;; Maintainer:  bjpope@unimelb.edu.au
+;;; Stability:   stable
+;;; Portability: POSIX
+
+;;; The main parts of the program are:
+;;; 1. Parse command line arguments.
+;;; 2. Process each FASTA file in sequence
+;;; 3. Pretty print output for each file.
+;;;
+;;; If no FASTA filenames are specified on the command line then the program
+;;; will try to read a FASTA file from standard input.
+
 (ns biotool.core
   (:require [clj-biosequence.core :as bs]
             [clojure.string :as string]
@@ -7,7 +25,10 @@
             [taoensso.timbre.appenders.core :as appenders])
   (:gen-class))

+
+;; Set up logging infrastructure
 (timbre/refer-timbre)
+

 (def initial-stats
   "Initial value of stats, before any sequences have been considered"
@@ -16,23 +37,50 @@
    :min-sequence-length nil
    :max-sequence-length nil})

+
 (defn update-stats
-  "Update stats accumulator with information from the next sequence"
+  "Update stats accumulator with information from the next sequence.
+
+  Arguments:
+    stats: The current value of the stats mapping.
+    record: The next FASTA record from the input file.
+
+  Result:
+    A new stats mapping updated to reflect the input FASTA record"
+
   [stats record]
   (let [{:keys [num-sequences num-bases min-sequence-length max-sequence-length]} stats
         sequence (:sequence record)
         sequence-length (count sequence)]
        {:num-sequences (inc num-sequences)
         :num-bases (+ num-bases sequence-length)
+        ;; If min-sequence-length is nil then the current sequence
+        ;; is the first we have seen, and thus the shortest.
         :min-sequence-length (if min-sequence-length
                                  (min min-sequence-length sequence-length)
                                  sequence-length)
+        ;; If max-sequence-length is nil then the current sequence
+        ;; is the first we have seen, and thus the longest.
         :max-sequence-length (if max-sequence-length
                                  (max max-sequence-length sequence-length)
                                  sequence-length)}))

+
 (defn print-results
-  "Display the computed stats in pretty fashion on the standard output"
+  "Display the computed stats in pretty fashion on the standard output.
+
+  Arguments:
+    filename: The string name of the input FASTA file (could also be stdin)
+    stats: The final computed value of stats to print.
+
+  Result:
+    nil
+
+  Notes:
+    - If the number of sequences seen is at least one then we also compute
+      the average sequence length and print it out.
+    - If any computed stat is nil then we print a single dash (-) in its place."
+
   [filename stats]
   (let [{:keys [num-sequences num-bases min-sequence-length max-sequence-length]} stats
         average (if (> num-sequences 0)
@@ -45,6 +93,7 @@
           (if min-sequence-length (str min-sequence-length) "-")
         max-sequence-length-str
           (if max-sequence-length (str max-sequence-length) "-")
+        ;; Output fields are tab separated.
         output-str (str filename "\t"
                         num-sequences-str "\t"
                         num-bases-str "\t"
@@ -53,35 +102,62 @@
                         max-sequence-length-str)]
   (println output-str)))

-(defn length-gte-minlen?
+
+(defn seq-length-gte-minlen?
+  "Test if the length of a sequence is >= to a minimum value.
+
+  Arguments:
+    minlen: The minimum length sequence allowed (non-negative int).
+    record: A FASTA record.
+
+  Result:
+    true if the sequence length is >= minlen, false otherwise."
+
   [minlen record]
   (let [sequence (:sequence record)
         num-bases (count sequence)]
     (>= num-bases minlen)))

+
 (defn process-fasta-reader
-  [minlen reader filename]
+  "Compute the statistics for a single input FASTA file from a reader object,
+  and pretty print the result to the standard output.
+
+  Arguments:
+    minlen: The minimum length sequence allowed (non-negative int). Sequences shorter than
+      this will be skipped by the program.
+    filename: The name of the file being processed, printed in the output.
+    reader: The reader object representing the input FASTA file contents.
+
+  Result:
+    nil"
+
+  [minlen filename reader]
     (print-results filename
       (reduce
         update-stats
         initial-stats
         (filter
-          (fn [record] (length-gte-minlen? minlen record))
+          (fn [record] (seq-length-gte-minlen? minlen record))
           (bs/biosequence-seq reader)))))

+
 (defn process-fasta-file
-  [minlen file]
-  (timbre/info "Processing FASTA file from" file)
-  (with-open [reader (bs/bs-reader (bs/init-fasta-file file :iupacAminoAcids))]
-    (process-fasta-reader minlen reader file)))
+  [minlen filename]
+  (timbre/info "Processing FASTA file from" filename)
+  (with-open [reader (bs/bs-reader (bs/init-fasta-file filename :iupacAminoAcids))]
+    (process-fasta-reader minlen filename reader)))
+

 (defn process-stdin
   [minlen]
   (timbre/info "Processing FASTA file from stdin")
   (with-open [reader (bs/init-fasta-reader (java.io.BufferedReader. *in*) :iupacAminoAcids)]
-    (process-fasta-reader minlen reader "stdin")))
+    (process-fasta-reader minlen "stdin" reader)))
+

 (def header "FILENAME\tTOTAL\tNUMSEQ\tMIN\tAVG\tMAX")
+

 (defn process-fasta-files
   [minlen files]
@@ -90,6 +166,7 @@
       (process-stdin minlen)
       (doseq [file files]
          (process-fasta-file minlen file))))
+

 (defn usage [options-summary]
   (->> ["Print fasta stats"
@@ -100,15 +177,19 @@
         options-summary]
        (string/join \newline)))

+
 (defn error-msg [errors]
   (str "The following errors occurred while parsing your command:\n\n"
        (string/join \newline errors)))

+
 (defn exit [status msg]
   (println msg)
   (System/exit status))

+
 (def default-minlen 0)
+

 (def cli-options
   [[nil "--minlen N" "Minimum length sequence to include in stats"
@@ -116,6 +197,7 @@
    [nil "--log LOG-FILE" "record program progress in LOG-FILE"]
    ["-v" "--version"]
    ["-h" "--help"]])
+

 (defn config-logging
   [log-filename]
@@ -125,6 +207,7 @@
       (timbre/merge-config! {:appenders {:spit (appenders/spit-appender {:fname log-filename})}})
       (timbre/set-level! :info))
     (timbre/info "Program started")))
+

 (defn -main
   "Orchestrate the computation"


[#136] import with []

[#136] import with []

--- api/src/clojure/org/akvo/flow_api/middleware/jdo_persistent_manager.clj
+++ api/src/clojure/org/akvo/flow_api/middleware/jdo_persistent_manager.clj
@@ -1,5 +1,5 @@
 (ns org.akvo.flow-api.middleware.jdo-persistent-manager
-  (:import (com.gallatinsystems.framework.servlet PersistenceFilter)))
+  (:import [com.gallatinsystems.framework.servlet PersistenceFilter]))

 (defn wrap-close-persistent-manager [handler]
   (fn [request]


[#8729] iOS crashes on personal_sign

[#8729] iOS crashes on personal_sign

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

--- src/status_im/browser/core.cljs
+++ src/status_im/browser/core.cljs
@@ -295,11 +295,12 @@
   "NOTE (andrey) we need this function, because params may be mixed up"
   [params]
   (let [[first-param second-param] params]
-    (cond
-      (ethereum/address? first-param)
-      [first-param second-param]
-      (ethereum/address? second-param)
-      [second-param first-param])))
+    (when (and (string? first-param) (string? second-param))
+      (cond
+        (ethereum/address? first-param)
+        [first-param second-param]
+        (ethereum/address? second-param)
+        [second-param first-param]))))

 (fx/defn web3-send-async
   [cofx {:keys [method params id] :as payload} message-id]


Fix parsing episode number

Fix parsing episode number

--- src/subman/sources/addicted.clj
+++ src/subman/sources/addicted.clj
@@ -85,7 +85,7 @@
   "Get episode from line"
   [line] {:number (-> line
                       :content
-                      (nth 2)
+                      (nth 4)
                       :content
                       first
                       :content


flush output buffers after each task

flush output buffers after each task

--- src/tailrecursion/boot/core.clj
+++ src/tailrecursion/boot/core.clj
@@ -36,7 +36,7 @@
 ;; PUBLIC ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

 (defn dummy-task [boot]
-  (printf "Usage: boot [task1 [task1 ...]]\n")
+  (printf "Usage: boot [task ...]\n")
   (printf "Available tasks: %s.\n"
           (apply str (interpose ", " (map name (keys (:tasks @boot)))))))

@@ -60,6 +60,7 @@
   (when-let [m (:main @boot)]
     (cond (symbol? m) ((load-sym m) boot) (seq? m) ((eval m) boot))
     (swap! boot dissoc :main)
+    (flush)
     :ok))

 (defn run-next-task! [boot & [spec]]


separate fetching original and creating thumbnail (to handle errors better), and don't do another potential network lookup to fetch the thumbnail

--- src/vignette/util/thumbnail.clj
+++ src/vignette/util/thumbnail.clj
@@ -51,9 +51,9 @@
   [system thumb-map]
   (if-let [thumb (store-prot/get-thumbnail (store system) thumb-map)]
     thumb
-    (if-let [thumb (generate-thumbnail (store-prot/get-original (store system) thumb-map)
-                                       thumb-map)]
-      (and (store-prot/save-thumbnail (store system) thumb thumb-map)
-           (io/delete-file thumb)
-           (store-prot/get-thumbnail (store system) thumb-map))
+    (if-let [original (store-prot/get-original (store system) thumb-map)]
+      (if-let [thumb (generate-thumbnail original thumb-map)]
+        (do (store-prot/save-thumbnail (store system) thumb thumb-map)
+            thumb) ; TODO: cron to delete thumbs older than X)
+        nil)
       nil)))


A little more eplanation and some more tasks on the intro clojure part.

--- clojure-functional/src/test/clojure/no/knowit/clojure_functional/intro.clj
+++ clojure-functional/src/test/clojure/no/knowit/clojure_functional/intro.clj
@@ -8,7 +8,9 @@

 (deftest very-basic-types
   (is (= 1 1))
+  ;; Lots of things are truthy, which is the simplest?
   (is (true? true))
+  ;; Now what is the concatenation of those Characters
   (is (= (str \a \b \c) "abc"))
   ;; Use vector literal
   (is (= '(1 2 3) [1 2 3]))
@@ -21,13 +23,16 @@

 (deftest use-conjoin
+  ;; conjoin is a special function that works with most datastructures.
+  ;; It nows where the right place is to append an element.
+  ;; Use (doc conj) for info
+  ;; Oh, and by the way. 'are' creates a template (using a macro),
+  ;; for alle the following test form, which need to be in pairs in this case.
   (are [x y] (= x y)
     (conj [1] 2) [1 2]
     (conj [1 2] 3 4) [1 2 3 4]
     (conj '(2 1) 3 4) '(4 3 2 1)
     (conj #{2 1} 3 4) #{1 2 3 4}))
-
-;; Use (doc conj) for info

 (deftest how-to-count-stuff
@@ -40,6 +45,8 @@

 (deftest how-to-find-length-of-something
+  ;; First class functions are so cool. Put in the right function in let
+  ;; and all assertions should be correct.
   (let [f count]
     (are [x y] (= x y)
       (f '(1 2 3 3 1)) 5
@@ -51,20 +58,50 @@

 (deftest using-if
   (are [x y] (= x y)
-       (if (> 1 0)
-         true
-         false)
-       true
+    (if (> 1 0)
+      true
+      false)
+    true

-       (if (> 3 2 1)
-         true
-         false)
-       true
+    (if (> 3 2 1)
+      true
+      false)
+    true

-       (if (> 3 2 3 1)
-         true
-         false)
-       false))
+    (if (> 3 2 3 1)
+      true
+      false)
+    false
+
+    (if nil
+      "nil is truthy"
+      "nil is falsey"
+      ) "nil is falsey"
+
+    (if true
+      "true is truthy"
+      "true is falsey"
+      ) "true is truthy"
+
+    (if false
+      "false is truthy"
+      "false is falsey"
+      ) "false is falsey"
+
+    (if '(1)
+      "list is truthy"
+      "list is falsey"
+      ) "list is truthy"
+
+    (if '()
+      "empty list is truthy"
+      "empty list is falsey"
+      ) "empty list is truthy"
+
+    (if (Object.)
+      "Object is truthy"
+      "Object is falsey"
+      ) "Object is truthy"))

 (deftest dealing-with-lists
@@ -87,13 +124,12 @@
     (filter even? '(1 2 3 4 5)) '(2 4)))

-(deftest define-a-function-that-checks-length
-  (let [long? (fn [str len] (> (count str) len))]
+(deftest define-a-function-that-checks-string-longer-than
+  (let [longer-than? (fn [str len] (> (count str) len))]
     (are [x y] (= x y)
-         (long? "long string" 5) true
-         (long? "short" 5) false
-         (long? nil 2) false
-         )))
+         (longer-than? "long string" 5) true
+         (longer-than? "short" 5) false
+         (longer-than? nil 2) false)))

 (deftest use-map-to-double-all-numbers-in-a-sequence


Fix Wrong number of args passed to: ex-info

clojure.lang.ArityException  Wrong number of args (1) passed to: clojure.core/ex-info

--- provider/pact-jvm-provider-lein/src/main/clojure/leiningen/pact_verify.clj
+++ provider/pact-jvm-provider-lein/src/main/clojure/leiningen/pact_verify.clj
@@ -20,4 +20,4 @@
       (if (contains? project :pact)
         (let [verifier (LeinVerifierProxy. project (parse-args args))]
           (verify/verify verifier (-> project :pact)))
-        (throw (ex-info "No pact definition was found in the project"))))
+        (throw (ex-info "No pact definition was found in the project" {}))))


Fix channel return value.

Fix channel return value.

--- src/workshop/workshop_utils.clj
+++ src/workshop/workshop_utils.clj
@@ -62,13 +62,17 @@

 (defonce channels (atom {}))

+(defn get-channel [id size]
+  (or (get @channels id)
+      (let [ch (chan size)]
+        (swap! channels assoc id ch)
+        ch)))
+
 (defn get-input-channel [id]
-  (or (get @channels id)
-      (swap! channels assoc id (chan input-channel-capacity))))
+  (get-channel id input-channel-capacity))

 (defn get-output-channel [id]
-  (or (get @channels id)
-      (swap! channels assoc id (chan output-channel-capacity))))
+  (get-channel id output-channel-capacity))

 (defn channel-id-for [lifecycles task-name]
   (->> lifecycles


Improve tailing

Improve tailing

--- test/com/nomistech/clojure_the_language/c_920_io/tailing.clj
+++ test/com/nomistech/clojure_the_language/c_920_io/tailing.clj
@@ -11,6 +11,11 @@
    (when-let [v (a/<!! c)]
      (cons v (chan->seq c)))))

+(defn tailer-and-channel->seq [t-and-c]
+  (-> t-and-c
+      :channel
+      chan->seq))
+
 (defn tailer-listener [c]
   (reify TailerListener
     (init [this tailer] ())
@@ -19,7 +24,6 @@
     (fileRotated [this]
       (println "Rotation detected"))
     (^void handle [this ^String line]
-     (println "Processing:" line)
      (a/>!! c line))
     (^void handle [this ^Exception i]
      (println (str "exception: " i)))))
@@ -33,21 +37,23 @@
     {:channel c
      :tailer  tailer}))

-(fact (let [lines                    ["a" "b" "c" "d" "e"]
-            file                     (File. "test/_work-dir/plop.log")
-            {:keys [channel tailer]} (tailer-and-channel file 100)
-            result-ch                (a/thread (doall (chan->seq channel)))]
+(defn stop-tailer-and-channel [{:keys [channel tailer]}]
+  (.stop tailer)
+  (a/close! channel))
+
+(fact (let [lines     ["a" "b" "c" "d" "e"]
+            file      (File. "test/_work-dir/plop.log")
+            t-and-c   (tailer-and-channel file 100)
+            result-ch (a/thread (doall (tailer-and-channel->seq t-and-c)))]
         (Thread/sleep 1000)
         (spit file "")
         (spit file (str (str/join "\n" lines)
                         "\n"))
         (Thread/sleep 1000)
         (println "Stopping")
-        (.stop tailer)
-        (a/close! channel)
+        (stop-tailer-and-channel t-and-c)
         (a/<!! result-ch)
         => lines))
-

 ;; TODO
 ;; Check that bug.


cleanup, markers

cleanup, markers

--- Clojure-Websockets/MainApp/src/cljs/birdwatch/timeseries.cljs
+++ Clojure-Websockets/MainApp/src/cljs/birdwatch/timeseries.cljs
@@ -4,18 +4,16 @@
   (:import [goog.events EventType]))

 (enable-console-print!)
-;(.log js/console (pr-str mx))

 (defn by-id [id] (.getElementById js/document id))

 (def bars (atom []))
-
 (def label (atom {}))

-(defn bar [{:keys [x y h w itm]}]
+(defn bar [{:keys [x y h w itm idx]}]
   [:rect {:x x :y (- y h) :fill "steelblue" :width w :height h
-          :on-mouse-enter (fn [_ elem] (reset! label {:top (str (- y h) "px") :left (str x "px") :itm itm}))
-          :on-mouse-leave (fn [_ elem] (reset! label {}))}])
+          :on-mouse-over #(reset! label {:top (str (- y h) "px") :left (str x "px") :idx idx :itm itm})
+          :on-mouse-leave #(reset! label {})}])

 (def ts-elem2 (by-id "timeseries2"))
 (def ts-w2 (aget ts-elem2 "offsetWidth"))
@@ -23,17 +21,18 @@

 (defn main []
   (let [label @label
-        bars @bars]
+        bars @bars
+        mx (apply max bars)
+        scaled-bars (map #(* (/ % mx) ts-h) bars)
+        cnt (count bars)
+        w (/ ts-w2 cnt)
+        gap (/ (/ ts-w2 20) cnt)]
     [:div.rickshaw_graph
-     [:svg {:width ts-w2 :height ts-h}
+     [:svg {:width ts-w2 :height ts-h :on-mouse-move (fn [ev el] (.log js/console ev))}
       [:g
        (doall (for [[idx itm] (map-indexed vector bars)]
-                (let [mx (apply max bars)
-                      cnt (count bars)
-                      w (/ ts-w2 cnt)
-                      gap (/ (/ ts-w2 20) cnt)]
-                  [bar {:x (* idx w) :y ts-h :itm itm
-                        :h (* (/ itm mx) ts-h) :w (- w gap)}])))]]
+                [bar {:x (* idx w) :y ts-h :itm itm :idx idx
+                      :h (* (/ itm mx) ts-h) :w (- w gap)}]))]]
      [:div.detail {:style {:left (:left label)} :class (if (empty? label)"inactive")}
       [:div.x_label.right "Fri, 12 Dec 2014 23:51:00 GMT"]
       [:div.item.active.right {:style {:top (:top label)}} (str "Tweets: " (:itm label))]
@@ -97,7 +96,7 @@
 (defn ts-data
   "perform time series analysis by counting tweets in even intervals"
   [app]
-  (let [tweets-by-id ((util/tweets-by-order :tweets-map :by-id) @app 10000)]
+  (let [tweets-by-id ((util/tweets-by-order :tweets-map :by-id) @app 100000)]
     (if (> (count tweets-by-id) 100)
       (let [oldest (tweet-ts (last tweets-by-id))
             newest (tweet-ts (first tweets-by-id))


Removed debugging output

Removed debugging output

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

--- src/conexp/contrib/algorithms/downing_gallier.clj
+++ src/conexp/contrib/algorithms/downing_gallier.clj
@@ -41,7 +41,6 @@
       (if (empty? queue)
         result
         (let [idx             (first queue),
-              _ (println idx)
               new             (difference (conclusion (implications idx)) result)
               [numargs queue] (reduce (fn [[numargs queue] i]
                                         (let [numargs (update-in numargs [i] dec)]
@@ -49,8 +48,7 @@
                                                      queue
                                                      (conj queue i))]))
                                       [numargs (pop queue)]
-                                      (mapcat in-premise new))
-              _ (println numargs)]
+                                      (mapcat in-premise new))]
           (recur queue numargs (into result new)))))))

 ;;; Interface


CMR-3701: Removed "dc"

CMR-3701: Removed "dc"

--- system-int-test/test/cmr/system_int_test/ingest/collection_ingest_test.clj
+++ system-int-test/test/cmr/system_int_test/ingest/collection_ingest_test.clj
@@ -12,7 +12,6 @@
     [cmr.common.mime-types :as mt]
     [cmr.common.util :as util]
     [cmr.mock-echo.client.echo-util :as e]
-    [cmr.system-int-test.data2.collection :as dc]
     [cmr.system-int-test.data2.core :as d]
     [cmr.system-int-test.data2.granule :as dg]
     [cmr.system-int-test.data2.umm-spec-collection :as data-umm-c]


More intent around spec validation

More intent around spec validation

--- test/alphabet_diamond/midje.clj
+++ test/alphabet_diamond/midje.clj
@@ -10,13 +10,14 @@
 (fact (commands-for "A") => [{:number 1 :letter "A"}])
 (fact (commands-for "d") => [{:number 1 :letter "A"} {:number 2 :letter "B"} {:number 3 :letter "C"} {:number 4 :letter "D"} {:number 3 :letter "C"} {:number 2 :letter "B"} {:number 1 :letter "A"}])

-(fact (check-spec "A") => truthy)
-(fact (check-spec "c") => truthy)
-(fact (check-spec "Z") => truthy)
-(fact (check-spec "  E   ") => truthy)
-(fact (check-spec "") => (throws AssertionError))
-(fact (check-spec "AA") => (throws AssertionError))
-(fact (check-spec " ") => (throws AssertionError))
-(fact (check-spec "4") => (throws AssertionError))
-(fact (check-spec "(") => (throws AssertionError))
-(fact (check-spec nil) => (throws AssertionError))
+(facts "Valid specs are single alphabetic characters"
+	(fact (check-spec "A") => truthy)
+	(fact (check-spec "c") => truthy)
+	(fact (check-spec "Z") => truthy)
+	(fact (check-spec "  E   ") => truthy)
+	(fact (check-spec "") => (throws AssertionError))
+	(fact (check-spec "AA") => (throws AssertionError))
+	(fact (check-spec " ") => (throws AssertionError))
+	(fact (check-spec "4") => (throws AssertionError))
+	(fact (check-spec "(") => (throws AssertionError))
+	(fact (check-spec nil) => (throws AssertionError)))


Add Tests for UnsupportedOperationException

--- test/http/async/client/test.clj
+++ test/http/async/client/test.clj
@@ -195,7 +195,10 @@
                                       (deliver headers# hds)
                                       [hds :abort]))
         headers @headers#]
-    (is (= (:test-header headers) "test-value"))))
+    (is (= (:test-header headers) "test-value"))
+    (is (thrown? UnsupportedOperationException (.cons ^clojure.lang.APersistentMap headers '())))
+    (is (thrown? UnsupportedOperationException (assoc ^clojure.lang.APersistentMap headers :a 1)))
+    (is (thrown? UnsupportedOperationException (.without ^clojure.lang.APersistentMap headers :a)))))

 (deftest test-status-and-header-callbacks
   (let [status# (promise)


fix previous commit and use :put as desired.  also add a test that non-superuser can't modify password of another user via PUT /api/user/:id/password

--- test/metabase/api/user_test.clj
+++ test/metabase/api/user_test.clj
@@ -139,7 +139,7 @@

 ;; Check that a non-superuser CANNOT update someone else's user details
 (expect "You don't have permissions to do that."
-  ((user->client :rasta) :get 403 (str "user/" (user->id :trashbird))))
+  ((user->client :rasta) :put 403 (str "user/" (user->id :trashbird))))

 ;; ## PUT /api/user/:id/password
@@ -165,3 +165,8 @@
                  "password mismatch"))
       ;; New creds *should* work
       (metabase.http-client/client :post 200 "session" (:new creds)))))
+
+;; Check that a non-superuser CANNOT update someone else's password
+(expect "You don't have permissions to do that."
+  ((user->client :rasta) :put 403 (format "user/%d/password" (user->id :trashbird)) {:password "anything"
+                                                                                :old_password "whatever"}))


chopping to clojure 1.7-alpha5 issue: previous failed

--- test/midje/util/t_one_seven.clj
+++ test/midje/util/t_one_seven.clj
@@ -14,6 +14,12 @@
   (binding [*mocked-function-produces-next-element* (fn [n] (swap! counter inc) (inc n))]
     (eagerly (take 5 (function-under-test-produces-a-lazy-list)))))

+(fact "eagerly forces evaluation"
+  (reset! counter 1)
+  (mock-use)
+;  @counter => 5
+)
+
 ;; After justification, more facts.

 (unfinished exploder)


Fix tests, were too tolerant.

Fix tests, were too tolerant.

--- test/afterglow/effects_test.clj
+++ test/afterglow/effects_test.clj
@@ -108,17 +108,16 @@
       (is (= red (fade-assignment red green -1 @test-show @test-snapshot)))
       (is (= green (fade-assignment red green 10 @test-show @test-snapshot)))
       (is (util/float= 60.0 (colors/hue (:value (fade-assignment red green 0.5 @test-show @test-snapshot)))))
-      (is (util/float= 50 (colors/lightness (:value (fade-assignment red green 0.5 @test-show @test-snapshot))) 0.2))
-      (is (util/float= 100 (colors/saturation (:value (fade-assignment red green 0.5 @test-show @test-snapshot))) 0.2))
+      (is (util/float= 50 (colors/lightness (:value (fade-assignment red green 0.5 @test-show @test-snapshot)))))
+      (is (util/float= 100 (colors/saturation (:value (fade-assignment red green 0.5 @test-show @test-snapshot)))))
       (is (util/float= 30.0 (colors/hue (:value (fade-assignment red green 0.25 @test-show @test-snapshot)))))
       (is (util/float= 90 (colors/hue (:value (fade-assignment red green 0.75 @test-show @test-snapshot)))))
       (is (util/float= 0.0 (colors/hue (:value (fade-assignment red white 0.5 @test-show @test-snapshot)))))
-      (is (util/float= 75.0 (colors/lightness (:value (fade-assignment red white 0.5 @test-show @test-snapshot))) 0.2))
+      (is (util/float= 75.0 (colors/lightness (:value (fade-assignment red white 0.5 @test-show @test-snapshot)))))
       (is (util/float= 0.0 (colors/hue (:value (fade-assignment red nil 0.9 @test-show @test-snapshot)))))
-      (is (util/float= 5.0 (colors/lightness (:value (fade-assignment red nil 0.9 @test-show @test-snapshot))) 0.2))
+      (is (util/float= 5.0 (colors/lightness (:value (fade-assignment red nil 0.9 @test-show @test-snapshot)))))
       (is (util/float= 120 (colors/hue (:value (fade-assignment nil green 0.02 @test-show @test-snapshot)))))
-      (is (util/float= 1.0 (colors/lightness (:value (fade-assignment nil green 0.02 @test-show @test-snapshot)))
-                       0.2)))))
+      (is (util/float= 1.0 (colors/lightness (:value (fade-assignment nil green 0.02 @test-show @test-snapshot))))))))

 (deftest test-fade-direction
   (testing "Fading a direction assigner moves between the directions"


adding a first fact making sure that the root route returns a status code of 200

--- test/bitfondue/handler_test.clj
+++ test/bitfondue/handler_test.clj
@@ -3,3 +3,7 @@
             [ring.mock.request :as mock])
   (:use midje.sweet))

+(fact "The root route / is returning a 200 status code"
+  (->> (mock/request :get "/")
+       app
+       :status) => 200)


add big query load job to import json/csv data from cloudstorage

--- bigquery/src/gclouj/bigquery.clj
+++ bigquery/src/gclouj/bigquery.clj
@@ -1,5 +1,5 @@
 (ns gclouj.bigquery
-  (:import [com.google.gcloud.bigquery BigQueryOptions BigQuery$DatasetListOption DatasetInfo DatasetId BigQuery$TableListOption TableInfo TableId BigQuery$DatasetOption BigQuery$TableOption Schema Field Field$Type Field$Mode TableInfo$StreamingBuffer InsertAllRequest InsertAllRequest$RowToInsert InsertAllResponse BigQueryError BigQuery$DatasetDeleteOption QueryRequest QueryResponse QueryResult JobId Field Field$Type$Value FieldValue FieldValue$Attribute]
+  (:import [com.google.gcloud.bigquery BigQueryOptions BigQuery$DatasetListOption DatasetInfo DatasetId BigQuery$TableListOption TableInfo TableId BigQuery$DatasetOption BigQuery$TableOption Schema Field Field$Type Field$Mode TableInfo$StreamingBuffer InsertAllRequest InsertAllRequest$RowToInsert InsertAllResponse BigQueryError BigQuery$DatasetDeleteOption QueryRequest QueryResponse QueryResult JobId Field Field$Type$Value FieldValue FieldValue$Attribute LoadJobInfo LoadConfiguration BigQuery$JobOption JobInfo$CreateDisposition JobInfo$WriteDisposition JobStatistics JobStatistics$LoadStatistics JobStatus JobStatus$State FormatOptions]
            [com.google.common.hash Hashing]
            [java.util List Collections]))

@@ -77,7 +77,26 @@
                    :results    (map (fn [fields] (map to-clojure fields))
                                     (iterator-seq (.. x result iterateAll)))
                    :schema     (to-clojure (.. x result schema))
-                   :cache-hit  (.. x result cacheHit)}))
+                   :cache-hit  (.. x result cacheHit)})
+  JobStatistics$LoadStatistics
+  (to-clojure [x] {:input-bytes  (.inputBytes x)
+                   :input-files  (.inputFiles x)
+                   :output-bytes (.outputBytes x)
+                   :output-rows  (.outputRows x)})
+  JobStatistics
+  (to-clojure [x] {:created (.creationTime x)
+                   :end     (.endTime x)
+                   :started (.startTime x)})
+  JobStatus
+  (to-clojure [x] {:state  ({JobStatus$State/DONE    :done
+                             JobStatus$State/PENDING :pending
+                             JobStatus$State/RUNNING :running} (.state x))
+                   :errors (seq (map to-clojure (.executionErrors x)))})
+  LoadJobInfo
+  (to-clojure [x] {:job-id     (to-clojure (.jobId x))
+                   :statistics (to-clojure (.statistics x))
+                   :email      (.userEmail x)
+                   :status     (to-clojure (.status x))}))

 (defn service
   ([] (.service (BigQueryOptions/defaultInstance))))
@@ -205,3 +224,22 @@
       (.useQueryCache builder use-cache?))
     (let [q (.build builder)]
       (to-clojure (.query service q)))))
+
+
+
+(defn job [service {:keys [project-id job-id] :as job}]
+  (to-clojure (.getJob service (JobId/of project-id job-id) (into-array BigQuery$JobOption []))))
+
+
+(defn load-job [service {:keys [project-id dataset-id table-id] :as table} {:keys [format create-disposition write-disposition]} & uris]
+  (let [config-builder (LoadConfiguration/builder (TableId/of project-id dataset-id table-id)
+                                                  ({:json (FormatOptions/json)
+                                                    :csv  (FormatOptions/csv)} (or format :json)))]
+    (.createDisposition config-builder ({:needed JobInfo$CreateDisposition/CREATE_IF_NEEDED
+                                         :never JobInfo$CreateDisposition/CREATE_NEVER} (or create-disposition :never)))
+    (.writeDisposition config-builder ({:append JobInfo$WriteDisposition/WRITE_APPEND
+                                        :empty  JobInfo$WriteDisposition/WRITE_EMPTY
+                                        :truncate JobInfo$WriteDisposition/WRITE_TRUNCATE} (or write-disposition :append)))
+    (let [configuration (.build config-builder)
+          job           (.build (LoadJobInfo/builder configuration ^List uris))]
+      (to-clojure (.create service job (into-array BigQuery$JobOption []))))))


proofreading

proofreading

--- Clojure-Websockets/MainApp/src/cljs/birdwatch/state/data.cljs
+++ Clojure-Websockets/MainApp/src/cljs/birdwatch/state/data.cljs
@@ -6,7 +6,7 @@
   "Init app state and wire all channels required in the state namespace. The app
    atom is held inside the let binding of this function and thus protected from
    outside access / alteration. The only way to interact with it is by sending
-   messages on channels, such the provided data channel for adding new data or
+   messages on channels, such as the provided data channel for adding new data or
    sending commands on the cmd-chan."
   [data-chan qry-chan stats-chan cmd-chan state-pub-chan]
   (let [app (atom {})]


Fix naming of tests.

Fix naming of tests.

--- test/manners/victorian_test.clj
+++ test/manners/victorian_test.clj
@@ -23,7 +23,7 @@
   (manner d-keyword-coach
           (comp (partial = "derp") name) "name is derp"))

-(deftest manner-test
+(deftest test-manner
   (testing "simple manner"
     (let [truthy-str-coach (manner identity "is truthy"
                                    string? "is a string")]
@@ -47,7 +47,7 @@
                      [number? num-msg]])
 (def odd-number-coach (etiquette odd-number-etq))

-(deftest manners-test
+(deftest test-etiquette
   (testing "always returns a sequence"
     (is (sequential? (odd-number-coach nil)))
     (is (sequential? (odd-number-coach 3737))))
@@ -66,7 +66,7 @@
         (is (= (list nine-or-three-msg) (nine-or-three-coach 5)))
         (is (= (list) (nine-or-three-coach 3)))))))

-(deftest bad-manners-test
+(deftest test-bad-manners
   (testing "works with an empty etiquette"
     (is (= (list) (bad-manners [] nil)))
     (is (= (list) (bad-manners [[]] false))))
@@ -76,14 +76,14 @@
     (is (= (list odd-msg) (bad-manners odd-number-etq 2)))
     (is (= (list) (bad-manners odd-number-etq 3)))))

-(deftest rude?-and-proper?-test
+(deftest test-rude?-and-proper?
   (testing "are complements"
     (is (rude? odd-number-etq 2))
     (is (not (proper? odd-number-etq 2)))
     (is (not (rude? odd-number-etq 1)))
     (is (proper? odd-number-etq 1))))

-(deftest avow-test
+(deftest test-avow
   (testing "throws an error when bad manners are found"
     (is (thrown? AssertionError #"it should be odd, it should be a number"
                  (avow odd-number-etq nil)))
@@ -94,7 +94,7 @@

 ;; An etiquette is a sequence of manners.
 ;; A manner is either a coach or a predicate message pair.
-(deftest composable-coaches-test
+(deftest test-composable-coaches
   (let [msg1 "should be a map"
         msg2 "should contain the key :hey"
         msg3 "should have an odd number of keys"
@@ -131,7 +131,7 @@
      (catch AssertionError e#
        (.getMessage e#))))

-(deftest defmannerisms-test
+(deftest test-defmannerisms
   (defmannerisms odd-number odd-number-etq)
   (doseq [v [nil 1 {} 2 "3"]]
     (doseq [[pfunc func] [[proper-odd-number? proper?]


cleaning up test handler

cleaning up test handler

--- test/prometheus/unit/t_core.clj
+++ test/prometheus/unit/t_core.clj
@@ -6,11 +6,14 @@
   (:import (io.prometheus.client CollectorRegistry)
            (io.prometheus.client.exporter.common TextFormat)))

-(def test-response (with-meta {:status 200 :body "ok"} {:path "/test"}))
+(defn test-handler [_]
+  (with-meta
+    {:status 200 :body "ok"}
+    {:path "/test"}))

 (facts "metrics export"
   (let [registry (CollectorRegistry.)
-        handler (prometheus/instrument-handler (constantly test-response) "test" registry)
+        handler (prometheus/instrument-handler test-handler "test" registry)
         response (handler (ring/request :get "/test"))
         metrics (prometheus/dump-metrics registry)]
     (fact "handler returns delegate's response"


Put a newline after the CSV header.

Put a newline after the CSV header.

--- src/frmr/dstt.clj
+++ src/frmr/dstt.clj
@@ -215,7 +215,7 @@
                                                parsed-handler)]
           (if csv
             (with-open [csv-writer (io/writer csv)]
-              (.write csv-writer (str "Load test: " url " Requests: " requests " Seconds: " seconds))
+              (.write csv-writer (str "Load test: " url " Requests: " requests " Seconds: " seconds "\n"))
               (let [raw-results (get load-test-results "RawResults")
                     lines (map #(join "," %) raw-results)
                     content (join "\n" lines)]


Revert "CMR-3298 removes commented out lines"

This reverts commit e4ffab281c1d0155f37a73036d41e95f6c57c24f.

Accidently removed some code that shouldn't have been removed.

--- access-control-app/src/cmr/access_control/services/acl_service.clj
+++ access-control-app/src/cmr/access_control/services/acl_service.clj
@@ -160,11 +160,15 @@
   [_]
   (cpv/merge-params-config
     cpv/basic-params-config
-    {:single-value #{}
+    {:single-value #{:include-full-acl}
      :multiple-value #{:permitted-group :identity-type :provider}
      :always-case-sensitive #{}
      :disallow-pattern #{:identity-type :permitted-user :group-permission}
      :allow-or #{}}))
+
+(defmethod cpv/valid-query-level-params :acl
+  [_]
+  #{:include-full-acl})

 (defmethod cpv/valid-parameter-options :acl
   [_]
@@ -274,6 +278,17 @@
       [(format (str "Parameter identity_type has invalid values [%s]. "
                     "Only 'provider', 'system', 'single_instance', or 'catalog_item' can be specified.")
                (str/join ", " invalid-types))])))
+
+(defn boolean-value-validation
+  "Validates that all of the boolean parameters have values of true or false."
+  [concept-type params]
+  (let [bool-params (select-keys params [:include-full-acl])]
+    (mapcat
+      (fn [[param value]]
+        (when-not (contains? #{"true" "false"} (when value (str/lower-case value)))
+          [(format "Parameter %s must take value of true or false but was [%s]"
+                   (csk/->snake_case_string param) value)]))
+      bool-params)))

 (defn validate-acl-search-params
   "Validates the parameters for an ACL search. Returns the parameters or throws an error if invalid."
@@ -289,7 +304,10 @@
     (cpv/validate-parameters
       :acl safe-params
       (concat cpv/common-validations
-              [permitted-group-validation identity-type-validation group-permission-validation])
+              [permitted-group-validation
+               identity-type-validation
+               group-permission-validation
+               boolean-value-validation])
       type-errors))
   params)

@@ -308,6 +326,16 @@
    :provider :string
    :permitted-user :acl-permitted-user
    :group-permission :acl-group-permission})
+
+(defmethod cp/parse-query-level-params :acl
+  [concept-type params]
+  (let [[params query-attribs] (cp/default-parse-query-level-params :acl params)
+        result-features (when (= (:include-full-acl params) "true"
+                                 [:include-full-acl]))]
+    [(dissoc params :include-full-acl)
+     (merge query-attribs
+            (when (= (:include-full-acl params) "true")
+              {:result-features [:include-full-acl]}))]))

 (defmethod cp/parameter->condition :acl-identity-type
  [context concept-type param value options]
@@ -410,10 +438,6 @@
 (def all-permissions
   "The set of all permissions checked and returned by the functions below."
   #{:read :order :update :delete})
-
-(def provider-level-permissions
-  "The set of permissions that are checked at the provider level."
-  #{:update :delete})

 (defn- collect-permissions
   "Returns seq of any permissions where (grants-permission? acl permission) returns true for any acl in acls."
@@ -467,20 +491,41 @@
   "Returns true if permission keyword is granted on concept to any sids by given acl."
   [acl permission concept sids]
   (and (acl/acl-matches-sids-and-permission? sids (name permission) acl)
-       (if (contains? provider-level-permissions permission)
-         (when-let [acl-provider-id (-> acl :provider-object-identity :provider-id)]
-           (= acl-provider-id (:provider-id concept)))
-         ;; else check that the concept matches
-         (case (:concept-type concept)
-           :collection (acl-matchers/coll-applicable-acl? (:provider-id concept) concept acl)
-           :granule (acl-matches-granule? acl concept)))))
+       (case (:concept-type concept)
+         :collection (acl-matchers/coll-applicable-acl? (:provider-id concept) concept acl)
+         :granule (acl-matches-granule? acl concept))))
+
+(defn- provider-acl?
+  "Returns true if the ECHO-style acl specifically identifies the given provider id."
+  [provider-id acl]
+  (or
+    (-> acl :provider-object-identity :provider-id (= provider-id))
+    (-> acl :catalog-item-identity :provider-id (= provider-id))))
+
+(defn- ingest-management-acl?
+  "Returns true if the ACL targets a provider INGEST_MANAGEMENT_ACL."
+  [acl]
+  (-> acl :provider-object-identity :target (= schema/ingest-management-acl-target)))

 (defn- concept-permissions-granted-by-acls
-  "Returns the set of permission keywords (:read, :update, :order, or :delete) granted on concept
+  "Returns the set of permission keywords (:read, :order, and :update) granted on concept
    to the seq of group guids by seq of acls."
   [concept sids acls]
-  (collect-permissions #(grants-concept-permission? %1 %2 concept sids)
-                       acls))
+  (let [provider-acls (filter #(provider-acl? (:provider-id concept) %) acls)
+        ;; When a user has UPDATE on the provider's INGEST_MANAGEMENT_ACL target, then they have UPDATE and
+        ;; DELETE permission on all of the provider's catalog items.
+        ingest-management-permissions (when (some #(acl/acl-matches-sids-and-permission? sids "update" %)
+                                                  (filter ingest-management-acl? provider-acls))
+                                        [:update :delete])
+        ;; The remaining catalog item ACLs can only grant READ or ORDER permission.
+        catalog-item-acls (filter :catalog-item-identity provider-acls)
+        catalog-item-permissions (for [permission [:read :order]
+                                       :when (some #(grants-concept-permission? % permission concept sids)
+                                                   catalog-item-acls)]
+                                   permission)]
+    (set
+      (concat catalog-item-permissions
+              ingest-management-permissions))))

 (defn- add-acl-enforcement-fields
   "Adds all fields necessary for comparing concept map against ACLs."
@@ -492,7 +537,7 @@
                        (mdb/get-latest-concept context parent-id)))
       concept)))

-(defn get-concept-permissions
+(defn get-catalog-item-permissions
   "Returns a map of concept ids to seqs of permissions granted on that concept for the given username."
   [context username-or-type concept-ids]
   (let [sids (get-sids context username-or-type)
@@ -506,10 +551,13 @@
 (defn- system-permissions-granted-by-acls
   "Returns a set of permission keywords granted on the system target to the given sids by the given acls."
   [system-object-target sids acls]
-  (collect-permissions (fn [acl permission]
-                         (and (= system-object-target (:target (:system-object-identity acl)))
-                              (acl/acl-matches-sids-and-permission? sids (name permission) acl)))
-                       acls))
+  (let [relevant-acls (filter #(-> % :system-object-identity :target (= system-object-target))
+                              acls)]
+    (set
+      (for [permission [:create :read :update :delete]
+            :when (some #(acl/acl-matches-sids-and-permission? sids (name permission) %)
+                        relevant-acls)]
+        permission))))

 (defn get-system-permissions
   "Returns a map of the system object type to the set of permissions granted to the given username or user type."


remove expect-let

remove expect-let

--- occi/java/jar/src/test/clojure/slipstream/credcache/common_test.clj
+++ occi/java/jar/src/test/clojure/slipstream/credcache/common_test.clj
@@ -40,16 +40,16 @@
                        {:typeURI "unknown" :other "field"}]]
                    (validate m)))

-(expect-let [m {}]
-            m
-            (try
-              (validate m)
-              (catch Exception e
-                (ex-data e))))
+(let [m {}]
+  (expect m
+          (try
+            (validate m)
+            (catch Exception e
+              (ex-data e)))))

-(expect-let [m {:typeURI "unknown" :other "field"}]
-            m
-            (try
-              (validate m)
-              (catch Exception e
-                (ex-data e))))
+(let [m {:typeURI "unknown" :other "field"}]
+  (expect m
+          (try
+            (validate m)
+            (catch Exception e
+              (ex-data e)))))


Gui: anonymous functions for handler removed

--- src/gui/menus.clj
+++ src/gui/menus.clj
@@ -19,16 +19,16 @@
                         :separator
                         (action
                           :icon (icon-path "task_sat.gif")
-                          :handler #(handler-sat %))
+                          :handler handler-sat)
                         (action
                           :icon (icon-path "task_tt.gif")
-                          :handler #(handler-tt %))
+                          :handler handler-tt)
                         (action
                           :icon (icon-path "task_cnf.gif")
-                          :handler #(handler-cnf %))
+                          :handler handler-cnf)
                         (action
                           :icon (icon-path "task_tcnf.gif")
-                          :handler #(handler-tseitin %))
+                          :handler handler-tseitin)
                         (button :text "Dimacs")
                         (button :icon (icon-path "task_m4.gif"))
                         :separator
@@ -100,23 +100,24 @@
                             :name "Check SAT"
                             ;:key "ctrl T+S"
                             :icon (icon-path "task_sat.gif")
-                            :handler #(handler-sat %))
+                            :handler handler-sat)
                           (action
                             :name "Truth Table"
                             ;:key "ctrl T T"
                             :icon (icon-path "task_tt.gif")
-                            :handler #(handler-tt %))
+                            :handler handler-tt)
                           (action
                             :name "Transform to CNF"
                             ;:key "ctrl T C"
                             :icon (icon-path "task_cnf.gif")
-                            :handler #(handler-cnf %))
+                            :handler handler-cnf)
                           (action
                             :name "Tseitin Transformation"
                             :icon (icon-path "task_tcnf.gif")
-                            :handler #(handler-tseitin %))
+                            :handler handler-tseitin)
                           (action
                             :name "Generate DIMACS")
+                            ;:handler #(handler-dimacs %))
                           (action
                             :name "Preprocess with M4"
                             ;:key "ctrl T M"


[#2925] Use column definition from data_group

Co-authored-by: Daniel Sunnerek <3d0f3b9ddcacec30c4008c5e030e6c13a478cb4f@akvo.org>

--- backend/src/akvo/lumen/lib/visualisation/map_metadata.clj
+++ backend/src/akvo/lumen/lib/visualisation/map_metadata.clj
@@ -116,15 +116,24 @@
                               first :st_extent)]
       (parse-box st-extent))))

-(defn get-column-titles [tenant-conn selector-name selector-value dataset-version-ns]
-  (let [sql-str "SELECT columns, modified FROM dataset_version WHERE %s='%s' AND namespace='%s' ORDER BY version DESC LIMIT 1"]
+(defn get-column-titles [tenant-conn selector-name selector-value dataset-version-ns dataset-id]
+  (let [sql-str "SELECT columns FROM dataset_version WHERE %s='%s' AND namespace='%s' ORDER BY version DESC LIMIT 1"
+        columns (-> (jdbc/query tenant-conn (format sql-str selector-name selector-value dataset-version-ns))
+                        first
+                        :columns)
+        columns (if (empty? columns)
+                  (->> (jdbc/query tenant-conn (format "SELECT dg.columns
+                                                          FROM (SELECT id FROM dataset_version_2
+                                                                 WHERE dataset_id = '%s'
+                                                         ORDER BY version DESC LIMIT 1) dv, data_group dg
+                                                         WHERE dv.id = dg.dataset_version_id" dataset-id))
+                      (mapcat :columns))
+                  columns)]
     (map (fn [{:strs [columnName title type]}]
            {:columnName columnName
             :type type
             :title title})
-         (-> (jdbc/query tenant-conn (format sql-str selector-name selector-value dataset-version-ns))
-             first
-             :columns))))
+         columns)))

 (defn get-column-title-for-name [collection column-name]
   (-> (filter (fn [{:keys [columnName]}]
@@ -134,7 +143,7 @@
       :title))

 (defn point-metadata [tenant-conn table-name layer where-clause opts]
-  (let [column-titles (get-column-titles tenant-conn "table_name" table-name "main")]
+  (let [column-titles (get-column-titles tenant-conn "table_name" table-name "main" (:datasetId layer))]
     {:boundingBox (bounds tenant-conn table-name layer where-clause opts)
      :pointColorMapping (point-color-mapping tenant-conn table-name layer where-clause column-titles)
      :availableColors palette
@@ -142,9 +151,9 @@
      :columnTitles column-titles}))

 (defn shape-aggregation-metadata [tenant-conn table-name layer where-clause opts]
-  (let [column-titles (get-column-titles tenant-conn "table_name" table-name "main")
+  (let [column-titles (get-column-titles tenant-conn "table_name" table-name "main" (:datasetId layer))
         column-title-for-name (get-column-title-for-name
-                               (get-column-titles tenant-conn "dataset_id" (:aggregationDataset layer) "main")
+                               (get-column-titles tenant-conn "dataset_id" (:aggregationDataset layer) "main" (:datasetId layer))
                                (:aggregationColumn layer))
         shape-color-mapping-title (format "%s (%s)" column-title-for-name
                                           (:aggregationMethod layer))]
@@ -155,7 +164,7 @@
      :shapeColorMappingTitle shape-color-mapping-title}))

 (defn shape-metadata [tenant-conn table-name layer where-clause opts]
-  (let [column-titles (get-column-titles tenant-conn "table_name" table-name "main")]
+  (let [column-titles (get-column-titles tenant-conn "table_name" table-name "main" (:datasetId layer))]
     {:columnTitles column-titles
      :boundingBox (bounds tenant-conn table-name layer where-clause opts)}))


Slightly better broadcast-update signature

--- worker/src/clinicico/worker.clj
+++ worker/src/clinicico/worker.clj
@@ -18,22 +18,21 @@
 (defonce ^{:private true} conn (rmq/connect))

 (defn broadcast-update
-  ([id status]
-   (broadcast-update id status nil "update"))
-  ([id status message]
-   (broadcast-update id status message "update"))
-  ([id status message type]
+  ([id]
+   (broadcast-update id {} "update"))
+  ([id content]
+   (broadcast-update id content "update"))
+  ([id content type]
    (with-open [ch (lch/open conn)]
-     (let [msg {:content {:status status :message message} :id id :type type}]
+     (let [msg {:content content :id id :type type}]
        (lb/publish ch outgoing type (json/encode-smile msg) :content-type "application/x-jackson-smile")))))

 (defn task-handler
   [ch {:keys [content-type delivery-tag type] :as meta} ^bytes payload]
   (let [task (json/parse-smile payload true)]
-    (log/debug
-      (format "[consumer] Received a message: %s, delivery tag: %d, content type: %s, type: %s" task delivery-tag content-type type))
+    (broadcast-update (:id task) {:status "processing" :accepted (java.util.Date.)})
     (Thread/sleep 6000)
-    (broadcast-update (:id task) "completed")))
+    (broadcast-update (:id task) {:status "completed" :completed (java.util.Date.)})))

 (defn start-consumer
   "Starts a consumer in a separate thread"
@@ -47,9 +46,9 @@
   [& args]
   (let [[options args banner]
         (cli args
-          ["-h" "--help" "Show help" :default false :flag true]
-          ["-n" "--nworkers" "The amount of worker threads to start" :default (.availableProcessors (Runtime/getRuntime)) :parse-fn #(Integer. %)]
-          ["-m" "--method" "The R method and queue name to execute" :default "echo"])
+             ["-h" "--help" "Show help" :default false :flag true]
+             ["-n" "--nworkers" "The amount of worker threads to start" :default (.availableProcessors (Runtime/getRuntime)) :parse-fn #(Integer. %)]
+             ["-m" "--method" "The R method and queue name to execute" :default "echo"])
         method (:method options)]
     (when (or (:help options))
       (println banner)
@@ -59,6 +58,7 @@
             q (.getQueue (lq/declare ch method :durable true :exclusive false :auto-delete true))]
         (log/info (format "[main] Connected worker %d. Channeld id: %d for channel %s" (inc n) (.getChannelNumber ch) method))
         (lq/bind ch q incoming :routing-key method)
-        (start-consumer conn ch q)))
-      (while true (Thread/sleep 100))
-      (rmq/close conn)))
+        (start-consumer conn (lch/open conn) q)
+        (rmq/close ch)))
+    (while true (Thread/sleep 100))
+    (rmq/close conn)))


Another test

Another test

--- test/ctia/http/routes/observable/verdict_test.clj
+++ test/ctia/http/routes/observable/verdict_test.clj
@@ -362,10 +362,13 @@
   (helpers/set-capabilities! "foouser" "user" all-capabilities)
   (whoami-helpers/set-whoami-response "45c1f5e3f05d0" "foouser" "user")

-  (testing ":start_time is now and :end_date is in 2 weeks"
-
-    (let [sha (str "39091a6e0d00472273c3d644a47611b"
-                   "ac95554d8d48899ec74d1b3127542f89b")
+  (testing ":start_time is now and :end_time is in 2 weeks"
+
+    (let [{:keys [type value]
+           :as observable}
+          {:type "sha256"
+           :value (str "39091a6e0d00472273c3d644a47611b"
+                       "ac95554d8d48899ec74d1b3127542f89b")}

           {status :status
            judgement :parsed-body}
@@ -374,8 +377,7 @@
                                                     time/format-date-time)
                                     :end_time (-> (time/plus-n :weeks (time/now) 2)
                                                   time/format-date-time)}
-                       :observable {:value sha,
-                                    :type "sha256"}
+                       :observable observable
                        :reason_uri "https://example.com/",
                        :source "Example",
                        :external_ids ["judgement-1"],
@@ -393,7 +395,7 @@
       (testing "GET /ctia/:observable_type/:observable_value/verdict"
         (let [{status :status
                verdict :parsed-body}
-              (get (str "ctia/sha256/" sha "/verdict")
+              (get (str "ctia/" type "/" value "/verdict")
                    :headers {"api_key" "45c1f5e3f05d0"})]
           (is (= 200 status))
           (is (= (:id judgement)
@@ -433,6 +435,11 @@
   (testing ":end_time is today, but in the future"
     (let [format (partial format/unparse (format/formatters :date-time))

+          {:keys [type value]
+           :as observable}
+          {:type "ip"
+           :value "10.0.0.2"}
+
           {status :status
            judgement :parsed-body}
           (post "ctia/judgement"
@@ -444,8 +451,7 @@
                                                   (clj-time/plus
                                                    (clj-time/seconds 10))
                                                   format)}
-                       :observable {:value "10.0.0.2"
-                                    :type "ip"}
+                       :observable observable
                        :reason_uri "https://example.com/",
                        :source "Example",
                        :external_ids ["judgement-3"],
@@ -463,8 +469,49 @@
       (testing "GET /ctia/:observable_type/:observable_value/verdict"
         (let [{status :status
                verdict :parsed-body}
-              (get "ctia/ip/10.0.0.2/verdict"
+              (get (str "ctia/" type "/" value "/verdict")
                    :headers {"api_key" "45c1f5e3f05d0"})]
           (is (= 200 status))
           (is (= (:id judgement)
-                 (:judgement_id verdict))))))))
+                 (:judgement_id verdict)))))))
+
+  (testing ":start_time and :end_time are both in the future"
+    (let [format (partial format/unparse (format/formatters :date-time))
+
+          {:keys [type value]
+           :as observable}
+          {:type "ip"
+           :value "10.0.0.3"}
+
+          {status :status
+           judgement :parsed-body}
+          (post "ctia/judgement"
+                :body {:valid_time {:start_time (-> (clj-time/now)
+                                                    (clj-time/plus
+                                                     (clj-time/minutes 1))
+                                                    format)
+                                    :end_time (-> (clj-time/now)
+                                                  (clj-time/plus
+                                                   (clj-time/minutes 2))
+                                                  format)}
+                       :observable observable
+                       :reason_uri "https://example.com/",
+                       :source "Example",
+                       :external_ids ["judgement-4"],
+                       :disposition 2,
+                       :disposition_name "Malicious"
+                       :reason "Example judgement",
+                       :source_uri "https://example.com/",
+                       :priority 0,
+                       :severity "None",
+                       :tlp "green",
+                       :confidence "None"}
+                :headers {"api_key" "45c1f5e3f05d0"})]
+      (is (= 201 status))
+
+      (testing "GET /ctia/:observable_type/:observable_value/verdict"
+        (let [{status :status
+               verdict :parsed-body}
+              (get (str "ctia/" type "/" value "/verdict")
+                   :headers {"api_key" "45c1f5e3f05d0"})]
+          (is (= 404 status)))))))


[#214] Catch NPE when trying to parse a value to number

--- api/src/clojure/org/akvo/flow_api/datastore/form_instance.clj
+++ api/src/clojure/org/akvo/flow_api/datastore/form_instance.clj
@@ -81,7 +81,8 @@

 (defn parse-double [s]
   (try (Double/parseDouble s)
-       (catch NumberFormatException _)))
+       (catch NumberFormatException _)
+       (catch NullPointerException _)))

 (defmethod parse-response "NUMBER"
   [_ response-str opts]


Add explanatory comment

Add explanatory comment

--- ui-gallery/desktop/src-common/ui_gallery/core.clj
+++ ui-gallery/desktop/src-common/ui_gallery/core.clj
@@ -32,6 +32,9 @@
   :on-render
   (fn [screen entities]
     (clear!)
+    ; we only need to render the screen, because UI entities are automatically drawn when
+    ; the stage they are attached to is drawn. if we called (render! screen entities)
+    ; as usual, it would cause the UI entities to be drawn twice.
     (render! screen)
     entities)


(SERVER-114) add comment about test coverage

--- test/integration/puppetlabs/services/puppet_admin/puppet_admin_int_test.clj
+++ test/integration/puppetlabs/services/puppet_admin/puppet_admin_int_test.clj
@@ -37,3 +37,6 @@
                        ssl-request-options)]
         (is (= 401 (:status response))
             (ks/pprint-to-string response))))))
+
+;; See 'environment-flush-integration-test'
+;; for additional test coverage on the /environment-cache endpoint


Upgrade to Clojure 1.9-alpha12 (for spec)

--- build.boot
+++ build.boot
@@ -20,7 +20,7 @@
    [deraen/boot-sass "0.2.1" :scope "test"]
    [reloaded.repl "0.2.1" :scope "test"]

-   [org.clojure/clojure "1.8.0"]
+   [org.clojure/clojure "1.9.0-alpha12"]
    [org.clojure/clojurescript "1.9.229"]

    [org.clojure/tools.nrepl "0.2.12"]
@@ -37,7 +37,12 @@
    [org.clojure/tools.namespace "0.2.11"]
    [prismatic/schema "1.0.4"]
    [selmer "1.0.4"]
-   [yada "1.1.33"]
+   [yada "1.1.33" :exclusions [aleph manifold ring-swagger prismatic/schema]]
+
+   [aleph "0.4.2-alpha8"]
+   [manifold "0.1.6-alpha1"]
+   [metosin/ring-swagger "0.22.10"]
+   [prismatic/schema "1.1.3"]

    ;; App deps
    [reagent "0.6.0-rc"]


Add empty_tasks_warning to project spec

Add empty_tasks_warning to project spec

--- src/cider_ci/builder/jobs/validator/project_configuration.clj
+++ src/cider_ci/builder/jobs/validator/project_configuration.clj
@@ -63,15 +63,16 @@
 ;##############################################################################

 (def job-config-meta-spec
-  {:key {:validator validate-string!}
+  {:context nil
+   :depends_on {:validator (build-map-of-validator validate-dependency-or-trigger!)}
+   :description {:validator validate-string!}
+   :empty_tasks_warning {:validator validate-boolean!}
+   :key {:validator validate-string!}
    :name {:validator validate-string!}
-   :description {:validator validate-string!}
    :run_when {:validator (build-map-of-validator validate-dependency-or-trigger!)}
-   :depends_on {:validator (build-map-of-validator validate-dependency-or-trigger!)}
    :task nil
+   :task_defaults nil
    :tasks nil
-   :context nil
-   :task_defaults nil
    })

 (defn validate-job! [job-spec chain]


CMR2819- fixed improper spacing

CMR2819- fixed improper spacing

--- access-control-app/src/cmr/access_control/data/access_control_index.clj
+++ access-control-app/src/cmr/access_control/data/access_control_index.clj
@@ -193,7 +193,6 @@
   (or (:provider-id (:catalog-item-identity acl))
       (:provider-id (:provider-identity acl))))

-
 (defn- acl-concept-map->elastic-doc
   "Converts a concept map containing an acl into the elasticsearch document to index."
   [concept-map]


remove obsolete file

remove obsolete file

--- dev/my.clj
+++ dev/my.clj
@@ -1,37 +0,0 @@
-(ns my
-  (:require [mount.core :as mount]
-            [traceman.keeper :refer [tracks]]
-            [traceman.core :refer [trace-env]]))
-
-(defn go
-  []
-  (mount/stop)
-  (mount/start))
-
-(defn foo
-  "I don't do a whole lot."
-  [x]
-  (trace-env)
-  (println x "Hello, World!")
-  (let [x 3 z 2]
-    (trace-env)
-    (let [{:keys [asd]} {:asd "test"}]
-      (trace-env))
-    :return))
-
-(defn rock-n-roll!
-  [data]
-  (trace-env)
-  (foo data))
-
-(defn bar
-  []
-  (println "some bar, calling foo")
-  (rock-n-roll! {:y 1}))
-
-(defn another
-  []
-  (println "another root")
-  (foo (range 5)))
-
-(defrecord Person [fname lname])


don't break if we store invalid html in a build message

we store invalid html in our build messages

--- frontend/components/common.cljs
+++ frontend/components/common.cljs
@@ -5,6 +5,7 @@
             [frontend.datetime :as datetime]
             [frontend.utils :as utils :include-macros true]
             [frontend.utils.github :as gh-utils]
+            [goog.dom.DomHelper]
             [om.core :as om :include-macros true]
             [om.dom :as dom :include-macros true])
   (:require-macros [frontend.utils :refer [html]]))
@@ -44,15 +45,24 @@
                        </path>
                        <circle fill=\"#fff\" cx=\"50\" cy=\"50\" r=\"11.905\"></circle>"}}])

+(defn normalize-html
+  "Creates a valid html string given a (possibly) invalid html string."
+  [html-string]
+  (let [dom-helper (goog.dom.DomHelper.)]
+    (->> html-string
+         (.htmlToDocumentFragment dom-helper)
+         (.getOuterHtml dom-helper))))
+
 (defn messages [messages]
   [:div.row-fluid
    (when (pos? (count messages))
-     [:div#build-messages.offset1.span10
-      (map (fn [message]
-             [:div.alert.alert-info
-              [:strong "Warning: "]
-              [:span {:dangerouslySetInnerHTML #js {"__html" (:message message)}}]])
-           messages)])])
+     (let [dom-helper (goog.dom.DomHelper.)]
+       [:div#build-messages.offset1.span10
+        (map (fn [message]
+               [:div.alert.alert-info
+                [:strong "Warning: "]
+                [:span {:dangerouslySetInnerHTML #js {"__html" (normalize-html (:message message))}}]])
+             messages)]))])

 ;; TODO: Why do we have ico and icon?
 (def ico-paths


draw signup text before rect in opening animation

--- src-cljs/frontend/components/drawing.cljs
+++ src-cljs/frontend/components/drawing.cljs
@@ -218,24 +218,33 @@
         text-start-y (+ rect-end-y text-height (/ (- rect-height text-height) 2))]
     (-> {:tick-ms 16
          :ticks {}}
-      (move-mouse {:start-tick 10 :end-tick 45 :start-x ex :end-x rect-start-x :start-y ey :end-y rect-start-y})
-      (draw-shape {:doc-id (:db/id document) :tool :rect :start-tick 50 :end-tick 100
+      (move-mouse {:tool :text
+                   :start-tick 10
+                   :end-tick 45
+                   :start-x ex :end-x text-start-x
+                   :start-y ey :end-y (- text-start-y (/ text-height 2))})
+      (draw-text {:text text
+                  :doc-id (:db/id document)
+                  :start-tick 50
+                  :end-tick 130
+                  :start-x text-start-x :end-x (+ text-start-x text-width)
+                  :start-y text-start-y :end-y (- text-start-y text-height)
+                  :source "signup-animation"
+                  :props {:layer/signup-button true}})
+      (move-mouse {:start-tick 140
+                   :end-tick 145
+                   :start-x text-start-x :end-x rect-start-x
+                   :start-y text-start-y :end-y rect-start-y})
+      (draw-shape {:doc-id (:db/id document)
+                   :tool :rect
+                   :start-tick 150
+                   :end-tick 200
                    :start-x rect-start-x :end-x rect-end-x
                    :start-y rect-start-y :end-y rect-end-y
                    :source "signup-animation"
                    :props {;; look into this later, right now it interfers with signup action
                            ;; :layer/ui-target "/signup"
                            :layer/signup-button true}})
-      (move-mouse {:tool :text :start-tick 100 :end-tick 120
-                   :start-x rect-end-x :end-x text-start-x
-                   :start-y rect-end-y :end-y (- text-start-y (/ text-height 2))})
-      (draw-text {:text text :doc-id (:db/id document) :start-tick 120 :end-tick 200
-                  :start-x text-start-x :end-x (+ text-start-x text-width)
-                  :start-y text-start-y :end-y (- text-start-y text-height)
-                  :source "signup-animation"
-                  :props {;; look into this later, right now it interfers with signup action
-                          ;;:layer/ui-target "/signup"
-                          :layer/signup-button true}})
       (clear-subscriber 201))))

 (defn signup-button [{:keys [document camera]} owner]


Start of links for better navigation.

Start of links for better navigation.

--- src-cljs/kixi/hecuba/tabs/programmes.cljs
+++ src-cljs/kixi/hecuba/tabs/programmes.cljs
@@ -202,10 +202,10 @@
                    (html [:h1 {:id "programmes"} (:title data)]
                          (om/build table programmes {:opts {:histkey :programme}})

-                         [:h2 {:id "projects"} (str  "Projects " (title-for programmes))]
+                         [:h2 {:id "projects"} "Projects" [:a {:href "#programmes"} (title-for programmes)]]
                          (om/build table projects {:opts {:histkey :project}})

-                         [:h2  {:id "properties"} (str "Properties" (title-for projects)) [:small (title-for programmes)]]
+                         [:h2  {:id "properties"} "Properties" (title-for projects) [:small (title-for programmes)]]
                          (om/build table properties {:opts {:histkey :property}})

                          [:h2 {:id "devices"} "Devices" (title-for properties :title-key :addressStreetTwo) [:small (title-for programmes) (title-for projects)]]


Handle world closing correctly.

Handle world closing correctly.

--- src/cbfg/vis.cljs
+++ src/cbfg/vis.cljs
@@ -308,7 +308,8 @@
              (if after
                (let [vis-next-positions (atom {})
                      actx-ch-ch-infos (group-by #(:first-taker-actx (second %)) (:chs vis-next))]
-                 (assign-positions vis-next world vis-next-positions actx-ch-ch-infos nil)
+                 (assign-positions vis-next world vis-next-positions actx-ch-ch-infos
+                                   (when (get-in vis-next [:actxs world :closed]) 0))
                  (let [vis-next-html (apply str (flatten (vis-html-actx vis-next world
                                                                         actx-ch-ch-infos)))
                        vis-next-svg (apply str (flatten (vis-svg-actxs vis-next @vis-next-positions


don't autodeploy frontend

don't autodeploy frontend

--- src/pc/assets.clj
+++ src/pc/assets.clj
@@ -220,8 +220,9 @@
                      :metadata {:content-length (count manifest-bytes)
                                 :content-type "application/edn"})
       (validate-manifest! (fetch-specific-manifest cdn-bucket manifest-key))
-      (log/infof "moving manifest pointer to %s" manifest-key)
-      (move-manifest-pointer cdn-bucket manifest-key)
+      ;; (log/infof "moving manifest pointer to %s" manifest-key)
+      ;; (move-manifest-pointer cdn-bucket manifest-key)
+      (log/infof "not moving manifest pointer to %s, should do it manually after deploy" manifest-key)
       (log/infof "uploading sourcemap to rollbar")
       (upload-sourcemap sha1 manifest))))


Added covfefe to profanity words.

Added covfefe to profanity words.

--- data_collection/profanity-power-index/src/profanity_power_index/core.clj
+++ data_collection/profanity-power-index/src/profanity_power_index/core.clj
@@ -57,7 +57,8 @@
       (str/includes? text "asshole")
       (str/includes? text "asshat")
       (str/includes? text "jackass")
-      (str/includes? text "dumbass")))
+      (str/includes? text "dumbass")
+      (str/includes? text "covfefe")))

 (defn safe-parse-json [text]
   (try


Changed memcache service parameter names to make more sense.

--- src/appengine_magic/services/memcache.clj
+++ src/appengine_magic/services/memcache.clj
@@ -56,25 +56,25 @@

 (defn delete
-  "If (sequential? key), deletes in batch."
-  [key & {:keys [namespace millis-no-readd]}]
+  "If (sequential? key-or-keys), deletes in batch."
+  [key-or-keys & {:keys [namespace millis-no-readd]}]
   (let [service (get-memcache-service :namespace namespace)]
     (if millis-no-readd
-        (if (sequential? key)
-            (.deletAll service key millis-no-readd)
-            (.delete service key millis-no-readd))
-        (if (sequential? key)
-            (.deleteAll service key)
-            (.delete service key)))))
+        (if (sequential? key-or-keys)
+            (.deletAll service key-or-keys millis-no-readd)
+            (.delete service key-or-keys millis-no-readd))
+        (if (sequential? key-or-keys)
+            (.deleteAll service key-or-keys)
+            (.delete service key-or-keys)))))

 (defn get
-  "If (sequential? key), returns values as a map."
-  [key & {:keys [namespace]}]
+  "If (sequential? key-or-keys), returns values as a map."
+  [key-or-keys & {:keys [namespace]}]
   (let [service (get-memcache-service :namespace namespace)]
-    (if (sequential? key)
-        (into {} (.getAll service key))
-        (.get service key))))
+    (if (sequential? key-or-keys)
+        (into {} (.getAll service key-or-keys))
+        (.get service key-or-keys))))

 (defn put [key value & {:keys [namespace expiration policy]
@@ -92,16 +92,16 @@

 (defn increment
-  "If (sequential? key), increment each key by the delta."
-  [key delta & {:keys [namespace initial]}]
+  "If (sequential? key-or-keys), increment each key by the delta."
+  [key-or-keys delta & {:keys [namespace initial]}]
   (let [service (get-memcache-service :namespace namespace)]
     (if initial
-        (if (sequential? key)
-            (.incrementAll service key delta (long initial))
-            (.increment service key delta (long initial)))
-        (if (sequential? key)
-            (.incrementAll service key delta)
-            (.increment service key delta)))))
+        (if (sequential? key-or-keys)
+            (.incrementAll service key-or-keys delta (long initial))
+            (.increment service key-or-keys delta (long initial)))
+        (if (sequential? key-or-keys)
+            (.incrementAll service key-or-keys delta)
+            (.increment service key-or-keys delta)))))

 (defn increment-map [values & {:keys [namespace initial]}]


add BB support to switch-user

add BB support to switch-user

--- src-cljs/frontend/components/admin.cljs
+++ src-cljs/frontend/components/admin.cljs
@@ -10,6 +10,7 @@
             [frontend.components.pieces.table :as table]
             [frontend.components.pieces.tabs :as tabs]
             [frontend.components.shared :as shared]
+            [frontend.config :as config]
             [frontend.datetime :as datetime]
             [frontend.routes :as routes]
             [frontend.state :as state]
@@ -45,17 +46,24 @@
           [:p "Switch user"]
           [:form.form-inline {:method "post", :action "/admin/switch-user"}
            [:input.input-medium {:name "login", :type "text"}]
+           (when-not (config/enterprise?)
+             [:div.col-lg-3
+              [:label
+               [:input {:type "checkbox"
+                        :name "bitbucket"}]
+               "Bitbucket"]])
            [:input {:value (utils/csrf-token)
                     :name "CSRFToken",
                     :type "hidden"}]
-           [:button.btn.btn-primary {:value "Switch user"
-                                     :type "submit"
-                                     :on-click (fn [event]
-                                                 ;; a higher level handler will stop all form submissions
-                                                 ;;
-                                                 ;; see frontend.components.app/app*
-                                                 (.stopPropagation event))}
-            "Switch user"]]]]]))))
+           [:div.col-lg-9
+            [:button.btn.btn-primary {:value "Switch user"
+                                               :type "submit"
+                                               :on-click (fn [event]
+                                                           ;; a higher level handler will stop all form submissions
+                                                           ;;
+                                                           ;; see frontend.components.app/app*
+                                                           (.stopPropagation event))}
+             "Switch user"]]]]]]))))

 (defn current-seat-usage [active-users total-seats]
   [:span


Make branch picker selected state differentiate between BB and GH

--- src-cljs/frontend/components/aside.cljs
+++ src-cljs/frontend/components/aside.cljs
@@ -112,7 +112,8 @@
                     repo-name (project-model/repo-name project)
                     branch-identifier (:identifier branch)]
                 [:li {:key (hash [vcs-type org-name repo-name branch-identifier])
-                      :class (when (and (= org-name (:org navigation-data))
+                      :class (when (and (= vcs-type (:vcs_type navigation-data))
+                                        (= org-name (:org navigation-data))
                                         (= repo-name (:repo navigation-data))
                                         (= (name branch-identifier)
                                            (:branch navigation-data)))
@@ -156,19 +157,20 @@
     om/IDisplayName (display-name [_] "Aside Project")
     om/IRender
     (render [_]
-      (let [repo (project-model/project-name project)
-            vcs-url (:vcs_url project)
+      (let [vcs-url (:vcs_url project)
+            vcs-type (project-model/vcs-type project)
             org-name (project-model/org-name project)
             repo-name (project-model/repo-name project)]
         (html [:li
                [:.project-heading
-                {:class (when (and (= org-name (:org navigation-data))
+                {:class (when (and (= vcs-type (:vcs_type navigation-data))
+                                   (= org-name (:org navigation-data))
                                    (= repo-name (:repo navigation-data))
                                    (not (contains? navigation-data :branch)))
                           "selected")
                  :title (project-model/project-name project)}
-                [:i.fa.rotating-chevron {:class (when (expanded-repos repo) "expanded")
-                                         :on-click #(raise! owner [:expand-repo-toggled {:repo repo}])}]
+                [:i.fa.rotating-chevron {:class (when (expanded-repos vcs-url) "expanded")
+                                         :on-click #(raise! owner [:expand-repo-toggled {:repo vcs-url}])}]
                 [:a.project-name {:href (routes/v1-project-dashboard-path {:vcs_type (:vcs_type project)
                                                                            :org (:username project)
                                                                            :repo (:reponame project)})
@@ -179,7 +181,7 @@
                  (project-model/project-name project)]
                 (project-settings-link {:project project} owner)]

-               (when (expanded-repos repo)
+               (when (expanded-repos vcs-url)
                  (om/build branch-list
                            {:branches (->> project
                                            project-model/branches


Recommend if problem persists

Recommend if problem persists

--- src-cljs/frontend/components/build.cljs
+++ src-cljs/frontend/components/build.cljs
@@ -53,7 +53,7 @@
        ") We should have automatically retried this build. We've been alerted of"
        " the issue and are almost certainly looking into it, please "
        (common/contact-us-inner owner)
-       " if you're interested in the cause of the problem."])))
+       " if you're interested in the cause or if the problem persists."])))

 (defn report-error [{:keys [build show-premium-content?]} owner]
   (let [build-id (build-model/id build)


Fix react warning about dead property.

Fix react warning about dead property.

"Warning: Unsupported style property z-index. Did you mean zIndex?"

--- src-cljs/frontend/components/build.cljs
+++ src-cljs/frontend/components/build.cljs
@@ -80,8 +80,7 @@
                             {:position :fixed
                              :top 0
                              :left (:left stick)
-                             :width (:width stick)
-                             :z-index 100})]
+                             :width (:width stick)})]
         (html [:div {:ref "wrapper" :class wrapper-class :style wrapper-style}
                [:div {:ref "content" :class content-class :style content-style}
                 content]])))


code submit box to CodeMirror

code submit box to CodeMirror

Change code box to CodeMirror text area & allow eval.

--- src-cljs/kata/pages/submit_problem.cljs
+++ src-cljs/kata/pages/submit_problem.cljs
@@ -1,6 +1,6 @@
 (ns kata.pages.submit-problem
-  (:require [reagent.core :as r]
-            [ajax.core :refer [GET POST]]))
+  (:require [ajax.core :refer [GET POST]]
+            [reagent.core :as reagent]))

 (defn save-input! [form-data id]
   (fn [event]
@@ -11,9 +11,49 @@
         {:params {:problem @form-data}
          :handler #(reset! result %)}))

+(defn render-code [this]
+  (->> this reagent/dom-node (.highlightBlock js/hljs)))
+
+(defn editor-did-mount [save-fn]
+  (fn [this]
+    (let [cm (.fromTextArea  js/CodeMirror
+                             (reagent/dom-node this)
+                             #js {:mode "clojure"
+                                  :lineNumbers true})]
+      (.on cm "change" save-fn))))
+
+(defn editor [input]
+  (reagent/create-class
+    {:render (fn [] [:textarea.form-control
+                     {:placeholder "code"
+                      :value (:code @input)
+                      :on-change (save-input! input :code)
+                      :auto-complete "off"}])
+     :component-did-mount (editor-did-mount
+                            #(swap! input assoc :code (.getValue %)))}))
+
+(defn eval-view [output]
+  (reagent/create-class
+    {:render (fn []
+               [:pre>code.clj
+                @output])
+     :component-did-update render-code
+     :component-did-mount render-code
+     }))
+
+(defn evaluate-code [input result]
+  ""
+  [input result]
+  (POST "/api/evaluate"
+        {:params  {:expr  (:code @input)}
+         :handler #(reset! result %)
+         ;:error-handler #(reset! error %)
+         }))
+
 (defn submit-problem-form []
-  (let [form-data (r/atom {})
-        result (r/atom {})]
+  (let [form-data (reagent/atom {})
+        result (reagent/atom {})
+        eval-result (reagent/atom {})]
     (fn []
       [:div.row>div.col-md-12
        [:h2 "Submit a problem"]
@@ -26,10 +66,15 @@
         {:placeholder "description"
          :value (:description @form-data)
          :on-change (save-input! form-data :description)}]
-       [:textarea.form-control
-        {:placeholder "code"
-         :value (:code @form-data)
-         :on-change (save-input! form-data :code)}]
+       [:div.row>div.col-md-12
+          [editor form-data]]
+       [:div.row
+        [:div.col-md-1>label "Result"]
+        [:div.col-md-11
+        [eval-view eval-result]]]
+       [:button.btn.btn-primary
+        {:on-click #(evaluate-code form-data eval-result)}
+        "evaluate"]
        [:button.btn.btn-primary
         {:on-click #(submit-problem form-data result)}
         "submit"]