Version CLI Utility
versionutil is a command-line utility for generating an application version using modified or strict SemVer numbering rules. It updates a build number and writes a generated version file for Dart, Java, or C++.
See my Version Utility Notes on why I created it, and AI usage. See Modification to the semantic versioning rules for why I default to not using strict SemVer rules.
Example usage
The first step is to create your version config files and your first version file. For Dart, just call without any params:
versionutil --help
versionutil
This generates the config files version.json, version-build.json and a Dart file lib/version.dart. Every time you run versionutil without params, it will update the appBuild number and build in version-build.json:
lib/version.dart:
/// GENERATED FILE - DO NOT EDIT
const String appVersion = "0.01.00+0001";
const int appVersionNumber = 0;
const int appRevision = 1;
const int appPatch = 0;
const int appBuild = 1;
After running versionutil, just include the version file in your application and print the appVersion:
Example app file bin/hello.dart:
import '../lib/version.dart';
void main(List<String> args) {
print("Hello, your app version is $appVersion");
}
Then run:
dart run bin\hello.dart
Hello, your app version is 0.01.00+0001
Print the version without changing files. Handy if you want to know what the version is but don't want to change it:
versionutil --show
Java
Generate Java output, update pom.xml, and set a package:
versionutil --lang=java --package=com.example.app --out=src/main/java/com/example/app/Version.java --pom=pom.xml
Version format
The generated version is:
MAJOR.MINOR.PATCH[-prerelease][+build]
By default, minor, patch, and build are zero-padded unless strict SemVer is enabled.
Output examples
| Output version | How to get it |
|---|---|
1.09.01+0102 |
default formatting with build enabled |
1.9.1+102 |
--strict |
1.09.01 |
--no-build |
1.09.01-alpha.2+0102 |
preRelease present in version-build.json |
1.9.1-alpha.2+102 |
preRelease present and --strict |
Config files
The config files can be generated by running versionutil without any parameters. If you pass --preRelease the preRelease block will be included in the version-build.json file.
version.json
{
"version": 1,
"revision": 9,
"patch": 1,
"strict": false,
"build": true
}
| Field | Description | Required |
|---|---|---|
version |
The MAJOR part of the version number | Yes |
revision |
The MINOR part of the version number | Yes |
patch |
The PATCH part of the version number | Yes |
strict |
default formatting rule if --strict is not passed |
No |
build |
default build-metadata rule if --build / --no-build is not passed |
No |
version-build.json
When preRelease exists, the generated version includes both the prerelease and build parts. 1.09.01-alpha.2+0102 vs 1.09.01+0102.
{
"build": 102,
"preRelease": {
"tag": "alpha",
"num": 2
}
}
| Field | Description | Required |
|---|---|---|
build |
The BUILD part of the version number | Yes |
preRelease |
The PRERELEASE part of the version number | No |
tag |
The tag name to include, typically alpha or beta. | Yes if preRelease present. |
num |
The version of alpha/beta you are working on | Yes if preRelease present. |
Options
| Option | Description |
|---|---|
--lang=dart/java/cpp |
Output language, defaults to Dart |
--package=<name> |
Java package name for generated Java file |
--out=<path> |
Output file path |
--pom=<pom.xml> |
Update the Maven <version> tag |
--in=<name> |
Use <name>.json and <name>-build.json instead of version.* |
--strict |
Use strict SemVer formatting such as 1.9.1+102 |
--build / --no-build |
Include or omit build metadata 1.9.1+102 vs 1.9.1 |
--prerelease |
When creating a build file, include preRelease: { "tag": "alpha", "num": 1 } |
--clean |
Delete the input JSON files and generated output file |
--show, -s |
Print the version only; do not increment or generate |
--verbose, -v |
Print generation details |
--help, -h |
Show help |
Generated output
Dart
/// GENERATED FILE - DO NOT EDIT
const String appVersion = "1.09.01+0102";
const int appVersionNumber = 1;
const int appRevision = 9;
const int appPatch = 1;
const int appBuild = 102;
Java
package com.example.app;
// GENERATED FILE - DO NOT EDIT
public final class Version {
private Version() {}
public static final String APP_VERSION = "1.09.01+0102";
public static final int APP_VERSIONNUMBER = 1;
public static final int APP_REVISION = 9;
public static final int APP_PATCH = 1;
public static final int APP_BUILD = 102;
}
C++
// GENERATED FILE - DO NOT EDIT
#pragma once
#define APP_VERSION "1.09.01+0102"
#define APP_VERSIONNUMBER 1;
#define APP_REVISION 9;
#define APP_PATCH 1;
#define APP_BUILD 102;