diff --git a/src/python/pants/backend/graph_info/tasks/listtargets.py b/src/python/pants/backend/graph_info/tasks/listtargets.py index a16b385677f..b6828a80cd3 100644 --- a/src/python/pants/backend/graph_info/tasks/listtargets.py +++ b/src/python/pants/backend/graph_info/tasks/listtargets.py @@ -65,7 +65,9 @@ def print_documented(target): print_fn = lambda target: target.address.spec visited = set() - for target in self.determine_target_roots('list', lambda target: not target.is_synthetic): + for target in self.determine_target_roots('list'): + if target.is_synthetic: + continue result = print_fn(target) if result and result not in visited: visited.add(result) diff --git a/src/python/pants/task/task.py b/src/python/pants/task/task.py index d218797d31f..8e2f31f92f9 100644 --- a/src/python/pants/task/task.py +++ b/src/python/pants/task/task.py @@ -6,6 +6,7 @@ unicode_literals, with_statement) import os +import sys from abc import abstractmethod from contextlib import contextmanager from hashlib import sha1 @@ -648,15 +649,13 @@ def require_single_root_target(self): .format(', '.join([repr(t) for t in target_roots]))) return target_roots[0] - def determine_target_roots(self, goal_name, predicate=None): + def determine_target_roots(self, goal_name): """Helper for tasks that scan for default target roots. :param string goal_name: The goal name to use for any warning emissions. - :param callable predicate: The predicate to pass to `context.scan().targets(predicate=X)`. """ if not self.context.target_roots: - raise TaskError('Please specify one or more explicit target ' - 'specs (e.g. `./pants {0} ::`).'.format(goal_name)) + print('WARNING: No targets were matched in goal `{}`.'.format(goal_name), file=sys.stderr) # For the v2 path, e.g. `./pants list` is a functional no-op. This matches the v2 mode behavior # of e.g. `./pants --changed-parent=HEAD list` (w/ no changes) returning an empty result. diff --git a/tests/python/pants_test/backend/graph_info/tasks/test_listtargets.py b/tests/python/pants_test/backend/graph_info/tasks/test_listtargets.py index c3d43c8d84b..39a24ac364f 100644 --- a/tests/python/pants_test/backend/graph_info/tasks/test_listtargets.py +++ b/tests/python/pants_test/backend/graph_info/tasks/test_listtargets.py @@ -14,7 +14,6 @@ from pants.backend.jvm.scala_artifact import ScalaArtifact from pants.backend.jvm.targets.java_library import JavaLibrary from pants.backend.python.targets.python_library import PythonLibrary -from pants.base.exceptions import TaskError from pants.build_graph.build_file_aliases import BuildFileAliases from pants.build_graph.target import Target from pants_test.tasks.task_test_base import ConsoleTaskTestBase @@ -30,8 +29,9 @@ def task_type(cls): class ListTargetsTestEmpty(BaseListTargetsTest): def test_list_all_empty(self): - with self.assertRaises(TaskError): - self.assertEqual('', self.execute_task()) + # NB: Also renders a warning to stderr, which is challenging to detect here but confirmed in: + # tests/python/pants_test/engine/legacy/test_list_integration.py + self.assertEqual('', self.execute_task()) class ListTargetsTest(BaseListTargetsTest): diff --git a/tests/python/pants_test/engine/legacy/test_list_integration.py b/tests/python/pants_test/engine/legacy/test_list_integration.py index ec86a0c7a78..a130767cfd5 100644 --- a/tests/python/pants_test/engine/legacy/test_list_integration.py +++ b/tests/python/pants_test/engine/legacy/test_list_integration.py @@ -21,8 +21,8 @@ def test_list_all(self): self.assertGreater(len(pants_run.stdout_data.strip().split()), 1) def test_list_none(self): - pants_run = self.do_command('list', success=False) - self.assertIn('Please specify one or more explicit target', pants_run.stdout_data) + pants_run = self.do_command('list', success=True) + self.assertIn('WARNING: No targets were matched in', pants_run.stderr_data) def test_list_invalid_dir(self): pants_run = self.do_command('list', 'abcde::', success=False)