From 0bf26bab48ce74c29d86ad5ba27b0ab5ec3c82a4 Mon Sep 17 00:00:00 2001 From: Hugh Aristotle Powell Date: Mon, 4 Jun 2018 16:34:49 +0100 Subject: [PATCH] Extract side effects --- src/lein_tools_deps/deps.clj | 45 +++++++--------------------- src/lein_tools_deps/env.clj | 38 +++++++++++++++++++++++ src/lein_tools_deps/lein_project.clj | 1 - src/lein_tools_deps/plugin.clj | 8 +++-- test/lein_tools_deps/deps_test.clj | 5 ++-- test/lein_tools_deps/plugin_test.clj | 44 ++++++++++++++------------- 6 files changed, 80 insertions(+), 61 deletions(-) create mode 100644 src/lein_tools_deps/env.clj diff --git a/src/lein_tools_deps/deps.clj b/src/lein_tools_deps/deps.clj index 3490683..b61e4f7 100644 --- a/src/lein_tools_deps/deps.clj +++ b/src/lein_tools_deps/deps.clj @@ -1,38 +1,13 @@ (ns lein-tools-deps.deps - (:require [clojure.java.shell :as shell] - [clojure.java.io :as io] - [clojure.tools.deps.alpha.reader :as reader] + (:require [clojure.java.io :as io] [lein-tools-deps.file-attributes :as file-attributes])) -(def default-clojure-executables ["/usr/local/bin/clojure"]) - -(defn- clojure-exe - [config] - (let [clojure-paths (or (:clojure-executables config) default-clojure-executables) - exe (->> clojure-paths - (filter #(.exists (io/file %))) - first)] - (or exe (throw (ex-info "Could not find clojure executable" {:tried-paths clojure-paths}))))) - -(defn- scrape-clojure-env - [config] - (let [exe (clojure-exe config) - {:keys [out exit] :as result} (shell/sh exe "-Sdescribe")] - (if (zero? exit) - (read-string out) - (throw (ex-info "Unable to locate Clojure's edn files" result))))) - -(def clojure-env - "Returns a map describing the environment known to clj/clojure: - {:config-files [ ... ]}" - (memoize scrape-clojure-env)) - (defn make-dep-loc-lookup "Returns a function mapping from a loc(ation) keyword (either :install, :user or :project) to a file location. If the value is a string it is returned as is." - [config] - (let [[system-deps home-deps project-deps] (:config-files (clojure-env config)) + [{:keys [config-files]}] + (let [[system-deps home-deps project-deps] config-files project-deps (or project-deps "deps.edn")] (fn [i] (if (string? i) @@ -44,10 +19,10 @@ (defn canonicalise-dep-locs "Returns a seq of absolute java.io.File given a seq of dep-refs. Any relative dep-refs will be made absolute relative to project-root." - [config project-root dep-refs] - (let [location->dep-path (shell/with-sh-dir project-root (make-dep-loc-lookup config))] + [env project-root dep-refs] + (let [location->dep-path (make-dep-loc-lookup env)] (->> dep-refs - (map #(location->dep-path %)) + (map location->dep-path) (map io/file) (map (partial file-attributes/absolute-file project-root))))) @@ -101,10 +76,10 @@ (defn make-deps "Reads and merges all of the deps-ref, returning a single deps map" - [{:keys [root] {:keys [config-files] :as config} :lein-tools-deps/config :as project}] + [exists? read-deps env {:keys [root] {:keys [config-files]} :lein-tools-deps/config}] (as-> config-files $ - (canonicalise-dep-locs config (:root project) $) - (filter #(.exists %) $) - (reader/read-deps $) + (canonicalise-dep-locs env root $) + (filter exists? $) + (read-deps $) (absolute-deps $ root))) diff --git a/src/lein_tools_deps/env.clj b/src/lein_tools_deps/env.clj new file mode 100644 index 0000000..1e6b603 --- /dev/null +++ b/src/lein_tools_deps/env.clj @@ -0,0 +1,38 @@ +(ns lein-tools-deps.env + (:require [clojure.java.shell :as shell] + [clojure.java.io :as io]) + (:import (java.io File))) + +(defmulti exists? class) + +(defmethod exists? String [file-path] + (.exists (io/file file-path))) + +(defmethod exists? File [file] + (.exists file)) + +(def default-clojure-executables ["/usr/local/bin/clojure"]) + +(defn- clojure-exe + [{:keys [clojure-executables]}] + (let [clojure-paths (or clojure-executables default-clojure-executables) + exe (->> clojure-paths + (filter exists?) + first)] + (or exe (throw (ex-info "Could not find clojure executable" {:tried-paths clojure-paths}))))) + +(defn- scrape-clojure-env + [{:keys [root] config :lein-tools-deps/config}] + (shell/with-sh-dir + root + (let [exe (clojure-exe config) + {:keys [out exit] :as result} (shell/sh exe "-Sdescribe")] + (if (zero? exit) + (read-string out) + (throw (ex-info "Unable to locate Clojure's edn files" result)))))) + +(def clojure-env + "Returns a map describing the environment known to clj/clojure: + {:config-files [ ... ]}" + (memoize scrape-clojure-env)) + diff --git a/src/lein_tools_deps/lein_project.clj b/src/lein_tools_deps/lein_project.clj index 3bb66f4..fad88f4 100644 --- a/src/lein_tools_deps/lein_project.clj +++ b/src/lein_tools_deps/lein_project.clj @@ -35,7 +35,6 @@ (into (:paths merged-deps)) (map (partial file-attributes/absolute-path project-root)))) - (defn make-classpath "Resolves additional classpaths, meta merging them into the lein project map" [{{:keys [classpath-aliases aliases]} :lein-tools-deps/config :as project} deps] diff --git a/src/lein_tools_deps/plugin.clj b/src/lein_tools_deps/plugin.clj index 0e4b14b..593df2c 100644 --- a/src/lein_tools_deps/plugin.clj +++ b/src/lein_tools_deps/plugin.clj @@ -1,6 +1,8 @@ (ns lein-tools-deps.plugin (:require [leiningen.core.main :as lein] + [clojure.tools.deps.alpha.reader :as reader] [lein-tools-deps.deps :as deps] + [lein-tools-deps.env :as env] [lein-tools-deps.lein-project :as lein-project])) ;; load extensions @@ -9,8 +11,8 @@ (require 'clojure.tools.deps.alpha.extensions.local) (require 'clojure.tools.deps.alpha.extensions.maven) -(defn apply-middleware [project] - (let [deps (deps/make-deps project)] +(defn apply-middleware [exists? reader env project] + (let [deps (deps/make-deps exists? reader env project)] (-> project (lein-project/resolve-deps deps) (lein-project/make-classpath deps)))) @@ -35,7 +37,7 @@ (seq config-files) (if (every? loc-or-string? config-files) - (apply-middleware project) + (apply-middleware env/exists? reader/read-deps (env/clojure-env project) project) (do (lein/warn "Every element in :lein-tools-deps/config :config-files must either be a file-path string or one of the location keys" valid-loc-keys) (lein/exit 1))) diff --git a/test/lein_tools_deps/deps_test.clj b/test/lein_tools_deps/deps_test.clj index cd1ddc7..6eb3759 100644 --- a/test/lein_tools_deps/deps_test.clj +++ b/test/lein_tools_deps/deps_test.clj @@ -1,13 +1,14 @@ (ns lein-tools-deps.deps-test (:require [clojure.test :refer :all] [clojure.java.io :as io] - [lein-tools-deps.deps :as sut])) + [lein-tools-deps.deps :as sut] + [lein-tools-deps.env :as env])) (defn absolute-base-path [] (.getAbsolutePath (io/file ""))) (deftest canonicalise-dep-refs-test - (let [canonicalised-files (sut/canonicalise-dep-locs {} (absolute-base-path) [:install "test-cases/basic-deps.edn"])] + (let [canonicalised-files (sut/canonicalise-dep-locs (env/clojure-env {}) (absolute-base-path) [:install "test-cases/basic-deps.edn"])] (is (every? #(instance? java.io.File %) canonicalised-files)) (is (every? #(.exists %) canonicalised-files)) (is (= 2 (count canonicalised-files)) diff --git a/test/lein_tools_deps/plugin_test.clj b/test/lein_tools_deps/plugin_test.clj index 6c2f795..55e23a3 100644 --- a/test/lein_tools_deps/plugin_test.clj +++ b/test/lein_tools_deps/plugin_test.clj @@ -1,7 +1,9 @@ (ns lein-tools-deps.plugin-test (:require [clojure.test :refer :all] [clojure.java.io :as io] - [lein-tools-deps.plugin :as sut]) + [lein-tools-deps.plugin :as sut] + [clojure.tools.deps.alpha.reader :as reader] + [lein-tools-deps.env :as env]) (:import (clojure.lang ExceptionInfo))) ; The mere presence of this file means that `lein test` will trigger a compilation @@ -10,9 +12,11 @@ (defn absolute-base-path [] (.getAbsolutePath (io/file ""))) +(def apply-middleware (partial sut/apply-middleware env/exists? reader/read-deps (env/clojure-env {}))) + (deftest apply-middleware-to-source-paths - (let [project (sut/apply-middleware {:root (absolute-base-path) - :lein-tools-deps/config {:config-files ["test-cases/basic-deps.edn"]}})] + (let [project (apply-middleware {:root (absolute-base-path) + :lein-tools-deps/config {:config-files ["test-cases/basic-deps.edn"]}})] (is (map? project)) (is (= [(.getAbsolutePath (io/file (absolute-base-path) "src")) (.getAbsolutePath (io/file (absolute-base-path) "test"))] @@ -26,8 +30,8 @@ (is (= ["src" "test"] (:source-paths deps))))) (deftest apply-middleware-git-to-dependencies - (let [project (sut/apply-middleware {:root (absolute-base-path) - :lein-tools-deps/config {:config-files ["test-cases/git-deps.edn"]}})] + (let [project (apply-middleware {:root (absolute-base-path) + :lein-tools-deps/config {:config-files ["test-cases/git-deps.edn"]}})] (is (map? project)) (let [dependencies (:dependencies project)] (is (>= (count dependencies) 2)) @@ -36,37 +40,37 @@ dependencies))))) (deftest apply-middleware-extra-deps - (let [project (sut/apply-middleware {:root (absolute-base-path) - :lein-tools-deps/config {:resolve-aliases [:bench] - :config-files ["test-cases/alias-deps.edn"]}})] + (let [project (apply-middleware {:root (absolute-base-path) + :lein-tools-deps/config {:resolve-aliases [:bench] + :config-files ["test-cases/alias-deps.edn"]}})] (is (map? project)) (is (= (select-keys project [:dependencies :source-paths]) {:dependencies [['criterium/criterium "0.4.4"]] :source-paths ()})))) (deftest apply-middleware-extra-paths - (let [project (sut/apply-middleware {:root (absolute-base-path) - :lein-tools-deps/config {:classpath-aliases [:extra-paths-test] - :config-files ["test-cases/alias-deps.edn"]}})] + (let [project (apply-middleware {:root (absolute-base-path) + :lein-tools-deps/config {:classpath-aliases [:extra-paths-test] + :config-files ["test-cases/alias-deps.edn"]}})] (is (map? project)) (is (= (:source-paths project) ["test"])))) (deftest apply-middleware-classpath-overrides - (let [project (sut/apply-middleware {:root (absolute-base-path) - :lein-tools-deps/config {:classpath-aliases [:classpath-overrides-test] - :config-files ["test-cases/alias-deps.edn"]} - :dependencies [['org.clojure/clojure "1.9.0"]]})] + (let [project (apply-middleware {:root (absolute-base-path) + :lein-tools-deps/config {:classpath-aliases [:classpath-overrides-test] + :config-files ["test-cases/alias-deps.edn"]} + :dependencies [['org.clojure/clojure "1.9.0"]]})] (is (map? project)) (is (= (:source-paths project) [(str (absolute-base-path) "/path/to/my/clojure")])) (is (empty? (:dependencies project))))) (deftest apply-middleware-all-aliases - (let [project (sut/apply-middleware {:root (absolute-base-path) - :lein-tools-deps/config {:aliases [:all] - :config-files ["test-cases/alias-deps.edn"]} - :dependencies [['org.clojure/clojure "1.9.0"]]})] + (let [project (apply-middleware {:root (absolute-base-path) + :lein-tools-deps/config {:aliases [:all] + :config-files ["test-cases/alias-deps.edn"]} + :dependencies [['org.clojure/clojure "1.9.0"]]})] (is (map? project)) (is (= (:source-paths project) [(str (absolute-base-path) "/path/to/my/clojure")])) @@ -80,7 +84,7 @@ (let [project {:lein-tools-deps/config {}}] (is (= (sut/resolve-dependencies-with-deps-edn project) project))) - + (let [project {:lein-tools-deps/config {:config-files [:bad-location]}}] (is (thrown? ExceptionInfo (sut/resolve-dependencies-with-deps-edn project)))) (is (thrown? ExceptionInfo (sut/resolve-dependencies-with-deps-edn {}))))