<s> """<STR_LIT>""" <EOL> import abc <EOL> import locale <EOL> import os <EOL> import ntpath <EOL> import posixpath <EOL> import operator <EOL> import difflib <EOL> import qisys . error <EOL> import qisys . project <EOL> import qisys . command <EOL> import qisys . sh <EOL> import qisys . qixml <EOL> from qisys import ui <EOL> import qibuild . config <EOL> class WorkTree ( object ) : <EOL> """<STR_LIT>""" <EOL> def __init__ ( self , root , sanity_check = True ) : <EOL> """<STR_LIT>""" <EOL> if not os . path . exists ( root ) : <EOL> raise qisys . error . Error ( """<STR_LIT>""" . format ( root ) ) <EOL> self . _observers = list ( ) <EOL> self . root = root <EOL> self . cache = self . load_cache ( ) <EOL> self . projects = list ( ) <EOL> self . load_projects ( ) <EOL> if sanity_check : <EOL> self . check ( ) <EOL> self . register_self ( ) <EOL> def register_self ( self ) : <EOL> """<STR_LIT>""" <EOL> qibuild_cfg = qibuild . config . QiBuildConfig ( ) <EOL> to_read = qibuild . config . get_global_cfg_path ( ) <EOL> qibuild_cfg . read ( to_read , create_if_missing = True ) <EOL> encoding = locale . getpreferredencoding ( ) <EOL> as_unicode = self . root . decode ( encoding ) <EOL> qibuild_cfg . add_worktree ( as_unicode ) <EOL> qibuild_cfg . write ( ) <EOL> def register ( self , observer ) : <EOL> """<STR_LIT>""" <EOL> self . _observers . append ( observer ) <EOL> def load_cache ( self ) : <EOL> """<STR_LIT>""" <EOL> self . projects = list ( ) <EOL> if not os . path . exists ( self . worktree_xml ) : <EOL> qisys . sh . mkdir ( self . dot_qi ) <EOL> with open ( self . worktree_xml , "<STR_LIT:w>" ) as fp : <EOL> fp . write ( "<STR_LIT>" ) <EOL> cache = WorkTreeCache ( self . worktree_xml ) <EOL> for src in cache . get_srcs ( ) : <EOL> if not os . path . exists ( os . path . join ( self . root , src ) ) : <EOL> cache . remove_src ( src ) <EOL> return cache <EOL> def reload ( self ) : <EOL> """<STR_LIT>""" <EOL> self . cache = self . load_cache ( ) <EOL> self . load_projects ( ) <EOL> for observer in self . _observers : <EOL> observer . reload ( ) <EOL> def check ( self ) : <EOL> """<STR_LIT>""" <EOL> parent_worktree = guess_worktree ( os . path . join ( self . root , "<STR_LIT:..>" ) ) <EOL> if parent_worktree and parent_worktree != self . root : <EOL> ui . warning ( """<STR_LIT>""" . format ( self . root , parent_worktree ) ) <EOL> @ property <EOL> def dot_qi ( self ) : <EOL> """<STR_LIT>""" <EOL> res = os . path . join ( self . root , "<STR_LIT>" ) <EOL> qisys . sh . mkdir ( res ) <EOL> return res <EOL> @ property <EOL> def worktree_xml ( self ) : <EOL> """<STR_LIT>""" <EOL> worktree_xml = os . path . join ( self . dot_qi , "<STR_LIT>" ) <EOL> if not os . path . exists ( worktree_xml ) : <EOL> with open ( worktree_xml , "<STR_LIT:w>" ) as fp : <EOL> fp . write ( "<STR_LIT>" ) <EOL> return worktree_xml <EOL> def has_project ( self , path ) : <EOL> src = self . normalize_path ( path ) <EOL> srcs = ( p . src for p in self . projects ) <EOL> return src in srcs <EOL> def load_projects ( self ) : <EOL> """<STR_LIT>""" <EOL> self . projects = list ( ) <EOL> srcs = self . cache . get_srcs ( ) <EOL> for src in srcs : <EOL> project = qisys . project . WorkTreeProject ( self , src ) <EOL> project . parse_qiproject_xml ( ) <EOL> self . projects . append ( project ) <EOL> res = set ( self . projects ) <EOL> for project in self . projects : <EOL> self . _rec_parse_sub_projects ( project , res ) <EOL> self . projects = sorted ( res , key = operator . attrgetter ( "<STR_LIT:src>" ) ) <EOL> def _rec_parse_sub_projects ( self , project , res ) : <EOL> """<STR_LIT>""" <EOL> for sub_project_src in project . subprojects : <EOL> src = os . path . join ( project . src , sub_project_src ) <EOL> src = qisys . sh . to_posix_path ( src ) <EOL> sub_project = qisys . project . WorkTreeProject ( self , src ) <EOL> sub_project . parse_qiproject_xml ( ) <EOL> res . add ( sub_project ) <EOL> self . _rec_parse_sub_projects ( sub_project , res ) <EOL> def get_project ( self , src , raises = False ) : <EOL> """<STR_LIT>""" <EOL> src = self . normalize_path ( src ) <EOL> if not self . has_project ( src ) : <EOL> if not raises : <EOL> return None <EOL> mess = ui . did_you_mean ( "<STR_LIT>" % src , <EOL> src , [ x . src for x in self . projects ] ) <EOL> raise WorkTreeError ( mess ) <EOL> match = ( p for p in self . projects if p . src == src ) <EOL> return match . next ( ) <EOL> def add_project ( self , path ) : <EOL> """<STR_LIT>""" <EOL> src = self . normalize_path ( path ) <EOL> if self . has_project ( src ) : <EOL> mess = "<STR_LIT>" <EOL> mess += "<STR_LIT>" % src <EOL> mess += "<STR_LIT>" % self . root <EOL> raise WorkTreeError ( mess ) <EOL> self . cache . add_src ( src ) <EOL> self . load_projects ( ) <EOL> project = self . get_project ( src ) <EOL> for observer in self . _observers : <EOL> observer . reload ( ) <EOL> return project <EOL> def remove_project ( self , path , from_disk = False ) : <EOL> """<STR_LIT>""" <EOL> src = self . normalize_path ( path ) <EOL> if not self . has_project ( src ) : <EOL> raise WorkTreeError ( "<STR_LIT>" % src ) <EOL> project = self . get_project ( src ) <EOL> if from_disk : <EOL> qisys . sh . rm ( project . path ) <EOL> self . cache . remove_src ( src ) <EOL> self . load_projects ( ) <EOL> for observer in self . _observers : <EOL> observer . reload ( ) <EOL> def move_project ( self , path , new_path ) : <EOL> """<STR_LIT>""" <EOL> src = self . normalize_path ( path ) <EOL> new_src = self . normalize_path ( new_path ) <EOL> if not self . has_project ( src ) : <EOL> raise WorkTreeError ( "<STR_LIT>" % src ) <EOL> if self . has_project ( new_src ) : <EOL> mess = "<STR_LIT>" <EOL> mess += "<STR_LIT>" % src <EOL> mess += "<STR_LIT>" % self . root <EOL> self . cache . remove_src ( src ) <EOL> self . cache . add_src ( new_src ) <EOL> self . load_projects ( ) <EOL> project = self . get_project ( src ) <EOL> for observer in self . _observers : <EOL> observer . reload ( ) <EOL> def normalize_path ( self , path ) : <EOL> """<STR_LIT>""" <EOL> if os . path . isabs ( path ) : <EOL> path = os . path . relpath ( path , start = self . root ) <EOL> path = path . replace ( ntpath . sep , posixpath . sep ) <EOL> if os . name == '<STR_LIT>' : <EOL> path = path . lower ( ) <EOL> return path <EOL> def __repr__ ( self ) : <EOL> res = "<STR_LIT>" % self . root <EOL> res += repr_list_projects ( self . projects ) <EOL> res += "<STR_LIT>" <EOL> return res <EOL> def repr_list_projects ( projects , name = "<STR_LIT>" ) : <EOL> res = "<STR_LIT>" <EOL> if projects : <EOL> res += name <EOL> for i , project in enumerate ( projects ) : <EOL> res += "<STR_LIT>" % ( i , project . src ) <EOL> res += "<STR_LIT:\n>" <EOL> return res <EOL> def is_worktree ( path ) : <EOL> path = os . path . join ( path , "<STR_LIT>" ) <EOL> return os . path . isdir ( path ) <EOL> def guess_worktree ( cwd = None , raises = False ) : <EOL> """<STR_LIT>""" <EOL> if cwd is None : <EOL> try : <EOL> cwd = os . getcwd ( ) <EOL> except OSError as e : <EOL> raise qisys . error . Error ( "<STR_LIT>" ) <EOL> cwd = qisys . sh . to_native_path ( cwd ) <EOL> head = cwd <EOL> _tail = True <EOL> while _tail : <EOL> if is_worktree ( head ) : <EOL> return head <EOL> ( head , _tail ) = os . path . split ( head ) <EOL> if raises : <EOL> raise NotInWorkTree ( ) <EOL> else : <EOL> return None <EOL> class WorkTreeObserver ( object ) : <EOL> """<STR_LIT>""" <EOL> __metaclass__ = abc . ABCMeta <EOL> @ abc . abstractmethod <EOL> def reload ( self ) : <EOL> pass <EOL> class WorkTreeCache ( object ) : <EOL> """<STR_LIT>""" <EOL> def __init__ ( self , xml_path ) : <EOL> self . xml_path = xml_path <EOL> self . xml_root = qisys . qixml . read ( xml_path ) . getroot ( ) <EOL> def add_src ( self , src ) : <EOL> """<STR_LIT>""" <EOL> project_elem = qisys . qixml . etree . Element ( "<STR_LIT>" ) <EOL> project_elem . set ( "<STR_LIT:src>" , src ) <EOL> self . xml_root . append ( project_elem ) <EOL> qisys . qixml . write ( self . xml_root , self . xml_path ) <EOL> def remove_src ( self , src ) : <EOL> """<STR_LIT>""" <EOL> projects_elem = self . xml_root . findall ( "<STR_LIT>" ) <EOL> for project_elem in projects_elem : <EOL> if project_elem . get ( "<STR_LIT:src>" ) == src : <EOL> self . xml_root . remove ( project_elem ) <EOL> qisys . qixml . write ( self . xml_root , self . xml_path ) <EOL> def get_srcs ( self ) : <EOL> """<STR_LIT>""" <EOL> srcs = list ( ) <EOL> projects_elem = self . xml_root . findall ( "<STR_LIT>" ) <EOL> for project_elem in projects_elem : <EOL> srcs . append ( qisys . qixml . parse_required_attr ( project_elem , "<STR_LIT:src>" ) ) <EOL> return srcs <EOL> class WorkTreeError ( qisys . error . Error ) : <EOL> """<STR_LIT>""" <EOL> class NotInWorkTree ( qisys . error . Error ) : <EOL> """<STR_LIT>""" <EOL> def __str__ ( self ) : <EOL> return """<STR_LIT>""" <EOL> class NoSuchProject ( qisys . error . Error ) : <EOL> def __init__ ( self , name , message ) : <EOL> self . name = name <EOL> self . message = message <EOL> def __str__ ( self ) : <EOL> return self . message </s>
