Skip to content

Commit 01545de

Browse files
committed
options for dependencies
<!-- ps-id: bc69715d-8c9e-4bfe-9aec-bb348c037204 -->
1 parent 0aa2493 commit 01545de

File tree

13 files changed

+185
-90
lines changed

13 files changed

+185
-90
lines changed

libs/kit-generator/src/kit/api.clj

Lines changed: 91 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -1,53 +1,102 @@
11
(ns kit.api
22
(:require
3-
[clojure.string :as string]
4-
[kit.generator.modules.generator :as generator]
5-
[kit.generator.modules.dependencies :as deps]
3+
[clojure.string :as str]
4+
[kit.generator.io :as io]
65
[kit.generator.modules :as modules]
6+
[kit.generator.modules.dependencies :as deps]
7+
[kit.generator.modules.generator :as generator]
78
[kit.generator.snippets :as snippets]
8-
[kit.generator.io :as io]))
9+
[clojure.test :as t]))
910

1011
;; TODO: Add docstrings
1112

12-
(defn read-ctx
13-
([] (read-ctx nil))
14-
([path]
15-
(-> (or path "kit.edn")
16-
(slurp)
17-
(io/str->edn))))
13+
(defn- read-ctx
14+
[path]
15+
(assert (not (str/blank? path)))
16+
(-> path
17+
(slurp)
18+
(io/str->edn)))
19+
20+
(defn- log-install-dependency [module-key feature-flag deps]
21+
(print "Installing module" module-key)
22+
23+
(when-let [extras (not-empty (cond-> []
24+
(not= :default feature-flag) (conj (str " - feature flag:" feature-flag))
25+
(seq deps) (conj (str " - requires:" (str/join ",")))))]
26+
(print (str "(" (str/join "; " extras) ")"))))
27+
28+
(defn- log-missing-module [module-key]
29+
(println "ERROR: no module found with name:" module-key))
30+
31+
(defn- install-dependency
32+
"Installs a module and its dependencies recursively. Asumes ctx has loaded :modules.
33+
Note that `opts` have a different schema than the one passed to `install-module`,
34+
the latter being preserved for backwards compatibility. Here `opts` is a map of
35+
module-key to module-specific options. For example:
1836
19-
(defn sync-modules []
20-
(modules/sync-modules! (read-ctx))
37+
{:html {:feature-flag :default}
38+
:auth {:feature-flag :oauth}}"
39+
[{:keys [modules] :as ctx} module-key opts]
40+
(if (modules/module-exists? ctx module-key)
41+
(let [{:keys [module-config]} (generator/read-module-config ctx modules module-key)
42+
{:keys [feature-flag] :or {feature-flag :default} :as module-opts} (get opts module-key {})
43+
deps (deps/resolve-dependencies module-config feature-flag)]
44+
(log-install-dependency module-key feature-flag deps)
45+
(doseq [module-key deps]
46+
(install-dependency ctx module-key opts))
47+
(generator/generate ctx module-key module-opts))
48+
(log-missing-module module-key))
2149
:done)
2250

23-
(defn list-modules []
24-
(let [ctx (modules/load-modules (read-ctx))]
25-
(modules/list-modules ctx))
51+
(defn- flat-module-options
52+
"Converts options map passed to install-module into a flat map
53+
of module-key to module-specific options."
54+
{:test (fn []
55+
(t/are [opts module-key output] (flat-module-options opts module-key)
56+
{} :meta {}
57+
{:feature-flag :extras} :meta {:meta {:feature-flag :extras}}
58+
{:feature-flag :extras
59+
:kit/cljs {:feature-flag :advanced}} :meta
60+
{:meta {:feature-flag :extras}
61+
:kit/cljs {:feature-flag :advanced}}))}
62+
[opts module-key]
63+
(let [supported-module-options [:feature-flag]]
64+
(as-> opts $
65+
{module-key (select-keys $ supported-module-options)}
66+
(merge opts $)
67+
(apply dissoc $ supported-module-options))))
68+
69+
(defn sync-modules
70+
"Downloads modules for the current project."
71+
[]
72+
(modules/sync-modules! (read-ctx "kit-edn"))
2673
:done)
2774

28-
(declare install-module)
29-
(defn install-dependency [module-key]
30-
(if (vector? module-key)
31-
(apply install-module module-key)
32-
(install-module module-key)))
75+
(defn list-modules
76+
"List modules available for the current project."
77+
[]
78+
(let [ctx (modules/load-modules (read-ctx "kit.edn"))]
79+
(modules/list-modules ctx))
80+
:done)
3381

3482
(defn install-module
83+
"Installs a kit module into the current project or the project specified by a
84+
path to kit.edn file.
85+
86+
NOTE: When adding new options, update flat-module-options."
3587
([module-key]
3688
(install-module module-key {:feature-flag :default}))
37-
([module-key {:keys [feature-flag kit-edn-path] :or {kit-edn-path "kit.edn"} :as opts}]
38-
(let [{:keys [modules] :as ctx} (modules/load-modules (read-ctx kit-edn-path))]
39-
(if (modules/module-exists? ctx module-key)
40-
(let [{:keys [module-config]} (generator/read-module-config ctx modules module-key)
41-
deps (deps/resolve-dependencies module-config feature-flag)]
42-
(println module-key "requires following modules:" deps)
43-
(doseq [module-key deps]
44-
(install-dependency module-key))
45-
(generator/generate ctx module-key opts))
46-
(println "no module found with name:" module-key))
47-
:done)))
48-
49-
(defn list-installed-modules []
50-
(doseq [[id status] (-> (read-ctx)
89+
([module-key opts]
90+
(install-module module-key "kit.edn" opts))
91+
([module-key kit-edn-path opts]
92+
(let [ctx (modules/load-modules (read-ctx kit-edn-path))]
93+
(install-dependency ctx module-key (flat-module-options opts module-key)))))
94+
95+
(defn list-installed-modules
96+
"Lists installed modules and modules that failed to install, for the current
97+
project."
98+
[]
99+
(doseq [[id status] (-> (read-ctx "kit.edn")
51100
:modules
52101
:root
53102
(generator/read-modules-log))]
@@ -64,22 +113,25 @@
64113
@db))))
65114

66115
(defn sync-snippets []
67-
(let [ctx (read-ctx)]
116+
(let [ctx (read-ctx "kit.edn")]
68117
(snippets/sync-snippets! ctx)
69118
(snippets-db ctx true)
70119
:done))
71120

72121
(defn find-snippets [query]
73-
(snippets/print-snippets (snippets-db (read-ctx)) query)
122+
(snippets/print-snippets (snippets-db (read-ctx "kit.edn")) query)
74123
:done)
75124

76125
(defn find-snippet-ids [query]
77-
(println (string/join ", " (map :id (snippets/match-snippets (snippets-db (read-ctx)) query))))
126+
(println (str/join ", " (map :id (snippets/match-snippets (snippets-db (read-ctx "kit.edn")) query))))
78127
:done)
79128

80129
(defn list-snippets []
81-
(println (string/join "\n" (keys (snippets-db (read-ctx)))))
130+
(println (str/join "\n" (keys (snippets-db (read-ctx "kit.edn")))))
82131
:done)
83132

84133
(defn snippet [id & args]
85-
(snippets/gen-snippet (snippets-db (read-ctx)) id args))
134+
(snippets/gen-snippet (snippets-db (read-ctx "kit.edn")) id args))
135+
136+
(comment
137+
(t/run-tests 'kit.api))

libs/kit-generator/src/kit/generator/modules.clj

Lines changed: 11 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,10 @@
11
(ns kit.generator.modules
22
(:require
3-
[clojure.java.io :as jio]
4-
[kit.generator.git :as git]
5-
[kit.generator.io :as io])
6-
(:import java.io.File))
3+
[clojure.java.io :as jio]
4+
[deep.merge :as deep-merge]
5+
[kit.generator.git :as git])
6+
(:import
7+
java.io.File))
78

89
(defn sync-modules!
910
"Clones or pulls modules from git repositories.
@@ -18,18 +19,18 @@
1819
[{:keys [modules]}]
1920
(doseq [{:keys [name url] :as repository} (-> modules :repositories)]
2021
(git/sync-repository!
21-
(:root modules)
22-
repository)))
22+
(:root modules)
23+
repository)))
2324

