#NEWLINE# def apply( self , strip = 0 , root = None ) : #NEWLINE# #INDENT# ' Apply parsed patch, optionally stripping leading components\n        from file paths. `root` parameter specifies working dir.\n        return True on success\n    ' #NEWLINE# if root : #NEWLINE# #INDENT# prevdir = os . getcwd ( ) #NEWLINE# os . chdir ( root ) #NEWLINE# #UNINDENT# total = len ( self . items ) #NEWLINE# errors = 0 #NEWLINE# if strip : #NEWLINE# #INDENT# try : #NEWLINE# #INDENT# strip = int ( strip ) #NEWLINE# #UNINDENT# except ValueError : #NEWLINE# #INDENT# errors += 1 #NEWLINE# warning ( ( "error: strip parameter '%s' must be an integer" % strip ) ) #NEWLINE# strip = 0 #NEWLINE# #UNINDENT# #UNINDENT# for ( i , p ) in enumerate ( self . items ) : #NEWLINE# #INDENT# if strip : #NEWLINE# #INDENT# debug ( ( 'stripping %s leading component(s) from:' % strip ) ) #NEWLINE# debug ( ( '   %s' % p . source ) ) #NEWLINE# debug ( ( '   %s' % p . target ) ) #NEWLINE# old = pathstrip ( p . source , strip ) #NEWLINE# new = pathstrip ( p . target , strip ) #NEWLINE# #UNINDENT# else : #NEWLINE# #INDENT# ( old , new ) = ( p . source , p . target ) #NEWLINE# #UNINDENT# filename = self . findfile ( old , new ) #NEWLINE# if ( not filename ) : #NEWLINE# #INDENT# warning ( ( 'source/target file does not exist:\n  --- %s\n  +++ %s' % ( old , new ) ) ) #NEWLINE# errors += 1 #NEWLINE# continue #NEWLINE# #UNINDENT# if ( not isfile ( filename ) ) : #NEWLINE# #INDENT# warning ( ( 'not a file - %s' % filename ) ) #NEWLINE# errors += 1 #NEWLINE# continue #NEWLINE# #UNINDENT# debug ( ( 'processing %d/%d:\t %s' % ( ( i + 1 ) , total , filename ) ) ) #NEWLINE# f2fp = open ( filename , 'rb' ) #NEWLINE# hunkno = 0 #NEWLINE# hunk = p . hunks [ hunkno ] #NEWLINE# hunkfind = [ ] #NEWLINE# hunkreplace = [ ] #NEWLINE# validhunks = 0 #NEWLINE# canpatch = False #NEWLINE# for ( lineno , line ) in enumerate ( f2fp ) : #NEWLINE# #INDENT# if ( ( lineno + 1 ) < hunk . startsrc ) : #NEWLINE# #INDENT# continue #NEWLINE# #UNINDENT# else : #NEWLINE# #INDENT# if ( ( lineno + 1 ) == hunk . startsrc ) : #NEWLINE# #INDENT# hunkfind = [ x [ 1 : ] . rstrip ( b'\r\n' ) for x in hunk . text if ( x [ 0 ] in b' -' ) ] #NEWLINE# hunkreplace = [ x [ 1 : ] . rstrip ( b'\r\n' ) for x in hunk . text if ( x [ 0 ] in b' +' ) ] #NEWLINE# hunklineno = 0 #NEWLINE# #UNINDENT# #UNINDENT# if ( ( lineno + 1 ) < ( ( hunk . startsrc + len ( hunkfind ) ) - 1 ) ) : #NEWLINE# #INDENT# if ( line . rstrip ( b'\r\n' ) == hunkfind [ hunklineno ] ) : #NEWLINE# #INDENT# hunklineno += 1 #NEWLINE# #UNINDENT# else : #NEWLINE# #INDENT# info ( ( 'file %d/%d:\t %s' % ( ( i + 1 ) , total , filename ) ) ) #NEWLINE# info ( ( " hunk no.%d doesn't match source file at line %d" % ( ( hunkno + 1 ) , ( lineno + 1 ) ) ) ) #NEWLINE# info ( ( '  expected: %s' % hunkfind [ hunklineno ] ) ) #NEWLINE# info ( ( '  actual  : %s' % line . rstrip ( b'\r\n' ) ) ) #NEWLINE# hunkno += 1 #NEWLINE# if ( hunkno < len ( p . hunks ) ) : #NEWLINE# #INDENT# hunk = p . hunks [ hunkno ] #NEWLINE# continue #NEWLINE# #UNINDENT# else : #NEWLINE# #INDENT# break #NEWLINE# #UNINDENT# #UNINDENT# #UNINDENT# if ( ( lineno + 1 ) == ( ( hunk . startsrc + len ( hunkfind ) ) - 1 ) ) : #NEWLINE# #INDENT# debug ( ( ' hunk no.%d for file %s  -- is ready to be patched' % ( ( hunkno + 1 ) , filename ) ) ) #NEWLINE# hunkno += 1 #NEWLINE# validhunks += 1 #NEWLINE# if ( hunkno < len ( p . hunks ) ) : #NEWLINE# #INDENT# hunk = p . hunks [ hunkno ] #NEWLINE# #UNINDENT# else : #NEWLINE# #INDENT# if ( validhunks == len ( p . hunks ) ) : #NEWLINE# #INDENT# canpatch = True #NEWLINE# break #NEWLINE# #UNINDENT# #UNINDENT# #UNINDENT# #UNINDENT# else : #NEWLINE# #INDENT# if ( hunkno < len ( p . hunks ) ) : #NEWLINE# #INDENT# warning ( ( 'premature end of source file %s at hunk %d' % ( filename , ( hunkno + 1 ) ) ) ) #NEWLINE# errors += 1 #NEWLINE# #UNINDENT# #UNINDENT# f2fp . close ( ) #NEWLINE# if ( validhunks < len ( p . hunks ) ) : #NEWLINE# #INDENT# if self . _match_file_hunks ( filename , p . hunks ) : #NEWLINE# #INDENT# warning ( ( 'already patched  %s' % filename ) ) #NEWLINE# #UNINDENT# else : #NEWLINE# #INDENT# warning ( ( 'source file is different - %s' % filename ) ) #NEWLINE# errors += 1 #NEWLINE# #UNINDENT# #UNINDENT# if canpatch : #NEWLINE# #INDENT# backupname = ( filename + b'.orig' ) #NEWLINE# if exists ( backupname ) : #NEWLINE# #INDENT# warning ( ( "can't backup original file to %s - aborting" % backupname ) ) #NEWLINE# #UNINDENT# else : #NEWLINE# #INDENT# import shutil #NEWLINE# shutil . move ( filename , backupname ) #NEWLINE# if self . write_hunks ( backupname , filename , p . hunks ) : #NEWLINE# #INDENT# info ( ( 'successfully patched %d/%d:\t %s' % ( ( i + 1 ) , total , filename ) ) ) #NEWLINE# os . unlink ( backupname ) #NEWLINE# #UNINDENT# else : #NEWLINE# #INDENT# errors += 1 #NEWLINE# warning ( ( 'error patching file %s' % filename ) ) #NEWLINE# shutil . copy ( filename , ( filename + '.invalid' ) ) #NEWLINE# warning ( ( ( 'invalid version is saved to %s' % filename ) + '.invalid' ) ) #NEWLINE# shutil . move ( backupname , filename ) #NEWLINE# #UNINDENT# #UNINDENT# #UNINDENT# #UNINDENT# if root : #NEWLINE# #INDENT# os . chdir ( prevdir ) #NEWLINE# #UNINDENT# return ( errors == 0 )