|
1 | 1 | (ns kit.api |
2 | 2 | (: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] |
6 | 5 | [kit.generator.modules :as modules] |
| 6 | + [kit.generator.modules.dependencies :as deps] |
| 7 | + [kit.generator.modules.generator :as generator] |
7 | 8 | [kit.generator.snippets :as snippets] |
8 | | - [kit.generator.io :as io])) |
| 9 | + [clojure.test :as t])) |
9 | 10 |
|
10 | 11 | ;; TODO: Add docstrings |
11 | 12 |
|
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. |
18 | 36 |
|
19 | | -(defn sync-modules [] |
20 | | - (modules/sync-modules! (read-ctx)) |
| 37 | + For example, let's say `:html` is the main module. It would still be on the same level |
| 38 | + as `:auth`, its dependency: |
| 39 | +
|
| 40 | + ```clojure |
| 41 | + {:html {:feature-flag :default} |
| 42 | + :auth {:feature-flag :oauth}} |
| 43 | + ``` |
| 44 | +
|
| 45 | + See flat-module-options for more details." |
| 46 | + [{:keys [modules] :as ctx} module-key opts] |
| 47 | + (if (modules/module-exists? ctx module-key) |
| 48 | + (let [{:keys [module-config]} (generator/read-module-config ctx modules module-key) |
| 49 | + {:keys [feature-flag] :or {feature-flag :default} :as module-opts} (get opts module-key {}) |
| 50 | + deps (deps/resolve-dependencies module-config feature-flag)] |
| 51 | + (log-install-dependency module-key feature-flag deps) |
| 52 | + (doseq [module-key deps] |
| 53 | + (install-dependency ctx module-key opts)) |
| 54 | + (generator/generate ctx module-key module-opts)) |
| 55 | + (log-missing-module module-key)) |
21 | 56 | :done) |
22 | 57 |
|
23 | | -(defn list-modules [] |
24 | | - (let [ctx (modules/load-modules (read-ctx))] |
25 | | - (modules/list-modules ctx)) |
| 58 | +(defn- flat-module-options |
| 59 | + "Converts options map passed to install-module into a flat map |
| 60 | + of module-key to module-specific options." |
| 61 | + {:test (fn [] |
| 62 | + (t/are [opts module-key output] (flat-module-options opts module-key) |
| 63 | + {} :meta {} |
| 64 | + {:feature-flag :extras} :meta {:meta {:feature-flag :extras}} |
| 65 | + {:feature-flag :extras |
| 66 | + :kit/cljs {:feature-flag :advanced}} :meta {:meta {:feature-flag :extras} |
| 67 | + :kit/cljs {:feature-flag :advanced}}))} |
| 68 | + [opts module-key] |
| 69 | + (let [supported-module-options [:feature-flag]] |
| 70 | + (as-> opts $ |
| 71 | + {module-key (select-keys $ supported-module-options)} |
| 72 | + (merge opts $) |
| 73 | + (apply dissoc $ supported-module-options)))) |
| 74 | + |
| 75 | +(defn sync-modules |
| 76 | + "Downloads modules for the current project." |
| 77 | + [] |
| 78 | + (modules/sync-modules! (read-ctx "kit-edn")) |
26 | 79 | :done) |
27 | 80 |
|
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))) |
| 81 | +(defn list-modules |
| 82 | + "List modules available for the current project." |
| 83 | + [] |
| 84 | + (let [ctx (modules/load-modules (read-ctx "kit.edn"))] |
| 85 | + (modules/list-modules ctx)) |
| 86 | + :done) |
33 | 87 |
|
34 | 88 | (defn install-module |
| 89 | + "Installs a kit module into the current project or the project specified by a |
| 90 | + path to kit.edn file. |
| 91 | +
|
| 92 | + > NOTE: When adding new options, update flat-module-options." |
35 | 93 | ([module-key] |
36 | 94 | (install-module module-key {:feature-flag :default})) |
37 | | - ([module-key {:keys [feature-flag] :as opts}] |
38 | | - (let [{:keys [modules] :as ctx} (modules/load-modules (read-ctx))] |
39 | | - (if (modules/module-exists? ctx module-key) |
40 | | - (let [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) |
| 95 | + ([module-key opts] |
| 96 | + (install-module module-key "kit.edn" opts)) |
| 97 | + ([module-key kit-edn-path opts] |
| 98 | + (let [ctx (modules/load-modules (read-ctx kit-edn-path))] |
| 99 | + (install-dependency ctx module-key (flat-module-options opts module-key))))) |
| 100 | + |
| 101 | +(defn list-installed-modules |
| 102 | + "Lists installed modules and modules that failed to install, for the current |
| 103 | + project." |
| 104 | + [] |
| 105 | + (doseq [[id status] (-> (read-ctx "kit.edn") |
51 | 106 | :modules |
52 | 107 | :root |
53 | 108 | (generator/read-modules-log))] |
|
64 | 119 | @db)))) |
65 | 120 |
|
66 | 121 | (defn sync-snippets [] |
67 | | - (let [ctx (read-ctx)] |
| 122 | + (let [ctx (read-ctx "kit.edn")] |
68 | 123 | (snippets/sync-snippets! ctx) |
69 | 124 | (snippets-db ctx true) |
70 | 125 | :done)) |
71 | 126 |
|
72 | 127 | (defn find-snippets [query] |
73 | | - (snippets/print-snippets (snippets-db (read-ctx)) query) |
| 128 | + (snippets/print-snippets (snippets-db (read-ctx "kit.edn")) query) |
74 | 129 | :done) |
75 | 130 |
|
76 | 131 | (defn find-snippet-ids [query] |
77 | | - (println (string/join ", " (map :id (snippets/match-snippets (snippets-db (read-ctx)) query)))) |
| 132 | + (println (str/join ", " (map :id (snippets/match-snippets (snippets-db (read-ctx "kit.edn")) query)))) |
78 | 133 | :done) |
79 | 134 |
|
80 | 135 | (defn list-snippets [] |
81 | | - (println (string/join "\n" (keys (snippets-db (read-ctx))))) |
| 136 | + (println (str/join "\n" (keys (snippets-db (read-ctx "kit.edn"))))) |
82 | 137 | :done) |
83 | 138 |
|
84 | 139 | (defn snippet [id & args] |
85 | | - (snippets/gen-snippet (snippets-db (read-ctx)) id args)) |
| 140 | + (snippets/gen-snippet (snippets-db (read-ctx "kit.edn")) id args)) |
86 | 141 |
|
| 142 | +(comment |
| 143 | + (t/run-tests 'kit.api)) |
0 commit comments