Skip to content

Commit 165422a

Browse files
authored
Merge pull request #1068 from efiop/master
misc fixes
2 parents 03a3cf2 + 49baf38 commit 165422a

File tree

3 files changed

+51
-2
lines changed

3 files changed

+51
-2
lines changed

dvc/config.py

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -171,7 +171,7 @@ def __init__(self, dvc_dir):
171171
# need to convert our config to dict before passing it to
172172
self._config = self._lower(self._config)
173173
local = self._lower(local)
174-
self._config.update(local)
174+
self._config = self._merge(self._config, local)
175175

176176
self._config = Schema(self.SCHEMA).validate(self._config)
177177

@@ -182,6 +182,17 @@ def __init__(self, dvc_dir):
182182
except Exception as ex:
183183
raise ConfigError(ex)
184184

185+
@staticmethod
186+
def _merge(first, second):
187+
res = {}
188+
sections = list(first.keys()) + list(second.keys())
189+
for section in sections:
190+
f = first.get(section, {}).copy()
191+
s = second.get(section, {}).copy()
192+
f.update(s)
193+
res[section] = f
194+
return res
195+
185196
@staticmethod
186197
def _lower(config):
187198
new_config = {}

dvc/state.py

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -96,7 +96,20 @@ def dump(self):
9696

9797
@staticmethod
9898
def mtime(path):
99-
return str(int(nanotime.timestamp(os.path.getmtime(path))))
99+
if os.path.isdir(path):
100+
mtime = -1
101+
for root, dirs, files in os.walk(path):
102+
for fname in files:
103+
f = os.path.join(root, fname)
104+
m = os.path.getmtime(f)
105+
if m > mtime:
106+
mtime = m
107+
if mtime == -1:
108+
mtime = os.path.getmtime(path)
109+
else:
110+
mtime = os.path.getmtime(path)
111+
112+
return str(int(nanotime.timestamp(mtime)))
100113

101114
@staticmethod
102115
def inode(path):

tests/test_repro.py

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -255,6 +255,31 @@ def test(self):
255255
self.assertEqual(len(stages), 1)
256256

257257

258+
class TestReproChangedDirData(TestDvc):
259+
def test(self):
260+
dir_name = 'dir'
261+
dir_code = 'dir_code.py'
262+
with open(dir_code, 'w+') as fd:
263+
fd.write("import os; import sys; import shutil; shutil.copytree(sys.argv[1], sys.argv[2])")
264+
265+
stage = self.dvc.run(outs=[dir_name],
266+
deps=[self.DATA_DIR, dir_code],
267+
cmd="python {} {} {}".format(dir_code,
268+
self.DATA_DIR,
269+
dir_name))
270+
self.assertTrue(stage is not None)
271+
272+
stages = self.dvc.reproduce(stage.path)
273+
self.assertEqual(len(stages), 0)
274+
275+
with open(self.DATA_SUB, 'a') as fd:
276+
fd.write('add')
277+
278+
stages = self.dvc.reproduce(stage.path)
279+
self.assertEqual(len(stages), 1)
280+
self.assertTrue(stages[0] is not None)
281+
282+
258283
class TestReproMissingMd5InStageFile(TestRepro):
259284
def test(self):
260285
with open(self.file1_stage, 'r') as fd:

0 commit comments

Comments
 (0)