lein 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367
  1. #!/usr/bin/env bash
  2. # Ensure this file is executable via `chmod a+x lein`, then place it
  3. # somewhere on your $PATH, like ~/bin. The rest of Leiningen will be
  4. # installed upon first run into the ~/.lein/self-installs directory.
  5. export LEIN_VERSION="2.5.1"
  6. case $LEIN_VERSION in
  7. *SNAPSHOT) SNAPSHOT="YES" ;;
  8. *) SNAPSHOT="NO" ;;
  9. esac
  10. if [[ "$OSTYPE" == "cygwin" ]] || [[ "$OSTYPE" == "msys" ]]; then
  11. delimiter=";"
  12. else
  13. delimiter=":"
  14. fi
  15. if [[ "$OSTYPE" == "cygwin" ]]; then
  16. cygwin=true
  17. else
  18. cygwin=false
  19. fi
  20. function make_native_path {
  21. # ensure we have native paths
  22. if $cygwin && [[ "$1" == /* ]]; then
  23. echo -n "$(cygpath -wp "$1")"
  24. elif [[ "$OSTYPE" == "msys" && "$1" == /?/* ]]; then
  25. echo -n "$(sh -c "(cd $1 2</dev/null && pwd -W) || echo $1 | sed 's/^\\/\([a-z]\)/\\1:/g'")"
  26. else
  27. echo -n "$1"
  28. fi
  29. }
  30. # usage : add_path PATH_VAR [PATH]...
  31. function add_path {
  32. local path_var="$1"
  33. shift
  34. while [ -n "$1" ];do
  35. # http://bashify.com/?Useful_Techniques:Indirect_Variables:Indirect_Assignment
  36. if [[ -z ${!path_var} ]]; then
  37. export ${path_var}="$(make_native_path "$1")"
  38. else
  39. export ${path_var}="${!path_var}${delimiter}$(make_native_path "$1")"
  40. fi
  41. shift
  42. done
  43. }
  44. function download_failed_message {
  45. echo "Failed to download $1 (exit code $2)"
  46. echo "It's possible your HTTP client's certificate store does not have the"
  47. echo "correct certificate authority needed. This is often caused by an"
  48. echo "out-of-date version of libssl. It's also possible that you're behind a"
  49. echo "firewall and haven't set HTTP_PROXY and HTTPS_PROXY."
  50. }
  51. function self_install {
  52. if [ -r "$LEIN_JAR" ]; then
  53. echo "The self-install jar already exists at $LEIN_JAR."
  54. echo "If you wish to re-download, delete it and rerun \"$0 self-install\"."
  55. exit 1
  56. fi
  57. echo "Downloading Leiningen to $LEIN_JAR now..."
  58. mkdir -p "$(dirname "$LEIN_JAR")"
  59. LEIN_URL="https://github.com/technomancy/leiningen/releases/download/$LEIN_VERSION/leiningen-$LEIN_VERSION-standalone.zip"
  60. $HTTP_CLIENT "$LEIN_JAR.pending" "$LEIN_URL"
  61. local exit_code=$?
  62. if [ $exit_code == 0 ]; then
  63. # TODO: checksum
  64. mv -f "$LEIN_JAR.pending" "$LEIN_JAR"
  65. else
  66. rm "$LEIN_JAR.pending" 2> /dev/null
  67. download_failed_message "$LEIN_URL" "$exit_code"
  68. exit 1
  69. fi
  70. }
  71. if [ `id -u` -eq 0 ] && [ "$LEIN_ROOT" = "" ]; then
  72. echo "WARNING: You're currently running as root; probably by accident."
  73. echo "Press control-C to abort or Enter to continue as root."
  74. echo "Set LEIN_ROOT to disable this warning."
  75. read _
  76. fi
  77. NOT_FOUND=1
  78. ORIGINAL_PWD="$PWD"
  79. while [ ! -r "$PWD/project.clj" ] && [ "$PWD" != "/" ] && [ $NOT_FOUND -ne 0 ]
  80. do
  81. cd ..
  82. if [ "$(dirname "$PWD")" = "/" ]; then
  83. NOT_FOUND=0
  84. cd "$ORIGINAL_PWD"
  85. fi
  86. done
  87. export LEIN_HOME="${LEIN_HOME:-"$HOME/.lein"}"
  88. for f in "$LEIN_HOME/leinrc" ".leinrc"; do
  89. if [ -e "$f" ]; then
  90. source "$f"
  91. fi
  92. done
  93. if $cygwin; then
  94. export LEIN_HOME=`cygpath -w "$LEIN_HOME"`
  95. fi
  96. LEIN_JAR="$LEIN_HOME/self-installs/leiningen-$LEIN_VERSION-standalone.jar"
  97. # normalize $0 on certain BSDs
  98. if [ "$(dirname "$0")" = "." ]; then
  99. SCRIPT="$(which $(basename "$0"))"
  100. if [ -z "$SCRIPT" ]; then
  101. SCRIPT="$0"
  102. fi
  103. else
  104. SCRIPT="$0"
  105. fi
  106. # resolve symlinks to the script itself portably
  107. while [ -h "$SCRIPT" ] ; do
  108. ls=`ls -ld "$SCRIPT"`
  109. link=`expr "$ls" : '.*-> \(.*\)$'`
  110. if expr "$link" : '/.*' > /dev/null; then
  111. SCRIPT="$link"
  112. else
  113. SCRIPT="$(dirname "$SCRIPT"$)/$link"
  114. fi
  115. done
  116. BIN_DIR="$(dirname "$SCRIPT")"
  117. export LEIN_JVM_OPTS="${LEIN_JVM_OPTS-"-XX:+TieredCompilation -XX:TieredStopAtLevel=1"}"
  118. # This needs to be defined before we call HTTP_CLIENT below
  119. if [ "$HTTP_CLIENT" = "" ]; then
  120. if type -p curl >/dev/null 2>&1; then
  121. if [ "$https_proxy" != "" ]; then
  122. CURL_PROXY="-x $https_proxy"
  123. fi
  124. HTTP_CLIENT="curl $CURL_PROXY -f -L -o"
  125. else
  126. HTTP_CLIENT="wget -O"
  127. fi
  128. fi
  129. # When :eval-in :classloader we need more memory
  130. grep -E -q '^\s*:eval-in\s+:classloader\s*$' project.clj 2> /dev/null && \
  131. export LEIN_JVM_OPTS="$LEIN_JVM_OPTS -Xms64m -Xmx512m"
  132. if [ -r "$BIN_DIR/../src/leiningen/version.clj" ]; then
  133. # Running from source checkout
  134. LEIN_DIR="$(dirname "$BIN_DIR")"
  135. # Need to use lein release to bootstrap the leiningen-core library (for aether)
  136. if [ ! -r "$LEIN_DIR/leiningen-core/.lein-bootstrap" ]; then
  137. echo "Leiningen is missing its dependencies."
  138. echo "Please run \"lein bootstrap\" in the leiningen-core/ directory"
  139. echo "with a stable release of Leiningen. See CONTRIBUTING.md for details."
  140. exit 1
  141. fi
  142. # If project.clj for lein or leiningen-core changes, we must recalculate
  143. LAST_PROJECT_CHECKSUM=$(cat "$LEIN_DIR/.lein-project-checksum" 2> /dev/null)
  144. PROJECT_CHECKSUM=$(sum "$LEIN_DIR/project.clj" "$LEIN_DIR/leiningen-core/project.clj")
  145. if [ "$PROJECT_CHECKSUM" != "$LAST_PROJECT_CHECKSUM" ]; then
  146. if [ -r "$LEIN_DIR/.lein-classpath" ]; then
  147. rm "$LEIN_DIR/.lein-classpath"
  148. fi
  149. fi
  150. # Use bin/lein to calculate its own classpath.
  151. if [ ! -r "$LEIN_DIR/.lein-classpath" ] && [ "$1" != "classpath" ]; then
  152. echo "Recalculating Leiningen's classpath."
  153. ORIG_PWD="$PWD"
  154. cd "$LEIN_DIR"
  155. LEIN_NO_USER_PROFILES=1 $0 classpath .lein-classpath
  156. sum "$LEIN_DIR/project.clj" "$LEIN_DIR/leiningen-core/project.clj" > \
  157. .lein-project-checksum
  158. cd "$ORIG_PWD"
  159. fi
  160. mkdir -p "$LEIN_DIR/target/classes"
  161. export LEIN_JVM_OPTS="$LEIN_JVM_OPTS -Dclojure.compile.path=$LEIN_DIR/target/classes"
  162. add_path CLASSPATH "$LEIN_DIR/leiningen-core/src/" "$LEIN_DIR/leiningen-core/resources/" \
  163. "$LEIN_DIR/test:$LEIN_DIR/target/classes" "$LEIN_DIR/src" ":$LEIN_DIR/resources"
  164. if [ -r "$LEIN_DIR/.lein-classpath" ]; then
  165. add_path CLASSPATH "$(cat "$LEIN_DIR/.lein-classpath" 2> /dev/null)"
  166. else
  167. add_path CLASSPATH "$(cat "$LEIN_DIR/leiningen-core/.lein-bootstrap" 2> /dev/null)"
  168. fi
  169. else # Not running from a checkout
  170. add_path CLASSPATH "$LEIN_JAR"
  171. BOOTCLASSPATH="-Xbootclasspath/a:$LEIN_JAR"
  172. if [ ! -r "$LEIN_JAR" -a "$1" != "self-install" ]; then
  173. self_install
  174. fi
  175. fi
  176. # TODO: explain what to do when Java is missing
  177. export JAVA_CMD="${JAVA_CMD:-"java"}"
  178. export LEIN_JAVA_CMD="${LEIN_JAVA_CMD:-$JAVA_CMD}"
  179. if [[ -z "${DRIP_INIT+x}" && "$(basename "$LEIN_JAVA_CMD")" == *drip* ]]; then
  180. export DRIP_INIT="$(printf -- '-e\n(require (quote leiningen.repl))')"
  181. export DRIP_INIT_CLASS="clojure.main"
  182. fi
  183. # Support $JAVA_OPTS for backwards-compatibility.
  184. export JVM_OPTS="${JVM_OPTS:-"$JAVA_OPTS"}"
  185. # Handle jline issue with cygwin not propagating OSTYPE through java subprocesses: https://github.com/jline/jline2/issues/62
  186. cygterm=false
  187. if $cygwin; then
  188. case "$TERM" in
  189. rxvt* | xterm* | vt*) cygterm=true ;;
  190. esac
  191. fi
  192. if $cygterm; then
  193. LEIN_JVM_OPTS="$LEIN_JVM_OPTS -Djline.terminal=jline.UnixTerminal"
  194. stty -icanon min 1 -echo > /dev/null 2>&1
  195. fi
  196. # TODO: investigate http://skife.org/java/unix/2011/06/20/really_executable_jars.html
  197. # If you're packaging this for a package manager (.deb, homebrew, etc)
  198. # you need to remove the self-install and upgrade functionality or see lein-pkg.
  199. if [ "$1" = "self-install" ]; then
  200. if [ -r "$BIN_DIR/../src/leiningen/version.clj" ]; then
  201. echo "Running self-install from a checkout is not supported."
  202. echo "See CONTRIBUTING.md for SNAPSHOT-specific build instructions."
  203. exit 1
  204. fi
  205. echo "Manual self-install is deprecated; it will run automatically when necessary."
  206. self_install
  207. elif [ "$1" = "upgrade" ] || [ "$1" = "downgrade" ]; then
  208. if [ "$LEIN_DIR" != "" ]; then
  209. echo "The upgrade task is not meant to be run from a checkout."
  210. exit 1
  211. fi
  212. if [ $SNAPSHOT = "YES" ]; then
  213. echo "The upgrade task is only meant for stable releases."
  214. echo "See the \"Hacking\" section of the README."
  215. exit 1
  216. fi
  217. if [ ! -w "$SCRIPT" ]; then
  218. echo "You do not have permission to upgrade the installation in $SCRIPT"
  219. exit 1
  220. else
  221. TARGET_VERSION="${2:-stable}"
  222. echo "The script at $SCRIPT will be upgraded to the latest $TARGET_VERSION version."
  223. echo -n "Do you want to continue [Y/n]? "
  224. read RESP
  225. case "$RESP" in
  226. y|Y|"")
  227. echo
  228. echo "Upgrading..."
  229. TARGET="/tmp/lein-$$-upgrade"
  230. if $cygwin; then
  231. TARGET=`cygpath -w $TARGET`
  232. fi
  233. LEIN_SCRIPT_URL="https://github.com/technomancy/leiningen/raw/$TARGET_VERSION/bin/lein"
  234. $HTTP_CLIENT "$TARGET" "$LEIN_SCRIPT_URL"
  235. if [ $? == 0 ]; then
  236. cmp -s "$TARGET" "$SCRIPT"
  237. if [ $? == 0 ]; then
  238. echo "Leiningen is already up-to-date."
  239. fi
  240. mv "$TARGET" "$SCRIPT" && chmod +x "$SCRIPT"
  241. exec "$SCRIPT" version
  242. else
  243. download_failed_message "$LEIN_SCRIPT_URL"
  244. fi;;
  245. *)
  246. echo "Aborted."
  247. exit 1;;
  248. esac
  249. fi
  250. else
  251. if $cygwin; then
  252. # When running on Cygwin, use Windows-style paths for java
  253. ORIGINAL_PWD=`cygpath -w "$ORIGINAL_PWD"`
  254. fi
  255. # apply context specific CLASSPATH entries
  256. if [ -f .lein-classpath ]; then
  257. add_path CLASSPATH "$(cat .lein-classpath)"
  258. fi
  259. if [ $DEBUG ]; then
  260. echo "Leiningen's classpath: $CLASSPATH"
  261. fi
  262. if [ -r .lein-fast-trampoline ]; then
  263. export LEIN_FAST_TRAMPOLINE='y'
  264. fi
  265. if [ "$LEIN_FAST_TRAMPOLINE" != "" ] && [ -r project.clj ]; then
  266. INPUTS="$@ $(cat project.clj) $LEIN_VERSION $(test -f "$LEIN_HOME/profiles.clj" && cat "$LEIN_HOME/profiles.clj")"
  267. export INPUT_CHECKSUM=$(echo $INPUTS | shasum - | cut -f 1 -d " ")
  268. # Just don't change :target-path in project.clj, mkay?
  269. TRAMPOLINE_FILE="target/trampolines/$INPUT_CHECKSUM"
  270. else
  271. if hash mktemp 2>/dev/null; then
  272. # Check if mktemp is available before using it
  273. TRAMPOLINE_FILE="$(mktemp /tmp/lein-trampoline-XXXXXXXXXXXXX)"
  274. else
  275. TRAMPOLINE_FILE="/tmp/lein-trampoline-$$"
  276. fi
  277. trap "rm -f $TRAMPOLINE_FILE" EXIT
  278. fi
  279. if $cygwin; then
  280. TRAMPOLINE_FILE=`cygpath -w $TRAMPOLINE_FILE`
  281. fi
  282. if [ "$INPUT_CHECKSUM" != "" ] && [ -r "$TRAMPOLINE_FILE" ]; then
  283. if [ $DEBUG ]; then
  284. echo "Fast trampoline with $TRAMPOLINE_FILE."
  285. fi
  286. exec sh -c "exec $(cat $TRAMPOLINE_FILE)"
  287. else
  288. export TRAMPOLINE_FILE
  289. "$LEIN_JAVA_CMD" \
  290. "${BOOTCLASSPATH[@]}" \
  291. -Dfile.encoding=UTF-8 \
  292. -Dmaven.wagon.http.ssl.easy=false \
  293. -Dmaven.wagon.rto=10000 \
  294. $LEIN_JVM_OPTS \
  295. -Dleiningen.original.pwd="$ORIGINAL_PWD" \
  296. -Dleiningen.script="$SCRIPT" \
  297. -classpath "$CLASSPATH" \
  298. clojure.main -m leiningen.core.main "$@"
  299. EXIT_CODE=$?
  300. if $cygterm ; then
  301. stty icanon echo > /dev/null 2>&1
  302. fi
  303. ## TODO: [ -r "$TRAMPOLINE_FILE" ] may be redundant? A trampoline file
  304. ## is always generated these days.
  305. if [ -r "$TRAMPOLINE_FILE" ] && [ "$LEIN_TRAMPOLINE_WARMUP" = "" ]; then
  306. TRAMPOLINE="$(cat $TRAMPOLINE_FILE)"
  307. if [ "$INPUT_CHECKSUM" = "" ]; then
  308. rm $TRAMPOLINE_FILE
  309. fi
  310. if [ "$TRAMPOLINE" = "" ]; then
  311. exit $EXIT_CODE
  312. else
  313. exec sh -c "exec $TRAMPOLINE"
  314. fi
  315. else
  316. exit $EXIT_CODE
  317. fi
  318. fi
  319. fi