|
1 | 1 | from __future__ import annotations
|
2 | 2 |
|
3 | 3 | import json
|
| 4 | +import jsonpath_ng # type: ignore |
4 | 5 | import re
|
5 | 6 | from abc import ABC, abstractmethod
|
6 | 7 | from pathlib import Path
|
@@ -166,6 +167,87 @@ class NpmProvider(JsonProvider):
|
166 | 167 | filename = "package.json"
|
167 | 168 |
|
168 | 169 |
|
| 170 | +class Npm2Provider(VersionProvider): |
| 171 | + """ |
| 172 | + npm package.json and package-lock.json version management |
| 173 | + """ |
| 174 | + |
| 175 | + indent: ClassVar[int] = 2 |
| 176 | + package_filename = "package.json" |
| 177 | + package_expression = "$.version" |
| 178 | + lock_filename = "package-lock.json" |
| 179 | + lock_expressions = ["$.version", "$.packages.''.version"] |
| 180 | + shrinkwrap_filename = "npm-shrinkwrap.json" |
| 181 | + shrinkwrap_expressions = ["$.version", "$.packages.''.version"] |
| 182 | + |
| 183 | + @property |
| 184 | + def package_file(self) -> Path: |
| 185 | + return Path() / self.package_filename |
| 186 | + |
| 187 | + @property |
| 188 | + def lock_file(self) -> Path: |
| 189 | + return Path() / self.lock_filename |
| 190 | + |
| 191 | + @property |
| 192 | + def shrinkwrap_file(self) -> Path: |
| 193 | + return Path() / self.shrinkwrap_filename |
| 194 | + |
| 195 | + def get_version(self) -> str: |
| 196 | + """ |
| 197 | + Get the current version from package.json |
| 198 | + """ |
| 199 | + package_document = json.loads(self.package_file.read_text()) |
| 200 | + return self.get_package_version(package_document) |
| 201 | + |
| 202 | + def set_version(self, version: str): |
| 203 | + package_document = self.set_package_version( |
| 204 | + json.loads(self.package_file.read_text()), version |
| 205 | + ) |
| 206 | + self.package_file.write_text( |
| 207 | + json.dumps(package_document, indent=self.indent) + "\n" |
| 208 | + ) |
| 209 | + if self.lock_file.exists(): |
| 210 | + lock_document = self.set_lock_version( |
| 211 | + json.loads(self.lock_file.read_text()), version |
| 212 | + ) |
| 213 | + self.lock_file.write_text( |
| 214 | + json.dumps(lock_document, indent=self.indent) + "\n" |
| 215 | + ) |
| 216 | + if self.shrinkwrap_file.exists(): |
| 217 | + shrinkwrap_document = self.set_lock_version( |
| 218 | + json.loads(self.shrinkwrap_file.read_text()), version |
| 219 | + ) |
| 220 | + self.shrinkwrap_file.write_text( |
| 221 | + json.dumps(shrinkwrap_document, indent=self.indent) + "\n" |
| 222 | + ) |
| 223 | + |
| 224 | + def get_package_version(self, document: dict[str, Any]) -> str: |
| 225 | + expr = jsonpath_ng.parse(self.package_expression) |
| 226 | + versions = expr.find(document) |
| 227 | + if len(versions) == 0: |
| 228 | + raise ValueError("No version found") |
| 229 | + elif len(versions) > 1: |
| 230 | + raise ValueError("Multiple versions found") |
| 231 | + return versions[0].value # type: ignore |
| 232 | + |
| 233 | + def set_package_version(self, document: dict[str, Any], version: str): |
| 234 | + expr = jsonpath_ng.parse(self.package_expression) |
| 235 | + document = expr.update(document, version) |
| 236 | + return document |
| 237 | + |
| 238 | + def set_lock_version(self, document: dict[str, Any], version: str): |
| 239 | + for expression in self.lock_expressions: |
| 240 | + expr = jsonpath_ng.parse(expression) |
| 241 | + document = expr.update(document, version) |
| 242 | + return document |
| 243 | + |
| 244 | + def set_shrinkwrap_version(self, document: dict[str, Any], version: str): |
| 245 | + for expression in self.shrinkwrap_expressions: |
| 246 | + expr = jsonpath_ng.parse(expression) |
| 247 | + document = expr.update(document, version) |
| 248 | + return document |
| 249 | + |
| 250 | + |
169 | 251 | class ComposerProvider(JsonProvider):
|
170 | 252 | """
|
171 | 253 | Composer version management
|
|
0 commit comments