@@ -43,6 +43,24 @@ def __init__(self, attempts: int, *args: object) -> None:
4343)
4444
4545
46+ def _skip_if_git_missing () -> None :
47+ """Skip the calling fixture when the ``git`` binary is unavailable."""
48+ if not shutil .which ("git" ):
49+ pytest .skip (reason = "git is not available" )
50+
51+
52+ def _skip_if_svn_missing () -> None :
53+ """Skip the calling fixture when ``svn`` or ``svnadmin`` is unavailable."""
54+ if not shutil .which ("svn" ) or not shutil .which ("svnadmin" ):
55+ pytest .skip (reason = "svn is not available" )
56+
57+
58+ def _skip_if_hg_missing () -> None :
59+ """Skip the calling fixture when the ``hg`` binary is unavailable."""
60+ if not shutil .which ("hg" ):
61+ pytest .skip (reason = "hg is not available" )
62+
63+
4664DEFAULT_VCS_NAME = "Test user"
4765DEFAULT_VCS_EMAIL = "test@example.com"
4866
@@ -145,13 +163,13 @@ def set_home(
145163
146164
147165@pytest .fixture (scope = "session" )
148- @skip_if_git_missing
149166def vcs_gitconfig (
150167 user_path : pathlib .Path ,
151168 vcs_email : str ,
152169 vcs_name : str ,
153170) -> pathlib .Path :
154171 """Return git configuration, pytest fixture."""
172+ _skip_if_git_missing ()
155173 gitconfig = user_path / ".gitconfig"
156174
157175 gitconfig .write_text (
@@ -173,24 +191,24 @@ def vcs_gitconfig(
173191
174192
175193@pytest .fixture
176- @skip_if_git_missing
177194def set_vcs_gitconfig (
178195 monkeypatch : pytest .MonkeyPatch ,
179196 vcs_gitconfig : pathlib .Path ,
180197) -> pathlib .Path :
181198 """Set git configuration."""
199+ _skip_if_git_missing ()
182200 monkeypatch .setenv ("GIT_CONFIG" , str (vcs_gitconfig ))
183201 monkeypatch .setenv ("GIT_CONFIG_GLOBAL" , str (vcs_gitconfig )) # For child processes
184202 return vcs_gitconfig
185203
186204
187205@pytest .fixture (scope = "session" )
188- @skip_if_hg_missing
189206def vcs_hgconfig (
190207 user_path : pathlib .Path ,
191208 vcs_user : str ,
192209) -> pathlib .Path :
193210 """Return Mercurial configuration."""
211+ _skip_if_hg_missing ()
194212 hgrc = user_path / ".hgrc"
195213 hgrc .write_text (
196214 textwrap .dedent (
@@ -209,12 +227,12 @@ def vcs_hgconfig(
209227
210228
211229@pytest .fixture
212- @skip_if_hg_missing
213230def set_vcs_hgconfig (
214231 monkeypatch : pytest .MonkeyPatch ,
215232 vcs_hgconfig : pathlib .Path ,
216233) -> pathlib .Path :
217234 """Set Mercurial configuration."""
235+ _skip_if_hg_missing ()
218236 monkeypatch .setenv ("HGRCPATH" , str (vcs_hgconfig ))
219237 return vcs_hgconfig
220238
@@ -338,11 +356,11 @@ def empty_git_bare_repo_path(libvcs_test_cache_path: pathlib.Path) -> pathlib.Pa
338356
339357
340358@pytest .fixture (scope = "session" )
341- @skip_if_git_missing
342359def empty_git_bare_repo (
343360 empty_git_bare_repo_path : pathlib .Path ,
344361) -> pathlib .Path :
345362 """Return factory to create git remote repo to for clone / push purposes."""
363+ _skip_if_git_missing ()
346364 if (
347365 empty_git_bare_repo_path .exists ()
348366 and (empty_git_bare_repo_path / ".git" ).exists ()
@@ -357,11 +375,11 @@ def empty_git_bare_repo(
357375
358376
359377@pytest .fixture (scope = "session" )
360- @skip_if_git_missing
361378def empty_git_repo (
362379 empty_git_repo_path : pathlib .Path ,
363380) -> pathlib .Path :
364381 """Return factory to create git remote repo to for clone / push purposes."""
382+ _skip_if_git_missing ()
365383 if empty_git_repo_path .exists () and (empty_git_repo_path / ".git" ).exists ():
366384 return empty_git_repo_path
367385
@@ -373,12 +391,12 @@ def empty_git_repo(
373391
374392
375393@pytest .fixture (scope = "session" )
376- @skip_if_git_missing
377394def create_git_remote_bare_repo (
378395 remote_repos_path : pathlib .Path ,
379396 empty_git_bare_repo : pathlib .Path ,
380397) -> CreateRepoFn :
381398 """Return factory to create git remote repo to for clone / push purposes."""
399+ _skip_if_git_missing ()
382400
383401 def fn (
384402 remote_repos_path : pathlib .Path = remote_repos_path ,
@@ -402,12 +420,12 @@ def fn(
402420
403421
404422@pytest .fixture (scope = "session" )
405- @skip_if_git_missing
406423def create_git_remote_repo (
407424 remote_repos_path : pathlib .Path ,
408425 empty_git_repo : pathlib .Path ,
409426) -> CreateRepoFn :
410427 """Return factory to create git remote repo to for clone / push purposes."""
428+ _skip_if_git_missing ()
411429
412430 def fn (
413431 remote_repos_path : pathlib .Path = remote_repos_path ,
@@ -455,13 +473,13 @@ def git_remote_repo_single_commit_post_init(
455473
456474
457475@pytest .fixture (scope = "session" )
458- @skip_if_git_missing
459476def git_remote_repo (
460477 create_git_remote_repo : CreateRepoFn ,
461478 vcs_gitconfig : pathlib .Path ,
462479 git_commit_envvars : GitCommitEnvVars ,
463480) -> pathlib .Path :
464481 """Copy the session-scoped Git repository to a temporary directory."""
482+ _skip_if_git_missing ()
465483 # TODO: Cache the effect of of this in a session-based repo
466484 repo_path = create_git_remote_repo ()
467485 git_remote_repo_single_commit_post_init (
@@ -519,15 +537,11 @@ def empty_svn_repo_path(libvcs_test_cache_path: pathlib.Path) -> pathlib.Path:
519537
520538
521539@pytest .fixture (scope = "session" )
522- @skip_if_svn_missing
523540def empty_svn_repo (
524541 empty_svn_repo_path : pathlib .Path ,
525542) -> pathlib .Path :
526543 """Return factory to create svn remote repo to for clone / push purposes."""
527- if not shutil .which ("svn" ) or not shutil .which ("svnadmin" ):
528- pytest .skip (
529- reason = "svn is not available" ,
530- )
544+ _skip_if_svn_missing ()
531545
532546 if empty_svn_repo_path .exists () and (empty_svn_repo_path / "conf" ).exists ():
533547 return empty_svn_repo_path
@@ -540,12 +554,12 @@ def empty_svn_repo(
540554
541555
542556@pytest .fixture (scope = "session" )
543- @skip_if_svn_missing
544557def create_svn_remote_repo (
545558 remote_repos_path : pathlib .Path ,
546559 empty_svn_repo : pathlib .Path ,
547560) -> CreateRepoFn :
548561 """Pre-made svn repo, bare, used as a file:// remote to checkout and commit to."""
562+ _skip_if_svn_missing ()
549563
550564 def fn (
551565 remote_repos_path : pathlib .Path = remote_repos_path ,
@@ -572,20 +586,20 @@ def fn(
572586
573587
574588@pytest .fixture (scope = "session" )
575- @skip_if_svn_missing
576589def svn_remote_repo (
577590 create_svn_remote_repo : CreateRepoFn ,
578591) -> pathlib .Path :
579592 """Pre-made. Local file:// based SVN server."""
593+ _skip_if_svn_missing ()
580594 return create_svn_remote_repo ()
581595
582596
583597@pytest .fixture (scope = "session" )
584- @skip_if_svn_missing
585598def svn_remote_repo_with_files (
586599 create_svn_remote_repo : CreateRepoFn ,
587600) -> pathlib .Path :
588601 """Pre-made. Local file:// based SVN server."""
602+ _skip_if_svn_missing ()
589603 repo_path = create_svn_remote_repo ()
590604 svn_remote_repo_single_commit_post_init (remote_repo_path = repo_path )
591605 return repo_path
@@ -629,11 +643,11 @@ def empty_hg_repo_path(libvcs_test_cache_path: pathlib.Path) -> pathlib.Path:
629643
630644
631645@pytest .fixture (scope = "session" )
632- @skip_if_hg_missing
633646def empty_hg_repo (
634647 empty_hg_repo_path : pathlib .Path ,
635648) -> pathlib .Path :
636649 """Return factory to create hg remote repo to for clone / push purposes."""
650+ _skip_if_hg_missing ()
637651 if empty_hg_repo_path .exists () and (empty_hg_repo_path / ".hg" ).exists ():
638652 return empty_hg_repo_path
639653
@@ -645,13 +659,13 @@ def empty_hg_repo(
645659
646660
647661@pytest .fixture (scope = "session" )
648- @skip_if_hg_missing
649662def create_hg_remote_repo (
650663 remote_repos_path : pathlib .Path ,
651664 empty_hg_repo : pathlib .Path ,
652665 vcs_hgconfig : pathlib .Path ,
653666) -> CreateRepoFn :
654667 """Pre-made hg repo, bare, used as a file:// remote to checkout and commit to."""
668+ _skip_if_hg_missing ()
655669
656670 def fn (
657671 remote_repos_path : pathlib .Path = remote_repos_path ,
@@ -681,13 +695,13 @@ def fn(
681695
682696
683697@pytest .fixture (scope = "session" )
684- @skip_if_hg_missing
685698def hg_remote_repo (
686699 remote_repos_path : pathlib .Path ,
687700 create_hg_remote_repo : CreateRepoFn ,
688701 vcs_hgconfig : pathlib .Path ,
689702) -> pathlib .Path :
690703 """Pre-made, file-based repo for push and pull."""
704+ _skip_if_hg_missing ()
691705 repo_path = create_hg_remote_repo ()
692706 hg_remote_repo_single_commit_post_init (
693707 remote_repo_path = repo_path ,
0 commit comments