aboutsummaryrefslogtreecommitdiffstats
path: root/plugins
diff options
context:
space:
mode:
authorJulien HENRY <julien.henry@sonarsource.com>2014-10-16 15:58:26 +0200
committerJulien HENRY <julien.henry@sonarsource.com>2014-10-16 16:52:40 +0200
commit229555a2030f9ea672654adf5087611ff2e60654 (patch)
treefcc28cc0c36f4a5670a22d651bc733822221fe07 /plugins
parent84c7aabe6ea304acaa96f14911b712bab02b51b8 (diff)
downloadsonarqube-229555a2030f9ea672654adf5087611ff2e60654.tar.gz
sonarqube-229555a2030f9ea672654adf5087611ff2e60654.zip
SONAR-5644 Apply some feedback on SCM API
Diffstat (limited to 'plugins')
-rw-r--r--plugins/sonar-git-plugin/src/main/java/org/sonar/plugins/scm/git/GitBlameCommand.java12
-rw-r--r--plugins/sonar-git-plugin/src/main/java/org/sonar/plugins/scm/git/GitBlameConsumer.java10
-rw-r--r--plugins/sonar-git-plugin/src/main/java/org/sonar/plugins/scm/git/JGitBlameCommand.java27
-rw-r--r--plugins/sonar-git-plugin/src/test/java/org/sonar/plugins/scm/git/GitBlameCommandTest.java30
-rw-r--r--plugins/sonar-git-plugin/src/test/java/org/sonar/plugins/scm/git/JGitBlameCommandTest.java147
-rw-r--r--plugins/sonar-svn-plugin/src/main/java/org/sonar/plugins/scm/svn/SvnBlameCommand.java18
-rw-r--r--plugins/sonar-svn-plugin/src/main/java/org/sonar/plugins/scm/svn/SvnBlameConsumer.java5
-rw-r--r--plugins/sonar-svn-plugin/src/test/java/org/sonar/plugins/scm/svn/SvnBlameCommandTest.java48
-rw-r--r--plugins/sonar-xoo-plugin/src/main/java/org/sonar/xoo/scm/XooBlameCommand.java24
-rw-r--r--plugins/sonar-xoo-plugin/src/test/java/org/sonar/xoo/scm/XooBlameCommandTest.java18
10 files changed, 180 insertions, 159 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
index 6cd5145457f..0e7c05f6b05 100644
--- 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
@@ -21,8 +21,6 @@ package org.sonar.plugins.scm.git;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
-import org.sonar.api.BatchComponent;
-import org.sonar.api.batch.InstantiationStrategy;
import org.sonar.api.batch.fs.FileSystem;
import org.sonar.api.batch.fs.InputFile;
import org.sonar.api.batch.scm.BlameCommand;
@@ -35,8 +33,7 @@ import org.sonar.api.utils.command.StringStreamConsumer;
import java.io.File;
import java.util.List;
-@InstantiationStrategy(InstantiationStrategy.PER_BATCH)
-public class GitBlameCommand implements BlameCommand, BatchComponent {
+public class GitBlameCommand extends BlameCommand {
private static final Logger LOG = LoggerFactory.getLogger(GitBlameCommand.class);
private final CommandExecutor commandExecutor;
@@ -50,9 +47,10 @@ public class GitBlameCommand implements BlameCommand, BatchComponent {
}
@Override
- public void blame(FileSystem fs, Iterable<InputFile> files, BlameResult result) {
+ public void blame(BlameInput input, BlameOutput output) {
+ FileSystem fs = input.fileSystem();
LOG.debug("Working directory: " + fs.baseDir().getAbsolutePath());
- for (InputFile inputFile : files) {
+ for (InputFile inputFile : input.filesToBlame()) {
String filename = inputFile.relativePath();
Command cl = createCommandLine(fs.baseDir(), filename);
GitBlameConsumer consumer = new GitBlameConsumer(filename);
@@ -67,7 +65,7 @@ public class GitBlameCommand implements BlameCommand, BatchComponent {
// SONARPLUGINS-3097 Git do not report blame on last empty line
lines.add(lines.get(lines.size() - 1));
}
- result.add(inputFile, lines);
+ output.blameResult(inputFile, lines);
}
}
diff --git a/plugins/sonar-git-plugin/src/main/java/org/sonar/plugins/scm/git/GitBlameConsumer.java b/plugins/sonar-git-plugin/src/main/java/org/sonar/plugins/scm/git/GitBlameConsumer.java
index 350d3dd956f..c8e4eec4f50 100644
--- a/plugins/sonar-git-plugin/src/main/java/org/sonar/plugins/scm/git/GitBlameConsumer.java
+++ b/plugins/sonar-git-plugin/src/main/java/org/sonar/plugins/scm/git/GitBlameConsumer.java
@@ -35,7 +35,6 @@ public class GitBlameConsumer implements StreamConsumer {
private static final String GIT_COMMITTER_PREFIX = "committer";
private static final String GIT_COMMITTER_TIME = GIT_COMMITTER_PREFIX + "-time ";
private static final String GIT_AUTHOR_EMAIL = "author-mail ";
- private static final String GIT_COMMITTER_EMAIL = GIT_COMMITTER_PREFIX + "-mail ";
private static final String OPENING_EMAIL_FIELD = "<";
private static final String CLOSING_EMAIL_FIELD = ">";
@@ -55,7 +54,6 @@ public class GitBlameConsumer implements StreamConsumer {
private String revision = null;
private String author = null;
- private String committer = null;
private Date time = null;
private final String filename;
@@ -93,11 +91,6 @@ public class GitBlameConsumer implements StreamConsumer {
return true;
}
- if (line.startsWith(GIT_COMMITTER_EMAIL)) {
- committer = extractEmail(line);
- return true;
- }
-
if (line.startsWith(GIT_COMMITTER_TIME)) {
String timeStr = line.substring(GIT_COMMITTER_TIME.length());
time = new Date(Long.parseLong(timeStr) * 1000L);
@@ -118,7 +111,7 @@ public class GitBlameConsumer implements StreamConsumer {
}
private void consumeContentLine() {
- BlameLine blameLine = new BlameLine(time, revision, author, committer);
+ BlameLine blameLine = new BlameLine().date(time).revision(revision).author(author);
getLines().add(blameLine);
// keep commitinfo for this sha-1
@@ -142,7 +135,6 @@ public class GitBlameConsumer implements StreamConsumer {
if (oldLine != null) {
// restore the commit info
author = oldLine.author();
- committer = oldLine.committer();
time = oldLine.date();
}
diff --git a/plugins/sonar-git-plugin/src/main/java/org/sonar/plugins/scm/git/JGitBlameCommand.java b/plugins/sonar-git-plugin/src/main/java/org/sonar/plugins/scm/git/JGitBlameCommand.java
index cfc044ad467..9f69f924fdb 100644
--- a/plugins/sonar-git-plugin/src/main/java/org/sonar/plugins/scm/git/JGitBlameCommand.java
+++ b/plugins/sonar-git-plugin/src/main/java/org/sonar/plugins/scm/git/JGitBlameCommand.java
@@ -26,9 +26,6 @@ import org.eclipse.jgit.lib.Repository;
import org.eclipse.jgit.lib.RepositoryBuilder;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
-import org.sonar.api.BatchComponent;
-import org.sonar.api.batch.InstantiationStrategy;
-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;
@@ -39,8 +36,7 @@ import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
-@InstantiationStrategy(InstantiationStrategy.PER_BATCH)
-public class JGitBlameCommand implements BlameCommand, BatchComponent {
+public class JGitBlameCommand extends BlameCommand {
private static final Logger LOG = LoggerFactory.getLogger(JGitBlameCommand.class);
@@ -51,9 +47,9 @@ public class JGitBlameCommand implements BlameCommand, BatchComponent {
}
@Override
- public void blame(FileSystem fs, Iterable<InputFile> files, BlameResult result) {
+ public void blame(BlameInput input, BlameOutput output) {
Git git = null;
- File basedir = fs.baseDir();
+ File basedir = input.fileSystem().baseDir();
try {
Repository repo = new RepositoryBuilder()
.findGitDir(basedir)
@@ -61,8 +57,8 @@ public class JGitBlameCommand implements BlameCommand, BatchComponent {
.build();
git = Git.wrap(repo);
File gitBaseDir = repo.getWorkTree();
- for (InputFile inputFile : files) {
- blame(result, git, gitBaseDir, inputFile);
+ for (InputFile inputFile : input.filesToBlame()) {
+ blame(output, git, gitBaseDir, inputFile);
}
} catch (IOException e) {
throw new IllegalStateException("Unable to open Git repository", e);
@@ -75,7 +71,7 @@ public class JGitBlameCommand implements BlameCommand, BatchComponent {
}
}
- private void blame(BlameResult result, Git git, File gitBaseDir, InputFile inputFile) throws GitAPIException {
+ private void blame(BlameOutput output, Git git, File gitBaseDir, InputFile inputFile) throws GitAPIException {
String filename = pathResolver.relativePath(gitBaseDir, inputFile.file());
org.eclipse.jgit.blame.BlameResult blameResult = git.blame()
// Equivalent to -w command line option
@@ -83,22 +79,19 @@ public class JGitBlameCommand implements BlameCommand, BatchComponent {
.setFilePath(filename).call();
List<BlameLine> lines = new ArrayList<BlameLine>();
for (int i = 0; i < blameResult.getResultContents().size(); i++) {
- if (blameResult.getSourceAuthor(i) == null || blameResult.getSourceCommit(i) == null || blameResult.getSourceCommitter(i) == null) {
+ if (blameResult.getSourceAuthor(i) == null || blameResult.getSourceCommit(i) == null) {
LOG.info("Author: " + blameResult.getSourceAuthor(i));
- LOG.info("Committer: " + blameResult.getSourceCommitter(i));
LOG.info("Source commit: " + blameResult.getSourceCommit(i));
throw new IllegalStateException("Unable to blame file " + inputFile.relativePath() + ". No blame info at line " + (i + 1) + ". Is file commited?");
}
- lines.add(new org.sonar.api.batch.scm.BlameLine(blameResult.getSourceAuthor(i).getWhen(),
- blameResult.getSourceCommit(i).getName(),
- blameResult.getSourceAuthor(i).getEmailAddress(),
- blameResult.getSourceCommitter(i).getEmailAddress()));
+ lines.add(new org.sonar.api.batch.scm.BlameLine().date(blameResult.getSourceAuthor(i).getWhen()).revision(blameResult.getSourceCommit(i).getName())
+ .author(blameResult.getSourceAuthor(i).getEmailAddress()));
}
if (lines.size() == inputFile.lines() - 1) {
// SONARPLUGINS-3097 Git do not report blame on last empty line
lines.add(lines.get(lines.size() - 1));
}
- result.add(inputFile, lines);
+ output.blameResult(inputFile, lines);
}
}
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
index 574f68dc4da..f5fff20d9da 100644
--- 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
@@ -30,7 +30,8 @@ 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.BlameCommand.BlameInput;
+import org.sonar.api.batch.scm.BlameCommand.BlameOutput;
import org.sonar.api.batch.scm.BlameLine;
import org.sonar.api.utils.DateUtils;
import org.sonar.api.utils.command.Command;
@@ -57,12 +58,15 @@ public class GitBlameCommandTest {
private DefaultFileSystem fs;
private File baseDir;
+ private BlameInput input;
@Before
public void prepare() throws IOException {
baseDir = temp.newFolder();
fs = new DefaultFileSystem();
fs.setBaseDir(baseDir);
+ input = mock(BlameInput.class);
+ when(input.fileSystem()).thenReturn(fs);
}
@Test
@@ -72,7 +76,7 @@ public class GitBlameCommandTest {
DefaultInputFile inputFile = new DefaultInputFile("foo", "src/foo.xoo").setAbsolutePath(new File(baseDir, "src/foo.xoo").getAbsolutePath());
fs.add(inputFile);
- BlameResult result = mock(BlameResult.class);
+ BlameOutput result = mock(BlameOutput.class);
CommandExecutor commandExecutor = mock(CommandExecutor.class);
when(commandExecutor.execute(any(Command.class), any(StreamConsumer.class), any(StreamConsumer.class), anyLong())).thenAnswer(new Answer<Integer>() {
@@ -98,11 +102,13 @@ public class GitBlameCommandTest {
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")));
+ when(input.filesToBlame()).thenReturn(Arrays.<InputFile>asList(inputFile));
+ new GitBlameCommand(commandExecutor).blame(input, result);
+ verify(result).blameResult(
+ inputFile,
+ Arrays.asList(
+ new BlameLine().date(DateUtils.parseDateTime("2011-08-05T10:49:31+0200")).revision("2c68c473da7fc293e12ca50f19380c5118be7ead").author("simon.brandhof@gmail.com"),
+ new BlameLine().date(DateUtils.parseDateTime("2011-08-05T10:49:31+0200")).revision("2c68c473da7fc293e12ca50f19380c5118be7ead").author("simon.brandhof@gmail.com")));
}
@Test
@@ -112,7 +118,7 @@ public class GitBlameCommandTest {
DefaultInputFile inputFile = new DefaultInputFile("foo", "src/foo.xoo").setAbsolutePath(new File(baseDir, "src/foo.xoo").getAbsolutePath());
fs.add(inputFile);
- BlameResult result = mock(BlameResult.class);
+ BlameOutput result = mock(BlameOutput.class);
CommandExecutor commandExecutor = mock(CommandExecutor.class);
when(commandExecutor.execute(any(Command.class), any(StreamConsumer.class), any(StreamConsumer.class), anyLong())).thenAnswer(new Answer<Integer>() {
@@ -141,7 +147,8 @@ public class GitBlameCommandTest {
thrown.expect(IllegalStateException.class);
thrown.expectMessage("Unable to blame file src/foo.xoo. No blame info at line 1. Is file commited?");
- new GitBlameCommand(commandExecutor).blame(fs, Arrays.<InputFile>asList(inputFile), result);
+ when(input.filesToBlame()).thenReturn(Arrays.<InputFile>asList(inputFile));
+ new GitBlameCommand(commandExecutor).blame(input, result);
}
@Test
@@ -151,7 +158,7 @@ public class GitBlameCommandTest {
DefaultInputFile inputFile = new DefaultInputFile("foo", "src/foo.xoo").setAbsolutePath(new File(baseDir, "src/foo.xoo").getAbsolutePath());
fs.add(inputFile);
- BlameResult result = mock(BlameResult.class);
+ BlameOutput result = mock(BlameOutput.class);
CommandExecutor commandExecutor = mock(CommandExecutor.class);
when(commandExecutor.execute(any(Command.class), any(StreamConsumer.class), any(StreamConsumer.class), anyLong())).thenAnswer(new Answer<Integer>() {
@@ -167,7 +174,8 @@ public class GitBlameCommandTest {
thrown.expect(IllegalStateException.class);
thrown.expectMessage("The git blame command [git blame --porcelain src/foo.xoo -w] failed: My error");
- new GitBlameCommand(commandExecutor).blame(fs, Arrays.<InputFile>asList(inputFile), result);
+ when(input.filesToBlame()).thenReturn(Arrays.<InputFile>asList(inputFile));
+ new GitBlameCommand(commandExecutor).blame(input, result);
}
}
diff --git a/plugins/sonar-git-plugin/src/test/java/org/sonar/plugins/scm/git/JGitBlameCommandTest.java b/plugins/sonar-git-plugin/src/test/java/org/sonar/plugins/scm/git/JGitBlameCommandTest.java
index 20b96962f83..7f74bea84a9 100644
--- a/plugins/sonar-git-plugin/src/test/java/org/sonar/plugins/scm/git/JGitBlameCommandTest.java
+++ b/plugins/sonar-git-plugin/src/test/java/org/sonar/plugins/scm/git/JGitBlameCommandTest.java
@@ -22,6 +22,7 @@ package org.sonar.plugins.scm.git;
import com.google.common.io.Closeables;
import org.apache.commons.io.FileUtils;
import org.apache.commons.io.IOUtils;
+import org.junit.Before;
import org.junit.Rule;
import org.junit.Test;
import org.junit.rules.ExpectedException;
@@ -29,7 +30,8 @@ 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.BlameCommand.BlameInput;
+import org.sonar.api.batch.scm.BlameCommand.BlameOutput;
import org.sonar.api.batch.scm.BlameLine;
import org.sonar.api.scan.filesystem.PathResolver;
import org.sonar.api.utils.DateUtils;
@@ -46,6 +48,7 @@ import java.util.zip.ZipFile;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
public class JGitBlameCommandTest {
@@ -57,6 +60,16 @@ public class JGitBlameCommandTest {
@Rule
public TemporaryFolder temp = new TemporaryFolder();
+ private DefaultFileSystem fs;
+ private BlameInput input;
+
+ @Before
+ public void prepare() throws IOException {
+ fs = new DefaultFileSystem();
+ input = mock(BlameInput.class);
+ when(input.fileSystem()).thenReturn(fs);
+ }
+
@Test
public void testBlame() throws IOException {
File projectDir = temp.newFolder();
@@ -64,47 +77,47 @@ public class JGitBlameCommandTest {
JGitBlameCommand jGitBlameCommand = new JGitBlameCommand(new PathResolver());
- DefaultFileSystem fs = new DefaultFileSystem();
File baseDir = new File(projectDir, "dummy-git");
fs.setBaseDir(baseDir);
DefaultInputFile inputFile = new DefaultInputFile("foo", DUMMY_JAVA)
.setFile(new File(baseDir, DUMMY_JAVA));
fs.add(inputFile);
- BlameResult blameResult = mock(BlameResult.class);
- jGitBlameCommand.blame(fs, Arrays.<InputFile>asList(inputFile), blameResult);
+ BlameOutput blameResult = mock(BlameOutput.class);
+ when(input.filesToBlame()).thenReturn(Arrays.<InputFile>asList(inputFile));
+ jGitBlameCommand.blame(input, blameResult);
Date revisionDate = DateUtils.parseDateTime("2012-07-17T16:12:48+0200");
String revision = "6b3aab35a3ea32c1636fee56f996e677653c48ea";
String author = "david@gageot.net";
- verify(blameResult).add(inputFile,
+ verify(blameResult).blameResult(inputFile,
Arrays.asList(
- new BlameLine(revisionDate, revision, author),
- new BlameLine(revisionDate, revision, author),
- new BlameLine(revisionDate, revision, author),
- new BlameLine(revisionDate, revision, author),
- new BlameLine(revisionDate, revision, author),
- new BlameLine(revisionDate, revision, author),
- new BlameLine(revisionDate, revision, author),
- new BlameLine(revisionDate, revision, author),
- new BlameLine(revisionDate, revision, author),
- new BlameLine(revisionDate, revision, author),
- new BlameLine(revisionDate, revision, author),
- new BlameLine(revisionDate, revision, author),
- new BlameLine(revisionDate, revision, author),
- new BlameLine(revisionDate, revision, author),
- new BlameLine(revisionDate, revision, author),
- new BlameLine(revisionDate, revision, author),
- new BlameLine(revisionDate, revision, author),
- new BlameLine(revisionDate, revision, author),
- new BlameLine(revisionDate, revision, author),
- new BlameLine(revisionDate, revision, author),
- new BlameLine(revisionDate, revision, author),
- new BlameLine(revisionDate, revision, author),
- new BlameLine(revisionDate, revision, author),
- new BlameLine(revisionDate, revision, author),
- new BlameLine(revisionDate, revision, author),
- new BlameLine(revisionDate, revision, author)));
+ new BlameLine().revision(revision).date(revisionDate).author(author),
+ new BlameLine().revision(revision).date(revisionDate).author(author),
+ new BlameLine().revision(revision).date(revisionDate).author(author),
+ new BlameLine().revision(revision).date(revisionDate).author(author),
+ new BlameLine().revision(revision).date(revisionDate).author(author),
+ new BlameLine().revision(revision).date(revisionDate).author(author),
+ new BlameLine().revision(revision).date(revisionDate).author(author),
+ new BlameLine().revision(revision).date(revisionDate).author(author),
+ new BlameLine().revision(revision).date(revisionDate).author(author),
+ new BlameLine().revision(revision).date(revisionDate).author(author),
+ new BlameLine().revision(revision).date(revisionDate).author(author),
+ new BlameLine().revision(revision).date(revisionDate).author(author),
+ new BlameLine().revision(revision).date(revisionDate).author(author),
+ new BlameLine().revision(revision).date(revisionDate).author(author),
+ new BlameLine().revision(revision).date(revisionDate).author(author),
+ new BlameLine().revision(revision).date(revisionDate).author(author),
+ new BlameLine().revision(revision).date(revisionDate).author(author),
+ new BlameLine().revision(revision).date(revisionDate).author(author),
+ new BlameLine().revision(revision).date(revisionDate).author(author),
+ new BlameLine().revision(revision).date(revisionDate).author(author),
+ new BlameLine().revision(revision).date(revisionDate).author(author),
+ new BlameLine().revision(revision).date(revisionDate).author(author),
+ new BlameLine().revision(revision).date(revisionDate).author(author),
+ new BlameLine().revision(revision).date(revisionDate).author(author),
+ new BlameLine().revision(revision).date(revisionDate).author(author),
+ new BlameLine().revision(revision).date(revisionDate).author(author)));
}
@Test
@@ -114,47 +127,47 @@ public class JGitBlameCommandTest {
JGitBlameCommand jGitBlameCommand = new JGitBlameCommand(new PathResolver());
- DefaultFileSystem fs = new DefaultFileSystem();
File baseDir = new File(projectDir, "dummy-git-nested/dummy-project");
fs.setBaseDir(baseDir);
DefaultInputFile inputFile = new DefaultInputFile("foo", DUMMY_JAVA)
.setFile(new File(baseDir, DUMMY_JAVA));
fs.add(inputFile);
- BlameResult blameResult = mock(BlameResult.class);
- jGitBlameCommand.blame(fs, Arrays.<InputFile>asList(inputFile), blameResult);
+ BlameOutput blameResult = mock(BlameOutput.class);
+ when(input.filesToBlame()).thenReturn(Arrays.<InputFile>asList(inputFile));
+ jGitBlameCommand.blame(input, blameResult);
Date revisionDate = DateUtils.parseDateTime("2012-07-17T16:12:48+0200");
String revision = "6b3aab35a3ea32c1636fee56f996e677653c48ea";
String author = "david@gageot.net";
- verify(blameResult).add(inputFile,
+ verify(blameResult).blameResult(inputFile,
Arrays.asList(
- new BlameLine(revisionDate, revision, author),
- new BlameLine(revisionDate, revision, author),
- new BlameLine(revisionDate, revision, author),
- new BlameLine(revisionDate, revision, author),
- new BlameLine(revisionDate, revision, author),
- new BlameLine(revisionDate, revision, author),
- new BlameLine(revisionDate, revision, author),
- new BlameLine(revisionDate, revision, author),
- new BlameLine(revisionDate, revision, author),
- new BlameLine(revisionDate, revision, author),
- new BlameLine(revisionDate, revision, author),
- new BlameLine(revisionDate, revision, author),
- new BlameLine(revisionDate, revision, author),
- new BlameLine(revisionDate, revision, author),
- new BlameLine(revisionDate, revision, author),
- new BlameLine(revisionDate, revision, author),
- new BlameLine(revisionDate, revision, author),
- new BlameLine(revisionDate, revision, author),
- new BlameLine(revisionDate, revision, author),
- new BlameLine(revisionDate, revision, author),
- new BlameLine(revisionDate, revision, author),
- new BlameLine(revisionDate, revision, author),
- new BlameLine(revisionDate, revision, author),
- new BlameLine(revisionDate, revision, author),
- new BlameLine(revisionDate, revision, author),
- new BlameLine(revisionDate, revision, author)));
+ new BlameLine().revision(revision).date(revisionDate).author(author),
+ new BlameLine().revision(revision).date(revisionDate).author(author),
+ new BlameLine().revision(revision).date(revisionDate).author(author),
+ new BlameLine().revision(revision).date(revisionDate).author(author),
+ new BlameLine().revision(revision).date(revisionDate).author(author),
+ new BlameLine().revision(revision).date(revisionDate).author(author),
+ new BlameLine().revision(revision).date(revisionDate).author(author),
+ new BlameLine().revision(revision).date(revisionDate).author(author),
+ new BlameLine().revision(revision).date(revisionDate).author(author),
+ new BlameLine().revision(revision).date(revisionDate).author(author),
+ new BlameLine().revision(revision).date(revisionDate).author(author),
+ new BlameLine().revision(revision).date(revisionDate).author(author),
+ new BlameLine().revision(revision).date(revisionDate).author(author),
+ new BlameLine().revision(revision).date(revisionDate).author(author),
+ new BlameLine().revision(revision).date(revisionDate).author(author),
+ new BlameLine().revision(revision).date(revisionDate).author(author),
+ new BlameLine().revision(revision).date(revisionDate).author(author),
+ new BlameLine().revision(revision).date(revisionDate).author(author),
+ new BlameLine().revision(revision).date(revisionDate).author(author),
+ new BlameLine().revision(revision).date(revisionDate).author(author),
+ new BlameLine().revision(revision).date(revisionDate).author(author),
+ new BlameLine().revision(revision).date(revisionDate).author(author),
+ new BlameLine().revision(revision).date(revisionDate).author(author),
+ new BlameLine().revision(revision).date(revisionDate).author(author),
+ new BlameLine().revision(revision).date(revisionDate).author(author),
+ new BlameLine().revision(revision).date(revisionDate).author(author)));
}
@Test
@@ -164,7 +177,6 @@ public class JGitBlameCommandTest {
JGitBlameCommand jGitBlameCommand = new JGitBlameCommand(new PathResolver());
- DefaultFileSystem fs = new DefaultFileSystem();
File baseDir = new File(projectDir, "dummy-git");
fs.setBaseDir(baseDir);
String relativePath = DUMMY_JAVA;
@@ -175,11 +187,12 @@ public class JGitBlameCommandTest {
// Emulate a modification
FileUtils.write(new File(baseDir, relativePath), "modification and \n some new line", true);
- BlameResult blameResult = mock(BlameResult.class);
+ BlameOutput blameResult = mock(BlameOutput.class);
thrown.expect(IllegalStateException.class);
thrown.expectMessage("Unable to blame file " + relativePath + ". No blame info at line 27. Is file commited?");
- jGitBlameCommand.blame(fs, Arrays.<InputFile>asList(inputFile), blameResult);
+ when(input.filesToBlame()).thenReturn(Arrays.<InputFile>asList(inputFile));
+ jGitBlameCommand.blame(input, blameResult);
}
@Test
@@ -189,7 +202,6 @@ public class JGitBlameCommandTest {
JGitBlameCommand jGitBlameCommand = new JGitBlameCommand(new PathResolver());
- DefaultFileSystem fs = new DefaultFileSystem();
File baseDir = new File(projectDir, "dummy-git");
fs.setBaseDir(baseDir);
String relativePath = DUMMY_JAVA;
@@ -204,11 +216,12 @@ public class JGitBlameCommandTest {
// Emulate a new file
FileUtils.copyFile(new File(baseDir, relativePath), new File(baseDir, relativePath2));
- BlameResult blameResult = mock(BlameResult.class);
+ BlameOutput blameResult = mock(BlameOutput.class);
thrown.expect(IllegalStateException.class);
thrown.expectMessage("Unable to blame file " + relativePath2 + ". No blame info at line 1. Is file commited?");
- jGitBlameCommand.blame(fs, Arrays.<InputFile>asList(inputFile, inputFile2), blameResult);
+ when(input.filesToBlame()).thenReturn(Arrays.<InputFile>asList(inputFile, inputFile2));
+ jGitBlameCommand.blame(input, blameResult);
}
private static void javaUnzip(File zip, File toDir) {
diff --git a/plugins/sonar-svn-plugin/src/main/java/org/sonar/plugins/scm/svn/SvnBlameCommand.java b/plugins/sonar-svn-plugin/src/main/java/org/sonar/plugins/scm/svn/SvnBlameCommand.java
index 48b65ffee6d..27647c8cad2 100644
--- a/plugins/sonar-svn-plugin/src/main/java/org/sonar/plugins/scm/svn/SvnBlameCommand.java
+++ b/plugins/sonar-svn-plugin/src/main/java/org/sonar/plugins/scm/svn/SvnBlameCommand.java
@@ -22,8 +22,6 @@ package org.sonar.plugins.scm.svn;
import com.google.common.annotations.VisibleForTesting;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
-import org.sonar.api.BatchComponent;
-import org.sonar.api.batch.InstantiationStrategy;
import org.sonar.api.batch.fs.FileSystem;
import org.sonar.api.batch.fs.InputFile;
import org.sonar.api.batch.scm.BlameCommand;
@@ -44,8 +42,7 @@ import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;
-@InstantiationStrategy(InstantiationStrategy.PER_BATCH)
-public class SvnBlameCommand implements BlameCommand, BatchComponent {
+public class SvnBlameCommand extends BlameCommand {
private static final Logger LOG = LoggerFactory.getLogger(SvnBlameCommand.class);
private final CommandExecutor commandExecutor;
@@ -61,12 +58,13 @@ public class SvnBlameCommand implements BlameCommand, BatchComponent {
}
@Override
- public void blame(final FileSystem fs, Iterable<InputFile> files, final BlameResult result) {
+ public void blame(final BlameInput input, final BlameOutput output) {
+ FileSystem fs = input.fileSystem();
LOG.debug("Working directory: " + fs.baseDir().getAbsolutePath());
ExecutorService executorService = Executors.newFixedThreadPool(Runtime.getRuntime().availableProcessors() + 1);
List<Future<Void>> tasks = new ArrayList<Future<Void>>();
- for (InputFile inputFile : files) {
- tasks.add(submitTask(fs, result, executorService, inputFile));
+ for (InputFile inputFile : input.filesToBlame()) {
+ tasks.add(submitTask(fs, output, executorService, inputFile));
}
for (Future<Void> task : tasks) {
@@ -81,7 +79,7 @@ public class SvnBlameCommand implements BlameCommand, BatchComponent {
}
}
- private Future<Void> submitTask(final FileSystem fs, final BlameResult result, ExecutorService executorService, final InputFile inputFile) {
+ private Future<Void> submitTask(final FileSystem fs, final BlameOutput result, ExecutorService executorService, final InputFile inputFile) {
return executorService.submit(new Callable<Void>() {
@Override
public Void call() {
@@ -91,7 +89,7 @@ public class SvnBlameCommand implements BlameCommand, BatchComponent {
});
}
- private void blame(final FileSystem fs, final InputFile inputFile, final BlameResult result) {
+ private void blame(final FileSystem fs, final InputFile inputFile, final BlameOutput output) {
String filename = inputFile.relativePath();
Command cl = createCommandLine(fs.baseDir(), filename);
SvnBlameConsumer consumer = new SvnBlameConsumer(filename);
@@ -111,7 +109,7 @@ public class SvnBlameCommand implements BlameCommand, BatchComponent {
// SONARPLUGINS-3097 SVN do not report blame on last empty line
lines.add(lines.get(lines.size() - 1));
}
- result.add(inputFile, lines);
+ output.blameResult(inputFile, lines);
}
private int execute(Command cl, StreamConsumer consumer, StreamConsumer stderr) {
diff --git a/plugins/sonar-svn-plugin/src/main/java/org/sonar/plugins/scm/svn/SvnBlameConsumer.java b/plugins/sonar-svn-plugin/src/main/java/org/sonar/plugins/scm/svn/SvnBlameConsumer.java
index dcf67a50572..8224fab347d 100644
--- a/plugins/sonar-svn-plugin/src/main/java/org/sonar/plugins/scm/svn/SvnBlameConsumer.java
+++ b/plugins/sonar-svn-plugin/src/main/java/org/sonar/plugins/scm/svn/SvnBlameConsumer.java
@@ -43,6 +43,8 @@ import org.slf4j.LoggerFactory;
import org.sonar.api.batch.scm.BlameLine;
import org.sonar.api.utils.command.StreamConsumer;
+import javax.annotation.CheckForNull;
+
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
@@ -101,13 +103,14 @@ public class SvnBlameConsumer implements StreamConsumer {
String date = matcher.group(1);
String time = matcher.group(2);
Date dateTime = parseDateTime(date + " " + time);
- lines.add(new BlameLine(dateTime, revision, author));
+ lines.add(new BlameLine().revision(revision).author(author).date(dateTime));
lineNumber = 0;
revision = null;
author = null;
}
}
+ @CheckForNull
protected Date parseDateTime(String dateTimeStr) {
try {
return dateFormat.parse(dateTimeStr);
diff --git a/plugins/sonar-svn-plugin/src/test/java/org/sonar/plugins/scm/svn/SvnBlameCommandTest.java b/plugins/sonar-svn-plugin/src/test/java/org/sonar/plugins/scm/svn/SvnBlameCommandTest.java
index f7bb1fc66dc..b85b71d2fdb 100644
--- a/plugins/sonar-svn-plugin/src/test/java/org/sonar/plugins/scm/svn/SvnBlameCommandTest.java
+++ b/plugins/sonar-svn-plugin/src/test/java/org/sonar/plugins/scm/svn/SvnBlameCommandTest.java
@@ -31,7 +31,8 @@ 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.BlameCommand.BlameInput;
+import org.sonar.api.batch.scm.BlameCommand.BlameOutput;
import org.sonar.api.batch.scm.BlameLine;
import org.sonar.api.config.PropertyDefinitions;
import org.sonar.api.config.Settings;
@@ -48,7 +49,9 @@ import java.util.List;
import static org.fest.assertions.Assertions.assertThat;
import static org.mockito.Matchers.any;
import static org.mockito.Matchers.anyLong;
-import static org.mockito.Mockito.*;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
public class SvnBlameCommandTest {
@@ -60,12 +63,15 @@ public class SvnBlameCommandTest {
private DefaultFileSystem fs;
private File baseDir;
+ private BlameInput input;
@Before
public void prepare() throws IOException {
baseDir = temp.newFolder();
fs = new DefaultFileSystem();
fs.setBaseDir(baseDir);
+ input = mock(BlameInput.class);
+ when(input.fileSystem()).thenReturn(fs);
}
@Test
@@ -75,7 +81,7 @@ public class SvnBlameCommandTest {
DefaultInputFile inputFile = new DefaultInputFile("foo", "src/foo.xoo").setAbsolutePath(new File(baseDir, "src/foo.xoo").getAbsolutePath());
fs.add(inputFile);
- BlameResult result = mock(BlameResult.class);
+ BlameOutput result = mock(BlameOutput.class);
CommandExecutor commandExecutor = mock(CommandExecutor.class);
when(commandExecutor.execute(any(Command.class), any(StreamConsumer.class), any(StreamConsumer.class), anyLong())).thenAnswer(new Answer<Integer>() {
@@ -91,12 +97,14 @@ public class SvnBlameCommandTest {
}
});
- new SvnBlameCommand(commandExecutor, mock(SvnConfiguration.class)).blame(fs, Arrays.<InputFile>asList(inputFile), result);
- verify(result).add(inputFile,
+ when(input.filesToBlame()).thenReturn(Arrays.<InputFile>asList(inputFile));
+
+ new SvnBlameCommand(commandExecutor, mock(SvnConfiguration.class)).blame(input, result);
+ verify(result).blameResult(inputFile,
Arrays.asList(
- new BlameLine(DateUtils.parseDateTime("2009-04-18T10:29:59+0000"), "9491", "simon.brandhof"),
- new BlameLine(DateUtils.parseDateTime("2009-04-18T10:29:59+0000"), "9491", "simon.brandhof"),
- new BlameLine(DateUtils.parseDateTime("2009-08-31T22:32:17+0000"), "10558", "david")));
+ new BlameLine().date(DateUtils.parseDateTime("2009-04-18T10:29:59+0000")).revision("9491").author("simon.brandhof"),
+ new BlameLine().date(DateUtils.parseDateTime("2009-04-18T10:29:59+0000")).revision("9491").author("simon.brandhof"),
+ new BlameLine().date(DateUtils.parseDateTime("2009-08-31T22:32:17+0000")).revision("10558").author("david")));
}
@Test
@@ -106,7 +114,7 @@ public class SvnBlameCommandTest {
DefaultInputFile inputFile = new DefaultInputFile("foo", "src/foo.xoo").setAbsolutePath(new File(baseDir, "src/foo.xoo").getAbsolutePath());
fs.add(inputFile);
- BlameResult result = mock(BlameResult.class);
+ BlameOutput result = mock(BlameOutput.class);
CommandExecutor commandExecutor = mock(CommandExecutor.class);
when(commandExecutor.execute(any(Command.class), any(StreamConsumer.class), any(StreamConsumer.class), anyLong())).thenAnswer(new Answer<Integer>() {
@@ -122,12 +130,14 @@ public class SvnBlameCommandTest {
}
});
- new SvnBlameCommand(commandExecutor, mock(SvnConfiguration.class)).blame(fs, Arrays.<InputFile>asList(inputFile), result);
- verify(result).add(inputFile,
+ when(input.filesToBlame()).thenReturn(Arrays.<InputFile>asList(inputFile));
+
+ new SvnBlameCommand(commandExecutor, mock(SvnConfiguration.class)).blame(input, result);
+ verify(result).blameResult(inputFile,
Arrays.asList(
- new BlameLine(DateUtils.parseDateTime("2009-04-18T10:29:59+0000"), "9491", "simon.brandhof"),
- new BlameLine(DateUtils.parseDateTime("2009-04-01T10:29:59+0000"), "1", null),
- new BlameLine(DateUtils.parseDateTime("2009-08-31T22:32:17+0000"), "10558", "david")));
+ new BlameLine().date(DateUtils.parseDateTime("2009-04-18T10:29:59+0000")).revision("9491").author("simon.brandhof"),
+ new BlameLine().date(DateUtils.parseDateTime("2009-04-01T10:29:59+0000")).revision("1"),
+ new BlameLine().date(DateUtils.parseDateTime("2009-08-31T22:32:17+0000")).revision("10558").author("david")));
}
@Test
@@ -137,7 +147,7 @@ public class SvnBlameCommandTest {
DefaultInputFile inputFile = new DefaultInputFile("foo", "src/foo.xoo").setAbsolutePath(new File(baseDir, "src/foo.xoo").getAbsolutePath());
fs.add(inputFile);
- BlameResult result = mock(BlameResult.class);
+ BlameOutput result = mock(BlameOutput.class);
CommandExecutor commandExecutor = mock(CommandExecutor.class);
when(commandExecutor.execute(any(Command.class), any(StreamConsumer.class), any(StreamConsumer.class), anyLong())).thenAnswer(new Answer<Integer>() {
@@ -156,7 +166,8 @@ public class SvnBlameCommandTest {
thrown.expect(IllegalStateException.class);
thrown.expectMessage("Unable to blame file src/foo.xoo. No blame info at line 2. Is file commited?");
- new SvnBlameCommand(commandExecutor, mock(SvnConfiguration.class)).blame(fs, Arrays.<InputFile>asList(inputFile), result);
+ when(input.filesToBlame()).thenReturn(Arrays.<InputFile>asList(inputFile));
+ new SvnBlameCommand(commandExecutor, mock(SvnConfiguration.class)).blame(input, result);
}
@Test
@@ -166,7 +177,7 @@ public class SvnBlameCommandTest {
DefaultInputFile inputFile = new DefaultInputFile("foo", "src/foo.xoo").setAbsolutePath(new File(baseDir, "src/foo.xoo").getAbsolutePath());
fs.add(inputFile);
- BlameResult result = mock(BlameResult.class);
+ BlameOutput result = mock(BlameOutput.class);
CommandExecutor commandExecutor = mock(CommandExecutor.class);
when(commandExecutor.execute(any(Command.class), any(StreamConsumer.class), any(StreamConsumer.class), anyLong())).thenAnswer(new Answer<Integer>() {
@@ -182,7 +193,8 @@ public class SvnBlameCommandTest {
thrown.expect(IllegalStateException.class);
thrown.expectMessage("The svn blame command [svn blame --xml src/foo.xoo --non-interactive] failed: My error");
- new SvnBlameCommand(commandExecutor, mock(SvnConfiguration.class)).blame(fs, Arrays.<InputFile>asList(inputFile), result);
+ when(input.filesToBlame()).thenReturn(Arrays.<InputFile>asList(inputFile));
+ new SvnBlameCommand(commandExecutor, mock(SvnConfiguration.class)).blame(input, result);
}
@Test
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 0534d92d8cb..b78deb2812c 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
@@ -23,9 +23,6 @@ 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.BatchComponent;
-import org.sonar.api.batch.InstantiationStrategy;
-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;
@@ -34,27 +31,25 @@ import org.sonar.api.utils.DateUtils;
import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
-import java.util.Date;
import java.util.List;
-@InstantiationStrategy(InstantiationStrategy.PER_BATCH)
-public class XooBlameCommand implements BlameCommand, BatchComponent {
+public class XooBlameCommand extends BlameCommand {
private static final String SCM_EXTENSION = ".scm";
@Override
- public void blame(FileSystem fs, Iterable<InputFile> files, BlameResult result) {
- for (InputFile inputFile : files) {
+ public void blame(BlameInput input, BlameOutput result) {
+ for (InputFile inputFile : input.filesToBlame()) {
processFile(inputFile, result);
}
}
@VisibleForTesting
- protected void processFile(InputFile inputFile, BlameResult result) {
+ protected void processFile(InputFile inputFile, BlameOutput result) {
File ioFile = inputFile.file();
File scmDataFile = new java.io.File(ioFile.getParentFile(), ioFile.getName() + SCM_EXTENSION);
if (!scmDataFile.exists()) {
- throw new IllegalStateException("Missing file " + scmDataFile);
+ return;
}
try {
@@ -71,13 +66,16 @@ public class XooBlameCommand implements BlameCommand, BatchComponent {
}
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]);
// Will throw an exception, when date is not in format "yyyy-MM-dd"
- Date date = dateStr != null ? DateUtils.parseDate(dateStr) : null;
- blame.add(new BlameLine(date, revision, author));
+ if (dateStr != null) {
+ blameLine.date(DateUtils.parseDate(dateStr));
+ }
+ blame.add(blameLine);
}
}
- result.add(inputFile, blame);
+ result.blameResult(inputFile, blame);
} catch (IOException e) {
throw new IllegalStateException(e);
}
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 bba495dd400..793752bcf0c 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
@@ -28,7 +28,8 @@ 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.BlameCommand.BlameInput;
+import org.sonar.api.batch.scm.BlameCommand.BlameOutput;
import org.sonar.api.batch.scm.BlameLine;
import org.sonar.api.utils.DateUtils;
import org.sonar.xoo.Xoo;
@@ -39,6 +40,7 @@ import java.util.Arrays;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
public class XooBlameCommandTest {
@@ -50,11 +52,14 @@ public class XooBlameCommandTest {
private DefaultFileSystem fs;
private File baseDir;
+ private BlameInput input;
@Before
public void prepare() throws IOException {
baseDir = temp.newFolder();
fs = new DefaultFileSystem();
+ input = mock(BlameInput.class);
+ when(input.fileSystem()).thenReturn(fs);
}
@Test
@@ -66,10 +71,11 @@ public class XooBlameCommandTest {
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")));
+ BlameOutput result = mock(BlameOutput.class);
+ when(input.filesToBlame()).thenReturn(Arrays.<InputFile>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"))));
}
-
}