kmono is a command runner tool designed specifically for managing Clojure monorepos. With features like automatic change detection via git, semantic versioning through commit prefixes, and parallel excution, kmono aims to simplify and automate your monorepo experience.
local/root
dependencies with real
version numbers during the build.just test
0.0.0.0
.One can use it as a library or download a native binary.
Download one of the binaries from the releases page. Or use Github CLI by setting pattern to one of the binary archive names from the release. Following command installs latest mac arm64 binary:
gh release download --clobber --repo kepler16/kmono \
--pattern "kmono-macos-arm64.tar.gz" --dir . && \
tar -xzf kmono-macos-arm64.tar.gz && \
rm kmono-macos-arm64.tar.gz && \
mv kmono ~/.local/bin/kmono
Directory Structure
Ensure your monorepo has the following directory structure:
repo-root
├── packages
│ ├── package1
│ │ └── deps.edn
│ ├── package2
│ │ └── deps.edn
│ └── package3
│ └── deps.edn
└── deps.edn (for starting monorepo repl and kmono alias)
Basic Usage using as a Tool (the old way)
Root deps.edn
:
{:deps {;; add local/root deps for all packages to start repo level REPL (optional)
{kepler16/package1 {:local/root "packages/package1"}}}
:aliases {:kmono {:deps {kepler16/kmono {:mvn/version "1.0.0.0"}}
:ns-default k16.kmono.api}}}
All commands below runs against all changed packages.
Build a package:
clojure -T:kmono run :exec :build
Deploy a package:
clojure -T:kmono run :exec :release
Run a custom command:
clojure -T:kmono run :exec '"just test"'
Start a REPL:
:aliases "[:dev]"
- use alias from root deps.edn (optional):package-aliases "[:my-package/test]"
- add :test
alias from packages/my-package/deps.edn
,
all paths (e.g. :extra-paths
, :local/root
etc.) are modified to be relative
to root (optional).:cp-file '".kmonocp"'
- optionally generate a classpath file.clojure -T:kmono repl :aliases "[:dev]" :package-aliases "[:my-package/test]" :cp-file '".kmonocp"'
Generate classpath to output:
clojure -T:kmono generate-classpath :aliases "[:dev]" :package-aliases "[:my-package/test]"
Generate classpath to a file:
clojure -T:kmono generate-classpath :aliases "[:dev]" :package-aliases "[:my-package/test]" :cp-file '".kmonocp"'
Basic Usage using Main endpoint (preferred way)
Root deps.edn
:
{:deps {;; add local/root deps for all packages to start repo level REPL (optional)
{kepler16/package1 {:local/root "packages/package1"}}}
:aliases {:kmono {:deps {kepler16/kmono {:mvn/version "1.0.0.0"}}
:main-opts ["-m" "k16.kmono.main"]}}}
All commands below runs against all changed packages.
Display help:
clojure -M:kmono -h
outputs:
kmono <mode> opts...
Modes:
=== run - execute command for monorepo ===
-h, --help Show this help
-x, --exec CMD :build Command to exec [build, release, <custom cmd>]
-r, --repo-root PATH . Repository root (default: '.')
-p, --packages GLOB packages/* A glob string describing where to search for packages, (default: 'packages/*')
-s, --snapshot FLAG false A snapshot flag (default: false)
-t, --create-tags FLAG false Should create tags flag (default: false)
-i, --include-unchanged FLAG true Should include unchanged packages flag (default: true)
=== repl - start a REPL for monorepo ===
-h, --help Show this help
-A, --aliases :alias1:alias2:namespace/alias3 List of aliases from root deps.edn
-P, --package-aliases :package/alias1:package/alias2 List of aliases from packages
-r, --repo-root PATH . Repository root (default: '.')
-p, --packages GLOB packages/* A glob string describing where to search for packages, (default: 'packages/*')
-f, --cp-file FILENAME nil Classpath file name (default: do nothing)
=== cp - save/print a classpath ===
-h, --help Show this help
-A, --aliases :alias1:alias2:namespace/alias3 List of aliases from root deps.edn
-P, --package-aliases :package/alias1:package/alias2 List of aliases from packages
-r, --repo-root PATH . Repository root (default: '.')
-p, --packages GLOB packages/* A glob string describing where to search for packages, (default: 'packages/*')
-f, --cp-file FILENAME nil Classpath file name (default: do nothing)
Build a package:
clojure -M:kmono run -x build
Deploy a package:
clojure -M:kmono run -x release
Run a custom command:
clojure -M:kmono run -x "just test"
Start a REPL:
-A :dev
- use alias from root deps.edn (optional)-P :my-package/test
- add :test
alias from packages/my-package/deps.edn
,
all paths (e.g. :extra-paths
, :local/root
etc.) are modified to be relative
to root (optional).-f .kmonocp
- optionally generate a classpath file.clojure -M:kmono repl -A :dev -P :my-package/test -f .kmonocp
Generate classpath to output:
clojure -M:kmono cp -A :dev -P :my-package/test
Generate classpath to a file:
clojure -M:kmono cp -A :dev -P :my-package/test -f .kmonocp
During each command following environment variables are available for each package:
KMONO_PKG_VERSION
- version of a packageKMONO_PKG_DEPS
- dependency overrides for a packageKMONO_PKG_NAME
- full name of a package artifact, e.g. com.example/my-lib
One can pass this CLI args to -T:kmono
command
:include-unchanged?
-jk boolean
, should kmono include unchanged packages into build process (default false
):snapshot?
- boolean
, whether release is a snapshot, useful when releasing from PR branch (default true
):create-tags?
- boolean
, should kmono create new baseline tags after release. Usually baseline tags are created on master releases, not snapshots (default false
):packages
- string
, where to search for packages, defaults to "packages/*"
:build-cmd
- string
, overrides build-cmd
option from package kmono config:release-cmd
- string
, overrides release-cmd
option from package kmono config:repo-root
- string
, root of the monorepo, defaults to "."
:dry-run?
- boolean
, dry run to check command output (default false
)Package-specific configurations are done within each deps.edn
file under the :kmono/package
key:
:kmono/package {;; maven artifact's group
:group com.example
;; maven's artifactId
;; this is optional and inferred from a package's dir name
:artifact my-lib
;; below are two builtin commands, each package must provide this commands
;; run :exec :build
:build-cmd "just build"
;; run :exec :release
:release-cmd "just release"}
If a package directory has kmono.edn
file it will be preferred. Configuration schema is the same, but without :kmono/package
top level key:
{;; maven artifact's group
:group com.example
;; maven's artifactId
;; this is optional and inferred from a package's dir name
:artifact my-lib
;; below are two builtin commands, each package must provide this commands
;; run :exec :build
:build-cmd "just build"
;; run :exec :release
:release-cmd "just release"
;; since we are not relying on deps.edn's local/root anymore
;; list of local packages this package depends on
:local-deps [group1/package1 group1/package2]}
KMONO_PKG_DEPS
, for generic packages
KMONO_PKG_DEPS
env variable contains semicolon separated package name/version: group1/package1@1.0.0.0;group2/package2@1.0.0.0
.
Package's build tool must know how to handle that.Can you improve this documentation? These fine people already did:
Artem Medeu & Alexis VincentEdit on GitHub
cljdoc is a website building & hosting documentation for Clojure/Script libraries
× close