Skip to content

Commit 69db83f

Browse files
committed
dev: update script/task deps, use docopt for args
After upgrading docopt, decided to take a crack at using it for all task command line args for consistency for users and for maintainability. I was previously using a mix of adhoc, docopt and clojure.tools.cli. I think overall, this went quite well. I wrote a little wrapper-hack helper.main/doc-arg-opt to allow us to specify "Valid args: ..." instead of "Usage: my-exe...". The Usage syntax focuses on the executable, which is really not appropriate for tasks, so we focus on the args only. If docopt also supported validation of option arguments (ex. --my-option OPTION_ARG) that'd be awesome, but it doesn't so had to include extra validation for these args.
1 parent c6de98b commit 69db83f

23 files changed

+356
-453
lines changed

bb.edn

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,7 @@
22
:paths ["script"]
33
:deps {org.clojure/data.zip {:mvn/version "1.0.0"}
44
io.aviso/pretty {:mvn/version "0.1.37"}
5-
docopt/docopt {:git/url "https://github.com/nubank/docopt.clj"
6-
:sha "98814f559d2e50fdf10f43cbe3b7da0ca3cca423"}
5+
dev.nubank/docopt {:mvn/version "0.6.1-fix2"}
76
doric/doric {:mvn/version "0.9.0"}
87
version-clj/version-clj {:mvn/version "2.0.1"}
98
lread/status-line {:git/url "https://github.com/lread/status-line.git"

deps.edn

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -68,7 +68,7 @@
6868
cli-matic/cli-matic {:mvn/version "0.4.3"}}}
6969

