Kaynağa Gözat

Revert "SONAR-5644 Rework SCM API"

This reverts commit a4e76de077.
tags/5.0-RC1
Simon Brandhof 9 yıl önce
ebeveyn
işleme
8664470d82
24 değiştirilmiş dosya ile 244 ekleme ve 667 silme
  1. 0
    96
      plugins/sonar-git-plugin/src/main/java/org/sonar/plugins/scm/git/GitBlameCommand.java
  2. 1
    2
      plugins/sonar-git-plugin/src/main/java/org/sonar/plugins/scm/git/GitPlugin.java
  3. 56
    9
      plugins/sonar-git-plugin/src/main/java/org/sonar/plugins/scm/git/GitScmProvider.java
  4. 11
    10
      plugins/sonar-git-plugin/src/main/java/org/sonar/plugins/scm/git/SonarGitBlameConsumer.java
  5. 0
    108
      plugins/sonar-git-plugin/src/test/java/org/sonar/plugins/scm/git/GitBlameCommandTest.java
  6. 1
    1
      plugins/sonar-git-plugin/src/test/java/org/sonar/plugins/scm/git/GitPluginTest.java
  7. 0
    53
      plugins/sonar-git-plugin/src/test/java/org/sonar/plugins/scm/git/GitScmProviderTest.java
  8. 119
    0
      plugins/sonar-git-plugin/src/test/java/org/sonar/plugins/scm/git/medium/GitMediumTest.java
  9. 1
    3
      plugins/sonar-xoo-plugin/src/main/java/org/sonar/xoo/XooPlugin.java
  10. 28
    8
      plugins/sonar-xoo-plugin/src/main/java/org/sonar/xoo/lang/XooScmProvider.java
  11. 0
    23
      plugins/sonar-xoo-plugin/src/main/java/org/sonar/xoo/lang/package-info.java
  12. 1
    1
      plugins/sonar-xoo-plugin/src/main/java/org/sonar/xoo/rule/OneIssuePerLineSensor.java
  13. 0
    43
      plugins/sonar-xoo-plugin/src/main/java/org/sonar/xoo/scm/XooScmProvider.java
  14. 0
    23
      plugins/sonar-xoo-plugin/src/main/java/org/sonar/xoo/scm/package-info.java
  15. 1
    1
      plugins/sonar-xoo-plugin/src/test/java/org/sonar/xoo/XooPluginTest.java
  16. 0
    104
      plugins/sonar-xoo-plugin/src/test/java/org/sonar/xoo/rule/OneIssuePerLineSensorTest.java
  17. 0
    75
      plugins/sonar-xoo-plugin/src/test/java/org/sonar/xoo/scm/XooBlameCommandTest.java
  18. 0
    1
      pom.xml
  19. 2
    2
      sonar-batch/src/main/java/org/sonar/batch/scm/ScmActivitySensor.java
  20. 0
    47
      sonar-plugin-api/src/main/java/org/sonar/api/batch/scm/BlameCommand.java
  21. 0
    42
      sonar-plugin-api/src/main/java/org/sonar/api/batch/scm/BlameLine.java
  22. 20
    9
      sonar-plugin-api/src/main/java/org/sonar/api/batch/scm/ScmProvider.java
  23. 3
    2
      sonar-plugin-api/src/main/java/org/sonar/api/batch/sensor/issue/internal/DefaultIssue.java
  24. 0
    4
      sonar-plugin-api/src/main/java/org/sonar/api/batch/sensor/test/internal/DefaultTestCase.java

+ 0
- 96
plugins/sonar-git-plugin/src/main/java/org/sonar/plugins/scm/git/GitBlameCommand.java Dosyayı Görüntüle

@@ -1,96 +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;

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();
}
}

}

+ 1
- 2
plugins/sonar-git-plugin/src/main/java/org/sonar/plugins/scm/git/GitPlugin.java Dosyayı Görüntüle

@@ -28,8 +28,7 @@ public final class GitPlugin extends SonarPlugin {

public List getExtensions() {
return ImmutableList.of(
GitScmProvider.class,
GitBlameCommand.class);
GitScmProvider.class);
}

}

+ 56
- 9
plugins/sonar-git-plugin/src/main/java/org/sonar/plugins/scm/git/GitScmProvider.java Dosyayı Görüntüle

@@ -19,18 +19,20 @@
*/
package org.sonar.plugins.scm.git;

