Permalink
Browse files

Allow successive eval-in-project calls with trampoline. Fixes #665.

  • Loading branch information...
1 parent 6f04e0d commit 4beeb70d1cadafe4c5a6de509a5358fc65e7422b @technomancy committed Jul 8, 2012
Showing with 24 additions and 23 deletions.
  1. +1 −2 leiningen-core/src/leiningen/core/eval.clj
  2. +21 −18 src/leiningen/trampoline.clj
  3. +2 −3 todo.org
@@ -165,8 +165,7 @@
(throw (Exception. (str "Process exited with " exit-code)))))))
(defmethod eval-in :trampoline [project form]
- (deliver (:trampoline-promise (meta project))
- (shell-command project form)))
+ (swap! (:trampoline-forms (meta project)) conj form))
(defmethod eval-in :classloader [project form]
(let [classpath (map io/file (classpath/get-classpath project))
@@ -13,18 +13,22 @@
(defn- quote-arg [arg]
(format "\"%s\"" arg))
-(defn trampoline-command-string [command]
- (string/join " " (if (win-batch?)
- (map quote-arg command)
- (conj (vec (map quote-arg (butlast command)))
- (with-out-str
- (prn (last command)))))))
-
-(defn write-trampoline [command]
- (main/debug "Trampoline command:"
- (trampoline-command-string command))
- (spit (System/getProperty "leiningen.trampoline-file")
- (trampoline-command-string command)))
+(defn trampoline-command-string [project forms]
+ ;; each form is (do init & body)
+ (let [forms (map rest forms) ;; strip off do
+ inits (map first forms)
+ rests (mapcat rest forms)
+ command (eval/shell-command project (concat '(do) inits rests))]
+ (string/join " " (if (win-batch?)
+ (map quote-arg command)
+ (conj (vec (map quote-arg (butlast command)))
+ (with-out-str
+ (prn (last command))))))))
+
+(defn write-trampoline [project forms]
+ (let [command (trampoline-command-string project forms)]
+ (main/debug "Trampoline command:" command)
+ (spit (System/getProperty "leiningen.trampoline-file") command)))
(defn ^:higher-order trampoline
"Run a task without nesting the project's JVM inside Leiningen's.
@@ -33,17 +37,16 @@ Calculates what needs to run in the project's process for the provided
task and runs it after Leiningen's own JVM process has exited rather
than as a subprocess of Leiningen's project.
-Use this to save memory or to work around things like stdin issues.
-Not compatible with tasks like do that call eval-in-project multiple times."
+Use this to save memory or to work around stdin issues."
[project task-name & args]
;; TODO: allow trampoline calls to chain with do
- (let [command (promise)]
+ (let [forms (atom [])]
(when (:eval-in-leiningen project)
(main/info "Warning: trampoline has no effect with :eval-in-leiningen."))
(binding [*trampoline?* true]
(main/apply-task (main/lookup-alias task-name project)
(with-meta (assoc project :eval-in :trampoline)
- {:trampoline-promise command}) args))
- (if (realized? command)
- (write-trampoline @command)
+ {:trampoline-forms forms}) args))
+ (if (seq @forms)
+ (write-trampoline project @forms)
(main/abort task-name "did not run any project code for trampolining."))))
View
@@ -4,10 +4,9 @@ See also https://github.com/technomancy/leiningen/issues
* For 2.0.0
** 2.0.0-final
- - [ ] Implement add-profiles task (#661)
- - [ ] Allow trampoline to work with chaining in do task (#665)
- - [ ] Reduce Aether verbosity (#610)
+ - [X] Allow trampoline to work with chaining in do task (#665)
- [ ] Improve speed of trampoline restarts (#573)
+ - [ ] Reduce Aether verbosity (#610)
- [ ] Isolate target dir per profile (#468)
- [ ] Honor mirror for search indices (#281)
- [ ] Drop clojars snapshots from default repos (#241)

0 comments on commit 4beeb70

Please sign in to comment.