Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Monkeypatch core.logic to make sets work #172

Merged
merged 1 commit into from
Nov 20, 2016
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
45 changes: 29 additions & 16 deletions src/kibit/driver.clj
Original file line number Diff line number Diff line change
@@ -1,10 +1,14 @@
(ns kibit.driver
"The (leiningen) facing interface for Kibit. Provides helpers for finding files in a project, and
linting a list of files."
(:require [clojure.java.io :as io]
[kibit.rules :refer [all-rules]]
[kibit.check :refer [check-file]]
[kibit.reporters :refer :all]
[clojure.tools.cli :refer [cli]])
(:import [java.io File]))
[clojure.tools.cli :refer [cli]]
[kibit
[check :refer [check-file]]
[reporters :refer :all]
[rules :refer [all-rules]]
[monkeypatch :refer :all]])
(:import java.io.File))

(def cli-specs [["-r" "--reporter"
"The reporter used when rendering suggestions"
Expand All @@ -31,18 +35,27 @@
(sort-by #(.getAbsolutePath ^File %)
(filter clojure-file? (file-seq dir))))

(defn run [source-paths rules & args]
(defn run
"Runs the kibit checker against the given paths, rules and args.

Paths is expected to be a sequence of io.File objects.

Rules is either a collection of rules or nil. If Rules is nil, all of kibit's checkers are used.

Optionally accepts a :reporter keyword argument, defaulting to \"text\"."
[source-paths rules & args]
(let [[options file-args usage-text] (apply (partial cli args) cli-specs)
source-files (mapcat #(-> % io/file find-clojure-sources-in-dir)
(if (empty? file-args) source-paths file-args))]
(mapcat (fn [file] (try (check-file file
:reporter (name-to-reporter (:reporter options)
cli-reporter)
:rules (or rules all-rules))
(catch Exception e
(binding [*out* *err*]
(println "Check failed -- skipping rest of file")
(println (.getMessage e))))))
source-files (mapcat #(-> % io/file find-clojure-sources-in-dir)
(if (empty? file-args) source-paths file-args))]
(mapcat (fn [file]
(with-monkeypatches kibit-redefs
(check-file file
:reporter (name-to-reporter (:reporter options) cli-reporter)
:rules (or rules all-rules))
(catch Exception e
(binding [*out* *err*]
(println "Check failed -- skipping rest of file")
(println (.getMessage e))))))
source-files)))

(defn external-run
Expand Down
40 changes: 40 additions & 0 deletions src/kibit/monkeypatch.clj
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
(ns kibit.monkeypatch
"Various helpers providing a with-monkeypatches form which wraps"
(:require [clojure.core.logic :as c.c.l])
(:import [clojure.lang
Var
IPersistentSet]
[clojure.core.logic.protocols
ITreeTerm]))

(defn ^:pivate tree-term? [x]
(and (or (coll? x)
(instance? ITreeTerm x))
(not (instance? IPersistentSet x))))

(def kibit-redefs
{#'c.c.l/tree-term? tree-term?})

(defmacro with-monkeypatches
"Builds a try/finally which captures Var bindings (and ^:macro tags) comming in, creates new Var
bindings within the try and in the finally restores the original bindings. This allows users to
establish stack-local patched contexts."
{:style/indent [1]}
[redefs & forms]
(let [redefs (eval redefs)
original-bindings (into {}
(for [k (keys redefs)]
[k (gensym)]))]
`(let [~@(for [[k v] original-bindings
f [v `(deref ~k)]]
f)]
(try ~@(for [[k v] redefs]
`(do (.bindRoot ~k ~v)
~(if (.isMacro ^Var k)
`(.setMacro ~k))))
~@forms
(finally
~@(for [[k v] redefs]
`(do (.bindRoot ~k ~(get original-bindings k))
~(if (.isMacro ^Var k)
`(.setMacro ~k)))))))))
4 changes: 4 additions & 0 deletions test/kibit/test/driver.clj
Original file line number Diff line number Diff line change
Expand Up @@ -13,5 +13,9 @@
(deftest find-clojure-sources-are
(is (= [(io/file "test/resources/first.clj")
(io/file "test/resources/second.cljx")
(io/file "test/resources/sets.clj")
(io/file "test/resources/third.cljs")]
(driver/find-clojure-sources-in-dir (io/file "test/resources")))))

(deftest test-set-file
(is (driver/run ["test/resources/sets.clj"] nil)))
4 changes: 4 additions & 0 deletions test/resources/sets.clj
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
(ns resources.sets)

(defn killit [coll]
(not-any? #{"string1" "string2"} (map ffirst coll)))