import org.sonar.api.batch.scm.BlameCommand;
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.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 extends ScmProvider {
public class GitScmProvider implements ScmProvider {

private GitBlameCommand blameCommand;

public GitScmProvider(GitBlameCommand blameCommand) {
this.blameCommand = blameCommand;
}
private static final Logger LOG = LoggerFactory.getLogger(GitScmProvider.class);

@Override
public String key() {
@@ -43,8 +45,53 @@ public class GitScmProvider extends ScmProvider {
}

@Override
public BlameCommand blameCommand() {
return this.blameCommand;
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();
}
}

}

plugins/sonar-git-plugin/src/main/java/org/sonar/plugins/scm/git/GitBlameConsumer.java → plugins/sonar-git-plugin/src/main/java/org/sonar/plugins/scm/git/SonarGitBlameConsumer.java Dosyayı Görüntüle

@@ -1,22 +1,23 @@
/*
* SonarQube, open source software quality management tool.
* Copyright (C) 2008-2014 SonarSource
* mailto:contact AT sonarsource DOT com
* Sonar SCM Activity Plugin
* Copyright (C) 2010 SonarSource
* dev@sonar.codehaus.org
*
* SonarQube is free software; you can redistribute it and/or
* 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.
*
* SonarQube is distributed in the hope that it will be useful,
* 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, write to the Free Software Foundation,
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
* 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
*/

package org.sonar.plugins.scm.git;

import com.google.common.annotations.VisibleForTesting;
@@ -44,7 +45,7 @@ import java.util.Map;
*
* @since 1.5.1
*/
public class GitBlameConsumer implements StreamConsumer {
public class SonarGitBlameConsumer implements StreamConsumer {

private static final String GIT_COMMITTER_PREFIX = "committer";
private static final String GIT_COMMITTER_TIME = GIT_COMMITTER_PREFIX + "-time ";
@@ -77,7 +78,7 @@ public class GitBlameConsumer implements StreamConsumer {
return logger;
}

public GitBlameConsumer(Logger logger) {
public SonarGitBlameConsumer(Logger logger) {
this.logger = logger;
}


+ 0
- 108
plugins/sonar-git-plugin/src/test/java/org/sonar/plugins/scm/git/GitBlameCommandTest.java Dosyayı Görüntüle

@@ -1,108 +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;

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")));
}

}

+ 1
- 1
plugins/sonar-git-plugin/src/test/java/org/sonar/plugins/scm/git/GitPluginTest.java Dosyayı Görüntüle

@@ -27,6 +27,6 @@ public class GitPluginTest {

@Test
public void getExtensions() {
assertThat(new GitPlugin().getExtensions()).hasSize(2);
assertThat(new GitPlugin().getExtensions()).hasSize(1);
}
}

+ 0
- 53
plugins/sonar-git-plugin/src/test/java/org/sonar/plugins/scm/git/GitScmProviderTest.java Dosyayı Görüntüle

@@ -1,53 +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;

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();
}

}

+ 119
- 0
plugins/sonar-git-plugin/src/test/java/org/sonar/plugins/scm/git/medium/GitMediumTest.java Dosyayı Görüntüle

@@ -0,0 +1,119 @@
/*
* 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);
}

}

+ 1
- 3
plugins/sonar-xoo-plugin/src/main/java/org/sonar/xoo/XooPlugin.java Dosyayı Görüntüle

@@ -25,14 +25,13 @@ 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;
@@ -54,7 +53,6 @@ public class XooPlugin extends SonarPlugin {

// SCM
XooScmProvider.class,
XooBlameCommand.class,

// sensors
MeasureSensor.class,

plugins/sonar-xoo-plugin/src/main/java/org/sonar/xoo/scm/XooBlameCommand.java → plugins/sonar-xoo-plugin/src/main/java/org/sonar/xoo/lang/XooScmProvider.java Dosyayı Görüntüle

@@ -17,16 +17,18 @@
* 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;
package org.sonar.xoo.lang;

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.sonar.api.batch.fs.FileSystem;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
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;
@@ -35,19 +37,37 @@ import java.util.ArrayList;
import java.util.Date;
import java.util.List;

public class XooBlameCommand implements BlameCommand {
public class XooScmProvider implements ScmProvider {

private static final Logger LOG = LoggerFactory.getLogger(XooScmProvider.class);

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(FileSystem fs, Iterable<InputFile> files, BlameResult result) {
public void blame(Iterable<InputFile> files, BlameResult handler) {
for (InputFile inputFile : files) {
processFile(inputFile, result);
processFile(inputFile, handler);
}
}

@VisibleForTesting
protected void processFile(InputFile inputFile, BlameResult result) {
protected void processFile(InputFile inputFile, BlameResult handler) {
File ioFile = inputFile.file();
File scmDataFile = new java.io.File(ioFile.getParentFile(), ioFile.getName() + SCM_EXTENSION);
if (!scmDataFile.exists()) {
@@ -74,7 +94,7 @@ public class XooBlameCommand implements BlameCommand {
blame.add(new BlameLine(date, revision, author));
}
}
result.add(inputFile, blame);
handler.add(inputFile, blame);
} catch (IOException e) {
throw new IllegalStateException(e);
}

+ 0
- 23
plugins/sonar-xoo-plugin/src/main/java/org/sonar/xoo/lang/package-info.java Dosyayı Görüntüle

@@ -1,23 +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.
*/
@ParametersAreNonnullByDefault
package org.sonar.xoo.lang;

