]> source.dussan.org Git - sonarqube.git/commitdiff
SONAR-18210 not computing the whole file metadata when only status is needed.
authorLukasz Jarocki <lukasz.jarocki@sonarsource.com>
Mon, 8 May 2023 08:58:39 +0000 (10:58 +0200)
committersonartech <sonartech@sonarsource.com>
Mon, 8 May 2023 20:03:47 +0000 (20:03 +0000)
Co-authored-by: Duarte Meneses <duarte.meneses@sonarsource.com>
sonar-plugin-api-impl/src/main/java/org/sonar/api/batch/fs/internal/DefaultInputFile.java
sonar-plugin-api-impl/src/main/java/org/sonar/api/batch/fs/internal/TestInputFileBuilder.java
sonar-plugin-api-impl/src/test/java/org/sonar/api/batch/fs/internal/fs/DefaultInputFileTest.java
sonar-scanner-engine/src/main/java/org/sonar/scanner/scan/filesystem/FileIndexer.java
sonar-scanner-engine/src/main/java/org/sonar/scanner/scan/filesystem/MetadataGenerator.java
sonar-scanner-engine/src/main/java/org/sonar/scanner/scan/filesystem/StatusDetection.java
sonar-scanner-engine/src/test/java/org/sonar/scanner/externalissue/sarif/RegionMapperTest.java
sonar-scanner-engine/src/test/java/org/sonar/scm/git/ChangedFileTest.java

index 2af4bc494645c93fefd88889426f8a4b581dbb03..869009dac941ac2d37e296687ada3f756f771896 100644 (file)
@@ -58,6 +58,7 @@ public class DefaultInputFile extends DefaultInputComponent implements InputFile
   private final DefaultIndexedFile indexedFile;
   private final String contents;
   private final Consumer<DefaultInputFile> metadataGenerator;
+  private final Consumer<DefaultInputFile> scmStatusGenerator;
 
   private boolean published;
   private boolean excludedForCoverage;
@@ -73,15 +74,17 @@ public class DefaultInputFile extends DefaultInputComponent implements InputFile
   private boolean markedAsUnchanged;
 
 
