standard-version
standard-version copied to clipboard
feat(Java): add support for Java projects which use Maven or Gradle
(I've also published a blog post on how to use this for Java here Supercharge your Java Projects with Conventional Commits, Semantic Versioning and Semantic Releases)
What is the problem this is addressing?
This project is amazing, I use it all the time both personally and professionally. However, I use more than just Node.js, and find myself missing standard-version
in every other language. Although by default this project assume Node.js, 99.9% of the code is not Node specific. Creating the changelog, committing, checking for the changes, deciding how to bump, dry runs, etc etc.
Although there does exist a mechanism to update files in a custom way with updaters, I think many people do not use this feature.
This small change means that with just a few extra lines, we can support Java projects out-of-the-box. That potentially adds a massive number of people who can use the library. It adds no new dependencies. If I search for 'standard version java' I find nothing relevant, there is no equivalent tool.
I'd love any feedback on this PR, this would help me enormously in my own projects, but I understand it somewhat muddies the API as you could do this with custom updaters.
This is also a non-breaking change and will not affect any existing projects or use cases.
Here are the changes:
Adds support for Java projects which use the 'Maven' build system, by simply setting the flags as below
In the Maven world, the pom.xml
is basically your package.json
.
Adds support for Java projects which use the 'Gradle' build system, by simply setting the flags as below
npx standard-version --packageFiles build.gradle --bumpFiles build.gradle
Fixed a bug in resolveUpdaterObjectFromArgument
which led to a cryptic error message in a failing test
Before:
After:
would be nice to change the regex to support "
around version (apart from single quotes) in gradle files like
version = "0.2.4"
@hashd very good point - have updated the code now and tested it works. Thanks for the suggestion!
Thanks for the PR. I'm also wondering if we should maintain these additional logic here? My preference is to make it pluggable so that the logics can live in any repo
Yes this is exactly the conversation I want to check with you. Basically the effort required to support another language in most cases is trivial - regex against a file, replace a version. All of the great stuff in this library around managing the commits, the changelog, etc etc is universal. Now there is the approach of custom-updaters
, as is present now, but that seems to be much more project specific.
Something like a pom.xml
, gradle.build
, AssemblyVersion.cs
or whatever is going to work the same way in any project. But the more we add, the more we bloat this codebase. So finding some way to make this pluggable would make sense.
The only challenge will be making it work for a codebase which isn't already node.js. Because (for example) Java projects won't have a package.json
which you can npm install
a plugin into, so ideally the whole thing should still be able to work with a single npx
command, such as:
npx standard-version --plugin pom
Or something like this.
Any thoughts on what might be the best way to go?
Yes this is exactly the conversation I want to check with you. Basically the effort required to support another language in most cases is trivial - regex against a file, replace a version. All of the great stuff in this library around managing the commits, the changelog, etc etc is universal. Now there is the approach of
custom-updaters
, as is present now, but that seems to be much more project specific.Something like a
pom.xml
,gradle.build
,AssemblyVersion.cs
or whatever is going to work the same way in any project. But the more we add, the more we bloat this codebase. So finding some way to make this pluggable would make sense.The only challenge will be making it work for a codebase which isn't already node.js. Because (for example) Java projects won't have a
package.json
which you cannpm install
a plugin into, so ideally the whole thing should still be able to work with a singlenpx
command, such as:npx standard-version --plugin pom
Or something like this.
Any thoughts on what might be the best way to go?
Yep, would prefer a solution which avoids a package.json in a Java maven/gradle project
Hi there, for the maven implementation, it may be safer to use maven version plugin instead of raw replacement.
mvn versions:set -DnewVersion=x.x.x
This would work better with maven multi-module project as well.
In any case, nice work ! And I would love to see this released :)
@uguy that would be a conventional way to do it in Java, but has the issue which is that it would require Maven to be installed on the machine this runs on. What's nice about this approach is that there is no need for the Java tooling to be present. Also if we call out to another process we need to check error codes etc etc, whereas this approach uses all of the existing mechanisms (you get the file as a string, manipulate it, that's it, the existing code paths take care of the rest).
standard-version is exactly what I need, but for Java project (and in the future Lua projects for an PC game I'm modding). Is this integration in the base version still on the table? It would be so awesome to use standard-version for other programming projects as well.
I'm more than happy to update the PR, and also to use xmldom
if preferred, just waiting on input from a maintainer to know if we're going to go down this route. It looks like there are other PRs which also would leverage this approach to widen the potential use cases for the library. I'd love it if we can get this in - I'd like to have standard-version
as a pretty much standard part of my workflow for every project!
Hello, I'm also very interested with this feature for java.
I tried it on your repo with
npx @dwmkerr/standard-version --prerelease rc --packageFiles pom.xml --bumpFiles pom.xml
It work with
<version>1.1.0</version>
But did not work with
<version>1.1.0-rc.0</version>
I have this message : "Failed to read the
Another remark, it did not bump child module pom.xml, only the parent.
@eemeli sorry for the delay I've been slammed - xmldom
seems to work great. There is only one potential issue - as it reads into what is essentially an AST then writes back out, the user's pom.xml
can end up having a bunch of other changes. For example, if someone has re-indented xml attributes to line up nicely, these changes will be lost.
The benefit is definitely more robust handling of XML so I think that outweighs the single consequence - it'll essentially 'standardise' your XML.
Do you think this would be worth noting the in the docs?
@UnleashSpirit I believe the current version will now fix your issue, would you mind letting me know?
Im wondering if this variant can accommodate the usual maven extensions (ie qualifier/buildnumber) to semver? Fwiw Im not really interested in the version bump functionality, but I am interested in running this via docker or directly as a github action, independent of maven/gradle.
Good points @jeacott am happy to take any suggestions, basically as long as the project maintainers think the overall approach/feature is useful to have!
@dwmkerr I try again just now
command :
npx @dwmkerr/standard-version@latest --prerelease rc --packageFiles pom.xml --bumpFiles pom.xml
Same result if
<version>2.0.0</version>
It works, bump to 2.1.0-rc.0
But if
<version>2.0.0-rc.0</version>
Same message Failed to read the <version> tag in your pom file - is it present?
and the version becomes 1.1.0-rc.0
And it still bumping only parent pom.xml and not module's one (or do I have to list them all in the command ? is yes, how ?)
Hi, great work. I was wondering if there is anyway to create the tag of format x.y.z
and not vx.y.z
(v prefixed) as in the case of default
Hi, great work. I was wondering if there is anyway to create the tag of format
x.y.z
and notvx.y.z
(v prefixed) as in the case of default
Nevermind, I found the solution I had to pass --tag-prefix=
parameter
Does this PR is still alive ?
I found why the npx @dwmkerr/standard-version@latest
did not work, the @lastest
is not the master so the code not the same as here (no xmldoc)
With the real last version, the master banch and not the latest npm published, the bump problem with prerelease rc is resolved.
For the maven sub module, as you don't use mvn cli, which is a good idea, I have a proposition.
Update the pom.js
and use .versionrc
as here. It's kind of a workaround but still good (at least for me)
// updaters/types/pom.js
function getDocAndVersionNode(contents) {
const doc = new DOMParser().parseFromString(contents)
const nodes = doc.documentElement.childNodes
let parentNodes = null
for (let i = 0; i < nodes.length; ++i) {
const node = nodes[i]
if (node.nodeName === 'version') return { doc, node }
if (node.nodeName === 'parent') parentNodes = node.childNodes
}
// Maven sub-module
if (parentNodes) {
for (let i = 0; i < parentNodes.length; ++i) {
const node = parentNodes[i]
if (node.nodeName === 'version') return { doc, node }
}
}
return { doc }
}
// .versionrc.json
{
"packageFiles": [
{ "filename": "pom.xml", "type": "pom" }
],
"bumpFiles": [
{ "filename": "pom.xml", "type": "pom" },
{ "filename": "module_a/pom.xml", "type": "pom" },
{ "filename": "module_b/pom.xml", "type": "pom" }
]
}
@dwmkerr @UnleashSpirit The command mvn versions:set -DnewVersion={{version}}
would also update its child modules.
@dwmkerr @UnleashSpirit The command
mvn versions:set -DnewVersion={{version}}
would also update its child modules.
But it brings maven cli dependency which we want to avoid ...
Hi all - again I'm more than happy to update the PR from latest, I just want to get a steer from the project maintainers on whether this is likely to go in or whether they want to keep it separate, I'm fine either way just want to confirm before I update!
It looks like it's been a minute on this, but I'd love to see java supported. Any updates? Anything I can do to help?
Hi there! Since standard-version is deprecated, I've forked it here. I'm keen to bring in updaters for common frameworks to the fork, and I've proposed a guideline to do so in this RFC here - I was able to write the proposed guideline thanks in large part to the excellent discussion on this PR so far - thanks very much! Further discussion welcome on that RFC.
if you're still interested in this feature, a PR against the fork would be very welcome.