forked from iterative/dvc
-
Notifications
You must be signed in to change notification settings - Fork 0
/
dir_helpers.py
108 lines (80 loc) · 3.19 KB
/
dir_helpers.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
"""
The goal of this module is making dvc functional tests setup a breeze. This
includes a temporary dir, initializing git and DVC repos and bootstrapping some
file structure.
The cornerstone of these fixtures is `tmp_dir`, which creates a temporary dir
and changes path to it, it might be combined with `scm` and `dvc` to initialize
empty git and DVC repos. `tmp_dir` returns a Path instance, which should save
you from using `open()`, `os` and `os.path` utils many times:
(tmp_dir / "some_file").write_text("some text")
# ...
assert "some text" == (tmp_dir / "some_file").read_text()
assert (tmp_dir / "some_file").exists()
Additionally it provides `.gen()`, `.scm_gen()` and `.dvc_gen()` methods to
bootstrap a required file structure in a single call:
# Generate a dir with files
tmp_dir.gen({"dir": {"file": "file text", "second_file": "..."}})
# Generate a single file, dirs will be created along the way
tmp_dir.gen("dir/file", "file text")
# Generate + git add
tmp_dir.scm_gen({"file1": "...", ...})
# Generate + git add + git commit
tmp_dir.scm_gen({"file1": "...", ...}, commit="add files")
# Generate + dvc add
tmp_dir.dvc_gen({"file1": "...", ...})
# Generate + dvc add + git commit -am "..."
# This commits stages to git not the generated files.
tmp_dir.dvc_gen({"file1": "...", ...}, commit="add files")
Making it easier to bootstrap things has a supergoal of incentivizing a move
from global repo template to creating everything inplace, which:
- makes all path references local to test, enhancing readability
- allows using telling filenames, e.g. "git_tracked_file" instead of "foo"
- does not create unnecessary files
"""
import os
import pytest
__all__ = [
"erepo_dir",
"git_dir",
"git_downstream",
"git_upstream",
"run_head",
]
@pytest.fixture
def run_head(tmp_dir, head_script, dvc):
script = os.path.abspath(tmp_dir / "head.py")
def run(*args, **run_kwargs):
return dvc.run(
**{
"cmd": "python {} {}".format(script, " ".join(args)),
"outs": [dep + "-1" for dep in args],
"deps": list(args),
**run_kwargs,
}
)
return run
@pytest.fixture
def erepo_dir(make_tmp_dir):
return make_tmp_dir("erepo", scm=True, dvc=True)
@pytest.fixture
def git_dir(make_tmp_dir):
path = make_tmp_dir("git-erepo", scm=True)
path.scm.commit("init repo")
return path
class GitRemote:
def __init__(self, tmp_dir, name, url):
self.tmp_dir = tmp_dir
self.remote = name
self.url = url
@pytest.fixture
def git_upstream(tmp_dir, erepo_dir, git_dir, request):
remote = erepo_dir if "dvc" in request.fixturenames else git_dir
url = f"file://{remote.resolve().as_posix()}"
tmp_dir.scm.gitpython.repo.create_remote("upstream", url)
return GitRemote(remote, "upstream", url)
@pytest.fixture
def git_downstream(tmp_dir, erepo_dir, git_dir, request):
remote = erepo_dir if "dvc" in request.fixturenames else git_dir
url = f"file://{tmp_dir.resolve().as_posix()}"
remote.scm.gitpython.repo.create_remote("upstream", url)
return GitRemote(remote, "upstream", url)