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
32 changes: 20 additions & 12 deletions dvc/command/diff.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,19 +11,31 @@
logger = logging.getLogger(__name__)


def _show_md(diff):
def _digest(checksum):
if isinstance(checksum, str):
return checksum[0:8]
return "{}..{}".format(checksum["old"][0:8], checksum["new"][0:8])


def _show_md(diff, show_hash=False):
from dvc.utils.diff import table

header = ["Status", "Hash", "Path"] if show_hash else ["Status", "Path"]
rows = []
for status in ["added", "deleted", "modified"]:
entries = diff.get(status, [])
if not entries:
continue
paths = sorted(entry["path"] for entry in entries)
for path in paths:
rows.append([status, path])
sorted_entries = sorted(entries, key=lambda entry: entry["path"])
for entry in sorted_entries:
path = entry["path"]
if show_hash:
check_sum = _digest(entry.get("hash", ""))
rows.append([status, check_sum, path])
else:
rows.append([status, path])

return table(["Status", "Path"], rows, True)
return table(header, rows, True)


class CmdDiff(CmdBase):
Expand Down Expand Up @@ -55,11 +67,6 @@ def _format(diff):
At the bottom, include a summary with the number of files per state.
"""

def _digest(checksum):
if isinstance(checksum, str):
return checksum[0:8]
return "{}..{}".format(checksum["old"][0:8], checksum["new"][0:8])

colors = {
"added": colorama.Fore.GREEN,
"modified": colorama.Fore.YELLOW,
Expand Down Expand Up @@ -111,15 +118,16 @@ def run(self):
try:
diff = self.repo.diff(self.args.a_rev, self.args.b_rev)

if not self.args.show_hash:
show_hash = self.args.show_hash
if not show_hash:
for _, entries in diff.items():
for entry in entries:
del entry["hash"]

if self.args.show_json:
logger.info(json.dumps(diff))
elif self.args.show_md:
logger.info(_show_md(diff))
logger.info(_show_md(diff, show_hash))
elif diff:
logger.info(self._format(diff))

Expand Down
71 changes: 62 additions & 9 deletions tests/unit/command/test_diff.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,23 @@
import logging
import os

import mock
import pytest

from dvc.cli import parse_args
from dvc.command.diff import _show_md
from dvc.command.diff import _digest, _show_md


@pytest.mark.parametrize(
"checksum, expected",
[
("wxyz1234pq", "wxyz1234"),
(dict(old="1234567890", new="0987654321"), "12345678..09876543"),
],
ids=["str", "dict"],
)
def test_digest(checksum, expected):
assert expected == _digest(checksum)


def test_default(mocker, caplog):
Expand Down Expand Up @@ -90,6 +105,21 @@ def test_show_json_and_hash(mocker, caplog):
assert '"modified": []' in caplog.text


@pytest.mark.parametrize("show_hash", [None, True, False])
@mock.patch("dvc.command.diff._show_md")
def test_diff_show_md_and_hash(mock_show_md, mocker, caplog, show_hash):
options = ["diff", "--show-md"] + (["--show-hash"] if show_hash else [])
args = parse_args(options)
cmd = args.func(args)

diff = {}
show_hash = show_hash if show_hash else False
mocker.patch("dvc.repo.Repo.diff", return_value=diff)

assert 0 == cmd.run()
mock_show_md.assert_called_once_with(diff, show_hash)


def test_no_changes(mocker, caplog):
args = parse_args(["diff", "--show-json"])
cmd = args.func(args)
Expand Down Expand Up @@ -120,15 +150,13 @@ def test_show_md_empty():
def test_show_md():
Comment thread
PuneethaPai marked this conversation as resolved.
Outdated
diff = {
"deleted": [
{"path": "zoo", "hash": "22222"},
{"path": os.path.join("data", ""), "hash": "XXXXXXXX.dir"},
{"path": os.path.join("data", "foo"), "hash": "11111111"},
{"path": os.path.join("data", "bar"), "hash": "00000000"},
],
"modified": [
{"path": "file", "hash": {"old": "AAAAAAAA", "new": "BBBBBBBB"}}
{"path": "zoo"},
{"path": os.path.join("data", "")},
{"path": os.path.join("data", "foo")},
{"path": os.path.join("data", "bar")},
],
"added": [{"path": "file", "hash": "00000000"}],
"modified": [{"path": "file"}],
"added": [{"path": "file"}],
}
assert _show_md(diff) == (
"| Status | Path |\n"
Expand All @@ -140,3 +168,28 @@ def test_show_md():
"| deleted | zoo |\n"
"| modified | file |\n"
).format(sep=os.path.sep)


def test_show_md_with_hash():
Comment thread
PuneethaPai marked this conversation as resolved.
Outdated
diff = {
"deleted": [
{"path": "zoo", "hash": "22222"},
{"path": os.path.join("data", ""), "hash": "XXXXXXXX.dir"},
{"path": os.path.join("data", "foo"), "hash": "11111111"},
{"path": os.path.join("data", "bar"), "hash": "00000000"},
],
"modified": [
{"path": "file", "hash": {"old": "AAAAAAAA", "new": "BBBBBBBB"}}
],
"added": [{"path": "file", "hash": "00000000"}],
}
assert _show_md(diff, show_hash=True) == (
"| Status | Hash | Path |\n"
"|----------|--------------------|----------|\n"
"| added | 00000000 | file |\n"
"| deleted | XXXXXXXX | data{sep} |\n"
"| deleted | 00000000 | data{sep}bar |\n"
"| deleted | 11111111 | data{sep}foo |\n"
"| deleted | 22222 | zoo |\n"
"| modified | AAAAAAAA..BBBBBBBB | file |\n"
).format(sep=os.path.sep)