Skip to content

Commit ffd66c4

Browse files
refactor configuring the Workdir class for tests
- methods to setup the scm's - move skipping to the helper methods - unify construction
1 parent d4e727e commit ffd66c4

File tree

9 files changed

+112
-122
lines changed

9 files changed

+112
-122
lines changed

CHANGELOG.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@
1717

1818
### changed
1919

20-
- refine activation logic and add unittest for the relevant cases instead of trying to speedrun setuptools
20+
- refine activation logic and add unittest for the relevant cases instead of trying to speedrun setuptools
2121

2222
## v9.1.1
2323

testing/conftest.py

Lines changed: 16 additions & 44 deletions
Original file line numberDiff line numberDiff line change
@@ -27,16 +27,6 @@ def pytest_configure(config: pytest.Config) -> None:
2727
os.environ["SOURCE_DATE_EPOCH"] = "1234567890"
2828
os.environ["SETUPTOOLS_SCM_DEBUG"] = "1"
2929

30-
# Register custom markers
31-
config.addinivalue_line(
32-
"markers",
33-
"git: mark test to use git SCM",
34-
)
35-
config.addinivalue_line(
36-
"markers",
37-
"hg: mark test to use mercurial SCM",
38-
)
39-
4030

4131
VERSION_PKGS = ["setuptools", "setuptools_scm", "packaging", "build", "wheel"]
4232

@@ -99,48 +89,30 @@ def debug_mode() -> Iterator[DebugMode]:
9989

10090

10191
def setup_git_wd(wd: WorkDir, monkeypatch: pytest.MonkeyPatch | None = None) -> WorkDir:
102-
"""Set up a WorkDir with git initialized and configured for testing."""
103-
if monkeypatch:
104-
monkeypatch.delenv("HOME", raising=False)
105-
wd("git init")
106-
wd("git config user.email [email protected]")
107-
wd('git config user.name "a test"')
108-
wd.add_command = "git add ."
109-
wd.commit_command = "git commit -m test-{reason}"
110-
wd.tag_command = "git tag {tag}"
111-
return wd
92+
"""Set up a WorkDir with git initialized and configured for testing.
93+
94+
Note: This is a compatibility wrapper. Consider using wd.setup_git() directly.
95+
"""
96+
return wd.setup_git(monkeypatch)
11297

11398

11499
def setup_hg_wd(wd: WorkDir) -> WorkDir:
115-
"""Set up a WorkDir with mercurial initialized and configured for testing."""
116-
wd("hg init")
117-
wd.add_command = "hg add ."
118-
wd.commit_command = 'hg commit -m test-{reason} -u test -d "0 0"'
119-
wd.tag_command = "hg tag {tag}"
120-
return wd
100+
"""Set up a WorkDir with mercurial initialized and configured for testing.
101+
102+
Note: This is a compatibility wrapper. Consider using wd.setup_hg() directly.
103+
"""
104+
return wd.setup_hg()
121105

122106

123107
@pytest.fixture
124-
def wd(
125-
tmp_path: Path, request: pytest.FixtureRequest, monkeypatch: pytest.MonkeyPatch
126-
) -> WorkDir:
127-
"""WorkDir fixture that automatically configures SCM based on markers."""
108+
def wd(tmp_path: Path) -> WorkDir:
109+
"""Base WorkDir fixture that returns an unconfigured working directory.
110+
111+
Individual test modules should override this fixture to set up specific SCM configurations.
112+
"""
128113
target_wd = tmp_path.resolve() / "wd"
129114
target_wd.mkdir()
130-
wd = WorkDir(target_wd)
131-
132-
# Check for SCM markers on the test function or module
133-
git_marker = request.node.get_closest_marker("git")
134-
hg_marker = request.node.get_closest_marker("hg")
135-
136-
# Configure SCM based on markers
137-
if git_marker:
138-
setup_git_wd(wd, monkeypatch)
139-
elif hg_marker:
140-
setup_hg_wd(wd)
141-
# If no SCM markers, return unconfigured workdir
142-
143-
return wd
115+
return WorkDir(target_wd)
144116

