dvc: introduce dvc install for installing git hooks

Fixes #277
Fixes #657

Signed-off-by: Ruslan Kuprieiev <[email protected]>
This commit is contained in:
Ruslan Kuprieiev
2018-04-24 10:47:22 +03:00
parent 347338837b
commit 441098b35e
6 changed files with 57 additions and 0 deletions
+8
View File
@@ -18,6 +18,7 @@ from dvc.command.config import CmdConfig
from dvc.command.checkout import CmdCheckout
from dvc.command.remote import CmdRemoteAdd, CmdRemoteRemove, CmdRemoteModify
from dvc.command.metrics import CmdMetrics
from dvc.command.install import CmdInstall
from dvc.stage import Stage
from dvc import VERSION
@@ -341,6 +342,13 @@ def parse_args(argv=None):
help='Headed TSV path \'row,column\'(e.g. \'Name,3\'')
metrics_parser.set_defaults(func=CmdMetrics)
# Install
install_parser = subparsers.add_parser(
'install',
parents=[parent_parser],
help='Install dvc hooks into the repository')
install_parser.set_defaults(func=CmdInstall)
args = parser.parse_args(argv)
return args
+13
View File
@@ -0,0 +1,13 @@
from dvc.project import Project
from dvc.logger import Logger
from dvc.command.common.base import CmdBase
class CmdInstall(CmdBase):
def run_cmd(self):
try:
self.project.install()
except Exception as e:
Logger.error('Failed to install dvc hooks', e)
return 1
return 0
+3
View File
@@ -91,6 +91,9 @@ class Project(object):
return Project(root_dir)
def install(self):
self.scm.install()
def to_dvc_path(self, path):
return os.path.relpath(path, self.root_dir)
+11
View File
@@ -55,6 +55,9 @@ class Base(object):
def list_branches(self):
pass
def install(self):
pass
class Git(Base):
GITIGNORE = '.gitignore'
@@ -145,6 +148,14 @@ class Git(Base):
def list_branches(self):
return [h.name for h in self.repo.heads]
def install(self):
hook = os.path.join(self.root_dir, self.GIT_DIR, 'hooks', 'post-checkout')
if os.path.isfile(hook):
raise SCMError('Git hook \'{}\' already exists.'.format(os.path.relpath(hook)))
with open(hook, 'w+') as fd:
fd.write('#!/bin/sh\nexec dvc checkout\n')
os.chmod(hook, 0o777)
def SCM(root_dir=os.curdir, no_scm=False):
if Git.is_repo(root_dir):
+3
View File
@@ -4,4 +4,7 @@ from subprocess import check_call
REPO_ROOT = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
os.chdir(REPO_ROOT)
os.putenv('PATH', '{}:{}'.format(os.path.join(REPO_ROOT, 'bin'), os.getenv('PATH')))
os.putenv('DVC_HOME', REPO_ROOT)
check_call('nosetests --cover-inclusive --cover-erase --cover-package=dvc --with-coverage', shell=True)
+19
View File
@@ -0,0 +1,19 @@
import os
from dvc.main import main
from tests.basic_env import TestDvc
class TestInit(TestDvc):
def test(self):
ret = main(['install'])
self.assertEqual(ret, 0)
self.assertTrue(os.path.isfile('.git/hooks/post-checkout'))
self.dvc.add(self.FOO)
os.unlink(self.FOO)
self.dvc.scm.checkout('branch', create_new=True)
self.assertTrue(os.path.isfile(self.FOO))