From 415a85c6bebf658e3cc6b35ec250897ba94869ea Mon Sep 17 00:00:00 2001 From: nik123 Date: Mon, 4 May 2020 01:12:17 +0700 Subject: [PATCH] status: --recursive flag (#3726) * status: --recursive flag * tests: fixed test_status_recursive for Windows platform --- dvc/command/data_sync.py | 8 ++++++++ dvc/command/status.py | 1 + dvc/repo/status.py | 17 +++++++++++++---- tests/func/test_status.py | 20 ++++++++++++++++++++ tests/unit/command/test_status.py | 2 ++ 5 files changed, 44 insertions(+), 4 deletions(-) diff --git a/dvc/command/data_sync.py b/dvc/command/data_sync.py index 3091fc915a..1c4dac243a 100644 --- a/dvc/command/data_sync.py +++ b/dvc/command/data_sync.py @@ -334,4 +334,12 @@ def add_parser(subparsers, _parent_parser): default=False, help="Show status for all dependencies of the specified target.", ) + status_parser.add_argument( + "-R", + "--recursive", + action="store_true", + default=False, + help="Show status of all stages in the specified directory.", + ) + status_parser.set_defaults(func=CmdDataStatus) diff --git a/dvc/command/status.py b/dvc/command/status.py index a441f71369..f72dd43dda 100644 --- a/dvc/command/status.py +++ b/dvc/command/status.py @@ -49,6 +49,7 @@ def run(self): all_tags=self.args.all_tags, all_commits=self.args.all_commits, with_deps=self.args.with_deps, + recursive=self.args.recursive, ) if st: if self.args.quiet: diff --git a/dvc/repo/status.py b/dvc/repo/status.py index 402aca0996..122231a7e6 100644 --- a/dvc/repo/status.py +++ b/dvc/repo/status.py @@ -25,11 +25,14 @@ def _joint_status(stages): return status -def _local_status(self, targets=None, with_deps=False): +def _local_status(self, targets=None, with_deps=False, recursive=False): if targets: - stages = cat(self.collect(t, with_deps=with_deps) for t in targets) + stages = cat( + self.collect(t, with_deps=with_deps, recursive=recursive) + for t in targets + ) else: - stages = self.collect(None, with_deps=with_deps) + stages = self.collect(None, with_deps=with_deps, recursive=recursive) return _joint_status(stages) @@ -42,6 +45,7 @@ def _cloud_status( all_branches=False, with_deps=False, all_tags=False, + recursive=False, all_commits=False, ): """Returns a dictionary with the files that are new or deleted. @@ -81,6 +85,7 @@ def _cloud_status( force=True, remote=remote, jobs=jobs, + recursive=recursive, ) ret = {} @@ -109,6 +114,7 @@ def status( with_deps=False, all_tags=False, all_commits=False, + recursive=False, ): if cloud or remote: return _cloud_status( @@ -120,6 +126,7 @@ def status( remote=remote, all_tags=all_tags, all_commits=all_commits, + recursive=True, ) ignored = list( @@ -132,4 +139,6 @@ def status( msg = "The following options are meaningless for local status: {}" raise InvalidArgumentError(msg.format(", ".join(ignored))) - return _local_status(self, targets, with_deps=with_deps) + return _local_status( + self, targets, with_deps=with_deps, recursive=recursive + ) diff --git a/tests/func/test_status.py b/tests/func/test_status.py index 1956fa7c99..900022d51e 100644 --- a/tests/func/test_status.py +++ b/tests/func/test_status.py @@ -93,3 +93,23 @@ def test_status_on_pipeline_stages(tmp_dir, dvc, run_copy): "changed command", ], } + + +def test_status_recursive(tmp_dir, dvc): + tmp_dir.gen({"dir": {"file": "text1", "subdir": {"file2": "text2"}}}) + stages = dvc.add("dir", recursive=True, no_commit=True) + + assert len(stages) == 2 + + assert dvc.status(targets=["dir"], recursive=True) == { + os.path.join("dir", "file.dvc"): [ + {"changed outs": {os.path.join("dir", "file"): "not in cache"}} + ], + os.path.join("dir", "subdir", "file2.dvc"): [ + { + "changed outs": { + os.path.join("dir", "subdir", "file2"): "not in cache" + } + } + ], + } diff --git a/tests/unit/command/test_status.py b/tests/unit/command/test_status.py index 7b8ea33248..6ac7c6970d 100644 --- a/tests/unit/command/test_status.py +++ b/tests/unit/command/test_status.py @@ -17,6 +17,7 @@ def test_cloud_status(mocker): "--all-tags", "--all-commits", "--with-deps", + "--recursive", ] ) assert cli_args.func == CmdDataStatus @@ -35,4 +36,5 @@ def test_cloud_status(mocker): all_tags=True, all_commits=True, with_deps=True, + recursive=True, )