<s> from __future__ import ( absolute_import , division , generators , nested_scopes , print_function , <EOL> unicode_literals , with_statement ) <EOL> import logging <EOL> from pants . base . exceptions import TargetDefinitionException <EOL> from pants . build_graph . address import Address , Addresses <EOL> from pants . build_graph . address_lookup_error import AddressLookupError <EOL> from pants . build_graph . build_graph import BuildGraph <EOL> from pants . engine . exp . legacy . globs import BaseGlobs , Files <EOL> from pants . engine . exp . legacy . parser import TargetAdaptor <EOL> from pants . engine . exp . nodes import Return , SelectNode , State , Throw <EOL> from pants . engine . exp . selectors import Select , SelectDependencies <EOL> from pants . util . objects import datatype <EOL> logger = logging . getLogger ( __name__ ) <EOL> class ExpGraph ( BuildGraph ) : <EOL> """<STR_LIT>""" <EOL> def __init__ ( self , scheduler , engine , symbol_table_cls ) : <EOL> """<STR_LIT>""" <EOL> self . _scheduler = scheduler <EOL> self . _graph = scheduler . product_graph <EOL> self . _target_types = symbol_table_cls . aliases ( ) . target_types <EOL> self . _engine = engine <EOL> super ( ExpGraph , self ) . __init__ ( ) <EOL> def reset ( self ) : <EOL> super ( ExpGraph , self ) . reset ( ) <EOL> self . _index ( self . _graph . completed_nodes ( ) . keys ( ) ) <EOL> def _index ( self , roots ) : <EOL> """<STR_LIT>""" <EOL> all_addresses = set ( ) <EOL> new_targets = list ( ) <EOL> for node , state in self . _graph . walk ( roots = roots ) : <EOL> if type ( state ) is Throw : <EOL> raise AddressLookupError ( <EOL> '<STR_LIT>' . format ( node . subject , state . exc ) ) <EOL> elif type ( state ) is not Return : <EOL> State . raise_unrecognized ( state ) <EOL> if node . product is not LegacyBuildGraphNode : <EOL> continue <EOL> if type ( node ) is not SelectNode : <EOL> continue <EOL> target_adaptor , dependency_addresses = state . value <EOL> address = target_adaptor . address <EOL> all_addresses . add ( address ) <EOL> if address not in self . _target_by_address : <EOL> new_targets . append ( self . _index_target ( target_adaptor , dependency_addresses ) ) <EOL> deps_to_inject = set ( ) <EOL> addresses_to_inject = set ( ) <EOL> def inject ( target , dep_spec , is_dependency ) : <EOL> address = Address . parse ( dep_spec , relative_to = target . address . spec_path ) <EOL> if not any ( address == t . address for t in target . dependencies ) : <EOL> addresses_to_inject . add ( address ) <EOL> if is_dependency : <EOL> deps_to_inject . add ( ( target . address , address ) ) <EOL> for target in new_targets : <EOL> for spec in target . traversable_dependency_specs : <EOL> inject ( target , spec , is_dependency = True ) <EOL> for spec in target . traversable_specs : <EOL> inject ( target , spec , is_dependency = False ) <EOL> self . inject_addresses_closure ( addresses_to_inject ) <EOL> for target_address , dep_address in deps_to_inject : <EOL> self . inject_dependency ( dependent = target_address , dependency = dep_address ) <EOL> return all_addresses <EOL> def _index_target ( self , target_adaptor , dependencies ) : <EOL> """<STR_LIT>""" <EOL> address = target_adaptor . address <EOL> target = self . _instantiate_target ( target_adaptor ) <EOL> self . _target_by_address [ address ] = target <EOL> self . _target_dependencies_by_address [ address ] . update ( dependencies ) <EOL> for dependency in dependencies : <EOL> self . _target_dependees_by_address [ dependency ] . add ( address ) <EOL> return target <EOL> def _instantiate_sources ( self , relpath , sources ) : <EOL> """<STR_LIT>""" <EOL> if isinstance ( sources , Addresses ) : <EOL> return sources <EOL> if not isinstance ( sources , BaseGlobs ) : <EOL> sources = Files ( * sources ) <EOL> return sources . to_fileset_with_spec ( self . _engine , self . _scheduler , relpath ) <EOL> def _instantiate_target ( self , target_adaptor ) : <EOL> """<STR_LIT>""" <EOL> target_cls = self . _target_types [ target_adaptor . type_alias ] <EOL> try : <EOL> kwargs = target_adaptor . kwargs ( ) <EOL> kwargs . pop ( '<STR_LIT>' ) <EOL> spec_path = kwargs . pop ( '<STR_LIT>' ) <EOL> sources = kwargs . get ( '<STR_LIT>' , None ) <EOL> if sources is not None : <EOL> kwargs [ '<STR_LIT>' ] = self . _instantiate_sources ( spec_path , sources ) <EOL> return target_cls ( build_graph = self , ** kwargs ) <EOL> except TargetDefinitionException : <EOL> raise <EOL> except Exception as e : <EOL> raise TargetDefinitionException ( <EOL> target_adaptor . address , <EOL> '<STR_LIT>' . format ( target_cls , e ) ) <EOL> def inject_synthetic_target ( self , <EOL> address , <EOL> target_type , <EOL> dependencies = None , <EOL> derived_from = None , <EOL> ** kwargs ) : <EOL> sources = kwargs . get ( '<STR_LIT>' , None ) <EOL> if sources is not None : <EOL> kwargs [ '<STR_LIT>' ] = self . _instantiate_sources ( address . spec_path , sources ) <EOL> target = target_type ( name = address . target_name , <EOL> address = address , <EOL> build_graph = self , <EOL> ** kwargs ) <EOL> self . inject_target ( target , <EOL> dependencies = dependencies , <EOL> derived_from = derived_from , <EOL> synthetic = True ) <EOL> def inject_address_closure ( self , address ) : <EOL> if address in self . _target_by_address : <EOL> return <EOL> for _ in self . _inject ( [ address ] ) : <EOL> pass <EOL> def inject_addresses_closure ( self , addresses ) : <EOL> addresses = set ( addresses ) - set ( self . _target_by_address . keys ( ) ) <EOL> if not addresses : <EOL> return <EOL> for _ in self . _inject ( addresses ) : <EOL> pass <EOL> def inject_specs_closure ( self , specs , fail_fast = None ) : <EOL> for address in self . _inject ( specs ) : <EOL> yield address <EOL> def _inject ( self , subjects ) : <EOL> """<STR_LIT>""" <EOL> logger . debug ( '<STR_LIT>' . format ( self , subjects ) ) <EOL> request = self . _scheduler . execution_request ( [ LegacyBuildGraphNode ] , subjects ) <EOL> result = self . _engine . execute ( request ) <EOL> if result . error : <EOL> raise result . error <EOL> for address in self . _index ( request . roots ) : <EOL> yield address <EOL> class LegacyBuildGraphNode ( datatype ( '<STR_LIT>' , [ '<STR_LIT>' , '<STR_LIT>' ] ) ) : <EOL> """<STR_LIT>""" <EOL> def reify_legacy_graph ( target_adaptor , dependency_nodes ) : <EOL> """<STR_LIT>""" <EOL> return LegacyBuildGraphNode ( target_adaptor , <EOL> [ node . target_adaptor . address for node in dependency_nodes ] ) <EOL> def create_legacy_graph_tasks ( ) : <EOL> """<STR_LIT>""" <EOL> return [ <EOL> ( LegacyBuildGraphNode , <EOL> [ Select ( TargetAdaptor ) , <EOL> SelectDependencies ( LegacyBuildGraphNode , TargetAdaptor ) ] , <EOL> reify_legacy_graph ) , <EOL> ] </s>
