First cut at a trampoline task.

This commit is contained in:
Phil Hagelberg 2011-06-19 19:28:16 -07:00
parent 1dded4a643
commit dead008fcf
3 changed files with 65 additions and 12 deletions

View file

@ -119,10 +119,10 @@ if type -p curl >/dev/null 2>&1; then
HTTP_CLIENT="curl $CURL_PROXY --insecure -f -L -o"
fi
JAVA_CMD=${JAVA_CMD:-"java"}
export JAVA_CMD=${JAVA_CMD:-"java"}
# Support $JAVA_OPTS for backwards-compatibility.
JVM_OPTS=${JVM_OPTS:-$JAVA_OPTS}
export JVM_OPTS=${JVM_OPTS:-$JAVA_OPTS}
# If you're packaging this for a package manager (.deb, homebrew, etc)
# you need to remove the self-install and upgrade functionality.
@ -215,9 +215,23 @@ else
# doesn't exist everything will still work, it will just have a
# slower JVM boot.
test $CYGWIN_JLINE && stty -icanon min 1 -echo
exec $RLWRAP $JAVA_CMD -Xbootclasspath/a:"$CLOJURE_JAR" -client $JVM_OPTS \
-Dleiningen.original.pwd="$ORIGINAL_PWD" \
-cp "$CLASSPATH" $JLINE clojure.main -e "(use 'leiningen.core)(-main)" \
$NULL_DEVICE "$@"
test $CYGWIN_JLINE && stty icanon echo
if [ "$1" = "trampoline" ]; then
TRAMPOLINE_COMMAND_FILE="/tmp/lein-trampoline-$$"
CMD=`$JAVA_CMD -Xbootclasspath/a:"$CLOJURE_JAR" -client $JVM_OPTS \
-Dleiningen.original.pwd="$ORIGINAL_PWD" \
-Dleiningen.trampoline-file=$TRAMPOLINE_COMMAND_FILE \
-cp "$CLASSPATH" $JLINE clojure.main -e "(use 'leiningen.core)(-main)" \
$NULL_DEVICE "$@"`
if [ -r $TRAMPOLINE_COMMAND_FILE ]; then
TRAMPOLINE_COMMAND=`cat $TRAMPOLINE_COMMAND_FILE`
rm $TRAMPOLINE_COMMAND_FILE
exec $TRAMPOLINE_COMMAND
fi
else
exec $RLWRAP $JAVA_CMD -Xbootclasspath/a:"$CLOJURE_JAR" -client $JVM_OPTS \
-Dleiningen.original.pwd="$ORIGINAL_PWD" \
-cp "$CLASSPATH" $JLINE clojure.main -e "(use 'leiningen.core)(-main)" \
$NULL_DEVICE "$@"
test $CYGWIN_JLINE && stty icanon echo
fi
fi

View file

@ -84,9 +84,10 @@
(defn- get-raw-input-args []
(.getInputArguments (ManagementFactory/getRuntimeMXBean)))
(defn- get-input-args
(defn ^{:internal true} get-input-args
"Returns a vector of input arguments, accounting for a bug in RuntimeMXBean
that splits arguments which contain spaces."
that splits arguments which contain spaces. Removes -Xbootclasspath as it
requires special handling on the called code."
[]
;; RuntimeMXBean.getInputArguments() is buggy when an input argument
;; contains spaces. For an input argument of -Dprop="hello world" it
@ -95,7 +96,8 @@
(conj v arg)
(conj (vec (butlast v))
(format "%s %s" (last v) arg))))]
(reduce join-broken-args [] (get-raw-input-args))))
(remove #(re-find #"^-Xbootclasspath.+" %)
(reduce join-broken-args [] (get-raw-input-args)))))
(defn- get-jvm-args [project]
(concat (get-input-args) (:jvm-opts project) (:jvm-opts (user-settings))))
@ -175,8 +177,7 @@
(.setFork java true)
(.setDir java (file (:root project)))
(doseq [arg (get-jvm-args project)]
(when-not (re-matches #"^-Xbootclasspath.+" arg)
(.setValue (.createJvmarg java) arg)))
(.setValue (.createJvmarg java) arg))
(.setClassname java "clojure.main")
;; to allow plugins and other tasks to customize
(when handler

View file

@ -0,0 +1,38 @@
(ns leiningen.trampoline
(:refer-clojure :exclude [trampoline])
(:use [leiningen.core :only [apply-task task-not-found abort]]
[leiningen.compile :only [get-input-args eval-in-project
get-readable-form]]
[leiningen.classpath :only [get-classpath-string]])
(:require [clojure.string :as string]))
(defn escape [form-string]
(format "\"%s\"" (.replaceAll form-string "\"" "\\\\\"")))
(defn command-string [project java-cmd jvm-opts [_ form _ _ init]]
(string/join " " [java-cmd "-cp" (get-classpath-string project)
"clojure.main" "-e"
(escape (get-readable-form nil project form init))]))
(defn write-trampoline [command]
(spit (System/getProperty "leiningen.trampoline-file") command))
(defn trampoline
"Calculate what needs to run in the project's process for the
provided task and run it after Leiningen's own process has exited
rather than as a subprocess of Leiningen's project.
Use this to save memory or to work around things like Ant's stdin
issues. Not compatible with chaining."
[project task-name & args]
(let [java-cmd (format "%s/bin/java" (System/getProperty "java.home"))
jvm-opts (get-input-args)
jvm-opts (if (:debug project)
(conj jvm-opts "-Dclojure.debug=true")
jvm-opts)
eval-args (atom nil)]
(binding [eval-in-project #(do (reset! eval-args %&) 0)]
(apply-task task-name project args task-not-found))
(if @eval-args
(write-trampoline (command-string project java-cmd jvm-opts @eval-args))
(abort task-name "is not trampolineable."))))