diff --git a/cli/src/main/java/de/pfeufferweb/gitcover/GCOptions.java b/cli/src/main/java/de/pfeufferweb/gitcover/GCOptions.java index 341efa6..ac94f0e 100644 --- a/cli/src/main/java/de/pfeufferweb/gitcover/GCOptions.java +++ b/cli/src/main/java/de/pfeufferweb/gitcover/GCOptions.java @@ -16,8 +16,11 @@ class GCOptions private String ignoreFile = null; private String repository = null; private String reference = null; + private boolean failed = false; + private CoverageTool coverageTool = CoverageTool.COBERTURA; + public void parse(String[] args) { Options options = buildOptions(); @@ -54,6 +57,16 @@ private void parse(String[] args, Options options, CommandLineParser parser) thr printHelp(options); failed = true; } + if(line.hasOption("ct")) + { + switch (line.getOptionValue("ct")){ + case "cobertura": coverageTool = CoverageTool.COBERTURA; + break; + case "jacoco": coverageTool = CoverageTool.JACOCO; + break; + default: break; + } + } } @SuppressWarnings("static-access") @@ -66,6 +79,8 @@ private Options buildOptions() .withDescription("use this to ignore files that have been modified").create("em"); Option excludeAddedOption = OptionBuilder.withLongOpt("exclude-added") .withDescription("use this to ignore files that have been modified").create("ea"); + Option coverageToolOption = OptionBuilder.withLongOpt("coverage-tool") + .withDescription("use this to select between cobertura and jacoco").create("ct"); options.addOption(ignoreFileOption); options.addOption(excludeModifiedOption); options.addOption(excludeAddedOption); diff --git a/cli/src/main/java/de/pfeufferweb/gitcover/GitCover.java b/cli/src/main/java/de/pfeufferweb/gitcover/GitCover.java index e6c990b..9247116 100644 --- a/cli/src/main/java/de/pfeufferweb/gitcover/GitCover.java +++ b/cli/src/main/java/de/pfeufferweb/gitcover/GitCover.java @@ -76,13 +76,13 @@ private void process(GCOptions options) throws Exception out.println("a.ignored {background:#CDF;}"); out.println("a.allCovered {background:#CFC;}"); out.println("a.coverageMissing {background:#FDC;}"); - out.println("a.exp::after {content:\"»\";float:right;}"); + out.println("a.exp::after {content:\"�\";float:right;}"); out.println("a.exp:focus {border-width: 1px 1px 0 1px;border-radius:4px 4px 0 0}"); out.println("a.exp + div {display:none;}"); out.println("a.exp:focus + div {display:block;border-width: 0 1px 1px 1px;border-style:solid; border-radius:0 0 4px 4px;border-color:black;}"); out.println("a.exp:focus::after {content:\"\";}"); out.println("div.exp *{padding:0.3em 10px 0em 10px;}"); - out.println("div.exp table:last-child::after {content:\"«\";float:right;}"); + out.println("div.exp table:last-child::after {content:\"�\";float:right;}"); out.println("div.exp *:first-child {margin-top:0;}"); out.println("tr.notCovered {background: orangered;}"); out.println("tr.covered {background: lightgreen;}"); @@ -91,9 +91,9 @@ private void process(GCOptions options) throws Exception out.println(""); ChangedLines changedLines = createChangedLinesBuilder(options, options.getRepository()).build( options.getReference()); - Coverage coverage = new CoverageBuilder().computeAll(new File(options.getRepository())); + Coverage coverage = new CoberturaCoverageBuilder().computeAll(new File(options.getRepository())); out.println(""); - out.println("

Unittestabdeckung der Änderungen bzgl. Branch " + options.getReference() + "

"); + out.println("

Unittestabdeckung der �nderungen bzgl. Branch " + options.getReference() + "

"); List fileNames = new ArrayList(changedLines.getFileNames()); sort(fileNames); OverallCoverage overall = new OverallCoverage(); @@ -135,7 +135,7 @@ private void process(GCOptions options) throws Exception } out.println(""); } - out.println("Durchschnittliche Abdeckung aller testrelevanten Änderungen: " + overall.getCoverage() + "%"); + out.println("Durchschnittliche Abdeckung aller testrelevanten �nderungen: " + overall.getCoverage() + "%"); out.println(""); out.println(""); } diff --git a/core/src/main/java/de/pfeufferweb/gitcover/CoverageTool.java b/core/src/main/java/de/pfeufferweb/gitcover/CoverageTool.java new file mode 100644 index 0000000..bcbf0af --- /dev/null +++ b/core/src/main/java/de/pfeufferweb/gitcover/CoverageTool.java @@ -0,0 +1,9 @@ +package de.pfeufferweb.gitcover; + +/** + * + */ +public enum CoverageTool { + COBERTURA, + JACOCO +} diff --git a/core/src/main/java/de/pfeufferweb/gitcover/JacocoCoverageBuilder.java b/core/src/main/java/de/pfeufferweb/gitcover/JacocoCoverageBuilder.java new file mode 100644 index 0000000..8c3460e --- /dev/null +++ b/core/src/main/java/de/pfeufferweb/gitcover/JacocoCoverageBuilder.java @@ -0,0 +1,107 @@ +package de.pfeufferweb.gitcover; + +import org.apache.commons.io.FileUtils; +import org.apache.commons.io.filefilter.IOFileFilter; +import org.w3c.dom.Document; +import org.w3c.dom.NamedNodeMap; +import org.w3c.dom.NodeList; +import org.xml.sax.EntityResolver; +import org.xml.sax.InputSource; +import org.xml.sax.SAXException; + +import javax.xml.parsers.DocumentBuilder; +import javax.xml.parsers.DocumentBuilderFactory; +import javax.xml.xpath.XPath; +import javax.xml.xpath.XPathConstants; +import javax.xml.xpath.XPathExpression; +import javax.xml.xpath.XPathFactory; +import java.io.File; +import java.io.IOException; +import java.io.StringReader; +import java.util.Collection; + +import static java.lang.Integer.parseInt; + +public class JacocoCoverageBuilder +{ + public Coverage computeAll(File directory) throws Exception + { + Coverage overallCoverage = new Coverage(); + Collection files = FileUtils.listFiles(directory, new IOFileFilter() + { + + @Override + public boolean accept(File dir, String name) + { + return false; + } + + @Override + public boolean accept(File file) + { + return file.getName().equals("jacoco.xml"); + } + }, new IOFileFilter() + { + + @Override + public boolean accept(File dir, String name) + { + return false; + } + + @Override + public boolean accept(File file) + { + return true; + } + }); + for (File file : files) + { + overallCoverage.addAll(compute(file)); + } + return overallCoverage; + } + + public Coverage compute(File file) throws Exception + { + Coverage result = new Coverage(); + DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance(); + DocumentBuilder builder = factory.newDocumentBuilder(); + builder.setEntityResolver(new EntityResolver() + { + @Override + public InputSource resolveEntity(String publicId, String systemId) throws SAXException, IOException + { + if (systemId.contains("JACOCO")) + { + return new InputSource(new StringReader("")); + } + else + { + return null; + } + } + }); + Document doc = builder.parse(file); + XPathFactory xPathfactory = XPathFactory.newInstance(); + XPath xpath = xPathfactory.newXPath(); + XPathExpression classExpr = xpath.compile("//sourcefile/@name"); + NodeList foundFileNodes = (NodeList) classExpr.evaluate(doc, XPathConstants.NODESET); + for (int i = 0; i < foundFileNodes.getLength(); ++i) + { + String fileName = foundFileNodes.item(i).getNodeValue(); + result.addFile(fileName); + XPathExpression linesExpr = xpath.compile("//sourcefile[@name='" + fileName + "']//line"); + NodeList foundLineNodes = (NodeList) linesExpr.evaluate(doc, XPathConstants.NODESET); + for (int j = 0; j < foundLineNodes.getLength(); ++j) + { + NamedNodeMap attributes = foundLineNodes.item(j).getAttributes(); + int line = parseInt(attributes.getNamedItem("nr").getNodeValue()); + int hits = parseInt(attributes.getNamedItem("ci").getNodeValue()); + result.addLine(fileName, line, hits); + } + } + return result; + } +}