8000 refactor!(pytest plugin[git]) Session-scoped, cached VCS fixtures · vcs-python/libvcs@30d1889 · GitHub
[go: up one dir, main page]

Skip to content

Commit 30d1889

Browse files
committed
refactor!(pytest plugin[git]) Session-scoped, cached VCS fixtures
1 parent bc6e897 commit 30d1889

File tree

1 file changed

+128
-19
lines changed

1 file changed

+128
-19
lines changed

src/libvcs/pytest_plugin.py

Lines changed: 128 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -180,7 +180,7 @@ def clean() -> None:
180180
return path
181181

182182

183-
@pytest.fixture
183+
@pytest.fixture(scope="session")
184184
def remote_repos_path(
185185
user_path: pathlib.Path,
186186
request: pytest.FixtureRequest,
@@ -255,10 +255,111 @@ def _create_git_remote_repo(
255255
return remote_repo_path
256256

257257

258-
@pytest.fixture
258+
def _create_git_remote_repo_full_path(
259+
remote_repo_path: pathlib.Path,
260+
remote_repo_post_init: Optional[CreateRepoPostInitFn] = None,
261+
init_cmd_args: InitCmdArgs = DEFAULT_GIT_REMOTE_REPO_CMD_ARGS,
262+
) -> pathlib.Path:
263+
if init_cmd_args is None:
264+
init_cmd_args = []
265+
run(
266+
["git", "init", remote_repo_path.stem, *init_cmd_args],
267+
cwd=remote_repo_path.parent,
268+
)
269+
270+
if remote_repo_post_init is not None and callable(remote_repo_post_init):
271+
remote_repo_post_init(remote_repo_path=remote_repo_path)
272+
273+
return remote_repo_path
274+
275+
276+
@pytest.fixture(scope="session")
277+
def libvcs_test_cache_path(tmp_path_factory: pytest.TempPathFactory) -> pathlib.Path:
278+
"""Return temporary directory to use as cache path for libvcs tests."""
279+
return tmp_path_factory.mktemp("libvcs-test-cache")
280+
281+
282+
@pytest.fixture(scope="session")
283+
def empty_git_repo_path(libvcs_test_cache_path: pathlib.Path) -> pathlib.Path:
284+
"""Return temporary directory to use for master-copy of a git repo."""
285+
return libvcs_test_cache_path / "empty_git_repo"
286+
287+
288+
@pytest.fixture(scope="session")
289+
def empty_git_bare_repo_path(libvcs_test_cache_path: pathlib.Path) -> pathlib.Path:
290+
"""Return temporary directory to use for master-copy of a bare git repo."""
291+
return libvcs_test_cache_path / "empty_git_bare_repo"
292+
293+
294+
@pytest.fixture(scope="session")
295+
@skip_if_git_missing
296+
def empty_git_bare_repo(
297+
empty_git_bare_repo_path: pathlib.Path,
298+
) -> pathlib.Path:
299+
"""Return factory to create git remote repo to for clone / push purposes."""
300+
if (
301+
empty_git_bare_repo_path.exists()
302+
and (empty_git_bare_repo_path / ".git").exists()
303+
):
304+
return empty_git_bare_repo_path
305+
306+
return _create_git_remote_repo_full_path(
307+
remote_repo_path=empty_git_bare_repo_path,
308+
remote_repo_post_init=None,
309+
init_cmd_args=DEFAULT_GIT_REMOTE_REPO_CMD_ARGS, # --bare
310+
)
311+
312+
313+
@pytest.fixture(scope="session")
314+
@skip_if_git_missing
315+
def empty_git_repo(
316+
empty_git_repo_path: pathlib.Path,
317+
) -> pathlib.Path:
318+
"""Return factory to create git remote repo to for clone / push purposes."""
319+
if empty_git_repo_path.exists() and (empty_git_repo_path / ".git").exists():
320+
return empty_git_repo_path
321+
322+
return _create_git_remote_repo_full_path(
323+
remote_repo_path=empty_git_repo_path,
324+
remote_repo_post_init=None,
325+
init_cmd_args=None,
326+
)
327+
328+
329+
@pytest.fixture(scope="session")
330+
@skip_if_git_missing
331+
def create_git_remote_bare_repo(
332+
remote_repos_path: pathlib.Path,
333+
empty_git_bare_repo: pathlib.Path,
334+
) -> CreateRepoPytestFixtureFn:
335+
"""Return factory to create git remote repo to for clone / push purposes."""
336+
337+
def fn(
338+
remote_repos_path: pathlib.Path = remote_repos_path,
339+
remote_repo_name: Optional[str] = None,
340+
remote_repo_post_init: Optional[CreateRepoPostInitFn] = None,
341+
init_cmd_args: InitCmdArgs = DEFAULT_GIT_REMOTE_REPO_CMD_ARGS,
342+
) -> pathlib.Path:
343+
if remote_repo_name is None:
344+
remote_repo_name = unique_repo_name(remote_repos_path=remote_repos_path)
345+
remote_repo_path = remote_repos_path / remote_repo_name
346+
347+
shutil.copytree(empty_git_bare_repo, remote_repo_path)
348+
349+
assert empty_git_bare_repo.exists()
350+
351+
assert remote_repo_path.exists()
352+
353+
return remote_repo_path
354+
355+
return fn
356+
357+
358+
@pytest.fixture(scope="session")
259359
@skip_if_git_missing
260360
def create_git_remote_repo(
261361
remote_repos_path: pathlib.Path,
362+
empty_git_repo: pathlib.Path,
262363
) -> CreateRepoPytestFixtureFn:
263364
"""Return factory to create git remote repo to for clone / push purposes."""
264365

@@ -268,14 +369,22 @@ def fn(
268369
remote_repo_post_init: Optional[CreateRepoPostInitFn] = None,
269370
init_cmd_args: InitCmdArgs = DEFAULT_GIT_REMOTE_REPO_CMD_ARGS,
270371
) -> pathlib.Path:
271-
return _create_git_remote_repo(
272-
remote_repos_path=remote_repos_path,
273-
remote_repo_name=remote_repo_name
274-
if remote_repo_name is not None
275-
else unique_repo_name(remote_repos_path=remote_repos_path),
276-
remote_repo_post_init=remote_repo_post_init,
277-
init_cmd_args=init_cmd_args,
278-
)
372+
if remote_repo_name is None:
373+
remote_repo_name = unique_repo_name(remote_repos_path=remote_repos_path)
374+
remote_repo_path = remote_repos_path / remote_repo_name
375+
376+
shutil.copytree(empty_git_repo, remote_repo_path)
377+
378+
if remote_repo_post_init is not None and callable(remote_repo_post_init):
379+
remote_repo_post_init(remote_repo_path=remote_repo_path)
380+
381+
assert empty_git_repo.exists()
382+
assert (empty_git_repo / ".git").exists()
383+
384+
assert remote_repo_path.exists()
385+
assert (remote_repo_path / ".git").exists()
386+
387+
return remote_repo_path
279388

280389
return fn
281390

@@ -288,16 +397,16 @@ def git_remote_repo_single_commit_post_init(remote_repo_path: pathlib.Path) -> N
288397
run(["git", "commit", "-m", "test file for dummyrepo"], cwd=remote_repo_path)
289398

290399

291-
@pytest.fixture
400+
@pytest.fixture(scope="session")
292401
@skip_if_git_missing
293-
def git_remote_repo(remote_repos_path: pathlib.Path) -> pathlib.Path:
294-
"""Pre-made git repo w/ 1 commit, used as a file:// remote to clone and push to."""
295-
return _create_git_remote_repo(
296-
remote_repos_path=remote_repos_path,
297-
remote_repo_name="dummyrepo",
298-
remote_repo_post_init=git_remote_repo_single_commit_post_init,
299-
init_cmd_args=None, # Don't do --bare
300-
)
402+
def git_remote_repo(
403+
create_git_remote_repo: CreateRepoPytestFixtureFn,
404+
) -> pathlib.Path:
405+
"""Copy the session-scoped Git repository to a temporary directory."""
406+
# TODO: Cache the effect of of this in a session-based repo
407+
repo_path = create_git_remote_repo()
408+
git_remote_repo_single_commit_post_init(remote_repo_path=repo_path)
409+
return repo_path
301410

302411

303412
def _create_svn_remote_repo(

0 commit comments

Comments
 (0)
0