Skip to content

Commit d0d08a2

Browse files
committed
Document Clojure functions
1 parent 08b4c71 commit d0d08a2

File tree

5 files changed

+146
-28
lines changed

5 files changed

+146
-28
lines changed

src/main/clojure/dev/clojurephant/tooling/api.clj

Lines changed: 35 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,19 @@
11
(ns dev.clojurephant.tooling.api
2+
"A higher-level API to interact with Gradle's tooling API.
3+
Generally, prefer this to use the `dev.clojurephat.tooling.core`
4+
API."
25
(:require [dev.clojurephant.tooling.core :as core]
36
[clojure.edn :as edn]
47
[clojure.string :as string]))
58

69
(defonce db (atom {}))
710

8-
(defn connect! [project-dir]
11+
(defn connect!
12+
"Connects to a Gradle project in PROJECT-DIR. If DB
13+
already has a connection for this PROJECT-DIR, do
14+
nothing. If DB has a connection for another dir, throw.
15+
Otherwise create a new connection and store in DB."
16+
[project-dir]
917
(swap! db (fn [{:keys [dir connection] :as current-db}]
1018
(cond
1119
(nil? connection)
@@ -20,14 +28,21 @@
2028
(throw (ex-info "Must close existing connection" {:dir dir})))))
2129
nil)
2230

23-
(defn close! []
31+
(defn close!
32+
"Closes an existing connection in DB. If there's
33+
no existing connection, do nothing."
34+
[]
2435
(swap! db (fn [{:keys [connection]}]
2536
(when connection
2637
(.close connection))
2738
nil))
2839
nil)
2940

30-
(defn reload-model! []
41+
(defn reload-model!
42+
"Loads the Clojurephant model and stores it in DB. Requires you to
43+
have called (connect! ...) before. Reloads model from Gradle config
44+
even if model already populated in DB."
45+
[]
3146
(swap! db (fn [current-db]
3247
(if-let [con (:connection current-db)]
3348
(let [m (core/wait (core/clojurephant-model con))]
@@ -37,10 +52,17 @@
3752
(select-keys m [:error])))))
3853
(throw (ex-info "Cannot get model until connect" {}))))))
3954