import javax.annotation.ParametersAreNonnullByDefault;

+ 1
- 1
plugins/sonar-xoo-plugin/src/main/java/org/sonar/xoo/rule/OneIssuePerLineSensor.java Dosyayı Görüntüle

@@ -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";
public static final String FORCE_SEVERITY_PROPERTY = "sonar.oneIssuePerLine.forceSeverity";
private static final String FORCE_SEVERITY_PROPERTY = "sonar.oneIssuePerLine.forceSeverity";

@Override
public void describe(SensorDescriptor descriptor) {

+ 0
- 43
plugins/sonar-xoo-plugin/src/main/java/org/sonar/xoo/scm/XooScmProvider.java Dosyayı Görüntüle

@@ -1,43 +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.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;
}

}

+ 0
- 23
plugins/sonar-xoo-plugin/src/main/java/org/sonar/xoo/scm/package-info.java Dosyayı Görüntüle

@@ -1,23 +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.
*/
@ParametersAreNonnullByDefault
package org.sonar.xoo.scm;

import javax.annotation.ParametersAreNonnullByDefault;

+ 1
- 1
plugins/sonar-xoo-plugin/src/test/java/org/sonar/xoo/XooPluginTest.java Dosyayı Görüntüle

@@ -27,6 +27,6 @@ public class XooPluginTest {

@Test
public void provide_extensions() {
assertThat(new XooPlugin().getExtensions()).hasSize(14);
assertThat(new XooPlugin().getExtensions()).hasSize(13);
}
}

+ 0
- 104
plugins/sonar-xoo-plugin/src/test/java/org/sonar/xoo/rule/OneIssuePerLineSensorTest.java Dosyayı Görüntüle

@@ -1,104 +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.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);
}

}

+ 0
- 75
plugins/sonar-xoo-plugin/src/test/java/org/sonar/xoo/scm/XooBlameCommandTest.java Dosyayı Görüntüle

@@ -1,75 +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.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")));
}

}

+ 0
- 1
pom.xml Dosyayı Görüntüle

@@ -34,7 +34,6 @@
<module>plugins/sonar-cpd-plugin</module>
<module>plugins/sonar-l10n-en-plugin</module>
<module>plugins/sonar-email-notifications-plugin</module>
<module>plugins/sonar-git-plugin</module>
<module>plugins/sonar-xoo-plugin</module>
</modules>


+ 2
- 2
sonar-batch/src/main/java/org/sonar/batch/scm/ScmActivitySensor.java Dosyayı Görüntüle

