<s> from __future__ import ( absolute_import , division , generators , nested_scopes , print_function , <EOL> unicode_literals , with_statement ) <EOL> import os <EOL> from collections import defaultdict <EOL> from twitter . common . collections import OrderedSet <EOL> from pants . backend . jvm . tasks . jvm_dependency_analyzer import JvmDependencyAnalyzer <EOL> from pants . base . build_environment import get_buildroot <EOL> from pants . base . exceptions import TaskError <EOL> from pants . java . distribution . distribution import DistributionLocator <EOL> class JvmDependencyCheck ( JvmDependencyAnalyzer ) : <EOL> """<STR_LIT>""" <EOL> @ classmethod <EOL> def register_options ( cls , register ) : <EOL> super ( JvmDependencyCheck , cls ) . register_options ( register ) <EOL> register ( '<STR_LIT>' , choices = [ '<STR_LIT>' , '<STR_LIT>' , '<STR_LIT>' ] , default = '<STR_LIT>' , <EOL> fingerprint = True , <EOL> help = '<STR_LIT>' <EOL> '<STR_LIT>' <EOL> '<STR_LIT>' ) <EOL> register ( '<STR_LIT>' , choices = [ '<STR_LIT>' , '<STR_LIT>' , '<STR_LIT>' ] , <EOL> default = '<STR_LIT>' , <EOL> fingerprint = True , <EOL> help = '<STR_LIT>' <EOL> '<STR_LIT>' <EOL> '<STR_LIT>' <EOL> '<STR_LIT>' <EOL> '<STR_LIT>' <EOL> '<STR_LIT>' <EOL> '<STR_LIT>' ) <EOL> register ( '<STR_LIT>' , type = list , default = [ ] , <EOL> fingerprint = True , <EOL> help = "<STR_LIT>" ) <EOL> register ( '<STR_LIT>' , choices = [ '<STR_LIT>' , '<STR_LIT>' , '<STR_LIT>' ] , default = '<STR_LIT>' , <EOL> fingerprint = True , <EOL> help = '<STR_LIT>' <EOL> '<STR_LIT>' <EOL> '<STR_LIT>' ) <EOL> def __init__ ( self , * args , ** kwargs ) : <EOL> super ( JvmDependencyCheck , self ) . __init__ ( * args , ** kwargs ) <EOL> def munge_flag ( flag ) : <EOL> flag_value = self . get_options ( ) . get ( flag , None ) <EOL> return None if flag_value == '<STR_LIT>' else flag_value <EOL> self . _check_missing_deps = munge_flag ( '<STR_LIT>' ) <EOL> self . _check_missing_direct_deps = munge_flag ( '<STR_LIT>' ) <EOL> self . _check_unnecessary_deps = munge_flag ( '<STR_LIT>' ) <EOL> self . _target_whitelist = self . get_options ( ) . missing_deps_whitelist <EOL> @ classmethod <EOL> def skip ( cls , options ) : <EOL> values = [ options . missing_deps , options . missing_direct_deps , options . unnecessary_deps ] <EOL> return all ( v == '<STR_LIT>' for v in values ) <EOL> @ property <EOL> def cache_target_dirs ( self ) : <EOL> return True <EOL> def execute ( self ) : <EOL> if self . skip ( self . get_options ( ) ) : <EOL> return <EOL> with self . invalidated ( self . context . targets ( ) , <EOL> invalidate_dependents = True ) as invalidation_check : <EOL> for vt in invalidation_check . invalid_vts : <EOL> product_deps_by_src = self . context . products . get_data ( '<STR_LIT>' ) . get ( vt . target ) <EOL> if product_deps_by_src is not None : <EOL> self . check ( vt . target , product_deps_by_src ) <EOL> def check ( self , src_tgt , actual_deps ) : <EOL> """<STR_LIT>""" <EOL> if self . _check_missing_deps or self . _check_missing_direct_deps or self . _check_unnecessary_deps : <EOL> missing_file_deps , missing_tgt_deps , missing_direct_tgt_deps = self . _compute_missing_deps ( src_tgt , actual_deps ) <EOL> buildroot = get_buildroot ( ) <EOL> def shorten ( path ) : <EOL> if path . startswith ( buildroot ) : <EOL> return os . path . relpath ( path , buildroot ) <EOL> return path <EOL> def filter_whitelisted ( missing_deps ) : <EOL> return [ ( tgt_pair , evidence ) for ( tgt_pair , evidence ) in missing_deps <EOL> if tgt_pair [ <NUM_LIT:0> ] . address . reference ( ) not in self . _target_whitelist ] <EOL> missing_tgt_deps = filter_whitelisted ( missing_tgt_deps ) <EOL> if self . _check_missing_deps and ( missing_file_deps or missing_tgt_deps ) : <EOL> log_fn = ( self . context . log . error if self . _check_missing_deps == '<STR_LIT>' <EOL> else self . context . log . warn ) <EOL> for ( tgt_pair , evidence ) in missing_tgt_deps : <EOL> evidence_str = '<STR_LIT:\n>' . join ( [ '<STR_LIT>' . format ( shorten ( e [ <NUM_LIT:0> ] ) , shorten ( e [ <NUM_LIT:1> ] ) ) <EOL> for e in evidence ] ) <EOL> log_fn ( '<STR_LIT>' <EOL> . format ( tgt_pair [ <NUM_LIT:0> ] . address . reference ( ) , tgt_pair [ <NUM_LIT:1> ] . address . reference ( ) , <EOL> evidence_str ) ) <EOL> for ( src_tgt , dep ) in missing_file_deps : <EOL> log_fn ( '<STR_LIT>' <EOL> . format ( src_tgt . address . reference ( ) , shorten ( dep ) ) ) <EOL> if self . _check_missing_deps == '<STR_LIT>' : <EOL> raise TaskError ( '<STR_LIT>' ) <EOL> missing_direct_tgt_deps = filter_whitelisted ( missing_direct_tgt_deps ) <EOL> if self . _check_missing_direct_deps and missing_direct_tgt_deps : <EOL> log_fn = ( self . context . log . error if self . _check_missing_direct_deps == '<STR_LIT>' <EOL> else self . context . log . warn ) <EOL> for ( tgt_pair , evidence ) in missing_direct_tgt_deps : <EOL> evidence_str = '<STR_LIT:\n>' . join ( [ '<STR_LIT>' . format ( shorten ( e [ <NUM_LIT:0> ] ) , shorten ( e [ <NUM_LIT:1> ] ) ) <EOL> for e in evidence ] ) <EOL> log_fn ( '<STR_LIT>' <EOL> . format ( tgt_pair [ <NUM_LIT:0> ] . address , tgt_pair [ <NUM_LIT:1> ] . address , evidence_str ) ) <EOL> if self . _check_missing_direct_deps == '<STR_LIT>' : <EOL> raise TaskError ( '<STR_LIT>' ) <EOL> if self . _check_unnecessary_deps : <EOL> raise TaskError ( '<STR_LIT>' ) <EOL> def _compute_missing_deps ( self , src_tgt , actual_deps ) : <EOL> """<STR_LIT>""" <EOL> def must_be_explicit_dep ( dep ) : <EOL> return ( dep not in self . bootstrap_jar_classfiles <EOL> and not dep . startswith ( DistributionLocator . cached ( ) . real_home ) ) <EOL> def target_or_java_dep_in_targets ( target , targets ) : <EOL> if target in targets : <EOL> return True <EOL> elif target . is_scala : <EOL> return any ( t in targets for t in target . java_sources ) <EOL> else : <EOL> return False <EOL> transitive_deps_by_target = self . _compute_transitive_deps_by_target ( ) <EOL> missing_file_deps = OrderedSet ( ) <EOL> missing_tgt_deps_map = defaultdict ( list ) <EOL> missing_direct_tgt_deps_map = defaultdict ( list ) <EOL> buildroot = get_buildroot ( ) <EOL> abs_srcs = [ os . path . join ( buildroot , src ) for src in src_tgt . sources_relative_to_buildroot ( ) ] <EOL> for src in abs_srcs : <EOL> for actual_dep in filter ( must_be_explicit_dep , actual_deps . get ( src , [ ] ) ) : <EOL> actual_dep_tgts = self . targets_by_file . get ( actual_dep ) <EOL> if actual_dep_tgts is None : <EOL> missing_file_deps . add ( ( src_tgt , actual_dep ) ) <EOL> elif not target_or_java_dep_in_targets ( src_tgt , actual_dep_tgts ) : <EOL> canonical_actual_dep_tgt = next ( iter ( actual_dep_tgts ) ) <EOL> if actual_dep_tgts . isdisjoint ( transitive_deps_by_target . get ( src_tgt , [ ] ) ) : <EOL> missing_tgt_deps_map [ ( src_tgt , canonical_actual_dep_tgt ) ] . append ( ( src , actual_dep ) ) <EOL> elif canonical_actual_dep_tgt not in src_tgt . dependencies : <EOL> missing_direct_tgt_deps_map [ ( src_tgt , canonical_actual_dep_tgt ) ] . append ( <EOL> ( src , actual_dep ) ) <EOL> return ( list ( missing_file_deps ) , <EOL> missing_tgt_deps_map . items ( ) , <EOL> missing_direct_tgt_deps_map . items ( ) ) </s>
