aboutsummaryrefslogtreecommitdiffstats
path: root/plugins
diff options
context:
space:
mode:
authorJulien HENRY <julien.henry@sonarsource.com>2014-09-25 13:48:35 +0200
committerJulien HENRY <julien.henry@sonarsource.com>2014-10-02 17:52:23 +0200
commitcb639f864815f8dfd7dbbd0f21fd4ad08b7db8cc (patch)
tree89798ee35e415d2a024e320e6369636654780520 /plugins
parenta1cb900c90178390776c987462a4f2501b1e4e2c (diff)
downloadsonarqube-cb639f864815f8dfd7dbbd0f21fd4ad08b7db8cc.tar.gz
sonarqube-cb639f864815f8dfd7dbbd0f21fd4ad08b7db8cc.zip
SONAR-5644 Rework SCM API
Diffstat (limited to 'plugins')
-rw-r--r--plugins/sonar-git-plugin/src/main/java/org/sonar/plugins/scm/git/GitBlameCommand.java96
-rw-r--r--plugins/sonar-git-plugin/src/main/java/org/sonar/plugins/scm/git/GitBlameConsumer.java (renamed from plugins/sonar-git-plugin/src/main/java/org/sonar/plugins/scm/git/SonarGitBlameConsumer.java)21
-rw-r--r--plugins/sonar-git-plugin/src/main/java/org/sonar/plugins/scm/git/GitPlugin.java3
-rw-r--r--plugins/sonar-git-plugin/src/main/java/org/sonar/plugins/scm/git/GitScmProvider.java65
-rw-r--r--plugins/sonar-git-plugin/src/test/java/org/sonar/plugins/scm/git/GitBlameCommandTest.java108
-rw-r--r--plugins/sonar-git-plugin/src/test/java/org/sonar/plugins/scm/git/GitPluginTest.java2
-rw-r--r--plugins/sonar-git-plugin/src/test/java/org/sonar/plugins/scm/git/GitScmProviderTest.java53
-rw-r--r--plugins/sonar-git-plugin/src/test/java/org/sonar/plugins/scm/git/medium/GitMediumTest.java119
-rw-r--r--plugins/sonar-xoo-plugin/src/main/java/org/sonar/xoo/XooPlugin.java4
-rw-r--r--plugins/sonar-xoo-plugin/src/main/java/org/sonar/xoo/lang/package-info.java23
-rw-r--r--plugins/sonar-xoo-plugin/src/main/java/org/sonar/xoo/rule/OneIssuePerLineSensor.java2
-rw-r--r--plugins/sonar-xoo-plugin/src/main/java/org/sonar/xoo/scm/XooBlameCommand.java (renamed from plugins/sonar-xoo-plugin/src/main/java/org/sonar/xoo/lang/XooScmProvider.java)36
-rw-r--r--plugins/sonar-xoo-plugin/src/main/java/org/sonar/xoo/scm/XooScmProvider.java43
-rw-r--r--plugins/sonar-xoo-plugin/src/main/java/org/sonar/xoo/scm/package-info.java23
-rw-r--r--plugins/sonar-xoo-plugin/src/test/java/org/sonar/xoo/XooPluginTest.java2
-rw-r--r--plugins/sonar-xoo-plugin/src/test/java/org/sonar/xoo/rule/OneIssuePerLineSensorTest.java104
-rw-r--r--plugins/sonar-xoo-plugin/src/test/java/org/sonar/xoo/scm/XooBlameCommandTest.java75
17 files changed, 560 insertions, 219 deletions
diff --git a/plugins/sonar-git-plugin/src/main/java/org/sonar/plugins/scm/git/GitBlameCommand.java b/plugins/sonar-git-plugin/src/main/java/org/sonar/plugins/scm/git/GitBlameCommand.java
new file mode 100644
index 00000000000..0d8b447cdd8
--- /dev/null
+++ b/plugins/sonar-git-plugin/src/main/java/org/sonar/plugins/scm/git/GitBlameCommand.java
@@ -0,0 +1,96 @@
+/*
+ * 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.plugins.scm.git;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.sonar.api.batch.fs.FileSystem;
+import org.sonar.api.batch.fs.InputFile;
+import org.sonar.api.batch.scm.BlameCommand;
+import org.sonar.api.utils.command.Command;
+import org.sonar.api.utils.command.CommandExecutor;
+import org.sonar.api.utils.command.StreamConsumer;
+
+import java.io.File;
+
+public class GitBlameCommand implements BlameCommand {
+
+ private static final Logger LOG = LoggerFactory.getLogger(GitBlameCommand.class);
+ private final CommandExecutor commandExecutor;
+
+ public GitBlameCommand() {
+ this(CommandExecutor.create());
+ }
+
+ GitBlameCommand(CommandExecutor commandExecutor) {
+ this.commandExecutor = commandExecutor;
+ }
+
+ @Override
+ public void blame(FileSystem fs, Iterable<InputFile> files, BlameResult result) {
+ for (InputFile inputFile : files) {
+ String filename = inputFile.relativePath();
+ Command cl = createCommandLine(fs.baseDir(), filename);
+ GitBlameConsumer consumer = new GitBlameConsumer(LOG);
+ StringStreamConsumer stderr = new StringStreamConsumer();
+
+ int exitCode = execute(cl, consumer, stderr);
+ if (exitCode != 0) {
+ throw new IllegalStateException("The git blame command [" + cl.toString() + "] failed: " + stderr.getOutput());
+ }
+ result.add(inputFile, consumer.getLines());
+ }
+ }
+
+ public int execute(Command cl, StreamConsumer consumer, StreamConsumer stderr) {
+ LOG.info("Executing: " + cl);
+ LOG.info("Working directory: " + cl.getDirectory().getAbsolutePath());
+
+ return commandExecutor.execute(cl, consumer, stderr, 10 * 1000);
+ }
+
+ private Command createCommandLine(File workingDirectory, String filename) {
+ Command cl = Command.create("git");
+ cl.addArgument("blame");
+ if (workingDirectory != null) {
+ cl.setDirectory(workingDirectory);
+ }
+ cl.addArgument("--porcelain");
+ cl.addArgument(filename);
+ cl.addArgument("-w");
+ return cl;
+ }
+
+ private static class StringStreamConsumer implements StreamConsumer {
+ private StringBuffer string = new StringBuffer();
+
+ private String ls = System.getProperty("line.separator");
+
+ @Override
+ public void consumeLine(String line) {
+ string.append(line + ls);
+ }
+
+ public String getOutput() {
+ return string.toString();
+ }
+ }
+
+}
diff --git a/plugins/sonar-git-plugin/src/main/java/org/sonar/plugins/scm/git/SonarGitBlameConsumer.java b/plugins/sonar-git-plugin/src/main/java/org/sonar/plugins/scm/git/GitBlameConsumer.java
index 3102b00f105..1c7ef86cb98 100644
--- a/plugins/sonar-git-plugin/src/main/java/org/sonar/plugins/scm/git/SonarGitBlameConsumer.java
+++ b/plugins/sonar-git-plugin/src/main/java/org/sonar/plugins/scm/git/GitBlameConsumer.java
@@ -1,23 +1,22 @@
/*
- * Sonar SCM Activity Plugin
- * Copyright (C) 2010 SonarSource
- * dev@sonar.codehaus.org
+ * SonarQube, open source software quality management tool.
+ * Copyright (C) 2008-2014 SonarSource
+ * mailto:contact AT sonarsource DOT com
*
- * This program is free software; you can redistribute it and/or
+ * 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.
*
- * This program is distributed in the hope that it will be useful,
+ * 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 02
+ * 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.plugins.scm.git;
import com.google.common.annotations.VisibleForTesting;
@@ -45,7 +44,7 @@ import java.util.Map;
*
* @since 1.5.1
*/
-public class SonarGitBlameConsumer implements StreamConsumer {
+public class GitBlameConsumer implements StreamConsumer {
private static final String GIT_COMMITTER_PREFIX = "committer";
private static final String GIT_COMMITTER_TIME = GIT_COMMITTER_PREFIX + "-time ";
@@ -78,7 +77,7 @@ public class SonarGitBlameConsumer implements StreamConsumer {
return logger;
}
- public SonarGitBlameConsumer(Logger logger) {
+ public GitBlameConsumer(Logger logger) {
this.logger = logger;
}
diff --git a/plugins/sonar-git-plugin/src/main/java/org/sonar/plugins/scm/git/GitPlugin.java b/plugins/sonar-git-plugin/src/main/java/org/sonar/plugins/scm/git/GitPlugin.java
index 033cef7b7de..e5c12c42900 100644
--- a/plugins/sonar-git-plugin/src/main/java/org/sonar/plugins/scm/git/GitPlugin.java
+++ b/plugins/sonar-git-plugin/src/main/java/org/sonar/plugins/scm/git/GitPlugin.java
@@ -28,7 +28,8 @@ public final class GitPlugin extends SonarPlugin {
public List getExtensions() {
return ImmutableList.of(
- GitScmProvider.class);
+ GitScmProvider.class,
+ GitBlameCommand.class);
}
}
diff --git a/plugins/sonar-git-plugin/src/main/java/org/sonar/plugins/scm/git/GitScmProvider.java b/plugins/sonar-git-plugin/src/main/java/org/sonar/plugins/scm/git/GitScmProvider.java
index 7fbfe516c20..a0dfeb92601 100644
--- a/plugins/sonar-git-plugin/src/main/java/org/sonar/plugins/scm/git/GitScmProvider.java
+++ b/plugins/sonar-git-plugin/src/main/java/org/sonar/plugins/scm/git/GitScmProvider.java
@@ -19,20 +19,18 @@
*/
package org.sonar.plugins.scm.git;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-import org.sonar.api.batch.fs.FileSystem;
-import org.sonar.api.batch.fs.InputFile;
+import org.sonar.api.batch.scm.BlameCommand;
import org.sonar.api.batch.scm.ScmProvider;
-import org.sonar.api.utils.command.Command;
-import org.sonar.api.utils.command.CommandExecutor;
-import org.sonar.api.utils.command.StreamConsumer;
import java.io.File;
-public class GitScmProvider implements ScmProvider {
+public class GitScmProvider extends ScmProvider {
- private static final Logger LOG = LoggerFactory.getLogger(GitScmProvider.class);
+ private GitBlameCommand blameCommand;
+
+ public GitScmProvider(GitBlameCommand blameCommand) {
+ this.blameCommand = blameCommand;
+ }
@Override
public String key() {
@@ -45,53 +43,8 @@ public class GitScmProvider implements ScmProvider {
}
@Override
- public void blame(FileSystem fs, Iterable<InputFile> files, BlameResult result) {
- for (InputFile inputFile : files) {
- String filename = inputFile.relativePath();
- Command cl = createCommandLine(fs.baseDir(), filename);
- SonarGitBlameConsumer consumer = new SonarGitBlameConsumer(LOG);
- StringStreamConsumer stderr = new StringStreamConsumer();
-
- int exitCode = execute(cl, consumer, stderr);
- if (exitCode != 0) {
- throw new IllegalStateException("The git blame command [" + cl.toString() + "] failed: " + stderr.getOutput());
- }
- result.add(inputFile, consumer.getLines());
- }
- }
-
- public static int execute(Command cl, StreamConsumer consumer, StreamConsumer stderr) {
- LOG.info("Executing: " + cl);
- LOG.info("Working directory: " + cl.getDirectory().getAbsolutePath());
-
- return CommandExecutor.create().execute(cl, consumer, stderr, 10 * 1000);
- }
-
- private static Command createCommandLine(File workingDirectory, String filename) {
- Command cl = Command.create("git");
- cl.addArgument("blame");
- if (workingDirectory != null) {
- cl.setDirectory(workingDirectory);
- }
- cl.addArgument("--porcelain");
- cl.addArgument(filename);
- cl.addArgument("-w");
- return cl;
- }
-
- private static class StringStreamConsumer implements StreamConsumer {
- private StringBuffer string = new StringBuffer();
-
- private String ls = System.getProperty("line.separator");
-
- @Override
- public void consumeLine(String line) {
- string.append(line + ls);
- }
-
- public String getOutput() {
- return string.toString();
- }
+ public BlameCommand blameCommand() {
+ return this.blameCommand;
}
}
diff --git a/plugins/sonar-git-plugin/src/test/java/org/sonar/plugins/scm/git/GitBlameCommandTest.java b/plugins/sonar-git-plugin/src/test/java/org/sonar/plugins/scm/git/GitBlameCommandTest.java
new file mode 100644
index 00000000000..805b0222af3
--- /dev/null
+++ b/plugins/sonar-git-plugin/src/test/java/org/sonar/plugins/scm/git/GitBlameCommandTest.java
@@ -0,0 +1,108 @@
+/*
+ * 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.plugins.scm.git;
+
+import org.apache.commons.io.FileUtils;
+import org.junit.Before;
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.rules.ExpectedException;
+import org.junit.rules.TemporaryFolder;
+import org.mockito.invocation.InvocationOnMock;
+import org.mockito.stubbing.Answer;
+import org.sonar.api.batch.fs.InputFile;
+import org.sonar.api.batch.fs.internal.DefaultFileSystem;
+import org.sonar.api.batch.fs.internal.DefaultInputFile;
+import org.sonar.api.batch.scm.BlameCommand.BlameResult;
+import org.sonar.api.batch.scm.BlameLine;
+import org.sonar.api.utils.DateUtils;
+import org.sonar.api.utils.command.Command;
+import org.sonar.api.utils.command.CommandExecutor;
+import org.sonar.api.utils.command.StreamConsumer;
+
+import java.io.File;
+import java.io.IOException;
+import java.util.Arrays;
+
+import static org.mockito.Matchers.any;
+import static org.mockito.Matchers.anyLong;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
+
+public class GitBlameCommandTest {
+
+ @Rule
+ public TemporaryFolder temp = new TemporaryFolder();
+
+ @Rule
+ public ExpectedException thrown = ExpectedException.none();
+
+ private DefaultFileSystem fs;
+ private File baseDir;
+
+ @Before
+ public void prepare() throws IOException {
+ baseDir = temp.newFolder();
+ fs = new DefaultFileSystem();
+ fs.setBaseDir(baseDir);
+ }
+
+ @Test
+ public void testParsingOfOutput() throws IOException {
+ File source = new File(baseDir, "src/foo.xoo");
+ FileUtils.write(source, "sample content");
+ DefaultInputFile inputFile = new DefaultInputFile("foo", "src/foo.xoo").setAbsolutePath(new File(baseDir, "src/foo.xoo").getAbsolutePath());
+ fs.add(inputFile);
+
+ BlameResult result = mock(BlameResult.class);
+ CommandExecutor commandExecutor = mock(CommandExecutor.class);
+
+ when(commandExecutor.execute(any(Command.class), any(StreamConsumer.class), any(StreamConsumer.class), anyLong())).thenAnswer(new Answer<Integer>() {
+
+ @Override
+ public Integer answer(InvocationOnMock invocation) throws Throwable {
+ StreamConsumer outConsumer = (StreamConsumer) invocation.getArguments()[1];
+ outConsumer.consumeLine("2c68c473da7fc293e12ca50f19380c5118be7ead 68 54 1");
+ outConsumer.consumeLine("author Simon Brandhof");
+ outConsumer.consumeLine("author-mail <simon.brandhof@gmail.com>");
+ outConsumer.consumeLine("author-time 1312534171");
+ outConsumer.consumeLine("author-tz +0200");
+ outConsumer.consumeLine("committer Simon Brandhof");
+ outConsumer.consumeLine("committer-mail <simon.brandhof@gmail.com>");
+ outConsumer.consumeLine("committer-time 1312534171");
+ outConsumer.consumeLine("committer-tz +0200");
+ outConsumer.consumeLine("summary Move to nexus.codehaus.org + configuration of maven release plugin is back");
+ outConsumer.consumeLine("previous 1bec1c3a77f6957175be13e4433110f7fc8e387e pom.xml");
+ outConsumer.consumeLine("filename pom.xml");
+ outConsumer.consumeLine("\t<id>codehaus-nexus-staging</id>");
+ outConsumer.consumeLine("2c68c473da7fc293e12ca50f19380c5118be7ead 72 60 1");
+ outConsumer.consumeLine("\t<url>${sonar.snapshotRepository.url}</url>");
+ return 0;
+ }
+ });
+
+ new GitBlameCommand(commandExecutor).blame(fs, Arrays.<InputFile>asList(inputFile), result);
+ verify(result).add(inputFile,
+ Arrays.asList(new BlameLine(DateUtils.parseDateTime("2011-08-05T10:49:31+0200"), "2c68c473da7fc293e12ca50f19380c5118be7ead", "simon.brandhof@gmail.com"),
+ new BlameLine(DateUtils.parseDateTime("2011-08-05T10:49:31+0200"), "2c68c473da7fc293e12ca50f19380c5118be7ead", "simon.brandhof@gmail.com")));
+ }
+
+}
diff --git a/plugins/sonar-git-plugin/src/test/java/org/sonar/plugins/scm/git/GitPluginTest.java b/plugins/sonar-git-plugin/src/test/java/org/sonar/plugins/scm/git/GitPluginTest.java
index d65e0eb5844..d175cdcbe91 100644
--- a/plugins/sonar-git-plugin/src/test/java/org/sonar/plugins/scm/git/GitPluginTest.java
+++ b/plugins/sonar-git-plugin/src/test/java/org/sonar/plugins/scm/git/GitPluginTest.java
@@ -27,6 +27,6 @@ public class GitPluginTest {
@Test
public void getExtensions() {
- assertThat(new GitPlugin().getExtensions()).hasSize(1);
+ assertThat(new GitPlugin().getExtensions()).hasSize(2);
}
}
diff --git a/plugins/sonar-git-plugin/src/test/java/org/sonar/plugins/scm/git/GitScmProviderTest.java b/plugins/sonar-git-plugin/src/test/java/org/sonar/plugins/scm/git/GitScmProviderTest.java
new file mode 100644
index 00000000000..9bc5801d055
--- /dev/null
+++ b/plugins/sonar-git-plugin/src/test/java/org/sonar/plugins/scm/git/GitScmProviderTest.java
@@ -0,0 +1,53 @@
+/*
+ * 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.plugins.scm.git;
+
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.rules.TemporaryFolder;
+
+import java.io.File;
+import java.io.IOException;
+
+import static org.fest.assertions.Assertions.assertThat;
+
+public class GitScmProviderTest {
+
+ @Rule
+ public TemporaryFolder temp = new TemporaryFolder();
+
+ @Test
+ public void sanityCheck() {
+ assertThat(new GitScmProvider(null).key()).isEqualTo("git");
+ GitBlameCommand blameCommand = new GitBlameCommand();
+ assertThat(new GitScmProvider(blameCommand).blameCommand()).isEqualTo(blameCommand);
+ }
+
+ @Test
+ public void testAutodetection() throws IOException {
+ File baseDirEmpty = temp.newFolder();
+ assertThat(new GitScmProvider(null).supports(baseDirEmpty)).isFalse();
+
+ File gitBaseDir = temp.newFolder();
+ new File(gitBaseDir, ".git").mkdir();
+ assertThat(new GitScmProvider(null).supports(gitBaseDir)).isTrue();
+ }
+
+}
diff --git a/plugins/sonar-git-plugin/src/test/java/org/sonar/plugins/scm/git/medium/GitMediumTest.java b/plugins/sonar-git-plugin/src/test/java/org/sonar/plugins/scm/git/medium/GitMediumTest.java
deleted file mode 100644
index a1f34593f1b..00000000000
--- a/plugins/sonar-git-plugin/src/test/java/org/sonar/plugins/scm/git/medium/GitMediumTest.java
+++ /dev/null
@@ -1,119 +0,0 @@
-/*
- * 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.plugins.scm.git.medium;
-
-import com.google.common.collect.ImmutableMap;
-import org.apache.commons.io.FileUtils;
-import org.junit.After;
-import org.junit.Before;
-import org.junit.Rule;
-import org.junit.Test;
-import org.junit.rules.ExpectedException;
-import org.junit.rules.TemporaryFolder;
-import org.sonar.api.batch.fs.InputFile;
-import org.sonar.api.batch.sensor.duplication.DuplicationGroup;
-import org.sonar.batch.mediumtest.BatchMediumTester;
-import org.sonar.batch.mediumtest.BatchMediumTester.TaskResult;
-import org.sonar.plugins.scm.git.GitPlugin;
-import org.sonar.xoo.XooPlugin;
-
-import java.io.File;
-import java.io.IOException;
-import java.util.List;
-
-import static org.fest.assertions.Assertions.assertThat;
-
-public class GitMediumTest {
-
- @Rule
- public TemporaryFolder temp = new TemporaryFolder();
-
- @Rule
- public ExpectedException thrown = ExpectedException.none();
-
- public BatchMediumTester tester = BatchMediumTester.builder()
- .registerPlugin("xoo", new XooPlugin())
- .registerPlugin("git", new GitPlugin())
- .addDefaultQProfile("xoo", "Sonar Way")
- .bootstrapProperties(ImmutableMap.of("sonar.analysis.mode", "sensor"))
- .build();
-
- private File baseDir;
-
- private ImmutableMap.Builder<String, String> builder;
-
- @Before
- public void prepare() throws IOException {
- tester.start();
-
- baseDir = temp.newFolder();
-
- builder = ImmutableMap.<String, String>builder()
- .put("sonar.task", "scan")
- .put("sonar.projectBaseDir", baseDir.getAbsolutePath())
- .put("sonar.projectKey", "com.foo.project")
- .put("sonar.projectName", "Foo Project")
- .put("sonar.projectVersion", "1.0-SNAPSHOT")
- .put("sonar.projectDescription", "Description of Foo Project");
- }
-
- @After
- public void stop() {
- tester.stop();
- }
-
- @Test
- public void testDuplications() throws IOException {
- File srcDir = new File(baseDir, "src");
- srcDir.mkdir();
-
- String duplicatedStuff = "Sample xoo\ncontent\nfoo\nbar\ntoto\ntiti\nfoo\nbar\ntoto\ntiti\nbar\ntoto\ntiti\nfoo\nbar\ntoto\ntiti";
-
- File xooFile1 = new File(srcDir, "sample1.xoo");
- FileUtils.write(xooFile1, duplicatedStuff);
-
- File xooFile2 = new File(srcDir, "sample2.xoo");
- FileUtils.write(xooFile2, duplicatedStuff);
-
- TaskResult result = tester.newTask()
- .properties(builder
- .put("sonar.sources", "src")
- .put("sonar.cpd.xoo.minimumTokens", "10")
- .put("sonar.verbose", "true")
- .build())
- .start();
-
- assertThat(result.inputFiles()).hasSize(2);
-
- // 4 measures per file
- assertThat(result.measures()).hasSize(8);
-
- InputFile inputFile = result.inputFiles().get(0);
- // One clone group
- List<DuplicationGroup> duplicationGroups = result.duplicationsFor(inputFile);
- assertThat(duplicationGroups).hasSize(1);
-
- DuplicationGroup cloneGroup = duplicationGroups.get(0);
- assertThat(cloneGroup.duplicates()).hasSize(1);
- assertThat(cloneGroup.originBlock().startLine()).isEqualTo(1);
- assertThat(cloneGroup.originBlock().length()).isEqualTo(17);
- }
-
-}
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 e1988ac37ab..148a6df0b7c 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
@@ -25,13 +25,14 @@ 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.XooScmProvider;
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.XooQualityProfile;
import org.sonar.xoo.rule.XooRulesDefinition;
+import org.sonar.xoo.scm.XooBlameCommand;
+import org.sonar.xoo.scm.XooScmProvider;
import java.util.Arrays;
import java.util.List;
@@ -53,6 +54,7 @@ public class XooPlugin extends SonarPlugin {
// SCM
XooScmProvider.class,
+ XooBlameCommand.class,
// sensors
MeasureSensor.class,
diff --git a/plugins/sonar-xoo-plugin/src/main/java/org/sonar/xoo/lang/package-info.java b/plugins/sonar-xoo-plugin/src/main/java/org/sonar/xoo/lang/package-info.java
new file mode 100644
index 00000000000..9963cc34bd9
--- /dev/null
+++ b/plugins/sonar-xoo-plugin/src/main/java/org/sonar/xoo/lang/package-info.java
@@ -0,0 +1,23 @@
+/*
+ * 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.
+ */
+@ParametersAreNonnullByDefault
+package org.sonar.xoo.lang;
+
+import javax.annotation.ParametersAreNonnullByDefault;
diff --git a/plugins/sonar-xoo-plugin/src/main/java/org/sonar/xoo/rule/OneIssuePerLineSensor.java b/plugins/sonar-xoo-plugin/src/main/java/org/sonar/xoo/rule/OneIssuePerLineSensor.java
index 7a11c639e38..31db08c01f2 100644
--- a/plugins/sonar-xoo-plugin/src/main/java/org/sonar/xoo/rule/OneIssuePerLineSensor.java
+++ b/plugins/sonar-xoo-plugin/src/main/java/org/sonar/xoo/rule/OneIssuePerLineSensor.java
@@ -32,7 +32,7 @@ public class OneIssuePerLineSensor implements Sensor {
public static final String RULE_KEY = "OneIssuePerLine";
private static final String EFFORT_TO_FIX_PROPERTY = "sonar.oneIssuePerLine.effortToFix";
- private static final String FORCE_SEVERITY_PROPERTY = "sonar.oneIssuePerLine.forceSeverity";
+ public static final String FORCE_SEVERITY_PROPERTY = "sonar.oneIssuePerLine.forceSeverity";
@Override
public void describe(SensorDescriptor descriptor) {
diff --git a/plugins/sonar-xoo-plugin/src/main/java/org/sonar/xoo/lang/XooScmProvider.java b/plugins/sonar-xoo-plugin/src/main/java/org/sonar/xoo/scm/XooBlameCommand.java
index 895d47dfbbe..7d492cc315b 100644
--- a/plugins/sonar-xoo-plugin/src/main/java/org/sonar/xoo/lang/XooScmProvider.java
+++ b/plugins/sonar-xoo-plugin/src/main/java/org/sonar/xoo/scm/XooBlameCommand.java
@@ -17,18 +17,16 @@
* 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;
+package org.sonar.xoo.scm;
import com.google.common.annotations.VisibleForTesting;
import com.google.common.base.Charsets;
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.FileSystem;
import org.sonar.api.batch.fs.InputFile;
+import org.sonar.api.batch.scm.BlameCommand;
import org.sonar.api.batch.scm.BlameLine;
-import org.sonar.api.batch.scm.ScmProvider;
-import org.sonar.api.config.Settings;
import org.sonar.api.utils.DateUtils;
import java.io.File;
@@ -37,37 +35,19 @@ import java.util.ArrayList;
import java.util.Date;
import java.util.List;
-public class XooScmProvider implements ScmProvider {
-
- private static final Logger LOG = LoggerFactory.getLogger(XooScmProvider.class);
+public class XooBlameCommand implements BlameCommand {
private static final String SCM_EXTENSION = ".scm";
- private final Settings settings;
-
- public XooScmProvider(Settings settings) {
- this.settings = settings;
- }
-
- @Override
- public String key() {
- return "xoo";
- }
-
- @Override
- public boolean supports(File baseDir) {
- return false;
- }
-
@Override
- public void blame(Iterable<InputFile> files, BlameResult handler) {
+ public void blame(FileSystem fs, Iterable<InputFile> files, BlameResult result) {
for (InputFile inputFile : files) {
- processFile(inputFile, handler);
+ processFile(inputFile, result);
}
}
@VisibleForTesting
- protected void processFile(InputFile inputFile, BlameResult handler) {
+ protected void processFile(InputFile inputFile, BlameResult result) {
File ioFile = inputFile.file();
File scmDataFile = new java.io.File(ioFile.getParentFile(), ioFile.getName() + SCM_EXTENSION);
if (!scmDataFile.exists()) {
@@ -94,7 +74,7 @@ public class XooScmProvider implements ScmProvider {
blame.add(new BlameLine(date, revision, author));
}
}
- handler.add(inputFile, blame);
+ result.add(inputFile, blame);
} catch (IOException e) {
throw new IllegalStateException(e);
}
diff --git a/plugins/sonar-xoo-plugin/src/main/java/org/sonar/xoo/scm/XooScmProvider.java b/plugins/sonar-xoo-plugin/src/main/java/org/sonar/xoo/scm/XooScmProvider.java
new file mode 100644
index 00000000000..5807d820043
--- /dev/null
+++ b/plugins/sonar-xoo-plugin/src/main/java/org/sonar/xoo/scm/XooScmProvider.java
@@ -0,0 +1,43 @@
+/*
+ * 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.scm;
+
+import org.sonar.api.batch.scm.BlameCommand;
+import org.sonar.api.batch.scm.ScmProvider;
+
+public class XooScmProvider extends ScmProvider {
+
+ private final XooBlameCommand blame;
+
+ public XooScmProvider(XooBlameCommand blame) {
+ this.blame = blame;
+ }
+
+ @Override
+ public String key() {
+ return "xoo";
+ }
+
+ @Override
+ public BlameCommand blameCommand() {
+ return blame;
+ }
+
+}
diff --git a/plugins/sonar-xoo-plugin/src/main/java/org/sonar/xoo/scm/package-info.java b/plugins/sonar-xoo-plugin/src/main/java/org/sonar/xoo/scm/package-info.java
new file mode 100644
index 00000000000..f5c68e3c563
--- /dev/null
+++ b/plugins/sonar-xoo-plugin/src/main/java/org/sonar/xoo/scm/package-info.java
@@ -0,0 +1,23 @@
+/*
+ * 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.
+ */
+@ParametersAreNonnullByDefault
+package org.sonar.xoo.scm;
+
+import javax.annotation.ParametersAreNonnullByDefault;
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 96ea0ea923c..e8100740345 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(13);
+ assertThat(new XooPlugin().getExtensions()).hasSize(14);
}
}
diff --git a/plugins/sonar-xoo-plugin/src/test/java/org/sonar/xoo/rule/OneIssuePerLineSensorTest.java b/plugins/sonar-xoo-plugin/src/test/java/org/sonar/xoo/rule/OneIssuePerLineSensorTest.java
new file mode 100644
index 00000000000..31d109e3653
--- /dev/null
+++ b/plugins/sonar-xoo-plugin/src/test/java/org/sonar/xoo/rule/OneIssuePerLineSensorTest.java
@@ -0,0 +1,104 @@
+/*
+ * 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.rule;
+
+import org.junit.Test;
+import org.mockito.ArgumentCaptor;
+import org.mockito.invocation.InvocationOnMock;
+import org.mockito.stubbing.Answer;
+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.internal.DefaultSensorDescriptor;
+import org.sonar.api.batch.sensor.issue.Issue;
+import org.sonar.api.batch.sensor.issue.Issue.Severity;
+import org.sonar.api.batch.sensor.issue.internal.DefaultIssue;
+import org.sonar.api.config.Settings;
+import org.sonar.xoo.Xoo;
+
+import static org.fest.assertions.Assertions.assertThat;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.times;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
+
+public class OneIssuePerLineSensorTest {
+
+ private OneIssuePerLineSensor sensor = new OneIssuePerLineSensor();
+
+ @Test
+ public void testDescriptor() {
+ DefaultSensorDescriptor descriptor = new DefaultSensorDescriptor();
+ sensor.describe(descriptor);
+ assertThat(descriptor.ruleRepositories()).containsOnly(XooRulesDefinition.XOO_REPOSITORY);
+ }
+
+ @Test
+ public void testRule() {
+ DefaultFileSystem fs = new DefaultFileSystem();
+ DefaultInputFile inputFile = new DefaultInputFile("foo", "src/Foo.xoo").setLanguage(Xoo.KEY).setLines(10);
+ fs.add(inputFile);
+
+ SensorContext context = mock(SensorContext.class);
+ final SensorStorage sensorStorage = mock(SensorStorage.class);
+ when(context.settings()).thenReturn(new Settings());
+ when(context.fileSystem()).thenReturn(fs);
+ when(context.newIssue()).thenAnswer(new Answer<Issue>() {
+ @Override
+ public Issue answer(InvocationOnMock invocation) throws Throwable {
+ return new DefaultIssue(sensorStorage);
+ }
+ });
+ sensor.execute(context);
+
+ ArgumentCaptor<DefaultIssue> argCaptor = ArgumentCaptor.forClass(DefaultIssue.class);
+ verify(sensorStorage, times(10)).store(argCaptor.capture());
+ assertThat(argCaptor.getAllValues()).hasSize(10); // One issue per line
+ assertThat(argCaptor.getValue().overridenSeverity()).isNull();
+ }
+
+ @Test
+ public void testForceSeverity() {
+ DefaultFileSystem fs = new DefaultFileSystem();
+ DefaultInputFile inputFile = new DefaultInputFile("foo", "src/Foo.xoo").setLanguage(Xoo.KEY).setLines(10);
+ fs.add(inputFile);
+
+ SensorContext context = mock(SensorContext.class);
+ final SensorStorage sensorStorage = mock(SensorStorage.class);
+ Settings settings = new Settings();
+ settings.setProperty(OneIssuePerLineSensor.FORCE_SEVERITY_PROPERTY, "MINOR");
+ when(context.settings()).thenReturn(settings);
+ when(context.fileSystem()).thenReturn(fs);
+ when(context.newIssue()).thenAnswer(new Answer<Issue>() {
+ @Override
+ public Issue answer(InvocationOnMock invocation) throws Throwable {
+ return new DefaultIssue(sensorStorage);
+ }
+ });
+ sensor.execute(context);
+
+ ArgumentCaptor<DefaultIssue> argCaptor = ArgumentCaptor.forClass(DefaultIssue.class);
+ verify(sensorStorage, times(10)).store(argCaptor.capture());
+ assertThat(argCaptor.getAllValues()).hasSize(10); // One issue per line
+ assertThat(argCaptor.getValue().overridenSeverity()).isEqualTo(Severity.MINOR);
+ }
+
+}
diff --git a/plugins/sonar-xoo-plugin/src/test/java/org/sonar/xoo/scm/XooBlameCommandTest.java b/plugins/sonar-xoo-plugin/src/test/java/org/sonar/xoo/scm/XooBlameCommandTest.java
new file mode 100644
index 00000000000..bba495dd400
--- /dev/null
+++ b/plugins/sonar-xoo-plugin/src/test/java/org/sonar/xoo/scm/XooBlameCommandTest.java
@@ -0,0 +1,75 @@
+/*
+ * 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.scm;
+
+import org.apache.commons.io.FileUtils;
+import org.junit.Before;
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.rules.ExpectedException;
+import org.junit.rules.TemporaryFolder;
+import org.sonar.api.batch.fs.InputFile;
+import org.sonar.api.batch.fs.internal.DefaultFileSystem;
+import org.sonar.api.batch.fs.internal.DefaultInputFile;
+import org.sonar.api.batch.scm.BlameCommand.BlameResult;
+import org.sonar.api.batch.scm.BlameLine;
+import org.sonar.api.utils.DateUtils;
+import org.sonar.xoo.Xoo;
+
+import java.io.File;
+import java.io.IOException;
+import java.util.Arrays;
+
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.verify;
+
+public class XooBlameCommandTest {
+
+ @Rule
+ public TemporaryFolder temp = new TemporaryFolder();
+
+ @Rule
+ public ExpectedException thrown = ExpectedException.none();
+
+ private DefaultFileSystem fs;
+ private File baseDir;
+
+ @Before
+ public void prepare() throws IOException {
+ baseDir = temp.newFolder();
+ fs = new DefaultFileSystem();
+ }
+
+ @Test
+ public void testBlame() throws IOException {
+ File source = new File(baseDir, "src/foo.xoo");
+ FileUtils.write(source, "sample content");
+ File scm = new File(baseDir, "src/foo.xoo.scm");
+ FileUtils.write(scm, "123,julien,2014-12-12\n234,julien,2014-12-24");
+ DefaultInputFile inputFile = new DefaultInputFile("foo", "src/foo.xoo").setAbsolutePath(new File(baseDir, "src/foo.xoo").getAbsolutePath()).setLanguage(Xoo.KEY);
+ fs.add(inputFile);
+
+ BlameResult result = mock(BlameResult.class);
+ new XooBlameCommand().blame(fs, Arrays.<InputFile>asList(inputFile), result);
+ verify(result).add(inputFile, Arrays.asList(new BlameLine(DateUtils.parseDate("2014-12-12"), "123", "julien"),
+ new BlameLine(DateUtils.parseDate("2014-12-24"), "234", "julien")));
+ }
+
+}