def _visit_goal(self, goal, context, goal_info_by_goal, target_roots_replacement): if goal in goal_info_by_goal: return tasktypes_by_name = OrderedDict() goal_dependencies = set() visited_task_types = set() for task_name in reversed(goal.ordered_task_names()): task_type = goal.task_type_by_name(task_name) tasktypes_by_name[task_name] = task_type visited_task_types.add(task_type) alternate_target_roots = task_type._alternate_target_roots( context.options, context.address_mapper, context.build_graph) target_roots_replacement.propose_alternates( task_type, alternate_target_roots) round_manager = RoundManager(context) task_type._prepare(context.options, round_manager) try: dependencies = round_manager.get_dependencies() for producer_info in dependencies: producer_goal = producer_info.goal if producer_goal == goal: if producer_info.task_type in visited_task_types: ordering = '\n\t'.join( "[{0}] '{1}' {2}".format( i, tn, goal.task_type_by_name(tn).__name__) for i, tn in enumerate( goal.ordered_task_names())) raise self.TaskOrderError( "TaskRegistrar '{name}' with action {consumer_task} depends on {data} from task " "{producer_task} which is ordered after it in the '{goal}' goal:\n\t{ordering}" .format(name=task_name, consumer_task=task_type.__name__, data=producer_info.product_type, producer_task=producer_info.task_type. __name__, goal=goal.name, ordering=ordering)) else: # We don't express dependencies on downstream tasks in this same goal. pass else: goal_dependencies.add(producer_goal) except round_manager.MissingProductError as e: raise self.MissingProductError( "Could not satisfy data dependencies for goal '{name}' with action {action}: {error}" .format(name=task_name, action=task_type.__name__, error=e)) goal_info = self.GoalInfo(goal, tasktypes_by_name, goal_dependencies) goal_info_by_goal[goal] = goal_info for goal_dependency in goal_dependencies: self._visit_goal(goal_dependency, context, goal_info_by_goal, target_roots_replacement)
def _visit_goal(self, goal, context, goal_info_by_goal): if goal in goal_info_by_goal: return tasktypes_by_name = OrderedDict() goal_dependencies = set() visited_task_types = set() for task_name in reversed(goal.ordered_task_names()): task_type = goal.task_type_by_name(task_name) tasktypes_by_name[task_name] = task_type visited_task_types.add(task_type) round_manager = RoundManager(context) task_type.invoke_prepare(context.options, round_manager) try: dependencies = round_manager.get_dependencies() for producer_info in dependencies: producer_goal = producer_info.goal if producer_goal == goal: if producer_info.task_type == task_type: # We allow a task to produce products it itself needs. We trust the Task writer # to arrange for proper sequencing. pass elif producer_info.task_type in visited_task_types: ordering = "\n\t".join( "[{0}] '{1}' {2}".format( i, tn, goal.task_type_by_name(tn).__name__) for i, tn in enumerate( goal.ordered_task_names())) raise self.TaskOrderError( "TaskRegistrar '{name}' with action {consumer_task} depends on {data} from task " "{producer_task} which is ordered after it in the '{goal}' goal:\n\t{ordering}" .format( name=task_name, consumer_task=task_type.__name__, data=producer_info.product_type, producer_task=producer_info.task_type. __name__, goal=goal.name, ordering=ordering, )) else: # We don't express dependencies on downstream tasks in this same goal. pass else: goal_dependencies.add(producer_goal) except round_manager.MissingProductError as e: raise self.MissingProductError( "Could not satisfy data dependencies for goal '{name}' with action {action}: {error}" .format(name=task_name, action=task_type.__name__, error=e)) goal_info = self.GoalInfo(goal, tasktypes_by_name, goal_dependencies) goal_info_by_goal[goal] = goal_info for goal_dependency in goal_dependencies: self._visit_goal(goal_dependency, context, goal_info_by_goal)
def _visit_goal(self, goal, context, goal_info_by_goal, target_roots_replacement): if goal in goal_info_by_goal: return tasktypes_by_name = OrderedDict() goal_dependencies = set() visited_task_types = set() for task_name in reversed(goal.ordered_task_names()): task_type = goal.task_type_by_name(task_name) tasktypes_by_name[task_name] = task_type visited_task_types.add(task_type) alternate_target_roots = task_type.get_alternate_target_roots(context.options, context.address_mapper, context.build_graph) target_roots_replacement.propose_alternates(task_type, alternate_target_roots) round_manager = RoundManager(context) task_type.invoke_prepare(context.options, round_manager) try: dependencies = round_manager.get_dependencies() for producer_info in dependencies: producer_goal = producer_info.goal if producer_goal == goal: if producer_info.task_type == task_type: # We allow a task to produce products it itself needs. We trust the Task writer # to arrange for proper sequencing. pass elif producer_info.task_type in visited_task_types: ordering = '\n\t'.join("[{0}] '{1}' {2}".format(i, tn, goal.task_type_by_name(tn).__name__) for i, tn in enumerate(goal.ordered_task_names())) raise self.TaskOrderError( "TaskRegistrar '{name}' with action {consumer_task} depends on {data} from task " "{producer_task} which is ordered after it in the '{goal}' goal:\n\t{ordering}" .format(name=task_name, consumer_task=task_type.__name__, data=producer_info.product_type, producer_task=producer_info.task_type.__name__, goal=goal.name, ordering=ordering)) else: # We don't express dependencies on downstream tasks in this same goal. pass else: goal_dependencies.add(producer_goal) except round_manager.MissingProductError as e: raise self.MissingProductError( "Could not satisfy data dependencies for goal '{name}' with action {action}: {error}" .format(name=task_name, action=task_type.__name__, error=e)) goal_info = self.GoalInfo(goal, tasktypes_by_name, goal_dependencies) goal_info_by_goal[goal] = goal_info for goal_dependency in goal_dependencies: self._visit_goal(goal_dependency, context, goal_info_by_goal, target_roots_replacement)
def _visit_phase(self, phase, context, phase_info_by_phase): if phase in phase_info_by_phase: return tasks_by_name = OrderedDict() phase_dependencies = set() visited_task_types = set() phase_goals = phase.goals() for goal in reversed(phase_goals): task_type = goal.task_type visited_task_types.add(task_type) task_workdir = os.path.join(context.config.getdefault('pants_workdir'), phase.name, goal.name) task = task_type(context, task_workdir) tasks_by_name[goal.name] = task round_manager = RoundManager(context) task.prepare(round_manager) try: dependencies = round_manager.get_dependencies() for producer_info in dependencies: producer_phase = producer_info.phase if producer_phase == phase: if producer_info.task_type in visited_task_types: ordering = '\n\t'.join("[{0}] '{1}' {2}".format(i, goal.name, goal.task_type.__name__) for i, goal in enumerate(phase_goals)) raise self.TaskOrderError( "Goal '{name}' with action {consumer_task} depends on {data} from task " "{producer_task} which is ordered after it in the '{phase}' phase:\n\t{ordering}" .format(name=goal.name, consumer_task=task_type.__name__, data=producer_info.product_type, producer_task=producer_info.task_type.__name__, phase=phase.name, ordering=ordering)) else: # We don't express dependencies on downstream tasks in this same phase. pass else: phase_dependencies.add(producer_phase) except round_manager.MissingProductError as e: raise self.MissingProductError( "Could not satisfy data dependencies for goal '{name}' with action {action}: {error}" .format(name=goal.name, action=task_type.__name__, error=e)) phase_info = self.PhaseInfo(phase, tasks_by_name, phase_dependencies) phase_info_by_phase[phase] = phase_info for phase_dependency in phase_dependencies: self._visit_phase(phase_dependency, context, phase_info_by_phase)
def _visit_goal(self, goal, context, goal_info_by_goal): if goal in goal_info_by_goal: return tasks_by_name = OrderedDict() goal_dependencies = set() visited_task_types = set() for task_name in reversed(goal.ordered_task_names()): task_type = goal.task_type_by_name(task_name) visited_task_types.add(task_type) task_workdir = os.path.join(context.new_options.for_global_scope().pants_workdir, goal.name, task_name) task = task_type(context, task_workdir) tasks_by_name[task_name] = task round_manager = RoundManager(context) task.prepare(round_manager) try: dependencies = round_manager.get_dependencies() for producer_info in dependencies: producer_goal = producer_info.goal if producer_goal == goal: if producer_info.task_type in visited_task_types: ordering = '\n\t'.join("[{0}] '{1}' {2}".format(i, tn, goal.task_type_by_name(tn).__name__) for i, tn in enumerate(goal.ordered_task_names())) raise self.TaskOrderError( "TaskRegistrar '{name}' with action {consumer_task} depends on {data} from task " "{producer_task} which is ordered after it in the '{goal}' goal:\n\t{ordering}" .format(name=task_name, consumer_task=task_type.__name__, data=producer_info.product_type, producer_task=producer_info.task_type.__name__, goal=goal.name, ordering=ordering)) else: # We don't express dependencies on downstream tasks in this same goal. pass else: goal_dependencies.add(producer_goal) except round_manager.MissingProductError as e: raise self.MissingProductError( "Could not satisfy data dependencies for goal '{name}' with action {action}: {error}" .format(name=task_name, action=task_type.__name__, error=e)) goal_info = self.GoalInfo(goal, tasks_by_name, goal_dependencies) goal_info_by_goal[goal] = goal_info for goal_dependency in goal_dependencies: self._visit_goal(goal_dependency, context, goal_info_by_goal)
def setUp(self): super(BaseGroupTaskTest, self).setUp() self.set_options_for_scope('test.RecordingGroupMember', level='info', colors='False') self.maxDiff = None self._context = self.context(target_roots=self.create_targets()) self.populate_compile_classpath(self._context) self.recorded_actions = [] # NB: GroupTask has a cache of tasks by name... use a distinct name self.group_task = GroupTask.named( 'jvm-compile-%s' % uuid.uuid4().hex, ['classes_by_target', 'classes_by_source'], ['test']) javac = self.group_member( name='javac', selector=lambda t: isinstance(t, self.JavaLibrary)) self.group_task.add_member(javac) scalac = self.group_member( name='scalac', selector=lambda t: isinstance(t, self.ScalaLibrary)) self.group_task.add_member(scalac) self.group_task._prepare(self.options, round_manager=RoundManager(self._context)) self.task = self.group_task(self._context, workdir='/not/real') self.task.execute()
def setUp(self): super(BaseGroupTaskTest, self).setUp() self.set_options_for_scope('test.RecordingGroupMember', level='info', colors='False') self.maxDiff = None self.recorded_actions = [] # NB: GroupTask has a cache of tasks by name... use a distinct name self.group_task = GroupTask.named(name='jvm-compile-{}'.format( uuid.uuid4().hex), product_type=['runtime_classpath'], flag_namespace=['test']) javac = self.group_member( name='javac', selector=lambda t: isinstance(t, self.JavaLibrary)) self.group_task.add_member(javac) scalac = self.group_member( name='scalac', selector=lambda t: isinstance(t, self.ScalaLibrary)) self.group_task.add_member(scalac) self._context = self.context(target_roots=self.create_targets(), for_task_types=[self.group_task]) self.group_task._prepare(self.options, round_manager=RoundManager(self._context)) self.task = self.group_task(self._context, workdir='/not/real') self.task.execute()
def test_cmdline_only(self): jvm_binary = self.make_target('src/java/com/pants:binary', JvmBinary, main="com.pants.Binary") jvm_run = self.prepare_task(args=['--test-only-write-cmd-line=a'], targets=[jvm_binary], build_graph=self.build_graph) round_manager = RoundManager(jvm_run.context) jvm_run.prepare(round_manager) self.populate_exclusive_groups(context=jvm_run.context, classpaths=['bob', 'fred']) with temporary_dir() as pwd: with pushd(pwd): cmdline_file = os.path.join(pwd, 'a') self.assertFalse(os.path.exists(cmdline_file)) jvm_run.execute() self.assertTrue(os.path.exists(cmdline_file)) with open(cmdline_file) as fp: contents = fp.read() expected_suffix = 'java -cp bob:fred com.pants.Binary' self.assertEquals(expected_suffix, contents[-len(expected_suffix):])
def setUp(self): super(BaseGroupTaskTest, self).setUp() self._context = self.context(target_roots=self.create_targets()) exclusives_mapping = ExclusivesMapping(self._context) exclusives_mapping._populate_target_maps(self._context.targets()) self._context.products.safe_create_data('exclusives_groups', lambda: exclusives_mapping) self.recorded_actions = [] # NB: GroupTask has a cache of tasks by name... use a distinct name self.group_task = GroupTask.named('jvm-compile-%s' % uuid.uuid4().hex, ['classes_by_target', 'classes_by_source']) self.group_task.add_member(self.group_member('javac', lambda t: t.is_java)) self.group_task.add_member(self.group_member('scalac', lambda t: t.is_scala)) self.task = self.group_task(self._context, workdir='/not/real') self.task.prepare(round_manager=RoundManager(self._context)) self.task.execute()
def setUp(self): super(BaseGroupTaskTest, self).setUp() self._context = self.context(target_roots=self.create_targets()) self.populate_compile_classpath(self._context) self.recorded_actions = [] # NB: GroupTask has a cache of tasks by name... use a distinct name self.group_task = GroupTask.named( 'jvm-compile-%s' % uuid.uuid4().hex, ['classes_by_target', 'classes_by_source'], ['test']) self.group_task.add_member( self.group_member('javac', lambda t: t.is_java)) self.group_task.add_member( self.group_member('scalac', lambda t: t.is_scala)) self.task = self.group_task(self._context, workdir='/not/real') self.task.prepare(round_manager=RoundManager(self._context)) self.task.execute()