From 69cde99ce4e8e26df34f2c90c58b9788b6ff4c7c Mon Sep 17 00:00:00 2001 From: Julien Vincent Date: Sun, 8 Sep 2024 22:21:42 +0100 Subject: [PATCH] Add example workspace project --- README.md | 6 ++ examples/workspace/README.md | 71 ++++++++++++++++ examples/workspace/build.clj | 80 +++++++++++++++++++ examples/workspace/deps.edn | 10 +++ examples/workspace/justfile | 11 +++ examples/workspace/packages/a/deps.edn | 5 ++ examples/workspace/packages/a/src/k16/a.clj | 4 + .../workspace/packages/a/test/k16/a_test.clj | 7 ++ examples/workspace/packages/b/deps.edn | 7 ++ examples/workspace/packages/b/src/k16/b.clj | 6 ++ .../workspace/packages/b/test/k16/b_test.clj | 7 ++ examples/workspace/tests.edn | 1 + 12 files changed, 215 insertions(+) create mode 100644 examples/workspace/README.md create mode 100644 examples/workspace/build.clj create mode 100644 examples/workspace/deps.edn create mode 100644 examples/workspace/justfile create mode 100644 examples/workspace/packages/a/deps.edn create mode 100644 examples/workspace/packages/a/src/k16/a.clj create mode 100644 examples/workspace/packages/a/test/k16/a_test.clj create mode 100644 examples/workspace/packages/b/deps.edn create mode 100644 examples/workspace/packages/b/src/k16/b.clj create mode 100644 examples/workspace/packages/b/test/k16/b_test.clj create mode 100644 examples/workspace/tests.edn diff --git a/README.md b/README.md index 62ca208..02b8201 100644 --- a/README.md +++ b/README.md @@ -39,6 +39,12 @@ packages. API's for building jar artifacts or simplifying the use of `tools.build` in a kmono workspace. + **[kmono-version](https://cljdoc.org/d/com.kepler16/kmono-version)** - A set of API's for versioning kmono packages. +## Example project + +Take a look at **[the example project](./examples/workspace/)** to get a better idea of the type of project +structures kmono is built to support and for references on how to correctly use the kmono API's and integrate it into +your own project. + ## Installation #### Homebrew diff --git a/examples/workspace/README.md b/examples/workspace/README.md new file mode 100644 index 0000000..47c5d6d --- /dev/null +++ b/examples/workspace/README.md @@ -0,0 +1,71 @@ +# Example Workspace Project + +This is a very simple project structure which serves as an example of how kmono is intended to be setup and used. + +## Overview + +This is the overall structure of the project: + +```bash +. +├── packages +│ ├── a +│ │ ├── src +│ │ ├── test +│ │ └── deps.edn +│ └── b +│ ├── src +│ ├── test +│ └── deps.edn +├── build.clj +└── deps.edn +``` + +In this structure we have two packages - `a` and `b` where package `b` depends on package `a`. + +This project demonstrates a workflow where: + +1) Packages are built and released when PR's are merged to master. +2) Only packages that have changed since their previous version are build and released. +3) The project uses convensional-commits and package versions are derived from commits. + +The above requirements aren't needed to make use of kmono - this just serves to demonstrate a particular workflow and +how you might use kmono to achieve it. + +## Building/Releasing + +The build and release workflow described above is entirely encapsulated in the `build.clj` file using `tools.build` and +kmono-* APIs. + +Packages can be built by running: + +```bash +clojure -T:build build +``` + +And the built packages can then be released by running + +```bash +clojure -T:build release +``` + +For both building and releasing you can add the `:skip-unchanged true` argument to build and release only packages that +have changed. The idea being that you would pass this by default during CI. + +```bash +clojure -T:build build :skip-unchanged true +``` + +This behaviour hasn't been hard-coded into the build process so that one might run `just build` locally during +development to build all packages. + +## Testing + +To run the tests for each package you can run the command + +```bash +kmono run -M ':*/test' +``` + +This means run `clojure -M` in each package (indicated by the `*`) that has a `:test` alias. Each respective packages' +`:test` alias will then be appended to the command when it is run, like so: `clojure -M:test`. diff --git a/examples/workspace/build.clj b/examples/workspace/build.clj new file mode 100644 index 0000000..690cfcf --- /dev/null +++ b/examples/workspace/build.clj @@ -0,0 +1,80 @@ +(ns build + (:require + [clojure.tools.build.api :as b] + [deps-deploy.deps-deploy :as deps-deploy] + [k16.kmono.build :as kmono.build] + [k16.kmono.core.config :as core.config] + [k16.kmono.core.fs :as core.fs] + [k16.kmono.core.graph :as core.graph] + [k16.kmono.core.packages :as core.packages] + [k16.kmono.git.tags :as git.tags] + [k16.kmono.version :as kmono.version] + [k16.kmono.version.alg.semantic :as semantic])) + +(defn load-packages [{:keys [skip-unchanged]}] + (let [project-root (core.fs/find-project-root) + workspace-config (core.config/resolve-workspace-config project-root) + + packages + (cond->> (->> (core.packages/resolve-packages project-root workspace-config) + (kmono.version/resolve-package-versions project-root) + (kmono.version/resolve-package-changes project-root)) + + ;; Only perform a build and/or release for packages which have changed + ;; since their last version + skip-unchanged (core.graph/filter-by kmono.version/package-changed?))] + + ;; Use semantic commits to increment package versions based on commits which + ;; modified them since their last version. + (kmono.version/inc-package-versions semantic/version-fn packages))) + +(defn build [opts] + (b/delete {:path "target"}) + + (let [packages (load-packages opts)] + (kmono.build/for-each-package + (fn [pkg] + (let [;; Create a basis with all local kmono libs replaced with their + ;; respective :mvn/version coordinate + {:keys [basis paths]} (kmono.build/create-basis packages pkg) + + pkg-name (:fqn pkg) + class-dir "target/classes" + jar-file "target/lib.jar"] + + (b/copy-dir {:src-dirs paths + :target-dir class-dir}) + + (b/write-pom + {:class-dir class-dir + :lib pkg-name + :version (:version pkg) + :basis basis}) + + (b/jar {:class-dir class-dir + :jar-file jar-file}))) + packages))) + +(defn release [{:keys [repository] :as opts}] + (let [project-root (core.fs/find-project-root) + packages (load-packages opts) + changed-packages (core.graph/filter-by kmono.build/not-published? packages)] + (kmono.build/for-each-package + (fn [pkg] + ;; Release the package using deps-deploy + (deps-deploy/deploy + {:installer :remote + :artifact (b/resolve-path "target/lib.jar") + :pom-file (b/pom-path {:lib (:fqn pkg) + :class-dir (b/resolve-path "target/classes")}) + :repository repository}) + + ;; Create tags after successfully releasing the package + ;; This will require calling `git push --tags` separately but you could + ;; just as easilly call it here too. + (git.tags/create-tags + project-root {:tags [(kmono.version/create-package-version-tag pkg)]})) + + {:title "Release" + :concurrency 1} + changed-packages))) diff --git a/examples/workspace/deps.edn b/examples/workspace/deps.edn new file mode 100644 index 0000000..995ae63 --- /dev/null +++ b/examples/workspace/deps.edn @@ -0,0 +1,10 @@ +{:kmono/workspace {:group com.kepler16} + + :aliases {:build {:extra-deps {io.github.clojure/tools.build {:mvn/version "0.10.5"} + slipset/deps-deploy {:mvn/version "0.2.1"} + + com.kepler16/kmono-version {:local/root "../../packages/kmono-version"} + com.kepler16/kmono-build {:local/root "../../packages/kmono-build"} + com.kepler16/kmono-core {:local/root "../../packages/kmono-core"} + com.kepler16/kmono-git {:local/root "../../packages/kmono-git"}} + :ns-default build}}} diff --git a/examples/workspace/justfile b/examples/workspace/justfile new file mode 100644 index 0000000..6255244 --- /dev/null +++ b/examples/workspace/justfile @@ -0,0 +1,11 @@ +default: + @just --choose + +build *args: + clojure -T:build build {{args}} + +release *args: + clojure -T:build release {{args}} + +test *args: + kmono run -M ':*/test' diff --git a/examples/workspace/packages/a/deps.edn b/examples/workspace/packages/a/deps.edn new file mode 100644 index 0000000..aa82cd9 --- /dev/null +++ b/examples/workspace/packages/a/deps.edn @@ -0,0 +1,5 @@ +{:kmono/package {} + + :aliases {:test {:extra-paths ["test"] + :extra-deps {lambdaisland/kaocha {:mvn/version "1.91.1392"}} + :main-opts ["-m" "kaocha.runner" "-c" "../../tests.edn"]}}} diff --git a/examples/workspace/packages/a/src/k16/a.clj b/examples/workspace/packages/a/src/k16/a.clj new file mode 100644 index 0000000..b0914ce --- /dev/null +++ b/examples/workspace/packages/a/src/k16/a.clj @@ -0,0 +1,4 @@ +(ns k16.a) + +(defn return-one [] + 1) diff --git a/examples/workspace/packages/a/test/k16/a_test.clj b/examples/workspace/packages/a/test/k16/a_test.clj new file mode 100644 index 0000000..c96dbd7 --- /dev/null +++ b/examples/workspace/packages/a/test/k16/a_test.clj @@ -0,0 +1,7 @@ +(ns k16.a-test + (:require + [clojure.test :refer [deftest is]] + [k16.a :as a])) + +(deftest should-return-one + (is 1 (a/return-one))) diff --git a/examples/workspace/packages/b/deps.edn b/examples/workspace/packages/b/deps.edn new file mode 100644 index 0000000..c919fd6 --- /dev/null +++ b/examples/workspace/packages/b/deps.edn @@ -0,0 +1,7 @@ +{:kmono/package {} + + :deps {com.kepler16/a {:local/root "../a"}} + + :aliases {:test {:extra-paths ["test"] + :extra-deps {lambdaisland/kaocha {:mvn/version "1.91.1392"}} + :main-opts ["-m" "kaocha.runner" "-c" "../../tests.edn"]}}} diff --git a/examples/workspace/packages/b/src/k16/b.clj b/examples/workspace/packages/b/src/k16/b.clj new file mode 100644 index 0000000..1b67319 --- /dev/null +++ b/examples/workspace/packages/b/src/k16/b.clj @@ -0,0 +1,6 @@ +(ns k16.b + (:require + [k16.a :as a])) + +(defn also-return-one [] + (a/return-one)) diff --git a/examples/workspace/packages/b/test/k16/b_test.clj b/examples/workspace/packages/b/test/k16/b_test.clj new file mode 100644 index 0000000..25355c2 --- /dev/null +++ b/examples/workspace/packages/b/test/k16/b_test.clj @@ -0,0 +1,7 @@ +(ns k16.b-test + (:require + [clojure.test :refer [deftest is]] + [k16.b :as b])) + +(deftest should-return-one + (is 1 (b/also-return-one))) diff --git a/examples/workspace/tests.edn b/examples/workspace/tests.edn new file mode 100644 index 0000000..d91eb14 --- /dev/null +++ b/examples/workspace/tests.edn @@ -0,0 +1 @@ +#kaocha/v1 {:reporter [kaocha.report/documentation]}