diff --git a/dvc/command/data_sync.py b/dvc/command/data_sync.py index e44e8ea7a..3e6a3b8ed 100644 --- a/dvc/command/data_sync.py +++ b/dvc/command/data_sync.py @@ -26,6 +26,7 @@ class CmdDataPull(CmdDataBase): remote=self.args.remote, all_branches=self.args.all_branches, all_tags=self.args.all_tags, + all_commits=self.args.all_commits, with_deps=self.args.with_deps, force=self.args.force, recursive=self.args.recursive, @@ -49,6 +50,7 @@ class CmdDataPush(CmdDataBase): remote=self.args.remote, all_branches=self.args.all_branches, all_tags=self.args.all_tags, + all_commits=self.args.all_commits, with_deps=self.args.with_deps, recursive=self.args.recursive, ) @@ -68,6 +70,7 @@ class CmdDataFetch(CmdDataBase): remote=self.args.remote, all_branches=self.args.all_branches, all_tags=self.args.all_tags, + all_commits=self.args.all_commits, with_deps=self.args.with_deps, recursive=self.args.recursive, ) @@ -128,6 +131,12 @@ def add_parser(subparsers, _parent_parser): default=False, help="Fetch cache for all tags.", ) + pull_parser.add_argument( + "--all-commits", + action="store_true", + default=False, + help="Fetch cache for all commits.", + ) pull_parser.add_argument( "-f", "--force", @@ -178,6 +187,12 @@ def add_parser(subparsers, _parent_parser): default=False, help="Push cache for all tags.", ) + push_parser.add_argument( + "--all-commits", + action="store_true", + default=False, + help="Push cache for all commits.", + ) push_parser.add_argument( "-d", "--with-deps", @@ -224,6 +239,12 @@ def add_parser(subparsers, _parent_parser): default=False, help="Fetch cache for all tags.", ) + fetch_parser.add_argument( + "--all-commits", + action="store_true", + default=False, + help="Fetch cache for all commits.", + ) fetch_parser.add_argument( "-d", "--with-deps", @@ -289,6 +310,13 @@ def add_parser(subparsers, _parent_parser): help="Show status of a local cache compared to a remote repository " "for all tags.", ) + status_parser.add_argument( + "--all-commits", + action="store_true", + default=False, + help="Show status of a local cache compared to a remote repository " + "for all commits.", + ) status_parser.add_argument( "-d", "--with-deps", diff --git a/dvc/command/metrics.py b/dvc/command/metrics.py index 5222108b3..ddc9a2bd5 100644 --- a/dvc/command/metrics.py +++ b/dvc/command/metrics.py @@ -11,7 +11,9 @@ from dvc.exceptions import DvcException logger = logging.getLogger(__name__) -def show_metrics(metrics, all_branches=False, all_tags=False): +def show_metrics( + metrics, all_branches=False, all_tags=False, all_commits=False +): """ Args: metrics (list): Where each element is either a `list` @@ -22,7 +24,7 @@ def show_metrics(metrics, all_branches=False, all_tags=False): missing = metrics.pop(None, None) for branch, val in metrics.items(): - if all_branches or all_tags: + if all_branches or all_tags or all_commits: logger.info("{branch}:".format(branch=branch)) for fname, metric in val.items(): @@ -55,10 +57,16 @@ class CmdMetricsShow(CmdBase): xpath=self.args.xpath, all_branches=self.args.all_branches, all_tags=self.args.all_tags, + all_commits=self.args.all_commits, recursive=self.args.recursive, ) - show_metrics(metrics, self.args.all_branches, self.args.all_tags) + show_metrics( + metrics, + self.args.all_branches, + self.args.all_tags, + self.args.all_commits, + ) except DvcException: logger.exception("failed to show metrics") return 1 @@ -215,6 +223,12 @@ def add_parser(subparsers, parent_parser): default=False, help="Show metrics for all tags.", ) + metrics_show_parser.add_argument( + "--all-commits", + action="store_true", + default=False, + help="Show metrics for all commits.", + ) metrics_show_parser.add_argument( "-R", "--recursive", diff --git a/dvc/command/status.py b/dvc/command/status.py index 640294860..a441f7136 100644 --- a/dvc/command/status.py +++ b/dvc/command/status.py @@ -47,6 +47,7 @@ class CmdDataStatus(CmdDataBase): remote=self.args.remote, all_branches=self.args.all_branches, all_tags=self.args.all_tags, + all_commits=self.args.all_commits, with_deps=self.args.with_deps, ) if st: diff --git a/dvc/repo/fetch.py b/dvc/repo/fetch.py index fbbaab1be..f77491bb7 100644 --- a/dvc/repo/fetch.py +++ b/dvc/repo/fetch.py @@ -20,6 +20,7 @@ def _fetch( with_deps=False, all_tags=False, recursive=False, + all_commits=False, ): """Download data items from a cloud and imported repositories @@ -37,6 +38,7 @@ def _fetch( targets, all_branches=all_branches, all_tags=all_tags, + all_commits=all_commits, with_deps=with_deps, force=True, remote=remote, diff --git a/dvc/repo/metrics/show.py b/dvc/repo/metrics/show.py index 9f0f3ef13..fcd71b632 100644 --- a/dvc/repo/metrics/show.py +++ b/dvc/repo/metrics/show.py @@ -267,6 +267,7 @@ def show( all_tags=False, recursive=False, revs=None, + all_commits=False, ): res = {} found = set() @@ -276,7 +277,10 @@ def show( targets = [None] for branch in repo.brancher( - revs=revs, all_branches=all_branches, all_tags=all_tags + revs=revs, + all_branches=all_branches, + all_tags=all_tags, + all_commits=all_commits, ): metrics = {} diff --git a/dvc/repo/pull.py b/dvc/repo/pull.py index 993d50be8..4623f6a4e 100644 --- a/dvc/repo/pull.py +++ b/dvc/repo/pull.py @@ -17,6 +17,7 @@ def pull( all_tags=False, force=False, recursive=False, + all_commits=False, ): processed_files_count = self._fetch( targets, @@ -24,6 +25,7 @@ def pull( remote=remote, all_branches=all_branches, all_tags=all_tags, + all_commits=all_commits, with_deps=with_deps, recursive=recursive, ) diff --git a/dvc/repo/push.py b/dvc/repo/push.py index 4ea1dd0b3..43946d37c 100644 --- a/dvc/repo/push.py +++ b/dvc/repo/push.py @@ -11,11 +11,13 @@ def push( with_deps=False, all_tags=False, recursive=False, + all_commits=False, ): used = self.used_cache( targets, all_branches=all_branches, all_tags=all_tags, + all_commits=all_commits, with_deps=with_deps, force=True, remote=remote, diff --git a/dvc/repo/status.py b/dvc/repo/status.py index b8c3a8fcf..40780c66e 100644 --- a/dvc/repo/status.py +++ b/dvc/repo/status.py @@ -44,6 +44,7 @@ def _cloud_status( all_branches=False, with_deps=False, all_tags=False, + all_commits=False, ): """Returns a dictionary with the files that are new or deleted. @@ -77,6 +78,7 @@ def _cloud_status( targets, all_branches=all_branches, all_tags=all_tags, + all_commits=all_commits, with_deps=with_deps, force=True, remote=remote, @@ -108,6 +110,7 @@ def status( all_branches=False, with_deps=False, all_tags=False, + all_commits=False, ): if cloud or remote: return _cloud_status( @@ -118,12 +121,13 @@ def status( with_deps=with_deps, remote=remote, all_tags=all_tags, + all_commits=all_commits, ) ignored = list( compress( - ["--all-branches", "--all-tags", "--jobs"], - [all_branches, all_tags, jobs], + ["--all-branches", "--all-tags", "--all-commits", "--jobs"], + [all_branches, all_tags, all_commits, jobs], ) ) if ignored: diff --git a/tests/unit/command/test_data_sync.py b/tests/unit/command/test_data_sync.py new file mode 100644 index 000000000..41d464dbd --- /dev/null +++ b/tests/unit/command/test_data_sync.py @@ -0,0 +1,112 @@ +from dvc.cli import parse_args +from dvc.command.data_sync import CmdDataFetch, CmdDataPull, CmdDataPush + + +def test_fetch(mocker): + cli_args = parse_args( + [ + "fetch", + "target1", + "target2", + "--jobs", + "2", + "--remote", + "remote", + "--all-branches", + "--all-tags", + "--all-commits", + "--with-deps", + "--recursive", + ] + ) + assert cli_args.func == CmdDataFetch + + cmd = cli_args.func(cli_args) + m = mocker.patch.object(cmd.repo, "fetch", autospec=True) + + assert cmd.run() == 0 + + m.assert_called_once_with( + targets=["target1", "target2"], + jobs=2, + remote="remote", + all_branches=True, + all_tags=True, + all_commits=True, + with_deps=True, + recursive=True, + ) + + +def test_pull(mocker): + cli_args = parse_args( + [ + "pull", + "target1", + "target2", + "--jobs", + "2", + "--remote", + "remote", + "--all-branches", + "--all-tags", + "--all-commits", + "--with-deps", + "--force", + "--recursive", + ] + ) + assert cli_args.func == CmdDataPull + + cmd = cli_args.func(cli_args) + m = mocker.patch.object(cmd.repo, "pull", autospec=True) + + assert cmd.run() == 0 + + m.assert_called_once_with( + targets=["target1", "target2"], + jobs=2, + remote="remote", + all_branches=True, + all_tags=True, + all_commits=True, + with_deps=True, + force=True, + recursive=True, + ) + + +def test_push(mocker): + cli_args = parse_args( + [ + "push", + "target1", + "target2", + "--jobs", + "2", + "--remote", + "remote", + "--all-branches", + "--all-tags", + "--all-commits", + "--with-deps", + "--recursive", + ] + ) + assert cli_args.func == CmdDataPush + + cmd = cli_args.func(cli_args) + m = mocker.patch.object(cmd.repo, "push", autospec=True) + + assert cmd.run() == 0 + + m.assert_called_once_with( + targets=["target1", "target2"], + jobs=2, + remote="remote", + all_branches=True, + all_tags=True, + all_commits=True, + with_deps=True, + recursive=True, + ) diff --git a/tests/unit/command/test_metrics.py b/tests/unit/command/test_metrics.py index 7b212ea3f..7a520dddf 100644 --- a/tests/unit/command/test_metrics.py +++ b/tests/unit/command/test_metrics.py @@ -1,5 +1,5 @@ from dvc.cli import parse_args -from dvc.command.metrics import CmdMetricsDiff, _show_diff +from dvc.command.metrics import CmdMetricsDiff, _show_diff, CmdMetricsShow def test_metrics_diff(dvc, mocker): @@ -83,3 +83,39 @@ def test_metrics_diff_deleted_metric(): " Path Metric Value Change \n" "other.json a.b.d None diff not supported" ) + + +def test_metrics_show(dvc, mocker): + cli_args = parse_args( + [ + "metrics", + "show", + "-t", + "json", + "-x", + "x.path", + "-R", + "--all-tags", + "--all-branches", + "--all-commits", + "target1", + "target2", + ] + ) + assert cli_args.func == CmdMetricsShow + + cmd = cli_args.func(cli_args) + m = mocker.patch("dvc.repo.metrics.show.show", return_value={}) + + assert cmd.run() == 0 + + m.assert_called_once_with( + cmd.repo, + ["target1", "target2"], + typ="json", + xpath="x.path", + recursive=True, + all_tags=True, + all_branches=True, + all_commits=True, + ) diff --git a/tests/unit/command/test_status.py b/tests/unit/command/test_status.py new file mode 100644 index 000000000..7b8ea3324 --- /dev/null +++ b/tests/unit/command/test_status.py @@ -0,0 +1,38 @@ +from dvc.cli import parse_args +from dvc.command.status import CmdDataStatus + + +def test_cloud_status(mocker): + cli_args = parse_args( + [ + "status", + "--cloud", + "target1", + "target2", + "--jobs", + "2", + "--remote", + "remote", + "--all-branches", + "--all-tags", + "--all-commits", + "--with-deps", + ] + ) + assert cli_args.func == CmdDataStatus + + cmd = cli_args.func(cli_args) + m = mocker.patch.object(cmd.repo, "status", autospec=True, return_value={}) + + assert cmd.run() == 0 + + m.assert_called_once_with( + cloud=True, + targets=["target1", "target2"], + jobs=2, + remote="remote", + all_branches=True, + all_tags=True, + all_commits=True, + with_deps=True, + )