From 782c1096ff98b6654d308db5ceb8ecf13e325d9b Mon Sep 17 00:00:00 2001 From: Isaac Christopher Wang Date: Fri, 10 Aug 2018 11:21:29 -0700 Subject: [PATCH 1/2] Refactor including the following: - Created SwiftSensor abstract class, which SwiftLintSensor and SwiftCoberturaSensor extend - Removed ReportFilesFinder. Report finding functionality moved to Util, and settings reading functionality moved to SwiftSensor - Reworked reportDirectory to reportInRoot, which makes reportPattern / reportPath evaluated from the project root - Cleaned up CoberturaReportParser and SwiftLintReportParser - Reworked ReportFilesFinderTest to SwiftSensorTest --- .../org/sonar/plugins/swift/SwiftPlugin.java | 14 ++ .../swift/coverage/CoberturaReportParser.java | 29 +--- .../swift/coverage/ReportFilesFinder.java | 123 -------------- .../swift/coverage/SwiftCoberturaSensor.java | 64 +------ .../plugins/swift/generic/SwiftSensor.java | 108 ++++++++++++ .../org/sonar/plugins/swift/generic/Util.java | 50 ++++++ .../swiftlint/SwiftLintReportParser.java | 21 ++- .../issues/swiftlint/SwiftLintSensor.java | 56 +----- .../swift/coverage/ReportFilesFinderTest.java | 98 ----------- .../swift/generic/SwiftSensorTest.java | 160 ++++++++++++++++++ .../resources/coverage/dir3/cobertura.xml | 0 .../{coverage => generic}/dir1/cobertura.xml | 0 .../myMod}/dir2/cobertura.xml | 0 13 files changed, 363 insertions(+), 360 deletions(-) delete mode 100644 sonar-swift-plugin/src/main/java/org/sonar/plugins/swift/coverage/ReportFilesFinder.java create mode 100644 sonar-swift-plugin/src/main/java/org/sonar/plugins/swift/generic/SwiftSensor.java create mode 100644 sonar-swift-plugin/src/main/java/org/sonar/plugins/swift/generic/Util.java delete mode 100644 sonar-swift-plugin/src/test/java/org/sonar/plugins/swift/coverage/ReportFilesFinderTest.java create mode 100644 sonar-swift-plugin/src/test/java/org/sonar/plugins/swift/generic/SwiftSensorTest.java delete mode 100644 sonar-swift-plugin/src/test/resources/coverage/dir3/cobertura.xml rename sonar-swift-plugin/src/test/resources/{coverage => generic}/dir1/cobertura.xml (100%) rename sonar-swift-plugin/src/test/resources/{coverage => generic/myMod}/dir2/cobertura.xml (100%) diff --git a/sonar-swift-plugin/src/main/java/org/sonar/plugins/swift/SwiftPlugin.java b/sonar-swift-plugin/src/main/java/org/sonar/plugins/swift/SwiftPlugin.java index ccf460e8..26f80415 100644 --- a/sonar-swift-plugin/src/main/java/org/sonar/plugins/swift/SwiftPlugin.java +++ b/sonar-swift-plugin/src/main/java/org/sonar/plugins/swift/SwiftPlugin.java @@ -46,6 +46,13 @@ description = "Relative to projects' root. Ant patterns are accepted", global = false, project = true), + @Property( + key = SwiftCoberturaSensor.REPORTS_IN_ROOT_KEY, + defaultValue = "false", + name = "Whether reports are located in the root directory", + description = "Determines where to find reports in modular analysis", + global = false, + project = true), @Property( key = SwiftLintSensor.REPORT_PATH_KEY, defaultValue = SwiftLintSensor.DEFAULT_REPORT_PATH, @@ -53,6 +60,13 @@ description = "Relative to projects' root.", global = false, project = true), + @Property( + key = SwiftLintSensor.REPORTS_IN_ROOT_KEY, + defaultValue = "false", + name = "Whether the report is located in the root directory", + description = "Determines where to find the report in modular analysis", + global = false, + project = true), @Property( key = TailorSensor.REPORT_PATH_KEY, defaultValue = TailorSensor.DEFAULT_REPORT_PATH, diff --git a/sonar-swift-plugin/src/main/java/org/sonar/plugins/swift/coverage/CoberturaReportParser.java b/sonar-swift-plugin/src/main/java/org/sonar/plugins/swift/coverage/CoberturaReportParser.java index a268498b..6307f1b9 100644 --- a/sonar-swift-plugin/src/main/java/org/sonar/plugins/swift/coverage/CoberturaReportParser.java +++ b/sonar-swift-plugin/src/main/java/org/sonar/plugins/swift/coverage/CoberturaReportParser.java @@ -29,7 +29,6 @@ import org.sonar.api.batch.fs.InputFile; import org.sonar.api.measures.CoverageMeasuresBuilder; import org.sonar.api.measures.Measure; -import org.sonar.api.resources.Project; import org.sonar.api.resources.Resource; import org.sonar.api.utils.ParsingUtils; import org.sonar.api.utils.StaxParser; @@ -46,20 +45,20 @@ final class CoberturaReportParser { private static final Logger LOGGER = LoggerFactory.getLogger(CoberturaReportParser.class); private final FileSystem fileSystem; - private final Project project; private final SensorContext context; + private final String rootDirectory; - private CoberturaReportParser(FileSystem fileSystem, Project project, SensorContext context) { + private CoberturaReportParser(FileSystem fileSystem, SensorContext context, String rootDirectory) { this.fileSystem = fileSystem; - this.project = project; this.context = context; + this.rootDirectory = rootDirectory; } /** * Parse a Cobertura xml report and create measures accordingly */ - public static void parseReport(File xmlFile, FileSystem fileSystem, Project project, SensorContext context) { - new CoberturaReportParser(fileSystem, project, context).parse(xmlFile); + public static void parseReport(File xmlFile, FileSystem fileSystem, SensorContext sensorContext, String rootDirectory) { + new CoberturaReportParser(fileSystem, sensorContext, rootDirectory).parse(xmlFile); } private void parse(File xmlFile) { @@ -84,11 +83,7 @@ private void collectPackageMeasures(SMInputCursor pack) throws XMLStreamExceptio collectFileMeasures(pack.descendantElementCursor("class"), builderByFilename); for (Map.Entry entry : builderByFilename.entrySet()) { String filePath = entry.getKey(); - filePath = getAdjustedPathIfProjectIsModule(filePath); - if (filePath == null) { - continue; - } - File file = new File(fileSystem.baseDir(), filePath); + File file = new File(rootDirectory, filePath); InputFile inputFile = fileSystem.inputFile(fileSystem.predicates().hasAbsolutePath(file.getAbsolutePath())); if (inputFile == null) { @@ -111,18 +106,6 @@ private boolean resourceExists(Resource file) { return context.getResource(file) != null; } - private String getAdjustedPathIfProjectIsModule(String filePath) { - if (project.isModule()) { - // the file doesn't belong to the module we're analyzing - if (!filePath.startsWith(project.path())) { - return null; - } - // fileSystem.baseDir() will include the module path, so we need to get rid of it here - return filePath.substring(project.path().length()); - } - return filePath; - } - private static void collectFileMeasures(SMInputCursor clazz, Map builderByFilename) throws XMLStreamException { while (clazz.getNext() != null) { diff --git a/sonar-swift-plugin/src/main/java/org/sonar/plugins/swift/coverage/ReportFilesFinder.java b/sonar-swift-plugin/src/main/java/org/sonar/plugins/swift/coverage/ReportFilesFinder.java deleted file mode 100644 index f34077a6..00000000 --- a/sonar-swift-plugin/src/main/java/org/sonar/plugins/swift/coverage/ReportFilesFinder.java +++ /dev/null @@ -1,123 +0,0 @@ -/** - * backelite-sonar-swift-plugin - Enables analysis of Swift projects into SonarQube. - * Copyright © 2015 Backelite (${email}) - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this program. If not, see . - */ -package org.sonar.plugins.swift.coverage; - -import org.apache.tools.ant.DirectoryScanner; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; -import org.sonar.api.config.Settings; - -import java.io.File; -import java.util.Arrays; -import java.util.ArrayList; -import java.util.List; - -final class ReportFilesFinder { - - private static final Logger LOGGER = LoggerFactory.getLogger(ReportFilesFinder.class); - - private final Settings conf; - private final String settingsReportKey; - private final String settingsReportDefault; - private final String settingsDirectoryKey; - - public ReportFilesFinder(final Settings settings, final String settingsReportKey, final String settingsReportDefault, final String settingsDirectoryKey) { - - conf = settings; - this.settingsReportKey = settingsReportKey; - this.settingsReportDefault = settingsReportDefault; - this.settingsDirectoryKey = settingsDirectoryKey; - } - - public List reportsIn(final String baseDirectory) { - - final String reportDirectory = getReportDirectory(baseDirectory, baseDirectory); // the root directory in this case is the base directory - final String reportPattern = getReportPattern(); - return reportsInHelper(reportDirectory, reportPattern); - } - - public List reportsIn(final String module, final String rootDirectory, final String baseDirectory) { - - final String reportDirectory = getReportDirectory(module, rootDirectory, baseDirectory); - final String reportPattern = getReportPattern(module); - return reportsInHelper(reportDirectory, reportPattern); - } - - private List reportsInHelper(final String reportDirectory, final String reportPattern) { - - final String[] relPaths = filesMathingPattern(reportDirectory, reportPattern); - - final List reports = new ArrayList(); - - for (final String relPath : relPaths) { - reports.add(new File(reportDirectory, relPath)); - } - - return reports; - } - - private String[] filesMathingPattern(final String reportDirectory, final String reportPath) { - - final DirectoryScanner scanner = new DirectoryScanner(); - scanner.setIncludes(new String[] { reportPath }); - scanner.setBasedir(new File(reportDirectory)); - scanner.scan(); - - LOGGER.info("Files found in directory '{}' including '{}': {}", reportDirectory, reportPath, Arrays.toString(scanner.getIncludedFiles())); - - return scanner.getIncludedFiles(); - } - - private String getReportPattern() { - - String reportPath = conf.getString(settingsReportKey); - if (reportPath == null) { - reportPath = settingsReportDefault; - } - return reportPath; - } - - private String getReportPattern(final String module) { - - String reportPath = conf.getString(module + "." + settingsReportKey); - if (reportPath == null) { - return getReportPattern(); - } - return reportPath; - } - - private String getReportDirectory(final String rootDirectory, final String baseDirectory) { - - String reportDirectory = conf.getString(settingsDirectoryKey); - if (reportDirectory == null) { - return baseDirectory; - } - return rootDirectory + "/" + reportDirectory; - } - - - private String getReportDirectory(final String module, final String rootDirectory, final String baseDirectory) { - - String reportDirectory = conf.getString(module + "." + settingsDirectoryKey); - if (reportDirectory == null) { - return getReportDirectory(rootDirectory, baseDirectory); - } - return rootDirectory + "/" + reportDirectory; - } - -} \ No newline at end of file diff --git a/sonar-swift-plugin/src/main/java/org/sonar/plugins/swift/coverage/SwiftCoberturaSensor.java b/sonar-swift-plugin/src/main/java/org/sonar/plugins/swift/coverage/SwiftCoberturaSensor.java index ec37d797..33ee888f 100644 --- a/sonar-swift-plugin/src/main/java/org/sonar/plugins/swift/coverage/SwiftCoberturaSensor.java +++ b/sonar-swift-plugin/src/main/java/org/sonar/plugins/swift/coverage/SwiftCoberturaSensor.java @@ -19,78 +19,28 @@ import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import org.sonar.api.batch.Sensor; import org.sonar.api.batch.SensorContext; import org.sonar.api.batch.fs.FileSystem; import org.sonar.api.config.Settings; import org.sonar.api.resources.Project; -import org.sonar.api.scan.filesystem.PathResolver; import org.sonar.plugins.swift.SwiftPlugin; -import org.sonar.plugins.swift.lang.core.Swift; +import org.sonar.plugins.swift.generic.SwiftSensor; import java.io.File; -import java.util.List; - -public final class SwiftCoberturaSensor implements Sensor { +public class SwiftCoberturaSensor extends SwiftSensor { private static final Logger LOGGER = LoggerFactory.getLogger(SwiftCoberturaSensor.class); public static final String REPORT_PATTERN_KEY = SwiftPlugin.PROPERTY_PREFIX + ".coverage.reportPattern"; public static final String DEFAULT_REPORT_PATTERN = "sonar-reports/coverage-swift*.xml"; - public static final String REPORT_DIRECTORY_KEY = SwiftPlugin.PROPERTY_PREFIX + ".coverage.reportDirectory"; - - private final ReportFilesFinder reportFilesFinder; - - private final Settings settings; - private final FileSystem fileSystem; - private final PathResolver pathResolver; - private Project project; - - public SwiftCoberturaSensor(final FileSystem fileSystem, final PathResolver pathResolver, final Settings settings) { - - this.settings = settings; - this.fileSystem = fileSystem; - this.pathResolver = pathResolver; - - reportFilesFinder = new ReportFilesFinder(settings, REPORT_PATTERN_KEY, DEFAULT_REPORT_PATTERN, REPORT_DIRECTORY_KEY); - } - - public boolean shouldExecuteOnProject(final Project project) { - - this.project = project; - - return fileSystem.languages().contains(Swift.KEY); - } - - public void analyse(final Project project, final SensorContext context) { - - final String projectBaseDir = fileSystem.baseDir().getPath(); - LOGGER.info("Analyzing directory: {}", projectBaseDir); - - List reports; - if (project.isRoot()) { - reports = reportFilesFinder.reportsIn(projectBaseDir); - } - else { - final String module = project.getName(); - final String rootDir = getRootDirectory(project); - reports = reportFilesFinder.reportsIn(module, rootDir, projectBaseDir); - } + public static final String REPORTS_IN_ROOT_KEY = SwiftPlugin.PROPERTY_PREFIX + ".coverage.reportsInRoot"; - for (final File report : reports) { - LOGGER.info("Processing coverage report {}", report); - CoberturaReportParser.parseReport(report, fileSystem, project, context); - } + public SwiftCoberturaSensor(FileSystem fileSystem, Settings settings) { + super(fileSystem, settings, REPORT_PATTERN_KEY, DEFAULT_REPORT_PATTERN, REPORTS_IN_ROOT_KEY, true); } - private String getRootDirectory(Project project) { - final String projectBaseDir = fileSystem.baseDir().getPath(); - if (project.isRoot()) { - return projectBaseDir; - } else { - final String modulePath = project.path(); - return projectBaseDir.substring(0, projectBaseDir.length() - modulePath.length()); - } + public void parseReport(File report, Project project, SensorContext context) { + CoberturaReportParser.parseReport(report, fileSystem, context, getRootDirectory(project)); } } diff --git a/sonar-swift-plugin/src/main/java/org/sonar/plugins/swift/generic/SwiftSensor.java b/sonar-swift-plugin/src/main/java/org/sonar/plugins/swift/generic/SwiftSensor.java new file mode 100644 index 00000000..a2253ced --- /dev/null +++ b/sonar-swift-plugin/src/main/java/org/sonar/plugins/swift/generic/SwiftSensor.java @@ -0,0 +1,108 @@ +/** + * backelite-sonar-swift-plugin - Enables analysis of Swift projects into SonarQube. + * Copyright © 2015 Backelite (${email}) + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program. If not, see . + */ +package org.sonar.plugins.swift.generic; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.sonar.api.batch.Sensor; +import org.sonar.api.batch.SensorContext; +import org.sonar.api.batch.fs.FileSystem; +import org.sonar.api.config.Settings; +import org.sonar.api.resources.Project; +import org.sonar.plugins.swift.lang.core.Swift; + +import java.io.File; +import java.util.Arrays; +import java.util.List; + +public abstract class SwiftSensor implements Sensor { + + private static final Logger LOGGER = LoggerFactory.getLogger(SwiftSensor.class); + public final FileSystem fileSystem; + + private final Settings settings; + private final String reportPatternKey; + private final String reportPatternDefault; + private final String reportsInRootKey; + private final boolean multipleReports; + + public SwiftSensor(FileSystem fileSystem, Settings settings, String reportPatternKey, + String reportPatternDefault, String reportsInRootKey, boolean multipleReports) { + this.fileSystem = fileSystem; + this.settings = settings; + this.reportPatternKey = reportPatternKey; + this.reportPatternDefault = reportPatternDefault; + this.reportsInRootKey = reportsInRootKey; + this.multipleReports = multipleReports; + } + + public boolean shouldExecuteOnProject(Project project) { + return fileSystem.languages().contains(Swift.KEY); + } + + public void analyse(Project project, SensorContext context) { + String reportDirectory = getReportDirectory(project); + String reportPattern = getReportPattern(project); + List reports; + if (multipleReports) { + reports = Util.findReports(reportDirectory, reportPattern); + } + else { + reports = Arrays.asList(new File(reportDirectory + "/" + reportPattern)); + } + for (final File report : reports) { + LOGGER.info("Processing report {}", report); + parseReport(report, project, context); + } + } + + public abstract void parseReport(File report, Project project, SensorContext context); + + public String getRootDirectory(Project project) { + final String baseDir = fileSystem.baseDir().getPath(); + if (project.isRoot()) { + return baseDir; + } + return baseDir.substring(0, baseDir.length() - project.path().length()); + } + + private String getReportDirectory(Project project) { + if (getSettingsValue(project, reportsInRootKey, "false").equals("true")) { + return getRootDirectory(project); + } + return fileSystem.baseDir().getPath(); + } + + private String getReportPattern(Project project) { + return getSettingsValue(project, reportPatternKey, reportPatternDefault); + } + + private String getSettingsValue(Project project, String key, String defaultValue) { + String value; + // modular case + if (!project.isRoot()) { + value = settings.getString(project.getName() + "." + key); + if (value != null) { + return value; + } + } + // root case + value = settings.getString(key); + return value != null ? value : defaultValue; + } +} diff --git a/sonar-swift-plugin/src/main/java/org/sonar/plugins/swift/generic/Util.java b/sonar-swift-plugin/src/main/java/org/sonar/plugins/swift/generic/Util.java new file mode 100644 index 00000000..62a253b3 --- /dev/null +++ b/sonar-swift-plugin/src/main/java/org/sonar/plugins/swift/generic/Util.java @@ -0,0 +1,50 @@ +/** + * backelite-sonar-swift-plugin - Enables analysis of Swift projects into SonarQube. + * Copyright © 2015 Backelite (${email}) + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program. If not, see . + */ +package org.sonar.plugins.swift.generic; + +import org.apache.tools.ant.DirectoryScanner; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import java.io.File; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; + +public final class Util { + + private static final Logger LOGGER = LoggerFactory.getLogger(Util.class); + + public static List findReports(final String reportDirectory, final String reportPattern) { + final String[] relPaths = filesMatchingPattern(reportDirectory, reportPattern); + final List reports = new ArrayList(); + for (final String relPath : relPaths) { + reports.add(new File(reportDirectory, relPath)); + } + return reports; + } + + private static String[] filesMatchingPattern(final String reportDirectory, final String reportPattern) { + final DirectoryScanner scanner = new DirectoryScanner(); + scanner.setIncludes(reportPattern.split(",")); + scanner.setBasedir(new File(reportDirectory)); + scanner.scan(); + LOGGER.info("Files found in directory '{}' including '{}': {}", reportDirectory, reportPattern, Arrays.toString(scanner.getIncludedFiles())); + return scanner.getIncludedFiles(); + } +} \ No newline at end of file diff --git a/sonar-swift-plugin/src/main/java/org/sonar/plugins/swift/issues/swiftlint/SwiftLintReportParser.java b/sonar-swift-plugin/src/main/java/org/sonar/plugins/swift/issues/swiftlint/SwiftLintReportParser.java index c6a052e1..aacb56b3 100644 --- a/sonar-swift-plugin/src/main/java/org/sonar/plugins/swift/issues/swiftlint/SwiftLintReportParser.java +++ b/sonar-swift-plugin/src/main/java/org/sonar/plugins/swift/issues/swiftlint/SwiftLintReportParser.java @@ -20,13 +20,11 @@ import org.apache.commons.io.IOUtils; import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import org.sonar.api.batch.SensorContext; import org.sonar.api.batch.fs.FileSystem; import org.sonar.api.batch.fs.InputFile; import org.sonar.api.component.ResourcePerspectives; import org.sonar.api.issue.Issuable; import org.sonar.api.issue.Issue; -import org.sonar.api.resources.Project; import org.sonar.api.rule.RuleKey; import java.io.*; @@ -37,22 +35,22 @@ public class SwiftLintReportParser { private static final Logger LOGGER = LoggerFactory.getLogger(SwiftLintReportParser.class); - private final Project project; - private final SensorContext context; - private final ResourcePerspectives resourcePerspectives; private final FileSystem fileSystem; + private final ResourcePerspectives resourcePerspectives; - public SwiftLintReportParser(final Project project, final SensorContext context, final ResourcePerspectives resourcePerspectives, final FileSystem fileSystem) { - this.project = project; - this.context = context; - this.resourcePerspectives = resourcePerspectives; + private SwiftLintReportParser(final FileSystem fileSystem, final ResourcePerspectives resourcePerspectives) { this.fileSystem = fileSystem; + this.resourcePerspectives = resourcePerspectives; } - public void parseReport(File reportFile) { + public static void parseReport(File report, FileSystem fileSystem, ResourcePerspectives resourcePerspectives) { + new SwiftLintReportParser(fileSystem, resourcePerspectives).parse(report); + } + + private void parse(File report) { try { // Read and parse report - FileReader fr = new FileReader(reportFile); + FileReader fr = new FileReader(report); BufferedReader br = new BufferedReader(fr); String line; @@ -106,4 +104,5 @@ private void recordIssue(final String line) { } } } + } diff --git a/sonar-swift-plugin/src/main/java/org/sonar/plugins/swift/issues/swiftlint/SwiftLintSensor.java b/sonar-swift-plugin/src/main/java/org/sonar/plugins/swift/issues/swiftlint/SwiftLintSensor.java index 297f3147..05ee6456 100644 --- a/sonar-swift-plugin/src/main/java/org/sonar/plugins/swift/issues/swiftlint/SwiftLintSensor.java +++ b/sonar-swift-plugin/src/main/java/org/sonar/plugins/swift/issues/swiftlint/SwiftLintSensor.java @@ -17,74 +17,34 @@ */ package org.sonar.plugins.swift.issues.swiftlint; -import org.apache.tools.ant.DirectoryScanner; import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import org.sonar.api.batch.Sensor; import org.sonar.api.batch.SensorContext; import org.sonar.api.batch.fs.FileSystem; import org.sonar.api.component.ResourcePerspectives; import org.sonar.api.config.Settings; import org.sonar.api.resources.Project; import org.sonar.plugins.swift.SwiftPlugin; -import org.sonar.plugins.swift.lang.core.Swift; +import org.sonar.plugins.swift.generic.SwiftSensor; import java.io.File; +public class SwiftLintSensor extends SwiftSensor { -public class SwiftLintSensor implements Sensor { + private static final Logger LOGGER = LoggerFactory.getLogger(SwiftLintSensor.class); public static final String REPORT_PATH_KEY = SwiftPlugin.PROPERTY_PREFIX + ".swiftlint.report"; public static final String DEFAULT_REPORT_PATH = "sonar-reports/*swiftlint.txt"; + public static final String REPORTS_IN_ROOT_KEY = SwiftPlugin.PROPERTY_PREFIX + ".swiftlint.reportsInRoot"; - private static final Logger LOGGER = LoggerFactory.getLogger(SwiftLintSensor.class); - - private final Settings conf; - private final FileSystem fileSystem; private final ResourcePerspectives resourcePerspectives; - public SwiftLintSensor(final FileSystem fileSystem, final Settings config, final ResourcePerspectives resourcePerspectives) { - this.conf = config; - this.fileSystem = fileSystem; + public SwiftLintSensor(FileSystem fileSystem, Settings settings, ResourcePerspectives resourcePerspectives) { + super(fileSystem, settings, REPORT_PATH_KEY, DEFAULT_REPORT_PATH, REPORTS_IN_ROOT_KEY, false); this.resourcePerspectives = resourcePerspectives; } - @Override - public boolean shouldExecuteOnProject(final Project project) { - - return project.isRoot() && fileSystem.languages().contains(Swift.KEY); - } - @Override - public void analyse(Project module, SensorContext context) { - - final String projectBaseDir = fileSystem.baseDir().getAbsolutePath(); - - SwiftLintReportParser parser = new SwiftLintReportParser(module, context, resourcePerspectives, fileSystem); - parseReportIn(projectBaseDir, parser); + public void parseReport(File report, Project project, SensorContext context) { + SwiftLintReportParser.parseReport(report, fileSystem, resourcePerspectives); } - - private void parseReportIn(final String baseDir, final SwiftLintReportParser parser) { - - DirectoryScanner scanner = new DirectoryScanner(); - scanner.setIncludes(new String[]{reportPath()}); - scanner.setBasedir(baseDir); - scanner.setCaseSensitive(false); - scanner.scan(); - String[] files = scanner.getIncludedFiles(); - - for(String filename : files) { - LOGGER.info("Processing SwiftLint report {}", filename); - parser.parseReport(new File(filename)); - } - - } - - private String reportPath() { - String reportPath = conf.getString(REPORT_PATH_KEY); - if (reportPath == null) { - reportPath = DEFAULT_REPORT_PATH; - } - return reportPath; - } - } diff --git a/sonar-swift-plugin/src/test/java/org/sonar/plugins/swift/coverage/ReportFilesFinderTest.java b/sonar-swift-plugin/src/test/java/org/sonar/plugins/swift/coverage/ReportFilesFinderTest.java deleted file mode 100644 index 9949b7e9..00000000 --- a/sonar-swift-plugin/src/test/java/org/sonar/plugins/swift/coverage/ReportFilesFinderTest.java +++ /dev/null @@ -1,98 +0,0 @@ -/** - * backelite-sonar-swift-plugin - Enables analysis of Swift projects into SonarQube. - * Copyright © 2015 Backelite (${email}) - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this program. If not, see . - */ -package org.sonar.plugins.swift.coverage; - -import java.io.*; -import java.util.*; - -import org.junit.Before; -import org.junit.Test; - -import org.sonar.api.config.Settings; -import org.sonar.plugins.swift.lang.core.Swift; - -import static org.junit.Assert.*; -import static org.mockito.Mockito.*; - -public class ReportFilesFinderTest { - - private static final String TEST_REPORT_PATTERN = "**/cobertura.xml"; - private static final String TEST_MATERIALS_DIR = "./src/test/resources/coverage"; - private static final String TEST_MOD_NAME = "myMod"; - private static final File REPORT_PATH_1 = new File(TEST_MATERIALS_DIR + "/dir1/cobertura.xml"); - private static final File REPORT_PATH_2 = new File(TEST_MATERIALS_DIR + "/dir2/cobertura.xml"); - private static final File REPORT_PATH_3 = new File(TEST_MATERIALS_DIR + "/dir3/cobertura.xml"); - - private Settings settings; - private ReportFilesFinder reportFilesFinder; - - @Before - public void setUp() { - settings = mock(Settings.class); - when(settings.getString(SwiftCoberturaSensor.REPORT_PATTERN_KEY)).thenReturn(TEST_REPORT_PATTERN); - when(settings.getString(TEST_MOD_NAME + "." + SwiftCoberturaSensor.REPORT_PATTERN_KEY)).thenReturn(TEST_REPORT_PATTERN); - - reportFilesFinder = new ReportFilesFinder(settings, SwiftCoberturaSensor.REPORT_PATTERN_KEY, - SwiftCoberturaSensor.DEFAULT_REPORT_PATTERN, SwiftCoberturaSensor.REPORT_DIRECTORY_KEY); - } - - @Test - public void findsFoldersInRootWithNoReportsDirectory() { - assertSameFiles(Arrays.asList(REPORT_PATH_1, REPORT_PATH_2, REPORT_PATH_3), reportFilesFinder.reportsIn(TEST_MATERIALS_DIR)); - } - - @Test - public void findsFoldersInRootWithReportsDirectory() { - when(settings.getString(SwiftCoberturaSensor.REPORT_DIRECTORY_KEY)).thenReturn("/dir1"); - assertSameFiles(Arrays.asList(REPORT_PATH_1), reportFilesFinder.reportsIn(TEST_MATERIALS_DIR)); - } - - @Test - public void findsFoldersInModuleWithNoReportsDirectory() { - assertSameFiles(Arrays.asList(REPORT_PATH_1), reportFilesFinder.reportsIn(TEST_MOD_NAME, TEST_MATERIALS_DIR, TEST_MATERIALS_DIR + "/dir1")); - } - - @Test - public void findsFoldersInModuleWithDefaultReportsDirectory() { - when(settings.getString(SwiftCoberturaSensor.REPORT_DIRECTORY_KEY)).thenReturn("/dir2"); - assertSameFiles(Arrays.asList(REPORT_PATH_2), reportFilesFinder.reportsIn(TEST_MOD_NAME, TEST_MATERIALS_DIR, TEST_MATERIALS_DIR + "/dir1")); - } - - @Test - public void findsFoldersInModuleWithModuleReportsDirectory() { - when(settings.getString(SwiftCoberturaSensor.REPORT_DIRECTORY_KEY)).thenReturn("/dir2"); - when(settings.getString(TEST_MOD_NAME + "." + SwiftCoberturaSensor.REPORT_DIRECTORY_KEY)).thenReturn("/dir3"); - assertSameFiles(Arrays.asList(REPORT_PATH_3), reportFilesFinder.reportsIn(TEST_MOD_NAME, TEST_MATERIALS_DIR, TEST_MATERIALS_DIR + "/dir1")); - } - - private void assertSameFiles(List list1, List list2) { - assertEquals(getPaths(list1), getPaths(list2)); - } - - private Set getPaths(List files) { - Set paths = new HashSet(); - for (File file: files) { - try { - paths.add(file.getCanonicalPath()); - } catch (IOException e) { - fail(e.toString()); - } - } - return paths; - } -} \ No newline at end of file diff --git a/sonar-swift-plugin/src/test/java/org/sonar/plugins/swift/generic/SwiftSensorTest.java b/sonar-swift-plugin/src/test/java/org/sonar/plugins/swift/generic/SwiftSensorTest.java new file mode 100644 index 00000000..6001b3f3 --- /dev/null +++ b/sonar-swift-plugin/src/test/java/org/sonar/plugins/swift/generic/SwiftSensorTest.java @@ -0,0 +1,160 @@ +/** + * backelite-sonar-swift-plugin - Enables analysis of Swift projects into SonarQube. + * Copyright © 2015 Backelite (${email}) + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program. If not, see . + */ +package org.sonar.plugins.swift.generic; + +import java.io.*; +import java.util.*; + +import org.junit.Before; +import org.junit.Test; + +import org.sonar.api.batch.SensorContext; +import org.sonar.api.batch.fs.FileSystem; +import org.sonar.api.config.Settings; +import org.sonar.api.resources.Project; +import org.sonar.plugins.swift.coverage.SwiftCoberturaSensor; +import org.sonar.plugins.swift.generic.SwiftSensor; + +import static org.junit.Assert.*; +import static org.mockito.Mockito.*; + +public class SwiftSensorTest { + + private static final String TEST_REPORT_PATTERN = "**/cobertura.xml"; + private static final String TEST_MATERIALS_DIR = "./src/test/resources/generic"; + private static final String TEST_MOD_NAME = "myMod"; + private static final File ROOT_REPORT = new File(TEST_MATERIALS_DIR + "/dir1/cobertura.xml"); + private static final File MODULE_REPORT = new File(TEST_MATERIALS_DIR + "/" + TEST_MOD_NAME + "/dir2/cobertura.xml"); + + private FileSystem fileSystem; + private Settings settings; + private Project project; + private SensorContext context; + private File baseDir; + private SwiftSensor sensorSpy; + private List parsedReports; + + @Before + public void setUp() { + fileSystem = mock(FileSystem.class); + settings = mock(Settings.class); + project = mock(Project.class); + context = mock(SensorContext.class); + baseDir = mock(File.class); + sensorSpy = spy(new SwiftCoberturaSensor(fileSystem, settings)); + parsedReports = new LinkedList(); + + when(fileSystem.baseDir()).thenReturn(baseDir); + when(settings.getString(SwiftCoberturaSensor.REPORT_PATTERN_KEY)).thenReturn(TEST_REPORT_PATTERN); + when(settings.getString(TEST_MOD_NAME + "." + SwiftCoberturaSensor.REPORT_PATTERN_KEY)).thenReturn(TEST_REPORT_PATTERN); + doAnswer(invocation -> parsedReports.add((File) invocation.getArguments()[0])) + .when(sensorSpy).parseReport(any(File.class), any(Project.class), any(SensorContext.class)); + } + + private void setupRootProject() { + when(project.isRoot()).thenReturn(true); + when(baseDir.getPath()).thenReturn(TEST_MATERIALS_DIR); + } + + private void setupModularProject() { + when(project.isRoot()).thenReturn(false); + when(project.getName()).thenReturn(TEST_MOD_NAME); + when(project.path()).thenReturn(TEST_MOD_NAME); + when(baseDir.getPath()).thenReturn(TEST_MATERIALS_DIR + "/" + TEST_MOD_NAME); + } + + @Test + public void findReportsInRootWithReportsInRootUnset() { + setupRootProject(); + sensorSpy.analyse(project, context); + assertSameFiles(Arrays.asList(ROOT_REPORT, MODULE_REPORT), parsedReports); + } + + @Test + public void findReportsInRootWithReportsInRootFalse() { + setupRootProject(); + when(settings.getString(SwiftCoberturaSensor.REPORTS_IN_ROOT_KEY)).thenReturn("false"); + sensorSpy.analyse(project, context); + assertSameFiles(Arrays.asList(ROOT_REPORT, MODULE_REPORT), parsedReports); + } + + @Test + public void findReportsInRootWithReportsInRootTrue() { + setupRootProject(); + when(settings.getString(SwiftCoberturaSensor.REPORTS_IN_ROOT_KEY)).thenReturn("true"); + sensorSpy.analyse(project, context); + assertSameFiles(Arrays.asList(ROOT_REPORT, MODULE_REPORT), parsedReports); + } + + @Test + public void findReportsInModuleWithDefaultReportsInRootUnset() { + setupModularProject(); + sensorSpy.analyse(project, context); + assertSameFiles(Arrays.asList(MODULE_REPORT), parsedReports); + } + + @Test + public void findReportsInModuleWithDefaultReportsInRootFalse() { + setupModularProject(); + when(settings.getString(SwiftCoberturaSensor.REPORTS_IN_ROOT_KEY)).thenReturn("false"); + sensorSpy.analyse(project, context); + assertSameFiles(Arrays.asList(MODULE_REPORT), parsedReports); + } + + @Test + public void findReportsInModuleWithDefaultReportsInRootTrue() { + setupModularProject(); + when(settings.getString(SwiftCoberturaSensor.REPORTS_IN_ROOT_KEY)).thenReturn("true"); + sensorSpy.analyse(project, context); + assertSameFiles(Arrays.asList(ROOT_REPORT, MODULE_REPORT), parsedReports); + } + + @Test + public void findReportsInModuleWithModuleReportsInRootFalse() { + setupModularProject(); + when(settings.getString(SwiftCoberturaSensor.REPORTS_IN_ROOT_KEY)).thenReturn("true"); + when(settings.getString(TEST_MOD_NAME + "." + SwiftCoberturaSensor.REPORTS_IN_ROOT_KEY)).thenReturn("false"); + sensorSpy.analyse(project, context); + assertSameFiles(Arrays.asList(MODULE_REPORT), parsedReports); + } + + @Test + public void findReportsInModuleWithModuleReportsInRootTrue() { + setupModularProject(); + when(settings.getString(SwiftCoberturaSensor.REPORTS_IN_ROOT_KEY)).thenReturn("false"); + when(settings.getString(TEST_MOD_NAME + "." + SwiftCoberturaSensor.REPORTS_IN_ROOT_KEY)).thenReturn("true"); + sensorSpy.analyse(project, context); + assertSameFiles(Arrays.asList(ROOT_REPORT, MODULE_REPORT), parsedReports); + } + + private void assertSameFiles(List list1, List list2) { + assertEquals(getPaths(list1), getPaths(list2)); + } + + private Set getPaths(List files) { + Set paths = new HashSet(); + for (File file: files) { + try { + paths.add(file.getCanonicalPath()); + } catch (IOException e) { + fail(e.toString()); + } + } + return paths; + } +} diff --git a/sonar-swift-plugin/src/test/resources/coverage/dir3/cobertura.xml b/sonar-swift-plugin/src/test/resources/coverage/dir3/cobertura.xml deleted file mode 100644 index e69de29b..00000000 diff --git a/sonar-swift-plugin/src/test/resources/coverage/dir1/cobertura.xml b/sonar-swift-plugin/src/test/resources/generic/dir1/cobertura.xml similarity index 100% rename from sonar-swift-plugin/src/test/resources/coverage/dir1/cobertura.xml rename to sonar-swift-plugin/src/test/resources/generic/dir1/cobertura.xml diff --git a/sonar-swift-plugin/src/test/resources/coverage/dir2/cobertura.xml b/sonar-swift-plugin/src/test/resources/generic/myMod/dir2/cobertura.xml similarity index 100% rename from sonar-swift-plugin/src/test/resources/coverage/dir2/cobertura.xml rename to sonar-swift-plugin/src/test/resources/generic/myMod/dir2/cobertura.xml From 3c7883e4af2318ffdf298fc1138b7f8452ceab76 Mon Sep 17 00:00:00 2001 From: Isaac Christopher Wang Date: Wed, 15 Aug 2018 09:57:27 -0700 Subject: [PATCH 2/2] Now using StringBuilder in SwiftSensor --- .../main/java/org/sonar/plugins/swift/generic/SwiftSensor.java | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/sonar-swift-plugin/src/main/java/org/sonar/plugins/swift/generic/SwiftSensor.java b/sonar-swift-plugin/src/main/java/org/sonar/plugins/swift/generic/SwiftSensor.java index a2253ced..0cc157f0 100644 --- a/sonar-swift-plugin/src/main/java/org/sonar/plugins/swift/generic/SwiftSensor.java +++ b/sonar-swift-plugin/src/main/java/org/sonar/plugins/swift/generic/SwiftSensor.java @@ -63,7 +63,8 @@ public void analyse(Project project, SensorContext context) { reports = Util.findReports(reportDirectory, reportPattern); } else { - reports = Arrays.asList(new File(reportDirectory + "/" + reportPattern)); + StringBuilder filePathBuilder = new StringBuilder(reportDirectory).append("/").append(reportPattern); + reports = Arrays.asList(new File(filePathBuilder.toString())); } for (final File report : reports) { LOGGER.info("Processing report {}", report);