@@ -24,8 +24,8 @@ import org.slf4j.LoggerFactory;
import org.sonar.api.batch.fs.FileSystem;
import org.sonar.api.batch.fs.InputFile;
import org.sonar.api.batch.fs.InputFile.Status;
import org.sonar.api.batch.scm.BlameCommand.BlameResult;
import org.sonar.api.batch.scm.BlameLine;
import org.sonar.api.batch.scm.ScmProvider.BlameResult;
import org.sonar.api.batch.sensor.Sensor;
import org.sonar.api.batch.sensor.SensorContext;
import org.sonar.api.batch.sensor.SensorDescriptor;
@@ -92,7 +92,7 @@ public final class ScmActivitySensor implements Sensor {
filesToBlame.add(f);
}
}
configuration.provider().blameCommand().blame(fs, filesToBlame, new BlameResult() {
configuration.provider().blame(fs, filesToBlame, new BlameResult() {

@Override
public void add(InputFile file, List<BlameLine> lines) {

+ 0
- 47
sonar-plugin-api/src/main/java/org/sonar/api/batch/scm/BlameCommand.java Dosyayı Görüntüle

@@ -1,47 +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.api.batch.scm;

import org.sonar.api.batch.fs.FileSystem;
import org.sonar.api.batch.fs.InputFile;

import java.util.List;

/**
* @since 5.0
*/
public interface BlameCommand {

/**
* Compute blame of the provided files. Computation can be done in parallel.
* If there is an error that prevent to blame a file then an exception should be raised.
*/
void blame(FileSystem fs, Iterable<InputFile> files, BlameResult result);

/**
* Callback for the provider to report results of blame per file.
*/
public static interface BlameResult {

void add(InputFile file, List<BlameLine> lines);

}

}

+ 0
- 42
sonar-plugin-api/src/main/java/org/sonar/api/batch/scm/BlameLine.java Dosyayı Görüntüle

@@ -19,11 +19,6 @@
*/
package org.sonar.api.batch.scm;

import org.apache.commons.lang.builder.EqualsBuilder;
import org.apache.commons.lang.builder.HashCodeBuilder;
import org.apache.commons.lang.builder.ToStringBuilder;
import org.apache.commons.lang.builder.ToStringStyle;

import java.util.Date;

/**
@@ -104,41 +99,4 @@ public class BlameLine {
this.date = null;
}
}

// For testing purpose

@Override
public boolean equals(Object obj) {
if (obj == null) {
return false;
}
if (obj == this) {
return true;
}
if (obj.getClass() != getClass()) {
return false;
}
BlameLine rhs = (BlameLine) obj;
return new EqualsBuilder()
.append(date, rhs.date)
.append(revision, rhs.revision)
.append(author, rhs.author)
.append(committer, rhs.committer)
.isEquals();
}

@Override
public int hashCode() {
return new HashCodeBuilder(27, 45).
append(date)
.append(revision)
.append(author)
.append(committer)
.toHashCode();
}

@Override
public String toString() {
return ToStringBuilder.reflectionToString(this, ToStringStyle.SHORT_PREFIX_STYLE);
}
}

+ 20
- 9
sonar-plugin-api/src/main/java/org/sonar/api/batch/scm/ScmProvider.java Dosyayı Görüntüle

@@ -21,31 +21,42 @@ package org.sonar.api.batch.scm;

import org.sonar.api.BatchExtension;
import org.sonar.api.batch.InstantiationStrategy;
import org.sonar.api.batch.fs.FileSystem;
import org.sonar.api.batch.fs.InputFile;

import java.io.File;
import java.util.List;

/**
* @since 5.0
*/
@InstantiationStrategy(InstantiationStrategy.PER_BATCH)
public abstract class ScmProvider implements BatchExtension {
public interface ScmProvider extends BatchExtension {

/**
* Unique identifier of the provider. Can be used in SCM URL to define the provider to use.
*/
public abstract String key();
String key();

/**
* Does this provider able to manage files located in this directory.
* Used by autodetection. Not considered if user has forced the provider key.
* @return false by default
* Used by autodetection.
*/
public boolean supports(File baseDir) {
return false;
}
boolean supports(File baseDir);

/**
* Compute blame of the provided files. Computation can be done in parallel.
* If there is an error that prevent to blame a file then an exception should be raised.
*/
void blame(FileSystem fs, Iterable<InputFile> files, BlameResult result);

/**
* Callback for the provider to save results of blame per file.
*/
public static interface BlameResult {

void add(InputFile file, List<BlameLine> lines);

public BlameCommand blameCommand() {
throw new UnsupportedOperationException("Blame command is not supported by " + key() + " provider");
}

}

+ 3
- 2
sonar-plugin-api/src/main/java/org/sonar/api/batch/sensor/issue/internal/DefaultIssue.java Dosyayı Görüntüle

@@ -52,12 +52,10 @@ public class DefaultIssue implements Issue {
private final SensorStorage storage;

public DefaultIssue() {
this.key = UUID.randomUUID().toString();
this.storage = null;
}

public DefaultIssue(SensorStorage storage) {
this.key = UUID.randomUUID().toString();
this.storage = storage;
}

@@ -157,6 +155,9 @@ public class DefaultIssue implements Issue {
public void save() {
Preconditions.checkNotNull(this.storage, "No persister on this object");
Preconditions.checkNotNull(this.ruleKey, "ruleKey is mandatory on issue");
if (this.key == null) {
this.key = UUID.randomUUID().toString();
}
Preconditions.checkState(!Strings.isNullOrEmpty(key), "Fail to generate issue key");

storage.store(this);

+ 0
- 4
sonar-plugin-api/src/main/java/org/sonar/api/batch/sensor/test/internal/DefaultTestCase.java Dosyayı Görüntüle

@@ -43,10 +43,6 @@ public class DefaultTestCase implements TestCase {
private TestCase.Type type = Type.UNIT;
private String stackTrace;

public DefaultTestCase() {
this.storage = null;
}

public DefaultTestCase(SensorStorage storage) {
this.storage = storage;
}

Loading…
İptal
Kaydet