Files
dvc/tests/func/test_install.py
T
Gunnlaugur Thor Briem e917ce0ae8 dvc: hooks only act in branches where dvc active (#2338)
* dvc: hooks only act in branches where dvc active

In a branch where DVC hasn't been initialized (as detected by
`git ls-files .dvc` not listing any files), don't invoke dvc in the git hooks.
This avoids trouble when switching between branches with and without dvc
initialized.

Fixes #2208

* dvc: simplify hooks per PR comment
2019-07-29 16:26:49 +03:00

100 lines
3.0 KiB
Python

import os
import sys
import pytest
from dvc.utils import file_md5
from dvc.main import main
from dvc.stage import Stage
@pytest.mark.skipif(
sys.platform == "win32", reason="Git hooks aren't supported on Windows"
)
class TestInstall(object):
def _hook(self, name):
return os.path.join(".git", "hooks", name)
def test_should_create_hooks(self, git, dvc_repo):
assert main(["install"]) == 0
hooks_with_commands = [
("post-checkout", "exec dvc checkout"),
("pre-commit", "exec dvc status"),
("pre-push", "exec dvc push"),
]
for fname, command in hooks_with_commands:
assert os.path.isfile(self._hook(fname))
with open(self._hook(fname), "r") as fobj:
assert command in fobj.read()
def test_should_append_hooks_if_file_already_exists(self, git, dvc_repo):
with open(self._hook("post-checkout"), "w") as fobj:
fobj.write("#!/bin/sh\n" "echo hello\n")
assert main(["install"]) == 0
expected_script = (
"#!/bin/sh\n"
"echo hello\n"
'[ -z "$(git ls-files .dvc)" ] || exec dvc checkout\n'
)
with open(self._hook("post-checkout"), "r") as fobj:
assert fobj.read() == expected_script
def test_should_be_idempotent(self, git, dvc_repo):
assert main(["install"]) == 0
assert main(["install"]) == 0
expected_script = (
"#!/bin/sh\n"
'[ -z "$(git ls-files .dvc)" ] || exec dvc checkout\n'
)
with open(self._hook("post-checkout"), "r") as fobj:
assert fobj.read() == expected_script
def test_should_post_checkout_hook_checkout(self, repo_dir, git, dvc_repo):
assert main(["install"]) == 0
stage_file = repo_dir.FOO + Stage.STAGE_FILE_SUFFIX
dvc_repo.add(repo_dir.FOO)
dvc_repo.scm.add([".gitignore", stage_file])
dvc_repo.scm.commit("add")
os.unlink(repo_dir.FOO)
dvc_repo.scm.checkout("new_branc", create_new=True)
assert os.path.isfile(repo_dir.FOO)
def test_should_pre_push_hook_push(self, repo_dir, git, dvc_repo):
assert main(["install"]) == 0
temp = repo_dir.mkdtemp()
git_remote = os.path.join(temp, "project.git")
storage_path = os.path.join(temp, "dvc_storage")
foo_checksum = file_md5(repo_dir.FOO)[0]
expected_cache_path = dvc_repo.cache.local.get(foo_checksum)
ret = main(["remote", "add", "-d", "store", storage_path])
assert ret == 0
ret = main(["add", repo_dir.FOO])
assert ret == 0
stage_file = repo_dir.FOO + Stage.STAGE_FILE_SUFFIX
dvc_repo.scm.git.index.add([stage_file, ".gitignore"])
dvc_repo.scm.git.index.commit("commit message")
dvc_repo.scm.git.clone(git_remote)
dvc_repo.scm.git.create_remote("origin", git_remote)
dvc_repo.scm.git.git.push("origin", "master")
assert os.path.isfile(expected_cache_path)