<s> from __future__ import ( absolute_import , division , generators , nested_scopes , print_function , <EOL> unicode_literals , with_statement ) <EOL> import os <EOL> from collections import namedtuple <EOL> from six . moves import range <EOL> from pants . base . build_environment import get_buildroot <EOL> from pants . subsystem . subsystem import Subsystem <EOL> from pants . util . memo import memoized_method <EOL> SourceRoot = namedtuple ( '<STR_LIT>' , [ '<STR_LIT:path>' , '<STR_LIT>' ] ) <EOL> class SourceRoots ( object ) : <EOL> """<STR_LIT>""" <EOL> def __init__ ( self , source_root_config ) : <EOL> """<STR_LIT>""" <EOL> self . _trie = source_root_config . create_trie ( ) <EOL> self . _options = source_root_config . get_options ( ) <EOL> def add_source_root ( self , path , langs = tuple ( ) ) : <EOL> """<STR_LIT>""" <EOL> if os . path . isabs ( path ) : <EOL> path = os . path . relpath ( path , get_buildroot ( ) ) <EOL> self . _trie . add_fixed ( path , langs ) <EOL> def find ( self , target ) : <EOL> """<STR_LIT>""" <EOL> return self . find_by_path ( target . address . spec_path ) <EOL> def find_by_path ( self , path ) : <EOL> """<STR_LIT>""" <EOL> if os . path . isabs ( path ) : <EOL> path = os . path . relpath ( path , get_buildroot ( ) ) <EOL> matched = self . _trie . find ( path ) <EOL> if matched : <EOL> return matched <EOL> elif self . _options . unmatched == '<STR_LIT>' : <EOL> return None <EOL> elif self . _options . unmatched == '<STR_LIT>' : <EOL> return SourceRoot ( path , [ ] ) <EOL> def all_roots ( self ) : <EOL> """<STR_LIT>""" <EOL> buildroot = get_buildroot ( ) <EOL> ignore = { '<STR_LIT>' } . union ( { os . path . relpath ( self . _options [ k ] , buildroot ) for k in <EOL> [ '<STR_LIT>' , '<STR_LIT>' , '<STR_LIT>' ] } ) <EOL> for dirpath , dirnames , _ in os . walk ( buildroot , topdown = True ) : <EOL> relpath = os . path . relpath ( dirpath , buildroot ) <EOL> if relpath in ignore : <EOL> del dirnames [ : ] <EOL> else : <EOL> match = self . _trie . find ( relpath ) <EOL> if match : <EOL> yield match <EOL> del dirnames [ : ] <EOL> class SourceRootConfig ( Subsystem ) : <EOL> """<STR_LIT>""" <EOL> options_scope = '<STR_LIT:source>' <EOL> _DEFAULT_LANG_CANONICALIZATIONS = { <EOL> '<STR_LIT>' : ( '<STR_LIT>' , '<STR_LIT>' ) , <EOL> '<STR_LIT>' : ( '<STR_LIT>' , ) , <EOL> '<STR_LIT>' : ( '<STR_LIT>' , ) <EOL> } <EOL> _DEFAULT_SOURCE_ROOT_PATTERNS = [ <EOL> '<STR_LIT>' , <EOL> '<STR_LIT>' , <EOL> '<STR_LIT>' , <EOL> ] <EOL> _DEFAULT_TEST_ROOT_PATTERNS = [ <EOL> '<STR_LIT>' , <EOL> '<STR_LIT>' , <EOL> '<STR_LIT>' <EOL> ] <EOL> _DEFAULT_SOURCE_ROOTS = { <EOL> '<STR_LIT>' : ( '<STR_LIT>' , ) , <EOL> '<STR_LIT>' : ( '<STR_LIT>' , ) <EOL> } <EOL> _DEFAULT_TEST_ROOTS = { <EOL> } <EOL> @ classmethod <EOL> def register_options ( cls , register ) : <EOL> super ( SourceRootConfig , cls ) . register_options ( register ) <EOL> register ( '<STR_LIT>' , choices = [ '<STR_LIT>' , '<STR_LIT>' ] , default = '<STR_LIT>' , advanced = True , <EOL> help = '<STR_LIT>' <EOL> '<STR_LIT>' <EOL> '<STR_LIT>' ) <EOL> register ( '<STR_LIT>' , metavar = '<STR_LIT>' , type = dict , <EOL> default = cls . _DEFAULT_LANG_CANONICALIZATIONS , advanced = True , <EOL> help = '<STR_LIT>' ) <EOL> register ( '<STR_LIT>' , metavar = '<STR_LIT>' , type = list , <EOL> default = cls . _DEFAULT_SOURCE_ROOT_PATTERNS , advanced = True , <EOL> help = '<STR_LIT>' <EOL> '<STR_LIT>' ) <EOL> register ( '<STR_LIT>' , metavar = '<STR_LIT>' , type = list , <EOL> default = cls . _DEFAULT_TEST_ROOT_PATTERNS , advanced = True , <EOL> help = '<STR_LIT>' <EOL> '<STR_LIT>' ) <EOL> register ( '<STR_LIT>' , metavar = '<STR_LIT>' , type = dict , <EOL> default = cls . _DEFAULT_SOURCE_ROOTS , advanced = True , <EOL> help = '<STR_LIT>' <EOL> '<STR_LIT>' ) <EOL> register ( '<STR_LIT>' , metavar = '<STR_LIT>' , type = dict , <EOL> default = cls . _DEFAULT_TEST_ROOTS , advanced = True , <EOL> help = '<STR_LIT>' <EOL> '<STR_LIT>' ) <EOL> @ memoized_method <EOL> def get_source_roots ( self ) : <EOL> return SourceRoots ( self ) <EOL> def create_trie ( self ) : <EOL> """<STR_LIT>""" <EOL> options = self . get_options ( ) <EOL> trie = SourceRootTrie ( options . lang_canonicalizations ) <EOL> for pattern in options . source_root_patterns or [ ] : <EOL> trie . add_pattern ( pattern ) <EOL> for pattern in options . test_root_patterns or [ ] : <EOL> trie . add_pattern ( pattern ) <EOL> for path , langs in ( options . source_roots or { } ) . items ( ) : <EOL> trie . add_fixed ( path , langs ) <EOL> for path , langs in ( options . test_roots or { } ) . items ( ) : <EOL> trie . add_fixed ( path , langs ) <EOL> return trie <EOL> class SourceRootTrie ( object ) : <EOL> """<STR_LIT>""" <EOL> class Node ( object ) : <EOL> def __init__ ( self ) : <EOL> self . children = { } <EOL> self . langs = tuple ( ) <EOL> self . is_terminal = False <EOL> def get_child ( self , key , langs ) : <EOL> """<STR_LIT>""" <EOL> ret = self . children . get ( key ) <EOL> if ret : <EOL> langs . update ( ret . langs ) <EOL> else : <EOL> ret = self . children . get ( '<STR_LIT:*>' ) <EOL> if ret : <EOL> langs . add ( key ) <EOL> return ret <EOL> def new_child ( self , key ) : <EOL> child = SourceRootTrie . Node ( ) <EOL> self . children [ key ] = child <EOL> return child <EOL> def __init__ ( self , lang_canonicalizations ) : <EOL> self . _lang_canonicalizations = lang_canonicalizations <EOL> self . _root = SourceRootTrie . Node ( ) <EOL> def add_pattern ( self , pattern ) : <EOL> """<STR_LIT>""" <EOL> self . _do_add_pattern ( pattern , tuple ( ) ) <EOL> def add_fixed ( self , path , langs = None ) : <EOL> """<STR_LIT>""" <EOL> self . _do_add_pattern ( os . path . join ( '<STR_LIT>' , path ) , tuple ( langs ) ) <EOL> def _do_add_pattern ( self , pattern , langs ) : <EOL> keys = pattern . split ( os . path . sep ) <EOL> node = self . _root <EOL> for key in keys : <EOL> child = node . children . get ( key ) <EOL> if not child : <EOL> child = node . new_child ( key ) <EOL> node = child <EOL> node . langs = langs <EOL> node . is_terminal = True <EOL> def _canonicalize_langs ( self , langs ) : <EOL> ret = [ ] <EOL> for lang in langs or [ ] : <EOL> canonicalized = self . _lang_canonicalizations . get ( lang ) <EOL> if canonicalized : <EOL> ret . extend ( canonicalized ) <EOL> else : <EOL> ret . append ( lang ) <EOL> return tuple ( ret ) <EOL> def find ( self , path ) : <EOL> """<STR_LIT>""" <EOL> keys = [ '<STR_LIT>' ] + path . split ( os . path . sep ) <EOL> for i in range ( len ( keys ) ) : <EOL> node = self . _root <EOL> langs = set ( ) <EOL> j = i <EOL> while j < len ( keys ) : <EOL> child = node . get_child ( keys [ j ] , langs ) <EOL> if child is None : <EOL> break <EOL> else : <EOL> node = child <EOL> j += <NUM_LIT:1> <EOL> if node . is_terminal : <EOL> return SourceRoot ( os . path . join ( * keys [ <NUM_LIT:1> : j ] ) , self . _canonicalize_langs ( langs ) ) <EOL> return None </s>