145117

146118
@pytest.fixture(scope="session")

testing/test_better_root_errors.py

Lines changed: 7 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -16,32 +16,13 @@
1616
from setuptools_scm._get_version_impl import _version_missing
1717
from testing.wd_wrapper import WorkDir
1818

19-
20-
def setup_git_repo(wd: WorkDir) -> WorkDir:
21-
"""Set up a git repository for testing."""
22-
wd("git init")
23-
wd("git config user.email [email protected]")
24-
wd('git config user.name "a test"')
25-
wd.add_command = "git add ."
26-
wd.commit_command = "git commit -m test-{reason}"
27-
return wd
28-
29-
30-
def setup_hg_repo(wd: WorkDir) -> WorkDir:
31-
"""Set up a mercurial repository for testing."""
32-
try:
33-
wd("hg init")
34-
wd.add_command = "hg add ."
35-
wd.commit_command = 'hg commit -m test-{reason} -u test -d "0 0"'
36-
return wd
37-
except Exception:
38-
pytest.skip("hg not available")
19+
# No longer need to import setup functions - using WorkDir methods directly
3920

4021

4122
def test_find_scm_in_parents_finds_git(wd: WorkDir) -> None:
4223
"""Test that _find_scm_in_parents correctly finds git repositories in parent directories."""
4324
# Set up git repo in root
44-
setup_git_repo(wd)
25+
wd.setup_git()
4526

4627
# Create a subdirectory structure
4728
subdir = wd.cwd / "subproject" / "nested"
@@ -57,7 +38,7 @@ def test_find_scm_in_parents_finds_git(wd: WorkDir) -> None:
5738
def test_find_scm_in_parents_finds_hg(wd: WorkDir) -> None:
5839
"""Test that _find_scm_in_parents correctly finds mercurial repositories in parent directories."""
5940
# Set up hg repo in root
60-
setup_hg_repo(wd)
41+
wd.setup_hg()
6142

6243
# Create a subdirectory structure
6344
subdir = wd.cwd / "subproject" / "nested"
@@ -85,7 +66,7 @@ def test_find_scm_in_parents_returns_none(wd: WorkDir) -> None:
8566
def test_version_missing_with_scm_in_parent(wd: WorkDir) -> None:
8667
"""Test that _version_missing provides helpful error message when SCM is found in parent."""
8768
# Set up git repo in root
88-
setup_git_repo(wd)
69+
wd.setup_git()
8970

9071
# Create a subdirectory structure
9172
subdir = wd.cwd / "subproject" / "nested"
@@ -130,7 +111,7 @@ def test_version_missing_no_scm_found(wd: WorkDir) -> None:
130111
def test_version_missing_with_relative_to_set(wd: WorkDir) -> None:
131112
"""Test that when relative_to is set, we don't search parents for error messages."""
132113
# Set up git repo in root
133-
setup_git_repo(wd)
114+
wd.setup_git()
134115

135116
# Create a subdirectory structure
136117
subdir = wd.cwd / "subproject" / "nested"
@@ -161,7 +142,7 @@ def test_search_parent_directories_works_as_suggested(
161142
) -> None:
162143
"""Test that the suggested search_parent_directories=True solution actually works."""
163144
# Set up git repo
164-
setup_git_repo(wd)
145+
wd.setup_git()
165146
wd.commit_testfile() # Make sure there's a commit for version detection
166147

167148
# Create a subdirectory
@@ -182,7 +163,7 @@ def test_integration_better_error_from_nested_directory(
182163
) -> None:
183164
"""Integration test: get_version from nested directory should give helpful error."""
184165
# Set up git repo
185-
setup_git_repo(wd)
166+
wd.setup_git()
186167

187168
# Create a subdirectory
188169
subdir = wd.cwd / "subproject"

testing/test_file_finder.py

