mirror of
https://github.com/Stone-Red-Code/dvc.git
synced 2026-11-02 07:18:25 +01:00
+41
-29
@@ -261,49 +261,61 @@ class Project(object):
|
||||
return stage
|
||||
|
||||
def move(self, from_path, to_path):
|
||||
"""
|
||||
Renames an output file and modifies the stage associated
|
||||
to reflect the change on the pipeline.
|
||||
|
||||
If the output has the same name as its stage, it would
|
||||
also rename the corresponding stage file.
|
||||
|
||||
E.g.
|
||||
Having: (hello, hello.dvc)
|
||||
|
||||
$ dvc move hello greetings
|
||||
|
||||
Result: (greeting, greeting.dvc)
|
||||
|
||||
It only works with outputs generated by `add` or `import`,
|
||||
also known as data sources.
|
||||
"""
|
||||
import dvc.output as Output
|
||||
from dvc.stage import Stage
|
||||
|
||||
from_out = Output.loads_from(Stage(self, cwd=os.curdir),
|
||||
[from_path])[0]
|
||||
|
||||
found = False
|
||||
self._files_to_git_add = []
|
||||
try:
|
||||
stage, out = next((stage, out)
|
||||
for stage in self.stages()
|
||||
for out in stage.outs
|
||||
if from_out.path == out.path)
|
||||
except StopIteration:
|
||||
raise DvcException("unable to find stage file with output '{path}'"
|
||||
.format(path=from_path))
|
||||
|
||||
if not stage.is_data_source:
|
||||
raise MoveNotDataSourceError(stage.relpath)
|
||||
|
||||
to_out = Output.loads_from(stage, [to_path], out.cache, out.metric)[0]
|
||||
|
||||
with self.state:
|
||||
for stage in self.stages():
|
||||
for out in stage.outs:
|
||||
if out.path != from_out.path:
|
||||
continue
|
||||
out.move(to_out)
|
||||
|
||||
if not stage.is_data_source:
|
||||
raise MoveNotDataSourceError(stage.relpath)
|
||||
stage_name = os.path.splitext(os.path.basename(stage.path))[0]
|
||||
from_name = os.path.basename(from_out.path)
|
||||
|
||||
found = True
|
||||
to_out = Output.loads_from(out.stage,
|
||||
[to_path],
|
||||
out.cache,
|
||||
out.metric)[0]
|
||||
out.move(to_out)
|
||||
if stage_name == from_name:
|
||||
os.unlink(stage.path)
|
||||
|
||||
stage_base = os.path.basename(stage.path)
|
||||
stage_base = stage_base.rstrip(Stage.STAGE_FILE_SUFFIX)
|
||||
stage.path = os.path.join(
|
||||
os.path.dirname(stage.path),
|
||||
os.path.basename(to_path) + Stage.STAGE_FILE_SUFFIX
|
||||
)
|
||||
|
||||
stage_dir = os.path.dirname(stage.path)
|
||||
from_base = os.path.basename(from_path)
|
||||
to_base = os.path.basename(to_path)
|
||||
if stage_base == from_base:
|
||||
os.unlink(stage.path)
|
||||
path = to_base + Stage.STAGE_FILE_SUFFIX
|
||||
stage.path = os.path.join(stage_dir, path)
|
||||
|
||||
stage.dump()
|
||||
stage.dump()
|
||||
|
||||
self._remind_to_git_add()
|
||||
|
||||
if not found:
|
||||
msg = "unable to find dvcfile with output '{}'"
|
||||
raise DvcException(msg.format(from_path))
|
||||
|
||||
def _unprotect_file(self, path):
|
||||
import stat
|
||||
import uuid
|
||||
|
||||
@@ -57,3 +57,22 @@ class TestMoveNotDataSource(TestRepro):
|
||||
|
||||
ret = main(['move', self.file1, 'dst'])
|
||||
self.assertNotEqual(ret, 0)
|
||||
|
||||
|
||||
class TestMoveFileWithExtension(TestDvc):
|
||||
def test(self):
|
||||
with open(os.path.join(self.dvc.root_dir, 'file.csv'), 'w') as fd:
|
||||
fd.write('1,2,3\n')
|
||||
|
||||
self.dvc.add('file.csv')
|
||||
|
||||
self.assertTrue(os.path.exists('file.csv'))
|
||||
self.assertTrue(os.path.exists('file.csv.dvc'))
|
||||
|
||||
ret = main(['move', 'file.csv', 'other_name.csv'])
|
||||
self.assertEqual(ret, 0)
|
||||
|
||||
self.assertFalse(os.path.exists('file.csv'))
|
||||
self.assertFalse(os.path.exists('file.csv.dvc'))
|
||||
self.assertTrue(os.path.exists('other_name.csv'))
|
||||
self.assertTrue(os.path.exists('other_name.csv.dvc'))
|
||||
|
||||
Reference in New Issue
Block a user