From 37260b7956395910f2a4a85552ccc941ef086f73 Mon Sep 17 00:00:00 2001 From: nickgieschen Date: Sat, 24 Aug 2013 00:58:08 -0700 Subject: [PATCH] Add Leiningen integration --- README.md | 4 ++ browser-connected-repl-sample/project.clj | 5 +- leiningen.md | 34 +++++++++ src/clj/leiningen/austin.clj | 87 +++++++++++++++++++++++ 4 files changed, 129 insertions(+), 1 deletion(-) create mode 100644 leiningen.md create mode 100644 src/clj/leiningen/austin.clj diff --git a/README.md b/README.md index 8ca38e5..7902d98 100644 --- a/README.md +++ b/README.md @@ -185,6 +185,10 @@ documenting how to use Austin for your browser-connected REPL'ing needs. [Check it out](https://github.com/cemerick/austin/blob/master/browser-connected-repl-sample). +## Leiningen Integration + +Instructions on starting Austin REPLs with Leiningen can be found [here](leiningen.md). + ## TODO * ISO a reasonable automated test strategy diff --git a/browser-connected-repl-sample/project.clj b/browser-connected-repl-sample/project.clj index 9e5c5c2..34c9796 100644 --- a/browser-connected-repl-sample/project.clj +++ b/browser-connected-repl-sample/project.clj @@ -12,5 +12,8 @@ :cljsbuild {:builds [{:source-paths ["src/cljs"] :compiler {:output-to "target/classes/public/app.js" :optimizations :simple - :pretty-print true}}]}}}) + :pretty-print true}}]}} + :austin {:start-up (cemerick.austin.bcrepl-sample/run) + :phantom-cmd "phantomjs" + :exec-cmds ["open" "-ga" "/Applications/Google Chrome.app"]}}) diff --git a/leiningen.md b/leiningen.md new file mode 100644 index 0000000..7febaef --- /dev/null +++ b/leiningen.md @@ -0,0 +1,34 @@ +# Leiningen Integration + +Austin can be started with Leiningen via the `austin` task. The `austin` task requires one of two subtasks, `project` or `browser`, which correspond to Austin's two ClojureScript REPL environments. + +### project + +`project` creates, in Austin parlance, a project REPL environment (`cemerick.austin/exec-env`.) To launch the simplest form of a project REPL use: + + $ lein trampoline austin project + +`project` supports `exec-env`'s two paraments `:phantom-cmd` and `:exec-cmds`. These can either be specified in the `austin` section of project.clj or on the command line. An example of specifying them on the command line is: + + $ lein trampoline austin project :phantom-cmd slimerjs :exec-cmds '["open" "-ga" "/Applications/Google Chrome.app"]' + +In project.clj, the above would be represented as: + + :austin {:phantom-cmd "slimerjs" + :exec-cmds ["open" "-ga" "/Applications/Google Chrome.app"]} + +Any options specified on the command line will override those specified in project.clj. + +### browser + +`browser` creates, in Austin parlance, a browser REPL environment (`cemerick.austin/repl-env`.) To launch it use: + + $ lein trampoline austin browser + +`browser` requires a function to start the app. This function should be specified in the `austin` section of project.clj under the `:start-up` key. For example: + + :austin {:start-up (cemerick.austin.bcrepl-sample/run)} + +## Example + +[The example project's project.clj](browser-connected-repl-sample/project.clj) contains an example of the options. diff --git a/src/clj/leiningen/austin.clj b/src/clj/leiningen/austin.clj new file mode 100644 index 0000000..ffa23a9 --- /dev/null +++ b/src/clj/leiningen/austin.clj @@ -0,0 +1,87 @@ +(ns leiningen.austin + (:require [leiningen.help :as lhelp] + [leiningen.core.eval :as leval] + [leiningen.core.main :as lmain] + [leiningen.trampoline :as ltrampoline])) + +;; Ripped off from cljsbuild +(defmacro require-trampoline [& forms] + `(if ltrampoline/*trampoline?* + (do ~@forms) + (do + (println "REPL subcommands must be run via \"lein trampoline austin \".") + (lmain/abort)))) + +;; Ripped off from cljsbuild +(defn run-local-project [project requires form] + (leval/eval-in-project project + ; Without an explicit exit, the in-project subprocess seems to just hang for + ; around 30 seconds before exiting. I don't fully understand why... + `(try + (do + ~form + (System/exit 0)) + (catch Exception e# + (do + (.printStackTrace e#) + (System/exit 1)))) + requires)) + +;; Ripped off from lein-ring. +(defn load-namespaces + "Create require forms for each of the supplied symbols. This exists because + Clojure cannot load and use a new namespace in the same eval form." + [& syms] + `(require + ~@(for [s syms :when s] + `'~(if-let [ns (namespace s)] + (symbol ns) + s)))) + +(defn- build-project-commands [options args] + (let [phantom-cmd (or (args ":phantom-cmd") (options :phantom-cmd)) + exec-cmds (or (read-string (get args ":exec-cmds" "false")) (options :exec-cmds)) + cmds `(cemerick.austin.repls/cljs-repl (cemerick.austin/exec-env :phantom-cmd ~phantom-cmd :exec-cmds ~exec-cmds))] + cmds)) + +(defn- project + "Run an austin project REPL." + [project options args] + (require-trampoline + (#'run-local-project + project + (load-namespaces 'cemerick.austin.repls) + (build-project-commands options args)))) + +(defn- build-browser-commands [start-up] + `(do + ~@(list start-up) + (def ~'repl-env (reset! cemerick.austin.repls/browser-repl-env (cemerick.austin/repl-env))) + (cemerick.austin.repls/cljs-repl ~'repl-env))) + +(defn- browser + "Run an austin browser REPL." + [project {start-up :start-up}] + (require-trampoline + (#'run-local-project + project + (load-namespaces (first start-up) 'cemerick.austin.repls 'cemerick.austin) ;; todo go through start-up recursively grabbing namespaces in case its in a do block + (build-browser-commands start-up)))) + +(defn austin + "Run the austin plugin." + {:help-arglists '([repl-type]) + :subtasks [#'project #'browser]} + ([proj] + (println (lhelp/help-for "austin")) + (lmain/abort)) + ([proj repl-type & args] + (let [options (proj :austin)] + (case repl-type + "project" (project proj options (apply hash-map args)) + "browser" (browser proj options) + (do + (println + "Subtask" (str \" repl-type \") "not found." + (lhelp/subtask-help-for *ns* #'austin)) + (lmain/abort))))))