Last active
April 13, 2021 00:58
-
-
Save leonelag/c6b6aeea3502f25dd6603d33a287f129 to your computer and use it in GitHub Desktop.
Clojure launcher for cygwin
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/usr/bin/env bash | |
# | |
# From: https://raw.githubusercontent.com/clojure/brew-install/1.9.0/src/main/resources/clojure | |
# | |
# Version = 1.10.3.814 | |
project_version=1.10.3.814 | |
# Check for cygwin | |
cygwin=false | |
case "`uname`" in | |
CYGWIN*) cygwin=true;; | |
esac | |
set -e | |
function join { local d=$1; shift; echo -n "$1"; shift; printf "%s" "${@/#/$d}"; } | |
# Extract opts | |
print_classpath=false | |
describe=false | |
verbose=false | |
trace=false | |
force=false | |
repro=false | |
tree=false | |
pom=false | |
help=false | |
prep=false | |
jvm_opts=() | |
resolve_aliases=() | |
classpath_aliases=() | |
repl_aliases=() | |
mode="repl" | |
while [ $# -gt 0 ] | |
do | |
case "$1" in | |
-version) | |
>&2 echo "Clojure CLI version 1.10.3.814" | |
exit 0 | |
;; | |
--version) | |
echo "Clojure CLI version 1.10.3.814" | |
exit 0 | |
;; | |
-J*) | |
jvm_opts+=("${1:2}") | |
shift | |
;; | |
-R*) | |
resolve_aliases+=("${1:2}") | |
shift | |
>&2 echo "-R is deprecated, use -A with repl, -M for main, or -X for exec" | |
;; | |
-C*) | |
classpath_aliases+=("${1:2}") | |
shift | |
>&2 echo "-C is deprecated, use -A with repl, -M for main, or -X for exec" | |
;; | |
-O*) | |
>&2 echo "-O is no longer supported, use -A with repl, -M for main, or -X for exec" | |
exit 1 | |
;; | |
-T*) | |
>&2 echo "-T is no longer supported, use -A with repl, -M for main, or -X for exec" | |
exit 1 | |
;; | |
-A) | |
>&2 echo "-A requires an alias" | |
exit 1 | |
;; | |
-A*) | |
repl_aliases+=("${1:2}") | |
shift | |
;; | |
-M) | |
mode="main" | |
shift | |
break | |
;; | |
-M*) | |
mode="main" | |
main_aliases="${1:2}" | |
shift | |
break | |
;; | |
-X) | |
mode="exec" | |
shift | |
break | |
;; | |
-X*) | |
mode="exec" | |
exec_aliases="${1:2}" | |
shift | |
break | |
;; | |
-P) | |
prep=true | |
shift | |
;; | |
-Sdeps) | |
shift | |
deps_data="${1}" | |
shift | |
;; | |
-Scp) | |
shift | |
force_cp="${1}" | |
shift | |
;; | |
-Spath) | |
print_classpath=true | |
shift | |
;; | |
-Sverbose) | |
verbose=true | |
shift | |
;; | |
-Sthreads) | |
shift | |
threads="${1}" | |
shift | |
;; | |
-Strace) | |
trace=true | |
shift | |
;; | |
-Sdescribe) | |
describe=true | |
shift | |
;; | |
-Sforce) | |
force=true | |
shift | |
;; | |
-Srepro) | |
repro=true | |
shift | |
;; | |
-Stree) | |
tree=true | |
shift | |
;; | |
-Spom) | |
pom=true | |
shift | |
;; | |
-Sresolve-tags) | |
>&2 echo "Option changed, use: clj -X:deps git-resolve-tags" | |
exit 1 | |
;; | |
-S*) | |
>&2 echo "Invalid option: $1" | |
exit 1 | |
;; | |
-h|--help|"-?") | |
if [[ -n "$main_aliases" ]] || [[ -n "$repl_aliases" ]]; then | |
break | |
else | |
help=true | |
shift | |
fi | |
;; | |
--) | |
shift | |
break | |
;; | |
*) | |
break | |
;; | |
esac | |
done | |
# Find java executable | |
if [[ -n "$JAVA_HOME" ]] && [[ -x "$JAVA_HOME/bin/java" ]]; then | |
JAVA_CMD=$(cygpath --mixed --absolute "$JAVA_HOME/bin/java.exe") | |
else | |
>&2 echo "Couldn't find 'java'. Please set JAVA_HOME." | |
exit 1 | |
fi | |
if "$help"; then | |
cat <<-END | |
Version: 1.10.3.814 | |
You use the Clojure tools ('clj' or 'clojure') to run Clojure programs | |
on the JVM, e.g. to start a REPL or invoke a specific function with data. | |
The Clojure tools will configure the JVM process by defining a classpath | |
(of desired libraries), an execution environment (JVM options) and | |
specifying a main class and args. | |
Using a deps.edn file (or files), you tell Clojure where your source code | |
resides and what libraries you need. Clojure will then calculate the full | |
set of required libraries and a classpath, caching expensive parts of this | |
process for better performance. | |
The internal steps of the Clojure tools, as well as the Clojure functions | |
you intend to run, are parameterized by data structures, often maps. Shell | |
command lines are not optimized for passing nested data, so instead you | |
will put the data structures in your deps.edn file and refer to them on the | |
command line via 'aliases' - keywords that name data structures. | |
'clj' and 'clojure' differ in that 'clj' has extra support for use as a REPL | |
in a terminal, and should be preferred unless you don't want that support, | |
then use 'clojure'. | |
Usage: | |
Start a REPL clj [clj-opt*] [-Aaliases] [init-opt*] | |
Exec function clojure [clj-opt*] -X[aliases] [a/fn] [kpath v]* | |
Run main clojure [clj-opt*] -M[aliases] [init-opt*] [main-opt] [arg*] | |
Prepare clojure [clj-opt*] -P [other exec opts] | |
exec-opts: | |
-Aaliases Use concatenated aliases to modify classpath | |
-X[aliases] Use concatenated aliases to modify classpath or supply exec fn/args | |
-M[aliases] Use concatenated aliases to modify classpath or supply main opts | |
-P Prepare deps - download libs, cache classpath, but don't exec | |
clj-opts: | |
-Jopt Pass opt through in java_opts, ex: -J-Xmx512m | |
-Sdeps EDN Deps data to use as the last deps file to be merged | |
-Spath Compute classpath and echo to stdout only | |
-Spom Generate (or update) pom.xml with deps and paths | |
-Stree Print dependency tree | |
-Scp CP Do NOT compute or cache classpath, use this one instead | |
-Srepro Ignore the ~/.clojure/deps.edn config file | |
-Sforce Force recomputation of the classpath (don't use the cache) | |
-Sverbose Print important path info to console | |
-Sdescribe Print environment and command parsing info as data | |
-Sthreads Set specific number of download threads | |
-Strace Write a trace.edn file that traces deps expansion | |
-- Stop parsing dep options and pass remaining arguments to clojure.main | |
--version Print the version to stdout and exit | |
-version Print the version to stderr and exit | |
init-opt: | |
-i, --init path Load a file or resource | |
-e, --eval string Eval exprs in string; print non-nil values | |
--report target Report uncaught exception to "file" (default), "stderr", or "none" | |
main-opt: | |
-m, --main ns-name Call the -main function from namespace w/args | |
-r, --repl Run a repl | |
path Run a script from a file or resource | |
- Run a script from standard input | |
-h, -?, --help Print this help message and exit | |
Programs provided by :deps alias: | |
-X:deps mvn-install Install a maven jar to the local repository cache | |
-X:deps git-resolve-tags Resolve git coord tags to shas and update deps.edn | |
For more info, see: | |
https://clojure.org/guides/deps_and_cli | |
https://clojure.org/reference/repl_and_main | |
END | |
exit 0 | |
fi | |
# Set dir containing the installed files | |
install_dir=/usr/local/lib/clojure | |
tools_cp=$(cygpath --windows --absolute "$install_dir/libexec/clojure-tools-1.10.3.814.jar") | |
# Determine user config directory | |
if [[ -n "$CLJ_CONFIG" ]]; then | |
config_dir="$CLJ_CONFIG" | |
elif [[ -n "$XDG_CONFIG_HOME" ]]; then | |
config_dir="$XDG_CONFIG_HOME/clojure" | |
else | |
config_dir="$HOME/.clojure" | |
fi | |
# If user config directory does not exist, create it | |
if [[ ! -d "$config_dir" ]]; then | |
mkdir -p "$config_dir" | |
fi | |
if [[ ! -e "$config_dir/deps.edn" ]]; then | |
cp "$install_dir/example-deps.edn" "$config_dir/deps.edn" | |
fi | |
# Determine user cache directory | |
if [[ -n "$CLJ_CACHE" ]]; then | |
user_cache_dir="$CLJ_CACHE" | |
elif [[ -n "$XDG_CACHE_HOME" ]]; then | |
user_cache_dir="$XDG_CACHE_HOME/clojure" | |
else | |
user_cache_dir="$config_dir/.cpcache" | |
fi | |
# Chain deps.edn in config paths. repro=skip config dir | |
config_project="deps.edn" | |
if "$repro"; then | |
config_paths=("$install_dir/deps.edn" "deps.edn") | |
else | |
config_user=$(cygpath --windows --absolute "$config_dir/deps.edn") | |
config_paths=("$install_dir/deps.edn" "$config_dir/deps.edn" "deps.edn") | |
fi | |
config_str=$(printf ",%s" "${config_paths[@]}") | |
config_str=${config_str:1} | |
# Determine whether to use user or project cache | |
if [[ -f deps.edn ]]; then | |
cache_dir=.cpcache | |
else | |
cache_dir="$user_cache_dir" | |
fi | |
# Construct location of cached classpath file | |
val="$(join '' ${resolve_aliases[@]})|$(join '' ${classpath_aliases[@]})|$(join '' ${repl_aliases[@]})|$exec_aliases|$main_aliases|$deps_data" | |
for config_path in "${config_paths[@]}"; do | |
if [[ -f "$config_path" ]]; then | |
val="$val|$config_path" | |
else | |
val="$val|NIL" | |
fi | |
done | |
ck=$(echo "$val" | cksum | cut -d" " -f 1) | |
libs_file=$(cygpath --windows --absolute "$cache_dir/$ck.libs") | |
cp_file=$(cygpath --windows --absolute "$cache_dir/$ck.cp") | |
jvm_file=$(cygpath --windows --absolute "$cache_dir/$ck.jvm") | |
main_file=$(cygpath --windows --absolute "$cache_dir/$ck.main") | |
basis_file=$(cygpath --windows --absolute "$cache_dir/$ck.basis") | |
# Print paths in verbose mode | |
if "$verbose"; then | |
echo "version = 1.10.3.814" | |
echo "install_dir = $install_dir" | |
echo "config_dir = $config_dir" | |
echo "config_paths =" "${config_paths[@]}" | |
echo "cache_dir = $cache_dir" | |
echo "cp_file = $cp_file" | |
echo | |
fi | |
# Check for stale classpath file | |
stale=false | |
if "$force" || "$trace" || "$tree" || "$prep" || [ ! -f "$cp_file" ]; then | |
stale=true | |
else | |
for config_path in "${config_paths[@]}"; do | |
if [ "$config_path" -nt "$cp_file" ]; then | |
stale=true | |
break | |
fi | |
done | |
fi | |
# Make tools args if needed | |
if "$stale" || "$pom"; then | |
tools_args=() | |
if [[ -n "$deps_data" ]]; then | |
tools_args+=("--config-data" "$deps_data") | |
fi | |
if [[ ${#resolve_aliases[@]} -gt 0 ]]; then | |
tools_args+=("-R$(join '' ${resolve_aliases[@]})") | |
fi | |
if [[ ${#classpath_aliases[@]} -gt 0 ]]; then | |
tools_args+=("-C$(join '' ${classpath_aliases[@]})") | |
fi | |
if [[ -n "$main_aliases" ]]; then | |
tools_args+=("-M$main_aliases") | |
fi | |
if [[ ${#repl_aliases[@]} -gt 0 ]]; then | |
tools_args+=("-A$(join '' ${repl_aliases[@]})") | |
fi | |
if [[ -n "$exec_aliases" ]]; then | |
tools_args+=("-X$exec_aliases") | |
fi | |
if [[ -n "$force_cp" ]]; then | |
tools_args+=("--skip-cp") | |
fi | |
if [[ -n "$threads" ]]; then | |
tools_args+=("--threads" "$threads") | |
fi | |
if "$trace"; then | |
tools_args+=("--trace") | |
fi | |
if "$tree"; then | |
tools_args+=("--tree") | |
fi | |
fi | |
# If stale, run make-classpath to refresh cached classpath | |
if [[ "$stale" = true && "$describe" = false ]]; then | |
if "$verbose"; then | |
>&2 echo "Refreshing classpath" | |
fi | |
"$JAVA_CMD" -classpath "$tools_cp" clojure.main -m clojure.tools.deps.alpha.script.make-classpath2 --config-user "$config_user" --config-project "$config_project" --basis-file "$basis_file" --libs-file "$libs_file" --cp-file "$cp_file" --jvm-file "$jvm_file" --main-file "$main_file" "${tools_args[@]}" | |
fi | |
if "$describe"; then | |
cp= | |
elif [[ -n "$force_cp" ]]; then | |
cp="$force_cp" | |
else | |
cp=$(cat "$cp_file") | |
fi | |
if "$prep"; then | |
exit 0 | |
elif "$pom"; then | |
exec "$JAVA_CMD" -classpath "$tools_cp" clojure.main -m clojure.tools.deps.alpha.script.generate-manifest2 --config-user "$config_user" --config-project "$config_project" --gen=pom "${tools_args[@]}" | |
elif "$print_classpath"; then | |
echo "$cp" | |
elif "$describe"; then | |
for config_path in "${config_paths[@]}"; do | |
if [[ -f "$config_path" ]]; then | |
path_vector="$path_vector\"$config_path\" " | |
fi | |
done | |
cat <<-END | |
{:version "1.10.3.814" | |
:config-files [$path_vector] | |
:config-user "$config_user" | |
:config-project "$config_project" | |
:install-dir "$install_dir" | |
:config-dir "$config_dir" | |
:cache-dir "$cache_dir" | |
:force $force | |
:repro $repro | |
:main-aliases "$main_aliases" | |
:repl-aliases "$repl_aliases"} | |
END | |
elif "$tree"; then | |
exit 0 | |
elif "$trace"; then | |
>&2 echo "Wrote trace.edn" | |
else | |
set -f | |
if [[ -e "$jvm_file" ]]; then | |
set +e | |
IFS=$'\n' read -ra jvm_cache_opts -d '' <"$jvm_file" | |
set -e | |
fi | |
if [ "$mode" == "exec" ]; then | |
exec_args=() | |
if [[ -n "$exec_aliases" ]]; then | |
exec_args+=("--aliases" "$exec_aliases") | |
fi | |
exec "$JAVA_CMD" "${jvm_cache_opts[@]}" "${jvm_opts[@]}" "-Dclojure.basis=$basis_file" -classpath "$cp:$install_dir/libexec/exec.jar" clojure.main -m clojure.run.exec "${exec_args[@]}" "$@" | |
else | |
if [[ -e "$main_file" ]]; then | |
set +e | |
IFS=$'\n' read -ra main_cache_opts -d '' <"$main_file" | |
set -e | |
fi | |
if [ "$#" -gt 0 ] && [ "$mode" == "repl" ]; then | |
>&2 echo "WARNING: When invoking clojure.main, use -M" | |
fi | |
exec "$JAVA_CMD" "${jvm_cache_opts[@]}" "${jvm_opts[@]}" "-Dclojure.basis=$basis_file" -classpath "$cp" clojure.main "${main_cache_opts[@]}" "$@" | |
fi | |
fi |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment