<s> from __future__ import ( absolute_import , division , generators , nested_scopes , print_function , <EOL> unicode_literals , with_statement ) <EOL> import os <EOL> from collections import OrderedDict , namedtuple <EOL> from twitter . common . collections . orderedset import OrderedSet <EOL> from pants . base . exceptions import TaskError <EOL> from pants . base . workunit import WorkUnit , WorkUnitLabel <EOL> from pants . engine . engine import Engine <EOL> from pants . engine . round_manager import RoundManager <EOL> class GoalExecutor ( object ) : <EOL> def __init__ ( self , context , goal , tasktypes_by_name ) : <EOL> self . _context = context <EOL> self . _goal = goal <EOL> self . _tasktypes_by_name = tasktypes_by_name <EOL> @ property <EOL> def goal ( self ) : <EOL> return self . _goal <EOL> def attempt ( self , explain ) : <EOL> """<STR_LIT>""" <EOL> goal_workdir = os . path . join ( self . _context . options . for_global_scope ( ) . pants_workdir , <EOL> self . _goal . name ) <EOL> with self . _context . new_workunit ( name = self . _goal . name , labels = [ WorkUnitLabel . GOAL ] ) : <EOL> for name , task_type in reversed ( self . _tasktypes_by_name . items ( ) ) : <EOL> task_workdir = os . path . join ( goal_workdir , name ) <EOL> task = task_type ( self . _context , task_workdir ) <EOL> log_config = WorkUnit . LogConfig ( level = task . get_options ( ) . level , colors = task . get_options ( ) . colors ) <EOL> with self . _context . new_workunit ( name = name , labels = [ WorkUnitLabel . TASK ] , log_config = log_config ) : <EOL> if explain : <EOL> self . _context . log . debug ( '<STR_LIT>' . format ( name ) ) <EOL> else : <EOL> task . execute ( ) <EOL> if explain : <EOL> reversed_tasktypes_by_name = reversed ( self . _tasktypes_by_name . items ( ) ) <EOL> goal_to_task = '<STR_LIT:U+002CU+0020>' . join ( <EOL> '<STR_LIT>' . format ( name , task_type . __name__ ) for name , task_type in reversed_tasktypes_by_name ) <EOL> print ( '<STR_LIT>' . format ( goal = self . _goal . name , goal_to_task = goal_to_task ) ) <EOL> class RoundEngine ( Engine ) : <EOL> """<STR_LIT>""" <EOL> class DependencyError ( ValueError ) : <EOL> """<STR_LIT>""" <EOL> class GoalCycleError ( DependencyError ) : <EOL> """<STR_LIT>""" <EOL> class TaskOrderError ( DependencyError ) : <EOL> """<STR_LIT>""" <EOL> class MissingProductError ( DependencyError ) : <EOL> """<STR_LIT>""" <EOL> GoalInfo = namedtuple ( '<STR_LIT>' , [ '<STR_LIT>' , '<STR_LIT>' , '<STR_LIT>' ] ) <EOL> def _topological_sort ( self , goal_info_by_goal ) : <EOL> dependees_by_goal = OrderedDict ( ) <EOL> def add_dependee ( goal , dependee = None ) : <EOL> dependees = dependees_by_goal . get ( goal ) <EOL> if dependees is None : <EOL> dependees = set ( ) <EOL> dependees_by_goal [ goal ] = dependees <EOL> if dependee : <EOL> dependees . add ( dependee ) <EOL> for goal , goal_info in goal_info_by_goal . items ( ) : <EOL> add_dependee ( goal ) <EOL> for dependency in goal_info . goal_dependencies : <EOL> add_dependee ( dependency , goal ) <EOL> satisfied = set ( ) <EOL> while dependees_by_goal : <EOL> count = len ( dependees_by_goal ) <EOL> for goal , dependees in dependees_by_goal . items ( ) : <EOL> unsatisfied = len ( dependees - satisfied ) <EOL> if unsatisfied == <NUM_LIT:0> : <EOL> satisfied . add ( goal ) <EOL> dependees_by_goal . pop ( goal ) <EOL> yield goal_info_by_goal [ goal ] <EOL> break <EOL> if len ( dependees_by_goal ) == count : <EOL> for dependees in dependees_by_goal . values ( ) : <EOL> dependees . difference_update ( satisfied ) <EOL> raise self . GoalCycleError ( '<STR_LIT>' <EOL> . format ( '<STR_LIT>' . join ( '<STR_LIT>' . format ( goal , list ( dependees ) ) <EOL> for goal , dependees <EOL> in dependees_by_goal . items ( ) ) ) ) <EOL> class TargetRootsReplacement ( object ) : <EOL> class ConflictingProposalsError ( Exception ) : <EOL> """<STR_LIT>""" <EOL> def __init__ ( self ) : <EOL> self . _proposer = None <EOL> self . _target_roots = None <EOL> def propose_alternates ( self , proposer , target_roots ) : <EOL> if target_roots is not None : <EOL> if self . _target_roots and ( self . _target_roots != target_roots ) : <EOL> raise self . ConflictingProposalsError ( <EOL> '<STR_LIT>' <EOL> '<STR_LIT>' . format ( self . _proposer , self . _target_roots , proposer , target_roots ) ) <EOL> self . _proposer = proposer <EOL> self . _target_roots = target_roots <EOL> def apply ( self , context ) : <EOL> if self . _target_roots is not None : <EOL> context . _replace_targets ( self . _target_roots ) <EOL> def _visit_goal ( self , goal , context , goal_info_by_goal , target_roots_replacement ) : <EOL> if goal in goal_info_by_goal : <EOL> return <EOL> tasktypes_by_name = OrderedDict ( ) <EOL> goal_dependencies = set ( ) <EOL> visited_task_types = set ( ) <EOL> for task_name in reversed ( goal . ordered_task_names ( ) ) : <EOL> task_type = goal . task_type_by_name ( task_name ) <EOL> tasktypes_by_name [ task_name ] = task_type <EOL> visited_task_types . add ( task_type ) <EOL> alternate_target_roots = task_type . _alternate_target_roots ( context . options , <EOL> context . address_mapper , <EOL> context . build_graph ) <EOL> target_roots_replacement . propose_alternates ( task_type , alternate_target_roots ) <EOL> round_manager = RoundManager ( context ) <EOL> task_type . _prepare ( context . options , round_manager ) <EOL> try : <EOL> dependencies = round_manager . get_dependencies ( ) <EOL> for producer_info in dependencies : <EOL> producer_goal = producer_info . goal <EOL> if producer_goal == goal : <EOL> if producer_info . task_type == task_type : <EOL> pass <EOL> elif producer_info . task_type in visited_task_types : <EOL> ordering = '<STR_LIT>' . join ( "<STR_LIT>" . format ( i , tn , <EOL> goal . task_type_by_name ( tn ) . __name__ ) <EOL> for i , tn in enumerate ( goal . ordered_task_names ( ) ) ) <EOL> raise self . TaskOrderError ( <EOL> "<STR_LIT>" <EOL> "<STR_LIT>" <EOL> . format ( name = task_name , <EOL> consumer_task = task_type . __name__ , <EOL> data = producer_info . product_type , <EOL> producer_task = producer_info . task_type . __name__ , <EOL> goal = goal . name , <EOL> ordering = ordering ) ) <EOL> else : <EOL> pass <EOL> else : <EOL> goal_dependencies . add ( producer_goal ) <EOL> except round_manager . MissingProductError as e : <EOL> raise self . MissingProductError ( <EOL> "<STR_LIT>" <EOL> . format ( name = task_name , action = task_type . __name__ , error = e ) ) <EOL> goal_info = self . GoalInfo ( goal , tasktypes_by_name , goal_dependencies ) <EOL> goal_info_by_goal [ goal ] = goal_info <EOL> for goal_dependency in goal_dependencies : <EOL> self . _visit_goal ( goal_dependency , context , goal_info_by_goal , target_roots_replacement ) <EOL> def _prepare ( self , context , goals ) : <EOL> if len ( goals ) == <NUM_LIT:0> : <EOL> raise TaskError ( '<STR_LIT>' ) <EOL> goal_info_by_goal = OrderedDict ( ) <EOL> target_roots_replacement = self . TargetRootsReplacement ( ) <EOL> for goal in reversed ( OrderedSet ( goals ) ) : <EOL> self . _visit_goal ( goal , context , goal_info_by_goal , target_roots_replacement ) <EOL> target_roots_replacement . apply ( context ) <EOL> for goal_info in reversed ( list ( self . _topological_sort ( goal_info_by_goal ) ) ) : <EOL> yield GoalExecutor ( context , goal_info . goal , goal_info . tasktypes_by_name ) <EOL> def attempt ( self , context , goals ) : <EOL> """<STR_LIT>""" <EOL> goal_executors = list ( self . _prepare ( context , goals ) ) <EOL> execution_goals = '<STR_LIT>' . join ( e . goal . name for e in goal_executors ) <EOL> context . log . info ( '<STR_LIT>' . format ( goals = execution_goals ) ) <EOL> explain = context . options . for_global_scope ( ) . explain <EOL> if explain : <EOL> print ( '<STR_LIT>' . format ( execution_goals ) ) <EOL> print ( '<STR_LIT>' ) <EOL> serialized_goals_executors = [ ge for ge in goal_executors if ge . goal . serialize ] <EOL> outer_lock_holder = serialized_goals_executors [ - <NUM_LIT:1> ] if serialized_goals_executors else None <EOL> if outer_lock_holder : <EOL> context . acquire_lock ( ) <EOL> try : <EOL> for goal_executor in goal_executors : <EOL> goal_executor . attempt ( explain ) <EOL> if goal_executor is outer_lock_holder : <EOL> context . release_lock ( ) <EOL> outer_lock_holder = None <EOL> finally : <EOL> if outer_lock_holder : <EOL> context . release_lock ( ) </s>
