From e97c1a556345be0199c23204ea89bf6486beb438 Mon Sep 17 00:00:00 2001 From: Ruslan Kuprieiev Date: Wed, 31 Jan 2018 18:18:48 +0200 Subject: [PATCH 1/5] stage: save: remove link from cache if cache already exists Fixes #447 Signed-off-by: Ruslan Kuprieiev --- dvc/stage.py | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/dvc/stage.py b/dvc/stage.py index 30098c977..e59051e52 100644 --- a/dvc/stage.py +++ b/dvc/stage.py @@ -285,7 +285,11 @@ class Output(Dependency): cache = self.project.cache.get(md5) cache_info = os.path.join(self.cache, relpath) - self.hardlink(path, cache) + if os.path.exists(cache): + self._remove(path, None) + self.hardlink(cache, path) + else: + self.hardlink(path, cache) os.makedirs(os.path.dirname(cache_info)) with open(cache_info, 'w') as fd: From 24f8c4ca9fd24575400246f2e793bb4e7bd255c2 Mon Sep 17 00:00:00 2001 From: Ruslan Kuprieiev Date: Fri, 2 Feb 2018 16:51:48 +0200 Subject: [PATCH 2/5] test: add test for adding same data in and inside dir Signed-off-by: Ruslan Kuprieiev --- tests/test_add.py | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/tests/test_add.py b/tests/test_add.py index 0f823bbfd..a5e6e0981 100644 --- a/tests/test_add.py +++ b/tests/test_add.py @@ -59,6 +59,17 @@ class TestAddTrackedFile(TestDvc): self.dvc.add(fname) +class TestAddDirWithExistingCache(TestDvc): + def test(self): + dname = 'a' + fname = os.path.join(dname, 'b') + os.mkdir(dname) + shutil.copyfile(self.FOO, fname) + + self.dvc.add(self.FOO) + self.dvc.add(dname) + + class TestCmdAdd(TestDvc): def test(self): ret = main(['add', From 39f1ba8c5805606e5e1fa9aa2e0fc57f5c7f381c Mon Sep 17 00:00:00 2001 From: Ruslan Kuprieiev Date: Fri, 2 Feb 2018 17:50:16 +0200 Subject: [PATCH 3/5] stage: check if dir exists before calling makedirs Fixes #448 Signed-off-by: Ruslan Kuprieiev --- dvc/stage.py | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/dvc/stage.py b/dvc/stage.py index e59051e52..8aeff60a5 100644 --- a/dvc/stage.py +++ b/dvc/stage.py @@ -284,6 +284,7 @@ class Output(Dependency): md5 = file_md5(path)[0] cache = self.project.cache.get(md5) cache_info = os.path.join(self.cache, relpath) + cache_dir = os.path.dirname(cache_info) if os.path.exists(cache): self._remove(path, None) @@ -291,7 +292,9 @@ class Output(Dependency): else: self.hardlink(path, cache) - os.makedirs(os.path.dirname(cache_info)) + if not os.path.exists(cache_dir): + os.makedirs(cache_dir) + with open(cache_info, 'w') as fd: yaml.safe_dump({self.PARAM_MD5: md5}, fd, default_flow_style=False) From 14ae7811c1146c7a236df40e9ca75cc79688a88e Mon Sep 17 00:00:00 2001 From: Ruslan Kuprieiev Date: Sat, 3 Feb 2018 14:13:04 +0200 Subject: [PATCH 4/5] test: add modified dir test Signed-off-by: Ruslan Kuprieiev --- tests/test_add.py | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/tests/test_add.py b/tests/test_add.py index a5e6e0981..9b5b1e0a8 100644 --- a/tests/test_add.py +++ b/tests/test_add.py @@ -1,4 +1,5 @@ import os +import stat import shutil import filecmp from checksumdir import dirhash @@ -70,6 +71,14 @@ class TestAddDirWithExistingCache(TestDvc): self.dvc.add(dname) +class TestAddModifiedDir(TestDvc): + def test(self): + self.dvc.add(self.DATA_DIR) + os.chmod(self.DATA, stat.S_IWRITE) + os.unlink(self.DATA) + self.dvc.add(self.DATA_DIR) + + class TestCmdAdd(TestDvc): def test(self): ret = main(['add', From a3f2110dd365d6724c0fe0b5cc2fa8986cb83247 Mon Sep 17 00:00:00 2001 From: Ruslan Kuprieiev Date: Sat, 3 Feb 2018 14:26:24 +0200 Subject: [PATCH 5/5] test: add pywin32 dep Signed-off-by: Ruslan Kuprieiev --- test-requirements.txt | 1 + 1 file changed, 1 insertion(+) diff --git a/test-requirements.txt b/test-requirements.txt index a719f4228..5e847837e 100644 --- a/test-requirements.txt +++ b/test-requirements.txt @@ -2,3 +2,4 @@ coverage==4.3.1 codeclimate-test-reporter==0.2.3 xmltodict==0.11.0 awscli==1.14.18 +pywin32; sys_platform == 'nt'