<s> from __future__ import ( absolute_import , division , generators , nested_scopes , print_function , <EOL> unicode_literals , with_statement ) <EOL> from abc import abstractmethod , abstractproperty <EOL> from os . path import dirname <EOL> from pants . build_graph . address import Address <EOL> from pants . engine . exp . addressable import parse_variants <EOL> from pants . engine . exp . fs import ( Dir , DirectoryListing , File , FileContent , Link , Path , ReadLink , <EOL> Stats , file_content , list_directory , path_stat , read_link ) <EOL> from pants . engine . exp . struct import HasStructs , Variants <EOL> from pants . util . meta import AbstractClass <EOL> from pants . util . objects import datatype <EOL> class ConflictingProducersError ( Exception ) : <EOL> """<STR_LIT>""" <EOL> @ classmethod <EOL> def create ( cls , subject , product , matches ) : <EOL> """<STR_LIT>""" <EOL> msgs = '<STR_LIT>' . join ( '<STR_LIT>' . format ( k , v ) for k , v in matches . items ( ) ) <EOL> return ConflictingProducersError ( '<STR_LIT>' <EOL> . format ( product . __name__ , subject , msgs ) ) <EOL> def __init__ ( self , message ) : <EOL> super ( ConflictingProducersError , self ) . __init__ ( message ) <EOL> class State ( object ) : <EOL> @ classmethod <EOL> def raise_unrecognized ( cls , state ) : <EOL> raise ValueError ( '<STR_LIT>' . format ( state ) ) <EOL> class Noop ( datatype ( '<STR_LIT>' , [ '<STR_LIT>' ] ) , State ) : <EOL> """<STR_LIT>""" <EOL> class Return ( datatype ( '<STR_LIT>' , [ '<STR_LIT:value>' ] ) , State ) : <EOL> """<STR_LIT>""" <EOL> class Throw ( datatype ( '<STR_LIT>' , [ '<STR_LIT>' ] ) , State ) : <EOL> """<STR_LIT>""" <EOL> class Waiting ( datatype ( '<STR_LIT>' , [ '<STR_LIT>' ] ) , State ) : <EOL> """<STR_LIT>""" <EOL> class Node ( AbstractClass ) : <EOL> @ classmethod <EOL> def validate_node ( cls , node ) : <EOL> if not isinstance ( node , Node ) : <EOL> raise ValueError ( '<STR_LIT>' . format ( node ) ) <EOL> @ abstractproperty <EOL> def subject ( self ) : <EOL> """<STR_LIT>""" <EOL> @ abstractproperty <EOL> def product ( self ) : <EOL> """<STR_LIT>""" <EOL> @ abstractproperty <EOL> def variants ( self ) : <EOL> """<STR_LIT>""" <EOL> @ abstractproperty <EOL> def is_cacheable ( self ) : <EOL> """<STR_LIT>""" <EOL> @ abstractmethod <EOL> def step ( self , dependency_states , step_context ) : <EOL> """<STR_LIT>""" <EOL> class SelectNode ( datatype ( '<STR_LIT>' , [ '<STR_LIT>' , '<STR_LIT>' , '<STR_LIT>' , '<STR_LIT>' ] ) , Node ) : <EOL> """<STR_LIT>""" <EOL> @ property <EOL> def is_cacheable ( self ) : <EOL> return True <EOL> def _variants_node ( self ) : <EOL> if type ( self . subject ) is Address and self . product is not Variants : <EOL> return SelectNode ( self . subject , Variants , self . variants , None ) <EOL> return None <EOL> def _select_literal ( self , candidate , variant_value ) : <EOL> """<STR_LIT>""" <EOL> def items ( ) : <EOL> yield candidate <EOL> if isinstance ( candidate , HasStructs ) : <EOL> for subject in getattr ( candidate , candidate . collection_field ) : <EOL> yield subject <EOL> for item in items ( ) : <EOL> if not isinstance ( item , self . product ) : <EOL> continue <EOL> if variant_value and not getattr ( item , '<STR_LIT:name>' , None ) == variant_value : <EOL> continue <EOL> return item <EOL> return None <EOL> def step ( self , dependency_states , step_context ) : <EOL> variants = self . variants <EOL> variants_node = self . _variants_node ( ) <EOL> if variants_node : <EOL> dep_state = dependency_states . get ( variants_node , None ) <EOL> if dep_state is None or type ( dep_state ) == Waiting : <EOL> return Waiting ( [ variants_node ] ) <EOL> elif type ( dep_state ) == Return : <EOL> variants = Variants . merge ( dep_state . value . default . items ( ) , variants ) <EOL> variant_value = None <EOL> if self . variant_key : <EOL> variant_values = [ value for key , value in variants <EOL> if key == self . variant_key ] if variants else None <EOL> if not variant_values : <EOL> return Noop ( '<STR_LIT>' . format ( <EOL> self . variant_key , variants ) ) <EOL> variant_value = variant_values [ <NUM_LIT:0> ] <EOL> literal_value = self . _select_literal ( self . subject , variant_value ) <EOL> if literal_value is not None : <EOL> return Return ( literal_value ) <EOL> has_waiting_dep = False <EOL> dependencies = list ( step_context . gen_nodes ( self . subject , self . product , variants ) ) <EOL> matches = { } <EOL> for dep in dependencies : <EOL> dep_state = dependency_states . get ( dep , None ) <EOL> if dep_state is None or type ( dep_state ) == Waiting : <EOL> has_waiting_dep = True <EOL> continue <EOL> elif type ( dep_state ) == Throw : <EOL> return dep_state <EOL> elif type ( dep_state ) == Noop : <EOL> continue <EOL> elif type ( dep_state ) != Return : <EOL> State . raise_unrecognized ( dep_state ) <EOL> literal_value = self . _select_literal ( dep_state . value , variant_value ) <EOL> if literal_value is not None : <EOL> matches [ dep ] = literal_value <EOL> if has_waiting_dep : <EOL> return Waiting ( dependencies ) <EOL> elif len ( matches ) > <NUM_LIT:1> : <EOL> return Throw ( ConflictingProducersError . create ( self . subject , self . product , matches ) ) <EOL> elif len ( matches ) == <NUM_LIT:1> : <EOL> return Return ( matches . values ( ) [ <NUM_LIT:0> ] ) <EOL> return Noop ( '<STR_LIT>' . format ( self ) ) <EOL> class DependenciesNode ( datatype ( '<STR_LIT>' , [ '<STR_LIT>' , '<STR_LIT>' , '<STR_LIT>' , '<STR_LIT>' , '<STR_LIT>' ] ) , Node ) : <EOL> """<STR_LIT>""" <EOL> @ property <EOL> def is_cacheable ( self ) : <EOL> return True <EOL> def _dep_product_node ( self ) : <EOL> return SelectNode ( self . subject , self . dep_product , self . variants , None ) <EOL> def _dependency_nodes ( self , step_context , dep_product ) : <EOL> for dependency in getattr ( dep_product , self . field or '<STR_LIT>' ) : <EOL> variants = self . variants <EOL> if isinstance ( dependency , Address ) : <EOL> dependency , literal_variants = parse_variants ( dependency ) <EOL> variants = Variants . merge ( variants , literal_variants ) <EOL> yield SelectNode ( dependency , self . product , variants , None ) <EOL> def step ( self , dependency_states , step_context ) : <EOL> dep_product_node = self . _dep_product_node ( ) <EOL> dep_product_state = dependency_states . get ( dep_product_node , None ) <EOL> if dep_product_state is None or type ( dep_product_state ) == Waiting : <EOL> return Waiting ( [ dep_product_node ] ) <EOL> elif type ( dep_product_state ) == Throw : <EOL> return dep_product_state <EOL> elif type ( dep_product_state ) == Noop : <EOL> return Noop ( '<STR_LIT>' . format ( dep_product_node ) ) <EOL> elif type ( dep_product_state ) != Return : <EOL> State . raise_unrecognized ( dep_product_state ) <EOL> dependencies = list ( self . _dependency_nodes ( step_context , dep_product_state . value ) ) <EOL> for dependency in dependencies : <EOL> dep_state = dependency_states . get ( dependency , None ) <EOL> if dep_state is None or type ( dep_state ) == Waiting : <EOL> return Waiting ( [ dep_product_node ] + dependencies ) <EOL> elif type ( dep_state ) == Throw : <EOL> return dep_state <EOL> elif type ( dep_state ) == Noop : <EOL> return Throw ( ValueError ( '<STR_LIT>' . format ( dependency ) ) ) <EOL> elif type ( dep_state ) != Return : <EOL> raise State . raise_unrecognized ( dep_state ) <EOL> return Return ( [ dependency_states [ d ] . value for d in dependencies ] ) <EOL> class ProjectionNode ( datatype ( '<STR_LIT>' , [ '<STR_LIT>' , '<STR_LIT>' , '<STR_LIT>' , '<STR_LIT>' , '<STR_LIT>' , '<STR_LIT>' ] ) , Node ) : <EOL> """<STR_LIT>""" <EOL> @ property <EOL> def is_cacheable ( self ) : <EOL> return True <EOL> def _input_node ( self ) : <EOL> return SelectNode ( self . subject , self . input_product , self . variants , None ) <EOL> def _output_node ( self , step_context , projected_subject ) : <EOL> return SelectNode ( projected_subject , self . product , self . variants , None ) <EOL> def step ( self , dependency_states , step_context ) : <EOL> input_node = self . _input_node ( ) <EOL> input_state = dependency_states . get ( input_node , None ) <EOL> if input_state is None or type ( input_state ) == Waiting : <EOL> return Waiting ( [ input_node ] ) <EOL> elif type ( input_state ) == Throw : <EOL> return input_state <EOL> elif type ( input_state ) == Noop : <EOL> return Noop ( '<STR_LIT>' . format ( input_node ) ) <EOL> elif type ( input_state ) != Return : <EOL> State . raise_unrecognized ( input_state ) <EOL> input_product = input_state . value <EOL> values = [ ] <EOL> for field in self . fields : <EOL> values . append ( getattr ( input_product , field ) ) <EOL> if len ( values ) == <NUM_LIT:1> and type ( values [ <NUM_LIT:0> ] ) is self . projected_subject : <EOL> projected_subject = values [ <NUM_LIT:0> ] <EOL> else : <EOL> projected_subject = self . projected_subject ( * values ) <EOL> output_node = self . _output_node ( step_context , projected_subject ) <EOL> output_state = dependency_states . get ( output_node , None ) <EOL> if output_state is None or type ( output_state ) == Waiting : <EOL> return Waiting ( [ input_node , output_node ] ) <EOL> elif type ( output_state ) == Noop : <EOL> return Noop ( '<STR_LIT>' . format ( output_node ) ) <EOL> elif type ( output_state ) in [ Throw , Return ] : <EOL> return output_state <EOL> else : <EOL> raise State . raise_unrecognized ( output_state ) <EOL> class TaskNode ( datatype ( '<STR_LIT>' , [ '<STR_LIT>' , '<STR_LIT>' , '<STR_LIT>' , '<STR_LIT>' , '<STR_LIT>' ] ) , Node ) : <EOL> @ property <EOL> def is_cacheable ( self ) : <EOL> return True <EOL> def step ( self , dependency_states , step_context ) : <EOL> dep_values = [ ] <EOL> dependencies = [ step_context . select_node ( selector , self . subject , self . variants ) <EOL> for selector in self . clause ] <EOL> for dep_select , dep_key in zip ( self . clause , dependencies ) : <EOL> dep_state = dependency_states . get ( dep_key , None ) <EOL> if dep_state is None or type ( dep_state ) == Waiting : <EOL> return Waiting ( dependencies ) <EOL> elif type ( dep_state ) == Return : <EOL> dep_values . append ( dep_state . value ) <EOL> elif type ( dep_state ) == Noop : <EOL> if dep_select . optional : <EOL> dep_values . append ( None ) <EOL> else : <EOL> return Noop ( '<STR_LIT>' . format ( dep_key ) ) <EOL> elif type ( dep_state ) == Throw : <EOL> return dep_state <EOL> else : <EOL> State . raise_unrecognized ( dep_state ) <EOL> try : <EOL> return Return ( self . func ( * dep_values ) ) <EOL> except Exception as e : <EOL> return Throw ( e ) <EOL> def __repr__ ( self ) : <EOL> return '<STR_LIT>' . format ( self . subject , self . product , self . variants , self . func . __name__ , self . clause ) <EOL> def __str__ ( self ) : <EOL> return repr ( self ) <EOL> class FilesystemNode ( datatype ( '<STR_LIT>' , [ '<STR_LIT>' , '<STR_LIT>' , '<STR_LIT>' ] ) , Node ) : <EOL> """<STR_LIT>""" <EOL> _FS_PAIRS = { <EOL> ( DirectoryListing , Dir ) , <EOL> ( FileContent , File ) , <EOL> ( Stats , Path ) , <EOL> ( ReadLink , Link ) , <EOL> } <EOL> _FS_PRODUCT_TYPES = { product for product , subject in _FS_PAIRS } <EOL> @ classmethod <EOL> def is_filesystem_pair ( cls , subject_type , product ) : <EOL> """<STR_LIT>""" <EOL> return ( product , subject_type ) in cls . _FS_PAIRS <EOL> @ classmethod <EOL> def generate_subjects ( self , filenames ) : <EOL> """<STR_LIT>""" <EOL> for f in filenames : <EOL> yield Path ( f ) <EOL> yield File ( f ) <EOL> yield Link ( f ) <EOL> yield Dir ( dirname ( f ) ) <EOL> @ property <EOL> def is_cacheable ( self ) : <EOL> """<STR_LIT>""" <EOL> return False <EOL> def step ( self , dependency_states , step_context ) : <EOL> try : <EOL> if self . product is Stats : <EOL> return Return ( path_stat ( step_context . project_tree , self . subject ) ) <EOL> elif self . product is FileContent : <EOL> return Return ( file_content ( step_context . project_tree , self . subject ) ) <EOL> elif self . product is DirectoryListing : <EOL> return Return ( list_directory ( step_context . project_tree , self . subject ) ) <EOL> elif self . product is ReadLink : <EOL> return Return ( read_link ( step_context . project_tree , self . subject ) ) <EOL> else : <EOL> raise ValueError ( '<STR_LIT>' . format ( self . subject , self ) ) <EOL> except Exception as e : <EOL> return Throw ( e ) <EOL> class StepContext ( object ) : <EOL> """<STR_LIT>""" <EOL> def __init__ ( self , node_builder , project_tree ) : <EOL> self . _node_builder = node_builder <EOL> self . project_tree = project_tree <EOL> def gen_nodes ( self , subject , product , variants ) : <EOL> """<STR_LIT>""" <EOL> return self . _node_builder . gen_nodes ( subject , product , variants ) <EOL> def select_node ( self , selector , subject , variants ) : <EOL> """<STR_LIT>""" <EOL> return self . _node_builder . select_node ( selector , subject , variants ) </s>