7070
:apply-import-vars {:override-deps {org.clojure/clojure {:mvn/version "1.10.3"}}
71-
:extra-deps {metosin/malli {:mvn/version "0.4.0"}
71+
:extra-deps {metosin/malli {:mvn/version "0.5.1"}
7272
io.aviso/pretty {:mvn/version "0.1.37"}}
7373
:ns-default lread.apply-import-vars}
7474

script/apply_import_vars.clj

Lines changed: 14 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -1,30 +1,25 @@
11
#!/usr/bin/env bb
22

33
(ns apply-import-vars
4-
(:require [helper.env :as env]
4+
(:require [helper.main :as main]
55
[helper.shell :as shell]
66
[lread.status-line :as status]))
77

8-
(def arg-usage (str "Valid args: (gen-code|check|--help)\n"
9-
"\n"
10-
" gen-code Generate API sources from templates\n"
11-
" check Fail if API sources are stale as compared to templates\n"
12-
" --help Show this help"))
8+
(def args-usage "Valid args: (gen-code|check|--help)
139
14-
(defn -main[& args]
15-
(env/assert-min-versions)
16-
(let [cmd (first args)]
17-
(cond
18-
(= "--help" cmd)
19-
(status/line :detail arg-usage)
10+
Commands:
11+
gen-code Generate API sources from templates
12+
check Fail if API sources are stale as compared to templates
2013
21-
(not (#{"gen-code" "check"} cmd))
22-
(status/die 1 arg-usage)
14+
Options:
15+
--help Show this help")
2316

24-
:else
25-
(do (status/line :head (str "Running apply import vars " cmd))
26-
(shell/command ["clojure" "-X:apply-import-vars:script" cmd])))
27-
nil))
17+
(defn -main[& args]
18+
(when-let [opts (main/doc-arg-opt args-usage args)]
19+
(let [cmd (if (get opts "check") "check" "gen-code")]
20+
(status/line :head (str "Running apply import vars " cmd))
21+
(shell/command ["clojure" "-X:apply-import-vars:script" cmd])))
22+
nil)
2823

29-
(env/when-invoked-as-script
24+
(main/when-invoked-as-script
3025
(apply -main *command-line-args*))

script/ci_release.clj

Lines changed: 55 additions & 67 deletions
Original file line numberDiff line numberDiff line change
@@ -7,8 +7,8 @@
77
(ns ci-release
88
(:require [clojure.java.io :as io]
99
[clojure.string :as string]
10-
[helper.env :as env]
1110
[helper.fs :as fs]
11+
[helper.main :as main]
1212
[helper.shell :as shell]
1313
[lread.status-line :as status]
1414
[release.version :as version]))
@@ -153,72 +153,60 @@
153153
(when (not (zero? exit-code))
154154
(status/line :warn (str "Informing cljdoc did not seem to work, exited with " exit-code)))))
155155

156-
(def usage (string/join "\n"
157-
["Valid args: <cmd>"
158-
""
159-
"Where cmd can be:"
160-
" prep update user guide, changelog and create jar"
161-
" deploy-remote deploy jar to clojars"
162-
" commit commit changes made back to repo, inform cljdoc of release"
163-
""
164-
"These commands are expected to be run in order from CI."
165-
"Why the awkward separation?"
166-
"To restrict the exposure of our CLOJARS secrets during deploy workflow"
167-
""
168-
"Additional commands:"
169-
" validate verify that change log is good for release"
170-
" version calculate and report version"
171-
" --help show this help"]))
172-
173-
174-
(defn- validate-args [args]
175-
(let [cmd (first args)]
176-
(when (or (not= 1 (count args))
177-
(not (some #{cmd} '("prep" "deploy-remote" "commit" "validate" "version" "--help"))))
178-
(status/die 1 usage))
179-
cmd))
156+
(def args-usage "Valid args: (prep|deploy-remote|commit|validate|version|--help)
157+
158+
Commands:
159+
prep Update user guide, changelog and create jar
160+
deploy-remote Deploy jar to clojars
161+
commit Commit changes made back to repo, inform cljdoc of release
162+
163+
These commands are expected to be run in order from CI.
164+
Why the awkward separation?
165+
To restrict the exposure of our CLOJARS secrets during deploy workflow
166+
167+
Additional commands:
168+
validate Verify that change log is good for release
169+
version Calculate and report version
170+
171+
Options
172+
--help Show this help")
180173

181174
(defn -main [& args]
182-
(let [cmd (validate-args args)
183-
target-version-filename "target/target-version.txt"]
184-
(if (= "--help" cmd)
185-
(status/line :detail usage)
186-
(do
187-
(status/line :head (str "Attempting release step: " cmd))
188-
(case cmd
189-
"prep"
190-
(do (clean!)
191-
(let [changelog-status (validate-changelog)
192-
target-version (calculate-version)
193-
last-version (last-release-tag)]
194-
(status/line :detail (str "Last version released: " (or last-version "<none>")))
195-
(status/line :detail (str "Target version: " target-version))
196-
(io/make-parents target-version-filename)
197-
(spit target-version-filename target-version)
198-
(update-user-guide! target-version)
199-
(update-changelog! target-version last-version changelog-status)
200-
(create-jar! target-version)))
201-
202-
"deploy-remote"
203-
(deploy-jar!)
204-
205-
"commit"
206-
(if (not (.exists (io/file target-version-filename)))
207-
(status/die 1
208-
"Target version file not found: %s\nWas prep step run?"
209-
target-version-filename)
210-
(let [target-version (slurp target-version-filename)]
211-
(commit-changes! target-version)
212-
(inform-cljdoc! target-version)))
213-
214-
"validate"
215-
(do (validate-changelog)
216-
nil)
217-
218-
"version"
219-
(do (calculate-version)
220-
nil))
221-
(status/line :detail (str "Release step done:" cmd))))))
222-
223-
(env/when-invoked-as-script
175+
(when-let [opts (main/doc-arg-opt args-usage args)]
176+
(let [target-version-filename "target/target-version.txt"]
177+
(cond
178+
(get opts "prep")
179+
(do (clean!)
180+
(let [changelog-status (validate-changelog)
181+
target-version (calculate-version)
182+
last-version (last-release-tag)]
183+
(status/line :detail (str "Last version released: " (or last-version "<none>")))
184+
(status/line :detail (str "Target version: " target-version))
185+
(io/make-parents target-version-filename)
186+
(spit target-version-filename target-version)
187+
(update-user-guide! target-version)
188+
(update-changelog! target-version last-version changelog-status)
189+
(create-jar! target-version)))
190+
191+
(get opts "deploy-remote")
192+
(deploy-jar!)
193+
194+
(get opts "commit")
195+
(if (not (.exists (io/file target-version-filename)))
196+
(status/die 1
197+
"Target version file not found: %s\nWas prep step run?"
198+
target-version-filename)
199+
(let [target-version (slurp target-version-filename)]
200+
(commit-changes! target-version)
201+
(inform-cljdoc! target-version)))
202+
203+
(get opts "validate")
204+
(do (validate-changelog)
205+
nil)
206+
207+
(get opts "version")
208+
(do (calculate-version)
209+
nil)))))
210+
211+
(main/when-invoked-as-script
224212
(apply -main *command-line-args*))

script/ci_unit_tests.clj

Lines changed: 10 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -38,19 +38,16 @@
3838
(status/line :warn "skipping planck tests, they can only be run on linux and macOS")) )
3939

4040
(defn -main [& args]
41-
(main/run-argless-cmd
42-
args
43-
(fn []
44-
(env/assert-min-versions)
45-
(clean)
46-
(check-import-vars)
47-
(lint)
48-
(doc-tests)
49-
(clojure-tests)
50-
(cljs-tests)
51-
(shadow-cljs-tests)
52-
(cljs-bootstrap-tests)))
41+
(when (main/doc-arg-opt args)
42+
(clean)
43+
(check-import-vars)
44+
(lint)
45+
(doc-tests)
46+
(clojure-tests)
47+
(cljs-tests)
48+
(shadow-cljs-tests)
49+
(cljs-bootstrap-tests))
5350
nil)
5451

55-
(env/when-invoked-as-script
52+
(main/when-invoked-as-script
5653
(apply -main *command-line-args*))

script/cljdoc_preview.clj

Lines changed: 22 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -7,8 +7,8 @@
77
[clojure.java.browse :as browse]
88
[clojure.string :as string]
99
[clojure.zip :as zip]
10-
[helper.env :as env]
1110
[helper.fs :as fs]
11+
[helper.main :as main]
1212
[helper.shell :as shell]
1313
[lread.status-line :as status]))
1414

@@ -215,57 +215,50 @@
215215
(defn cleanup-resources []
216216
(fs/delete-file-recursively cljdoc-db-dir true))
217217

218-
(def usage (string/join "\n"
219-
["Valid args: [start|ingest|view|stop|status]"
220-
""
221-
" start - start docker containers supporting cljdoc preview"
222-
" ingest - locally publishes your project for cljdoc preview"
223-
" view - opens cljdoc preview in your default browser"
224-
" stop - stops docker containers supporting cljdoc preview"
225-
" status - status of docker containers supporting cljdoc preview"
226-
""
227-
" --help - show this help"
228-
""
229-
"Must be run from project root directory."]))
218+
(def args-usage "Valid args: (start|ingest|view|stop|status|--help)
230219
231-
(defn -main [& args]
220+
Commands:
221+
start Start docker containers supporting cljdoc preview
222+
ingest Locally publishes your project for cljdoc preview
223+
view Opens cljdoc preview in your default browser
224+
stop Stops docker containers supporting cljdoc preview
225+
status Status of docker containers supporting cljdoc preview
232226
233-
(check-prerequisites)
227+
Options:
228+
--help Show this help
234229
235-
(let [command (first args)]
236-
(case command
237-
"--help"
238-
(status/line :detail usage)
230+
Must be run from project root directory.")
239231

240-
"start"
232+
(defn -main [& args]
233+
(check-prerequisites)
234+
(when-let [opts (main/doc-arg-opt args-usage args)]
235+
(cond
236+
(get opts "start")
241237
(do
242238
(start-cljdoc-server cljdoc-container)
243239
nil)
244240

245-
"ingest"
241+
(get opts "ingest")
246242
(do
247243
(git-warnings)
248244
(local-install)
249245
(cljdoc-ingest cljdoc-container (get-project) (get-version))
250246
nil)
251247

252-
"view"
248+
(get opts "view")
253249
(do
254250
(wait-for-server cljdoc-container)
255251
(view-in-browser (str "http://localhost:" (:port cljdoc-container) "/d/" (get-project) "/" (get-version)))
256252
nil)
257253

258-
"status"
254+
(get opts "status")
259255
(status-server-print cljdoc-container)
260256

261-
"stop"
257+
(get opts "stop")
262258
(do
263259
(stop-server cljdoc-container)
264260
(cleanup-resources)
265-
nil)
266-
267-
;; else
268-
(status/die 1 usage))))
261+
nil))))
269262

270-
(env/when-invoked-as-script
263+
(main/when-invoked-as-script
271264
(apply -main *command-line-args*))

script/doc_api_diffs.clj

Lines changed: 21 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,6 @@
33
(ns doc-api-diffs
44
(:require [clojure.java.io :as io]
55
[clojure.string :as string]
6-
[helper.env :as env]
76
[helper.fs :as fs]
87
[helper.main :as main]
98
[helper.shell :as shell]
@@ -49,29 +48,27 @@
4948
extra-args)))
5049

5150
(defn -main [& args]
52-
(main/run-argless-cmd
53-
args
54-
(fn []
55-
(let [opts {:notes-dir "doc/diff-notes"
56-
:report-dir "doc/generated/api-diffs"}
57-
rewrite-clj-v0-lang-clj {:coords "rewrite-clj/rewrite-clj" :version "0.6.1" :lang "clj"}
58-
rewrite-cljs-lang-cljs {:coords "rewrite-cljs/rewrite-cljs" :version "0.4.5" :lang "cljs"}
59-
rewrite-clj-v1-lang-clj {:coords "rewrite-clj/rewrite-clj" :version "1.0.0-alpha" :lang "clj"}
60-
rewrite-clj-v1-lang-cljs (assoc rewrite-clj-v1-lang-clj :lang "cljs")
61-
existing-to-cljc-args ["--exclude-namespace" "rewrite-clj"
62-
"--exclude-namespace" "rewrite-clj.potemkin"
63-
"--exclude-namespace" "rewrite-clj.custom-zipper.switchable"
64-
"--exclude-namespace" "rewrite-clj.interop"]
65-
to-self-args ["--exclude-namespace" "rewrite-clj.potemkin.clojure"]
66-
documented-only-args ["--exclude-with" ":no-doc" "--exclude-with" ":skip-wiki"]]
67-
(install-locally)
68-
(clean opts rewrite-clj-v1-lang-clj)
69-
(diff-apis opts rewrite-clj-v0-lang-clj rewrite-cljs-lang-cljs "rewrite-clj-v0-lang-clj-and-rewrite-cljs-lang-cljs" [])
70-
(diff-apis opts rewrite-clj-v0-lang-clj rewrite-clj-v1-lang-clj "rewrite-clj-v0-lang-clj-and-rewrite-clj-v1-lang-clj" existing-to-cljc-args)
71-
(diff-apis opts rewrite-cljs-lang-cljs rewrite-clj-v1-lang-cljs "rewrite-cljs-lang-cljs-and-rewrite-clj-v1-lang-cljs" existing-to-cljc-args)
72-
(diff-apis opts rewrite-clj-v1-lang-cljs rewrite-clj-v1-lang-clj "rewrite-clj-v1-lang-cljs-and-rewrite-clj-v1-lang-clj" to-self-args)
73-
(diff-apis opts rewrite-clj-v1-lang-cljs rewrite-clj-v1-lang-clj "rewrite-clj-v1-lang-cljs-and-rewrite-clj-v1-lang-clj-documented-only" (concat to-self-args documented-only-args)))))
51+
(when (main/doc-arg-opt args)
52+
(let [opts {:notes-dir "doc/diff-notes"
53+
:report-dir "doc/generated/api-diffs"}
54+
rewrite-clj-v0-lang-clj {:coords "rewrite-clj/rewrite-clj" :version "0.6.1" :lang "clj"}
55+
rewrite-cljs-lang-cljs {:coords "rewrite-cljs/rewrite-cljs" :version "0.4.5" :lang "cljs"}
56+
rewrite-clj-v1-lang-clj {:coords "rewrite-clj/rewrite-clj" :version "1.0.0-alpha" :lang "clj"}
57+
rewrite-clj-v1-lang-cljs (assoc rewrite-clj-v1-lang-clj :lang "cljs")
58+
existing-to-cljc-args ["--exclude-namespace" "rewrite-clj"
59+
"--exclude-namespace" "rewrite-clj.potemkin"
60+
"--exclude-namespace" "rewrite-clj.custom-zipper.switchable"
61+
"--exclude-namespace" "rewrite-clj.interop"]
62+
to-self-args ["--exclude-namespace" "rewrite-clj.potemkin.clojure"]
63+
documented-only-args ["--exclude-with" ":no-doc" "--exclude-with" ":skip-wiki"]]
64+
(install-locally)
65+
(clean opts rewrite-clj-v1-lang-clj)
66+
(diff-apis opts rewrite-clj-v0-lang-clj rewrite-cljs-lang-cljs "rewrite-clj-v0-lang-clj-and-rewrite-cljs-lang-cljs" [])
67+
(diff-apis opts rewrite-clj-v0-lang-clj rewrite-clj-v1-lang-clj "rewrite-clj-v0-lang-clj-and-rewrite-clj-v1-lang-clj" existing-to-cljc-args)
68+
(diff-apis opts rewrite-cljs-lang-cljs rewrite-clj-v1-lang-cljs "rewrite-cljs-lang-cljs-and-rewrite-clj-v1-lang-cljs" existing-to-cljc-args)
69+
(diff-apis opts rewrite-clj-v1-lang-cljs rewrite-clj-v1-lang-clj "rewrite-clj-v1-lang-cljs-and-rewrite-clj-v1-lang-clj" to-self-args)
70+
(diff-apis opts rewrite-clj-v1-lang-cljs rewrite-clj-v1-lang-clj "rewrite-clj-v1-lang-cljs-and-rewrite-clj-v1-lang-clj-documented-only" (concat to-self-args documented-only-args))))
7471
nil)
7572

76-
(env/when-invoked-as-script
73+
(main/when-invoked-as-script
7774
(apply -main *command-line-args*))

0 commit comments

Comments
 (0)