2425
(defn set-module-path [module-config base-path]
2526
(update module-config :path #(str base-path File/separator %)))
2627

2728
(defn set-module-paths [root {:keys [module-root modules]}]
2829
(reduce
29-
(fn [modules [id config]]
30-
(assoc modules id (set-module-path config (str root File/separator module-root))))
31-
{}
32-
modules))
30+
(fn [modules [id config]]
31+
(assoc modules id (set-module-path config (str root File/separator module-root))))
32+
{}
33+
modules))
3334

3435
(defn load-modules [{:keys [modules] :as ctx}]
3536
(let [root (:root modules)]

libs/kit-generator/src/kit/generator/modules/generator.clj

Lines changed: 8 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,7 @@
4040
(defn write-asset [asset path force?]
4141
(jio/make-parents path)
4242
(if (and (.exists (jio/file path)) (not force?))
43-
(println "asset already exists:" path)
43+
(println "WARNING: Asset already exists:" path)
4444
((if (string? asset) write-string write-binary) asset path)))
4545

4646
(defmulti handle-action (fn [_ [id]] id))
@@ -63,13 +63,13 @@
6363
(renderer/render-template ctx target-path)
6464
force?))
6565
:else
66-
(println "unrecognized asset type:" asset))))
66+
(println "ERROR: Unrecognized asset type:" asset))))
6767

