Skip to content

Instantly share code, notes, and snippets.

Embed
What would you like to do?
grasp_if_when_seq.clj
#!/usr/bin/env bash
#_" -*- mode: clojure; -*-"
#_(
"exec" "clojure" "-Sdeps" "{:deps {borkdude/grasp {:git/url \"https://github.com/borkdude/grasp\" :sha \"464f86af5866a134374af9ef7ed152882846b531\"}}}" "-M" "$0" "$@"
)
(require '[clojure.java.io :as io]
'[clojure.spec.alpha :as s]
'[clojure.string :as str]
'[grasp.api :as g])
(def files (filter #(or (str/ends-with? % ".jar")
(str/ends-with? % ".clj")
(str/ends-with? % ".cljc")
(str/ends-with? % ".cljs"))
(file-seq (io/file "."))))
(def results (atom []))
(def error-log (io/file (System/getProperty "java.io.tmpdir") "grasp_errors.txt"))
(def errors? (atom false))
(defn write-errors [s]
(when-not (str/blank? s)
(reset! errors? true)
(locking error-log
(spit error-log s :append true))))
(def progress-indicator (cycle ["-" "\\" "|" "/"]))
(def spec (g/seq #{'when-let 'if-let}
(s/and vector? (fn [v]
(let [snd (second v)]
(and (seq? snd)
(= 'seq (first snd))))))
(s/+ any?)))
(defn grasp-task [^java.util.concurrent.LinkedBlockingDeque deque]
(loop []
(when-let [[file progress] (.pollFirst deque)]
(try
(binding [*out* *err*]
(print (str "\r" progress)) (flush))
(let [errors (java.io.StringWriter.)]
(binding [*err* errors]
(let [found (g/grasp file spec)]
(swap! results conj (doall found))))
(write-errors (str errors)))
(catch Exception e (binding [*out* *err*]
(prn e))))
(recur))))
(defn parallel-grasp [files]
(let [files-and-progress (map (fn [file progress]
[file progress])
files progress-indicator)
deque (java.util.concurrent.LinkedBlockingDeque. ^java.util.List files-and-progress)
cnt (+ 2 (int (* 0.6 (.. Runtime getRuntime availableProcessors))))
latch (java.util.concurrent.CountDownLatch. cnt)
es (java.util.concurrent.Executors/newFixedThreadPool cnt)]
(dotimes [_ cnt]
(.execute es
(bound-fn []
(grasp-task deque)
(.countDown latch))))
(.await latch)
(.shutdown es)))
(parallel-grasp files)
(print "\r") (flush)
(when @errors?
(binding [*out* *err*]
(println "Logged errors to" (.getPath error-log))))
(defn report! [results]
(prn (count results)))
(report! (mapcat identity @results))
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment