Repository: ofek/hatch-vcs

Issue:
setuptools-scm warning raised when `tag-pattern` is not defined
This package defaults to an empty string when `tag-pattern` is not defined by the user:

https://github.com/ofek/hatch-vcs/blob/e186a8b5d97dd9c9f93ae6015139b55411d9011b/hatch_vcs/version_source.py#L17-L26

This is causing `setuptools-scm` to raise a deprecation warning:

```
DeprecationWarning: Error getting the version from source `vcs`: empty regex for tag regex is invalid, using default
```

This warning is coming from https://github.com/pypa/setuptools_scm/blob/102f56a896bc4ea8d4c58d9c49f455f15310de38/src/setuptools_scm/_get_version_impl.py#L167-L175.

I don't know what the best solution is (if one's really needed) other than repeating setuptools_scm's default string value in this codebase.

Hints from issue comments:
@ofek: Could we import the default value? I'm definitely open to PRs!@mihaic: The PyPI version does not include with the fix for this issue. Could we please have a new release?

Solution patch:
diff --git a/hatch.toml b/hatch.toml
index b1c3fe9..e30762a 100644
--- a/hatch.toml
+++ b/hatch.toml
@@ -16,7 +16,7 @@ cov = [
 ]
 
 [[envs.all.matrix]]
-python = ["3.7", "3.8", "3.9", "3.10", "3.11"]
+python = ["3.8", "3.9", "3.10", "3.11", "3.12"]
 
 [envs.lint]
 detached = true
@@ -28,7 +28,7 @@ dependencies = [
 [envs.lint.scripts]
 typing = "mypy --install-types --non-interactive {args:hatch_vcs tests}"
 style = [
-  "ruff {args:.}",
+  "ruff check {args:.}",
   "black --check --diff {args:.}",
 ]
 fmt = [
diff --git a/hatch_vcs/version_source.py b/hatch_vcs/version_source.py
index 3ad713e..dfed7d1 100644
--- a/hatch_vcs/version_source.py
+++ b/hatch_vcs/version_source.py
@@ -53,7 +53,9 @@ class VCSVersionSource(VersionSourceInterface):
         config = deepcopy(self.config_raw_options)
         config.setdefault('root', self.root)
 
-        config.setdefault('tag_regex', self.config_tag_pattern)
+        # Only set for non-empty strings
+        if self.config_tag_pattern:
+            config['tag_regex'] = self.config_tag_pattern
 
         # Only set for non-empty strings
         if self.config_fallback_version:
diff --git a/pyproject.toml b/pyproject.toml
index fbaa025..3dc2bf6 100644
--- a/pyproject.toml
+++ b/pyproject.toml
@@ -57,6 +57,8 @@ skip-string-normalization = true
 [tool.ruff]
 target-version = "py38"
 line-length = 120
+
+[tool.ruff.lint]
 select = [
   "A",
   "B",
@@ -89,16 +91,16 @@ ignore = [
   "FBT002",
 ]
 
-[tool.ruff.isort]
+[tool.ruff.lint.isort]
 known-first-party = ["hatch_vcs"]
 
-[tool.ruff.flake8-quotes]
+[tool.ruff.lint.flake8-quotes]
 inline-quotes = "single"
 
-[tool.ruff.flake8-tidy-imports]
+[tool.ruff.lint.flake8-tidy-imports]
 ban-relative-imports = "all"
 
-[tool.ruff.per-file-ignores]
+[tool.ruff.lint.per-file-ignores]
 # Tests can use relative imports and assertions
 "tests/**/*" = ["TID252", "S101"]
 


Test patch:
diff --git a/tests/conftest.py b/tests/conftest.py
index 9179244..93d7a50 100644
--- a/tests/conftest.py
+++ b/tests/conftest.py
@@ -86,7 +86,8 @@ def create_project(directory, metadata, *, setup_vcs=True, nested=False):
             git('config', '--local', 'user.email', 'foo@bar.baz')
             git('add', '.')
             git('commit', '-m', 'test')
-            git('tag', '1.2.3')
+            # TODO: Confirm that creating a tag without a message locally causes tests to hang
+            git('tag', '1.2.3', '-m', 'test')
 
             if nested:
                 os.chdir(project_dir)
diff --git a/tests/test_version_config.py b/tests/test_version_config.py
index 782a541..14df634 100644
--- a/tests/test_version_config.py
+++ b/tests/test_version_config.py
@@ -1,6 +1,8 @@
 # SPDX-FileCopyrightText: 2022-present Ofek Lev <oss@ofek.dev>
 #
 # SPDX-License-Identifier: MIT
+import warnings
+
 import pytest
 
 from hatch_vcs.version_source import VCSVersionSource
@@ -20,6 +22,23 @@ class TestTagPattern:
         with pytest.raises(TypeError, match='option `tag-pattern` must be a string'):
             _ = version_source.config_tag_pattern
 
+    def test_no_tag_pattern(self, new_project_basic):
+        config = {}
+        version_source = VCSVersionSource(new_project_basic, config)
+
+        assert version_source.config_tag_pattern == ''
+
+        # Should not raise any deprecation warnings
+        with warnings.catch_warnings():
+            warnings.simplefilter('error')
+            _ = version_source.get_version_data()
+
+    def test_custom_tag_pattern_get_version(self, new_project_basic):
+        config = {'tag-pattern': '(?P<version>.+)'}
+        version_source = VCSVersionSource(new_project_basic, config)
+
+        assert version_source.get_version_data() == {'version': '1.2.3'}
+
 
 class TestFallbackVersion:
     def test_correct(self, new_project_basic):