6868
(defmethod handle-action :injections [ctx [_ injections]]
6969
(ij/inject-data ctx injections))
7070

7171
(defmethod handle-action :default [_ [id]]
72-
(println "undefined action:" id))
72+
(println "ERROR: Undefined action:" id))
7373

7474
(defn- render-module-config [ctx module-path]
7575
(some->> (str module-path File/separator "config.edn")
@@ -106,7 +106,6 @@
106106
[edn-config {:keys [feature-requires] :as config}]
107107
(if (some? feature-requires)
108108
(do
109-
(println "applying features to config:" feature-requires)
110109
(apply deep-merge/concat-merge
111110
(conj (mapv #(get-throw-on-not-found edn-config %) feature-requires)
112111
config)))
@@ -117,7 +116,7 @@
117116
(let [modules-root (:root modules)
118117
module-log (read-modules-log modules-root)]
119118
(if (= :success (module-log module-key))
120-
(println "module" module-key "is already installed!")
119+
(println "WARNING: Module" module-key "is already installed!")
121120
(try
122121
(let [{:keys [module-path module-config config-str]} (read-module-config ctx modules module-key)
123122
ctx (assoc ctx :module-path module-path)
@@ -126,12 +125,12 @@
126125
(cond
127126
(nil? module-config)
128127
(do
129-
(println "module" module-key "not found, available modules:")
128+
(println "ERROR: Module" module-key "not found, available modules:")
130129
(pprint (modules/list-modules ctx)))
131130

132131
(nil? config)
133132
(do
134-
(println "feature" feature-flag "not found for module" module-key ", available features:")
133+
(println "ERROR: Feature" feature-flag "not found for module" module-key ", available features:")
135134
(pprint (keys module-config)))
136135

137136
:else
@@ -141,11 +140,11 @@
141140
(handle-action ctx action))
142141
(write-modules-log modules-root (assoc module-log module-key :success))
143142
(println (or success-message
144-
(str module-key " installed successfully!")))
143+
(str "Module " module-key " installed successfully!")))
145144
(when require-restart?
146145
(println "restart required!")))))
147146
(catch Exception e
148-
(println "failed to install module" module-key)
147+
(println "ERROR: Failed to install module" module-key)
149148
(write-modules-log modules-root (assoc module-log module-key :error))
150149
(.printStackTrace e))))))
151150

libs/kit-generator/test/kit_generator/core_test.clj

Lines changed: 41 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
(ns kit-generator.core-test
22
(:require
33
[clojure.string :as str]
4-
[clojure.test :refer [deftest is testing]]
4+
[clojure.test :refer [deftest is testing are]]
55
[kit-generator.generator-test]
66
[kit-generator.injections]
77
[kit-generator.io :as io]
@@ -39,26 +39,44 @@
3939
(io/write-edn ctx kit-edn-path)
4040
kit-edn-path))
4141

