Unified version syntax for aliases
You've always been able to run a specific version of an alias - but how depended entirely on what the alias pointed at. A Maven GAV took a version one way, a git tag or branch another, a property placeholder another still. Three mechanisms, three mental models, and in some cases the catalog author had to set things up ahead of time for it to work at all.
With special effort and thanks to @wfouche we've managed to unify all of that behind a single syntax:
jbang mytool:1.5.0@mycatalogThat's it. The same alias:version@catalog form works whether the alias resolves to a Maven artifact, a GitHub/GitLab/Bitbucket URL, or a property-driven path - you no longer need to know how it's wired underneath.
Under the covers JBang looks at the alias's script-ref and applies the matching strategy, so the one syntax maps cleanly onto each mechanism:
| What the alias points at | script-ref
| jbang mytool:2.0.0 resolves to
|
|---|---|---|
| Maven artifact | com.example:mytool:1.0.0
| com.example:mytool:2.0.0
|
| Maven artifact w/ classifier | com.example:mytool:1.0.0:jar@dist
| com.example:mytool:2.0.0:jar@dist
|
| GitHub/GitLab/Bitbucket URL | https://github.com/acme/mytool/blob/v1.0.0/Tool.java
| .../blob/v2.0.0/Tool.java
|
| Property placeholder | io.quarkus:quarkus-cli:${jbang.app.version:3.0.0}
| io.quarkus:quarkus-cli:2.0.0
|
| Anything else | tool.jar
| tool.jar unchanged - version still exposed to the script
|
For the common cases the author does nothing special - Maven GAVs and git URLs just work, and the catalog format is unchanged and fully backward-compatible. When an author does want to adapt, they can expose a ${jbang.app.version} placeholder in the script-ref with a default:
{
"aliases": {
"quarkus": {
"script-ref": "io.quarkus:quarkus-cli:${jbang.app.version:3.0.0}"
}
}
}jbang quarkus@mycatalog gives you 3.0.0, jbang quarkus:3.15.1@mycatalog gives you that one - same alias, no duplicated entries. And the requested version is always passed to the script as -Djbang.app.version=<version>, so even an alias that matches none of the patterns can read it and act on it itself:
String version = System.getProperty("jbang.app.version", "dev");A few things worth knowing:
- It's a selector, not a lock file - asking for a floating version or a git branch still resolves to whatever that ref points at today.
- Applying a version through an alias chain is rejected - pin the final target directly.
So the everyday case - reproducing a bug report and checking the fix - becomes just:
jbang mytool:1.4.0@mycatalog # reproduce the report
jbang mytool:1.5.0@mycatalog # verify the fixSee the updated Alias Catalogs guide for the full details.
Have fun!
Changelog
π Features
- a94fc61 feat: replace sdkman with mise (#2679)
- 2d079dd feat: implement version pinning for JBang aliases (#2433)
π Fixes
- 32082a2 fix(deps): upgrade JSpecify to 1.0.1 (#2681)
- 7ba652f fix: suppress command typo warnings for resolved aliases (#2687)
- cae3ad7 fix: support all versions of Groovy (#2664)
ποΈ Changes
π§° Tasks
- a891489 chore(deps): update github/codeql-action digest to 9b32540 (#2670)
- 8e4518a chore(deps): update plugin com.diffplug.spotless to v8.10.4 (#2614)
- fe95e4d chore(deps): upgrade Gradle to 8.14.6 (#2680)
- 9ce399e chore: shorten fully-qualified type names via OpenRewrite (#2673)
π Build
π Documentation
Contributors
We'd like to thank the following people for their contributions:
Arnab Nandy, GitHub, MD. Mohiuddin ahmed, Max Rydahl Andersen, Mend Renovate, Tamas Cservenak, Werner FouchΓ©, coderabbitai[bot]