}
private static List<BlameLine> readFile(File inputStream) throws IOException {
+ Date now = new Date();
try (CSVParser csvParser = CSVFormat.RFC4180
.withIgnoreEmptyLines()
.withIgnoreSurroundingSpaces()
.parse(new FileReader(inputStream))) {
List<CSVRecord> records = csvParser.getRecords();
return records.stream()
- .map(XooBlameCommand::convertToBlameLine)
+ .map(r -> convertToBlameLine(now, r))
.collect(toList());
}
}
- private static BlameLine convertToBlameLine(CSVRecord csvRecord) {
+ private static BlameLine convertToBlameLine(Date now, 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));
+ // try to load a relative number of days
+ try {
+ int days = Integer.parseInt(dateStr);
+ blameLine.date(DateUtils.addDays(now, days));
+ } catch (NumberFormatException e) {
+ 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;
import java.io.File;
import java.io.IOException;
import java.util.Arrays;
+import java.util.Date;
+import java.util.List;
+import java.util.function.Predicate;
import org.apache.commons.io.FileUtils;
import org.junit.Before;
import org.junit.Rule;
import org.junit.Test;
import org.junit.rules.TemporaryFolder;
+import org.mockito.ArgumentCaptor;
import org.sonar.api.batch.fs.internal.DefaultFileSystem;
import org.sonar.api.batch.fs.internal.DefaultInputFile;
import org.sonar.api.batch.fs.internal.TestInputFileBuilder;
import org.sonar.xoo.Xoo;
import static java.util.Collections.singletonList;
+import static org.assertj.core.api.Assertions.assertThat;
+import static org.mockito.ArgumentMatchers.eq;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
new BlameLine().revision("234").author("julien").date(DateUtils.parseDate("2014-12-24"))));
}
+ @Test
+ public void testBlameWithRelativeDate() 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,-10\n234,julien,-10");
+ 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);
+
+ Predicate<Date> datePredicate = argument -> {
+ Date approximate = DateUtils.addDays(new Date(), -10);
+ return argument.getTime() > approximate.getTime() - 5000 && argument.getTime() < approximate.getTime() + 5000;
+ };
+ ArgumentCaptor<List<BlameLine>> blameLinesCaptor = ArgumentCaptor.forClass(List.class);
+ verify(result).blameResult(eq(inputFile), blameLinesCaptor.capture());
+ assertThat(blameLinesCaptor.getValue())
+ .extracting(BlameLine::date)
+ .allMatch(datePredicate);
+ }
+
@Test
public void blame_containing_author_with_comma() throws IOException {
File source = new File(baseDir, "src/foo.xoo");