diff options
author | Julien HENRY <julien.henry@sonarsource.com> | 2014-10-13 11:54:50 +0200 |
---|---|---|
committer | Julien HENRY <julien.henry@sonarsource.com> | 2014-10-14 14:26:45 +0200 |
commit | 6882924ef2d57618e9391c20b1a7a54546a7d9dd (patch) | |
tree | de6469b2b4aa3f9599995186317b037c715024c9 /plugins/sonar-xoo-plugin/src | |
parent | 95551739d6659af8c03250a708f075937e607456 (diff) | |
download | sonarqube-6882924ef2d57618e9391c20b1a7a54546a7d9dd.tar.gz sonarqube-6882924ef2d57618e9391c20b1a7a54546a7d9dd.zip |
SONAR-5389 Refactor dependency API
Diffstat (limited to 'plugins/sonar-xoo-plugin/src')
4 files changed, 228 insertions, 4 deletions
diff --git a/plugins/sonar-xoo-plugin/src/main/java/org/sonar/xoo/XooPlugin.java b/plugins/sonar-xoo-plugin/src/main/java/org/sonar/xoo/XooPlugin.java index d28dc487dec..102aa38dfb1 100644 --- a/plugins/sonar-xoo-plugin/src/main/java/org/sonar/xoo/XooPlugin.java +++ b/plugins/sonar-xoo-plugin/src/main/java/org/sonar/xoo/XooPlugin.java @@ -20,8 +20,21 @@ package org.sonar.xoo; import org.sonar.api.SonarPlugin; -import org.sonar.xoo.lang.*; -import org.sonar.xoo.rule.*; +import org.sonar.xoo.lang.CoveragePerTestSensor; +import org.sonar.xoo.lang.DependencySensor; +import org.sonar.xoo.lang.MeasureSensor; +import org.sonar.xoo.lang.SymbolReferencesSensor; +import org.sonar.xoo.lang.SyntaxHighlightingSensor; +import org.sonar.xoo.lang.TestCaseSensor; +import org.sonar.xoo.lang.XooTokenizerSensor; +import org.sonar.xoo.rule.CreateIssueByInternalKeySensor; +import org.sonar.xoo.rule.OneIssueOnDirPerFileSensor; +import org.sonar.xoo.rule.OneIssuePerLineSensor; +import org.sonar.xoo.rule.XooFakeExporter; +import org.sonar.xoo.rule.XooFakeImporter; +import org.sonar.xoo.rule.XooFakeImporterWithMessages; +import org.sonar.xoo.rule.XooQualityProfile; +import org.sonar.xoo.rule.XooRulesDefinition; import org.sonar.xoo.scm.XooBlameCommand; import org.sonar.xoo.scm.XooScmProvider; @@ -58,11 +71,12 @@ public class XooPlugin extends SonarPlugin { XooTokenizerSensor.class, TestCaseSensor.class, CoveragePerTestSensor.class, + DependencySensor.class, OneIssuePerLineSensor.class, OneIssueOnDirPerFileSensor.class, CreateIssueByInternalKeySensor.class - ); + ); } } diff --git a/plugins/sonar-xoo-plugin/src/main/java/org/sonar/xoo/lang/DependencySensor.java b/plugins/sonar-xoo-plugin/src/main/java/org/sonar/xoo/lang/DependencySensor.java new file mode 100644 index 00000000000..929092da866 --- /dev/null +++ b/plugins/sonar-xoo-plugin/src/main/java/org/sonar/xoo/lang/DependencySensor.java @@ -0,0 +1,103 @@ +/* + * SonarQube, open source software quality management tool. + * Copyright (C) 2008-2014 SonarSource + * mailto:contact AT sonarsource DOT com + * + * SonarQube 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. + * + * SonarQube 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, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ +package org.sonar.xoo.lang; + +import com.google.common.base.Splitter; +import org.apache.commons.io.FileUtils; +import org.apache.commons.lang.StringUtils; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.sonar.api.batch.fs.FilePredicates; +import org.sonar.api.batch.fs.FileSystem; +import org.sonar.api.batch.fs.InputFile; +import org.sonar.api.batch.sensor.Sensor; +import org.sonar.api.batch.sensor.SensorContext; +import org.sonar.api.batch.sensor.SensorDescriptor; +import org.sonar.xoo.Xoo; + +import java.io.File; +import java.io.IOException; +import java.util.Iterator; +import java.util.List; + +/** + * Parse files *.xoo.deps + */ +public class DependencySensor implements Sensor { + + private static final Logger LOG = LoggerFactory.getLogger(DependencySensor.class); + + private static final String DEPS_EXTENSION = ".deps"; + + private void processDependencies(InputFile inputFile, SensorContext context) { + File ioFile = inputFile.file(); + File depsFile = new File(ioFile.getParentFile(), ioFile.getName() + DEPS_EXTENSION); + if (depsFile.exists()) { + LOG.debug("Processing " + depsFile.getAbsolutePath()); + try { + List<String> lines = FileUtils.readLines(depsFile, context.fileSystem().encoding().name()); + int lineNumber = 0; + for (String line : lines) { + lineNumber++; + if (StringUtils.isBlank(line) || line.startsWith("#")) { + continue; + } + processLine(depsFile, lineNumber, context, line, inputFile); + } + } catch (IOException e) { + throw new IllegalStateException(e); + } + } + } + + private void processLine(File coverPerTest, int lineNumber, SensorContext context, String line, InputFile file) { + try { + Iterator<String> split = Splitter.on(":").split(line).iterator(); + String otherFileRelativePath = split.next(); + FileSystem fs = context.fileSystem(); + InputFile otherFile = fs.inputFile(fs.predicates().hasRelativePath(otherFileRelativePath)); + int weight = Integer.parseInt(split.next()); + context.newDependency() + .from(file) + .to(otherFile) + .weight(weight) + .save(); + } catch (Exception e) { + throw new IllegalStateException("Error processing line " + lineNumber + " of file " + coverPerTest.getAbsolutePath(), e); + } + } + + @Override + public void describe(SensorDescriptor descriptor) { + descriptor + .name("Xoo Dependency Sensor") + .workOnLanguages(Xoo.KEY) + .workOnFileTypes(InputFile.Type.MAIN); + } + + @Override + public void execute(SensorContext context) { + FileSystem fs = context.fileSystem(); + FilePredicates p = fs.predicates(); + for (InputFile file : fs.inputFiles(p.and(p.hasLanguages(Xoo.KEY), p.hasType(InputFile.Type.MAIN)))) { + processDependencies(file, context); + } + } +} diff --git a/plugins/sonar-xoo-plugin/src/test/java/org/sonar/xoo/XooPluginTest.java b/plugins/sonar-xoo-plugin/src/test/java/org/sonar/xoo/XooPluginTest.java index 193f3b95349..d5913f277a8 100644 --- a/plugins/sonar-xoo-plugin/src/test/java/org/sonar/xoo/XooPluginTest.java +++ b/plugins/sonar-xoo-plugin/src/test/java/org/sonar/xoo/XooPluginTest.java @@ -27,6 +27,6 @@ public class XooPluginTest { @Test public void provide_extensions() { - assertThat(new XooPlugin().getExtensions()).hasSize(17); + assertThat(new XooPlugin().getExtensions()).hasSize(18); } } diff --git a/plugins/sonar-xoo-plugin/src/test/java/org/sonar/xoo/lang/DependencySensorTest.java b/plugins/sonar-xoo-plugin/src/test/java/org/sonar/xoo/lang/DependencySensorTest.java new file mode 100644 index 00000000000..11ed815ac3c --- /dev/null +++ b/plugins/sonar-xoo-plugin/src/test/java/org/sonar/xoo/lang/DependencySensorTest.java @@ -0,0 +1,107 @@ +/* + * SonarQube, open source software quality management tool. + * Copyright (C) 2008-2014 SonarSource + * mailto:contact AT sonarsource DOT com + * + * SonarQube 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. + * + * SonarQube 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, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ +package org.sonar.xoo.lang; + +import org.apache.commons.io.FileUtils; +import org.junit.Before; +import org.junit.Rule; +import org.junit.Test; +import org.junit.rules.TemporaryFolder; +import org.mockito.invocation.InvocationOnMock; +import org.mockito.stubbing.Answer; +import org.sonar.api.batch.fs.InputFile.Type; +import org.sonar.api.batch.fs.internal.DefaultFileSystem; +import org.sonar.api.batch.fs.internal.DefaultInputFile; +import org.sonar.api.batch.sensor.SensorContext; +import org.sonar.api.batch.sensor.SensorStorage; +import org.sonar.api.batch.sensor.dependency.Dependency; +import org.sonar.api.batch.sensor.dependency.internal.DefaultDependency; +import org.sonar.api.batch.sensor.internal.DefaultSensorDescriptor; + +import java.io.File; +import java.io.IOException; + +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.verify; +import static org.mockito.Mockito.when; + +public class DependencySensorTest { + + private DependencySensor sensor; + private SensorContext context = mock(SensorContext.class); + private DefaultFileSystem fileSystem; + + @Rule + public TemporaryFolder temp = new TemporaryFolder(); + private File baseDir; + + @Before + public void prepare() throws IOException { + baseDir = temp.newFolder(); + sensor = new DependencySensor(); + fileSystem = new DefaultFileSystem(); + when(context.fileSystem()).thenReturn(fileSystem); + } + + @Test + public void testDescriptor() { + sensor.describe(new DefaultSensorDescriptor()); + } + + @Test + public void testNoExecutionIfNoDepsFile() { + DefaultInputFile file = new DefaultInputFile("foo", "src/foo.xoo").setAbsolutePath(new File(baseDir, "src/foo.xoo").getAbsolutePath()).setLanguage("xoo") + .setType(Type.MAIN); + fileSystem.add(file); + sensor.execute(context); + } + + @Test + public void testExecution() throws IOException { + File deps = new File(baseDir, "src/foo.xoo.deps"); + FileUtils.write(deps, "src/foo2.xoo:2\nsrc2/foo3.xoo:6\n\n#comment"); + DefaultInputFile inputFile1 = new DefaultInputFile("foo", "src/foo.xoo").setAbsolutePath(new File(baseDir, "src/foo.xoo").getAbsolutePath()).setLanguage("xoo"); + DefaultInputFile inputFile2 = new DefaultInputFile("foo", "src/foo2.xoo").setAbsolutePath(new File(baseDir, "src/foo2.xoo").getAbsolutePath()).setLanguage("xoo"); + DefaultInputFile inputFile3 = new DefaultInputFile("foo", "src2/foo3.xoo").setAbsolutePath(new File(baseDir, "src2/foo3.xoo").getAbsolutePath()).setLanguage("xoo"); + fileSystem.add(inputFile1); + fileSystem.add(inputFile2); + fileSystem.add(inputFile3); + + final SensorStorage sensorStorage = mock(SensorStorage.class); + + when(context.newDependency()).thenAnswer(new Answer<Dependency>() { + @Override + public Dependency answer(InvocationOnMock invocation) throws Throwable { + return new DefaultDependency(sensorStorage); + } + }); + + sensor.execute(context); + + verify(sensorStorage).store(new DefaultDependency() + .from(inputFile1) + .to(inputFile2) + .weight(2)); + verify(sensorStorage).store(new DefaultDependency() + .from(inputFile1) + .to(inputFile3) + .weight(6)); + } +} |