Skip to content

Commit 19a3c97

Browse files
authored
Cli tools api (#17)
* add tools namespace for tools CLI * use correct tools ns * check another tools idea * add help function for cli * fix formatting * use better summary printing * fix help printer, cleanup migration * introduce better help config * rename help function * remove reflection again * update readme * remove unused namespace
1 parent 258e2a4 commit 19a3c97

File tree

3 files changed

+110
-52
lines changed

3 files changed

+110
-52
lines changed

README.md

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,36 @@ Alternatively open your Clojure project, add `io.lambdaforge/wanderung` to your
3838
You can use `clj -T:build jar` to create a jar file and `clj -T:build install` to install the library in your local maven repository.
3939
Take a look at `build.clj` for further commands.
4040

41+
### CLI tools
42+
43+
If you have Clojure [CLI tools](https://clojure.org/guides/deps_and_cli) installed you can install `wanderung` locally and use it as a commandline tool.
44+
45+
Install it with:
46+
```bash
47+
clj -Ttools install io.lambdaforge/wanderung '{:git/url "https://github.com/lambdaforge/wanderung" :git/tag "v0.2.65"}' :as wanderung
48+
```
49+
50+
Make sure it is installed with:
51+
```bash
52+
clj -Ttools list
53+
```
54+
55+
Run it with:
56+
```bash
57+
clj -Twanderung migration :source '"./source-cfg.edn"' :target '"./target-cfg.edn"'
58+
```
59+
60+
Show help with:
61+
```bash
62+
clj -Twanderung help
63+
```
64+
65+
Uninstall it with:
66+
```bash
67+
clj -Ttools remove :tool wanderung
68+
```
69+
70+
4171
## Tests
4272

4373
Before using Wanderung for performing a migration, you may wish to run tests that to check that Wanderung works correctly. In order to do so, you need to perform the following steps:

deps.edn

Lines changed: 21 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -1,25 +1,26 @@
1-
{:paths ["src" "resources"]
2-
:deps {org.clojure/clojure {:mvn/version "1.10.3"}
3-
io.replikativ/konserve {:mvn/version "0.6.0-alpha3"}
4-
io.replikativ/datahike {:mvn/version "0.4.1488" :exclusions [io.replikativ/konserve]}
5-
com.datomic/client-cloud {:mvn/version "0.8.105"}
6-
com.cognitect/transit-clj {:mvn/version "0.8.313"}
7-
com.taoensso/nippy {:mvn/version "3.1.1"}
8-
org.clojure/tools.cli {:mvn/version "1.0.206"}}
1+
{:paths ["src" "resources"]
2+
:deps {org.clojure/clojure {:mvn/version "1.10.3"}
3+
io.replikativ/konserve {:mvn/version "0.6.0-alpha3"}
4+
io.replikativ/datahike {:mvn/version "0.4.1488" :exclusions [io.replikativ/konserve]}
5+
com.datomic/client-cloud {:mvn/version "0.8.105"}
6+
com.cognitect/transit-clj {:mvn/version "0.8.313"}
7+
com.taoensso/nippy {:mvn/version "3.1.1"}
8+
org.clojure/tools.cli {:mvn/version "1.0.206"}}
99
:tools/usage {:ns-default wanderung.core}
1010
:aliases
11-
{:run-m {:main-opts ["-m" "wanderung.core"]}
12-
:dev {:extra-deps {org.clojure/test.check {:mvn/version "0.9.0"}}}
13-
:test {:extra-paths ["test"]
14-
:extra-deps {com.datomic/dev-local {:mvn/version "1.0.242"}
15-
io.github.cognitect-labs/test-runner {:git/tag "v0.5.0"
16-
:git/sha "48c3c67"}}}
17-
:run-bench {:extra-paths ["benchmark/src"]
18-
:main-opts ["-m" "wanderung.benchmark.core"]
19-
:extra-deps {io.github.cognitect-labs/test-runner {:git/tag "v0.5.0"
20-
:git/sha "48c3c67"}}}
21-
:format {:extra-deps {cljfmt/cljfmt {:mvn/version "0.8.0"}}
22-
:main-opts ["-m" "cljfmt.main" "check"]}
11+
{:run-m {:main-opts ["-m" "wanderung.core"]}
12+
:dev {:extra-deps {org.clojure/test.check {:mvn/version "0.9.0"}}
13+
:ns-default wanderung.core}
14+
:test {:extra-paths ["test"]
15+
:extra-deps {com.datomic/dev-local {:mvn/version "1.0.242"}
16+
io.github.cognitect-labs/test-runner {:git/tag "v0.5.0"
17+
:git/sha "48c3c67"}}}
18+
:run-bench {:extra-paths ["benchmark/src"]
19+
:main-opts ["-m" "wanderung.benchmark.core"]
20+
:extra-deps {io.github.cognitect-labs/test-runner {:git/tag "v0.5.0"
21+
:git/sha "48c3c67"}}}
22+
:format {:extra-deps {cljfmt/cljfmt {:mvn/version "0.8.0"}}
23+
:main-opts ["-m" "cljfmt.main" "check"]}
2324

2425
:ffix {:extra-deps {cljfmt/cljfmt {:mvn/version "0.8.0"}}
2526
:main-opts ["-m" "cljfmt.main" "fix"]}

src/wanderung/core.clj

Lines changed: 59 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -5,10 +5,9 @@
55
[wanderung.datahike :as wd]
66
[wanderung.datom :as datom]
77
[clojure.tools.cli :refer [parse-opts]]
8-
[clojure.string :refer [split]]
98
[clojure.java.io :as io]
109
[taoensso.nippy :as nippy])
11-
(:gen-class))
10+
(:import [clojure.lang IExceptionInfo]))
1211

1312
;;;------- Basic datoms interface -------
1413

@@ -94,35 +93,55 @@
9493
slurp
9594
read-string))
9695

97-
(defn execute-migration [options]
98-
(let [{:keys [source target help check]} options
99-
src-cfg (load-config source)
100-
tgt-cfg (load-config target)
101-
src-type (:wanderung/type src-cfg)
102-
tgt-type (:wanderung/type tgt-cfg)]
103-
(cond
104-
(not (multimethod-for-dispatch-value? datoms-from-storage src-type))
105-
(println "Cannot use" src-type "as source database.")
106-
107-
(not (multimethod-for-dispatch-value? datoms-to-storage tgt-type))
108-
(println "Cannot use" tgt-type "as target database.")
109-
110-
(:wanderung/read-only? tgt-cfg)
111-
(println "Cannot migrate to read-only database.")
112-
113-
:default (do
114-
(println "➜ Start migrating from" src-type "to" tgt-type "...")
115-
(migrate src-cfg tgt-cfg)
116-
(println " ✓ Done")
117-
(when check
118-
(if (multimethod-for-dispatch-value? datoms-from-storage tgt-type)
119-
(do
120-
(println "➜ Comparing datoms between source and target...")
121-
(if (datom/similar-datoms? (datoms-from-storage src-cfg)
122-
(datoms-from-storage tgt-cfg))
123-
(println " ✓ Success: Datoms look the same.")
124-
(println "ERROR: The datoms differ between source and target.")))
125-
(println "ERROR: The target does not support reading datoms")))))))
96+
(defn help
97+
([]
98+
(help {}))
99+
([_]
100+
(println "WANDERUNG")
101+
(println "---------")
102+
(println "Run migrations with Datahike to and from various sources")
103+
(println "USAGE:")
104+
(println "clj -Twanderung [function] [function args]")
105+
(println "FUNCTIONS:")
106+
(println "---------")
107+
(println "migration :source SOURCE :target TARGET")
108+
(println "Description: Migrates from given source file to a target file.")
109+
(println "Example: clj -Twanderung migration :source '\"./source-cfg.edn\"' :target '\"target-cfg.edn\"'")
110+
(println "---------")
111+
(println "help")
112+
(println "Description: Prints this lovely help.")
113+
(println "Example: clj -Twanderung help")))
114+
115+
(defn migration [{:keys [source target check] show-help :help}]
116+
(if show-help
117+
(help)
118+
(let [src-cfg (load-config source)
119+
tgt-cfg (load-config target)
120+
src-type (:wanderung/type src-cfg)
121+
tgt-type (:wanderung/type tgt-cfg)]
122+
(cond
123+
(not (multimethod-for-dispatch-value? datoms-from-storage src-type))
124+
(println "Cannot use" src-type "as source database.")
125+
126+
(not (multimethod-for-dispatch-value? datoms-to-storage tgt-type))
127+
(println "Cannot use" tgt-type "as target database.")
128+
129+
(:wanderung/read-only? tgt-cfg)
130+
(println "Cannot migrate to read-only database.")
131+
132+
:else (do
133+
(println "➜ Start migrating from" src-type "to" tgt-type "...")
134+
(migrate src-cfg tgt-cfg)
135+
(println " ✓ Done")
136+
(when check
137+
(if (multimethod-for-dispatch-value? datoms-from-storage tgt-type)
138+
(do
139+
(println "➜ Comparing datoms between source and target...")
140+
(if (datom/similar-datoms? (datoms-from-storage src-cfg)
141+
(datoms-from-storage tgt-cfg))
142+
(println " ✓ Success: Datoms look the same.")
143+
(println "ERROR: The datoms differ between source and target.")))
144+
(println "ERROR: The target does not support reading datoms"))))))))
126145

127146
(defn -main [& args]
128147
(let [{options :options
@@ -135,4 +154,12 @@
135154
(println "Run migrations to datahike from various sources")
136155
(println "USAGE:")
137156
(println summary))
138-
(execute-migration options)))))
157+
(try
158+
(migration options)
159+
(catch Throwable t
160+
(println (.getMessage t))
161+
(when-not (instance? IExceptionInfo t)
162+
(.printStackTrace t))
163+
(System/exit 1))
164+
(finally
165+
(shutdown-agents)))))))

0 commit comments

Comments
 (0)