lein.sh 12 KB

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