Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Browse files

Extract out the lein command finding fns.

This makes them available for plugins to use for testing.
  • Loading branch information...
commit fb0b8e595b817ca237dda4d12d8fe23d6a8caebd 1 parent 6e788e8
@tobias tobias authored
View
14 README.md
@@ -22,6 +22,20 @@ leinjacker is a library of utilities for Leiningen plug-in developers. Current
since it was renamed between generations.
* `abort` - 1.x- and 2.x-compatible way to signal task failure.
+4. `leinjacker.lein-runner` has functions for finding and running the `lein` command on the
+ path for each Leiningen generation. Useful for testing plugins under various Leiningen
+ versions. It provides:
+
+ * `find-lein-cmd` - looks for `lein` on the $PATH by trying to call it. It takes a
+ `generation` argument, which should be `1` or `2`. It will then look for a command
+ called `lein` or `lein<generation>` that reports the correct generation when called
+ with `lein version`. It will memoize the found cmd to `./.lein-commands` to speed
+ up subsequent calls. This can be disabled via the `memoize?` arg.
+ * `run-lein` - Will execute the given Leiningen `generation` in `dir` with the given
+ `args`, returning the result map from the 'clojure.java.shell/sh' call.
+
+ See leinjacker's tests for examples of usage.
+
## Usage
Just drop the following into your plug-in’s `project.clj`:
View
60 src/leinjacker/lein_runner.clj
@@ -0,0 +1,60 @@
+(ns leinjacker.lein-runner
+ "Functions to locate and run the 'lein' command for either lein generation."
+ (:require [clojure.java.io :as io]
+ [clojure.java.shell :as shell]))
+
+(defn- clean-lein-env
+ "Gets a copy of the system environment tha removes Leiningen environment variables."
+ []
+ (dissoc (into {} (System/getenv))
+ "CLASSPATH" "LEIN_JVM_OPTS"))
+
+(defn- memoize-to-file
+ "Memoizes the result if not-found-fn under key in filename."
+ [filename key not-found-fn]
+ (let [cache-file (io/file filename)
+ cache (if (.exists cache-file) (read-string (slurp cache-file)) {})]
+ (or (cache key)
+ (let [cmd (not-found-fn key)]
+ (spit cache-file (prn-str (assoc cache key cmd)))
+ cmd))))
+
+(defn- find-lein-cmd*
+ "Does the work of looking up the lein command without any memoization options."
+ [generation]
+ (if-let [cmd (some
+ (fn [cmd]
+ (try
+ (if (.contains (:out (shell/sh cmd "version" :env (clean-lein-env)))
+ (str "Leiningen " generation "."))
+ cmd)
+ (catch java.io.IOException _)))
+ ["lein" (str "lein" generation)])]
+ cmd
+ (throw (IllegalStateException.
+ (str "Unable to find Leiningen " generation
+ " in the path as lein or lein" generation
+ ". Please make sure it is installed and in your path under one of those names.")))))
+
+(defn find-lein-cmd
+ "Attempts to locate the lein command for the given command on the path.
+Looks for: lein, lein<generation>. If memoize? isn't provided or is true,
+the results are cached in ./.lein-commands."
+ ([generation]
+ (find-lein-cmd generation true))
+ ([generation memoize?]
+ (if memoize?
+ (memoize-to-file ".lein-commands" generation find-lein-cmd*)
+ (find-lein-cmd* generation))))
+
+(defn run-lein
+ "Runs lein for the given generation with args.
+:dir and :env options may be specified with kwargs. Returns the result from sh."
+ [generation & args]
+ (let [[real-args {:as opts}] (split-with string? args)]
+ (apply shell/sh (find-lein-cmd generation)
+ (conj (vec real-args)
+ :dir (:dir opts)
+ :env (assoc (merge (clean-lein-env) (:env opts))
+ "LEIN_GENERATION" generation)))))
+
View
67 test/leinjacker/multiple_leins_runner.clj
@@ -1,67 +0,0 @@
-(ns leinjacker.multiple-leins-runner
- "Runs the tests in the test-projects projects under lein1 and lein2."
- {:author "Toby Crawley"}
- (:use midje.sweet)
- (:require [clojure.java.io :as io]
- [clojure.java.shell :as shell]
- [leinjacker.utils :as utils]
- [leiningen.install :as install]))
-
-(defn- clean-lein-env
- "Gets a copy of the system environment tha removes Leiningen environment variables."
- []
- (dissoc (into {} (System/getenv))
- "CLASSPATH" "LEIN_JVM_OPTS"))
-
-(defn- memoize-to-file
- "Memoizes the result if not-found-fn under key in filename."
- [filename key not-found-fn]
- (let [cache-file (io/file filename)
- cache (if (.exists cache-file) (read-string (slurp cache-file)) {})]
- (or
- (cache key)
- (let [cmd (not-found-fn)]
- (spit cache-file (prn-str (assoc cache key cmd)))
- cmd))))
-
-(defn- find-lein-cmd
- "Attempts to locate the lein command for the given command on the path. Looks for: lein, lein<generation>. The results are cached in .lein-commands"
- [generation]
- (memoize-to-file ".lein-commands"
- generation
- #(if-let [cmd (some
- (fn [cmd]
- (try
- (if (.contains (:out (shell/sh cmd "version" :env (clean-lein-env)))
- (str "Leiningen " generation "."))
- cmd)
- (catch java.io.IOException _)))
- ["lein" (str "lein" generation)])]
- cmd
- (throw (IllegalStateException. (str "Unable to find Leiningen " generation " in the path as lein or lein" generation ". Please make sure it is installed and in your path under one of those names."))))))
-
-(defn- run-lein-on-sub-project
- "Runs the midje command for the given generation of lein in test-project/"
- [generation]
- (let [cmd (find-lein-cmd generation)]
- (println "\n==> Running" (str \' cmd " midje'") "in test-project/")
- (let [result (shell/sh cmd "midje"
- :dir "test-project"
- :env (assoc (clean-lein-env)
- "LEIN_GENERATION" generation))]
- (print (:out result))
- (print (:err result))
- (println "==> Done\n")
- (:exit result))))
-
-;; install leinjacker for the test project to use
-(install/install (utils/read-lein-project))
-
-(fact "run lein1 tests."
- ;; lein1 needs deps resolved to see the installed leinjacker
- (shell/sh (find-lein-cmd "1") "deps" :dir "test-project" :env (clean-lein-env))
- (run-lein-on-sub-project "1") => 0)
-
-(fact "run lein2 tests."
- (run-lein-on-sub-project "2") => 0)
-
View
29 test/leinjacker/test_multiple_lein_versions.clj
@@ -0,0 +1,29 @@
+(ns leinjacker.test-multiple-lein-versions
+ "Runs the tests in the test-projects projects under lein1 and lein2."
+ {:author "Toby Crawley"}
+ (:use midje.sweet)
+ (:require [leinjacker.utils :as utils]
+ [leinjacker.lein-runner :as runner]
+ [leiningen.install :as install]))
+
+(defn- run-lein-on-sub-project
+ "Runs the midje command for the given generation of lein in test-project/"
+ [generation]
+ (println "\n==> Running 'lein midje' (generation" (str generation \)) "in test-project/")
+ (let [result (runner/run-lein generation "midje" :dir "test-project")]
+ (print (:out result))
+ (print (:err result))
+ (println "==> Done\n")
+ (:exit result)))
+
+;; install leinjacker for the test project to use
+(install/install (utils/read-lein-project))
+
+(fact "run lein1 tests."
+ ;; lein1 needs deps resolved to see the installed leinjacker
+ (runner/run-lein "1" "deps" :dir "test-project")
+ (run-lein-on-sub-project "1") => 0)
+
+(fact "run lein2 tests."
+ (run-lein-on-sub-project "2") => 0)
+
Please sign in to comment.
Something went wrong with that request. Please try again.