Lines changed: 3 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -18,21 +18,9 @@ def inwd(
1818
) -> WorkDir:
1919
param: str = request.param # type: ignore[attr-defined]
2020
if param == "git":
21-
try:
22-
wd("git init")
23-
except OSError:
24-
pytest.skip("git executable not found")
25-
wd("git config user.email [email protected]")
26-
wd('git config user.name "a test"')
27-
wd.add_command = "git add ."
28-
wd.commit_command = "git commit -m test-{reason}"
21+
wd.setup_git(monkeypatch)
2922
elif param == "hg":
30-
try:
31-
wd("hg init")
32-
except OSError:
33-
pytest.skip("hg executable not found")
34-
wd.add_command = "hg add ."
35-
wd.commit_command = 'hg commit -m test-{reason} -u test -d "0 0"'
23+
wd.setup_hg()
3624
(wd.cwd / "file1").touch()
3725
adir = wd.cwd / "adir"
3826
adir.mkdir()
@@ -249,10 +237,7 @@ def test_archive(
249237

250238
@pytest.fixture
251239
def hg_wd(wd: WorkDir, monkeypatch: pytest.MonkeyPatch) -> WorkDir:
252-
try:
253-
wd("hg init")
254-
except OSError:
255-
pytest.skip("hg executable not found")
240+
wd.setup_hg()
256241
(wd.cwd / "file").touch()
257242
wd("hg add file")
258243
monkeypatch.chdir(wd.cwd)

testing/test_git.py

Lines changed: 5 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -34,27 +34,14 @@
3434
from .conftest import DebugMode
3535
from .wd_wrapper import WorkDir
3636

37-
pytestmark = pytest.mark.skipif(
38-
not has_command("git", warn=False), reason="git executable not found"
39-
)
40-
41-
42-
def setup_git_wd(wd: WorkDir, monkeypatch: pytest.MonkeyPatch | None = None) -> WorkDir:
43-
"""Set up a WorkDir with git initialized and configured for testing."""
44-
if monkeypatch:
45-
monkeypatch.delenv("HOME", raising=False)
46-
wd("git init")
47-
wd("git config user.email [email protected]")
48-
wd('git config user.name "a test"')
49-
wd.add_command = "git add ."
50-
wd.commit_command = "git commit -m test-{reason}"
51-
return wd
37+
# Note: Git availability is now checked in WorkDir.setup_git() method
5238

5339

54-
@pytest.fixture(name="wd")
40+
@pytest.fixture
5541
def wd(wd: WorkDir, monkeypatch: pytest.MonkeyPatch, debug_mode: DebugMode) -> WorkDir:
42+
"""Set up git for git-specific tests."""
5643
debug_mode.disable()
57-
setup_git_wd(wd, monkeypatch)
44+
wd.setup_git(monkeypatch)
5845
debug_mode.enable()
5946
return wd
6047

@@ -685,7 +672,7 @@ def test_fail_on_missing_submodules_with_uninitialized_submodules(
685672
# Create a test repository with a .gitmodules file but no actual submodule
686673
test_repo = tmp_path / "test_repo"
687674
test_repo.mkdir()
688-
test_wd = setup_git_wd(WorkDir(test_repo))
675+
test_wd = WorkDir(test_repo).setup_git()
689676

690677
# Create a fake .gitmodules file (this simulates what happens after cloning without --recurse-submodules)
691678
gitmodules_content = """[submodule "external"]

testing/test_integration.py

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -34,8 +34,11 @@
3434
c = Configuration()
3535

3636

37-
# File-level marker for git tests
38-
pytestmark = pytest.mark.git
37+
# Module-level fixture for git SCM setup
38+
@pytest.fixture
39+
def wd(wd: WorkDir, monkeypatch: pytest.MonkeyPatch) -> WorkDir:
40+
"""Set up git for integration tests."""
41+
return wd.setup_git(monkeypatch)
3942

4043

4144
def test_pyproject_support(tmp_path: Path, monkeypatch: pytest.MonkeyPatch) -> None:

testing/test_main.py

Lines changed: 1 addition & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -22,11 +22,7 @@ def test_main() -> None:
2222

2323
@pytest.fixture
2424
def repo(wd: WorkDir) -> WorkDir:
25-
wd("git init")
26-
wd("git config user.email user@host")
27-
wd("git config user.name user")
28-
wd.add_command = "git add ."
29-
wd.commit_command = "git commit -m test-{reason}"
25+
wd.setup_git()
3026

3127
wd.write("README.rst", "My example")
3228
wd.add_and_commit()

testing/test_mercurial.py

Lines changed: 3 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -10,23 +10,18 @@
1010

1111
from setuptools_scm import Configuration
1212
from setuptools_scm._run_cmd import CommandNotFoundError
13-
from setuptools_scm._run_cmd import has_command
1413
from setuptools_scm.hg import archival_to_version
1514
from setuptools_scm.hg import parse
1615
from setuptools_scm.version import format_version
1716
from testing.wd_wrapper import WorkDir
1817

19-
pytestmark = pytest.mark.skipif(
20-
not has_command("hg", warn=False), reason="hg executable not found"
21-
)
18+
# Note: Mercurial availability is now checked in WorkDir.setup_hg() method
2219

2320

2421
@pytest.fixture
2522
def wd(wd: WorkDir) -> WorkDir:
26-
wd("hg init")
27-
wd.add_command = "hg add ."
28-
wd.commit_command = 'hg commit -m test-{reason} -u test -d "0 0"'
29-
return wd
23+
"""Set up mercurial for hg-specific tests."""
24+
return wd.setup_hg()
3025

3126

3227
archival_mapping = {

testing/wd_wrapper.py

Lines changed: 71 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,8 +3,16 @@
33
import itertools
44

55
from pathlib import Path
6+
from typing import TYPE_CHECKING
67
from typing import Any
78

9+
import pytest
10+
11+
from setuptools_scm._run_cmd import has_command
12+
13+
if TYPE_CHECKING:
14+
pass
15+
816

917
class WorkDir:
1018
"""a simple model for a"""
@@ -126,3 +134,66 @@ def create_tag(self, tag: str = "1.0.0") -> None:
126134
self(self.tag_command, tag=tag)
127135
else:
128136
raise RuntimeError("No tag_command configured")
137+
138+
def configure_git_commands(self) -> None:
139+
"""Configure git commands without initializing the repository."""
140+
self.add_command = "git add ."
141+
self.commit_command = "git commit -m test-{reason}"
142+
self.tag_command = "git tag {tag}"
143+
144+
def configure_hg_commands(self) -> None:
145+
"""Configure mercurial commands without initializing the repository."""
146+
self.add_command = "hg add ."
147+
self.commit_command = 'hg commit -m test-{reason} -u test -d "0 0"'
148+
self.tag_command = "hg tag {tag}"
149+
150+
def setup_git(
151+
self, monkeypatch: pytest.MonkeyPatch | None = None, *, init: bool = True
152+
) -> WorkDir:
153+
"""Set up git SCM for this WorkDir.
154+
155+
Args:
156+
monkeypatch: Optional pytest MonkeyPatch to clear HOME environment
157+
init: Whether to initialize the git repository (default: True)
158+
159+
Returns:
160+
Self for method chaining
161+
162+
Raises:
163+
pytest.skip: If git executable is not found
164+
"""
165+
if not has_command("git", warn=False):
166+
pytest.skip("git executable not found")
167+
168+
self.configure_git_commands()
169+
170+
if init:
171+
if monkeypatch:
172+
monkeypatch.delenv("HOME", raising=False)
173+
self("git init")
174+
self("git config user.email [email protected]")
175+
self('git config user.name "a test"')
176+
177+
return self
178+
179+
def setup_hg(self, *, init: bool = True) -> WorkDir:
180+
"""Set up mercurial SCM for this WorkDir.
181+
182+
Args:
183+
init: Whether to initialize the mercurial repository (default: True)
184+
185+
Returns:
186+
Self for method chaining
187+
188+
Raises:
189+
pytest.skip: If hg executable is not found
190+
"""
191+
if not has_command("hg", warn=False):
192+
pytest.skip("hg executable not found")
193+
194+
self.configure_hg_commands()
195+
196+
if init:
197+
self("hg init")
198+
199+
return self

0 commit comments

Comments
 (0)