Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: kmono workspace #26

Merged
merged 4 commits into from
May 21, 2024
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
2 changes: 1 addition & 1 deletion justfile
Original file line number Diff line number Diff line change
Expand Up @@ -34,4 +34,4 @@ test:
clojure -M:test -m "kaocha.runner"

repl *ARGS:
clojure -M:kmono{{ ARGS }} repl -P ':*/test' -l -v
clojure -M:kmono:test{{ ARGS }} repl
2 changes: 1 addition & 1 deletion src/k16/kmono/ansi.clj
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@
[v msg]
(when-not v
(println ERROR_PREFIX msg)
(System/exit 1)))
(throw (ex-info msg {:type :errors/assertion}))))

(defn print-raw
[output]
Expand Down
42 changes: 28 additions & 14 deletions src/k16/kmono/api.clj
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,16 @@
[malli.core :as m]
[malli.transform :as mt]))

(defmacro with-assertion-error
[& body]
`(try
~@body
(catch clojure.lang.ExceptionInfo ex#
(let [data# (ex-data ex#)]
(when-not (= :errors/assertion (:type data#))
(ansi/print-error (ex-message ex#)))
(System/exit 1)))))

(defn- print-stage-results
[stage-results]
(doseq [stage-result stage-results]
Expand Down Expand Up @@ -115,9 +125,9 @@
opts)
{:keys [repo-root glob exec]
:as run-params} (m/decode ?RunOpts opts' mt/default-value-transformer)
config (-> run-params
(merge (config/load-config repo-root glob))
(config/validate-config!))
config (->> run-params
(merge (config/load-config repo-root glob))
(config/validate-config!))
changes (git/scan-for-changes config)
_ (ansi/assert-err! (seq (:build-order config)) "no packages to execute found")]
(case exec
Expand All @@ -128,10 +138,11 @@
(defn run
([opts] (run opts nil))
([opts arguments]
(let [[success?] (-run opts arguments)]
(if success?
(System/exit 0)
(System/exit 1)))))
(with-assertion-error
(let [[success?] (-run opts arguments)]
(if success?
(System/exit 0)
(System/exit 1))))))

(defn- relativize-to-repo-root
[repo-root path]
Expand All @@ -144,23 +155,26 @@
([opts]
(repl opts nil))
([{:keys [repo-root cp-file configure-lsp?] :as opts} _]
(let [cp-file' (when configure-lsp?
(or (relativize-to-repo-root repo-root cp-file)
(relativize-to-repo-root repo-root ".lsp/.kmonocp")))
opts' (assoc opts :cp-file (str cp-file'))]
(repl.deps/run-repl opts'))))
(with-assertion-error
(let [cp-file' (when configure-lsp?
(or (relativize-to-repo-root repo-root cp-file)
(relativize-to-repo-root repo-root ".lsp/.kmonocp")))
opts' (assoc opts :cp-file (str cp-file'))]
(repl.deps/run-repl opts')))))

(defn generate-classpath!
([opts]
(generate-classpath! opts nil))
([opts _]
(binding [ansi/*logs-enabled* (:cp-file opts)]
(repl.deps/generate-classpath! opts))))
(with-assertion-error
(repl.deps/generate-classpath! opts)))))

(defn generate-deps!
([opts]
(generate-deps! opts nil))
([opts _]
(binding [ansi/*logs-enabled* (:deps-file opts)]
(repl.deps/generate-deps! opts))))
(with-assertion-error
(repl.deps/generate-deps! opts)))))

101 changes: 69 additions & 32 deletions src/k16/kmono/config.clj
Original file line number Diff line number Diff line change
Expand Up @@ -10,60 +10,96 @@
[k16.kmono.ansi :as ansi]
[k16.kmono.config-schema :as schema]
[k16.kmono.git :as git]
[k16.kmono.util :as util]
[malli.core :as m]
[malli.error :as me]))
[malli.error :as me]
[malli.transform :as mt]))

(defn- read-workspace-config
[repo-root deps-file]
(let [wp-deps-file (fs/file repo-root deps-file)]
(some-> (when (fs/exists? wp-deps-file)
(util/read-deps-edn! wp-deps-file))
(select-keys [:kmono/workspace :kmono/config]))))

(defn get-workspace-config
[repo-root]
(let [kmono-props (read-workspace-config repo-root "deps.edn")
kmono-props-local (read-workspace-config repo-root "deps.local.edn")
kmono-merged-props (merge-with merge kmono-props kmono-props-local)
workspace-config (:kmono/workspace kmono-merged-props)]
(when (seq workspace-config)
(ansi/assert-err!
(not (seq (:kmono/config kmono-merged-props)))
"Both `:kmono/config` and `:kmono/workspace can't be set")
(schema/assert-schema!
schema/?KmonoWorkspaceConfig "Workspace config error" workspace-config))
(m/encode schema/?KmonoWorkspaceConfig (or workspace-config {})
(mt/default-value-transformer
{::mt/add-optional-keys true}))))

(defn get-adapter
[pkg-dir]
(or (kmono.edn/->adapter (fs/file pkg-dir))
(clj.deps/->adapter (fs/file pkg-dir))))

(defn- assert-schema!
[?schema value]
(assert (m/validate ?schema value)
(me/humanize (m/explain ?schema value)))
value)

(defn validate-config!
[config]
(assert-schema! schema/?Config config))
(schema/assert-schema! schema/?Config config))

