import os, re, sys todoPattern = re.compile('Todo|TODO|todo\W') commentPattern = re.compile('//') excludePattern = re.compile('Test.java') def howBuggyIs(javaFile): lines = open(javaFile).readlines() numberOfLinesMetric = len(lines) numberOfCommentsMetric = len([l for l in lines if commentPattern.search(l) and not todoPattern.search(l)]) numberOfTodosMetric = len(todoPattern.findall(''.join(lines))) wouldBeTestName = os.path.basename(javaFile).replace('.java', 'Test.java') hasTest = len([f for f in javaFilesCopy if f.endswith(wouldBeTestName)]) > 0 buggyMetric = numberOfLinesMetric + (numberOfTodosMetric * 50) + (numberOfCommentsMetric * 10) if not hasTest: buggyMetric *= 10 return buggyMetric def bugMetric(x, y): return howBuggyIs(y) - howBuggyIs(x) if __name__ == "__main__": if len(sys.argv) == 1: print 'Usage: ' + os.path.basename(sys.argv[0]) + ' path [excludePattern]' print '' print ' e.g. ' + os.path.basename(sys.argv[0]) + ' .' print ' ' + os.path.basename(sys.argv[0]) + ' src/java Test' sys.exit(1) if len(sys.argv) == 3: excludePattern = re.compile(sys.argv[2]) javaFiles = [] for root, dirs, files in os.walk(sys.argv[1], topdown=False): javaFiles.extend([os.path.join(root, name) for name in files if name.endswith('.java')]) javaFilesCopy = list(javaFiles) javaFiles.sort(bugMetric) javaFiles = [f for f in javaFiles if not excludePattern.search(f)] for mostBuggy in javaFiles[:10]: print mostBuggy