diff options
Diffstat (limited to 'longbow/src/python/site-packages/longbow/StyleReport.py')
-rwxr-xr-x | longbow/src/python/site-packages/longbow/StyleReport.py | 382 |
1 files changed, 0 insertions, 382 deletions
diff --git a/longbow/src/python/site-packages/longbow/StyleReport.py b/longbow/src/python/site-packages/longbow/StyleReport.py deleted file mode 100755 index 7e8d72e0..00000000 --- a/longbow/src/python/site-packages/longbow/StyleReport.py +++ /dev/null @@ -1,382 +0,0 @@ -#! /usr/bin/env python -# Copyright (c) 2017 Cisco and/or its affiliates. -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at: -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# - -# - -import sys -import os -import tempfile -import subprocess -import difflib -import csv -import argparse - -import LongBow -import ANSITerm -import FileUtil -import pprint - -def getExemplar(fileName, command, config): - """Create the exemplar formatted file into memory as a string""" - - with open(fileName) as inputFile: - result = subprocess.check_output([command, "-q", "-c", config], stdin=inputFile) - return result; - - -def diff(exemplar, fileName): - d = difflib.Differ() - differ = d.compare(exemplar.splitlines(), fileName.splitlines()) - return differ - - -class Ratchet: - def __init__(self): - self.currentValue = 0 - self.signal = 0 - - def value(self): - return self.currentValue - - def toggle(self, signal): - if self.signal == "-": - if signal == "-": - self.currentValue = self.currentValue + 1 - elif signal == "?": - self.currentValue = self.currentValue + 1 - self.signal = 0 - else: - self.currentValue = self.currentValue + 1 - self.signal = 0 - pass - elif self.signal == "+": - if signal == "-": - self.currentValue = self.currentValue + 1 - elif signal == "?": - self.currentValue = self.currentValue + 1 - self.signal = 0 - else: - self.currentValue = self.currentValue + 1 - self.signal = 0 - pass - else: - self.signal = signal; - - return self.currentValue - - -def computeNonCompliantLines(differ): - lines = 0 - changes = Ratchet() - - for l in differ: - if l.startswith('-'): - changes.toggle(l[0]) - lines = lines - 1 - elif l.startswith('+'): - changes.toggle(l[0]) - lines = lines + 1 - elif l.startswith('?'): - pass - elif l.startswith(' '): - lines = lines +1 - else: - print "What is this:", l - - return changes.value() - - -def reportWhy(differ): - print '\n'.join(diff) - return - - -class SyntaxCompliance: - def __init__(self, fileName, exemplarCommand, exemplarConfig): - self.fileName = fileName - self.nonCompliantLines = 0 - self.score = 0 - self.exemplarCommand = exemplarCommand - self.exemplarConfig = exemplarConfig - try: - self.fileData = FileUtil.readFileString(self.fileName) - self.totalLines = len(self.fileData.splitlines()) - except IOError, e: - print >> sys.stderr, e - sys.exit(1) - pass - - def check(self): - self.exemplarData = getExemplar(self.fileName, self.exemplarCommand, self.exemplarConfig) - differ = diff(self.fileData, self.exemplarData) - - self.nonCompliantLines = computeNonCompliantLines(differ) - - return self - - def report(self): - result = { "fileName" : self.fileName, - "label": "style", - "score": self.getScore(), - "totalLines" : self.getTotalLines(), - "nonCompliantLines" : self.getNonCompliantLines() - } - return result - - def getFileName(self): - return self.fileName - - def getExemplarCommand(self): - return self.exemplarCommand; - - def getExemplarConfig(self): - return self.exemplarConfig; - - def getScore(self): - result = 0 - try: - result = int(100 * (1.0 - (float(self.getNonCompliantLines()) / float(self.getTotalLines())))) - except ZeroDivisionError: - pass - return result - - def getTotalLines(self): - return self.totalLines - - def getNonCompliantLines(self): - return self.nonCompliantLines - - def explain(self): - self.exemplarData = getExemplar(self.fileName, self.exemplarCommand, self.exemplarConfig) - differ = diff(self.fileData, self.exemplarData) - - ansiTerm = ANSITerm.ANSITerm() - - for l in differ: - if l[0] == '-': - ansiTerm.printColorized("red", l) - elif l[0] == '+': - ansiTerm.printColorized("green", l) - elif l[0] == '?': - ansiTerm.printColorized("yellow", l[0:len(l)-1]) - else: - print l - pass - return - - -def csvScore(distribution, report): - string = "style,%s,%d,%d,%.2f" % (report["fileName"], report["totalLines"], report["nonCompliantLines"], report["score"]) - LongBow.scorePrinter(distribution, report["score"], string) - return - - -def csvAverage(distribution, complianceList): - scores = map(lambda target: target.getScore(), complianceList) - sum = reduce(lambda sum, score : sum + score, scores) - value = float(sum) / float(len(complianceList)) - LongBow.scorePrinter(distribution, value, "%.2f" % (value)) - return - - -def csvTotal(distribution, complianceList): - totalLines = reduce(lambda sum, x: sum + x, map(lambda element : element.getTotalLines(), complianceList)) - totalNonCompliantLines = reduce(lambda sum, x: sum + x, map(lambda element : element.getNonCompliantLines(), complianceList)) - value = 100.0 - (100.0 * float(totalNonCompliantLines) / float(totalLines)) - LongBow.scorePrinter(distribution, value, "%.2f" % (value)) - return - - -def csvSummary(distribution, complianceList): - map(lambda target: csvScore(distribution, target.report()), complianceList) - return - - -def textScore(distribution, report, maxFileNameLength, prefix=""): - ''' - - ''' - format = "%s%-*s %6d %6d %6.2f" - string = format % (prefix, maxFileNameLength, report["fileName"], report["totalLines"], report["nonCompliantLines"], report["score"]) - LongBow.scorePrinter(distribution, report["score"], string) - return - - -def textAverage(distribution, complianceList): - scores = map(lambda target: target.getScore(), complianceList) - sum = reduce(lambda sum, score : sum + score, scores) - value = float(sum) / float(len(complianceList)) - LongBow.scorePrinter(distribution, value, "%.2f" % (value)) - return - - -def textTotal(distribution, complianceList): - totalLines = reduce(lambda sum, x: sum + x, map(lambda element : element.getTotalLines(), complianceList)) - totalNonCompliantLines = reduce(lambda sum, x: sum + x, map(lambda element : element.getNonCompliantLines(), complianceList)) - value = 100.0 - (100.0 * float(totalNonCompliantLines) / float(totalLines)) - LongBow.scorePrinter(distribution, value, "%.2f" % (value)) - return - - -def textSummary(distribution, complianceList, prefix=""): - if len(complianceList) > 0: - maxFileNameLength = max(max(map(lambda target: len(target.getFileName()), complianceList)), len("File Name")) - - print "%s%-*s %6s %6s %6s" % (prefix, maxFileNameLength, "File Name", "Lines", "Errors", "Score") - map(lambda target: textScore(distribution, target.report(), maxFileNameLength, prefix), complianceList) - - return - - -def textVisual(complianceList): - map(lambda target: target.explain(), complianceList) - return - - -def openDiff(sourceFile, exemplarCommand, exemplarConfig): - exemplar = getExemplar(sourceFile, exemplarCommand, exemplarConfig); - temporaryExemplarFile = tempfile.NamedTemporaryFile(suffix=".c", delete=False) - try: - with open(temporaryExemplarFile.name, "w") as exemplarOutput: - exemplarOutput.write(exemplar) - - subprocess.check_output(["opendiff", sourceFile, temporaryExemplarFile.name, "-merge", sourceFile]) - finally: - pass - - return - - -def displaySummary(args, complianceList): - distribution = eval(args.distribution) - - if args.output == "text": - textSummary(distribution, complianceList) - elif args.output == "gui": - textSummary(distribution, complianceList) - else: - csvSummary(distribution, complianceList) - return - - -def displayAverage(args, complianceList): - - distribution = eval(args.distribution) - - if args.output == "text": - textAverage(distribution, complianceList) - elif args.output == "gui": - textAverage(distribution, complianceList) - else: - csvAverage(distribution, complianceList) - return - - -def displayTotal(args, complianceList): - distribution = eval(args.distribution) - - if args.output == "text": - textTotal(distribution, complianceList) - elif args.output == "gui": - textTotal(distribution, complianceList) - else: - csvTotal(distribution, complianceList) - return - - -def guiVisual(args, complianceList): - map(lambda target: openDiff(target.getFileName(), target.getExemplarCommand(), target.getExemplarConfig()), complianceList) - return - - -def displayVisual(args, complianceList): - if args.output == "text": - textVisual(complianceList) - elif args.output == "gui": - guiVisual(args, complianceList) - else: - print >> sys.stderr, "Unsupported output format '%s'. Expected 'text' or 'gui'." % (args.output) - sys.exit(1) - return - - -def sortComplianceList(args, complianceList): - - sorter = { - "name" : { "function" : lambda k: k.getFileName(), "reverse" : False }, - "descending-name" : { "function" : lambda k: k.getFileName(), "reverse" : True }, - "score" : { "function" : lambda k: k.getScore(), "reverse" : False }, - "descending-score" : { "function" : lambda k: k.getScore(), "reverse" : True }, - "size" : { "function" : lambda k: k.getTotalLines(), "reverse" : False }, - "descending-size" : { "function" : lambda k: k.getTotalLines(), "reverse" : True }, - } - - if args.key == "help": - print >> sys.stderr, "Supported sort keys:" - map(lambda k: sys.stderr.write("'" + k + "' "), sorted(sorter)) - print - sys.exit(1) - - if args.key in sorter: - complianceList = sorted(complianceList, key=sorter[args.key]["function"], reverse=sorter[args.key]["reverse"]) - else: - print >> sys.stderr, "Unsupported sort key '%s'. Type '--key help'" % (args.key) - sys.exit(1) - - return complianceList - - -def exclude(args, complianceList): - excluded = map(lambda token : token.strip(), args.exclude.split(",")) - complianceList = filter(lambda entry: LongBow.score(eval(args.distribution), entry.getScore()) not in excluded, complianceList) - - return complianceList - - -def gradeAndPrint(targets, exemplarCommand, exemplarConfig, problemsOnly=False, prefix=""): - complianceList = [] - problemList = [] - for target in targets: - try: - complianceList.append(SyntaxCompliance(target, exemplarCommand, exemplarConfig).check()) - except: - problemList.append(target) - pass - complianceList = sorted(complianceList, key=lambda k: k.getFileName()) - if problemsOnly: - complianceList = filter(lambda entry: entry.getScore() < 100, complianceList) - distribution=[99,90] - textSummary(distribution, complianceList, prefix) - - for target in problemList: - print LongBow.buildRed("%s%s could not be evaluated" % (prefix, target)) - - -def commandLineMain(args, targets, exemplarCommand, exemplarConfig): - complianceList = map(lambda target: SyntaxCompliance(target, exemplarCommand, exemplarConfig).check(), targets) - - complianceList = sortComplianceList(args, complianceList) - - complianceList = exclude(args, complianceList) - - if args.summary: - displaySummary(args, complianceList) - elif args.average: - displayAverage(args, complianceList) - elif args.total: - displayTotal(args, complianceList) - elif args.visual: - displayVisual(args, complianceList) - return |