aboutsummaryrefslogtreecommitdiffstats
path: root/plugins
diff options
context:
space:
mode:
authorJulien Lancelot <julien.lancelot@sonarsource.com>2019-01-22 13:00:53 +0100
committersonartech <sonartech@sonarsource.com>2019-02-11 09:11:42 +0100
commit1361ba5fb9d1bf5f98cba5feff9227f177a44e94 (patch)
tree88c6b29b83a6fc67ac38950c2d5adadc1fa7f97d /plugins
parent37f879c7c552d23eeffdc6746aab58b7fd2db4a9 (diff)
downloadsonarqube-1361ba5fb9d1bf5f98cba5feff9227f177a44e94.tar.gz
sonarqube-1361ba5fb9d1bf5f98cba5feff9227f177a44e94.zip
SONAR-10199 Fix search of issues by author containing comma
Diffstat (limited to 'plugins')
-rw-r--r--plugins/sonar-xoo-plugin/build.gradle1
-rw-r--r--plugins/sonar-xoo-plugin/src/main/java/org/sonar/xoo/scm/XooBlameCommand.java72
-rw-r--r--plugins/sonar-xoo-plugin/src/test/java/org/sonar/xoo/scm/XooBlameCommandTest.java32
3 files changed, 67 insertions, 38 deletions
diff --git a/plugins/sonar-xoo-plugin/build.gradle b/plugins/sonar-xoo-plugin/build.gradle
index 66c6d051b68..693f0cb1363 100644
--- a/plugins/sonar-xoo-plugin/build.gradle
+++ b/plugins/sonar-xoo-plugin/build.gradle
@@ -6,6 +6,7 @@ dependencies {
compile 'com.google.guava:guava'
compile 'commons-io:commons-io'
compile 'commons-lang:commons-lang'
+ compile 'org.apache.commons:commons-csv'
compileOnly 'com.google.code.findbugs:jsr305'
runtime project(path: ':sonar-plugin-api', configuration: 'shadow')
compileOnly project(path: ':sonar-plugin-api')
diff --git a/plugins/sonar-xoo-plugin/src/main/java/org/sonar/xoo/scm/XooBlameCommand.java b/plugins/sonar-xoo-plugin/src/main/java/org/sonar/xoo/scm/XooBlameCommand.java
index 6138d7d5ba5..9a803dd3b4c 100644
--- a/plugins/sonar-xoo-plugin/src/main/java/org/sonar/xoo/scm/XooBlameCommand.java
+++ b/plugins/sonar-xoo-plugin/src/main/java/org/sonar/xoo/scm/XooBlameCommand.java
@@ -21,18 +21,22 @@ package org.sonar.xoo.scm;
import com.google.common.annotations.VisibleForTesting;
import java.io.File;
+import java.io.FileReader;
import java.io.IOException;
-import java.nio.charset.StandardCharsets;
-import java.util.ArrayList;
import java.util.Date;
import java.util.List;
-import org.apache.commons.io.FileUtils;
-import org.apache.commons.lang.StringUtils;
+import org.apache.commons.csv.CSVFormat;
+import org.apache.commons.csv.CSVParser;
+import org.apache.commons.csv.CSVRecord;
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.utils.DateUtils;
+import static com.google.common.base.Preconditions.checkState;
+import static java.util.stream.Collectors.toList;
+import static org.apache.commons.lang.StringUtils.trimToNull;
+
public class XooBlameCommand extends BlameCommand {
private static final String SCM_EXTENSION = ".scm";
@@ -47,42 +51,46 @@ public class XooBlameCommand extends BlameCommand {
@VisibleForTesting
protected void processFile(InputFile inputFile, BlameOutput result) {
File ioFile = inputFile.file();
- File scmDataFile = new java.io.File(ioFile.getParentFile(), ioFile.getName() + SCM_EXTENSION);
+ File scmDataFile = new File(ioFile.getParentFile(), ioFile.getName() + SCM_EXTENSION);
if (!scmDataFile.exists()) {
return;
}
try {
- List<String> lines = FileUtils.readLines(scmDataFile, StandardCharsets.UTF_8);
- List<BlameLine> blame = new ArrayList<>(lines.size());
- int lineNumber = 0;
- for (String line : lines) {
- lineNumber++;
- if (StringUtils.isNotBlank(line)) {
- // revision,author,dateTime
- String[] fields = StringUtils.splitPreserveAllTokens(line, ',');
- if (fields.length < 3) {
- throw new IllegalStateException("Not enough fields on line " + lineNumber);
- }
- String revision = StringUtils.trimToNull(fields[0]);
- String author = StringUtils.trimToNull(fields[1]);
- BlameLine blameLine = new BlameLine().revision(revision).author(author);
- String dateStr = StringUtils.trimToNull(fields[2]);
- if (dateStr != null) {
- Date dateTime = DateUtils.parseDateTimeQuietly(dateStr);
- if (dateTime != null) {
- blameLine.date(dateTime);
- } else {
- // Will throw an exception, when date is not in format "yyyy-MM-dd"
- blameLine.date(DateUtils.parseDate(dateStr));
- }
- }
- blame.add(blameLine);
- }
- }
+ List<BlameLine> blame = readFile(scmDataFile);
result.blameResult(inputFile, blame);
} catch (IOException e) {
throw new IllegalStateException(e);
}
}
+
+ private static List<BlameLine> readFile(File inputStream) throws IOException {
+ try (CSVParser csvParser = CSVFormat.RFC4180
+ .withIgnoreEmptyLines()
+ .withIgnoreSurroundingSpaces()
+ .parse(new FileReader(inputStream))) {
+ List<CSVRecord> records = csvParser.getRecords();
+ return records.stream()
+ .map(XooBlameCommand::convertToBlameLine)
+ .collect(toList());
+ }
+ }
+
+ private static BlameLine convertToBlameLine(CSVRecord csvRecord) {
+ checkState(csvRecord.size() == 3, "Not enough fields on line %s", csvRecord);
+ String revision = trimToNull(csvRecord.get(0));
+ String author = trimToNull(csvRecord.get(1));
+ BlameLine blameLine = new BlameLine().revision(revision).author(author);
+ String dateStr = trimToNull(csvRecord.get(2));
+ if (dateStr != null) {
+ Date dateTime = DateUtils.parseDateTimeQuietly(dateStr);
+ if (dateTime != null) {
+ blameLine.date(dateTime);
+ } else {
+ // Will throw an exception, when date is not in format "yyyy-MM-dd"
+ blameLine.date(DateUtils.parseDate(dateStr));
+ }
+ }
+ return blameLine;
+ }
}
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
index bb95b62e7f1..9f9a1a22b0e 100644
--- 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
@@ -19,13 +19,15 @@
*/
package org.sonar.xoo.scm;
+import java.io.File;
+import java.io.IOException;
+import java.util.Arrays;
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.fs.internal.TestInputFileBuilder;
@@ -35,10 +37,7 @@ 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 java.util.Collections.singletonList;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
@@ -74,12 +73,33 @@ public class XooBlameCommandTest {
.setModuleBaseDir(baseDir.toPath())
.build();
fs.add(inputFile);
-
BlameOutput result = mock(BlameOutput.class);
when(input.filesToBlame()).thenReturn(Arrays.asList(inputFile));
+
new XooBlameCommand().blame(input, result);
+
verify(result).blameResult(inputFile, Arrays.asList(
new BlameLine().revision("123").author("julien").date(DateUtils.parseDate("2014-12-12")),
new BlameLine().revision("234").author("julien").date(DateUtils.parseDate("2014-12-24"))));
}
+
+ @Test
+ public void blame_containing_author_with_comma() 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\",\"john,doe\",\"2019-01-22\"");
+ DefaultInputFile inputFile = new TestInputFileBuilder("foo", "src/foo.xoo")
+ .setLanguage(Xoo.KEY)
+ .setModuleBaseDir(baseDir.toPath())
+ .build();
+ fs.add(inputFile);
+ BlameOutput result = mock(BlameOutput.class);
+ when(input.filesToBlame()).thenReturn(Arrays.asList(inputFile));
+
+ new XooBlameCommand().blame(input, result);
+
+ verify(result).blameResult(inputFile, singletonList(
+ new BlameLine().revision("123").author("john,doe").date(DateUtils.parseDate("2019-01-22"))));
+ }
}