(defn- create-package-config [repo-root glob package-dir]
(defn- read-package-config
[workspace-config package-dir]
(when-let [adapter (get-adapter package-dir)]
(let [git-repo? (git/git-initialzied? repo-root)
kb-pkg-config (->> (adapter/get-kmono-config adapter)
(assert-schema! schema/?KmonoPackageConfig))
artifact (or (:artifact kb-pkg-config)
(let [derived-fields (cond-> (select-keys workspace-config
[:group :build-cmd :release-cmd])
:always (assoc :dir (str package-dir)
:adapter adapter))]
(some->> (adapter/get-kmono-config adapter)
(merge derived-fields)
(schema/assert-schema! schema/?KmonoPackageConfig
"Package config init error")))))

(defn- create-package-config
[repo-root glob {:keys [adapter] :as pkg-config}]
(when pkg-config
(let [package-dir (:dir pkg-config)
git-repo? (git/git-initialzied? repo-root)
artifact (or (:artifact pkg-config)
(symbol (fs/file-name package-dir)))
pkg-name (str (:group kb-pkg-config) "/" artifact)
pkg-name (str (:group pkg-config) "/" artifact)
root-package? (fs/same-file? repo-root package-dir)
exclusions (when root-package?
(str ":!:" glob))
pkg-commit-sha (or (when git-repo?
(git/subdir-commit-sha exclusions package-dir))
"untracked")
pkg-config (merge kb-pkg-config
{:artifact (or (:artifact kb-pkg-config)
pkg-config (merge pkg-config
{:artifact (or (:artifact pkg-config)
(symbol (fs/file-name package-dir)))
:name pkg-name
:commit-sha pkg-commit-sha
:root-package? root-package?
:adapter adapter
:dir (str package-dir)})]

:root-package? root-package?})]
(->> (assoc pkg-config :depends-on (adapter/get-managed-deps adapter))
(assert-schema! schema/?Package)))))
(schema/assert-schema! schema/?Package "Package config init error")))))

(defn- create-config
[repo-root glob]
(let [package-dirs (conj (fs/glob repo-root glob)
(let [workspace-config (get-workspace-config repo-root)
glob' (or glob (:glob workspace-config))
package-dirs (conj (fs/glob repo-root glob')
(-> (fs/path repo-root)
(fs/normalize)
(fs/absolutize)))]
{:packages (->> package-dirs
(map (partial create-package-config repo-root glob))
(remove nil?)
vec)}))
(merge
workspace-config
{:glob glob'
:repo-root repo-root
:packages (into []
(comp
(map (partial read-package-config workspace-config))
(map (partial create-package-config repo-root glob'))
(remove nil?))
package-dirs)})))

(defn create-graph
{:malli/schema [:=> [:cat schema/?Packages] schema/?Graph]}
Expand Down Expand Up @@ -156,10 +192,11 @@
(let [graph (create-graph packages)]
(assert-missing-deps! graph)
(assert-cycles! graph)
{:repo-root repo-root
:glob glob
:packages packages
:package-map (->pkg-map packages)
:graph graph
:build-order (parallel-topo-sort graph)})))))
(merge config {:package-map (->pkg-map packages)
:graph graph
:build-order (parallel-topo-sort graph)}))))))

(comment
(get-workspace-config ".")
(load-config "." nil)
nil)
65 changes: 53 additions & 12 deletions src/k16/kmono/config_schema.clj
Original file line number Diff line number Diff line change
@@ -1,7 +1,35 @@
(ns k16.kmono.config-schema
(:require
[clojure.pprint :as pp]
[k16.kmono.ansi :as ansi]
[malli.core :as m]
[malli.error :as me]
[malli.util :as mu]))

(def ?CommandConfig
[:map
[:glob {:optional true
:default "packages/*"}
:string]
[:snapshot? {:optional true
:default true}
:boolean]
[:include-unchanged? {:optional true
:default true}
:boolean]
[:main-aliases {:optional true}
[:vector :keyword]]
[:aliases {:optional true}
[:vector :keyword]]
[:package-aliases {:optional true}
[:vector :keyword]]])

(def ?KmonoWorkspaceConfig
(mu/merge ?CommandConfig
[:map
[:group {:optional true}
[:or :string :symbol]]]))

(def ?KmonoPackageConfig
[:map
[:group [:or :string :symbol]]
Expand Down Expand Up @@ -40,17 +68,30 @@
[:vector [:vector :string]])

(def ?Config
[:map {:closed true}
[:exec [:or :string [:enum :build :release]]]
[:glob :string]
[:dry-run? :boolean]
[:snapshot? :boolean]
[:include-unchanged? :boolean]
[:create-tags? :boolean]
[:repo-root :string]
[:packages ?Packages]
[:package-map ?PackageMap]
[:graph ?Graph]
[:build-order [:maybe ?BuildOrder]]])
(mu/merge
(mu/required-keys ?CommandConfig [:glob :snapshot? :include-unchanged?])
[:map {:closed true}
[:exec [:or :string [:enum :build :release]]]
[:workspace-config {:optional true}
?KmonoWorkspaceConfig]
[:dry-run? :boolean]
[:create-tags? :boolean]
[:repo-root :string]
[:packages ?Packages]
[:package-map ?PackageMap]
[:graph ?Graph]
[:build-order [:maybe ?BuildOrder]]]))

(defn assert-schema!
([?schema value]
(assert-schema! ?schema "Schema error" value))
([?schema title value]
(binding [ansi/*logs-enabled* true]
(if-not (m/validate ?schema value)
(do (ansi/print-error title)
(ansi/print-shifted
(with-out-str
(pp/pprint (me/humanize (m/explain ?schema value)))))
(throw (ex-info title {:type :errors/assertion})))
value))))

Loading
Loading