diff --git a/dvc/output/local.py b/dvc/output/local.py index 859c64621..c3b6688f3 100644 --- a/dvc/output/local.py +++ b/dvc/output/local.py @@ -87,8 +87,9 @@ class LocalOutput(BaseOutput): name = "metrics" if self.metric else "plot" if os.path.isdir(path): - msg = "directory '{}' cannot be used as {}." - raise IsADirectoryError(msg.format(self.path_info, name)) + msg = "directory '%s' cannot be used as %s." + logger.debug(msg, str(self.path_info), name) + return if not istextfile(path): msg = "binary file '{}' cannot be used as {}." diff --git a/tests/dir_helpers.py b/tests/dir_helpers.py index 6d1abf813..30fdfd295 100644 --- a/tests/dir_helpers.py +++ b/tests/dir_helpers.py @@ -299,7 +299,12 @@ def git_init(path): def run_copy(tmp_dir, dvc): tmp_dir.gen( "copy.py", - "import sys, shutil\nshutil.copyfile(sys.argv[1], sys.argv[2])", + ( + "import sys, shutil, os\n" + "shutil.copyfile(sys.argv[1], sys.argv[2]) " + "if os.path.isfile(sys.argv[1]) " + "else shutil.copytree(sys.argv[1], sys.argv[2])" + ), ) def run_copy(src, dst, **run_kwargs): diff --git a/tests/func/test_run_single_stage.py b/tests/func/test_run_single_stage.py index b43e91437..3f6265ec2 100644 --- a/tests/func/test_run_single_stage.py +++ b/tests/func/test_run_single_stage.py @@ -992,32 +992,17 @@ def test_should_raise_on_stage_output(tmp_dir, dvc, run_copy): run_copy("foo", "name.dvc", single_stage=True) -class TestRunDirMetrics: - @pytest.fixture(autouse=True) - def setup(self, dvc): - with open("script.py", "w+") as fobj: - fobj.write("import sys\n") - fobj.write("import os\n") - fobj.write("os.makedirs(sys.argv[1])\n") - fobj.write( - "with open(os.path.join(sys.argv[1], " - "'metrics.json'), 'a+') as fobj:\n" - ) - fobj.write(" fobj.write('foo')\n") - - def test_metrics_dir_cached(self, dvc): - with pytest.raises(IsADirectoryError): - dvc.run( - cmd="python script.py dir", metrics=["dir"], single_stage=True, - ) - - def test_metrics_dir_not_cached(self, dvc): - with pytest.raises(IsADirectoryError): - dvc.run( - cmd="python script.py dir", - metrics_no_cache=["dir"], - single_stage=True, - ) +@pytest.mark.parametrize( + "metrics_type", ["metrics", "metrics_no_cache"], +) +def test_metrics_dir(tmp_dir, dvc, caplog, run_copy_metrics, metrics_type): + copyargs = {metrics_type: ["dir_metric"]} + tmp_dir.gen({"dir": {"file": "content"}}) + with caplog.at_level(logging.DEBUG, "dvc"): + run_copy_metrics("dir", "dir_metric", **copyargs) + assert ( + "directory 'dir_metric' cannot be used as metrics." in caplog.messages + ) def test_run_force_doesnot_preserve_comments_and_meta(tmp_dir, dvc, run_copy):