+++ /dev/null
-/*
- * SonarQube
- * Copyright (C) 2009-2023 SonarSource SA
- * mailto:info AT sonarsource DOT com
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 3 of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- */
-package org.sonar.ce.task.projectanalysis.component;
-
-import java.util.Map;
-import java.util.function.Supplier;
-import org.sonar.ce.task.projectanalysis.batch.BatchReportReader;
-import org.sonar.scanner.protocol.output.ScannerReport;
-
-public class ReportModulesPath implements Supplier<Map<String, String>> {
- private final BatchReportReader reader;
- private Map<String, String> cache;
-
- public ReportModulesPath(BatchReportReader reader) {
- this.reader = reader;
- }
-
- public Map<String, String> get() {
- if (cache == null) {
- ScannerReport.Metadata metadata = reader.readMetadata();
- cache = metadata.getModulesProjectRelativePathByKeyMap();
- }
- return cache;
- }
-}
import org.sonar.ce.task.projectanalysis.component.PreviousSourceHashRepositoryImpl;
import org.sonar.ce.task.projectanalysis.component.ProjectPersister;
import org.sonar.ce.task.projectanalysis.component.ReferenceBranchComponentUuids;
-import org.sonar.ce.task.projectanalysis.component.ReportModulesPath;
import org.sonar.ce.task.projectanalysis.component.SiblingComponentsWithOpenIssues;
import org.sonar.ce.task.projectanalysis.component.TreeRootHolderImpl;
import org.sonar.ce.task.projectanalysis.duplication.CrossProjectDuplicationStatusHolderImpl;
// File System
new ComputationTempFolderProvider(),
- ReportModulesPath.class,
FileStatusesImpl.class,
new MetricModule(),
*/
package org.sonar.ce.task.projectanalysis.issue;
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.Date;
import java.util.List;
-import java.util.Map;
-import java.util.Optional;
-import java.util.Set;
-import java.util.function.Function;
-import java.util.stream.Collectors;
-import java.util.stream.Stream;
-import org.apache.commons.lang.StringUtils;
-import org.sonar.api.resources.Qualifiers;
-import org.sonar.ce.task.projectanalysis.analysis.AnalysisMetadataHolder;
import org.sonar.ce.task.projectanalysis.component.Component;
-import org.sonar.ce.task.projectanalysis.component.ReportModulesPath;
import org.sonar.core.issue.DefaultIssue;
-import org.sonar.core.issue.IssueChangeContext;
import org.sonar.db.DbClient;
-import org.sonar.db.DbSession;
-import org.sonar.db.component.ComponentDto;
-import org.sonar.server.issue.IssueFieldsSetter;
-
-import static org.apache.commons.lang.StringUtils.trimToEmpty;
-import static org.sonar.core.issue.IssueChangeContext.issueChangeContextByUserBuilder;
class ProjectTrackerBaseLazyInput extends BaseInputFactory.BaseLazyInput {
-
- private final AnalysisMetadataHolder analysisMetadataHolder;
- private final ComponentsWithUnprocessedIssues componentsWithUnprocessedIssues;
- private final DbClient dbClient;
- private final IssueFieldsSetter issueUpdater;
private final ComponentIssuesLoader issuesLoader;
- private final ReportModulesPath reportModulesPath;
- ProjectTrackerBaseLazyInput(AnalysisMetadataHolder analysisMetadataHolder, ComponentsWithUnprocessedIssues componentsWithUnprocessedIssues, DbClient dbClient,
- IssueFieldsSetter issueUpdater, ComponentIssuesLoader issuesLoader, ReportModulesPath reportModulesPath, Component component) {
+ ProjectTrackerBaseLazyInput(DbClient dbClient, ComponentIssuesLoader issuesLoader, Component component) {
super(dbClient, component, null);
- this.analysisMetadataHolder = analysisMetadataHolder;
- this.componentsWithUnprocessedIssues = componentsWithUnprocessedIssues;
- this.dbClient = dbClient;
- this.issueUpdater = issueUpdater;
this.issuesLoader = issuesLoader;
- this.reportModulesPath = reportModulesPath;
}
@Override
protected List<DefaultIssue> loadIssues() {
- List<DefaultIssue> result = new ArrayList<>();
- try (DbSession dbSession = dbClient.openSession(false)) {
- Set<String> dirOrModulesUuidsWithIssues = dbClient.issueDao().selectModuleAndDirComponentUuidsOfOpenIssuesForProjectUuid(dbSession, component.getUuid());
- if (!dirOrModulesUuidsWithIssues.isEmpty()) {
- Map<String, String> pathByModuleKey = reportModulesPath.get();
- // Migrate issues that were previously on modules or directories to the root project
- String branchKey = analysisMetadataHolder.isBranch() ? analysisMetadataHolder.getBranch().getName() : null;
- String prKey = analysisMetadataHolder.isPullRequest() ? analysisMetadataHolder.getBranch().getPullRequestKey() : null;
-
- Map<String, ComponentDto> modulesByUuid = dbClient.componentDao()
- .selectProjectAndModulesFromProjectKey(dbSession, component.getKey(), true, branchKey, prKey)
- .stream().collect(Collectors.toMap(ComponentDto::uuid, Function.identity()));
- List<ComponentDto> dirOrModulesWithIssues = dbClient.componentDao().selectByUuids(dbSession, dirOrModulesUuidsWithIssues);
- dirOrModulesWithIssues.forEach(c -> {
- List<DefaultIssue> issuesOnModuleOrDir = issuesLoader.loadOpenIssues(c.uuid());
- String moduleOrDirProjectRelativePath = c.qualifier().equals(Qualifiers.MODULE) ? buildModuleProjectRelativePath(pathByModuleKey, c)
- : buildDirectoryProjectRelativePath(pathByModuleKey, c, modulesByUuid.get(c.moduleUuid()));
- result.addAll(migrateIssuesToTheRoot(issuesOnModuleOrDir, moduleOrDirProjectRelativePath));
- componentsWithUnprocessedIssues.remove(c.uuid());
- });
- }
- result.addAll(issuesLoader.loadOpenIssues(effectiveUuid));
- return result;
- }
- }
-
- private static String buildDirectoryProjectRelativePath(Map<String, String> pathByModuleKey, ComponentDto c, ComponentDto parentModule) {
- String moduleProjectRelativePath = buildModuleProjectRelativePath(pathByModuleKey, parentModule);
- return Stream.of(moduleProjectRelativePath, c.path())
- .map(StringUtils::trimToNull)
- .filter(s -> s != null && !"/".equals(s))
- .collect(Collectors.joining("/"));
- }
-
- private static String buildModuleProjectRelativePath(Map<String, String> pathByModuleKey, ComponentDto parentModule) {
- return Optional.ofNullable(pathByModuleKey.get(parentModule.getKey()))
- // If module is not in the scanner report, we can't guess the path accurately. Fallback on what we have in DB
- .orElse(trimToEmpty(parentModule.path()));
- }
-
- private Collection<? extends DefaultIssue> migrateIssuesToTheRoot(List<DefaultIssue> issuesOnModule, String modulePath) {
- for (DefaultIssue i : issuesOnModule) {
- // changes the issue's component uuid, add a change and set issue as changed to enforce it is persisted to DB
- IssueChangeContext context = issueChangeContextByUserBuilder(new Date(analysisMetadataHolder.getAnalysisDate()), null).build();
- if (StringUtils.isNotBlank(modulePath)) {
- issueUpdater.setMessage(i, "[" + modulePath + "] " + i.getMessage(), context);
- }
- issueUpdater.setIssueComponent(i, component.getUuid(), component.getKey(), context.date());
- }
- return issuesOnModule;
+ return issuesLoader.loadOpenIssues(effectiveUuid);
}
}
import java.util.Collections;
import java.util.List;
import javax.annotation.Nullable;
-import org.sonar.ce.task.projectanalysis.analysis.AnalysisMetadataHolder;
import org.sonar.ce.task.projectanalysis.component.Component;
-import org.sonar.ce.task.projectanalysis.component.ReportModulesPath;
import org.sonar.ce.task.projectanalysis.filemove.MovedFilesRepository;
import org.sonar.ce.task.projectanalysis.filemove.MovedFilesRepository.OriginalFile;
import org.sonar.core.issue.DefaultIssue;
import org.sonar.core.issue.tracking.Input;
import org.sonar.db.DbClient;
-import org.sonar.server.issue.IssueFieldsSetter;
/**
* Factory of {@link Input} of base data for issue tracking. Data are lazy-loaded.
private final ComponentIssuesLoader issuesLoader;
private final DbClient dbClient;
private final MovedFilesRepository movedFilesRepository;
- private final ReportModulesPath reportModulesPath;
- private final AnalysisMetadataHolder analysisMetadataHolder;
- private final IssueFieldsSetter issueUpdater;
- private final ComponentsWithUnprocessedIssues componentsWithUnprocessedIssues;
- public TrackerBaseInputFactory(ComponentIssuesLoader issuesLoader, DbClient dbClient, MovedFilesRepository movedFilesRepository, ReportModulesPath reportModulesPath,
- AnalysisMetadataHolder analysisMetadataHolder, IssueFieldsSetter issueUpdater, ComponentsWithUnprocessedIssues componentsWithUnprocessedIssues) {
+ public TrackerBaseInputFactory(ComponentIssuesLoader issuesLoader, DbClient dbClient, MovedFilesRepository movedFilesRepository) {
this.issuesLoader = issuesLoader;
this.dbClient = dbClient;
this.movedFilesRepository = movedFilesRepository;
- this.reportModulesPath = reportModulesPath;
- this.analysisMetadataHolder = analysisMetadataHolder;
- this.issueUpdater = issueUpdater;
- this.componentsWithUnprocessedIssues = componentsWithUnprocessedIssues;
}
public Input<DefaultIssue> create(Component component) {
if (component.getType() == Component.Type.PROJECT) {
- return new ProjectTrackerBaseLazyInput(analysisMetadataHolder, componentsWithUnprocessedIssues, dbClient, issueUpdater, issuesLoader, reportModulesPath, component);
+ return new ProjectTrackerBaseLazyInput(dbClient, issuesLoader, component);
}
if (component.getType() == Component.Type.DIRECTORY) {
import org.sonar.ce.task.projectanalysis.component.ComponentUuidFactoryImpl;
import org.sonar.ce.task.projectanalysis.component.MutableTreeRootHolder;
import org.sonar.ce.task.projectanalysis.component.ProjectAttributes;
-import org.sonar.ce.task.projectanalysis.component.ReportModulesPath;
import org.sonar.ce.task.step.ComputationStep;
import org.sonar.db.DbClient;
import org.sonar.db.DbSession;
private final BatchReportReader reportReader;
private final MutableTreeRootHolder treeRootHolder;
private final MutableAnalysisMetadataHolder analysisMetadataHolder;
- private final ReportModulesPath reportModulesPath;
public BuildComponentTreeStep(DbClient dbClient, BatchReportReader reportReader, MutableTreeRootHolder treeRootHolder,
- MutableAnalysisMetadataHolder analysisMetadataHolder, ReportModulesPath reportModulesPath) {
+ MutableAnalysisMetadataHolder analysisMetadataHolder) {
this.dbClient = dbClient;
this.reportReader = reportReader;
this.treeRootHolder = treeRootHolder;
this.analysisMetadataHolder = analysisMetadataHolder;
- this.reportModulesPath = reportModulesPath;
}
@Override
+++ /dev/null
-/*
- * SonarQube
- * Copyright (C) 2009-2023 SonarSource SA
- * mailto:info AT sonarsource DOT com
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 3 of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- */
-package org.sonar.ce.task.projectanalysis.component;
-
-import java.util.Map;
-import org.junit.Test;
-import org.sonar.ce.task.projectanalysis.batch.BatchReportReader;
-import org.sonar.scanner.protocol.output.ScannerReport;
-
-import static org.assertj.core.api.Assertions.assertThat;
-import static org.assertj.core.api.Assertions.entry;
-import static org.mockito.Mockito.mock;
-import static org.mockito.Mockito.verify;
-import static org.mockito.Mockito.verifyNoMoreInteractions;
-import static org.mockito.Mockito.when;
-import static org.mockito.internal.verification.VerificationModeFactory.times;
-
-public class ReportModulesPathTest {
- private BatchReportReader reader = mock(BatchReportReader.class);
- private ReportModulesPath reportModulesPath = new ReportModulesPath(reader);
-
- @Test
- public void should_cache_report_data() {
- when(reader.readMetadata()).thenReturn(ScannerReport.Metadata.newBuilder()
- .putModulesProjectRelativePathByKey("module1", "path1")
- .setRootComponentRef(1)
- .build());
- Map<String, String> pathByModuleKey = reportModulesPath.get();
- assertThat(pathByModuleKey).containsExactly(entry("module1", "path1"));
- pathByModuleKey = reportModulesPath.get();
- assertThat(pathByModuleKey).containsExactly(entry("module1", "path1"));
-
- verify(reader, times(1)).readMetadata();
- verifyNoMoreInteractions(reader);
- }
-}
import org.sonar.ce.task.projectanalysis.component.FileStatuses;
import org.sonar.ce.task.projectanalysis.component.ReferenceBranchComponentUuids;
import org.sonar.ce.task.projectanalysis.component.ReportComponent;
-import org.sonar.ce.task.projectanalysis.component.ReportModulesPath;
import org.sonar.ce.task.projectanalysis.component.TreeRootHolderRule;
import org.sonar.ce.task.projectanalysis.component.TypeAwareVisitor;
import org.sonar.ce.task.projectanalysis.filemove.MovedFilesRepository;
DbClient dbClient = dbTester.getDbClient();
TrackerRawInputFactory rawInputFactory = new TrackerRawInputFactory(treeRootHolder, reportReader, sourceLinesHash, new CommonRuleEngineImpl(), issueFilter,
ruleRepositoryRule, activeRulesHolder);
- TrackerBaseInputFactory baseInputFactory = new TrackerBaseInputFactory(issuesLoader, dbClient, movedFilesRepository, mock(ReportModulesPath.class), analysisMetadataHolder,
- new IssueFieldsSetter(), mock(ComponentsWithUnprocessedIssues.class));
+ TrackerBaseInputFactory baseInputFactory = new TrackerBaseInputFactory(issuesLoader, dbClient, movedFilesRepository);
TrackerTargetBranchInputFactory targetInputFactory = new TrackerTargetBranchInputFactory(issuesLoader, targetBranchComponentUuids, dbClient, movedFilesRepository);
TrackerReferenceBranchInputFactory mergeInputFactory = new TrackerReferenceBranchInputFactory(issuesLoader, mergeBranchComponentsUuids, dbClient);
ClosedIssuesInputFactory closedIssuesInputFactory = new ClosedIssuesInputFactory(issuesLoader, dbClient, movedFilesRepository);
*/
package org.sonar.ce.task.projectanalysis.issue;
-import com.google.common.collect.ImmutableMap;
-import java.util.Collections;
import java.util.Date;
import org.junit.Before;
import org.junit.Rule;
import org.sonar.ce.task.projectanalysis.analysis.AnalysisMetadataHolderRule;
import org.sonar.ce.task.projectanalysis.component.Component;
import org.sonar.ce.task.projectanalysis.component.ReportComponent;
-import org.sonar.ce.task.projectanalysis.component.ReportModulesPath;
import org.sonar.ce.task.projectanalysis.qualityprofile.ActiveRulesHolderRule;
import org.sonar.core.issue.DefaultIssue;
import org.sonar.db.DbClient;
import org.sonar.db.component.ComponentDto;
import org.sonar.db.issue.IssueDto;
import org.sonar.db.rule.RuleDto;
-import org.sonar.server.issue.IssueFieldsSetter;
import static org.assertj.core.api.Assertions.assertThat;
import static org.assertj.core.api.Assertions.tuple;
import static org.mockito.Mockito.mock;
-import static org.mockito.Mockito.when;
import static org.sonar.api.utils.DateUtils.parseDate;
import static org.sonar.db.component.ComponentTesting.newDirectory;
import static org.sonar.db.component.ComponentTesting.newFileDto;
private ComponentDto rootProjectDto;
private ComponentIssuesLoader issuesLoader = new ComponentIssuesLoader(dbTester.getDbClient(), ruleRepositoryRule, activeRulesHolderRule, new MapSettings().asConfig(),
System2.INSTANCE, mock(IssueChangesToDeleteRepository.class));
- private ReportModulesPath reportModulesPath;
@Before
public void prepare() {
ReportComponent rootProject = ReportComponent.builder(Component.Type.FILE, 1)
.setKey(rootProjectDto.getKey())
.setUuid(rootProjectDto.uuid()).build();
- reportModulesPath = mock(ReportModulesPath.class);
- underTest = new ProjectTrackerBaseLazyInput(analysisMetadataHolder, mock(ComponentsWithUnprocessedIssues.class), dbClient, new IssueFieldsSetter(), issuesLoader,
- reportModulesPath, rootProject);
+ underTest = new ProjectTrackerBaseLazyInput(dbClient, issuesLoader, rootProject);
}
@Test
- public void return_only_open_project_issues_if_no_modules_and_folders() {
+ public void return_only_open_project_issues_if_no_folders() {
ComponentDto file = dbTester.components().insertComponent(newFileDto(rootProjectDto));
IssueDto openIssueOnProject = dbTester.issues().insert(rule, rootProjectDto, rootProjectDto, i -> i.setStatus("OPEN").setResolution(null));
IssueDto closedIssueOnProject = dbTester.issues().insert(rule, rootProjectDto, rootProjectDto, i -> i.setStatus("CLOSED").setResolution("FIXED"));
assertThat(underTest.loadIssues()).extracting(DefaultIssue::key).containsOnly(openIssueOnProject.getKey());
}
-
- @Test
- public void migrate_and_return_folder_issues_on_root_project() {
- when(reportModulesPath.get()).thenReturn(Collections.emptyMap());
- ComponentDto folder = dbTester.components().insertComponent(newDirectory(rootProjectDto, "src"));
- ComponentDto file = dbTester.components().insertComponent(newFileDto(rootProjectDto));
- IssueDto openIssueOnProject = dbTester.issues().insert(rule, rootProjectDto, rootProjectDto, i -> i.setStatus("OPEN").setResolution(null));
- IssueDto openIssueOnDir = dbTester.issues().insert(rule, rootProjectDto, folder, i -> i.setStatus("OPEN").setMessage("Issue on dir").setResolution(null));
- IssueDto openIssue1OnFile = dbTester.issues().insert(rule, rootProjectDto, file, i -> i.setStatus("OPEN").setResolution(null));
-
- assertThat(underTest.loadIssues()).extracting(DefaultIssue::key, DefaultIssue::getMessage)
- .containsExactlyInAnyOrder(
- tuple(openIssueOnProject.getKey(), openIssueOnProject.getMessage()),
- tuple(openIssueOnDir.getKey(), "[src] Issue on dir"));
-
- }
-
- @Test
- public void migrate_and_return_module_and_folder_issues_on_module() {
- ComponentDto module = dbTester.components().insertComponent(newModuleDto(rootProjectDto).setPath("moduleAInDb"));
- when(reportModulesPath.get()).thenReturn(ImmutableMap.of(module.getKey(), "moduleAInReport"));
- ComponentDto folder = dbTester.components().insertComponent(newDirectory(module, "src"));
- ComponentDto file = dbTester.components().insertComponent(newFileDto(module));
- IssueDto openIssueOnProject = dbTester.issues().insert(rule, rootProjectDto, rootProjectDto, i -> i.setStatus("OPEN").setResolution(null));
- IssueDto openIssueOnModule = dbTester.issues().insert(rule, rootProjectDto, module, i -> i.setStatus("OPEN").setMessage("Issue on module").setResolution(null));
- IssueDto openIssueOnDir = dbTester.issues().insert(rule, rootProjectDto, folder, i -> i.setStatus("OPEN").setMessage("Issue on dir").setResolution(null));
- IssueDto openIssue1OnFile = dbTester.issues().insert(rule, rootProjectDto, file, i -> i.setStatus("OPEN").setResolution(null));
-
- assertThat(underTest.loadIssues()).extracting(DefaultIssue::key, DefaultIssue::getMessage)
- .containsExactlyInAnyOrder(
- tuple(openIssueOnProject.getKey(), openIssueOnProject.getMessage()),
- tuple(openIssueOnModule.getKey(), "[moduleAInReport] Issue on module"),
- tuple(openIssueOnDir.getKey(), "[moduleAInReport/src] Issue on dir"));
-
- }
-
- @Test
- public void use_db_path_if_module_missing_in_report() {
- ComponentDto module = dbTester.components().insertComponent(newModuleDto(rootProjectDto).setPath("moduleAInDb"));
- when(reportModulesPath.get()).thenReturn(Collections.emptyMap());
- ComponentDto folder = dbTester.components().insertComponent(newDirectory(module, "src"));
- IssueDto openIssueOnProject = dbTester.issues().insert(rule, rootProjectDto, rootProjectDto, i -> i.setStatus("OPEN").setResolution(null));
- IssueDto openIssueOnModule = dbTester.issues().insert(rule, rootProjectDto, module, i -> i.setStatus("OPEN").setMessage("Issue on module").setResolution(null));
- IssueDto openIssueOnDir = dbTester.issues().insert(rule, rootProjectDto, folder, i -> i.setStatus("OPEN").setMessage("Issue on dir").setResolution(null));
-
- assertThat(underTest.loadIssues()).extracting(DefaultIssue::key, DefaultIssue::getMessage)
- .containsExactlyInAnyOrder(
- tuple(openIssueOnProject.getKey(), openIssueOnProject.getMessage()),
- tuple(openIssueOnModule.getKey(), "[moduleAInDb] Issue on module"),
- tuple(openIssueOnDir.getKey(), "[moduleAInDb/src] Issue on dir"));
-
- }
-
- @Test
- public void empty_path_if_module_missing_in_report_and_db_and_for_slash_folder() {
- ComponentDto module = dbTester.components().insertComponent(newModuleDto(rootProjectDto).setPath(null));
- when(reportModulesPath.get()).thenReturn(Collections.emptyMap());
- ComponentDto folder = dbTester.components().insertComponent(newDirectory(module, "/"));
- IssueDto openIssueOnProject = dbTester.issues().insert(rule, rootProjectDto, rootProjectDto, i -> i.setStatus("OPEN").setResolution(null));
- IssueDto openIssueOnModule = dbTester.issues().insert(rule, rootProjectDto, module, i -> i.setStatus("OPEN").setMessage("Issue on module").setResolution(null));
- IssueDto openIssueOnDir = dbTester.issues().insert(rule, rootProjectDto, folder, i -> i.setStatus("OPEN").setMessage("Issue on dir").setResolution(null));
-
- assertThat(underTest.loadIssues()).extracting(DefaultIssue::key, DefaultIssue::getMessage)
- .containsExactlyInAnyOrder(
- tuple(openIssueOnProject.getKey(), openIssueOnProject.getMessage()),
- tuple(openIssueOnModule.getKey(), "Issue on module"),
- tuple(openIssueOnDir.getKey(), "Issue on dir"));
-
- }
}
import org.sonar.ce.task.projectanalysis.analysis.AnalysisMetadataHolderRule;
import org.sonar.ce.task.projectanalysis.component.Component;
import org.sonar.ce.task.projectanalysis.component.ReportComponent;
-import org.sonar.ce.task.projectanalysis.component.ReportModulesPath;
import org.sonar.ce.task.projectanalysis.filemove.MovedFilesRepository;
import org.sonar.core.issue.DefaultIssue;
import org.sonar.core.issue.tracking.Input;
import org.sonar.db.DbClient;
import org.sonar.db.DbSession;
import org.sonar.db.source.FileSourceDao;
-import org.sonar.server.issue.IssueFieldsSetter;
import static org.assertj.core.api.Assertions.assertThat;
import static org.mockito.ArgumentMatchers.any;
private MovedFilesRepository movedFilesRepository = mock(MovedFilesRepository.class);
- private TrackerBaseInputFactory underTest = new TrackerBaseInputFactory(issuesLoader, dbClient, movedFilesRepository, mock(ReportModulesPath.class), analysisMetadataHolder,
- new IssueFieldsSetter(), mock(ComponentsWithUnprocessedIssues.class));
+ private TrackerBaseInputFactory underTest = new TrackerBaseInputFactory(issuesLoader, dbClient, movedFilesRepository);
@Before
public void setUp() {
import org.sonar.ce.task.projectanalysis.component.Component;
import org.sonar.ce.task.projectanalysis.component.DefaultBranchImpl;
import org.sonar.ce.task.projectanalysis.component.MutableTreeRootHolderRule;
-import org.sonar.ce.task.projectanalysis.component.ReportModulesPath;
import org.sonar.ce.task.step.TestComputationStepContext;
import org.sonar.db.DbClient;
import org.sonar.db.DbTester;
public MutableTreeRootHolderRule treeRootHolder = new MutableTreeRootHolderRule();
@Rule
public MutableAnalysisMetadataHolderRule analysisMetadataHolder = new MutableAnalysisMetadataHolderRule();
- private ReportModulesPath reportModulesPath = new ReportModulesPath(reportReader);
private DbClient dbClient = dbTester.getDbClient();
- private BuildComponentTreeStep underTest = new BuildComponentTreeStep(dbClient, reportReader, treeRootHolder, analysisMetadataHolder, reportModulesPath);
+ private BuildComponentTreeStep underTest = new BuildComponentTreeStep(dbClient, reportReader, treeRootHolder, analysisMetadataHolder);
@Test
public void fails_if_root_component_does_not_exist_in_reportReader() {
.setAnalysisDate(ANALYSIS_DATE)
.setProject(Project.from(newPrivateProjectDto().setKey(REPORT_PROJECT_KEY)))
.setBranch(branch);
- BuildComponentTreeStep underTest = new BuildComponentTreeStep(dbClient, reportReader, treeRootHolder, analysisMetadataHolder, reportModulesPath);
+ BuildComponentTreeStep underTest = new BuildComponentTreeStep(dbClient, reportReader, treeRootHolder, analysisMetadataHolder);
reportReader.putComponent(component(ROOT_REF, PROJECT, REPORT_PROJECT_KEY, FILE_1_REF));
reportReader.putComponent(componentWithPath(FILE_1_REF, FILE, REPORT_FILE_PATH_1));
.setAnalysisDate(ANALYSIS_DATE)
.setProject(Project.from(projectDto))
.setBranch(branch);
- BuildComponentTreeStep underTest = new BuildComponentTreeStep(dbClient, reportReader, treeRootHolder, analysisMetadataHolder, reportModulesPath);
+ BuildComponentTreeStep underTest = new BuildComponentTreeStep(dbClient, reportReader, treeRootHolder, analysisMetadataHolder);
reportReader.putComponent(component(ROOT_REF, PROJECT, componentDto.getKey()));
underTest.execute(new TestComputationStepContext());
@Test
public void generate_keys_when_using_main_branch() {
setAnalysisMetadataHolder();
- BuildComponentTreeStep underTest = new BuildComponentTreeStep(dbClient, reportReader, treeRootHolder, analysisMetadataHolder, reportModulesPath);
+ BuildComponentTreeStep underTest = new BuildComponentTreeStep(dbClient, reportReader, treeRootHolder, analysisMetadataHolder);
reportReader.putComponent(component(ROOT_REF, PROJECT, REPORT_PROJECT_KEY, FILE_1_REF));
reportReader.putComponent(componentWithPath(FILE_1_REF, FILE, REPORT_FILE_PATH_1));
return mapper(session).selectSubProjectsByComponentUuids(uuids);
}
- public List<ComponentDto> selectEnabledDescendantModules(DbSession session, String rootComponentUuid) {
- return mapper(session).selectDescendantModules(rootComponentUuid, Scopes.PROJECT, true);
- }
-
- public List<FilePathWithHashDto> selectEnabledDescendantFiles(DbSession session, String rootComponentUuid) {
- return mapper(session).selectDescendantFiles(rootComponentUuid, Scopes.FILE, true);
+ public List<ComponentDto> selectEnabledViewsFromRootView(DbSession session, String rootViewUuid) {
+ return mapper(session).selectEnabledViewsFromRootView(rootViewUuid);
}
public List<FilePathWithHashDto> selectEnabledFilesFromProject(DbSession session, String rootComponentUuid) {
return mapper(session).selectUuidsByKeyFromProjectKeyAndBranchOrPr(projectKey, null, pullrequest);
}
- /**
- * If no branch or pull request is provided, returns components in the main branch
- */
- public List<ComponentDto> selectProjectAndModulesFromProjectKey(DbSession session, String projectKey, boolean excludeDisabled,
- @Nullable String branch, @Nullable String pullRequest) {
- checkState(branch == null || pullRequest == null, "Can't set both branch and pull request");
- return mapper(session).selectComponentsFromProjectKeyAndScope(projectKey, Scopes.PROJECT, excludeDisabled, branch, pullRequest);
- }
-
public List<ComponentDto> selectByKeys(DbSession session, Collection<String> keys) {
return selectByKeys(session, keys, null, null);
}
List<ComponentDto> selectProjects();
/**
- * Return all descendant modules (including itself) from a given component uuid and scope
+ * Return all descendant views (including itself) from a given root view
*/
- List<ComponentDto> selectDescendantModules(@Param("moduleUuid") String moduleUuid, @Param(value = "scope") String scope,
- @Param(value = "excludeDisabled") boolean excludeDisabled);
+ List<ComponentDto> selectEnabledViewsFromRootView(@Param("rootViewUuid") String rootViewUuid);
/**
* Return all files from a given project uuid and scope
*/
List<FilePathWithHashDto> selectEnabledFilesFromProject(@Param("projectUuid") String projectUuid);
- /**
- * Return all descendant files from a given module uuid and scope
- */
- List<FilePathWithHashDto> selectDescendantFiles(@Param("moduleUuid") String moduleUuid, @Param(value = "scope") String scope,
- @Param(value = "excludeDisabled") boolean excludeDisabled);
-
/**
* Return uuids and project uuids from list of qualifiers
* <p/>
*/
List<UuidWithBranchUuidDto> selectUuidsForQualifiers(@Param("qualifiers") String... qualifiers);
- /**
- * Return components of a given scope of a project
- *
- * @param scope scope of components to return. If null, all components are returned
- */
- List<ComponentDto> selectComponentsFromProjectKeyAndScope(@Param("projectKey") String projectKey, @Nullable @Param("scope") String scope,
- @Param(value = "excludeDisabled") boolean excludeDisabled, @Nullable @Param("branch") String branch, @Nullable @Param("pullRequest") String pullRequest);
-
/**
* Return keys and UUIDs of all components belonging to a project
*/
import org.sonar.db.WildcardPosition;
import org.sonar.db.component.ComponentDto;
-import static java.util.Collections.emptyList;
import static org.sonar.db.DaoUtils.buildLikeValue;
import static org.sonar.db.DatabaseUtils.executeLargeInputs;
return mapper(session).selectComponentUuidsOfOpenIssuesForProjectUuid(projectUuid);
}
- public Set<String> selectModuleAndDirComponentUuidsOfOpenIssuesForProjectUuid(DbSession session, String projectUuid) {
- return mapper(session).selectModuleAndDirComponentUuidsOfOpenIssuesForProjectUuid(projectUuid);
- }
-
public List<IssueDto> selectNonClosedByComponentUuidExcludingExternalsAndSecurityHotspots(DbSession dbSession, String componentUuid) {
return mapper(dbSession).selectNonClosedByComponentUuidExcludingExternals(componentUuid);
}
Set<String> selectComponentUuidsOfOpenIssuesForProjectUuid(String projectUuid);
- Set<String> selectModuleAndDirComponentUuidsOfOpenIssuesForProjectUuid(String projectUuid);
-
List<IssueDto> selectByKeys(List<String> keys);
Set<String> selectIssueKeysByComponentUuid(@Param("componentUuid") String componentUuid);
</foreach>
</select>
- <select id="selectDescendantModules" parameterType="map" resultType="Component">
+ <select id="selectEnabledViewsFromRootView" parameterType="map" resultType="Component">
SELECT
<include refid="componentColumns"/>
FROM components p
- <include refid="modulesTreeQuery"/>
- </select>
-
- <sql id="modulesTreeQuery">
- INNER JOIN components module ON
- module.branch_uuid = p.branch_uuid
- and module.uuid = #{moduleUuid}
- and module.scope='PRJ' AND module.enabled = ${_true}
where
- p.scope = #{scope,jdbcType=VARCHAR}
- <if test="excludeDisabled">
- and p.enabled = ${_true}
- </if>
- and
- <choose>
- <when test="_databaseId == 'mssql'">
- p.module_uuid_path LIKE module.module_uuid_path + '%'
- </when>
- <otherwise>
- p.module_uuid_path LIKE module.module_uuid_path || '%'
- </otherwise>
- </choose>
- </sql>
+ p.enabled=${_true}
+ and p.scope='PRJ'
+ and p.qualifier in ('VW', 'SVW', 'APP')
+ and p.branch_uuid=#{rootViewUuid,jdbcType=VARCHAR}
+ </select>
<select id="selectEnabledFilesFromProject" parameterType="map" resultType="FilePathWithHash">
SELECT
root.uuid=#{projectUuid,jdbcType=VARCHAR}
</select>
- <select id="selectDescendantFiles" parameterType="map" resultType="FilePathWithHash">
- SELECT
- p.uuid,
- p.path,
- p.module_uuid as moduleUuid,
- fs.src_hash as srcHash,
- fs.revision
- FROM components p
- INNER JOIN file_sources fs ON
- fs.file_uuid=p.uuid
- <include refid="modulesTreeQuery"/>
- </select>
-
<select id="selectProjects" resultType="Component">
select
<include refid="componentColumns"/>
and p.copy_component_uuid is not null
</select>
- <select id="selectComponentsFromProjectKeyAndScope" parameterType="map" resultType="Component">
- SELECT
- <include refid="componentColumns"/>
- FROM components p
- INNER JOIN components root ON root.uuid=p.branch_uuid AND root.kee=#{projectKey,jdbcType=VARCHAR}
- <if test="branch != null || pullRequest != null">
- INNER JOIN project_branches pb ON pb.uuid=p.branch_uuid
- </if>
- <where>
- <if test="excludeDisabled">
- p.enabled = ${_true}
- </if>
- <if test="scope != null">
- AND p.scope=#{scope,jdbcType=VARCHAR}
- </if>
- <choose>
- <when test="branch != null">
- AND pb.kee=#{branch,jdbcType=VARCHAR} AND pb.branch_type = 'BRANCH'
- </when>
- <when test="pullRequest != null">
- AND pb.kee=#{pullRequest,jdbcType=VARCHAR} AND pb.branch_type = 'PULL_REQUEST'
- </when>
- <otherwise>
- AND root.main_branch_project_uuid is null
- </otherwise>
- </choose>
- </where>
- </select>
-
<select id="selectByBranchUuid" parameterType="map" resultType="Component">
SELECT
<include refid="componentColumns"/>
i.kee, ic.issue_change_creation_date desc
</select>
- <select id="selectModuleAndDirComponentUuidsOfOpenIssuesForProjectUuid" parameterType="string" resultType="string">
- select
- distinct(i.component_uuid)
- from issues i
- inner join components p on
- p.uuid = i.component_uuid
- and p.enabled = ${_true}
- where
- i.project_uuid=#{projectUuid,jdbcType=VARCHAR}
- and i.status <> 'CLOSED'
- and (p.qualifier = 'DIR' OR p.qualifier = 'BRC')
- </select>
-
<select id="selectComponentUuidsOfOpenIssuesForProjectUuid" parameterType="string" resultType="string">
select distinct(i.component_uuid)
from issues i
}
@Test
- public void select_enabled_module_files_tree_from_module() {
- ComponentDto project = db.components().insertPrivateProject();
- ComponentDto module = db.components().insertComponent(newModuleDto(project));
- ComponentDto fileDirectlyOnModule = db.components().insertComponent(newFileDto(module));
- FileSourceDto fileSourceDirectlyOnModule = db.fileSources().insertFileSource(fileDirectlyOnModule);
- ComponentDto subModule = db.components().insertComponent(newModuleDto(module));
- ComponentDto directory = db.components().insertComponent(newDirectory(subModule, "src"));
- ComponentDto file = db.components().insertComponent(newFileDto(subModule, directory));
- FileSourceDto fileSource = db.fileSources().insertFileSource(file);
-
- // From root project
- assertThat(underTest.selectEnabledDescendantFiles(dbSession, project.uuid()))
- .extracting(FilePathWithHashDto::getUuid, FilePathWithHashDto::getModuleUuid, FilePathWithHashDto::getSrcHash, FilePathWithHashDto::getPath, FilePathWithHashDto::getRevision)
- .containsExactlyInAnyOrder(
- tuple(fileDirectlyOnModule.uuid(), module.uuid(), fileSourceDirectlyOnModule.getSrcHash(), fileDirectlyOnModule.path(), fileSourceDirectlyOnModule.getRevision()),
- tuple(file.uuid(), subModule.uuid(), fileSource.getSrcHash(), file.path(), fileSource.getRevision()));
-
- // From module
- assertThat(underTest.selectEnabledDescendantFiles(dbSession, module.uuid()))
- .extracting(FilePathWithHashDto::getUuid, FilePathWithHashDto::getModuleUuid, FilePathWithHashDto::getSrcHash, FilePathWithHashDto::getPath, FilePathWithHashDto::getRevision)
- .containsExactlyInAnyOrder(
- tuple(fileDirectlyOnModule.uuid(), module.uuid(), fileSourceDirectlyOnModule.getSrcHash(), fileDirectlyOnModule.path(), fileSourceDirectlyOnModule.getRevision()),
- tuple(file.uuid(), subModule.uuid(), fileSource.getSrcHash(), file.path(), fileSource.getRevision()));
-
- // From sub module
- assertThat(underTest.selectEnabledDescendantFiles(dbSession, subModule.uuid()))
- .extracting(FilePathWithHashDto::getUuid, FilePathWithHashDto::getModuleUuid, FilePathWithHashDto::getSrcHash, FilePathWithHashDto::getPath, FilePathWithHashDto::getRevision)
- .containsExactlyInAnyOrder(
- tuple(file.uuid(), subModule.uuid(), fileSource.getSrcHash(), file.path(), fileSource.getRevision()));
-
- // From directory
- assertThat(underTest.selectEnabledDescendantFiles(dbSession, directory.uuid())).isEmpty();
-
- assertThat(underTest.selectEnabledDescendantFiles(dbSession, "unknown")).isEmpty();
- }
-
- @Test
- public void select_enabled_module_files_tree_from_project() {
+ public void select_enabled_files_from_project() {
ComponentDto project = db.components().insertPrivateProject();
ComponentDto module = db.components().insertComponent(newModuleDto(project));
ComponentDto fileDirectlyOnModule = db.components().insertComponent(newFileDto(module));
assertThat(underTest.selectProjectsFromView(dbSession, "Unknown", "Unknown")).isEmpty();
}
+ @Test
+ public void select_enabled_views_from_root_view() {
+ ComponentDto rootPortfolio = db.components().insertPrivatePortfolio();
+ ComponentDto subPortfolio = db.components().insertSubView(rootPortfolio);
+ ComponentDto project = db.components().insertPrivateProject();
+ db.components().insertComponent(newProjectCopy(project, subPortfolio));
+
+ assertThat(underTest.selectEnabledViewsFromRootView(dbSession, rootPortfolio.uuid()))
+ .extracting(ComponentDto::uuid)
+ .containsOnly(rootPortfolio.uuid(), subPortfolio.uuid());
+ assertThat(underTest.selectEnabledViewsFromRootView(dbSession, project.uuid())).isEmpty();
+ }
+
@Test
public void select_projects_from_view_should_escape_like_sensitive_characters() {
ComponentDto project1 = db.components().insertPrivateProject();
assertThat(result.stream().filter(g -> !g.isInLeak()).mapToLong(IssueGroupDto::getCount).sum()).isOne();
}
- @Test
- public void selectModuleAndDirComponentUuidsOfOpenIssuesForProjectUuid() {
- assertThat(underTest.selectModuleAndDirComponentUuidsOfOpenIssuesForProjectUuid(db.getSession(), randomAlphabetic(12)))
- .isEmpty();
-
- ComponentDto project1 = db.components().insertPrivateProject();
- ComponentDto module11 = db.components().insertComponent(newModuleDto(project1));
- ComponentDto dir11 = db.components().insertComponent(newDirectory(module11, randomAlphabetic(10)));
- ComponentDto dir12 = db.components().insertComponent(newDirectory(module11, randomAlphabetic(11)));
- ComponentDto module12 = db.components().insertComponent(newModuleDto(project1));
- ComponentDto dir13 = db.components().insertComponent(newDirectory(module12, randomAlphabetic(12)));
- ComponentDto dir14 = db.components().insertComponent(newDirectory(project1, randomAlphabetic(13)));
- ComponentDto file11 = db.components().insertComponent(newFileDto(project1));
- ComponentDto application = db.components().insertPrivateApplication();
- ComponentDto view = db.components().insertPublicPortfolio();
- ComponentDto subview = db.components().insertSubView(view);
- ComponentDto project2 = db.components().insertPublicProject();
- ComponentDto module21 = db.components().insertComponent(newModuleDto(project2));
- ComponentDto dir21 = db.components().insertComponent(newDirectory(project2, randomAlphabetic(15)));
- ComponentDto file21 = db.components().insertComponent(newFileDto(project2));
- List<ComponentDto> allcomponents = asList(project1, module11, dir11, dir12, module12, dir13, dir14, file11, application, view, subview, project2, module21, dir21, file21);
- List<ComponentDto> allModuleOrDirs = asList(module11, dir11, dir12, module12, dir13, dir14, module21, dir21);
-
- // no issues => always empty
- allcomponents.stream()
- .map(ComponentDto::uuid)
- .forEach(uuid -> assertThat(underTest.selectModuleAndDirComponentUuidsOfOpenIssuesForProjectUuid(db.getSession(), uuid))
- .isEmpty());
-
- // return module or dir only if has issue with status different from CLOSED
- allModuleOrDirs
- .forEach(moduleOrDir -> {
- String projectUuid = moduleOrDir.branchUuid();
- // CLOSED issue => not returned
- db.issues().insertIssue(t -> t.setProjectUuid(projectUuid).setComponent(moduleOrDir).setStatus(STATUS_CLOSED));
- assertThat(underTest.selectModuleAndDirComponentUuidsOfOpenIssuesForProjectUuid(db.getSession(), projectUuid))
- .isEmpty();
-
- // status != CLOSED => returned
- STATUSES.stream()
- .filter(t -> !STATUS_CLOSED.equals(t))
- .forEach(status -> {
- IssueDto issue = db.issues().insertIssue(t -> t.setProjectUuid(projectUuid).setComponent(moduleOrDir).setStatus(status));
- assertThat(underTest.selectModuleAndDirComponentUuidsOfOpenIssuesForProjectUuid(db.getSession(), projectUuid))
- .containsOnly(moduleOrDir.uuid());
-
- db.executeDdl("delete from issues where kee='" + issue.getKey() + "'");
- db.commit();
- assertThat(underTest.selectModuleAndDirComponentUuidsOfOpenIssuesForProjectUuid(db.getSession(), projectUuid))
- .isEmpty();
- });
- });
-
- // never return project, view, subview, app or file, whatever the issue status
- Stream.of(project1, file11, application, view, subview, project2, file21)
- .forEach(neitherModuleNorDir -> {
- String projectUuid = neitherModuleNorDir.branchUuid();
- STATUSES
- .forEach(status -> {
- db.issues().insertIssue(t -> t.setProjectUuid(projectUuid).setComponent(neitherModuleNorDir).setStatus(status));
- assertThat(underTest.selectModuleAndDirComponentUuidsOfOpenIssuesForProjectUuid(db.getSession(), projectUuid))
- .isEmpty();
- });
- });
-
- // never return whatever the component if it is disabled
- allcomponents
- .forEach(component -> {
- String projectUuid = component.branchUuid();
-
- // issues for each status => returned if component is dir or module
- STATUSES
- .forEach(status -> db.issues().insertIssue(t -> t.setProjectUuid(projectUuid).setComponent(component).setStatus(status)));
- if (allModuleOrDirs.contains(component)) {
- assertThat(underTest.selectModuleAndDirComponentUuidsOfOpenIssuesForProjectUuid(db.getSession(), projectUuid))
- .containsOnly(component.uuid());
- } else {
- assertThat(underTest.selectModuleAndDirComponentUuidsOfOpenIssuesForProjectUuid(db.getSession(), projectUuid))
- .isEmpty();
- }
-
- // disable component and test again => not returned anymore
- db.getDbClient().componentDao().update(db.getSession(), ComponentUpdateDto.copyFrom(component).setBEnabled(false).setBChanged(true), component.qualifier());
- db.getDbClient().componentDao().applyBChangesForRootComponentUuid(db.getSession(), projectUuid);
- db.commit();
- assertThat(db.getDbClient().componentDao().selectByUuid(db.getSession(), component.uuid()).get().isEnabled())
- .isFalse();
- assertThat(underTest.selectModuleAndDirComponentUuidsOfOpenIssuesForProjectUuid(db.getSession(), projectUuid))
- .isEmpty();
- });
- }
-
@Test
public void selectByKey_givenOneIssueNewOnReferenceBranch_selectOneIssueWithNewOnReferenceBranch() {
prepareIssuesComponent();
}
/**
- * Index a root view : it will load projects on each sub views and index it.
+ * Index a root view : it will a view and its subviews and index them.
* Used by the compute engine to reindex a root view.
* <p/>
* The views lookup cache will be cleared
public void index(String rootViewUuid) {
try (DbSession dbSession = dbClient.openSession(false)) {
Map<String, String> viewAndProjectViewUuidMap = new HashMap<>();
- for (ComponentDto viewOrSubView : dbClient.componentDao().selectEnabledDescendantModules(dbSession, rootViewUuid)) {
+ for (ComponentDto viewOrSubView : dbClient.componentDao().selectEnabledViewsFromRootView(dbSession, rootViewUuid)) {
viewAndProjectViewUuidMap.put(viewOrSubView.uuid(), viewOrSubView.branchUuid());
}
index(dbSession, viewAndProjectViewUuidMap, true, Size.REGULAR);
*/
package org.sonar.server.batch;
-import com.google.common.base.Splitter;
import java.io.IOException;
import java.io.OutputStream;
import java.util.ArrayList;
private static final String PARAM_KEY = "key";
private static final String PARAM_BRANCH = "branch";
- private static final Splitter MODULE_PATH_SPLITTER = Splitter.on('.').trimResults().omitEmptyStrings();
private final DbClient dbClient;
private final UserSession userSession;
*/
package org.sonar.server.batch;
-import com.google.common.collect.Maps;
import java.util.Map;
import java.util.stream.Collectors;
import org.sonar.api.server.ws.Change;
import org.sonar.api.server.ws.Response;
import org.sonar.api.server.ws.WebService;
import org.sonar.scanner.protocol.input.FileData;
-import org.sonar.scanner.protocol.input.MultiModuleProjectRepository;
import org.sonar.scanner.protocol.input.ProjectRepositories;
-import org.sonar.scanner.protocol.input.SingleProjectRepository;
import org.sonarqube.ws.Batch.WsProjectResponse;
import org.sonarqube.ws.Batch.WsProjectResponse.FileData.Builder;
.setChangelog(
new Change("7.6", String.format("The use of module keys in parameter '%s' is deprecated", PARAM_KEY)),
new Change("7.6", "Stop returning settings"),
- new Change("7.7", "Stop supporting preview mode, removed timestamp and last analysis date"))
+ new Change("7.7", "Stop supporting preview mode, removed timestamp and last analysis date"),
+ new Change("10.0", String.format("No longer possible to use module keys with parameter '%s'", PARAM_KEY)))
.setInternal(true)
.setHandler(this);
action
.createParam(PARAM_KEY)
.setRequired(true)
- .setDescription("Project or module key")
+ .setDescription("Project key")
.setExampleValue(KEY_PROJECT_EXAMPLE_001);
action
private static WsProjectResponse buildResponse(ProjectRepositories data) {
WsProjectResponse.Builder response = WsProjectResponse.newBuilder();
- if (data instanceof SingleProjectRepository singleProjectRepository) {
- response.putAllFileDataByPath(buildFileDataByPath(singleProjectRepository));
- } else {
- response.putAllFileDataByModuleAndPath(buildFileDataByModuleAndPath((MultiModuleProjectRepository) data));
- }
-
+ response.putAllFileDataByPath(buildFileDataByPath(data));
return response.build();
}
- private static Map<String, WsProjectResponse.FileDataByPath> buildFileDataByModuleAndPath(MultiModuleProjectRepository data) {
- return data.repositoriesByModule().entrySet()
- .stream()
- .map(entry -> Maps.immutableEntry(entry.getKey(), buildFileDataByPath(entry.getValue().fileData())))
- .collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue));
- }
-
- private static Map<String, WsProjectResponse.FileData> buildFileDataByPath(SingleProjectRepository data) {
+ private static Map<String, WsProjectResponse.FileData> buildFileDataByPath(ProjectRepositories data) {
return data.fileData().entrySet()
.stream()
.collect(Collectors.toMap(Map.Entry::getKey, e -> toFileDataResponse(e.getValue())));
}
- private static WsProjectResponse.FileDataByPath buildFileDataByPath(Map<String, FileData> fileDataByPath) {
- WsProjectResponse.FileDataByPath.Builder response = WsProjectResponse.FileDataByPath.newBuilder();
- fileDataByPath.forEach((key, value) -> response.putFileDataByPath(key, toFileDataResponse(value)));
- return response.build();
- }
-
private static WsProjectResponse.FileData toFileDataResponse(FileData fileData) {
Builder fileDataBuilder = WsProjectResponse.FileData.newBuilder();
ofNullable(fileData.hash()).ifPresent(fileDataBuilder::setHash);
package org.sonar.server.batch;
import java.util.Collections;
-import java.util.HashMap;
import java.util.List;
-import java.util.Map;
import javax.annotation.Nullable;
import org.sonar.api.server.ServerSide;
import org.sonar.api.web.UserRole;
import org.sonar.db.component.FilePathWithHashDto;
import org.sonar.db.permission.GlobalPermission;
import org.sonar.scanner.protocol.input.FileData;
-import org.sonar.scanner.protocol.input.MultiModuleProjectRepository;
import org.sonar.scanner.protocol.input.ProjectRepositories;
-import org.sonar.scanner.protocol.input.SingleProjectRepository;
import org.sonar.server.component.ComponentFinder;
import org.sonar.server.exceptions.ForbiddenException;
import org.sonar.server.user.UserSession;
boolean hasScanPerm = userSession.hasComponentPermission(UserRole.SCAN, project) ||
userSession.hasPermission(GlobalPermission.SCAN);
checkPermission(hasScanPerm);
- ComponentDto branchOrMainModule = (branch == null && pullRequest == null) ? project
+ ComponentDto branchComponent = (branch == null && pullRequest == null) ? project
: componentFinder.getByKeyAndOptionalBranchOrPullRequest(session, projectKey, branch, pullRequest);
- List<ComponentDto> modulesTree = dbClient.componentDao().selectEnabledDescendantModules(session, branchOrMainModule.uuid());
-
- List<FilePathWithHashDto> files = searchFilesWithHashAndRevision(session, branchOrMainModule);
-
- // MMF-365 we still have to support multi-module projects because it's not possible to transform from logical to
- // physical structure for some multi-module projects
- if (modulesTree.size() > 1) {
- MultiModuleProjectRepository repository = new MultiModuleProjectRepository();
- addFileDataPerModule(repository, modulesTree, files);
- return repository;
- } else {
- SingleProjectRepository repository = new SingleProjectRepository();
- addFileData(repository, files);
- return repository;
- }
+ List<FilePathWithHashDto> files = searchFilesWithHashAndRevision(session, branchComponent);
+ ProjectRepositories repository = new ProjectRepositories();
+ addFileData(repository, files);
+ return repository;
}
}
- private List<FilePathWithHashDto> searchFilesWithHashAndRevision(DbSession session, @Nullable ComponentDto module) {
- if (module == null) {
+ private List<FilePathWithHashDto> searchFilesWithHashAndRevision(DbSession session, @Nullable ComponentDto branchComponent) {
+ if (branchComponent == null) {
return Collections.emptyList();
}
- return module.isRootProject() ? dbClient.componentDao().selectEnabledFilesFromProject(session, module.uuid())
- : dbClient.componentDao().selectEnabledDescendantFiles(session, module.uuid());
- }
-
- private static void addFileDataPerModule(MultiModuleProjectRepository data, List<ComponentDto> moduleChildren, List<FilePathWithHashDto> files) {
- Map<String, String> moduleKeysByUuid = new HashMap<>();
- for (ComponentDto module : moduleChildren) {
- moduleKeysByUuid.put(module.uuid(), module.getKey());
- }
-
- for (FilePathWithHashDto file : files) {
- FileData fileData = new FileData(file.getSrcHash(), file.getRevision());
- data.addFileDataToModule(moduleKeysByUuid.get(file.getModuleUuid()), file.getPath(), fileData);
- }
+ return dbClient.componentDao().selectEnabledFilesFromProject(session, branchComponent.uuid());
}
- private static void addFileData(SingleProjectRepository data, List<FilePathWithHashDto> files) {
+ private static void addFileData(ProjectRepositories data, List<FilePathWithHashDto> files) {
for (FilePathWithHashDto file : files) {
FileData fileData = new FileData(file.getSrcHash(), file.getRevision());
data.addFileData(file.getPath(), fileData);
import org.junit.Test;
import org.mockito.ArgumentCaptor;
import org.sonar.scanner.protocol.input.FileData;
-import org.sonar.scanner.protocol.input.MultiModuleProjectRepository;
import org.sonar.scanner.protocol.input.ProjectRepositories;
-import org.sonar.scanner.protocol.input.SingleProjectRepository;
import org.sonar.server.ws.TestResponse;
import org.sonar.server.ws.WsActionTester;
import org.sonarqube.ws.Batch.WsProjectResponse;
import static org.sonar.test.JsonAssert.assertJson;
public class ProjectActionTest {
-
- private ProjectDataLoader projectDataLoader = mock(ProjectDataLoader.class);
- private WsActionTester ws = new WsActionTester(new ProjectAction(projectDataLoader));
+ private final ProjectDataLoader projectDataLoader = mock(ProjectDataLoader.class);
+ private final WsActionTester ws = new WsActionTester(new ProjectAction(projectDataLoader));
@Test
public void project_referentials() {
String projectKey = "org.codehaus.sonar:sonar";
- ProjectRepositories projectReferentials = mock(SingleProjectRepository.class);
+ ProjectRepositories projectReferentials = mock(ProjectRepositories.class);
ArgumentCaptor<ProjectDataQuery> queryArgumentCaptor = ArgumentCaptor.forClass(ProjectDataQuery.class);
when(projectDataLoader.load(queryArgumentCaptor.capture())).thenReturn(projectReferentials);
public void do_not_fail_when_a_path_is_null() {
String projectKey = "org.codehaus.sonar:sonar";
- ProjectRepositories projectRepositories = new MultiModuleProjectRepository()
- .addFileDataToModule("module-1", null, new FileData(null, null));
+ ProjectRepositories projectRepositories = new ProjectRepositories()
+ .addFileData(null, new FileData(null, null));
when(projectDataLoader.load(any(ProjectDataQuery.class))).thenReturn(projectRepositories);
WsProjectResponse wsProjectResponse = ws.newRequest()
public void use_new_file_structure_for_projects_without_submodules() {
String projectKey = "org.codehaus.sonar:sonar";
- ProjectRepositories projectRepositories = new SingleProjectRepository()
+ ProjectRepositories projectRepositories = new ProjectRepositories()
.addFileData("src/main/java/SomeClass.java", new FileData("789456", "123456789"));
when(projectDataLoader.load(any(ProjectDataQuery.class))).thenReturn(projectRepositories);
assertThat(wsProjectResponse.getFileDataByPathCount()).isOne();
assertThat(wsProjectResponse.getFileDataByPathMap().get("src/main/java/SomeClass.java")).isNotNull();
}
-
- @Test
- public void use_old_file_structure_for_projects_with_submodules() {
- String projectKey = "org.codehaus.sonar:sonar";
-
- ProjectRepositories projectRepositories = new MultiModuleProjectRepository()
- .addFileDataToModule("module-1", "src/main/java/SomeClass.java", new FileData("789456", "123456789"));
- when(projectDataLoader.load(any(ProjectDataQuery.class))).thenReturn(projectRepositories);
-
- WsProjectResponse wsProjectResponse = ws.newRequest()
- .setParam("key", projectKey)
- .setParam("profile", "Default")
- .executeProtobuf(WsProjectResponse.class);
-
- assertThat(wsProjectResponse.getFileDataByPathMap()).isEmpty();
- assertThat(wsProjectResponse.getFileDataByModuleAndPathCount()).isOne();
- WsProjectResponse.FileDataByPath moduleData = wsProjectResponse.getFileDataByModuleAndPathMap().get("module-1");
- assertThat(moduleData).isNotNull();
- assertThat(moduleData.getFileDataByPathCount()).isOne();
- WsProjectResponse.FileData fileData = moduleData.getFileDataByPathMap().get("src/main/java/SomeClass.java");
- assertThat(fileData).isNotNull();
- assertThat(fileData.getHash()).isEqualTo("789456");
- assertThat(fileData.getRevision()).isEqualTo("123456789");
- }
}
import org.sonar.db.component.ResourceTypesRule;
import org.sonar.db.source.FileSourceDto;
import org.sonar.scanner.protocol.input.FileData;
-import org.sonar.scanner.protocol.input.MultiModuleProjectRepository;
import org.sonar.scanner.protocol.input.ProjectRepositories;
-import org.sonar.scanner.protocol.input.SingleProjectRepository;
import org.sonar.server.component.ComponentFinder;
import org.sonar.server.exceptions.BadRequestException;
import org.sonar.server.exceptions.ForbiddenException;
dbClient.fileSourceDao().insert(dbSession, newFileSourceDto(file).setSrcHash("123456"));
db.commit();
- ProjectRepositories ref = underTest.load(ProjectDataQuery.create().setProjectKey(project.getKey()));
-
- assertTrue(ref instanceof SingleProjectRepository);
- SingleProjectRepository singleProjectRepository = ((SingleProjectRepository) ref);
- assertThat(singleProjectRepository.fileData()).hasSize(1);
- FileData fileData = singleProjectRepository.fileDataByPath(file.path());
+ ProjectRepositories projectRepository = underTest.load(ProjectDataQuery.create().setProjectKey(project.getKey()));
+ assertThat(projectRepository.fileData()).hasSize(1);
+ FileData fileData = projectRepository.fileDataByPath(file.path());
assertThat(fileData).isNotNull();
assertThat(fileData.hash()).isEqualTo("123456");
}
- @Test
- public void return_file_data_from_multi_modules() {
- ComponentDto project = db.components().insertPrivateProject();
- userSession.logIn().addProjectPermission(SCAN_EXECUTION, project);
- ComponentDto module = db.components().insertComponent(newModuleDto(project));
- // File on project
- ComponentDto projectFile = db.components().insertComponent(newFileDto(project));
- dbClient.fileSourceDao().insert(dbSession, newFileSourceDto(projectFile).setSrcHash("123456"));
- // File on module
- ComponentDto moduleFile = db.components().insertComponent(newFileDto(module));
- dbClient.fileSourceDao().insert(dbSession, newFileSourceDto(moduleFile).setSrcHash("789456"));
- dbSession.commit();
-
- ProjectRepositories ref = underTest.load(ProjectDataQuery.create().setProjectKey(project.getKey()));
-
- assertTrue(ref instanceof MultiModuleProjectRepository);
- MultiModuleProjectRepository repository = ((MultiModuleProjectRepository) ref);
- assertThat(repository.fileData(project.getKey(), projectFile.path()).hash()).isEqualTo("123456");
- assertThat(repository.fileData(module.getKey(), moduleFile.path()).hash()).isEqualTo("789456");
- }
-
@Test
public void return_file_data_from_branch() {
ComponentDto project = db.components().insertPrivateProject();
ComponentDto branch = db.components().insertProjectBranch(project, b -> b.setKey("my_branch"));
userSession.logIn().addProjectPermission(SCAN_EXECUTION, project);
- ComponentDto moduleBranch = db.components().insertComponent(newModuleDto(branch));
// File on branch
ComponentDto projectFile = db.components().insertComponent(newFileDto(branch));
dbClient.fileSourceDao().insert(dbSession, newFileSourceDto(projectFile).setSrcHash("123456"));
- // File on moduleBranch branch
- ComponentDto moduleFile = db.components().insertComponent(newFileDto(moduleBranch));
- dbClient.fileSourceDao().insert(dbSession, newFileSourceDto(moduleFile).setSrcHash("789456"));
dbSession.commit();
ProjectRepositories ref = underTest.load(ProjectDataQuery.create()
.setProjectKey(project.getKey())
.setBranch("my_branch"));
- assertTrue(ref instanceof MultiModuleProjectRepository);
- MultiModuleProjectRepository repository = ((MultiModuleProjectRepository) ref);
- assertThat(repository.fileData(branch.getKey(), projectFile.path()).hash()).isEqualTo("123456");
- assertThat(repository.fileData(moduleBranch.getKey(), moduleFile.path()).hash()).isEqualTo("789456");
+ assertThat(ref.fileDataByPath(projectFile.path()).hash()).isEqualTo("123456");
}
@Test
import java.io.File;
import java.nio.file.Path;
-import java.util.LinkedList;
import java.util.Map.Entry;
import java.util.regex.Pattern;
import org.sonar.api.batch.fs.internal.AbstractProjectOrModule;
-import org.sonar.api.batch.fs.internal.DefaultInputModule;
import org.sonar.api.batch.scm.ScmProvider;
import org.sonar.api.utils.log.Logger;
import org.sonar.api.utils.log.Loggers;
.setUpdatedAt(pluginEntry.getValue().getUpdatedAt()).build());
}
- addModulesRelativePaths(builder);
+ addRelativePathFromScmRoot(builder);
writer.writeMetadata(builder.build());
}
- private void addModulesRelativePaths(ScannerReport.Metadata.Builder builder) {
- LinkedList<DefaultInputModule> queue = new LinkedList<>();
- queue.add(moduleHierarchy.root());
-
- while (!queue.isEmpty()) {
- DefaultInputModule module = queue.removeFirst();
- queue.addAll(moduleHierarchy.children(module));
- String relativePath = moduleHierarchy.relativePathToRoot(module);
- if (relativePath != null) {
- builder.putModulesProjectRelativePathByKey(module.key(), relativePath);
- }
- }
-
+ private void addRelativePathFromScmRoot(ScannerReport.Metadata.Builder builder) {
ScmProvider scmProvider = scmConfiguration.provider();
if (scmProvider == null) {
return;
assertThat(metadata.getAnalysisDate()).isEqualTo(1234567L);
assertThat(metadata.getNewCodeReferenceBranch()).isEqualTo("newCodeReference");
assertThat(metadata.getProjectKey()).isEqualTo("root");
- assertThat(metadata.getModulesProjectRelativePathByKeyMap()).containsOnly(entry("module", "modulePath"), entry("root", ""));
assertThat(metadata.getProjectVersion()).isEmpty();
assertThat(metadata.getNotAnalyzedFilesByLanguageCount()).isZero();
assertThat(metadata.getQprofilesPerLanguageMap()).containsOnly(entry("java", org.sonar.scanner.protocol.output.ScannerReport.Metadata.QProfile.newBuilder()
+++ /dev/null
-/*
- * SonarQube
- * Copyright (C) 2009-2023 SonarSource SA
- * mailto:info AT sonarsource DOT com
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 3 of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- */
-package org.sonar.scanner.protocol.input;
-
-import java.util.HashMap;
-import java.util.Map;
-import java.util.Optional;
-import javax.annotation.CheckForNull;
-import javax.annotation.Nullable;
-
-public class MultiModuleProjectRepository implements ProjectRepositories {
- private Map<String, SingleProjectRepository> repositoryPerModule = new HashMap<>();
-
- public MultiModuleProjectRepository addFileDataToModule(String moduleKey, @Nullable String path, FileData fileData) {
- if (path == null || (fileData.hash() == null && fileData.revision() == null)) {
- return this;
- }
-
- SingleProjectRepository repository = repositoryPerModule.computeIfAbsent(moduleKey, k -> new SingleProjectRepository());
- repository.addFileData(path, fileData);
- return this;
- }
-
- public Map<String, SingleProjectRepository> repositoriesByModule() {
- return repositoryPerModule;
- }
-
- @CheckForNull
- public FileData fileData(String moduleKeyWithBranch, @Nullable String path) {
- Optional<SingleProjectRepository> moduleRepository = Optional.ofNullable(repositoryPerModule.get(moduleKeyWithBranch));
- return moduleRepository
- .map(singleProjectRepository -> singleProjectRepository.fileDataByPath(path))
- .orElse(null);
- }
-}
*/
package org.sonar.scanner.protocol.input;
-public interface ProjectRepositories {
+import java.util.HashMap;
+import java.util.Map;
+import javax.annotation.Nullable;
+
+public class ProjectRepositories {
+ private final Map<String, FileData> fileDataByPath = new HashMap<>();
+
+ public ProjectRepositories addFileData(@Nullable String path, FileData fileData) {
+ if (path == null || (fileData.hash() == null && fileData.revision() == null)) {
+ return this;
+ }
+
+ fileDataByPath.put(path, fileData);
+ return this;
+ }
+
+ public Map<String, FileData> fileData() {
+ return fileDataByPath;
+ }
+
+ public FileData fileDataByPath(@Nullable String path) {
+ return fileDataByPath.get(path);
+ }
}
+++ /dev/null
-/*
- * SonarQube
- * Copyright (C) 2009-2023 SonarSource SA
- * mailto:info AT sonarsource DOT com
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 3 of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- */
-package org.sonar.scanner.protocol.input;
-
-import java.util.HashMap;
-import java.util.Map;
-import javax.annotation.Nullable;
-
-public class SingleProjectRepository implements ProjectRepositories {
- private Map<String, FileData> fileDataByPath = new HashMap<>();
-
- public SingleProjectRepository addFileData(@Nullable String path, FileData fileData) {
- if (path == null || (fileData.hash() == null && fileData.revision() == null)) {
- return this;
- }
-
- fileDataByPath.put(path, fileData);
- return this;
- }
-
- public Map<String, FileData> fileData() {
- return fileDataByPath;
- }
-
- public FileData fileDataByPath(@Nullable String path) {
- return fileDataByPath.get(path);
- }
-}
string scm_revision_id = 13;
string pull_request_key = 14;
- map<string, string> modules_project_relative_path_by_key = 15;
+
+ reserved 15; // modules_project_relative_path_by_key (no longer used)
string projectVersion = 16;
string buildString = 17;
+++ /dev/null
-/*
- * SonarQube
- * Copyright (C) 2009-2023 SonarSource SA
- * mailto:info AT sonarsource DOT com
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 3 of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- */
-package org.sonar.scanner.protocol.input;
-
-import org.junit.Before;
-import org.junit.Test;
-
-import static org.assertj.core.api.Assertions.assertThat;
-
-public class MultiModuleProjectRepositoryTest {
-
- private MultiModuleProjectRepository repository;
-
- @Before
- public void setUp() {
- repository = new MultiModuleProjectRepository();
- }
-
- @Test
- public void add_file_data_to_nodule() {
- FileData fileData1 = new FileData("123", "456");
- FileData fileData2 = new FileData("153", "6432");
- FileData fileData3 = new FileData("987", "6343");
-
- repository.addFileDataToModule("Module1", "/Abc.java", fileData1);
- repository.addFileDataToModule("Module1", "/Xyz.java", fileData2);
- repository.addFileDataToModule("Module2", "/Def.java", fileData3);
-
- assertThat(repository.repositoriesByModule()).hasSize(2);
- assertThat(repository.fileData("Module1", "/Xyz.java")).isEqualTo(fileData2);
- assertThat(repository.fileData("Module2", "/Def.java")).isEqualTo(fileData3);
- }
-
- @Test
- public void add_file_does_not_add_the_file_without_path() {
- FileData fileData = new FileData("123", "456");
-
- repository.addFileDataToModule("module1", null, fileData);
-
- assertThat(repository.repositoriesByModule()).isEmpty();
- }
-
- @Test
- public void add_file_does_not_add_the_file_without_revision_and_hash() {
- FileData fileData = new FileData(null, null);
-
- repository.addFileDataToModule("module2", "/Abc.java", fileData);
-
- assertThat(repository.repositoriesByModule()).isEmpty();
- }
-}
--- /dev/null
+/*
+ * SonarQube
+ * Copyright (C) 2009-2023 SonarSource SA
+ * mailto:info AT sonarsource DOT com
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 3 of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+package org.sonar.scanner.protocol.input;
+
+import com.google.common.collect.Maps;
+import org.junit.Before;
+import org.junit.Test;
+
+import static org.assertj.core.api.Assertions.assertThat;
+
+public class ProjectRepositoriesTest {
+ private final ProjectRepositories repository = new ProjectRepositories();
+
+ @Test
+ public void add_file_data() {
+ FileData fileData = new FileData("123", "456");
+
+ repository.addFileData("/Abc.java", fileData);
+
+ assertThat(repository.fileData()).hasSize(1);
+ assertThat(repository.fileData()).contains(Maps.immutableEntry("/Abc.java", fileData));
+ assertThat(repository.fileDataByPath("/Abc.java")).isEqualTo(fileData);
+ }
+
+ @Test
+ public void add_file_data_doesnt_add_the_file_without_path() {
+ FileData fileData = new FileData("123", "456");
+
+ repository.addFileData(null, fileData);
+
+ assertThat(repository.fileData()).isEmpty();
+ }
+
+ @Test
+ public void add_file_data_doesnt_add_the_file_without_revision_and_hash() {
+ FileData fileData = new FileData(null, null);
+
+ repository.addFileData("/Abc.java", fileData);
+
+ assertThat(repository.fileData()).isEmpty();
+ }
+}
+++ /dev/null
-/*
- * SonarQube
- * Copyright (C) 2009-2023 SonarSource SA
- * mailto:info AT sonarsource DOT com
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 3 of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- */
-package org.sonar.scanner.protocol.input;
-
-import com.google.common.collect.Maps;
-import org.junit.Before;
-import org.junit.Test;
-
-import static org.assertj.core.api.Assertions.assertThat;
-
-public class SingleProjectRepositoryTest {
- private SingleProjectRepository repository;
-
- @Before
- public void setUp() {
- repository = new SingleProjectRepository();
- }
-
- @Test
- public void add_file_data() {
- FileData fileData = new FileData("123", "456");
-
- repository.addFileData("/Abc.java", fileData);
-
- assertThat(repository.fileData()).hasSize(1);
- assertThat(repository.fileData()).contains(Maps.immutableEntry("/Abc.java", fileData));
- assertThat(repository.fileDataByPath("/Abc.java")).isEqualTo(fileData);
- }
-
- @Test
- public void add_file_data_doesnt_add_the_file_without_path() {
- FileData fileData = new FileData("123", "456");
-
- repository.addFileData(null, fileData);
-
- assertThat(repository.fileData()).isEmpty();
- }
-
- @Test
- public void add_file_data_doesnt_add_the_file_without_revision_and_hash() {
- FileData fileData = new FileData(null, null);
-
- repository.addFileData("/Abc.java", fileData);
-
- assertThat(repository.fileData()).isEmpty();
- }
-}