Home | History | Annotate | Download | only in scripts
      1 #!/usr/bin/env python
      2 
      3 import os
      4 import sys
      5 import difflib
      6 import filecmp
      7 import tempfile
      8 from optparse import OptionParser
      9 from subprocess import call
     10 from subprocess import Popen
     11 from subprocess import PIPE
     12 
     13 def which(program):
     14     def executable(path):
     15         return os.path.isfile(path) and os.access(path, os.X_OK)
     16 
     17     path, file = os.path.split(program)
     18     if path and executable(program):
     19 		return program
     20     else:
     21         for path in os.environ["PATH"].split(os.pathsep):
     22             exe = os.path.join(path, program)
     23             if executable(exe):
     24                 return exe
     25     return ""
     26 
     27 DIFF_TOOLS=["meld", "kdiff3", "xdiff", "diffmerge.sh", "diff"]
     28 
     29 PROTO_SRC="./src/com/android/keyguard/"
     30 PROTO_RES="./res/"
     31 
     32 TEMP_FILE1="/tmp/tempFile1.txt"
     33 TEMP_FILE2="/tmp/tempFile2.txt"
     34 
     35 FW_SRC="../../../../frameworks/base/policy/src/com/android/internal/policy/impl/keyguard/"
     36 FW_RES="../../../../frameworks/base/core/res/res/"
     37 
     38 FW_PKG="com.android.internal.policy.impl.keyguard"
     39 PROTO_PKG="com.android.keyguard"
     40 
     41 FW_RES_IMPORT="import com.android.internal.R;"
     42 
     43 # Find a differ
     44 DIFF_TOOL=""
     45 if ("DIFF_TOOL" in os.environ and len(os.environ["DIFF_TOOL"]) > 0):
     46 	DIFF_TOOL=which(os.environ["DIFF_TOOL"])
     47 if len(DIFF_TOOL) == 0:
     48 	for differ in DIFF_TOOLS:
     49 		DIFF_TOOL=which(differ)
     50 		if len(DIFF_TOOL) > 0:
     51 			break
     52 
     53 print "Using differ", DIFF_TOOL
     54 
     55 #Anything file which contains any string in this list as a substring will be ommitted
     56 IGNORE=["LockHotnessActivity.java", "unified_lock_activity.xml", "optionmenu.xml"]
     57 WATCH=[]
     58 
     59 def dirCompare(sourceDir, destDir, ext, run_in_reverse):
     60 	sourceFiles = getFileList(sourceDir, ext)
     61 	destFiles = getFileList(destDir, ext)
     62 	for file in sourceFiles:
     63 		print file
     64 		destFile = destDir + file
     65 		sourceFile = sourceDir + file
     66 		if (file in destFiles):
     67 			if run_in_reverse:
     68 				prepareFileForCompare(sourceFile, TEMP_FILE1, FW_RES_IMPORT, FW_PKG, PROTO_PKG)
     69 				prepareFileForCompare(destFile, TEMP_FILE2, FW_RES_IMPORT,)
     70 			else:
     71 				prepareFileForCompare(destFile, TEMP_FILE1, FW_RES_IMPORT, FW_PKG, PROTO_PKG)
     72 				prepareFileForCompare(sourceFile, TEMP_FILE2, FW_RES_IMPORT,)
     73 			if (filecmp.cmp(TEMP_FILE1, TEMP_FILE2)):
     74 				print "File %s is the same in proto and framework" %(file)
     75 			else:
     76 				print "Running diff for: %s" %(file)
     77 				diff(sourceFile, destFile)
     78 		else:
     79 			print "File %s does not exist in framework" %(file)
     80 			if not run_in_reverse:
     81 				diff(sourceFile, destFile)
     82 
     83 def main(argv):
     84 	run_in_reverse = False
     85 	if len(argv) > 1:
     86 		if argv[1] == '--help' or argv[1] == '-h':
     87 			print ('Usage: %s [<commit>]' % argv[0])
     88 			print ('\tdiff to framework, ' +
     89 					'optionally restricting to files in <commit>')
     90 			sys.exit(0)
     91 		elif argv[1] == '--reverse':
     92 			print "Running in reverse"
     93 			run_in_reverse = True
     94 		else:
     95 			print ("**** Pulling file list from: %s" % argv[1])
     96 			pipe = Popen(['git', 'diff', '--name-only',  argv[1]], stdout=PIPE).stdout
     97 			for line in iter(pipe.readline,''):
     98 				path = line.rstrip()
     99 				file = path[path.rfind('/') + 1:]
    100 				print '**** watching: %s' % file
    101 				WATCH.append(file);
    102 			pipe.close()
    103 
    104 	if run_in_reverse:
    105 		#dirCompare(FW_RES, PROTO_RES, ".xml", run_in_reverse)
    106 		print ("**** Source files:")
    107 		dirCompare(FW_SRC, PROTO_SRC, ".java", run_in_reverse)
    108 	else:
    109 		#dirCompare(PROTO_RES, FW_RES, ".xml", run_in_reverse)
    110 		print ("**** Source files:")
    111 		dirCompare(PROTO_SRC, FW_SRC, ".java", run_in_reverse)
    112 
    113 	if (os.path.exists(TEMP_FILE1)):
    114 		os.remove(TEMP_FILE1)
    115 
    116 	if (os.path.exists(TEMP_FILE2)):
    117 		os.remove(TEMP_FILE2)
    118 
    119 def getFileList(rootdir, extension):
    120 	fileList = []
    121 
    122 	for root, subFolders, files in os.walk(rootdir):
    123 	    for file in files:
    124 	        f = os.path.join(root,file)
    125 	        if (os.path.splitext(f)[1] == extension and (not inIgnore(f))):
    126 	        	fileList.append(f[len(rootdir):])
    127 	return fileList
    128 
    129 
    130 def prepareFileForCompare(inFile, outFile, skip="", replace="", withText=""):
    131 	# Delete the outfile, so we're starting with a new file
    132 	if (os.path.exists(outFile)):
    133 		os.remove(outFile)
    134 
    135 	fin = open(inFile)
    136 	fout = open(outFile, "w")
    137 	for line in fin:
    138 		# Ignore any lines containing the ignore string ("import com.android.internal.R;) and
    139 		# ignore any lines containing only whitespace.
    140 		if (line.find(skip) < 0  and len(line.strip(' \t\n\r')) > 0):
    141 			# For comparison, for framework files, we replace the fw package with the
    142 			# proto package, since these aren't relevant.
    143 			if len(replace) > 0:
    144 				fout.write(line.replace(replace, withText))
    145 			else:
    146 				fout.write(line)
    147 	fin.close()
    148 	fout.close()
    149 
    150 def diff(file1, file2):
    151 	call([DIFF_TOOL, file1, file2])
    152 
    153 def inIgnore(file):
    154 	for ignore in IGNORE:
    155 		if file.find(ignore) >= 0:
    156 			return True
    157         if len(WATCH) > 0:
    158             for watch in WATCH:
    159 		if file.find(watch) >= 0:
    160                     return False
    161             return True
    162 	return False
    163 
    164 if __name__=="__main__":
    165   main(sys.argv)
    166