40-
(defn repl-output-dir []
55+
(defn repl-output-dir
56+
"Gets the repl output directory. Requires calling
57+
(reload-model!) before."
58+
[]
4159
(-> @db :model :repl :dir))
4260

43-
(defn ^:private reroot-cljs-build [build new-dir]
61+
(defn ^:private reroot-cljs-build
62+
"Takes a ClojureScript build and re-evaluates the
63+
output directories to be relative to the REPL's
64+
output directory."
65+
[build new-dir]
4466
(let [old-dir (:output-dir build)
4567
replacer (fn [dir]
4668
(cond
@@ -54,13 +76,19 @@
5476
(update-in [:output-to] replacer)
5577
(update-in [:source-map] replacer))))
5678

57-
(defn cljs-all-build-opts []
79+
(defn cljs-all-build-opts
80+
"Returns a map of all ClojureScript build's compiler options.
81+
Key is a keyword of the build name, value is a map of compiler
82+
options."
83+
[]
5884
(let [m (:model @db)
5985
repl-dir (repl-output-dir)
6086
builds (:clojurescript m)]
6187
(into {} (map (fn [[id build]]
6288
[id (reroot-cljs-build build repl-dir)]))
6389
builds)))
6490

65-
(defn cljs-build-opts [id]
91+
(defn cljs-build-opts
92+
"Returns a map of compiler options for the build ID."
93+
[id]
6694
(get (cljs-all-build-opts) id))

src/main/clojure/dev/clojurephant/tooling/cljs.clj

Lines changed: 31 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,7 @@
11
(ns dev.clojurephant.tooling.cljs
2+
"An API to run ClojureScript builds using configuration
3+
from the Gradle build within the REPL. These functions
4+
use the ClojureScript build API."
25
(:require [dev.clojurephant.tooling.api :as api]
36
[cljs.analyzer.api :as ana]
47
[cljs.build.api :as build]
@@ -7,41 +10,63 @@
710

811
(def registry (atom {}))
912

10-
(defn build-opts [id]
13+
(defn build-opts
14+
"Returns a map of compiler options for the build ID."
15+
[id]
1116
(api/cljs-build-opts id))
1217

13-
(defn compiler-env! [id]
18+
(defn compiler-env!
19+
"Gets the compiler environment for build ID
20+
or sets it to an empty state, if none exists
21+
in REGISTRY."
22+
[id]
1423
(let [opts (build-opts id)]
1524
(-> registry
1625
(swap! update-in [id :compiler-env]
1726
(fn [env] (or env (ana/empty-state opts))))
1827
(get-in [id :compiler-env]))))
1928

20-
(defn build! [id]
29+
(defn build!
30+
"Runs build ID once."
31+
[id]
2132
(let [opts (build-opts id)
2233
compiler-env (compiler-env! id)]
2334
(build/build nil opts compiler-env)))
2435

25-
(defn watch! [id]
36+
(defn watch!
37+
"Starts build ID in watch mode. Can be stopped
38+
with (stop-watch! id)."
39+
[id]
2640
(let [opts (build-opts id)
2741
compiler-env (compiler-env! id)
2842
stop (promise)]
2943
(swap! registry assoc-in [id :watch-stop] stop)
3044
(build/watch nil opts compiler-env stop)))
3145

32-
(defn stop-watch! [id]
46+
(defn stop-watch!
47+
"Stops build ID's watch."
48+
[id]
3349
(swap! registry update-in [id :watch-stop]
3450
(fn [stop] (when stop (deliver stop true))))
3551
nil)
3652

37-
(defn clean! [id]
53+
(defn clean!
54+
"Cleans build ID. Stops watch, and blows away details
55+
in REGISTRY."
56+
[id]
3857
(let [opts (build-opts id)]
3958
(stop-watch! id)
4059
(swap! registry dissoc id)
4160
;; TODO delete output-dir and output-to
4261
))
4362

4463
(defn repl-env!
64+
"Gets or sets the repl environment for build ID.
65+
With one argument -- the ID -- gets an existing
66+
repl env. With two arguments -- the ID and env
67+
-- sets the repl env. If build ID already has
68+
a repl env, tears it down before replacing it
69+
in REGISTRY."
4570
([id]
4671
(get-in @registry [id :repl-env]))
4772
([id env]

src/main/clojure/dev/clojurephant/tooling/core.clj

Lines changed: 41 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,29 +1,44 @@
11
(ns dev.clojurephant.tooling.core
2+
"The core interaction with Gradle's tooling API is all in
3+
this namespace. Generally, this shouldn't be used directly
4+
by users."
25
(:require [clojure.string :as string]
36
[clojure.java.io :as io]
47
[dev.clojurephant.tooling.impl.event :as event])
58
(:import [org.gradle.tooling GradleConnector ResultHandler]
69
[org.gradle.tooling.events ProgressListener]
710
[dev.clojurephant.plugin.common ClojurephantModel]))
811

9-
(defn connect [dir]
12+
(defn connect
13+
"Connects to a Gradle project in DIR.
14+
Returns a ProjectConnection."
15+
[dir]
1016
(-> (GradleConnector/newConnector)
1117
(.forProjectDirectory (io/file dir))
1218
(.connect)))
1319

14-
(defn tap-listener []
20+
(defn tap-listener
21+
"A progress listener that sends all events
22+
to Clojure's tap facility."
23+
[]
1524
(let [cache (atom {})]
1625
(reify ProgressListener
1726
(statusChanged [this event]
1827
(println (event/event event cache))))))
1928

20-
(defn collecting-listener [db]
29+
(defn collecting-listener
30+
"A progress listener that collects all events
31+
into an atom."
32+
[db]
2133
(let [cache (atom {})]
2234
(reify ProgressListener
2335
(statusChanged [this event]
2436
(swap! db conj (event/event event cache))))))
2537

26-
(defn handler [done db]
38+
(defn handler
39+
"A result handler that sends the result to
40+
DONE (a promise) including DB of events."
41+
[done db]
2742
(reify ResultHandler
2843
(onComplete [this result]
2944
(deliver done {:result :success
@@ -34,7 +49,10 @@
3449
:error failure
3550
:events @db}))))
3651

37-
(defn build [con & tasks]
52+
(defn build
53+
"Runs TASKS against the project CON. Returns a map that can
54+
be used to either wait for the build to finish or cancel it."
55+
[con & tasks]
3856
(let [cancel-source (GradleConnector/newCancellationTokenSource)
3957
done (promise)
4058
db (atom [])]
@@ -43,21 +61,27 @@
4361
(.setJavaHome (io/file "/usr/lib/jvm/java-18-openjdk-amd64"))
4462
(.setStandardOutput System/out)
4563
(.setStandardError System/err)
46-
#_(.addProgressListener (tap-listener))
4764
(.addProgressListener (collecting-listener db))
4865
(.withCancellationToken (.token cancel-source))
4966
(.run (handler done db)))
5067
{:result done
5168
:cancel cancel-source}))
5269

53-
(defn wait [run]
70+
(defn wait
71+
"Waits for a RUN started with (build ...) to finish and
72+
returns the build result."
73+
[run]
5474
@(:result run))
5575

56-
(defn cancel [run]
76+
(defn cancel
77+
"Cancels a RUN started with (build ...)."
78+
[run]
5779
(.cancel (:cancel run))
5880
run)
5981

6082
(defn task-results
83+
"Returns the RUN's task results. If STATE-FILTER is
84+
provided you can filter on the task's :state field."
6185
([run]
6286
(task-results run any?))
6387
([run state-filter]
@@ -75,19 +99,25 @@
7599
(filter (fn [t]
76100
(state-filter (:result t))))))))
77101

78-
(defn model [con type]
102+
(defn model
103+
"Gets a model of TYPE from project CON. Returns a map that
104+
can be used to either wait for the operation to finish or
105+
cancel it."
106+
[con type]
79107
(let [cancel-source (GradleConnector/newCancellationTokenSource)
80108
done (promise)
81109
db (atom [])]
82110
(-> (.model con type)
83111
(.setJavaHome (io/file "/usr/lib/jvm/java-18-openjdk-amd64"))
84112
(.setStandardOutput System/out)
85113
(.setStandardError System/err)
86-
(.addProgressListener (collecting-listener db))
87114
(.withCancellationToken (.token cancel-source))
88115
(.get (handler done db)))
89116
{:result done
90117
:cancel cancel-source}))
91118

92-
(defn clojurephant-model [con]
119+
(defn clojurephant-model
120+
"Gets the Clojurephant model. Returns a map that can be
121+
used to either wiat for the operation to finish or cancel it."
122+
[con]
93123
(model con ClojurephantModel))

src/main/clojure/dev/clojurephant/tooling/figwheel_main.clj

Lines changed: 19 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,34 @@
11
(ns dev.clojurephant.tooling.figwheel-main
2+
"An API to start a ClojureScript REPL via Figwheel
3+
Main. This uses configuration from Gradle, rather
4+
than `<build>.cljs.edn` files.
5+
6+
As opposed to the `.figwheel-repl` namespace, this
7+
does provide the full hot reload workflow."
28
(:require [dev.clojurephant.tooling.api :as api]
39
[dev.clojurephant.tooling.cljs :as cljs]
410
[figwheel.main.api :as fig]))
511

6-
(defn build-map [id]
12+
(defn build-map
13+
"Gets a build map for Figwheel Main usage. Loads
14+
the build configuration from Gradle. Presumes
15+
(api/reload-model!) has been called beforehand."
16+
[id]
717
{:id (name id)
818
:options (api/cljs-build-opts id)
919
:config {}})
1020

11-
(defn cljs-repl [id]
21+
(defn cljs-repl
22+
"Starts a ClojureScript REPL using
23+
Figwheel Main and Piggieback."
24+
[id]
1225
(fig/cljs-repl (name id)))
1326

1427
(defn start
28+
"Convenience function to start a ClojureScript
29+
REPL with one call. Will connect to and get model
30+
config from Gradle, then start the Figwheel Main
31+
build and REPL."
1532
([] (start :dev))
1633
([id]
1734
(api/connect! ".")

src/main/clojure/dev/clojurephant/tooling/figwheel_repl.clj

Lines changed: 20 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,19 +1,37 @@
11
(ns dev.clojurephant.tooling.figwheel-repl
2+
"An API to start a ClojureScript REPL via Figwheel
3+
REPL. This only provides the websocket-based REPL,
4+
not the full features of Figwheel Main.
5+
6+
Users may prefer this if they don't want a hot
7+
reload workflow or just want fewer moving pices
8+
in their process."
29
(:require [dev.clojurephant.tooling.api :as api]
310
[dev.clojurephant.tooling.cljs :as cljs]
411
[cider.piggieback :as piggie]
512
[figwheel.repl :as repl]))
613

7-
(defn repl-env [id]
14+
(defn repl-env
15+
"Creates a new repl environment for build ID.
16+
Uses the build configuration from Gradle. Presumes
17+
(api/reload-model!) has been called beforehand."
18+
[id]
819
(let [opts (assoc (cljs/build-opts id)
920
:open-url false)
1021
env (repl/repl-env* opts)]
1122
(cljs/repl-env! id env)))
1223

13-
(defn cljs-repl [id]
24+
(defn cljs-repl
25+
"Starts a ClojureScript REPL using
26+
Figwheel REPL and Piggieback."
27+
[id]
1428
(piggie/cljs-repl (repl-env id)))
1529

1630
(defn start
31+
"Convenience function to start a ClojureScript
32+
REPL with one call. Will connect to and get model
33+
config from Gradle, pre-build the ClojureScript
34+
then start the REPL."
1735
([] (start :dev))
1836
([id]
1937
(api/connect! ".")

0 commit comments

Comments
 (0)