Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -19,3 +19,6 @@ pom.xml.asc
.lsp
.clj-kondo/.cache/
.aider*
/libs/kit-generator/test/resources/generated/
/libs/kit-generator/test/resources/modules/install-log.edn
/.clj-kondo/
39 changes: 26 additions & 13 deletions libs/kit-generator/deps.edn
Original file line number Diff line number Diff line change
@@ -1,13 +1,26 @@
{:paths ["src"]
:deps {org.clojure/clojure {:mvn/version "1.11.1"}
hato/hato {:mvn/version "1.0.0"}
selmer/selmer {:mvn/version "1.12.59"}
clj-jgit/clj-jgit {:mvn/version "1.0.2"}
org.clojure/tools.logging {:mvn/version "1.2.4"}
borkdude/rewrite-edn {:mvn/version "0.4.6"}
enlive/enlive {:mvn/version "1.1.6"}
rewrite-clj/rewrite-clj {:mvn/version "1.1.46"}
mvxcvi/cljstyle {:mvn/version "0.15.0"}
cljfmt/cljfmt {:mvn/version "0.9.2"}
clj-fuzzy/clj-fuzzy {:mvn/version "0.4.1"}
clojure-deep-merge/clojure-deep-merge {:mvn/version "0.1.2"}}}
{:paths ["src"]
:deps {org.clojure/clojure {:mvn/version "1.11.1"}
hato/hato {:mvn/version "1.0.0"}
selmer/selmer {:mvn/version "1.12.59"}
clj-jgit/clj-jgit {:mvn/version "1.0.2"}
org.clojure/tools.logging {:mvn/version "1.2.4"}
borkdude/rewrite-edn {:mvn/version "0.4.6"}
enlive/enlive {:mvn/version "1.1.6"}
rewrite-clj/rewrite-clj {:mvn/version "1.1.46"}
mvxcvi/cljstyle {:mvn/version "0.15.0"}
cljfmt/cljfmt {:mvn/version "0.9.2"}
clj-fuzzy/clj-fuzzy {:mvn/version "0.4.1"}
clojure-deep-merge/clojure-deep-merge {:mvn/version "0.1.2"}}
:aliases {:cider
{:extra-deps {nrepl/nrepl {:mvn/version "1.5.1"}
cider/cider-nrepl {:mvn/version "0.58.0"}}
:main-opts ["-m" "nrepl.cmdline" "--middleware" "[cider.nrepl/cider-middleware]" "-i"]}

:test
{:extra-paths ["test"]
:extra-deps {io.github.cognitect-labs/test-runner
{:git/tag "v0.5.1" :git/sha "dfb30dd"}
babashka/fs {:mvn/version "0.5.27"}
babashka/process {:mvn/version "0.6.23"}}
:main-opts ["-m" "cognitect.test-runner"]
:exec-fn cognitect.test-runner.api/test}}}
135 changes: 96 additions & 39 deletions libs/kit-generator/src/kit/api.clj
Original file line number Diff line number Diff line change
@@ -1,53 +1,108 @@
(ns kit.api
(:require
[clojure.string :as string]
[kit.generator.modules.generator :as generator]
[kit.generator.modules.dependencies :as deps]
[clojure.string :as str]
[kit.generator.io :as io]
[kit.generator.modules :as modules]
[kit.generator.modules.dependencies :as deps]
[kit.generator.modules.generator :as generator]
[kit.generator.snippets :as snippets]
[kit.generator.io :as io]))
[clojure.test :as t]))

;; TODO: Add docstrings

(defn read-ctx
([] (read-ctx nil))
([path]
(-> (or path "kit.edn")
(slurp)
(io/str->edn))))
(defn- read-ctx
[path]
(assert (not (str/blank? path)))
(-> path
(slurp)
(io/str->edn)))

(defn- log-install-dependency [module-key feature-flag deps]
(print "Installing module" module-key)

(when-let [extras (not-empty (cond-> []
(not= :default feature-flag) (conj (str " - feature flag:" feature-flag))
(seq deps) (conj (str " - requires:" (str/join ",")))))]
(print (str "(" (str/join "; " extras) ")"))))

(defn- log-missing-module [module-key]
(println "ERROR: no module found with name:" module-key))