-  public DefaultInputFile(DefaultIndexedFile indexedFile, Consumer<DefaultInputFile> metadataGenerator) {
-    this(indexedFile, metadataGenerator, null);
+  public DefaultInputFile(DefaultIndexedFile indexedFile, Consumer<DefaultInputFile> metadataGenerator, Consumer<DefaultInputFile> scmStatusGenerator) {
+    this(indexedFile, metadataGenerator, null, scmStatusGenerator);
   }
 
   // For testing
-  public DefaultInputFile(DefaultIndexedFile indexedFile, Consumer<DefaultInputFile> metadataGenerator, @Nullable String contents) {
+  public DefaultInputFile(DefaultIndexedFile indexedFile, Consumer<DefaultInputFile> metadataGenerator, @Nullable String contents,
+    Consumer<DefaultInputFile> scmStatusGenerator) {
     super(indexedFile.scannerId());
     this.indexedFile = indexedFile;
     this.metadataGenerator = metadataGenerator;
+    this.scmStatusGenerator = scmStatusGenerator;
     this.metadata = null;
     this.markedAsUnchanged = false;
     this.published = false;
@@ -95,6 +98,12 @@ public class DefaultInputFile extends DefaultInputComponent implements InputFile
     }
   }
 
+  private void checkScmStatus() {
+    if(status == null) {
+      scmStatusGenerator.accept(this);
+    }
+  }
+
   @Override
   public InputStream inputStream() throws IOException {
     return contents != null ? new ByteArrayInputStream(contents.getBytes(charset()))
@@ -226,10 +235,18 @@ public class DefaultInputFile extends DefaultInputComponent implements InputFile
    */
   @Override
   public Status status() {
-    checkMetadata();
+    checkScmStatus();
+    if(status == null) {
+      // scm might not be available, fallback to using hashes in the metadata
+      checkMetadata();
+    }
     return status;
   }
 
+  public boolean isStatusSet() {
+    return status != null;
+  }
+
   @Override
   public int lines() {
     checkMetadata();
index 550d78fc3452bc118983c989d3e22767fd7f6491..a6dcddd2229660c1627725d7ef46004e30258d42 100644 (file)
@@ -230,7 +230,7 @@ public class TestInputFileBuilder {
     DefaultIndexedFile indexedFile = new DefaultIndexedFile(absolutePath, projectKey, projectRelativePath, relativePath, type, language, id, new SensorStrategy(), oldRelativePath);
     DefaultInputFile inputFile = new DefaultInputFile(indexedFile,
       f -> f.setMetadata(new Metadata(lines, nonBlankLines, hash, originalLineStartOffsets, originalLineEndOffsets, lastValidOffset)),
-      contents);
+      contents, f -> {});
     inputFile.setStatus(status);
     inputFile.setCharset(charset);
     inputFile.setPublished(publish);
index d18edd92f3aefd3e37e66fbc5b17e5cf9fcf62dc..78c4d3954bc66120543f1baf92b742ef02d74e38 100644 (file)
@@ -33,6 +33,7 @@ import java.nio.file.Files;
 import java.nio.file.Path;
 import java.nio.file.Paths;
 import java.nio.file.StandardOpenOption;
+import java.util.function.Consumer;
 import java.util.stream.Collectors;
 import org.junit.Before;
 import org.junit.Rule;
@@ -50,6 +51,8 @@ import org.sonar.api.notifications.AnalysisWarnings;
 import static org.assertj.core.api.Assertions.assertThat;
 import static org.junit.Assert.fail;
 import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.verifyNoInteractions;
 
 public class DefaultInputFileTest {
 
@@ -74,10 +77,31 @@ public class DefaultInputFileTest {
   }
 
   @Test
-  public void test() {
+  public void status_whenScmAvailable_shouldUseScmToCompute() {
+    Consumer<DefaultInputFile> metadata = mock(Consumer.class);
+    Consumer<DefaultInputFile> scmStatus = f -> f.setStatus(InputFile.Status.SAME);
+
+    DefaultInputFile inputFile = new DefaultInputFile(indexedFile, metadata, scmStatus);
+    assertThat(inputFile.status()).isEqualTo(InputFile.Status.SAME);
+    assertThat(inputFile.isStatusSet()).isTrue();
+    verifyNoInteractions(metadata);
+  }
+
+  @Test
+  public void status_whenNoScmAvailable_shouldUseMetadataToCompute() {
+    Consumer<DefaultInputFile> metadata = f -> f.setStatus(InputFile.Status.ADDED);
+    Consumer<DefaultInputFile> scmStatus = mock(Consumer.class);
+
+    DefaultInputFile inputFile = new DefaultInputFile(indexedFile, metadata, scmStatus);
+    assertThat(inputFile.status()).isEqualTo(InputFile.Status.ADDED);
+    assertThat(inputFile.isStatusSet()).isTrue();
+    verify(scmStatus).accept(inputFile);
+  }
 
+  @Test
+  public void test() {
     Metadata metadata = new Metadata(42, 42, "", new int[0], new int[0], 10);
-    DefaultInputFile inputFile = new DefaultInputFile(indexedFile, (f) -> f.setMetadata(metadata))
+    DefaultInputFile inputFile = new DefaultInputFile(indexedFile, f -> f.setMetadata(metadata), NO_OP)
       .setStatus(InputFile.Status.ADDED)
       .setCharset(StandardCharsets.ISO_8859_1);
 
@@ -104,10 +128,11 @@ public class DefaultInputFileTest {
 
   @Test
   public void test_moved_file() {
-    DefaultIndexedFile indexedFileForMovedFile = new DefaultIndexedFile(baseDir.resolve(PROJECT_RELATIVE_PATH), "ABCDE", PROJECT_RELATIVE_PATH, MODULE_RELATIVE_PATH, InputFile.Type.TEST, "php", 0,
+    DefaultIndexedFile indexedFileForMovedFile = new DefaultIndexedFile(baseDir.resolve(PROJECT_RELATIVE_PATH), "ABCDE", PROJECT_RELATIVE_PATH, MODULE_RELATIVE_PATH,
+      InputFile.Type.TEST, "php", 0,
       sensorStrategy, OLD_RELATIVE_PATH);
     Metadata metadata = new Metadata(42, 42, "", new int[0], new int[0], 10);
-    DefaultInputFile inputFile = new DefaultInputFile(indexedFileForMovedFile, (f) -> f.setMetadata(metadata))
+    DefaultInputFile inputFile = new DefaultInputFile(indexedFileForMovedFile, f -> f.setMetadata(metadata), NO_OP)
       .setStatus(InputFile.Status.ADDED)
       .setCharset(StandardCharsets.ISO_8859_1);
 
@@ -125,7 +150,7 @@ public class DefaultInputFileTest {
 
     Metadata metadata = new Metadata(42, 30, "", new int[0], new int[0], 10);
 
-    DefaultInputFile inputFile = new DefaultInputFile(indexedFile, f -> f.setMetadata(metadata))
+    DefaultInputFile inputFile = new DefaultInputFile(indexedFile, f -> f.setMetadata(metadata), NO_OP)
       .setStatus(InputFile.Status.ADDED)
       .setCharset(StandardCharsets.ISO_8859_1);
 
@@ -151,7 +176,7 @@ public class DefaultInputFileTest {
 
     Metadata metadata = new Metadata(42, 30, "", new int[0], new int[0], 10);
 
-    DefaultInputFile inputFile = new DefaultInputFile(indexedFile, f -> f.setMetadata(metadata))
+    DefaultInputFile inputFile = new DefaultInputFile(indexedFile, f -> f.setMetadata(metadata), NO_OP)
       .setStatus(InputFile.Status.ADDED)
       .setCharset(StandardCharsets.UTF_8);
 
@@ -165,9 +190,9 @@ public class DefaultInputFileTest {
 
   @Test
   public void test_equals_and_hashcode() {
-    DefaultInputFile f1 = new DefaultInputFile(new DefaultIndexedFile("ABCDE", Paths.get("module"), MODULE_RELATIVE_PATH, null), (f) -> mock(Metadata.class));
-    DefaultInputFile f1a = new DefaultInputFile(new DefaultIndexedFile("ABCDE", Paths.get("module"), MODULE_RELATIVE_PATH, null), (f) -> mock(Metadata.class));
-    DefaultInputFile f2 = new DefaultInputFile(new DefaultIndexedFile("ABCDE", Paths.get("module"), "src/Bar.php", null), (f) -> mock(Metadata.class));
+    DefaultInputFile f1 = new DefaultInputFile(new DefaultIndexedFile("ABCDE", Paths.get("module"), MODULE_RELATIVE_PATH, null), NO_OP, NO_OP);
+    DefaultInputFile f1a = new DefaultInputFile(new DefaultIndexedFile("ABCDE", Paths.get("module"), MODULE_RELATIVE_PATH, null), NO_OP, NO_OP);
+    DefaultInputFile f2 = new DefaultInputFile(new DefaultIndexedFile("ABCDE", Paths.get("module"), "src/Bar.php", null), NO_OP, NO_OP);
 
     assertThat(f1)
       .isEqualTo(f1)
@@ -183,14 +208,15 @@ public class DefaultInputFileTest {
 
   @Test
   public void test_toString() {
-    DefaultInputFile file = new DefaultInputFile(new DefaultIndexedFile("ABCDE", Paths.get("module"), MODULE_RELATIVE_PATH, null), (f) -> mock(Metadata.class));
+    DefaultInputFile file = new DefaultInputFile(new DefaultIndexedFile("ABCDE", Paths.get("module"), MODULE_RELATIVE_PATH, null), NO_OP, NO_OP);
     assertThat(file).hasToString(MODULE_RELATIVE_PATH);
   }
 
   @Test
   public void checkValidPointer() {
-    Metadata metadata = new Metadata(2, 2, "", new int[]{0, 10}, new int[]{9, 15}, 16);
-    DefaultInputFile file = new DefaultInputFile(new DefaultIndexedFile("ABCDE", Paths.get("module"), MODULE_RELATIVE_PATH, null), f -> f.setMetadata(metadata));
+    Metadata metadata = new Metadata(2, 2, "", new int[] {0, 10}, new int[] {9, 15}, 16);
+    DefaultInputFile file = new DefaultInputFile(new DefaultIndexedFile("ABCDE", Paths.get("module"), MODULE_RELATIVE_PATH, null),
+      f -> f.setMetadata(metadata), NO_OP);
     assertThat(file.newPointer(1, 0).line()).isOne();
     assertThat(file.newPointer(1, 0).lineOffset()).isZero();
     // Don't fail
@@ -226,8 +252,10 @@ public class DefaultInputFileTest {
 
   @Test
   public void checkValidPointerUsingGlobalOffset() {
-    Metadata metadata = new Metadata(2, 2, "", new int[]{0, 10}, new int[]{8, 15}, 16);
-    DefaultInputFile file = new DefaultInputFile(new DefaultIndexedFile("ABCDE", Paths.get("module"), MODULE_RELATIVE_PATH, null), f -> f.setMetadata(metadata));
+    Metadata metadata = new Metadata(2, 2, "", new int[] {0, 10}, new int[] {8, 15}, 16);
+    DefaultInputFile file = new DefaultInputFile(new DefaultIndexedFile("ABCDE", Paths.get("module"), MODULE_RELATIVE_PATH, null),
+      f -> f.setMetadata(metadata), f -> {
+    });
     assertThat(file.newPointer(0).line()).isOne();
     assertThat(file.newPointer(0).lineOffset()).isZero();
 
@@ -263,7 +291,8 @@ public class DefaultInputFileTest {
   @Test
   public void checkValidRange() {
     Metadata metadata = new FileMetadata(mock(AnalysisWarnings.class)).readMetadata(new StringReader("bla bla a\nabcde"));
-    DefaultInputFile file = new DefaultInputFile(new DefaultIndexedFile("ABCDE", Paths.get("module"), MODULE_RELATIVE_PATH, null), f -> f.setMetadata(metadata));
+    DefaultInputFile file = new DefaultInputFile(new DefaultIndexedFile("ABCDE", Paths.get("module"), MODULE_RELATIVE_PATH, null),
+      f -> f.setMetadata(metadata), NO_OP);
 
     assertThat(file.newRange(file.newPointer(1, 0), file.newPointer(2, 1)).start().line()).isOne();
     // Don't fail
@@ -289,7 +318,8 @@ public class DefaultInputFileTest {
   @Test
   public void selectLine() {
     Metadata metadata = new FileMetadata(mock(AnalysisWarnings.class)).readMetadata(new StringReader("bla bla a\nabcde\n\nabc"));
-    DefaultInputFile file = new DefaultInputFile(new DefaultIndexedFile("ABCDE", Paths.get("module"), MODULE_RELATIVE_PATH, null), f -> f.setMetadata(metadata));
+    DefaultInputFile file = new DefaultInputFile(new DefaultIndexedFile("ABCDE", Paths.get("module"), MODULE_RELATIVE_PATH, null),
+      f -> f.setMetadata(metadata), NO_OP);
 
     assertThat(file.selectLine(1).start().line()).isOne();
     assertThat(file.selectLine(1).start().lineOffset()).isZero();
@@ -312,8 +342,9 @@ public class DefaultInputFileTest {
 
   @Test
   public void checkValidRangeUsingGlobalOffset() {
-    Metadata metadata = new Metadata(2, 2, "", new int[]{0, 10}, new int[]{9, 15}, 16);
-    DefaultInputFile file = new DefaultInputFile(new DefaultIndexedFile("ABCDE", Paths.get("module"), MODULE_RELATIVE_PATH, null), f -> f.setMetadata(metadata));
+    Metadata metadata = new Metadata(2, 2, "", new int[] {0, 10}, new int[] {9, 15}, 16);
+    DefaultInputFile file = new DefaultInputFile(new DefaultIndexedFile("ABCDE", Paths.get("module"), MODULE_RELATIVE_PATH, null),
+      f -> f.setMetadata(metadata), NO_OP);
     TextRange newRange = file.newRange(10, 13);
     assertThat(newRange.start().line()).isEqualTo(2);
     assertThat(newRange.start().lineOffset()).isZero();
@@ -323,12 +354,16 @@ public class DefaultInputFileTest {
 
   @Test
   public void testRangeOverlap() {
-    Metadata metadata = new Metadata(2, 2, "", new int[]{0, 10}, new int[]{9, 15}, 16);
-    DefaultInputFile file = new DefaultInputFile(new DefaultIndexedFile("ABCDE", Paths.get("module"), MODULE_RELATIVE_PATH, null), f -> f.setMetadata(metadata));
+    Metadata metadata = new Metadata(2, 2, "", new int[] {0, 10}, new int[] {9, 15}, 16);
+    DefaultInputFile file = new DefaultInputFile(new DefaultIndexedFile("ABCDE", Paths.get("module"), MODULE_RELATIVE_PATH, null),
+      f -> f.setMetadata(metadata), NO_OP);
     // Don't fail
     assertThat(file.newRange(file.newPointer(1, 0), file.newPointer(1, 1)).overlap(file.newRange(file.newPointer(1, 0), file.newPointer(1, 1)))).isTrue();
     assertThat(file.newRange(file.newPointer(1, 0), file.newPointer(1, 1)).overlap(file.newRange(file.newPointer(1, 0), file.newPointer(1, 2)))).isTrue();
     assertThat(file.newRange(file.newPointer(1, 0), file.newPointer(1, 1)).overlap(file.newRange(file.newPointer(1, 1), file.newPointer(1, 2)))).isFalse();
     assertThat(file.newRange(file.newPointer(1, 2), file.newPointer(1, 3)).overlap(file.newRange(file.newPointer(1, 0), file.newPointer(1, 2)))).isFalse();
   }
+
+  private static final Consumer<DefaultInputFile> NO_OP = f -> {
+  };
 }
index e07679e003fb1f5278bb68badf749d286bbe8ba8..2d177d4edee5332600212615f34301733a13d890 100644 (file)
@@ -68,6 +68,7 @@ public class FileIndexer {
   private final InputComponentStore componentStore;
   private final SensorStrategy sensorStrategy;
   private final LanguageDetection langDetection;
+  private final StatusDetection statusDetection;
   private final ScmChangedFiles scmChangedFiles;
 
   private boolean warnInclusionsAlreadyLogged;
@@ -78,7 +79,7 @@ public class FileIndexer {
   public FileIndexer(DefaultInputProject project, ScannerComponentIdGenerator scannerComponentIdGenerator, InputComponentStore componentStore,
     ProjectExclusionFilters projectExclusionFilters, ProjectCoverageAndDuplicationExclusions projectCoverageAndDuplicationExclusions, IssueExclusionsLoader issueExclusionsLoader,
     MetadataGenerator metadataGenerator, SensorStrategy sensorStrategy, LanguageDetection languageDetection, AnalysisWarnings analysisWarnings, ScanProperties properties,
-    InputFileFilter[] filters, ScmChangedFiles scmChangedFiles) {
+    InputFileFilter[] filters, ScmChangedFiles scmChangedFiles, StatusDetection statusDetection) {
     this.project = project;
     this.scannerComponentIdGenerator = scannerComponentIdGenerator;
     this.componentStore = componentStore;
@@ -92,6 +93,7 @@ public class FileIndexer {
     this.filters = filters;
     this.projectExclusionFilters = projectExclusionFilters;
     this.scmChangedFiles = scmChangedFiles;
+    this.statusDetection = statusDetection;
   }
 
   void indexFile(DefaultInputModule module, ModuleExclusionFilters moduleExclusionFilters, ModuleCoverageAndDuplicationExclusions moduleCoverageAndDuplicationExclusions,
@@ -145,7 +147,8 @@ public class FileIndexer {
       scmChangedFiles.getOldRelativeFilePath(realAbsoluteFile)
     );
 
-    DefaultInputFile inputFile = new DefaultInputFile(indexedFile, f -> metadataGenerator.setMetadata(module.key(), f, module.getEncoding()));
+    DefaultInputFile inputFile = new DefaultInputFile(indexedFile, f -> metadataGenerator.setMetadata(module.key(), f, module.getEncoding()),
+      f -> f.setStatus(statusDetection.findStatusFromScm(f)));
     if (language != null && language.isPublishAllFiles()) {
       inputFile.setPublished(true);
     }
index 627cb3adc1782f2ef0cd818ac75ea2c8f01aaa96..562fcbe338aed5368725751bd85ebea83c42c7e2 100644 (file)
@@ -63,7 +63,9 @@ public class MetadataGenerator {
       inputFile.setCharset(charset);
       Metadata metadata = fileMetadata.readMetadata(is, charset, inputFile.absolutePath(), exclusionsScanner.createCharHandlerFor(inputFile));
       inputFile.setMetadata(metadata);
-      inputFile.setStatus(statusDetection.status(moduleKeyWithBranch, inputFile, metadata.hash()));
+      if(!inputFile.isStatusSet()) {
+        inputFile.setStatus(statusDetection.status(moduleKeyWithBranch, inputFile, metadata.hash()));
+      }
       LOG.debug("'{}' generated metadata{} with charset '{}'", inputFile, inputFile.type() == Type.TEST ? " as test " : "", charset);
     } catch (Exception e) {
       throw new IllegalStateException(e);
index 8c7d8af91da434ea4d78a730dfd5b8ea6497f92e..65349df4120cab64674fac6e672fbd1f083a2bc9 100644 (file)
@@ -41,13 +41,25 @@ public class StatusDetection {
     this.scmChangedFiles = scmChangedFiles;
   }
 
+  public boolean isScmStatusAvailable() {
+    return scmChangedFiles.isValid();
+  }
+
   InputFile.Status status(String moduleKeyWithBranch, DefaultInputFile inputFile, String hash) {
-    if (scmChangedFiles.isValid()) {
-      return checkChangedWithScm(inputFile);
+    InputFile.Status statusFromScm = findStatusFromScm(inputFile);
+    if (statusFromScm != null) {
+      return statusFromScm;
     }
     return checkChangedWithProjectRepositories(moduleKeyWithBranch, inputFile, hash);
   }
 
+  InputFile.Status findStatusFromScm(DefaultInputFile inputFile) {
+    if (isScmStatusAvailable()) {
+      return checkChangedWithScm(inputFile);
+    }
+    return null;
+  }
+
   private InputFile.Status checkChangedWithProjectRepositories(String moduleKeyWithBranch, DefaultInputFile inputFile, String hash) {
     FileData fileDataPerPath = projectRepositories.fileData(moduleKeyWithBranch, inputFile);
     if (fileDataPerPath == null) {
index 2b305833b52f0a7b528c60e16c5c8d12b1a484b9..6883d28e7eff7a44b67dd444853c297330932e71 100644 (file)
@@ -48,8 +48,8 @@ import static org.mockito.Mockito.when;
 public class RegionMapperTest {
   private static final int LINE_END_OFFSET = 10;
   private static final DefaultInputFile INPUT_FILE = new DefaultInputFile(new DefaultIndexedFile("ABCDE", Paths.get("module"), "relative/path", null),
-    f -> f.setMetadata(generateMetadata()));
-
+    f -> f.setMetadata(generateMetadata()), f -> {
+  });
 
   private static Metadata generateMetadata() {
     Metadata metadata = mock(Metadata.class);
@@ -97,9 +97,9 @@ public class RegionMapperTest {
 
   @DataProvider
   public static Object[][] index() {
-    return new Object[][]{
-      {1,3, 0,2},
-      {5,8, 4,7}
+    return new Object[][] {
+      {1, 3, 0, 2},
+      {5, 8, 4, 7}
     };
   }
 
index 1b7219ca85d335bac32810d06b720fa19756c0ed..adaf4ed24a93c5b5d779a75793a10a3c16f8ed7d 100644 (file)
@@ -30,11 +30,10 @@ import static org.apache.commons.lang.RandomStringUtils.random;
 import static org.apache.commons.lang.RandomStringUtils.randomNumeric;
 import static org.assertj.core.api.Assertions.assertThat;
 
-
 public class ChangedFileTest {
 
   @Test
-  public void test_unMovedFile(){
+  public void test_unMovedFile() {
     Path absolutePath = Path.of("/absolutePath");
     ChangedFile changedFile = ChangedFile.of(absolutePath);
 
@@ -44,7 +43,7 @@ public class ChangedFileTest {
   }
 
   @Test
-  public void test_movedFile(){
+  public void test_movedFile() {
     Path absolutePath = Path.of("/absolutePath");
     ChangedFile changedFile = ChangedFile.of(absolutePath, "/oldRelativePath");
 
@@ -54,7 +53,7 @@ public class ChangedFileTest {
   }
 
   @Test
-  public void test_equalsAndHashCode(){
+  public void test_equalsAndHashCode() {
     Path absolutePath = Path.of("/absolutePath");
     ChangedFile changedFile1 = ChangedFile.of(absolutePath, "/oldRelativePath");
     ChangedFile changedFile2 = ChangedFile.of(absolutePath, "/oldRelativePath");
@@ -76,7 +75,8 @@ public class ChangedFileTest {
 
   private DefaultInputFile composeDefaultInputFile(Path path, String oldRelativeReference) {
     DefaultIndexedFile indexedFile = composeDefaultIndexFile(path, oldRelativeReference);
-    return new DefaultInputFile(indexedFile, f -> f.setPublished(true));
+    return new DefaultInputFile(indexedFile, f -> f.setPublished(true), f -> {
+    });
   }
 
   private DefaultIndexedFile composeDefaultIndexFile(Path path, String oldRelativePath) {