diff --git a/dvc/command/diff.py b/dvc/command/diff.py index 3c6b2f447f..c8b6867851 100644 --- a/dvc/command/diff.py +++ b/dvc/command/diff.py @@ -36,11 +36,11 @@ def _format(diff): c157a790..f98bf6f1 bar If a group has no entries, it won't be included in the result. + + At the bottom, include a summary with the number of files per state. """ def _digest(checksum): - if not checksum: - return "" if type(checksum) is str: return checksum[0:8] return "{}..{}".format(checksum["old"][0:8], checksum["new"][0:8]) @@ -51,24 +51,47 @@ def _digest(checksum): "deleted": colorama.Fore.RED, } - return "\n\n".join( - "{color}{header}{nc}:\n{entries}".format( - color=colors[state], - header=state.capitalize(), - nc=colorama.Fore.RESET, - entries="\n".join( + summary = {} + groups = [] + + for state in ["added", "deleted", "modified"]: + summary[state] = 0 + entries = diff[state] + + if not entries: + continue + + content = [] + + for entry in entries: + path = entry["path"] + checksum = entry.get("checksum") + summary[state] += 1 if not path.endswith("/") else 0 + content.append( "{space}{checksum}{separator}{path}".format( space=" ", - checksum=_digest(entry.get("checksum")), - separator=" " if entry.get("checksum") else "", + checksum=_digest(checksum) if checksum else "", + separator=" " if checksum else "", path=entry["path"], ) - for entry in diff[state] - ), + ) + + groups.append( + "{color}{header}{nc}:\n{content}".format( + color=colors[state], + header=state.capitalize(), + nc=colorama.Fore.RESET, + content="\n".join(content), + ) ) - for state in ["added", "deleted", "modified"] + + groups.append( + "summary: added ({added}), deleted ({deleted})," + " modified ({modified})".format_map(summary) ) + return "\n\n".join(groups) + def run(self): try: diff = self.repo.diff(self.args.a_ref, self.args.b_ref) diff --git a/tests/unit/command/test_diff.py b/tests/unit/command/test_diff.py index 1f6b450d8f..fcf0209976 100644 --- a/tests/unit/command/test_diff.py +++ b/tests/unit/command/test_diff.py @@ -1,3 +1,5 @@ +import os + from dvc.cli import parse_args @@ -12,7 +14,12 @@ def test_default(mocker, caplog): mocker.patch("dvc.repo.Repo.diff", return_value=diff) assert 0 == cmd.run() - assert "Added:\n file\n" in caplog.text + assert ( + "Added:\n" + " file\n" + "\n" + "summary: added (1), deleted (0), modified (0)" + ) in caplog.text def test_checksums(mocker, caplog): @@ -21,8 +28,9 @@ def test_checksums(mocker, caplog): diff = { "added": [], "deleted": [ - {"path": "bar", "checksum": "00000000"}, - {"path": "foo", "checksum": "11111111"}, + {"path": os.path.join("data", ""), "checksum": "XXXXXXXX.dir"}, + {"path": os.path.join("data", "bar"), "checksum": "00000000"}, + {"path": os.path.join("data", "foo"), "checksum": "11111111"}, ], "modified": [ { @@ -35,11 +43,14 @@ def test_checksums(mocker, caplog): assert 0 == cmd.run() assert ( "Deleted:\n" - " 00000000 bar\n" - " 11111111 foo\n" + " XXXXXXXX " + os.path.join("data", "") + "\n" + " 00000000 " + os.path.join("data", "bar") + "\n" + " 11111111 " + os.path.join("data", "foo") + "\n" "\n" "Modified:\n" " AAAAAAAA..BBBBBBBB file\n" + "\n" + "summary: added (0), deleted (2), modified (1)" ) in caplog.text