(defn- install-dependency
"Installs a module and its dependencies recursively. Asumes ctx has loaded :modules.
Note that `opts` have a different schema than the one passed to `install-module`,
the latter being preserved for backwards compatibility. Here `opts` is a map of
module-key to module-specific options.

(defn sync-modules []
(modules/sync-modules! (read-ctx))
For example, let's say `:html` is the main module. It would still be on the same level
as `:auth`, its dependency:

```clojure
{:html {:feature-flag :default}
:auth {:feature-flag :oauth}}
```

See flat-module-options for more details."
[{:keys [modules] :as ctx} module-key opts]
(if (modules/module-exists? ctx module-key)
(let [{:keys [module-config]} (generator/read-module-config ctx modules module-key)
{:keys [feature-flag] :or {feature-flag :default} :as module-opts} (get opts module-key {})
deps (deps/resolve-dependencies module-config feature-flag)]
(log-install-dependency module-key feature-flag deps)
(doseq [module-key deps]
(install-dependency ctx module-key opts))
(generator/generate ctx module-key module-opts))
(log-missing-module module-key))
:done)

(defn list-modules []
(let [ctx (modules/load-modules (read-ctx))]
(modules/list-modules ctx))
(defn- flat-module-options
"Converts options map passed to install-module into a flat map
of module-key to module-specific options."
{:test (fn []
(t/are [opts module-key output] (flat-module-options opts module-key)
{} :meta {}
{:feature-flag :extras} :meta {:meta {:feature-flag :extras}}
{:feature-flag :extras
:kit/cljs {:feature-flag :advanced}} :meta {:meta {:feature-flag :extras}
:kit/cljs {:feature-flag :advanced}}))}
[opts module-key]
(let [supported-module-options [:feature-flag]]
(as-> opts $
{module-key (select-keys $ supported-module-options)}
(merge opts $)
(apply dissoc $ supported-module-options))))

(defn sync-modules
"Downloads modules for the current project."
[]
(modules/sync-modules! (read-ctx "kit-edn"))
:done)

(declare install-module)
(defn install-dependency [module-key]
(if (vector? module-key)
(apply install-module module-key)
(install-module module-key)))
(defn list-modules
"List modules available for the current project."
[]
(let [ctx (modules/load-modules (read-ctx "kit.edn"))]
(modules/list-modules ctx))
:done)

(defn install-module
"Installs a kit module into the current project or the project specified by a
path to kit.edn file.

> NOTE: When adding new options, update flat-module-options."
([module-key]
(install-module module-key {:feature-flag :default}))
([module-key {:keys [feature-flag] :as opts}]
(let [{:keys [modules] :as ctx} (modules/load-modules (read-ctx))]
(if (modules/module-exists? ctx module-key)
(let [module-config (generator/read-module-config ctx modules module-key)
deps (deps/resolve-dependencies module-config feature-flag)]
(println module-key "requires following modules:" deps)
(doseq [module-key deps]
(install-dependency module-key))
(generator/generate ctx module-key opts))
(println "no module found with name:" module-key))
:done)))

(defn list-installed-modules []
(doseq [[id status] (-> (read-ctx)
([module-key opts]
(install-module module-key "kit.edn" opts))
([module-key kit-edn-path opts]
(let [ctx (modules/load-modules (read-ctx kit-edn-path))]
(install-dependency ctx module-key (flat-module-options opts module-key)))))

(defn list-installed-modules
"Lists installed modules and modules that failed to install, for the current
project."
[]
(doseq [[id status] (-> (read-ctx "kit.edn")
:modules
:root
(generator/read-modules-log))]
Expand All @@ -64,23 +119,25 @@
@db))))

(defn sync-snippets []
(let [ctx (read-ctx)]
(let [ctx (read-ctx "kit.edn")]
(snippets/sync-snippets! ctx)
(snippets-db ctx true)
:done))

(defn find-snippets [query]
(snippets/print-snippets (snippets-db (read-ctx)) query)
(snippets/print-snippets (snippets-db (read-ctx "kit.edn")) query)
:done)

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

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

(defn snippet [id & args]
(snippets/gen-snippet (snippets-db (read-ctx)) id args))
(snippets/gen-snippet (snippets-db (read-ctx "kit.edn")) id args))

(comment
(t/run-tests 'kit.api))
21 changes: 11 additions & 10 deletions libs/kit-generator/src/kit/generator/modules.clj
Original file line number Diff line number Diff line change
@@ -1,9 +1,10 @@
(ns kit.generator.modules
(:require
[clojure.java.io :as jio]
[kit.generator.git :as git]
[kit.generator.io :as io])
(:import java.io.File))
[clojure.java.io :as jio]
[deep.merge :as deep-merge]
[kit.generator.git :as git])
(:import
java.io.File))

(defn sync-modules!
"Clones or pulls modules from git repositories.
Expand All @@ -18,18 +19,18 @@
[{:keys [modules]}]
(doseq [{:keys [name url] :as repository} (-> modules :repositories)]
(git/sync-repository!
(:root modules)
repository)))
(:root modules)
repository)))

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

(defn set-module-paths [root {:keys [module-root modules]}]
(reduce
(fn [modules [id config]]
(assoc modules id (set-module-path config (str root File/separator module-root))))
{}
modules))
(fn [modules [id config]]
(assoc modules id (set-module-path config (str root File/separator module-root))))
{}
modules))

(defn load-modules [{:keys [modules] :as ctx}]
(let [root (:root modules)]
Expand Down
Loading