Awesome
garamond
garamond is a clojure utility for maintaining git tag versions and for modifying pom.xml files.
garamond is meant to be run from a tools.deps alias. It has two main uses:
- Maintaining a version number for a library based on git tags
- Postprocessing the tools.deps
clojure -Spom
output to update it with the project's correct artifact ID, group ID, and version number.
Installation
To use garamond, install it as an alias in your deps.edn:
:aliases
{...
:garamond
{:main-opts ["-m" "garamond.main"]
:extra-deps {com.workframe/garamond {:mvn/version "0.4.0"}}}
...}
Now you can run it from the command-line via:
clojure -A:garamond
Note that garamond works on git tags; before you run it you should ensure
you have at least one "annotated" git tag in your repo. You can create one
via git tag --annotate -m "First version tag" v0.1.0
.
garamond follows the common github convention of using tag names
prepended by v
as in v1.2.3
. You can use the --prefix
flag to
modify the tags it produces. When reading tags to determine the current
version, garamond relies on git describe
and ignores everything before
the first number.
leiningen
leiningen users can also set up an alias in project.clj
to access garamond:
(defproject ...
:aliases {"garamond" ^:pass-through-help ["trampoline" "run" "-m" "garamond.main"]})
With this in place, you can run lein garamond
. Note that garamond does not
have any particular hooks into leiningen internals, but it should be compatible
with plugins such as lein-v
(see below).
Usage
clojure -A:garamond --help
will show the available options:
% clojure -A:garamond --help
garamond is a utility for printing and incrementing versions based on git tags,
and for updating pom.xml files generated by clojure -Spom with these versions.
Usage: clojure -m garamond.main [options] [increment-type]
Options:
-h, --help Print usage and exit
-d, --debug Print more debugging logs
--prefix PREFIX Use this prefix in front of versions for tags
-p, --pom Generate or update the pom.xml file
-t, --tag Create a new git tag based on the given version
-m, --message MESSAGE Commit message for git tag
-g, --group-id GROUP-ID Update the pom.xml file with this <groupId> value
-a, --artifact-id ARTIFACT-ID Update the pom.xml file with this <artifactId> value
-u, --scm-url URL Update the pom.xml's <scm> tag with this <url> value
--force-version VERSION Use this version number instead of relying on git describe
With no increment type, garamond will print the current version number and exit.
The prefix string ('v' in the tag 'v1.2.3') will be preserved in the new tag, or
it can be overridden via the -p option.
Increment types:
major 1.2.4 -> 2.0.0
minor 1.2.4 -> 1.3.0
patch 1.2.4 -> 1.2.5
major-rc 2.7.9 -> 3.0.0-rc.0, 4.0.0-rc.3 -> 4.0.0-rc.4
minor-rc 2.7.9 -> 2.8.0-rc.0, 4.3.0-rc.0 -> 4.3.0-rc.1
major-release 4.0.0-rc.4 -> 4.0.0, 3.2.9 -> 4.0.0
minor-release 8.1.0-rc.4 -> 8.2.0, 5.9.4 -> 5.10.0
See https://github.com/workframers/garamond for more information.
clojure -A:garamond
: Display the current version based on git tagsclojure -A:garamond major
: Increment the major versionclojure -A:garamond minor --tag
: Increment the minor version and create a new tagclojure -A:garamond --pom
: Runclojure -Spom
and modify the generated pom file to reflect the current version number along with the group-id and artifact-id given.clojure -A:garamond patch --tag --pom
: Increment the patch level of the version tag, generate a new pom.xml with the new version, and create a git tag based on that commit.
Versioning rules
garabond uses zafarkhaja/jsemver
under the hood to handle manipulating version numbers, and its public
interface mostly just delegates to methods there.
Accordingly, you can use clojure -A:garamond major
to bump the major
version number, patch
to increment the patchlevel, and minor
to
update the minor version level.
garabond does have some commands which operate somewhat differently from the jsemver defaults, centered around "release candidate" versions:
clojure -A:garamond increment major-rc
Create a "release candidate". If the current version does not have an
-rc.x
suffix, bump the major version and add a new -rc.0
suffix.
If it already has a suffix, increment the rc number. So v1.2.3
would
become v2.0.0-rc.0
, and v3.0.0-rc.2
would become v3.0.0-rc.3
.
clojure -A:garamond increment minor-rc
This is similar to the above, but if an rc suffix does not exist, the
minor number is incremented instead of the major one, so v2.4.7
becomes v2.5.0-rc.0
and v2.8.0-rc.1
becomes v2.8.0-rc.2
.
clojure -A:garamond increment major-release
This performs a release, which will either remove the -rc.x
suffix
from a version if it has one, or increment the major version if it does
not: v3.1.2
becomes v4.0.0
and v5.0.0-rc.3
becomes v5.0.0
.
clojure -A:garamond increment minor-release
This does the same thing as major-release
, but affects the minor version:
v2.3.7
becomes v2.4.0
and v5.6.0-rc.0
becomes v5.6.0
.
pom.xml modification
Running clojure -A:garamond --pom
will invoke tools.deps to generate a
pom.xml file, as in clojure -Spom
. It will then post-process the generated
file to make some modifications:
- The
<groupId>
and<artifactId>
tags are updated with values from command-line arguments - The
<version>
tag is modified with the current version. If you asked garamond to increment the version, the new version will be used; if you manually specified a version on the command line via--force-version v2.3.4
, that value will be used. - An
<scm>
tag will be created, if it doesn't exist; if it does exist its values will be updated.
The <scm>
tag is created largely so clojars and cljdoc can link back to
your project's home page
(see here).
garamond uses the current git SHA as the <tag>
value and the value of
git remote show origin
as the <connection>
. You need to specify the
<url>
tag on the command-line as --scm-url
.
Like clojure -Spom
, garamond will leave the bits of your pom.xml which
it isn't modifying alone.
Note: garamond currently generates pom.xml files using only the project-level
deps.edn
file. It should probably also include the system-level one, eg
/usr/local/lib/clojure/dep.edn
or what have you. This is planned as a
future enhancement.
Deploying tools.deps library jars to clojars
It is possible to deploy jars to clojars using a combination of garamond
to manage versions and update the pom file, Juxt's pack
project to
package the jar, and deps-deploy
to handle actually pushing the jar to clojars. garamond itself is deployed
this way; see its
.circleci/config.yml
and deps.edn
files for details.
Background and rationale
The basic goal of this project is to automate all the pre-pack/pack.alpha
stuff in this article about deploying library jars with
deps, and to make it possible
to do so without needing to check in partly machine-generated artifacts
(eg, pom.xml
) into the git repository itself.
Secondarily it aims to serve as an analogue to lein-v in the tools.deps universe.
Similar projects
The lein-v and lein-git-version projects do some similar stuff in a leiningen context.
About the name
Garamond is the name of a publishing company in Umberto Eco's 1988 novel Foucault's Pendulum, and is only tangentially related the typeface of the same name.
TODO
- Load in system
deps.edn
when generating pom.xml - Properly handle cases where there are no tags in the repo
- Support tag signing
- Tests for the pom generation stuff
- Maybe? support generated version.edn / version.clj file as lein-v