Jim Miller | 5ecd811 | 2013-01-09 18:50:26 -0800 | [diff] [blame] | 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) |