42-
(deftest test-install-module
43-
(testing "installing a module"
44-
(let [kit-edn-path (prepare-project)]
45-
(is (not (module-installed? :meta)))
46-
(is (= :done (kit/install-module :meta {:kit-edn-path kit-edn-path})))
47-
(is (module-installed? :meta))
48-
(is (empty? (io/folder-mismatches project-root
49-
{"resources/public/css/styles.css" []
50-
"resources/public/css/app.css" []
51-
"kit.edn" []}
52-
{:filter #(not (str/starts-with? % "modules/"))}))))))
42+
(defn test-install-module*
43+
[module-key opts expected-files]
44+
(let [kit-edn-path (prepare-project)]
45+
(is (not (module-installed? module-key)))
46+
(is (= :done (kit/install-module module-key kit-edn-path opts)))
47+
(is (module-installed? module-key))
48+
(is (empty? (io/folder-mismatches project-root
49+
expected-files
50+
{:filter #(not (str/starts-with? % "modules/"))})))))
5351

54-
(deftest test-install-module-with-feature-flag
55-
(testing "installing a module with a feature flag"
56-
(let [kit-edn-path (prepare-project)]
57-
(is (not (module-installed? :meta)))
58-
(is (= :done (kit/install-module :meta {:feature-flag :extras
59-
:kit-edn-path kit-edn-path})))
60-
(is (module-installed? :meta))
61-
(is (empty? (io/folder-mismatches project-root
62-
{"resources/public/css/styles.css" []
63-
"kit.edn" []}
64-
{:filter #(not (str/starts-with? % "modules/"))}))))))
52+
(deftest test-install-meta-module
53+
(are [module-key opts expected-files] (test-install-module* module-key opts expected-files)
54+
:meta {} {"resources/public/css/app.css" []
55+
"kit.edn" []}
56+
:meta {:feature-flag :extras} {"resources/public/css/styles.css" []
57+
"src/clj/myapp/db.clj" []
58+
"kit.edn" []}
59+
:meta {:feature-flag :full} {"resources/public/css/app.css" []
60+
"resources/public/css/styles.css" []
61+
"src/clj/myapp/db.clj" []
62+
"kit.edn" []}
63+
:meta {:feature-flag :extras
64+
:db {:feature-flag :postgres}} {"resources/public/css/styles.css" []
65+
"src/clj/myapp/db.clj" []
66+
"src/clj/myapp/db/postgres.clj" []
67+
"kit.edn" []}
68+
:meta {:feature-flag :extras
69+
:db {:feature-flag :migrations}} {"resources/public/css/styles.css" []
70+
"src/clj/myapp/db.clj" []
71+
"src/clj/myapp/db/postgres.clj" []
72+
"src/clj/myapp/db/migratus.clj" []
73+
"src/clj/myapp/db/migrations/001.clj" []
74+
"kit.edn" []}
75+
76+
;;
77+
))
78+
79+
;; TODO: Should feature-requires be transient? If so, add tests for that.
80+
81+
(comment
82+
(clojure.test/run-tests 'kit-generator.core-test))

libs/kit-generator/test/resources/modules/kit/cljs/config.edn

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -15,11 +15,11 @@
1515
:action :append
1616
:target [:body]
1717
:value [:script {:src "/js/app.js"}]}
18-
{:type :edn
19-
:path "deps.edn"
20-
:target [:paths]
21-
:action :append
22-
:value "target/classes/cljsbuild"}
18+
{:type :edn
19+
:path "deps.edn"
20+
:target [:paths]
21+
:action :append
22+
:value "target/classes/cljsbuild"}
2323
{:type :clj
2424
:path "build.clj"
2525
:action :append-requires
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
(ns resources.modules.kit.db.assets.db)
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
(ns resources.modules.kit.db.assets.migrations.001)
2+
3+
;; First migration
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
(ns resources.modules.kit.db.assets.postgres)
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
{:default {:actions
2+
{:assets [["assets/db.clj" "test/resources/generated/src/clj/<<sanitized>>/db.clj"]]}}
3+
:postgres {:actions
4+
{:assets [["assets/postgres.clj" "test/resources/generated/src/clj/<<sanitized>>/db/postgres.clj"]]}
5+
:feature-requires [:default]}
6+
:migrations {:actions
7+
{:assets [["assets/migrations/001.clj" "test/resources/generated/src/clj/<<sanitized>>/db/migrations/001.clj"]]}
8+
:requires [:migratus]
9+
:feature-requires [:postgres :default]}}

0 commit comments

Comments
 (0)