Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add Leiningen integration #15

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
5 changes: 4 additions & 1 deletion browser-connected-repl-sample/project.clj
Original file line number Diff line number Diff line change
Expand Up @@ -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"]}})

34 changes: 34 additions & 0 deletions leiningen.md
Original file line number Diff line number Diff line change
@@ -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.
87 changes: 87 additions & 0 deletions src/clj/leiningen/austin.clj
Original file line number Diff line number Diff line change
@@ -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 <command>\".")
(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))))))