Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Allow tasks to opt-in to target filtering #7283

Merged
merged 5 commits into from
Feb 26, 2019
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
1 change: 1 addition & 0 deletions src/python/pants/task/fmt_task_mixin.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,3 +11,4 @@
class FmtTaskMixin(HasSkipAndTransitiveGoalOptionsMixin):
"""A mixin to combine with code formatting tasks."""
goal_options_registrar_cls = SkipAndTransitiveGoalOptionsRegistrar
target_filtering_enabled = True
1 change: 1 addition & 0 deletions src/python/pants/task/lint_task_mixin.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,3 +11,4 @@
class LintTaskMixin(HasSkipAndTransitiveGoalOptionsMixin):
"""A mixin to combine with lint tasks."""
goal_options_registrar_cls = SkipAndTransitiveGoalOptionsRegistrar
target_filtering_enabled = True
26 changes: 22 additions & 4 deletions src/python/pants/task/task.py
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@
from pants.subsystem.subsystem_client_mixin import SubsystemClientMixin
from pants.util.dirutil import safe_mkdir, safe_rm_oldest_items_in_dir
from pants.util.memo import memoized_method, memoized_property
from pants.util.meta import AbstractClass
from pants.util.meta import AbstractClass, classproperty


class TaskBase(SubsystemClientMixin, Optionable, AbstractClass):
Expand Down Expand Up @@ -97,7 +97,8 @@ def _compute_stable_name(cls):
@classmethod
def subsystem_dependencies(cls):
return (super(TaskBase, cls).subsystem_dependencies() +
(CacheSetup.scoped(cls), TargetFilter.scoped(cls), BuildInvalidator.Factory, SourceRootConfig))
(CacheSetup.scoped(cls), BuildInvalidator.Factory, SourceRootConfig) +
((TargetFilter.scoped(cls),) if cls.target_filtering_enabled else tuple()))

@classmethod
def product_types(cls):
Expand Down Expand Up @@ -223,6 +224,17 @@ def act_transitively(self):
"""
return True

@classproperty
def target_filtering_enabled(cls):
"""Whether this task should apply configured filters against targets.

Tasks can override to enable target filtering (e.g. based on tags) and must
access targets via get_targets()

:API: public
"""
return False

def get_targets(self, predicate=None):
"""Returns the candidate targets this task should act on.

Expand All @@ -241,8 +253,14 @@ def get_targets(self, predicate=None):
initial_targets = (self.context.targets(predicate) if self.act_transitively
else list(filter(predicate, self.context.target_roots)))

included_targets = TargetFilter.scoped_instance(self).apply(initial_targets)
excluded_targets = set(initial_targets).difference(included_targets)
if not self.target_filtering_enabled:
return initial_targets
else:
return self._filter_targets(initial_targets)

def _filter_targets(self, targets):
included_targets = TargetFilter.scoped_instance(self).apply(targets)
excluded_targets = set(targets).difference(included_targets)

if excluded_targets:
self.context.log.info("{} target(s) excluded".format(len(excluded_targets)))
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ class TestTargetFilter(TaskTestBase):

class DummyTask(Task):
options_scope = 'dummy'
target_filtering_enabled = True

def execute(self):
self.context.products.safe_create_data('task_targets', self.get_targets)
Expand Down
12 changes: 12 additions & 0 deletions tests/python/pants_test/task/test_task.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
from pants.base.exceptions import TaskError
from pants.build_graph.build_file_aliases import BuildFileAliases
from pants.build_graph.files import Files
from pants.build_graph.target_filter_subsystem import TargetFilter
from pants.cache.cache_setup import CacheSetup
from pants.option.arg_splitter import GLOBAL_SCOPE
from pants.subsystem.subsystem import Subsystem
Expand Down Expand Up @@ -149,6 +150,11 @@ def execute(self):
pass


class TaskWithTargetFiltering(DummyTask):
options_scope = 'task-with-target-filtering'
target_filtering_enabled = True

codealchemy marked this conversation as resolved.
Show resolved Hide resolved

class TaskTest(TaskTestBase):

_filename = 'f'
Expand Down Expand Up @@ -650,3 +656,9 @@ def test_fingerprint_transitive(self):
fp3 = self._synth_fp(cls=TaskWithTransitiveSubsystemDependencies,
options_fingerprintable=option_spec)
self.assertNotEqual(fp1, fp3)

def test_target_filtering_enabled(self):
self.assertNotIn(TargetFilter.scoped(DummyTask),
DummyTask.subsystem_dependencies())
self.assertIn(TargetFilter.scoped(TaskWithTargetFiltering),
TaskWithTargetFiltering.subsystem_dependencies())