public void finish(boolean success) {
    progressReport.stopAndLogTotalTime("SCM Publisher " + count + "/" + total + " " + pluralize(count) + " have been analyzed");
    if (success && !allFilesToBlame.isEmpty()) {
      LOG.warn("Missing blame information for the following files:");
      for (InputFile f : allFilesToBlame) {
        LOG.warn("  * " + f);
      }
      LOG.warn("This may lead to missing/broken features in SonarQube");
      String docUrl = documentationLinkGenerator.getDocumentationLink(SCM_INTEGRATION_DOCUMENTATION_SUFFIX);
      analysisWarnings.addUnique(format("Missing blame information for %d %s. This may lead to some features not working correctly. " +
        "Please check the analysis logs and refer to <a href=\"%s\" rel=\"noopener noreferrer\" target=\"_blank\">the documentation</a>.",
        allFilesToBlame.size(),
        allFilesToBlame.size() > 1 ? "files" : "file",
        docUrl));
    }
  }
@Test
  public void addWarningIfFilesMissing() {
    when(documentationLinkGenerator.getDocumentationLink(SCM_INTEGRATION_DOCUMENTATION_SUFFIX)).thenReturn(DOC_LINK);
    InputFile file = new TestInputFileBuilder("foo", "src/main/java/Foo.java").setLines(10).build();
    new DefaultBlameOutput(null, analysisWarnings, singletonList(file), documentationLinkGenerator).finish(true);
    assertThat(analysisWarnings.warnings()).extracting(DefaultAnalysisWarnings.Message::getText)
      .containsOnly("Missing blame information for 1 file. This may lead to some features not working correctly. " +
        "Please check the analysis logs and refer to <a href=\"" + DOC_LINK + "\" rel=\"noopener noreferrer\" target=\"_blank\">the documentation</a>.");
  }