dvc: check stage filename

Fixes #1054

Signed-off-by: Ruslan Kuprieiev <[email protected]>
This commit is contained in:
Ruslan Kuprieiev
2018-08-24 18:45:56 +03:00
parent 93ef937fc2
commit fa89ec8789
3 changed files with 42 additions and 6 deletions
+6 -1
View File
@@ -217,7 +217,12 @@ def parse_args(argv=None):
run_parser.add_argument(
'-f',
'--file',
help='Specify name of the state file.')
help="Specify name of the stage file. It should be "
"either 'Dvcfile' or have a '.dvc' suffix (e.g. "
"'prepare.dvc', 'clean.dvc', etc) in order for "
"dvc to be able to find it later. By default "
"the first output basename + .dvc is used as "
"a stage filename.")
run_parser.add_argument(
'-c',
'--cwd',
+24 -4
View File
@@ -36,6 +36,13 @@ class StageFileIsNotDvcFileError(DvcException):
super(StageFileIsNotDvcFileError, self).__init__(msg)
class StageFileBadNameError(DvcException):
def __init__(self, fname):
msg = "Bad stage filename '{}'. Stage files should be named " \
"'Dvcfile' or have a '.dvc' suffix(e.g. '{}.dvc')."
super(StageFileBadNameError, self).__init__(msg.format(fname, fname))
class MissingDataSource(DvcException):
def __init__(self, missing_files):
assert len(missing_files) > 0
@@ -93,16 +100,20 @@ class Stage(object):
return self.cmd is None
@staticmethod
def is_stage_file(path):
if not os.path.isfile(path):
return False
def is_stage_filename(path):
if not path.endswith(Stage.STAGE_FILE_SUFFIX) \
and os.path.basename(path) != Stage.STAGE_FILE:
return False
return True
@staticmethod
def is_stage_file(path):
if not os.path.isfile(path):
return False
return Stage.is_stage_filename(path)
def changed_md5(self):
md5 = self.dumpd().get(self.PARAM_MD5, None)
@@ -276,6 +287,11 @@ class Stage(object):
return stage
@staticmethod
def _check_dvc_filename(fname):
if not Stage.is_stage_filename(fname):
raise StageFileBadNameError(os.path.relpath(fname))
@staticmethod
def _check_dvc_file(fname):
sname = fname + Stage.STAGE_FILE_SUFFIX
@@ -288,6 +304,8 @@ class Stage(object):
Stage._check_dvc_file(fname)
raise StageFileDoesNotExistError(fname)
Stage._check_dvc_filename(fname)
if not Stage.is_stage_file(fname):
Stage._check_dvc_file(fname)
raise StageFileIsNotDvcFileError(fname)
@@ -320,6 +338,8 @@ class Stage(object):
if not fname:
fname = self.path
self._check_dvc_filename(fname)
msg = "Saving information to '{}'.".format(os.path.relpath(fname))
Logger.info(msg)
+12 -1
View File
@@ -3,7 +3,7 @@ import filecmp
from dvc.main import main
from dvc.utils import file_md5
from dvc.stage import Stage
from dvc.stage import Stage, StageFileBadNameError
from dvc.command.run import CmdRun
from dvc.exceptions import OutputDuplicationError
@@ -55,6 +55,17 @@ class TestRunEmpty(TestDvc):
cwd=os.curdir)
class TestRunBadStageFilename(TestDvc):
def test(self):
with self.assertRaises(StageFileBadNameError):
self.dvc.run(cmd='',
deps=[],
outs=[],
outs_no_cache=[],
fname='empty',
cwd=os.curdir)
class TestRunNoExec(TestDvc):
def test(self):
self.dvc.run(cmd='python {} {} {}'.format(self.CODE, self.FOO, 'out'),