diff options
author | Julien Lancelot <julien.lancelot@sonarsource.com> | 2019-01-22 13:00:53 +0100 |
---|---|---|
committer | sonartech <sonartech@sonarsource.com> | 2019-02-11 09:11:42 +0100 |
commit | 1361ba5fb9d1bf5f98cba5feff9227f177a44e94 (patch) | |
tree | 88c6b29b83a6fc67ac38950c2d5adadc1fa7f97d /plugins | |
parent | 37f879c7c552d23eeffdc6746aab58b7fd2db4a9 (diff) | |
download | sonarqube-1361ba5fb9d1bf5f98cba5feff9227f177a44e94.tar.gz sonarqube-1361ba5fb9d1bf5f98cba5feff9227f177a44e94.zip |
SONAR-10199 Fix search of issues by author containing comma
Diffstat (limited to 'plugins')
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")))); + } } |