<s> from __future__ import ( absolute_import , division , generators , nested_scopes , print_function , <EOL> unicode_literals , with_statement ) <EOL> import itertools <EOL> import os <EOL> import re <EOL> from collections import OrderedDict <EOL> from twitter . common . collections import OrderedSet <EOL> from pants . backend . jvm . tasks . classpath_products import ClasspathEntry <EOL> from pants . util . contextutil import open_zip <EOL> from pants . util . dirutil import fast_relpath , safe_delete , safe_open , safe_walk <EOL> class MissingClasspathEntryError ( Exception ) : <EOL> """<STR_LIT>""" <EOL> class ClasspathUtil ( object ) : <EOL> @ classmethod <EOL> def compute_classpath ( cls , targets , classpath_products , extra_classpath_tuples , confs ) : <EOL> """<STR_LIT>""" <EOL> classpath_iter = cls . _classpath_iter ( targets , classpath_products , confs = confs ) <EOL> total_classpath = OrderedSet ( classpath_iter ) <EOL> filtered_extra_classpath_iter = cls . _filtered_classpath_by_confs_iter ( extra_classpath_tuples , <EOL> confs ) <EOL> extra_classpath_iter = cls . _entries_iter ( filtered_extra_classpath_iter ) <EOL> total_classpath . update ( extra_classpath_iter ) <EOL> return list ( total_classpath ) <EOL> @ classmethod <EOL> def classpath ( cls , targets , classpath_products , confs = ( '<STR_LIT:default>' , ) ) : <EOL> """<STR_LIT>""" <EOL> classpath_iter = cls . _classpath_iter ( targets , classpath_products , confs = confs ) <EOL> return list ( classpath_iter ) <EOL> @ classmethod <EOL> def _classpath_iter ( cls , targets , classpath_products , confs = ( '<STR_LIT:default>' , ) ) : <EOL> classpath_tuples = classpath_products . get_for_targets ( targets ) <EOL> filtered_tuples_iter = cls . _filtered_classpath_by_confs_iter ( classpath_tuples , confs ) <EOL> return cls . _entries_iter ( filtered_tuples_iter ) <EOL> @ classmethod <EOL> def internal_classpath ( cls , targets , classpath_products , confs = ( '<STR_LIT:default>' , ) ) : <EOL> """<STR_LIT>""" <EOL> classpath_tuples = classpath_products . get_internal_classpath_entries_for_targets ( targets ) <EOL> filtered_tuples_iter = cls . _filtered_classpath_by_confs_iter ( classpath_tuples , confs ) <EOL> return [ entry . path for entry in cls . _entries_iter ( filtered_tuples_iter ) ] <EOL> @ classmethod <EOL> def classpath_by_targets ( cls , targets , classpath_products , confs = ( '<STR_LIT:default>' , ) ) : <EOL> """<STR_LIT>""" <EOL> classpath_target_tuples = classpath_products . get_product_target_mappings_for_targets ( targets ) <EOL> filtered_items_iter = itertools . ifilter ( cls . _accept_conf_filter ( confs , lambda x : x [ <NUM_LIT:0> ] [ <NUM_LIT:0> ] ) , <EOL> classpath_target_tuples ) <EOL> target_to_classpath = OrderedDict ( ) <EOL> for classpath_entry , target in filtered_items_iter : <EOL> _ , entry = classpath_entry <EOL> if not target in target_to_classpath : <EOL> target_to_classpath [ target ] = [ ] <EOL> target_to_classpath [ target ] . append ( entry ) <EOL> return target_to_classpath <EOL> @ classmethod <EOL> def _accept_conf_filter ( cls , confs , unpack_func = None ) : <EOL> def accept_conf_in_item ( item ) : <EOL> conf = unpack_func ( item ) <EOL> return confs is None or conf in confs <EOL> unpack_func = unpack_func or ( lambda x : x ) <EOL> return accept_conf_in_item <EOL> @ classmethod <EOL> def _filtered_classpath_by_confs_iter ( cls , classpath_tuples , confs ) : <EOL> filter_func = cls . _accept_conf_filter ( confs , unpack_func = lambda x : x [ <NUM_LIT:0> ] ) <EOL> return itertools . ifilter ( filter_func , classpath_tuples ) <EOL> @ classmethod <EOL> def _entries_iter ( cls , classpath ) : <EOL> for conf , entry in classpath : <EOL> yield entry <EOL> @ classmethod <EOL> def classpath_contents ( cls , targets , classpath_products , confs = ( '<STR_LIT:default>' , ) ) : <EOL> """<STR_LIT>""" <EOL> classpath_iter = cls . _classpath_iter ( targets , classpath_products , confs = confs ) <EOL> for f in cls . classpath_entries_contents ( classpath_iter ) : <EOL> yield f <EOL> @ classmethod <EOL> def classpath_entries_contents ( cls , classpath_entries ) : <EOL> """<STR_LIT>""" <EOL> for entry in classpath_entries : <EOL> if cls . is_jar ( entry ) : <EOL> with open_zip ( entry , mode = '<STR_LIT:r>' ) as jar : <EOL> for name in jar . namelist ( ) : <EOL> yield name <EOL> elif os . path . isdir ( entry ) : <EOL> def rel_walk_name ( abs_sub_dir , name ) : <EOL> return fast_relpath ( os . path . join ( abs_sub_dir , name ) , entry ) <EOL> for abs_sub_dir , dirnames , filenames in safe_walk ( entry ) : <EOL> for name in dirnames : <EOL> yield '<STR_LIT>' . format ( rel_walk_name ( abs_sub_dir , name ) ) <EOL> for name in filenames : <EOL> yield rel_walk_name ( abs_sub_dir , name ) <EOL> else : <EOL> pass <EOL> @ classmethod <EOL> def classname_for_rel_classfile ( cls , class_file_name ) : <EOL> """<STR_LIT>""" <EOL> if not class_file_name . endswith ( '<STR_LIT>' ) : <EOL> return None <EOL> return class_file_name [ : - len ( '<STR_LIT>' ) ] . replace ( '<STR_LIT:/>' , '<STR_LIT:.>' ) <EOL> @ classmethod <EOL> def is_jar ( cls , path ) : <EOL> """<STR_LIT>""" <EOL> return path . endswith ( ( '<STR_LIT>' , '<STR_LIT>' ) ) and os . path . isfile ( path ) <EOL> @ classmethod <EOL> def is_dir ( cls , path ) : <EOL> """<STR_LIT>""" <EOL> return os . path . isdir ( path ) <EOL> @ classmethod <EOL> def create_canonical_classpath ( cls , classpath_products , targets , basedir , <EOL> save_classpath_file = False , <EOL> internal_classpath_only = True , <EOL> excludes = None ) : <EOL> """<STR_LIT>""" <EOL> def delete_old_target_output_files ( classpath_prefix ) : <EOL> """<STR_LIT>""" <EOL> directory , basename = os . path . split ( classpath_prefix ) <EOL> pattern = re . compile ( r'<STR_LIT>' <EOL> . format ( basename = re . escape ( basename ) ) ) <EOL> files = [ filename for filename in os . listdir ( directory ) if pattern . match ( filename ) ] <EOL> for rel_path in files : <EOL> path = os . path . join ( directory , rel_path ) <EOL> if os . path . islink ( path ) or os . path . isfile ( path ) : <EOL> safe_delete ( path ) <EOL> def prepare_target_output_folder ( basedir , target ) : <EOL> """<STR_LIT>""" <EOL> output_dir = basedir <EOL> classpath_prefix_for_target = '<STR_LIT>' . format ( basedir = basedir , <EOL> target_id = target . id ) <EOL> if os . path . exists ( output_dir ) : <EOL> delete_old_target_output_files ( classpath_prefix_for_target ) <EOL> else : <EOL> os . makedirs ( output_dir ) <EOL> return classpath_prefix_for_target <EOL> excludes = excludes or set ( ) <EOL> canonical_classpath = [ ] <EOL> target_to_classpath = cls . classpath_by_targets ( targets , classpath_products ) <EOL> processed_entries = set ( ) <EOL> for target , classpath_entries_for_target in target_to_classpath . items ( ) : <EOL> if internal_classpath_only : <EOL> classpath_entries_for_target = filter ( ClasspathEntry . is_internal_classpath_entry , <EOL> classpath_entries_for_target ) <EOL> if len ( classpath_entries_for_target ) > <NUM_LIT:0> : <EOL> classpath_prefix_for_target = prepare_target_output_folder ( basedir , target ) <EOL> for ( index , entry ) in enumerate ( classpath_entries_for_target ) : <EOL> if entry . is_excluded_by ( excludes ) : <EOL> continue <EOL> if entry in processed_entries : <EOL> continue <EOL> processed_entries . add ( entry ) <EOL> _ , ext = os . path . splitext ( entry . path ) <EOL> symlink_path = '<STR_LIT>' . format ( classpath_prefix_for_target , index , ext ) <EOL> real_entry_path = os . path . realpath ( entry . path ) <EOL> if not os . path . exists ( real_entry_path ) : <EOL> raise MissingClasspathEntryError ( '<STR_LIT>' <EOL> '<STR_LIT>' <EOL> . format ( realpath = real_entry_path , src = entry . path , dst = symlink_path ) ) <EOL> os . symlink ( real_entry_path , symlink_path ) <EOL> canonical_classpath . append ( symlink_path ) <EOL> if save_classpath_file : <EOL> classpath = [ entry . path for entry in classpath_entries_for_target ] <EOL> with safe_open ( '<STR_LIT>' . format ( classpath_prefix_for_target ) , '<STR_LIT:wb>' ) as classpath_file : <EOL> classpath_file . write ( os . pathsep . join ( classpath ) . encode ( '<STR_LIT:utf-8>' ) ) <EOL> classpath_file . write ( '<STR_LIT:\n>' ) <EOL> return canonical_classpath </s>
