<s> """<STR_LIT>""" <EOL> __docformat__ = '<STR_LIT>' <EOL> import select <EOL> import socket <EOL> import subprocess <EOL> import urlparse <EOL> from lib . dulwich . errors import ( <EOL> SendPackError , <EOL> UpdateRefsError , <EOL> ) <EOL> from lib . dulwich . protocol import ( <EOL> Protocol , <EOL> TCP_GIT_PORT , <EOL> ZERO_SHA , <EOL> extract_capabilities , <EOL> ) <EOL> from lib . dulwich . pack import ( <EOL> write_pack_data , <EOL> ) <EOL> def _fileno_can_read ( fileno ) : <EOL> """<STR_LIT>""" <EOL> return len ( select . select ( [ fileno ] , [ ] , [ ] , <NUM_LIT:0> ) [ <NUM_LIT:0> ] ) > <NUM_LIT:0> <EOL> COMMON_CAPABILITIES = [ "<STR_LIT>" ] <EOL> FETCH_CAPABILITIES = [ "<STR_LIT>" , "<STR_LIT>" ] + COMMON_CAPABILITIES <EOL> SEND_CAPABILITIES = [ '<STR_LIT>' ] + COMMON_CAPABILITIES <EOL> class GitClient ( object ) : <EOL> """<STR_LIT>""" <EOL> def __init__ ( self , thin_packs = True , report_activity = None ) : <EOL> """<STR_LIT>""" <EOL> self . _report_activity = report_activity <EOL> self . _fetch_capabilities = list ( FETCH_CAPABILITIES ) <EOL> self . _send_capabilities = list ( SEND_CAPABILITIES ) <EOL> if thin_packs : <EOL> self . _fetch_capabilities . append ( "<STR_LIT>" ) <EOL> def _connect ( self , cmd , path ) : <EOL> """<STR_LIT>""" <EOL> raise NotImplementedError ( ) <EOL> def read_refs ( self , proto ) : <EOL> server_capabilities = None <EOL> refs = { } <EOL> for pkt in proto . read_pkt_seq ( ) : <EOL> ( sha , ref ) = pkt . rstrip ( "<STR_LIT:\n>" ) . split ( "<STR_LIT:U+0020>" , <NUM_LIT:1> ) <EOL> if server_capabilities is None : <EOL> ( ref , server_capabilities ) = extract_capabilities ( ref ) <EOL> refs [ ref ] = sha <EOL> return refs , server_capabilities <EOL> def _parse_status_report ( self , proto ) : <EOL> unpack = proto . read_pkt_line ( ) . strip ( ) <EOL> if unpack != '<STR_LIT>' : <EOL> st = True <EOL> while st is not None : <EOL> st = proto . read_pkt_line ( ) <EOL> raise SendPackError ( unpack ) <EOL> statuses = [ ] <EOL> errs = False <EOL> ref_status = proto . read_pkt_line ( ) <EOL> while ref_status : <EOL> ref_status = ref_status . strip ( ) <EOL> statuses . append ( ref_status ) <EOL> if not ref_status . startswith ( '<STR_LIT>' ) : <EOL> errs = True <EOL> ref_status = proto . read_pkt_line ( ) <EOL> if errs : <EOL> ref_status = { } <EOL> ok = set ( ) <EOL> for status in statuses : <EOL> if '<STR_LIT:U+0020>' not in status : <EOL> continue <EOL> status , ref = status . split ( '<STR_LIT:U+0020>' , <NUM_LIT:1> ) <EOL> if status == '<STR_LIT>' : <EOL> if '<STR_LIT:U+0020>' in ref : <EOL> ref , status = ref . split ( '<STR_LIT:U+0020>' , <NUM_LIT:1> ) <EOL> else : <EOL> ok . add ( ref ) <EOL> ref_status [ ref ] = status <EOL> raise UpdateRefsError ( '<STR_LIT>' % <EOL> '<STR_LIT:U+002CU+0020>' . join ( [ ref for ref in ref_status <EOL> if ref not in ok ] ) , <EOL> ref_status = ref_status ) <EOL> def send_pack ( self , path , determine_wants , generate_pack_contents ) : <EOL> """<STR_LIT>""" <EOL> proto , unused_can_read = self . _connect ( '<STR_LIT>' , path ) <EOL> old_refs , server_capabilities = self . read_refs ( proto ) <EOL> if '<STR_LIT>' not in server_capabilities : <EOL> self . _send_capabilities . remove ( '<STR_LIT>' ) <EOL> new_refs = determine_wants ( old_refs ) <EOL> if not new_refs : <EOL> proto . write_pkt_line ( None ) <EOL> return { } <EOL> want = [ ] <EOL> have = [ x for x in old_refs . values ( ) if not x == ZERO_SHA ] <EOL> sent_capabilities = False <EOL> for refname in set ( new_refs . keys ( ) + old_refs . keys ( ) ) : <EOL> old_sha1 = old_refs . get ( refname , ZERO_SHA ) <EOL> new_sha1 = new_refs . get ( refname , ZERO_SHA ) <EOL> if old_sha1 != new_sha1 : <EOL> if sent_capabilities : <EOL> proto . write_pkt_line ( "<STR_LIT>" % ( old_sha1 , new_sha1 , <EOL> refname ) ) <EOL> else : <EOL> proto . write_pkt_line ( <EOL> "<STR_LIT>" % ( old_sha1 , new_sha1 , refname , <EOL> '<STR_LIT:U+0020>' . join ( self . _send_capabilities ) ) ) <EOL> sent_capabilities = True <EOL> if new_sha1 not in have and new_sha1 != ZERO_SHA : <EOL> want . append ( new_sha1 ) <EOL> proto . write_pkt_line ( None ) <EOL> if not want : <EOL> return new_refs <EOL> objects = generate_pack_contents ( have , want ) <EOL> entries , sha = write_pack_data ( proto . write_file ( ) , objects , <EOL> len ( objects ) ) <EOL> if '<STR_LIT>' in self . _send_capabilities : <EOL> self . _parse_status_report ( proto ) <EOL> data = proto . read ( ) <EOL> if data : <EOL> raise SendPackError ( '<STR_LIT>' % data ) <EOL> return new_refs <EOL> def fetch ( self , path , target , determine_wants = None , progress = None ) : <EOL> """<STR_LIT>""" <EOL> if determine_wants is None : <EOL> determine_wants = target . object_store . determine_wants_all <EOL> f , commit = target . object_store . add_pack ( ) <EOL> try : <EOL> return self . fetch_pack ( path , determine_wants , <EOL> target . get_graph_walker ( ) , f . write , progress ) <EOL> finally : <EOL> commit ( ) <EOL> def fetch_pack ( self , path , determine_wants , graph_walker , pack_data , <EOL> progress ) : <EOL> """<STR_LIT>""" <EOL> proto , can_read = self . _connect ( '<STR_LIT>' , path ) <EOL> ( refs , server_capabilities ) = self . read_refs ( proto ) <EOL> wants = determine_wants ( refs ) <EOL> if not wants : <EOL> proto . write_pkt_line ( None ) <EOL> return refs <EOL> assert isinstance ( wants , list ) and type ( wants [ <NUM_LIT:0> ] ) == str <EOL> proto . write_pkt_line ( "<STR_LIT>" % ( <EOL> wants [ <NUM_LIT:0> ] , '<STR_LIT:U+0020>' . join ( self . _fetch_capabilities ) ) ) <EOL> for want in wants [ <NUM_LIT:1> : ] : <EOL> proto . write_pkt_line ( "<STR_LIT>" % want ) <EOL> proto . write_pkt_line ( None ) <EOL> have = graph_walker . next ( ) <EOL> while have : <EOL> proto . write_pkt_line ( "<STR_LIT>" % have ) <EOL> if can_read ( ) : <EOL> pkt = proto . read_pkt_line ( ) <EOL> parts = pkt . rstrip ( "<STR_LIT:\n>" ) . split ( "<STR_LIT:U+0020>" ) <EOL> if parts [ <NUM_LIT:0> ] == "<STR_LIT>" : <EOL> graph_walker . ack ( parts [ <NUM_LIT:1> ] ) <EOL> assert parts [ <NUM_LIT:2> ] == "<STR_LIT>" <EOL> have = graph_walker . next ( ) <EOL> proto . write_pkt_line ( "<STR_LIT>" ) <EOL> pkt = proto . read_pkt_line ( ) <EOL> while pkt : <EOL> parts = pkt . rstrip ( "<STR_LIT:\n>" ) . split ( "<STR_LIT:U+0020>" ) <EOL> if parts [ <NUM_LIT:0> ] == "<STR_LIT>" : <EOL> graph_walker . ack ( pkt . split ( "<STR_LIT:U+0020>" ) [ <NUM_LIT:1> ] ) <EOL> if len ( parts ) < <NUM_LIT:3> or parts [ <NUM_LIT:2> ] != "<STR_LIT>" : <EOL> break <EOL> pkt = proto . read_pkt_line ( ) <EOL> for pkt in proto . read_pkt_seq ( ) : <EOL> channel = ord ( pkt [ <NUM_LIT:0> ] ) <EOL> pkt = pkt [ <NUM_LIT:1> : ] <EOL> if channel == <NUM_LIT:1> : <EOL> pack_data ( pkt ) <EOL> elif channel == <NUM_LIT:2> : <EOL> if progress is not None : <EOL> progress ( pkt ) <EOL> else : <EOL> raise AssertionError ( "<STR_LIT>" % channel ) <EOL> return refs <EOL> class TCPGitClient ( GitClient ) : <EOL> """<STR_LIT>""" <EOL> def __init__ ( self , host , port = None , * args , ** kwargs ) : <EOL> if port is None : <EOL> port = TCP_GIT_PORT <EOL> self . _host = host <EOL> self . _port = port <EOL> GitClient . __init__ ( self , * args , ** kwargs ) <EOL> def _connect ( self , cmd , path ) : <EOL> s = socket . socket ( type = socket . SOCK_STREAM ) <EOL> s . connect ( ( self . _host , self . _port ) ) <EOL> rfile = s . makefile ( '<STR_LIT:rb>' , - <NUM_LIT:1> ) <EOL> wfile = s . makefile ( '<STR_LIT:wb>' , <NUM_LIT:0> ) <EOL> proto = Protocol ( rfile . read , wfile . write , <EOL> report_activity = self . _report_activity ) <EOL> proto . send_cmd ( '<STR_LIT>' % cmd , path , '<STR_LIT>' % self . _host ) <EOL> return proto , lambda : _fileno_can_read ( s ) <EOL> class SubprocessWrapper ( object ) : <EOL> """<STR_LIT>""" <EOL> def __init__ ( self , proc ) : <EOL> self . proc = proc <EOL> self . read = proc . stdout . read <EOL> self . write = proc . stdin . write <EOL> def can_read ( self ) : <EOL> return _fileno_can_read ( self . proc . stdout . fileno ( ) ) <EOL> def close ( self ) : <EOL> self . proc . stdin . close ( ) <EOL> self . proc . stdout . close ( ) <EOL> self . proc . wait ( ) <EOL> class SubprocessGitClient ( GitClient ) : <EOL> """<STR_LIT>""" <EOL> def __init__ ( self , * args , ** kwargs ) : <EOL> self . _connection = None <EOL> GitClient . __init__ ( self , * args , ** kwargs ) <EOL> def _connect ( self , service , path ) : <EOL> argv = [ '<STR_LIT>' , service , path ] <EOL> p = SubprocessWrapper ( <EOL> subprocess . Popen ( argv , bufsize = <NUM_LIT:0> , stdin = subprocess . PIPE , <EOL> stdout = subprocess . PIPE ) ) <EOL> return Protocol ( p . read , p . write , <EOL> report_activity = self . _report_activity ) , p . can_read <EOL> class SSHVendor ( object ) : <EOL> def connect_ssh ( self , host , command , username = None , port = None ) : <EOL> args = [ '<STR_LIT>' , '<STR_LIT>' ] <EOL> if port is not None : <EOL> args . extend ( [ '<STR_LIT>' , str ( port ) ] ) <EOL> if username is not None : <EOL> host = "<STR_LIT>" % ( username , host ) <EOL> args . append ( host ) <EOL> proc = subprocess . Popen ( args + command , <EOL> stdin = subprocess . PIPE , <EOL> stdout = subprocess . PIPE ) <EOL> return SubprocessWrapper ( proc ) <EOL> get_ssh_vendor = SSHVendor <EOL> class SSHGitClient ( GitClient ) : <EOL> def __init__ ( self , host , port = None , username = None , * args , ** kwargs ) : <EOL> self . host = host <EOL> self . port = port <EOL> self . username = username <EOL> GitClient . __init__ ( self , * args , ** kwargs ) <EOL> self . alternative_paths = { } <EOL> def _get_cmd_path ( self , cmd ) : <EOL> return self . alternative_paths . get ( cmd , '<STR_LIT>' % cmd ) <EOL> def _connect ( self , cmd , path ) : <EOL> con = get_ssh_vendor ( ) . connect_ssh ( <EOL> self . host , [ "<STR_LIT>" % ( self . _get_cmd_path ( cmd ) , path ) ] , <EOL> port = self . port , username = self . username ) <EOL> return Protocol ( con . read , con . write ) , con . can_read <EOL> def get_transport_and_path ( uri ) : <EOL> """<STR_LIT>""" <EOL> parsed = urlparse . urlparse ( uri ) <EOL> if parsed . scheme == '<STR_LIT>' : <EOL> return TCPGitClient ( parsed . hostname , port = parsed . port ) , parsed . path <EOL> elif parsed . scheme == '<STR_LIT>' : <EOL> return SSHGitClient ( parsed . hostname , port = parsed . port , <EOL> username = parsed . username ) , parsed . path <EOL> if parsed . scheme and not parsed . netloc : <EOL> return SSHGitClient ( parsed . scheme ) , parsed . path <EOL> elif parsed . scheme : <EOL> raise ValueError ( '<STR_LIT>' % parsed . scheme ) <EOL> elif '<STR_LIT:@>' in parsed . path and '<STR_LIT::>' in parsed . path : <EOL> user_host , path = parsed . path . split ( '<STR_LIT::>' ) <EOL> user , host = user_host . rsplit ( '<STR_LIT:@>' ) <EOL> return SSHGitClient ( host , username = user ) , path <EOL> return SubprocessGitClient ( ) , uri </s>
