Skip to content

Commit e7d2f47

Browse files
committed
Add default option to RegexSource (#1980)
Signed-off-by: Furetur <furetur@gmail.com>
1 parent 4ebce0e commit e7d2f47

File tree

4 files changed

+35
-2
lines changed

4 files changed

+35
-2
lines changed

backend/src/hatchling/version/core.py

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,8 +18,10 @@ def __init__(self, root: str, relative_path: str) -> None:
1818
self.__path = os.path.normpath(os.path.join(root, relative_path))
1919
self.__cached_read_data: tuple | None = None
2020

21-
def read(self, *, pattern: str | bool) -> str:
21+
def read(self, *, pattern: str | bool, default: str | None = None) -> str:
2222
if not os.path.isfile(self.__path):
23+
if default is not None:
24+
return default
2325
message = f'file does not exist: {self.__relative_path}'
2426
raise OSError(message)
2527

backend/src/hatchling/version/source/regex.py

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,8 +20,13 @@ def get_version_data(self) -> dict:
2020
message = 'option `pattern` must be a string'
2121
raise TypeError(message)
2222

23+
default = self.config.get('default')
24+
if default is not None and not isinstance(default, str):
25+
message = 'option `default` must be a string'
26+
raise TypeError(message)
27+
2328
version_file = VersionFile(self.root, relative_path)
24-
version = version_file.read(pattern=pattern)
29+
version = version_file.read(pattern=pattern, default=default)
2530

2631
return {'version': version, 'version_file': version_file}
2732

docs/plugins/version-source/regex.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,3 +23,4 @@ source = "regex"
2323
| --- | --- |
2424
| `path` (required) | A relative path to a file containing the project's version |
2525
| `pattern` | A regular expression that has a named group called `version` that represents the version. The default pattern looks for a variable named `__version__` or `VERSION` that is set to a string containing the version, optionally prefixed with the lowercase letter `v`. |
26+
| `default` | A value used as the version if the file at path does not exist. |

tests/backend/version/source/test_regex.py

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -117,3 +117,28 @@ def foo():
117117
with temp_dir.as_cwd():
118118
source.set_version('foo', source.get_version_data())
119119
assert source.get_version_data()['version'] == 'foo'
120+
121+
122+
@pytest.mark.parametrize(
123+
('file_contents', 'default', 'expected_version'),
124+
[
125+
('1.2.3', '0.0.0', '1.2.3'),
126+
('1.2.3', '0.0.1', '1.2.3'),
127+
(None, '0.dev', '0.dev'),
128+
(None, '9.9.9', '9.9.9'),
129+
],
130+
)
131+
def test_with_default_value(temp_dir, file_contents, default, expected_version):
132+
source = RegexSource(
133+
str(temp_dir),
134+
{'path': 'x/y', 'pattern': '^(?P<version>.+)$', 'default': default},
135+
)
136+
137+
file_path = temp_dir / 'x' / 'y'
138+
file_path.ensure_parent_dir_exists()
139+
140+
if file_contents is not None:
141+
file_path.write_text(file_contents)
142+
143+
with temp_dir.as_cwd():
144+
assert source.get_version_data()['version'] == expected_version

0 commit comments

Comments
 (0)