<s> import datetime <EOL> import os <EOL> import re <EOL> import subprocess <EOL> from gitgoggles . progress import log <EOL> from gitgoggles . utils import AccumulatorDict , memoize , force_unicode , force_str , console <EOL> def log_activity ( func ) : <EOL> def _ ( self , * args , ** kwargs ) : <EOL> log . info ( '<STR_LIT>' % self . name ) <EOL> return func ( self , * args , ** kwargs ) <EOL> return _ <EOL> class Ref ( object ) : <EOL> def __new__ ( cls , repo , sha , refspec ) : <EOL> if cls != Ref : <EOL> return object . __new__ ( cls ) <EOL> ref_type , name = refspec [ <NUM_LIT:5> : ] . partition ( "<STR_LIT:/>" ) [ <NUM_LIT:0> : : <NUM_LIT:2> ] <EOL> if ref_type in ( '<STR_LIT>' , '<STR_LIT>' , ) : <EOL> return Branch ( repo , sha , refspec ) <EOL> elif ref_type in ( '<STR_LIT>' , ) : <EOL> return Tag ( repo , sha , refspec ) <EOL> return object . __new__ ( cls ) <EOL> def __init__ ( self , repo , sha , refspec ) : <EOL> self . repo = repo <EOL> self . refspec = refspec <EOL> self . sha = sha <EOL> self . ref_type , self . name = refspec [ <NUM_LIT:5> : ] . partition ( "<STR_LIT:/>" ) [ <NUM_LIT:0> : : <NUM_LIT:2> ] <EOL> self . shortname = re . match ( '<STR_LIT>' , self . name ) and self . name . partition ( "<STR_LIT:/>" ) [ <NUM_LIT:2> ] or self . name <EOL> def modified ( self ) : <EOL> try : <EOL> timestamp = float ( self . repo . shell ( '<STR_LIT>' , '<STR_LIT>' , '<STR_LIT>' , '<STR_LIT>' , '<STR_LIT>' , '<STR_LIT>' % ( self . repo . master , self . refspec ) ) . split [ <NUM_LIT:0> ] . strip ( ) ) <EOL> except IndexError : <EOL> timestamp = float ( self . repo . shell ( '<STR_LIT>' , '<STR_LIT>' , '<STR_LIT>' , '<STR_LIT>' , '<STR_LIT>' , self . refspec ) . split [ <NUM_LIT:0> ] . strip ( ) ) <EOL> return datetime . datetime . fromtimestamp ( timestamp ) <EOL> modified = property ( log_activity ( memoize ( modified ) ) ) <EOL> def timedelta ( self ) : <EOL> delta = datetime . datetime . now ( ) - self . modified <EOL> if delta . days > <NUM_LIT> : <EOL> return '<STR_LIT>' % round ( delta . days / <NUM_LIT> , <NUM_LIT:1> ) <EOL> elif delta . days >= <NUM_LIT:1> : <EOL> return '<STR_LIT>' % delta . days <EOL> elif delta . seconds >= <NUM_LIT> : <EOL> return '<STR_LIT>' % ( delta . seconds / <NUM_LIT> ) <EOL> else : <EOL> return '<STR_LIT>' % ( delta . seconds / <NUM_LIT> ) <EOL> timedelta = property ( timedelta ) <EOL> def __unicode__ ( self ) : <EOL> return '<STR_LIT>' % ( self . __class__ . __name__ , self . name ) <EOL> def __str__ ( self ) : <EOL> return self . __unicode__ ( ) <EOL> def __repr__ ( self ) : <EOL> return self . __unicode__ ( ) <EOL> class Branch ( Ref ) : <EOL> display_name = '<STR_LIT>' <EOL> def __new__ ( cls , repo , sha , refspec ) : <EOL> if cls != Branch : <EOL> return object . __new__ ( cls ) <EOL> if refspec . startswith ( '<STR_LIT>' ) : <EOL> remote = repo . configs . get ( '<STR_LIT>' % '<STR_LIT:/>' . join ( refspec . split ( '<STR_LIT:/>' ) [ <NUM_LIT:2> : ] ) , '<STR_LIT:.>' ) <EOL> remote = remote != '<STR_LIT:.>' and remote or None <EOL> if remote is None : <EOL> cls = LocalBranch <EOL> else : <EOL> cls = TrackingBranch <EOL> else : <EOL> if refspec in repo . branch_parents . keys ( ) : <EOL> cls = TrackedBranch <EOL> else : <EOL> cls = PublishedBranch <EOL> return object . __new__ ( cls ) <EOL> def __init__ ( self , * args , ** kwargs ) : <EOL> super ( Branch , self ) . __init__ ( * args , ** kwargs ) <EOL> self . parent_refspec = self . repo . branch_parents . get ( self . refspec , self . refspec ) <EOL> log . info ( '<STR_LIT>' % self . name ) <EOL> self . merge_refspec = None <EOL> if self . repo . master_sha : <EOL> merge_refspec = self . repo . shell ( '<STR_LIT>' , '<STR_LIT>' , self . repo . master_sha , self . sha ) . split <EOL> if merge_refspec : <EOL> self . merge_refspec = merge_refspec [ <NUM_LIT:0> ] . strip ( ) <EOL> def pull ( self ) : <EOL> return bool ( self . repo . shell ( '<STR_LIT>' , '<STR_LIT>' , '<STR_LIT>' , '<STR_LIT>' % ( self . refspec , self . parent_refspec ) ) . split ) <EOL> pull = property ( log_activity ( memoize ( pull ) ) ) <EOL> def push ( self ) : <EOL> return bool ( self . repo . shell ( '<STR_LIT>' , '<STR_LIT>' , '<STR_LIT>' , '<STR_LIT>' % ( self . parent_refspec , self . refspec ) ) . split ) <EOL> push = property ( log_activity ( memoize ( push ) ) ) <EOL> def ahead ( self ) : <EOL> if self . merge_refspec : <EOL> return len ( self . repo . shell ( '<STR_LIT>' , '<STR_LIT>' , '<STR_LIT>' , '<STR_LIT>' , '<STR_LIT>' % ( self . repo . master , self . refspec ) ) . split ) <EOL> return None <EOL> ahead = property ( log_activity ( memoize ( ahead ) ) ) <EOL> def behind ( self ) : <EOL> if self . merge_refspec : <EOL> return len ( self . repo . shell ( '<STR_LIT>' , '<STR_LIT>' , '<STR_LIT>' , '<STR_LIT>' , '<STR_LIT>' % ( self . refspec , self . repo . master ) ) . split ) <EOL> return None <EOL> behind = property ( log_activity ( memoize ( behind ) ) ) <EOL> @ property <EOL> def tracking ( self ) : <EOL> return None <EOL> class LocalBranch ( Branch ) : <EOL> """<STR_LIT>""" <EOL> display_name = '<STR_LIT>' <EOL> def push ( self ) : <EOL> return False <EOL> push = property ( push ) <EOL> def pull ( self ) : <EOL> return False <EOL> pull = property ( pull ) <EOL> class PublishedBranch ( Branch ) : <EOL> """<STR_LIT>""" <EOL> display_name = '<STR_LIT>' <EOL> class TrackingBranch ( PublishedBranch ) : <EOL> """<STR_LIT>""" <EOL> display_name = '<STR_LIT>' <EOL> @ property <EOL> def tracking ( self ) : <EOL> return True <EOL> class TrackedBranch ( PublishedBranch ) : <EOL> """<STR_LIT>""" <EOL> display_name = '<STR_LIT>' <EOL> @ property <EOL> def tracking ( self ) : <EOL> return True <EOL> class Tag ( Ref ) : <EOL> pass <EOL> class Repository ( object ) : <EOL> def __init__ ( self , path = None ) : <EOL> self . path = os . path . abspath ( path or os . path . curdir ) <EOL> try : <EOL> self . master = '<STR_LIT>' <EOL> master_sha = self . shell ( '<STR_LIT>' , '<STR_LIT>' , '<STR_LIT>' , '<STR_LIT>' , self . master , exceptions = True ) . split <EOL> except : <EOL> self . master = '<STR_LIT>' <EOL> master_sha = self . shell ( '<STR_LIT>' , '<STR_LIT>' , '<STR_LIT>' , '<STR_LIT>' , self . master ) . split <EOL> self . master_sha = master_sha and master_sha [ <NUM_LIT:0> ] . strip ( ) or '<STR_LIT>' <EOL> def shell ( self , * args , ** kwargs ) : <EOL> exceptions = kwargs . pop ( '<STR_LIT>' , False ) <EOL> join = kwargs . pop ( '<STR_LIT>' , False ) <EOL> if kwargs : <EOL> raise Exception ( '<STR_LIT>' ) <EOL> log . debug ( '<STR_LIT:U+0020>' . join ( args ) ) <EOL> if join : <EOL> process = subprocess . Popen ( args , cwd = self . path ) <EOL> process . communicate ( ) <EOL> else : <EOL> process = subprocess . Popen ( args , stdout = subprocess . PIPE , stderr = subprocess . STDOUT , cwd = self . path ) <EOL> stdout , stderr = process . communicate ( ) <EOL> process . stdout = stdout and force_unicode ( stdout . strip ( ) ) or u'<STR_LIT>' <EOL> process . stderr = stderr and force_unicode ( stderr . strip ( ) ) or u'<STR_LIT>' <EOL> process . split = filter ( lambda x : x , map ( lambda x : x . strip ( ) , process . stdout . split ( u'<STR_LIT:\n>' ) ) ) <EOL> if process . returncode != <NUM_LIT:0> : <EOL> message = '<STR_LIT>' % ( process . returncode , process . stderr , process . stdout ) <EOL> log . debug ( message ) <EOL> if exceptions : <EOL> raise Exception ( message ) <EOL> return process <EOL> def status ( self ) : <EOL> UNCOMMITTED_RE = re . compile ( r'<STR_LIT>' ) <EOL> CHANGED_RE = re . compile ( r'<STR_LIT>' ) <EOL> UNTRACKED_RE = re . compile ( r'<STR_LIT>' ) <EOL> uncommitted , changed , untracked , stashed = [ ] , [ ] , [ ] , [ ] <EOL> for entry in self . shell ( '<STR_LIT>' , '<STR_LIT:status>' , '<STR_LIT>' ) . split : <EOL> filename = entry [ <NUM_LIT:3> : ] <EOL> if UNCOMMITTED_RE . match ( entry ) : <EOL> uncommitted . append ( filename ) <EOL> elif CHANGED_RE . match ( entry ) : <EOL> changed . append ( filename ) <EOL> elif UNTRACKED_RE . match ( entry ) : <EOL> untracked . append ( filename ) <EOL> stashed = [ x for x in self . shell ( '<STR_LIT>' , '<STR_LIT>' , '<STR_LIT:list>' ) . split if x ] <EOL> return uncommitted , changed , untracked , stashed <EOL> def configs ( self ) : <EOL> return dict ( [ x . partition ( '<STR_LIT:=>' ) [ <NUM_LIT:0> : : <NUM_LIT:2> ] for x in self . shell ( '<STR_LIT>' , '<STR_LIT>' , '<STR_LIT>' ) . split ] ) <EOL> configs = property ( memoize ( configs ) ) <EOL> def fetch ( self ) : <EOL> log . info ( '<STR_LIT>' ) <EOL> self . shell ( '<STR_LIT>' , '<STR_LIT>' , '<STR_LIT>' , '<STR_LIT>' ) <EOL> def remotes ( self ) : <EOL> log . info ( '<STR_LIT>' ) <EOL> return self . shell ( '<STR_LIT>' , '<STR_LIT>' ) . split <EOL> remotes = memoize ( remotes ) <EOL> def refs ( self ) : <EOL> return [ Ref ( self , * x . split ( ) ) for x in self . shell ( '<STR_LIT>' , '<STR_LIT>' ) . split ] <EOL> refs = memoize ( refs ) <EOL> def branches ( self , * types ) : <EOL> if types : <EOL> return [ x for x in self . refs ( ) if x . __class__ in types ] <EOL> else : <EOL> return [ x for x in self . refs ( ) if isinstance ( x , Branch ) ] <EOL> branches = memoize ( branches ) <EOL> def tags ( self ) : <EOL> return [ x for x in self . refs ( ) if isinstance ( x , Tag ) ] <EOL> tags = memoize ( tags ) <EOL> def branch ( self ) : <EOL> try : <EOL> return '<STR_LIT:/>' . join ( self . shell ( '<STR_LIT>' , '<STR_LIT>' , '<STR_LIT>' ) . stdout . split ( '<STR_LIT:/>' ) [ <NUM_LIT:2> : ] ) <EOL> except : <EOL> return self . shell ( '<STR_LIT>' , '<STR_LIT>' , '<STR_LIT>' , '<STR_LIT>' ) . stdout <EOL> def branch_parents ( self ) : <EOL> parents = { } <EOL> for branch_refspec in [ x . split ( ) [ <NUM_LIT:1> ] for x in self . shell ( '<STR_LIT>' , '<STR_LIT>' , '<STR_LIT>' ) . split ] : <EOL> branch_name = '<STR_LIT:/>' . join ( branch_refspec . split ( '<STR_LIT:/>' ) [ <NUM_LIT:2> : ] ) <EOL> remote = self . configs . get ( '<STR_LIT>' % branch_name , '<STR_LIT:.>' ) <EOL> parent = self . configs . get ( '<STR_LIT>' % branch_name , '<STR_LIT>' ) <EOL> if remote != '<STR_LIT:.>' and parent : <EOL> parent = '<STR_LIT>' % ( remote , '<STR_LIT:/>' . join ( parent . split ( '<STR_LIT:/>' ) [ <NUM_LIT:2> : ] ) ) <EOL> parents [ branch_refspec ] = parent <EOL> parents [ parent ] = branch_refspec <EOL> else : <EOL> parents [ branch_refspec ] = parent <EOL> return parents <EOL> branch_parents = property ( memoize ( branch_parents ) ) </s>
