*/ | */ | ||||
package org.sonar.scanner.repository; | package org.sonar.scanner.repository; | ||||
import java.util.function.Supplier; | |||||
import org.sonar.api.utils.log.Logger; | import org.sonar.api.utils.log.Logger; | ||||
import org.sonar.api.utils.log.Loggers; | import org.sonar.api.utils.log.Loggers; | ||||
import org.sonar.api.utils.log.Profiler; | import org.sonar.api.utils.log.Profiler; | ||||
import org.sonar.scanner.bootstrap.ScannerProperties; | import org.sonar.scanner.bootstrap.ScannerProperties; | ||||
import org.sonar.scanner.scan.branch.BranchConfiguration; | import org.sonar.scanner.scan.branch.BranchConfiguration; | ||||
import org.springframework.context.annotation.Bean; | |||||
public class ProjectRepositoriesSupplier implements Supplier<ProjectRepositories> { | |||||
private static final Logger LOG = Loggers.get(ProjectRepositoriesSupplier.class); | |||||
public class ProjectRepositoriesProvider { | |||||
private static final Logger LOG = Loggers.get(ProjectRepositoriesProvider.class); | |||||
private static final String LOG_MSG = "Load project repositories"; | private static final String LOG_MSG = "Load project repositories"; | ||||
private final ProjectRepositoriesLoader loader; | private final ProjectRepositoriesLoader loader; | ||||
private final ScannerProperties scannerProperties; | private final ScannerProperties scannerProperties; | ||||
private final BranchConfiguration branchConfig; | private final BranchConfiguration branchConfig; | ||||
private ProjectRepositories project = null; | |||||
public ProjectRepositoriesSupplier(ProjectRepositoriesLoader loader, ScannerProperties scannerProperties, BranchConfiguration branchConfig) { | |||||
public ProjectRepositoriesProvider(ProjectRepositoriesLoader loader, ScannerProperties scannerProperties, BranchConfiguration branchConfig) { | |||||
this.loader = loader; | this.loader = loader; | ||||
this.scannerProperties = scannerProperties; | this.scannerProperties = scannerProperties; | ||||
this.branchConfig = branchConfig; | this.branchConfig = branchConfig; | ||||
} | } | ||||
public ProjectRepositories get() { | |||||
if (project == null) { | |||||
Profiler profiler = Profiler.create(LOG).startInfo(LOG_MSG); | |||||
project = loader.load(scannerProperties.getProjectKey(), branchConfig.referenceBranchName()); | |||||
profiler.stopInfo(); | |||||
} | |||||
@Bean | |||||
public ProjectRepositories projectRepositories() { | |||||
Profiler profiler = Profiler.create(LOG).startInfo(LOG_MSG); | |||||
ProjectRepositories project = loader.load(scannerProperties.getProjectKey(), branchConfig.referenceBranchName()); | |||||
profiler.stopInfo(); | |||||
return project; | return project; | ||||
} | } | ||||
} | } |
import org.sonar.scanner.repository.ContextPropertiesCache; | import org.sonar.scanner.repository.ContextPropertiesCache; | ||||
import org.sonar.scanner.repository.DefaultProjectRepositoriesLoader; | import org.sonar.scanner.repository.DefaultProjectRepositoriesLoader; | ||||
import org.sonar.scanner.repository.DefaultQualityProfileLoader; | import org.sonar.scanner.repository.DefaultQualityProfileLoader; | ||||
import org.sonar.scanner.repository.ProjectRepositoriesSupplier; | |||||
import org.sonar.scanner.repository.ProjectRepositoriesProvider; | |||||
import org.sonar.scanner.repository.QualityProfilesProvider; | import org.sonar.scanner.repository.QualityProfilesProvider; | ||||
import org.sonar.scanner.repository.ReferenceBranchSupplier; | import org.sonar.scanner.repository.ReferenceBranchSupplier; | ||||
import org.sonar.scanner.repository.language.DefaultLanguagesRepository; | import org.sonar.scanner.repository.language.DefaultLanguagesRepository; | ||||
new BranchConfigurationProvider(), | new BranchConfigurationProvider(), | ||||
new ProjectBranchesProvider(), | new ProjectBranchesProvider(), | ||||
new ProjectPullRequestsProvider(), | new ProjectPullRequestsProvider(), | ||||
ProjectRepositoriesSupplier.class, | |||||
ProjectRepositoriesProvider.class, | |||||
new ProjectServerSettingsProvider(), | new ProjectServerSettingsProvider(), | ||||
AnalysisCacheEnabled.class, | AnalysisCacheEnabled.class, | ||||
import org.sonar.api.batch.fs.InputFile; | import org.sonar.api.batch.fs.InputFile; | ||||
import org.sonar.api.batch.fs.internal.DefaultInputFile; | import org.sonar.api.batch.fs.internal.DefaultInputFile; | ||||
import org.sonar.scanner.repository.FileData; | import org.sonar.scanner.repository.FileData; | ||||
import org.sonar.scanner.repository.ProjectRepositoriesSupplier; | |||||
import org.sonar.scanner.repository.ProjectRepositories; | |||||
import org.sonar.scanner.scm.ScmChangedFiles; | import org.sonar.scanner.scm.ScmChangedFiles; | ||||
import static org.sonar.api.batch.fs.InputFile.Status.ADDED; | import static org.sonar.api.batch.fs.InputFile.Status.ADDED; | ||||
@Immutable | @Immutable | ||||
public class StatusDetection { | public class StatusDetection { | ||||
private final ProjectRepositoriesSupplier projectSettingsSupplier; | |||||
private final ProjectRepositories projectRepositories; | |||||
private final ScmChangedFiles scmChangedFiles; | private final ScmChangedFiles scmChangedFiles; | ||||
public StatusDetection(ProjectRepositoriesSupplier projectSettingsSupplier, ScmChangedFiles scmChangedFiles) { | |||||
this.projectSettingsSupplier = projectSettingsSupplier; | |||||
public StatusDetection(ProjectRepositories projectRepositories, ScmChangedFiles scmChangedFiles) { | |||||
this.projectRepositories = projectRepositories; | |||||
this.scmChangedFiles = scmChangedFiles; | this.scmChangedFiles = scmChangedFiles; | ||||
} | } | ||||
} | } | ||||
private InputFile.Status checkChangedWithProjectRepositories(String moduleKeyWithBranch, DefaultInputFile inputFile, String hash) { | private InputFile.Status checkChangedWithProjectRepositories(String moduleKeyWithBranch, DefaultInputFile inputFile, String hash) { | ||||
FileData fileDataPerPath = projectSettingsSupplier.get().fileData(moduleKeyWithBranch, inputFile); | |||||
FileData fileDataPerPath = projectRepositories.fileData(moduleKeyWithBranch, inputFile); | |||||
if (fileDataPerPath == null) { | if (fileDataPerPath == null) { | ||||
return ADDED; | return ADDED; | ||||
} | } |
import org.sonar.scanner.protocol.output.ScannerReportWriter; | import org.sonar.scanner.protocol.output.ScannerReportWriter; | ||||
import org.sonar.scanner.report.ReportPublisher; | import org.sonar.scanner.report.ReportPublisher; | ||||
import org.sonar.scanner.repository.FileData; | import org.sonar.scanner.repository.FileData; | ||||
import org.sonar.scanner.repository.ProjectRepositoriesSupplier; | |||||
import org.sonar.scanner.repository.ProjectRepositories; | |||||
import org.sonar.scanner.scan.branch.BranchConfiguration; | import org.sonar.scanner.scan.branch.BranchConfiguration; | ||||
import org.sonar.scanner.scan.filesystem.InputComponentStore; | import org.sonar.scanner.scan.filesystem.InputComponentStore; | ||||
private static final Logger LOG = Loggers.get(ScmPublisher.class); | private static final Logger LOG = Loggers.get(ScmPublisher.class); | ||||
private final ScmConfiguration configuration; | private final ScmConfiguration configuration; | ||||
private final ProjectRepositoriesSupplier projectRepositoriesSupplier; | |||||
private final ProjectRepositories projectRepositories; | |||||
private final InputComponentStore componentStore; | private final InputComponentStore componentStore; | ||||
private final FileSystem fs; | private final FileSystem fs; | ||||
private final ScannerReportWriter writer; | private final ScannerReportWriter writer; | ||||
private AnalysisWarnings analysisWarnings; | private AnalysisWarnings analysisWarnings; | ||||
private final BranchConfiguration branchConfiguration; | private final BranchConfiguration branchConfiguration; | ||||
public ScmPublisher(ScmConfiguration configuration, ProjectRepositoriesSupplier projectRepositoriesSupplier, InputComponentStore componentStore, FileSystem fs, | |||||
public ScmPublisher(ScmConfiguration configuration, ProjectRepositories projectRepositories, InputComponentStore componentStore, FileSystem fs, | |||||
ReportPublisher reportPublisher, BranchConfiguration branchConfiguration, AnalysisWarnings analysisWarnings) { | ReportPublisher reportPublisher, BranchConfiguration branchConfiguration, AnalysisWarnings analysisWarnings) { | ||||
this.configuration = configuration; | this.configuration = configuration; | ||||
this.projectRepositoriesSupplier = projectRepositoriesSupplier; | |||||
this.projectRepositories = projectRepositories; | |||||
this.componentStore = componentStore; | this.componentStore = componentStore; | ||||
this.fs = fs; | this.fs = fs; | ||||
this.branchConfiguration = branchConfiguration; | this.branchConfiguration = branchConfiguration; | ||||
if (configuration.forceReloadAll() || f.status() != Status.SAME) { | if (configuration.forceReloadAll() || f.status() != Status.SAME) { | ||||
addIfNotEmpty(filesToBlame, f); | addIfNotEmpty(filesToBlame, f); | ||||
} else if (!branchConfiguration.isPullRequest()) { | } else if (!branchConfiguration.isPullRequest()) { | ||||
FileData fileData = projectRepositoriesSupplier.get().fileData(componentStore.findModule(f).key(), f); | |||||
FileData fileData = projectRepositories.fileData(componentStore.findModule(f).key(), f); | |||||
if (fileData == null || StringUtils.isEmpty(fileData.revision())) { | if (fileData == null || StringUtils.isEmpty(fileData.revision())) { | ||||
addIfNotEmpty(filesToBlame, f); | addIfNotEmpty(filesToBlame, f); | ||||
} else { | } else { |
import static org.mockito.Mockito.verifyNoMoreInteractions; | import static org.mockito.Mockito.verifyNoMoreInteractions; | ||||
import static org.mockito.Mockito.when; | import static org.mockito.Mockito.when; | ||||
public class ProjectRepositoriesSupplierTest { | |||||
private ProjectRepositoriesSupplier underTest; | |||||
public class ProjectRepositoriesProviderTest { | |||||
private ProjectRepositoriesProvider underTest; | |||||
private ProjectRepositories project; | private ProjectRepositories project; | ||||
private ProjectRepositoriesLoader loader = mock(ProjectRepositoriesLoader.class); | |||||
private ScannerProperties props = mock(ScannerProperties.class); | |||||
private BranchConfiguration branchConfiguration = mock(BranchConfiguration.class); | |||||
private final ProjectRepositoriesLoader loader = mock(ProjectRepositoriesLoader.class); | |||||
private final ScannerProperties props = mock(ScannerProperties.class); | |||||
private final BranchConfiguration branchConfiguration = mock(BranchConfiguration.class); | |||||
@Before | @Before | ||||
public void setUp() { | public void setUp() { | ||||
underTest = new ProjectRepositoriesSupplier(loader, props, branchConfiguration); | |||||
underTest = new ProjectRepositoriesProvider(loader, props, branchConfiguration); | |||||
Map<String, FileData> fileMap = emptyMap(); | Map<String, FileData> fileMap = emptyMap(); | ||||
project = new SingleProjectRepository(fileMap); | project = new SingleProjectRepository(fileMap); | ||||
when(props.getProjectKey()).thenReturn("key"); | when(props.getProjectKey()).thenReturn("key"); | ||||
@Test | @Test | ||||
public void testValidation() { | public void testValidation() { | ||||
when(loader.load(eq("key"), any())).thenReturn(project); | when(loader.load(eq("key"), any())).thenReturn(project); | ||||
underTest.get(); | |||||
assertThat(underTest.projectRepositories()).isEqualTo(project); | |||||
} | } | ||||
@Test | @Test | ||||
public void testAssociated() { | public void testAssociated() { | ||||
when(loader.load(eq("key"), any())).thenReturn(project); | when(loader.load(eq("key"), any())).thenReturn(project); | ||||
ProjectRepositories repo = underTest.get(); | |||||
ProjectRepositories repo = underTest.projectRepositories(); | |||||
assertThat(repo.exists()).isTrue(); | assertThat(repo.exists()).isTrue(); | ||||
verify(props).getProjectKey(); | verify(props).getProjectKey(); | ||||
verify(loader).load(eq("key"), eq(null)); | |||||
verify(loader).load("key", null); | |||||
verifyNoMoreInteractions(loader, props); | verifyNoMoreInteractions(loader, props); | ||||
} | } | ||||
} | } |
import java.util.Collections; | import java.util.Collections; | ||||
import java.util.HashMap; | import java.util.HashMap; | ||||
import java.util.Map; | import java.util.Map; | ||||
import org.junit.Before; | |||||
import org.junit.Test; | import org.junit.Test; | ||||
import org.sonar.api.batch.fs.InputFile; | import org.sonar.api.batch.fs.InputFile; | ||||
import org.sonar.api.batch.fs.internal.DefaultInputFile; | import org.sonar.api.batch.fs.internal.DefaultInputFile; | ||||
import org.sonar.api.batch.fs.internal.TestInputFileBuilder; | import org.sonar.api.batch.fs.internal.TestInputFileBuilder; | ||||
import org.sonar.scanner.repository.FileData; | import org.sonar.scanner.repository.FileData; | ||||
import org.sonar.scanner.repository.ProjectRepositoriesSupplier; | |||||
import org.sonar.scanner.repository.ProjectRepositories; | |||||
import org.sonar.scanner.repository.SingleProjectRepository; | import org.sonar.scanner.repository.SingleProjectRepository; | ||||
import org.sonar.scanner.scm.ScmChangedFiles; | import org.sonar.scanner.scm.ScmChangedFiles; | ||||
import static org.assertj.core.api.Assertions.assertThat; | import static org.assertj.core.api.Assertions.assertThat; | ||||
import static org.mockito.Mockito.mock; | |||||
import static org.mockito.Mockito.when; | |||||
public class StatusDetectionTest { | public class StatusDetectionTest { | ||||
private ProjectRepositoriesSupplier projectRepositoriesSupplier = mock(ProjectRepositoriesSupplier.class); | |||||
@Before | |||||
public void setUp() { | |||||
when(projectRepositoriesSupplier.get()).thenReturn(new SingleProjectRepository(createFileDataPerPathMap())); | |||||
} | |||||
private final ProjectRepositories projectRepositories = new SingleProjectRepository(createFileDataPerPathMap()); | |||||
@Test | @Test | ||||
public void detect_status() { | public void detect_status() { | ||||
ScmChangedFiles changedFiles = new ScmChangedFiles(null); | ScmChangedFiles changedFiles = new ScmChangedFiles(null); | ||||
StatusDetection statusDetection = new StatusDetection(projectRepositoriesSupplier, changedFiles); | |||||
StatusDetection statusDetection = new StatusDetection(projectRepositories, changedFiles); | |||||
assertThat(statusDetection.status("foo", createFile("src/Foo.java"), "ABCDE")).isEqualTo(InputFile.Status.SAME); | assertThat(statusDetection.status("foo", createFile("src/Foo.java"), "ABCDE")).isEqualTo(InputFile.Status.SAME); | ||||
assertThat(statusDetection.status("foo", createFile("src/Foo.java"), "XXXXX")).isEqualTo(InputFile.Status.CHANGED); | assertThat(statusDetection.status("foo", createFile("src/Foo.java"), "XXXXX")).isEqualTo(InputFile.Status.CHANGED); | ||||
@Test | @Test | ||||
public void detect_status_branches_exclude() { | public void detect_status_branches_exclude() { | ||||
ScmChangedFiles changedFiles = new ScmChangedFiles(Collections.emptyList()); | ScmChangedFiles changedFiles = new ScmChangedFiles(Collections.emptyList()); | ||||
StatusDetection statusDetection = new StatusDetection(projectRepositoriesSupplier, changedFiles); | |||||
StatusDetection statusDetection = new StatusDetection(projectRepositories, changedFiles); | |||||
// normally changed | // normally changed | ||||
assertThat(statusDetection.status("foo", createFile("src/Foo.java"), "XXXXX")).isEqualTo(InputFile.Status.SAME); | assertThat(statusDetection.status("foo", createFile("src/Foo.java"), "XXXXX")).isEqualTo(InputFile.Status.SAME); | ||||
@Test | @Test | ||||
public void detect_status_branches_confirm() { | public void detect_status_branches_confirm() { | ||||
ScmChangedFiles changedFiles = new ScmChangedFiles(Collections.singletonList(Paths.get("module", "src", "Foo.java"))); | ScmChangedFiles changedFiles = new ScmChangedFiles(Collections.singletonList(Paths.get("module", "src", "Foo.java"))); | ||||
StatusDetection statusDetection = new StatusDetection(projectRepositoriesSupplier, changedFiles); | |||||
StatusDetection statusDetection = new StatusDetection(projectRepositories, changedFiles); | |||||
assertThat(statusDetection.status("foo", createFile("src/Foo.java"), "XXXXX")).isEqualTo(InputFile.Status.CHANGED); | assertThat(statusDetection.status("foo", createFile("src/Foo.java"), "XXXXX")).isEqualTo(InputFile.Status.CHANGED); | ||||
} | } |