version-updater
v7.0.0
Published
Automatically replace version numbers across the files of your project
Maintainers
Readme
version-updater v7.0.0
A small, fast CLI to keep version numbers in sync across the files of your project.
npm install -g version-updaterWhen you cut a release you often have to bump the version number in several files
(package.json, the README, an index.html, …). version-updater automates that:
you declare once which files to touch, then run a single command to update them all.
Quick start
cd my-project
version init # detect files + read the current version
version update -m # bump the minor number and rewrite every tracked file
version # print the current versionHow it works
version init creates a .versionFilesList.json file in your project root. It holds:
- the project name and current version (auto-detected from a project manifest — see Auto-detecting name & version);
- the list of files to update, each with a replacement strategy.
Only files listed there are ever touched — nothing else in your project is modified.
File strategies
Each tracked file has a strategy that decides how a version is located and
replaced. The strategy is auto-detected from the file name/extension but can be
set explicitly (path:type). Only the version token itself is ever rewritten.
| Strategy | What gets replaced | Auto-detected for |
| ----------- | -------------------------------------------------------- | --------------------------------- |
| normal | every ‹prefix›1.2.3 (prefix defaults to v) | everything else |
| package | a version field: "version": "1.2.3" / version: '…' | *.json, package.js, mix.exs |
| toml | version = "1.2.3" (line-anchored; skips inline deps) | *.toml |
| yaml | a top-level version: 1.2.3 | *.yaml, *.yml |
| xml | <version>1.2.3</version> / <Version>…</Version> | *.xml, *.csproj, *.nuspec |
The v prefix on "normal" files is what stops the tool from rewriting unrelated
numbers (like a 1.2.3 inside a URL). Change it per project with --prefix.
Glob patterns are supported. A file entry can be a glob such as
docs/**/*.md, which is expanded every time the command runs.
Commands
Syntax: version [global-options] <command> [command-options]
Global options
-V, --version— print version-updater's own version-h, --help— show help-d, --debug— verbose debug output-n, --dry-run— preview all changes without writing any file
init
Initialize the current folder (creates .versionFilesList.json) or, if it already
exists, update it.
-f, --force— re-initialize from scratch-p, --prefix <prefix>— version prefix for "normal" files (defaultv)-a, --add <files>— comma-separated files to add, each aspath[:type]-r, --remove <files>— comma-separated files to remove--project-name <name>— set the project name manually--current-version <version>— set the current version manually
version init -a CHANGELOG.md # added as a normal file
version init -a config.json:normal # force the normal strategy on a json file
version init -a "docs/**/*.md" # add every markdown file under docs/
version init -r CHANGELOG.md # stop tracking a filelist
List the files currently tracked.
--current— also print the current project version
update [newVersion]
Update the version across every tracked file.
Provide an explicit version or a bump flag:
-M, --major [n]— increase the major number (byn, default 1) →X+n.0.0-m, --minor [n]— increase the minor number →x.X+n.0-p, --patch [n]— increase the patch number →x.x.X+n--prerelease [preid]— bump to a prerelease, e.g.--prerelease beta→1.2.3-beta.0--preid <id>— prerelease identifier to combine with a bump--analyze— report version numbers that don't match the current one--verbose— with--analyze, print the offending lines--fix— with--analyze, rewrite the mismatched numbers too
version update 2.0.0 # set an explicit version (validated as semver)
version update -M # 1.4.2 -> 2.0.0
version update -m 3 # 1.4.2 -> 1.7.0
version update --prerelease rc -p # 1.4.2 -> 1.4.3-rc.0
version update --dry-run -m # preview only, write nothing
version update -m --analyze --fix # bump and repair stale version numbersConfiguration file
.versionFilesList.json (added to .gitignore automatically):
{
"name": "my-project",
"currentVersion": "2.1.0",
"versionPrefix": "v",
"files": [
{ "path": "package.json", "type": "package" },
{ "path": "README.md", "type": "normal" },
{ "path": "docs/**/*.md", "type": "normal" }
]
}You can edit it by hand at any time.
Auto-detecting name & version
On init, version-updater tries to fill in the project name and current
version by reading a project manifest. It supports many ecosystems (parsing is
read-only and best-effort). Sources are tried in the order below; the name and the
version are each taken from the first source that provides them — so, for example,
a Go project can take its name from go.mod and its version from a VERSION file.
| # | File | Ecosystem | Reads |
| --- | ------------------------ | -------------- | -------------------------------------------- |
| 1 | package.json | Node / npm | name, version |
| 2 | package.js | Meteor | name, version |
| 3 | composer.json | PHP / Composer | name, version |
| 4 | pyproject.toml | Python | [project] / [tool.poetry] name, version |
| 5 | setup.cfg | Python | [metadata] name, version |
| 6 | Cargo.toml | Rust | [package] name, version |
| 7 | pubspec.yaml | Dart / Flutter | name, version |
| 8 | pom.xml | Maven / Java | artifactId, version (ignores <parent>) |
| 9 | build.gradle(.kts) | Gradle | version |
| 10 | *.csproj | .NET | PackageId/AssemblyName, Version |
| 11 | *.nuspec | NuGet | id, version |
| 12 | *.gemspec | Ruby | name, version |
| 13 | mix.exs | Elixir | app, version |
| 14 | go.mod | Go | module name (no version) |
| 15 | CMakeLists.txt | C / C++ | project(<name> VERSION …) |
| 16 | VERSION, version.txt | any | the version number |
If nothing is found, init leaves those fields empty and warns you to fill them
in manually (or pass --project-name / --current-version).
Files added automatically by init
When you run version init, these files are added to the list if they exist
in the folder, each with the strategy shown. Anything else you add yourself with
-a.
| File | Strategy | Ecosystem |
| ---------------- | --------- | -------------- |
| package.json | package | Node / npm |
| package.js | package | Meteor |
| composer.json | package | PHP / Composer |
| mix.exs | package | Elixir |
| Cargo.toml | toml | Rust |
| pyproject.toml | toml | Python |
| pubspec.yaml | yaml | Dart / Flutter |
| pom.xml | xml | Maven / Java |
| README.md | normal | docs |
| index.html | normal | web |
Discovery (the table above) understands more file types than are auto-added, because reading a version is always safe whereas rewriting one is only offered for files version-updater knows how to edit precisely. Add any other file yourself, e.g.
version init -a build.gradle:tomlorversion init -a "*.csproj".
Programmatic API
The engine is also importable:
import { computeNextVersion, runUpdate, loadConfig } from "version-updater";
const config = loadConfig(process.cwd());
const next = computeNextVersion(config.currentVersion, { minor: true });
const report = runUpdate(config, next, { dryRun: true });
console.log(report.totalReplacements);Migrating from v6
v7 is backward compatible with existing projects:
- the old
filesList: ["path:type", …]format is read and migrated automatically to the newfiles: [{ path, type }]format the next time the file is written; - a legacy, non-hidden
versionFilesList.jsonis renamed to.versionFilesList.json.
You don't need to do anything — just run any command once.
Notable changes:
- explicit versions are now validated as semver (an invalid one is rejected instead of silently written);
- prerelease versions, glob patterns and
--dry-runare new; package-strategy files now only ever touch theversionfield (a long-standing bug could blank out other lines that happened to contain the version string).
Requirements
Node.js >= 20.11.0.
Development
npm install
npm test # node:test suite
npm run lint # eslint
npm run format # prettier --writeLicense
MIT.
History
7.0.0
- full rewrite into modern, modular ES modules with a test suite, ESLint, Prettier and CI;
- semver-based version handling, including prerelease support (
--prerelease,--preid); - glob patterns in the file list;
--dry-runto preview changes;- config schema modernized to
files: [{ path, type }](old format auto-migrated); - fixed:
init -a/-rcrash on an already-initialized folder; - fixed: auto file-type detection crash;
- fixed:
packagefiles could blank out non-version lines containing the version string; - fixed: the global
-d/--debugflag now works; - fixed: discovery crashes on warning paths and on
package.js.
6.x and earlier
See the project's git history.
