Skip to content

Instantly share code, notes, and snippets.

@mfikes
Created April 8, 2018 16:09
Show Gist options
  • Save mfikes/bbf8a9a5b9ed6ecac15a3bb75d2dc8b4 to your computer and use it in GitHub Desktop.
Save mfikes/bbf8a9a5b9ed6ecac15a3bb75d2dc8b4 to your computer and use it in GitHub Desktop.
#!/usr/bin/env bash

set -e

function join { local d=$1; shift; echo -n "$1"; shift; printf "%s" "${@/#/$d}"; }

# Extract opts
print_classpath=false
describe=false
verbose=false
force=false
repro=false
tree=false
pom=false
resolve_tags=false
help=false
resolve_aliases=()
classpath_aliases=()
jvm_aliases=()
main_aliases=()
all_aliases=()
while [ $# -gt 0 ]
do
  case "$1" in
    -R*)
      resolve_aliases+=("${1:2}")
      shift
      ;;
    -C*)
      classpath_aliases+=("${1:2}")
      shift
      ;;
    -O*)
      jvm_aliases+=("${1:2}")
      shift
      ;;
    -M*)
      main_aliases+=("${1:2}")
      shift
      ;;
    -A*)
      all_aliases+=("${1:2}")
      shift
      ;;
    -Sdeps)
      shift
      deps_data="${1}"
      shift
      ;;
    -Scp)
      shift
      force_cp="${1}"
      shift
      ;;
    -Spath)
      print_classpath=true
      shift
      ;;
    -Sverbose)
      verbose=true
      shift
      ;;
    -Sdescribe)
      describe=true
      shift
      ;;
    -Sforce)
      force=true
      shift
      ;;
    -Srepro)
      repro=true
      shift
      ;;
    -Stree)
      tree=true
      shift
      ;;
    -Spom)
      pom=true
      shift
      ;;
    -Sresolve-tags)
      resolve_tags=true
      shift
      ;;
    -S*)
      echo "Invalid option: $1"
      exit 1
      ;;
    -h|--help|"-?")
      if [[ ${#main_aliases[@]} -gt 0 ]] || [[ ${#all_aliases[@]} -gt 0 ]]; then
        break
      else
        help=true
        shift
      fi
      ;;
    *)
      break
      ;;
  esac
done

# Find planck executable
PLANCK_CMD=$(type -p planck)
if [[ ! -n "$PLANCK_CMD" ]]; then
  >&2 echo "Couldn't find 'planck'."
fi

# Find clojure executable
CLOJURE_CMD=$(type -p clojure)
if [[ ! -n "$CLOJURE_CMD" ]]; then
  >&2 echo "Couldn't find 'clojure'."
fi

if "$help"; then
  cat <<-END
Usage: plk [dep-opt*] [init-opt*] [main-opt] [arg*]

The plk script is a runner for Planck which ultimately constructs and
invokes a command-line of the form:

planck --classpath classpath [init-opt*] [main-opt] [arg*]

  The dep-opts are used to build the classpath using the clojure tool:
    -Oalias...     Concatenated jvm option aliases, ex: -O:mem
    -Ralias...     Concatenated resolve-deps aliases, ex: -R:bench:1.9
    -Calias...     Concatenated make-classpath aliases, ex: -C:dev
    -Malias...     Concatenated main option aliases, ex: -M:test
    -Aalias...     Concatenated aliases of any kind, ex: -A:dev:mem
    -Sdeps EDN     Deps data to use as the final deps file
    -Spath         Compute classpath and echo to stdout only
    -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)
    -Spom          Generate (or update existing) pom.xml with deps and paths
    -Stree         Print dependency tree
    -Sresolve-tags Resolve git coordinate tags to shas and update deps.edn
    -Sverbose      Print important path info to console
    -Sdescribe     Print environment and command parsing info as data
END
  planck -h | tail -n +6
  exit 0
fi

# Execute resolve-tags command
if "$resolve_tags"; then
  "$CLOJURE_CMD" -Sresolve-tags
  exit
fi

clojure_args=()
if [[ -n "$deps_data" ]]; then
  clojure_args+=("-Sdeps" "$deps_data")
fi
if [[ ${#resolve_aliases[@]} -gt 0 ]]; then
  clojure_args+=("-R$(join '' ${resolve_aliases[@]})")
fi
if [[ ${#classpath_aliases[@]} -gt 0 ]]; then
  clojure_args+=("-C$(join '' ${classpath_aliases[@]})")
fi
if [[ ${#main_aliases[@]} -gt 0 ]]; then
  clojure_args+=("-M$(join '' ${main_aliases[@]})")
fi
if [[ ${#all_aliases[@]} -gt 0 ]]; then
  clojure_args+=("-A$(join '' ${all_aliases[@]})")
fi
if "$repro"; then
  clojure_args+=("-Srepro")
fi
if "$force"; then
  clojure_args+=("-Sforce")
fi

if "$pom"; then
  if "$verbose"; then
    clojure_args+=("-Sverbose")
  fi
  "$CLOJURE_CMD" "${clojure_args[@]}" -Spom
elif "$describe"; then
  if "$verbose"; then
    clojure_args+=("-Sverbose")
  fi
  "$CLOJURE_CMD" "${clojure_args[@]}" -Sdescribe
elif "$tree"; then
  if "$verbose"; then
    clojure_args+=("-Sverbose")
  fi
  "$CLOJURE_CMD" "${clojure_args[@]}" -Stree
else
  set -f
  if [[ -n "$force_cp" ]]; then
    cp="$force_cp"
  else
    if "$verbose"; then
      "$CLOJURE_CMD" "${clojure_args[@]}" -Sverbose -e nil
    fi
    cp=`"$CLOJURE_CMD" "${clojure_args[@]}" -Spath`
  fi
  if "$print_classpath"; then
    echo $cp
  else
    if [[ ${#main_aliases[@]} -gt 0 ]] || [[ ${#all_aliases[@]} -gt 0 ]]; then
      # Attempt to extract the main cache filename by parsing the output of -Sverbose
      cp_file=`"$CLOJURE_CMD" "${clojure_args[@]}" -Sverbose -Spath | grep cp_file | cut -d = -f 2 | sed 's/^ *//g'`
      main_file="${cp_file%.cp}.main"
    fi
    if [[ -e "$main_file" ]]; then
      main_cache_opts=($(cat "$main_file"))
    fi
    exec "$PLANCK_CMD" --classpath "$cp" "${main_cache_opts[@]}" "$@"
  fi
fi
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment