Created
February 12, 2018 22:47
-
-
Save semperos/5c03bfafd291ac5e8b30205a352ea6ce to your computer and use it in GitHub Desktop.
Project scaffolding relying on clj/clojure at system level
This file contains hidden or 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
#!/bin/bash | |
# | |
# Usage: clj-new <project-name> | |
# | |
# The project-name will be sanitized to handle JVM directory requirements. | |
# Relies on clj/clojure being installed at the system level. | |
# | |
# TODO Support app vs. lib scripts and code | |
# TODO Support "all defaults" rather than requiring user interactivity | |
# TODO For dot-nested project name, make final root directory only the final portion of the project name (i.e., `foo` instead of `com.example.foo`) | |
set -e -u | |
[[ $# -ne 1 ]] && echo "Usage: clj-new <project-name>" && exit 1 | |
PROJECT_NS_NAME=$1 | |
PROJECT_DIR_NAME=$(echo "${PROJECT_NS_NAME//-/_}") | |
PROJECT_DIR_NAME=$(echo "${PROJECT_DIR_NAME//.//}") | |
[ -d "$PROJECT_DIR_NAME" ] && echo "Directory $PROJECT_DIR_NAME already exists. Quitting." && exit 1 | |
SCRATCH=$(mktemp -d -t tmp.XXXXXXXXXX) | |
mkdir -p $SCRATCH/script | |
function cleanUp { | |
rm -rf $SCRATCH | |
} | |
trap cleanUp EXIT | |
DEPS_EDN=$(cat <<'DEPS_EDN' | |
{:aliases {:dev {:extra-deps | |
{org.clojure/tools.nrepl {:mvn/version "0.2.13"} | |
cider/cider-nrepl {:mvn/version "0.17.0-SNAPSHOT"} | |
rebel-readline {:mvn/version "0.1.0-SNAPSHOT"}}} | |
:1.8 {:override-deps {org.clojure/clojure {:mvn/version "1.8.0"}}} | |
:std {:extra-paths ["resources"]} | |
:test {:extra-paths ["test"]}} | |
:deps {} | |
:mvn/repos {"internal-repo" {:url "https://example.com/repository/maven-releases/"}}} | |
DEPS_EDN | |
) | |
echo "$DEPS_EDN" > $SCRATCH/deps.edn | |
echo "Specify desired port for nREPL usage: [7889]" | |
read REPL_PORT | |
if [ -z "$REPL_PORT" ] | |
then | |
REPL_PORT="7889" | |
fi | |
USER_CLJ=$(cat <<'USER_CLJ' | |
(ns user | |
(:require [clojure.tools.nrepl.server :refer [start-server stop-server]] | |
[cider.nrepl :refer (cider-nrepl-handler)])) | |
(defonce nrepl-server (start-server :port (Integer/parseInt (or (get (System/getenv) "REPL_PORT") "__REPL_PORT__")) :handler cider-nrepl-handler)) | |
USER_CLJ | |
) | |
# Default to No, ask if user would like a local user.clj to override one | |
# at $HOME/opt/user.clj. | |
if [ -f "$HOME/opt/user.clj" ] | |
then | |
echo "Do you want to override $HOME/opt/user.clj with a local user.clj file in this project? [y/N]" | |
read ADD_LOCAL_USER_CLJ | |
if [ -z "$ADD_LOCAL_USER_CLJ" ] | |
then | |
ADD_LOCAL_USER_CLJ="n" | |
fi | |
ADD_LOCAL_USER_CLJ="$(echo $ADD_LOCAL_USER_CLJ | tr '[:upper]' '[:lower:]')" | |
fi | |
if [ "$ADD_LOCAL_USER_CLJ" = "y" ] | |
then | |
echo "Writing project-local user.clj file..." | |
echo "$USER_CLJ" > $SCRATCH/user.clj_template | |
sed -e "s/__REPL_PORT__/$REPL_PORT/g" $SCRATCH/user.clj_template > $SCRATCH/user.clj | |
rm $SCRATCH/user.clj_template | |
echo "Writing scripts leverage project-local user.clj file..." | |
SCRIPT_REPL_LOCAL=$(cat <<'SCRIPT_REPL_LOCAL' | |
#!/bin/bash | |
set -e -u | |
cd "$(dirname $0)/.." | |
export REPL_PORT=__REPL_PORT__ | |
echo "Starting nREPL on port $REPL_PORT..." | |
clojure -C:std -R:std:dev -i user.clj -m rebel-readline.main | |
# clj -C:std -R:std:dev -i user.clj -r | |
SCRIPT_REPL_LOCAL | |
) | |
echo "$SCRIPT_REPL_LOCAL" > $SCRATCH/script/repl_template | |
sed -e "s/__REPL_PORT__/$REPL_PORT/g" $SCRATCH/script/repl_template > $SCRATCH/script/repl | |
rm $SCRATCH/script/repl_template | |
else | |
echo "Writing scripts leveraging global $HOME/opt/user.clj..." | |
SCRIPT_REPL_GLOBAL=$(cat <<'SCRIPT_REPL_GLOBAL' | |
#!/bin/bash | |
set -e -u | |
cd "$(dirname $0)/.." | |
export REPL_PORT=__REPL_PORT__ | |
echo "Starting nREPL on port $REPL_PORT..." | |
clojure -C:std -R:std:dev -i $HOME/opt/user.clj -m rebel-readline.main | |
# clj -C:std -R:std:dev -i $HOME/opt/user.clj -r | |
SCRIPT_REPL_GLOBAL | |
) | |
echo "$SCRIPT_REPL_GLOBAL" > $SCRATCH/script/repl_template | |
sed -e "s/__REPL_PORT__/$REPL_PORT/g" $SCRATCH/script/repl_template > $SCRATCH/script/repl | |
rm $SCRATCH/script/repl_template | |
fi | |
echo "Writing remaining scripts..." | |
SCRIPT_RUN=$(cat <<'SCRIPT_RUN' | |
#!/bin/bash | |
MAIN_NS="__PROJECT_NS_NAME__.core" | |
echo "Running $MAIN_NS..." | |
echo "" | |
clj -C:std -m $MAIN_NS $* | |
SCRIPT_RUN | |
) | |
echo "$SCRIPT_RUN" > $SCRATCH/script/run_template | |
SCRIPT_TEST=$(cat <<'SCRIPT_TEST' | |
#!/bin/bash | |
set -e -u | |
cd "$(dirname $0)/.." | |
echo "Running test suite..." | |
TEST_NS="'__PROJECT_NS_NAME__.core-test" | |
clj -C:std:test -R:std -e "(do (require 'clojure.test $TEST_NS) (clojure.test/run-tests $TEST_NS))" | |
SCRIPT_TEST | |
) | |
echo "$SCRIPT_TEST" > $SCRATCH/script/test_template | |
sed -e "s/__PROJECT_NS_NAME__/$PROJECT_NS_NAME/g" $SCRATCH/script/run_template > $SCRATCH/script/run | |
rm $SCRATCH/script/run_template | |
sed -e "s/__PROJECT_NS_NAME__/$PROJECT_NS_NAME/g" $SCRATCH/script/test_template > $SCRATCH/script/test | |
rm $SCRATCH/script/test_template | |
chmod a+x $SCRATCH/script/repl | |
chmod a+x $SCRATCH/script/run | |
chmod a+x $SCRATCH/script/test | |
echo "Creating start src and test files..." | |
mkdir -p $SCRATCH/src/$PROJECT_DIR_NAME | |
mkdir -p $SCRATCH/test/$PROJECT_DIR_NAME | |
PROJECT_CORE_CLJ=$(cat <<'PROJECT_CORE_CLJ' | |
(ns __PROJECT_NS_NAME__.core) | |
(defn it-odd? [a] (odd? a)) | |
PROJECT_CORE_CLJ | |
) | |
echo "$PROJECT_CORE_CLJ" > $SCRATCH/src/$PROJECT_DIR_NAME/core.clj_template | |
PROJECT_CORE_TEST_CLJ=$(cat <<'PROJECT_CORE_TEST_CLJ' | |
(ns __PROJECT_NS_NAME__.core-test | |
(:require [clojure.test :refer :all] | |
[__PROJECT_NS_NAME__.core :as sut])) | |
(deftest test-example | |
(is (sut/it-odd? 2))) | |
PROJECT_CORE_TEST_CLJ | |
) | |
echo "$PROJECT_CORE_TEST_CLJ" > $SCRATCH/test/$PROJECT_DIR_NAME/core_test.clj_template | |
sed -e "s/__PROJECT_NS_NAME__/$PROJECT_NS_NAME/g" $SCRATCH/src/$PROJECT_DIR_NAME/core.clj_template > $SCRATCH/src/$PROJECT_DIR_NAME/core.clj | |
rm $SCRATCH/src/$PROJECT_DIR_NAME/core.clj_template | |
sed -e "s/__PROJECT_NS_NAME__/$PROJECT_NS_NAME/g" $SCRATCH/test/$PROJECT_DIR_NAME/core_test.clj_template > $SCRATCH/test/$PROJECT_DIR_NAME/core_test.clj | |
rm $SCRATCH/test/$PROJECT_DIR_NAME/core_test.clj_template | |
mv $SCRATCH $PROJECT_NS_NAME | |
[[ $(type -P "tree") ]] && tree $PROJECT_NS_NAME | |
echo "Finished. See folder: $PROJECT_NS_NAME" |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment