Skip to content

Commit ae26aef

Browse files
committed
feat(providers): add support for some JSON-based version providers (NPM, Composer)
1 parent b9e1380 commit ae26aef

File tree

4 files changed

+106
-1
lines changed

4 files changed

+106
-1
lines changed

commitizen/providers.py

+42-1
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,9 @@
11
from __future__ import annotations
22

3+
import json
34
from abc import ABC, abstractmethod
45
from pathlib import Path
5-
from typing import ClassVar, cast
6+
from typing import Any, ClassVar, cast
67

78
import importlib_metadata as metadata
89
import tomlkit
@@ -116,6 +117,46 @@ class CargoProvider(TomlProvider):
116117
filename = "Cargo.toml"
117118

118119

120+
class JsonProvider(FileProvider):
121+
"""
122+
Base class for JSON-based version providers
123+
"""
124+
125+
indent: ClassVar[int] = 2
126+
127+
def get_version(self) -> str:
128+
document = json.loads(self.file.read_text())
129+
return self.get(document)
130+
131+
def set_version(self, version: str):
132+
document = json.loads(self.file.read_text())
133+
self.set(document, version)
134+
self.file.write_text(json.dumps(document, indent=self.indent) + "\n")
135+
136+
def get(self, document: dict[str, Any]) -> str:
137+
return document["version"] # type: ignore
138+
139+
def set(self, document: dict[str, Any], version: str):
140+
document["version"] = version
141+
142+
143+
class NpmProvider(JsonProvider):
144+
"""
145+
npm package.json version management
146+
"""
147+
148+
filename = "package.json"
149+
150+
151+
class ComposerProvider(JsonProvider):
152+
"""
153+
Composer version management
154+
"""
155+
156+
filename = "composer.json"
157+
indent = 4
158+
159+
119160
def get_provider(config: BaseConfig) -> VersionProvider:
120161
"""
121162
Get the version provider as defined in the configuration

docs/config.md

+2
Original file line numberDiff line numberDiff line change
@@ -126,6 +126,8 @@ Commitizen provides some version providers for some well known formats:
126126
| `pep621` | Get and set version from `pyproject.toml` `project.version` field |
127127
| `poetry` | Get and set version from `pyproject.toml` `tool.poetry.version` field |
128128
| `cargo` | Get and set version from `Cargo.toml` `project.version` field |
129+
| `npm` | Get and set version from `package.json` `project.version` field |
130+
| `composer` | Get and set version from `composer.json` `project.version` field |
129131

130132
### Custom version provider
131133

pyproject.toml

+2
Original file line numberDiff line numberDiff line change
@@ -107,6 +107,8 @@ cz_customize = "commitizen.cz.customize:CustomizeCommitsCz"
107107
[tool.poetry.plugins."commitizen.provider"]
108108
cargo = "commitizen.providers:CargoProvider"
109109
commitizen = "commitizen.providers:CommitizenProvider"
110+
composer = "commitizen.providers:ComposerProvider"
111+
npm = "commitizen.providers:NpmProvider"
110112
pep621 = "commitizen.providers:Pep621Provider"
111113
poetry = "commitizen.providers:PoetryProvider"
112114

tests/test_version_providers.py

+60
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,8 @@
1212
from commitizen.providers import (
1313
CargoProvider,
1414
CommitizenProvider,
15+
ComposerProvider,
16+
NpmProvider,
1517
Pep621Provider,
1618
PoetryProvider,
1719
get_provider,
@@ -125,3 +127,61 @@ def test_cargo_provider(config: BaseConfig, chdir: Path):
125127
version = "43.1"
126128
"""
127129
)
130+
131+
132+
def test_npm_provider(config: BaseConfig, chdir: Path):
133+
package_json = chdir / "package.json"
134+
package_json.write_text(
135+
dedent(
136+
"""\
137+
{
138+
"name": "whatever",
139+
"version": "0.1.0"
140+
}
141+
"""
142+
)
143+
)
144+
config.settings["version_provider"] = "npm"
145+
146+
provider = get_provider(config)
147+
assert isinstance(provider, NpmProvider)
148+
assert provider.get_version() == "0.1.0"
149+
150+
provider.set_version("43.1")
151+
assert package_json.read_text() == dedent(
152+
"""\
153+
{
154+
"name": "whatever",
155+
"version": "43.1"
156+
}
157+
"""
158+
)
159+
160+
161+
def test_composer_provider(config: BaseConfig, chdir: Path):
162+
composer_json = chdir / "composer.json"
163+
composer_json.write_text(
164+
dedent(
165+
"""\
166+
{
167+
"name": "whatever",
168+
"version": "0.1.0"
169+
}
170+
"""
171+
)
172+
)
173+
config.settings["version_provider"] = "composer"
174+
175+
provider = get_provider(config)
176+
assert isinstance(provider, ComposerProvider)
177+
assert provider.get_version() == "0.1.0"
178+
179+
provider.set_version("43.1")
180+
assert composer_json.read_text() == dedent(
181+
"""\
182+
{
183+
"name": "whatever",
184+
"version": "43.1"
185+
}
186+
"""
187+
)

0 commit comments

Comments
 (0)