# Compares classpaths from ant -v logfiles # Useful for debugging errors in ant build scripts, # where a build typically works on one machine and not another import sys, os from optparse import OptionParser from sets import Set import re # Build dirs are different on machines # /src/SABS/build or /home/hendry/SABS/build or /u01/build/SABS/build # With '^.*SABS/' we strip all the above to the same build/ for comparison prefix = '^.*SABS/' # Regex for choosing what you do not want to see in the output exclude = 'ant|tools.jar' debug = 1 def win32file(line): win32 = re.search(r"\r\n", line) if win32: return 1 else: return 0 def compare(classpath1, classpath2): # Assuming UNIX style delimiter = ':' sep = "/" # Make sure classpath1 is the larger if len(classpath1) < len(classpath2): tmp = classpath1 classpath1 = classpath2 classpath2 = tmp tmp = None if debug: print "Length of 1: %d" % len(classpath1) print "Length of 2: %d" % len(classpath2) print classpath2length = len(classpath2) + 1 classes1 = Set([]) classes2 = Set([]) # Classpath with least classpath defs is loaded up first # This is the one which most likely bombed out of the compile # And requires comparing to at each stage for i in classpath2: j = i.split(delimiter) for jar in j: jar = re.sub(prefix, '', jar) classes2.add(jar) print "Adding %d values to classes2 of size %d" % (len(j), len(classes2)) print "Classpath2 loaded for comparison" for i in classpath1: classpath2length = classpath2length - 1 if not classpath2length: print '*'*25 print "Critical stage" print '*'*25, '\n' j = i.split(delimiter) for jar in j: jar = re.sub(prefix, '', jar) classes1.add(jar) print "Adding %d values to classes1 of size %d and comparing to classes2 of size %d" % (len(j), len(classes1), len(classes2)) print "What they share:" for i in (classes1 & classes2): display(i) print print "What classes1 has that classes2 doesn't:" for i in (classes1 - classes2): display(i) print print "What classes2 has that classes1 doesn't:" for i in (classes2 - classes1): display(i) print print def display(i): if not re.search(exclude, i): print i def grabclasspath(input): """ Grabs classpaths from Ant log """ s = re.findall(r"classpath\'\s+\[javac\]\s+'(.*)'\s+\[javac\]\s\'\-sourcepath", input) if s: return s else: print "No classpath(s) found!" sys.exit(1) def main(): usage = "Usage: %prog [options] classes" parser = OptionParser(usage, version="%prog $Id$ ") (options, args) = parser.parse_args() if len(args) == 2: classpath1 = open(args[0]).read() classpath2 = open(args[1]).read() compare(grabclasspath(classpath1), grabclasspath(classpath2)) if __name__ == '__main__': main()