Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
21 changes: 16 additions & 5 deletions dvc/output/base.py
Original file line number Diff line number Diff line change
Expand Up @@ -409,12 +409,23 @@ def get_used_cache(self, **kwargs):
cache.external[dep.repo_pair].add(dep.def_path)
return cache

if not self.info:
logger.warning(
"Output '{}'({}) is missing version info. Cache for it will "
"not be collected. Use `dvc repro` to get your pipeline up to "
"date.".format(self, self.stage)
if not self.checksum:
msg = (
"Output '{}'({}) is missing version info. "
"Cache for it will not be collected. "
"Use `dvc repro` to get your pipeline up to date.".format(
self, self.stage
)
)
if self.exists:
msg += (
"\n"
"You can also use `dvc commit {stage}` to associate "
"existing '{out}' with '{stage}'.".format(
out=self, stage=self.stage.relpath
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
out=self, stage=self.stage.relpath
out=self, stage=self.stage

same as above πŸ™‚

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

AFAIK it will result in dvc commit 'Stage file.dvc' ;)

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@pared Oh, but then the upper warning is broken too, right?

Copy link
Copy Markdown
Contributor Author

@pared pared Feb 21, 2020

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@efiop
I wouldn't say so: the upper message is pointing user to which stage particular output is associated to, while the lower one suggests command that can fix your situation. So in the upper one, its not crucial for stage to be printed just as relpath.

)
)
logger.warning(msg)
return NamedCache()

ret = NamedCache.make(self.scheme, self.checksum, str(self))
Expand Down
1 change: 1 addition & 0 deletions tests/func/test_stage.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import os
import tempfile


from dvc.main import main
from dvc.output.local import OutputLOCAL
from dvc.remote.local import RemoteLOCAL
Expand Down
50 changes: 49 additions & 1 deletion tests/unit/output/test_output.py
Original file line number Diff line number Diff line change
@@ -1,8 +1,12 @@
import logging

import pytest
from funcy import first

from voluptuous import Schema, MultipleInvalid

from dvc.output import CHECKSUM_SCHEMA
from dvc.cache import NamedCache
from dvc.output import CHECKSUM_SCHEMA, OutputBase


@pytest.mark.parametrize(
Expand Down Expand Up @@ -40,3 +44,47 @@ def test_checksum_schema(value, expected):
def test_checksum_schema_fail(value):
with pytest.raises(MultipleInvalid):
Schema(CHECKSUM_SCHEMA)(value)["md5"]


@pytest.mark.parametrize(
"exists, expected_message",
[
(
False,
(
"Output 'path'(Stage stage.dvc) is missing version info. "
"Cache for it will not be collected. "
"Use `dvc repro` to get your pipeline up to date."
),
),
(
True,
(
"Output 'path'(Stage stage.dvc) is missing version info. "
"Cache for it will not be collected. "
"Use `dvc repro` to get your pipeline up to date.\n"
"You can also use `dvc commit stage.dvc` to associate "
"existing 'path' with 'stage.dvc'."
),
),
],
)
def test_get_used_cache(exists, expected_message, mocker, caplog):
stage = mocker.MagicMock()
mocker.patch.object(stage, "__str__", return_value="Stage stage.dvc")
mocker.patch.object(stage, "relpath", "stage.dvc")

output = OutputBase(stage, "path")

mocker.patch.object(output, "use_cache", True)
mocker.patch.object(stage, "is_repo_import", False)
mocker.patch.object(
OutputBase, "checksum", new_callable=mocker.PropertyMock
).return_value = None
mocker.patch.object(
OutputBase, "exists", new_callable=mocker.PropertyMock
).return_value = exists

with caplog.at_level(logging.WARNING, logger="dvc"):
assert isinstance(output.get_used_cache(), NamedCache)
assert first(caplog.messages) == expected_message