Browse Source

SONAR-12197 completely drop "sonar.branch" code

tags/8.0
Michal Duda 4 years ago
parent
commit
05c8a2e004
69 changed files with 167 additions and 1119 deletions
  1. 1
    1
      server/sonar-ce-task-projectanalysis/src/main/java/org/sonar/ce/task/projectanalysis/analysis/AnalysisMetadataHolderImpl.java
  2. 0
    6
      server/sonar-ce-task-projectanalysis/src/main/java/org/sonar/ce/task/projectanalysis/analysis/Branch.java
  3. 2
    5
      server/sonar-ce-task-projectanalysis/src/main/java/org/sonar/ce/task/projectanalysis/api/posttask/PostProjectAnalysisTasksExecutor.java
  4. 4
    14
      server/sonar-ce-task-projectanalysis/src/main/java/org/sonar/ce/task/projectanalysis/component/BranchLoader.java
  5. 4
    26
      server/sonar-ce-task-projectanalysis/src/main/java/org/sonar/ce/task/projectanalysis/component/DefaultBranchImpl.java
  6. 1
    1
      server/sonar-ce-task-projectanalysis/src/main/java/org/sonar/ce/task/projectanalysis/notification/NotificationFactory.java
  7. 1
    1
      server/sonar-ce-task-projectanalysis/src/main/java/org/sonar/ce/task/projectanalysis/step/BuildComponentTreeStep.java
  8. 3
    14
      server/sonar-ce-task-projectanalysis/src/main/java/org/sonar/ce/task/projectanalysis/step/LoadReportAnalysisMetadataHolderStep.java
  9. 5
    22
      server/sonar-ce-task-projectanalysis/src/test/java/org/sonar/ce/task/projectanalysis/analysis/AnalysisMetadataHolderImplTest.java
  10. 0
    12
      server/sonar-ce-task-projectanalysis/src/test/java/org/sonar/ce/task/projectanalysis/analysis/ProjectConfigurationFactoryTest.java
  11. 2
    19
      server/sonar-ce-task-projectanalysis/src/test/java/org/sonar/ce/task/projectanalysis/api/posttask/PostProjectAnalysisTasksExecutorTest.java
  12. 7
    35
      server/sonar-ce-task-projectanalysis/src/test/java/org/sonar/ce/task/projectanalysis/component/BranchLoaderTest.java
  13. 0
    38
      server/sonar-ce-task-projectanalysis/src/test/java/org/sonar/ce/task/projectanalysis/component/DefaultBranchImplTest.java
  14. 2
    10
      server/sonar-ce-task-projectanalysis/src/test/java/org/sonar/ce/task/projectanalysis/notification/NotificationFactoryTest.java
  15. 1
    20
      server/sonar-ce-task-projectanalysis/src/test/java/org/sonar/ce/task/projectanalysis/step/BuildComponentTreeStepTest.java
  16. 0
    28
      server/sonar-ce-task-projectanalysis/src/test/java/org/sonar/ce/task/projectanalysis/step/QualityGateEventsStepTest.java
  17. 0
    5
      server/sonar-ce-task-projectanalysis/src/test/java/org/sonar/ce/task/projectanalysis/step/ReportPersistComponentsStepTest.java
  18. 6
    25
      server/sonar-server/src/main/java/org/sonar/server/ce/queue/BranchSupport.java
  19. 3
    4
      server/sonar-server/src/main/java/org/sonar/server/ce/queue/ReportSubmitter.java
  20. 1
    9
      server/sonar-server/src/main/java/org/sonar/server/ce/ws/SubmitAction.java
  21. 3
    11
      server/sonar-server/src/main/java/org/sonar/server/component/ComponentUpdater.java
  22. 0
    15
      server/sonar-server/src/main/java/org/sonar/server/component/NewComponent.java
  23. 0
    21
      server/sonar-server/src/main/java/org/sonar/server/project/ws/CreateAction.java
  24. 6
    28
      server/sonar-server/src/test/java/org/sonar/server/ce/queue/BranchReportSubmitterTest.java
  25. 4
    47
      server/sonar-server/src/test/java/org/sonar/server/ce/queue/BranchSupportTest.java
  26. 16
    32
      server/sonar-server/src/test/java/org/sonar/server/ce/queue/ReportSubmitterTest.java
  27. 9
    20
      server/sonar-server/src/test/java/org/sonar/server/ce/ws/SubmitActionTest.java
  28. 0
    29
      server/sonar-server/src/test/java/org/sonar/server/component/ComponentUpdaterTest.java
  29. 1
    22
      server/sonar-server/src/test/java/org/sonar/server/project/ws/CreateActionTest.java
  30. 0
    19
      sonar-core/src/main/java/org/sonar/core/component/ComponentKeys.java
  31. 0
    12
      sonar-core/src/test/java/org/sonar/core/component/ComponentKeysTest.java
  32. 0
    16
      sonar-plugin-api-impl/src/main/java/org/sonar/api/batch/fs/internal/AbstractProjectOrModule.java
  33. 0
    4
      sonar-plugin-api-impl/src/test/java/org/sonar/api/batch/fs/internal/fs/DefaultInputModuleTest.java
  34. 0
    2
      sonar-plugin-api-impl/src/test/java/org/sonar/api/batch/fs/internal/fs/DefaultInputProjectTest.java
  35. 0
    6
      sonar-plugin-api/src/main/java/org/sonar/api/CoreProperties.java
  36. 0
    23
      sonar-plugin-api/src/main/java/org/sonar/api/batch/bootstrap/ProjectDefinition.java
  37. 0
    30
      sonar-plugin-api/src/main/java/org/sonar/api/batch/bootstrap/ProjectKey.java
  38. 2
    3
      sonar-plugin-api/src/main/java/org/sonar/api/batch/bootstrap/ProjectReactor.java
  39. 5
    27
      sonar-scanner-engine/src/main/java/org/sonar/scanner/bootstrap/ProcessedScannerProperties.java
  40. 2
    7
      sonar-scanner-engine/src/main/java/org/sonar/scanner/cpd/CpdSettings.java
  41. 1
    5
      sonar-scanner-engine/src/main/java/org/sonar/scanner/report/ComponentsPublisher.java
  42. 0
    4
      sonar-scanner-engine/src/main/java/org/sonar/scanner/report/MetadataPublisher.java
  43. 3
    4
      sonar-scanner-engine/src/main/java/org/sonar/scanner/report/ReportPublisher.java
  44. 1
    1
      sonar-scanner-engine/src/main/java/org/sonar/scanner/repository/ProjectRepositoriesSupplier.java
  45. 1
    1
      sonar-scanner-engine/src/main/java/org/sonar/scanner/repository/QualityProfilesProvider.java
  46. 1
    1
      sonar-scanner-engine/src/main/java/org/sonar/scanner/repository/settings/DefaultProjectSettingsLoader.java
  47. 1
    12
      sonar-scanner-engine/src/main/java/org/sonar/scanner/scan/ProjectReactorValidator.java
  48. 4
    14
      sonar-scanner-engine/src/main/java/org/sonar/scanner/scan/ProjectScanContainer.java
  49. 1
    1
      sonar-scanner-engine/src/main/java/org/sonar/scanner/scan/branch/BranchParamsValidator.java
  50. 0
    30
      sonar-scanner-engine/src/main/java/org/sonar/scanner/scan/branch/DefaultBranchParamsValidator.java
  51. 9
    9
      sonar-scanner-engine/src/main/java/org/sonar/scanner/scan/branch/ProjectBranchesProvider.java
  52. 3
    3
      sonar-scanner-engine/src/main/java/org/sonar/scanner/scan/branch/ProjectPullRequestsProvider.java
  53. 1
    1
      sonar-scanner-engine/src/main/java/org/sonar/scanner/scan/filesystem/FileIndexer.java
  54. 1
    1
      sonar-scanner-engine/src/main/java/org/sonar/scanner/scm/ScmPublisher.java
  55. 1
    3
      sonar-scanner-engine/src/test/java/org/sonar/scanner/cpd/CpdSettingsTest.java
  56. 4
    87
      sonar-scanner-engine/src/test/java/org/sonar/scanner/mediumtest/branch/DeprecatedBranchMediumTest.java
  57. 0
    42
      sonar-scanner-engine/src/test/java/org/sonar/scanner/mediumtest/fs/FileSystemMediumTest.java
  58. 0
    40
      sonar-scanner-engine/src/test/java/org/sonar/scanner/mediumtest/fs/ProjectBuilderMediumTest.java
  59. 6
    59
      sonar-scanner-engine/src/test/java/org/sonar/scanner/mediumtest/scm/ScmMediumTest.java
  60. 1
    33
      sonar-scanner-engine/src/test/java/org/sonar/scanner/report/ComponentsPublisherTest.java
  61. 1
    25
      sonar-scanner-engine/src/test/java/org/sonar/scanner/report/MetadataPublisherTest.java
  62. 2
    2
      sonar-scanner-engine/src/test/java/org/sonar/scanner/repository/ProjectRepositoriesSupplierTest.java
  63. 1
    1
      sonar-scanner-engine/src/test/java/org/sonar/scanner/repository/QualityProfileProviderTest.java
  64. 1
    1
      sonar-scanner-engine/src/test/java/org/sonar/scanner/repository/settings/DefaultProjectSettingsLoaderTest.java
  65. 1
    7
      sonar-scanner-engine/src/test/java/org/sonar/scanner/scan/ModuleIndexerTest.java
  66. 0
    44
      sonar-scanner-engine/src/test/java/org/sonar/scanner/scan/ProjectReactorValidatorTest.java
  67. 10
    5
      sonar-scanner-engine/src/test/java/org/sonar/scanner/scan/branch/ProjectBranchesProviderTest.java
  68. 10
    4
      sonar-scanner-engine/src/test/java/org/sonar/scanner/scan/branch/ProjectPullRequestsProviderTest.java
  69. 11
    10
      sonar-scanner-protocol/src/main/protobuf/scanner_report.proto

+ 1
- 1
server/sonar-ce-task-projectanalysis/src/main/java/org/sonar/ce/task/projectanalysis/analysis/AnalysisMetadataHolderImpl.java View File

@@ -153,7 +153,7 @@ public class AnalysisMetadataHolderImpl implements MutableAnalysisMetadataHolder
checkState(!this.branch.isInitialized(), "Branch has already been set");
boolean isCommunityEdition = editionProvider.get().filter(t -> t == EditionProvider.Edition.COMMUNITY).isPresent();
checkState(
!isCommunityEdition || branch.isMain() || branch.isLegacyFeature(),
!isCommunityEdition || branch.isMain(),
"Branches and Pull Requests are not supported in Community Edition");
this.branch.setProperty(branch);
return this;

+ 0
- 6
server/sonar-ce-task-projectanalysis/src/main/java/org/sonar/ce/task/projectanalysis/analysis/Branch.java View File

@@ -30,12 +30,6 @@ public interface Branch extends ComponentKeyGenerator {

boolean isMain();

/**
* Whether branch has been created through the legacy configuration
* (scanner parameter sonar.branch) or not
*/
boolean isLegacyFeature();

/**
* Name of the branch
*/

+ 2
- 5
server/sonar-ce-task-projectanalysis/src/main/java/org/sonar/ce/task/projectanalysis/api/posttask/PostProjectAnalysisTasksExecutor.java View File

@@ -230,11 +230,8 @@ public class PostProjectAnalysisTasksExecutor implements ComputationStepExecutor
@CheckForNull
private BranchImpl createBranch() {
org.sonar.ce.task.projectanalysis.analysis.Branch analysisBranch = analysisMetadataHolder.getBranch();
if (!analysisBranch.isLegacyFeature()) {
String branchKey = analysisBranch.getType() == PULL_REQUEST ? analysisBranch.getPullRequestKey() : analysisBranch.getName();
return new BranchImpl(analysisBranch.isMain(), branchKey, Branch.Type.valueOf(analysisBranch.getType().name()));
}
return null;
String branchKey = analysisBranch.getType() == PULL_REQUEST ? analysisBranch.getPullRequestKey() : analysisBranch.getName();
return new BranchImpl(analysisBranch.isMain(), branchKey, Branch.Type.valueOf(analysisBranch.getType().name()));
}

private static QualityGate.Status convert(QualityGateStatus status) {

+ 4
- 14
server/sonar-ce-task-projectanalysis/src/main/java/org/sonar/ce/task/projectanalysis/component/BranchLoader.java View File

@@ -24,7 +24,6 @@ import org.sonar.api.utils.MessageException;
import org.sonar.ce.task.projectanalysis.analysis.MutableAnalysisMetadataHolder;
import org.sonar.scanner.protocol.output.ScannerReport;

import static org.apache.commons.lang.StringUtils.trimToNull;
import static org.sonar.scanner.protocol.output.ScannerReport.Metadata.BranchType.UNSET;

public class BranchLoader {
@@ -41,21 +40,12 @@ public class BranchLoader {
}

public void load(ScannerReport.Metadata metadata) {
String deprecatedBranch = trimToNull(metadata.getDeprecatedBranch());
String branchName = trimToNull(metadata.getBranchName());

if (deprecatedBranch != null && branchName != null) {
throw MessageException.of("Properties sonar.branch and sonar.branch.name can't be set together");
}

if (delegate == null && hasBranchProperties(metadata)) {
throw MessageException.of("Current edition does not support branch feature");
}

if (delegate != null && deprecatedBranch == null) {
if (delegate != null) {
delegate.load(metadata);
} else if (hasBranchProperties(metadata)) {
throw MessageException.of("Current edition does not support branch feature");
} else {
metadataHolder.setBranch(new DefaultBranchImpl(deprecatedBranch));
metadataHolder.setBranch(new DefaultBranchImpl());
}
}


+ 4
- 26
server/sonar-ce-task-projectanalysis/src/main/java/org/sonar/ce/task/projectanalysis/component/DefaultBranchImpl.java View File

@@ -20,36 +20,23 @@
package org.sonar.ce.task.projectanalysis.component;

import javax.annotation.Nullable;
import org.sonar.api.utils.MessageException;
import org.sonar.ce.task.projectanalysis.analysis.Branch;
import org.sonar.core.component.ComponentKeys;
import org.sonar.db.component.BranchDto;
import org.sonar.db.component.BranchType;

import static java.lang.String.format;
import static org.apache.commons.lang.StringUtils.isEmpty;
import static org.apache.commons.lang.StringUtils.trimToNull;

/**
* The default (and legacy) implementation of {@link Branch}. It is used
* when scanner is configured with parameter "sonar.branch" or when no branch is provided and the branch plugin is not installed.
* A legacy branch is implemented as a fork of the project, so any branch is considered as "main".
* Implementation of {@link Branch} for default/main branch. It is used
* when no branch is provided as a scanner parameter or if the branch plugin is not installed.
*/
public class DefaultBranchImpl implements Branch {
private final String branchName;
private final boolean isLegacyBranch;

public DefaultBranchImpl() {
this(null);
}

public DefaultBranchImpl(@Nullable String name) {
this.isLegacyBranch = (name != null);
this.branchName = (name == null) ? BranchDto.DEFAULT_MAIN_BRANCH_NAME : name;
if (!ComponentKeys.isValidLegacyBranch(branchName)) {
throw MessageException.of(format("\"%s\" is not a valid branch name. "
+ "Allowed characters are alphanumeric, '-', '_', '.' and '/'.", branchName));
}
this.branchName = BranchDto.DEFAULT_MAIN_BRANCH_NAME;
}

@Override
@@ -67,11 +54,6 @@ public class DefaultBranchImpl implements Branch {
throw new IllegalStateException("Not valid for the main branch");
}

@Override
public boolean isLegacyFeature() {
return isLegacyBranch;
}

@Override
public String getName() {
return branchName;
@@ -79,8 +61,7 @@ public class DefaultBranchImpl implements Branch {

@Override
public boolean supportsCrossProjectCpd() {
// only on regular project, not on branches
return !isLegacyBranch;
return true;
}

@Override
@@ -95,9 +76,6 @@ public class DefaultBranchImpl implements Branch {

@Override
public String generateKey(String projectKey, @Nullable String fileOrDirPath) {
if (isLegacyBranch) {
projectKey = ComponentKeys.createKey(projectKey, branchName);
}
if (isEmpty(fileOrDirPath)) {
return projectKey;
}

+ 1
- 1
server/sonar-ce-task-projectanalysis/src/main/java/org/sonar/ce/task/projectanalysis/notification/NotificationFactory.java View File

@@ -121,7 +121,7 @@ public class NotificationFactory {
Project.Builder builder = new Project.Builder(project.getUuid())
.setKey(project.getKey())
.setProjectName(project.getName());
if (!branch.isLegacyFeature() && branch.getType() != PULL_REQUEST && !branch.isMain()) {
if (branch.getType() != PULL_REQUEST && !branch.isMain()) {
builder.setBranchName(branch.getName());
}
return builder.build();

+ 1
- 1
server/sonar-ce-task-projectanalysis/src/main/java/org/sonar/ce/task/projectanalysis/step/BuildComponentTreeStep.java View File

@@ -135,7 +135,7 @@ public class BuildComponentTreeStep implements ComputationStep {
Branch branch = analysisMetadataHolder.getBranch();

// for non-legacy branches, the public key is different from the DB key.
if (!branch.isLegacyFeature() && !branch.isMain()) {
if (!branch.isMain()) {
return new DefaultBranchImpl();
}
return branch;

+ 3
- 14
server/sonar-ce-task-projectanalysis/src/main/java/org/sonar/ce/task/projectanalysis/step/LoadReportAnalysisMetadataHolderStep.java View File

@@ -25,7 +25,6 @@ import java.util.List;
import java.util.Optional;
import javax.annotation.CheckForNull;
import javax.annotation.Nullable;
import org.apache.commons.lang.StringUtils;
import org.sonar.api.utils.MessageException;
import org.sonar.ce.task.CeTask;
import org.sonar.ce.task.projectanalysis.analysis.MutableAnalysisMetadataHolder;
@@ -34,7 +33,6 @@ import org.sonar.ce.task.projectanalysis.analysis.ScannerPlugin;
import org.sonar.ce.task.projectanalysis.batch.BatchReportReader;
import org.sonar.ce.task.projectanalysis.component.BranchLoader;
import org.sonar.ce.task.step.ComputationStep;
import org.sonar.core.component.ComponentKeys;
import org.sonar.core.platform.PluginRepository;
import org.sonar.core.util.stream.MoreCollectors;
import org.sonar.db.DbClient;
@@ -104,7 +102,6 @@ public class LoadReportAnalysisMetadataHolderStep implements ComputationStep {
* @return a {@link Runnable} to execute some checks on the project at the end of the step
*/
private Runnable loadProject(ScannerReport.Metadata reportMetadata, Organization organization) {
String reportProjectKey = projectKeyFromReport(reportMetadata);
CeTask.Component mainComponent = mandatoryComponent(ceTask.getMainComponent());
String mainComponentKey = mainComponent.getKey()
.orElseThrow(() -> MessageException.of(format(
@@ -115,14 +112,14 @@ public class LoadReportAnalysisMetadataHolderStep implements ComputationStep {
.orElseThrow(() -> MessageException.of(format(
"Compute Engine task component key is null. Project with UUID %s must have been deleted since report was uploaded. Can not proceed.",
component.getUuid())));
ComponentDto dto = toProject(reportProjectKey);
ComponentDto dto = toProject(reportMetadata.getProjectKey());

analysisMetadata.setProject(Project.from(dto));
return () -> {
if (!mainComponentKey.equals(reportProjectKey)) {
if (!mainComponentKey.equals(reportMetadata.getProjectKey())) {
throw MessageException.of(format(
"ProjectKey in report (%s) is not consistent with projectKey under which the report has been submitted (%s)",
reportProjectKey,
reportMetadata.getProjectKey(),
mainComponentKey));
}
if (!dto.getOrganizationUuid().equals(organization.getUuid())) {
@@ -233,14 +230,6 @@ public class LoadReportAnalysisMetadataHolderStep implements ComputationStep {
}
}

private static String projectKeyFromReport(ScannerReport.Metadata reportMetadata) {
String deprecatedBranch = reportMetadata.getDeprecatedBranch();
if (StringUtils.isNotEmpty(deprecatedBranch)) {
return ComponentKeys.createKey(reportMetadata.getProjectKey(), deprecatedBranch);
}
return reportMetadata.getProjectKey();
}

@Override
public String getDescription() {
return "Load analysis metadata";

+ 5
- 22
server/sonar-ce-task-projectanalysis/src/test/java/org/sonar/ce/task/projectanalysis/analysis/AnalysisMetadataHolderImplTest.java View File

@@ -233,7 +233,7 @@ public class AnalysisMetadataHolderImplTest {
public void set_branch() {
AnalysisMetadataHolderImpl underTest = new AnalysisMetadataHolderImpl(editionProvider);

underTest.setBranch(new DefaultBranchImpl("master"));
underTest.setBranch(new DefaultBranchImpl());

assertThat(underTest.getBranch().getName()).isEqualTo("master");
}
@@ -249,11 +249,11 @@ public class AnalysisMetadataHolderImplTest {
@Test
public void setBranch_throws_ISE_when_called_twice() {
AnalysisMetadataHolderImpl underTest = new AnalysisMetadataHolderImpl(editionProvider);
underTest.setBranch(new DefaultBranchImpl("master"));
underTest.setBranch(new DefaultBranchImpl());

expectedException.expect(IllegalStateException.class);
expectedException.expectMessage("Branch has already been set");
underTest.setBranch(new DefaultBranchImpl("master"));
underTest.setBranch(new DefaultBranchImpl());
}

@Test
@@ -262,21 +262,6 @@ public class AnalysisMetadataHolderImplTest {
when(editionProvider.get()).thenReturn(Optional.ofNullable(edition));
Branch branch = mock(Branch.class);
when(branch.isMain()).thenReturn(true);
when(branch.isLegacyFeature()).thenReturn(false);
AnalysisMetadataHolderImpl underTest = new AnalysisMetadataHolderImpl(editionProvider);

underTest.setBranch(branch);

assertThat(underTest.getBranch()).isSameAs(branch);
}

@Test
@UseDataProvider("anyEditionIncludingNone")
public void setBranch_does_not_fail_if_legacy_branch_on_any_edition(@Nullable Edition edition) {
when(editionProvider.get()).thenReturn(Optional.ofNullable(edition));
Branch branch = mock(Branch.class);
when(branch.isMain()).thenReturn(false);
when(branch.isLegacyFeature()).thenReturn(true);
AnalysisMetadataHolderImpl underTest = new AnalysisMetadataHolderImpl(editionProvider);

underTest.setBranch(branch);
@@ -286,11 +271,10 @@ public class AnalysisMetadataHolderImplTest {

@Test
@UseDataProvider("anyEditionIncludingNoneButCommunity")
public void setBranch_does_not_fail_if_non_main_non_legacy_branch_on_any_edition_but_Community(@Nullable Edition edition) {
public void setBranch_does_not_fail_if_non_main_on_any_edition_but_Community(@Nullable Edition edition) {
when(editionProvider.get()).thenReturn(Optional.ofNullable(edition));
Branch branch = mock(Branch.class);
when(branch.isMain()).thenReturn(false);
when(branch.isLegacyFeature()).thenReturn(false);
AnalysisMetadataHolderImpl underTest = new AnalysisMetadataHolderImpl(editionProvider);

underTest.setBranch(branch);
@@ -299,11 +283,10 @@ public class AnalysisMetadataHolderImplTest {
}

@Test
public void setBranch_fails_if_non_main_non_legacy_branch_on_Community_edition() {
public void setBranch_fails_if_non_main_branch_on_Community_edition() {
when(editionProvider.get()).thenReturn(Optional.of(Edition.COMMUNITY));
Branch branch = mock(Branch.class);
when(branch.isMain()).thenReturn(false);
when(branch.isLegacyFeature()).thenReturn(false);
AnalysisMetadataHolderImpl underTest = new AnalysisMetadataHolderImpl(editionProvider);

expectedException.expect(IllegalStateException.class);

+ 0
- 12
server/sonar-ce-task-projectanalysis/src/test/java/org/sonar/ce/task/projectanalysis/analysis/ProjectConfigurationFactoryTest.java View File

@@ -138,18 +138,6 @@ public class ProjectConfigurationFactoryTest {
assertThat(config.get("sonar.leak.period")).hasValue("1");
}

@Test
public void legacy_branch() {
ComponentDto project = db.components().insertMainBranch();
db.properties().insertProperties(newComponentPropertyDto(project).setKey("sonar.leak.period").setValue("1"));
Branch branch = createBranch("legacy", true);
when(branch.isLegacyFeature()).thenReturn(true);

Configuration config = underTest.newProjectConfiguration(project.getKey(), createBranch(branch.getName(), true));

assertThat(config.get("sonar.leak.period")).hasValue("1");
}

private static Branch createBranch(String name, boolean isMain) {
Branch branch = mock(Branch.class);
when(branch.getName()).thenReturn(name);

+ 2
- 19
server/sonar-ce-task-projectanalysis/src/test/java/org/sonar/ce/task/projectanalysis/api/posttask/PostProjectAnalysisTasksExecutorTest.java View File

@@ -46,7 +46,6 @@ import org.sonar.ce.task.projectanalysis.analysis.AnalysisMetadataHolderRule;
import org.sonar.ce.task.projectanalysis.analysis.Branch;
import org.sonar.ce.task.projectanalysis.analysis.Organization;
import org.sonar.ce.task.projectanalysis.batch.BatchReportReaderRule;
import org.sonar.ce.task.projectanalysis.component.DefaultBranchImpl;
import org.sonar.ce.task.projectanalysis.metric.Metric;
import org.sonar.ce.task.projectanalysis.qualitygate.Condition;
import org.sonar.ce.task.projectanalysis.qualitygate.ConditionStatus;
@@ -276,17 +275,6 @@ public class PostProjectAnalysisTasksExecutorTest {
assertThat(taskContextCaptor.getValue().getProjectAnalysis().getAnalysis()).isEmpty();
}

@Test
public void branch_is_empty_when_legacy_branch_implementation_is_used() {
analysisMetadataHolder.setBranch(new DefaultBranchImpl("feature/foo"));

underTest.finished(true);

verify(postProjectAnalysisTask).finished(taskContextCaptor.capture());

assertThat(taskContextCaptor.getValue().getProjectAnalysis().getBranch()).isEmpty();
}

@Test
public void branch_comes_from_AnalysisMetadataHolder_when_set() {
analysisMetadataHolder.setBranch(new Branch() {
@@ -300,11 +288,6 @@ public class PostProjectAnalysisTasksExecutorTest {
return false;
}

@Override
public boolean isLegacyFeature() {
return false;
}

@Override
public String getMergeBranchUuid() {
throw new UnsupportedOperationException();
@@ -447,7 +430,7 @@ public class PostProjectAnalysisTasksExecutorTest {
new PostProjectAnalysisTasksExecutor(
ceTask, analysisMetadataHolder, qualityGateHolder, qualityGateStatusHolder, reportReader,
system2, new PostProjectAnalysisTask[] {logStatisticsTask})
.finished(allStepsExecuted);
.finished(allStepsExecuted);

verify(logStatisticsTask).finished(taskContextCaptor.capture());

@@ -455,7 +438,7 @@ public class PostProjectAnalysisTasksExecutorTest {
List<String> logs = logTester.logs(LoggerLevel.INFO);
assertThat(logs).hasSize(1);
StringBuilder expectedLog = new StringBuilder("^PT1 ");
stats.forEach((k,v) -> expectedLog.append("\\| " + k + "=" + v +" "));
stats.forEach((k, v) -> expectedLog.append("\\| " + k + "=" + v + " "));
expectedLog.append("\\| status=SUCCESS \\| time=\\d+ms$");
assertThat(logs.get(0)).matches(expectedLog.toString());
}

+ 7
- 35
server/sonar-ce-task-projectanalysis/src/test/java/org/sonar/ce/task/projectanalysis/component/BranchLoaderTest.java View File

@@ -30,6 +30,8 @@ import org.sonar.scanner.protocol.output.ScannerReport;

import static org.assertj.core.api.Assertions.assertThat;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.times;
import static org.mockito.Mockito.verify;

public class BranchLoaderTest {
@Rule
@@ -39,14 +41,13 @@ public class BranchLoaderTest {
public AnalysisMetadataHolderRule metadataHolder = new AnalysisMetadataHolderRule();

@Test
public void throw_ME_if_both_branch_properties_are_set() {
public void throw_ME_if_both_delegate_absent_and_has_branch_parameters() {
ScannerReport.Metadata metadata = ScannerReport.Metadata.newBuilder()
.setDeprecatedBranch("foo")
.setBranchName("bar")
.build();

expectedException.expect(MessageException.class);
expectedException.expectMessage("Properties sonar.branch and sonar.branch.name can't be set together");
expectedException.expectMessage("Current edition does not support branch feature");

new BranchLoader(metadataHolder).load(metadata);
}
@@ -66,42 +67,13 @@ public class BranchLoaderTest {
}

@Test
public void default_support_of_branches_is_enabled_if_delegate_is_absent() {
public void default_support_of_branches_is_enabled_if_delegate_is_present_for_main_branch() {
ScannerReport.Metadata metadata = ScannerReport.Metadata.newBuilder()
.setDeprecatedBranch("foo")
.build();
BranchLoaderDelegate delegate = mock(BranchLoaderDelegate.class);

new BranchLoader(metadataHolder).load(metadata);

assertThat(metadataHolder.getBranch()).isNotNull();

Branch branch = metadataHolder.getBranch();
assertThat(branch.isMain()).isTrue();
assertThat(branch.getName()).isEqualTo("foo");
}

@Test
public void default_support_of_branches_is_enabled_if_delegate_is_present() {
ScannerReport.Metadata metadata = ScannerReport.Metadata.newBuilder()
.setDeprecatedBranch("foo")
.build();

FakeDelegate delegate = new FakeDelegate();
new BranchLoader(metadataHolder, delegate).load(metadata);

assertThat(metadataHolder.getBranch()).isNotNull();

Branch branch = metadataHolder.getBranch();
assertThat(branch.isMain()).isTrue();
assertThat(branch.getName()).isEqualTo("foo");
}

private class FakeDelegate implements BranchLoaderDelegate {
Branch branch = mock(Branch.class);

@Override
public void load(ScannerReport.Metadata metadata) {
metadataHolder.setBranch(branch);
}
verify(delegate, times(1)).load(metadata);
}
}

+ 0
- 38
server/sonar-ce-task-projectanalysis/src/test/java/org/sonar/ce/task/projectanalysis/component/DefaultBranchImplTest.java View File

@@ -19,11 +19,9 @@
*/
package org.sonar.ce.task.projectanalysis.component;

import javax.annotation.Nullable;
import org.junit.Rule;
import org.junit.Test;
import org.junit.rules.ExpectedException;
import org.sonar.api.utils.MessageException;
import org.sonar.db.component.BranchDto;
import org.sonar.db.component.BranchType;
import org.sonar.scanner.protocol.output.ScannerReport;
@@ -38,16 +36,6 @@ public class DefaultBranchImplTest {
@Rule
public ExpectedException expectedException = ExpectedException.none();

@Test
public void throw_ME_if_name_contains_invalid_characters() {
assertThatNameIsCorrect("master");
assertThatNameIsCorrect("feature/foo");
assertThatNameIsCorrect("feature_foo");

assertThatNameIsNotCorrect("feature foo");
assertThatNameIsNotCorrect("feature#foo");
}

@Test
public void default_branch_represents_the_project() {
DefaultBranchImpl branch = new DefaultBranchImpl();
@@ -60,30 +48,4 @@ public class DefaultBranchImplTest {
assertThat(branch.generateKey(PROJECT_KEY, null)).isEqualTo("P");
assertThat(branch.generateKey(PROJECT_KEY, FILE.getProjectRelativePath())).isEqualTo("P:src/Foo.js");
}

@Test
public void branch_represents_a_forked_project_with_different_key() {
DefaultBranchImpl branch = new DefaultBranchImpl("bar");

// not a real branch. Parameter sonar.branch forks project.
assertThat(branch.isMain()).isTrue();
assertThat(branch.getType()).isEqualTo(BranchType.LONG);
assertThat(branch.getName()).isEqualTo("bar");
assertThat(branch.supportsCrossProjectCpd()).isFalse();

assertThat(branch.generateKey(PROJECT_KEY, null)).isEqualTo("P:bar");
assertThat(branch.generateKey(PROJECT_KEY, FILE.getProjectRelativePath())).isEqualTo("P:bar:src/Foo.js");
}

private void assertThatNameIsCorrect(@Nullable String name) {
DefaultBranchImpl branch = new DefaultBranchImpl(name);
assertThat(branch.getName()).isEqualTo(name);
}

private void assertThatNameIsNotCorrect(String name) {
expectedException.expect(MessageException.class);
expectedException.expectMessage("\"" + name + "\" is not a valid branch name. Allowed characters are alphanumeric, '-', '_', '.' and '/'.");

new DefaultBranchImpl(name);
}
}

+ 2
- 10
server/sonar-ce-task-projectanalysis/src/test/java/org/sonar/ce/task/projectanalysis/notification/NotificationFactoryTest.java View File

@@ -569,21 +569,15 @@ public class NotificationFactoryTest {
public static Object[][] noBranchNameBranches() {
Branch mainBranch = mock(Branch.class);
when(mainBranch.isMain()).thenReturn(true);
when(mainBranch.isLegacyFeature()).thenReturn(false);
when(mainBranch.getType()).thenReturn(BranchType.LONG);
Branch legacyBranch = mock(Branch.class);
when(legacyBranch.isLegacyFeature()).thenReturn(true);
Branch shortBranch = mock(Branch.class);
when(shortBranch.isLegacyFeature()).thenReturn(false);
when(shortBranch.isMain()).thenReturn(false);
when(shortBranch.getType()).thenReturn(BranchType.SHORT);
Branch pr = mock(Branch.class);
when(pr.isLegacyFeature()).thenReturn(false);
when(pr.isMain()).thenReturn(false);
when(pr.getType()).thenReturn(BranchType.PULL_REQUEST);
return new Object[][] {
{mainBranch},
{legacyBranch},
{shortBranch},
{pr}
};
@@ -664,7 +658,7 @@ public class NotificationFactoryTest {

expectedException.expect(IllegalStateException.class);
expectedException.expectMessage("Can not find DTO for assignee uuid " + assigneeUuid);
underTest.newIssuesChangesNotification(ImmutableSet.of(issue), assigneesByUuid);
}

@@ -762,8 +756,7 @@ public class NotificationFactoryTest {
assertThat(changedIssue.getAssignee()).isEmpty();
assertThat(changedIssue.getRule().getKey()).isEqualTo(issue.ruleKey());
assertThat(changedIssue.getRule().getName()).isEqualTo(ruleRepository.getByKey(issue.ruleKey()).getName());
}
);
});
}

private static Map<String, UserDto> nonEmptyAssigneesByUuid() {
@@ -782,7 +775,6 @@ public class NotificationFactoryTest {

private static Branch newBranch(BranchType branchType, String branchName) {
Branch longBranch = mock(Branch.class);
when(longBranch.isLegacyFeature()).thenReturn(false);
when(longBranch.isMain()).thenReturn(false);
when(longBranch.getType()).thenReturn(branchType);
when(longBranch.getName()).thenReturn(branchName);

+ 1
- 20
server/sonar-ce-task-projectanalysis/src/test/java/org/sonar/ce/task/projectanalysis/step/BuildComponentTreeStepTest.java View File

@@ -178,7 +178,6 @@ public class BuildComponentTreeStepTest {
Branch branch = mock(Branch.class);
when(branch.getName()).thenReturn("origin/feature");
when(branch.isMain()).thenReturn(false);
when(branch.isLegacyFeature()).thenReturn(false);
when(branch.generateKey(any(), any())).thenReturn("generated");
analysisMetadataHolder.setRootComponentRef(ROOT_REF)
.setAnalysisDate(ANALYSIS_DATE)
@@ -208,7 +207,6 @@ public class BuildComponentTreeStepTest {
Branch branch = mock(Branch.class);
when(branch.getName()).thenReturn(branchDto.getBranch());
when(branch.isMain()).thenReturn(false);
when(branch.isLegacyFeature()).thenReturn(false);
when(branch.generateKey(any(), any())).thenReturn(branchDto.getDbKey());
analysisMetadataHolder.setRootComponentRef(ROOT_REF)
.setAnalysisDate(ANALYSIS_DATE)
@@ -240,23 +238,6 @@ public class BuildComponentTreeStepTest {
verifyComponentByRef(FILE_1_REF, REPORT_PROJECT_KEY + ":" + REPORT_FILE_PATH_1, REPORT_PROJECT_KEY + ":" + REPORT_FILE_PATH_1, REPORT_FILE_NAME_1, null);
}

@Test
public void generate_keys_when_using_legacy_branch() {
analysisMetadataHolder.setRootComponentRef(ROOT_REF)
.setAnalysisDate(ANALYSIS_DATE)
.setProject(Project.from(newPrivateProjectDto(newOrganizationDto()).setDbKey(REPORT_PROJECT_KEY)))
.setBranch(new DefaultBranchImpl("origin/feature"));
BuildComponentTreeStep underTest = new BuildComponentTreeStep(dbClient, reportReader, treeRootHolder, analysisMetadataHolder, reportModulesPath);
reportReader.putComponent(component(ROOT_REF, PROJECT, REPORT_PROJECT_KEY, FILE_1_REF));
reportReader.putComponent(componentWithPath(FILE_1_REF, FILE, REPORT_FILE_PATH_1));

underTest.execute(new TestComputationStepContext());

verifyComponentByRef(ROOT_REF, REPORT_PROJECT_KEY + ":origin/feature", analysisMetadataHolder.getProject().getName(), null);
verifyComponentByKey(REPORT_PROJECT_KEY + ":origin/feature:" + REPORT_DIR_PATH_1, REPORT_DIR_PATH_1);
verifyComponentByRef(FILE_1_REF, REPORT_PROJECT_KEY + ":origin/feature:" + REPORT_FILE_PATH_1, REPORT_FILE_NAME_1, null);
}

@Test
public void compute_keys_and_uuids_on_project_having_module_and_directory() {
setAnalysisMetadataHolder();
@@ -517,7 +498,7 @@ public class BuildComponentTreeStepTest {
private void setAnalysisMetadataHolder() {
analysisMetadataHolder.setRootComponentRef(ROOT_REF)
.setAnalysisDate(ANALYSIS_DATE)
.setBranch(new DefaultBranchImpl(null))
.setBranch(new DefaultBranchImpl())
.setProject(Project.from(newPrivateProjectDto(newOrganizationDto()).setDbKey(REPORT_PROJECT_KEY)));
}


+ 0
- 28
server/sonar-ce-task-projectanalysis/src/test/java/org/sonar/ce/task/projectanalysis/step/QualityGateEventsStepTest.java View File

@@ -248,34 +248,6 @@ public class QualityGateEventsStepTest {
reset(measureRepository, eventRepository, notificationService);
}

@Test
public void verify_branch_name_is_set_in_notification_when_not_main() {
String branchName = "feature1";
analysisMetadataHolder.setBranch(new DefaultBranchImpl(branchName) {
@Override
public boolean isMain() {
return false;
}
});

when(measureRepository.getRawMeasure(PROJECT_COMPONENT, alertStatusMetric))
.thenReturn(of(Measure.newMeasureBuilder().setQualityGateStatus(OK_QUALITY_GATE_STATUS).createNoValue()));
when(measureRepository.getBaseMeasure(PROJECT_COMPONENT, alertStatusMetric)).thenReturn(
of(Measure.newMeasureBuilder().setQualityGateStatus(new QualityGateStatus(ERROR)).createNoValue()));

underTest.execute(new TestComputationStepContext());

verify(notificationService).deliver(notificationArgumentCaptor.capture());
Notification notification = notificationArgumentCaptor.getValue();
assertThat(notification.getType()).isEqualTo("alerts");
assertThat(notification.getFieldValue("projectKey")).isEqualTo(PROJECT_COMPONENT.getKey());
assertThat(notification.getFieldValue("projectName")).isEqualTo(PROJECT_COMPONENT.getName());
assertThat(notification.getFieldValue("projectVersion")).isEqualTo(PROJECT_COMPONENT.getProjectAttributes().getProjectVersion());
assertThat(notification.getFieldValue("branch")).isEqualTo(branchName);

reset(measureRepository, eventRepository, notificationService);
}

@Test
public void verify_branch_name_is_not_set_in_notification_when_main() {
analysisMetadataHolder.setBranch(new DefaultBranchImpl());

+ 0
- 5
server/sonar-ce-task-projectanalysis/src/test/java/org/sonar/ce/task/projectanalysis/step/ReportPersistComponentsStepTest.java View File

@@ -675,11 +675,6 @@ public class ReportPersistComponentsStepTest extends BaseStepTest {
throw new UnsupportedOperationException();
}

@Override
public boolean isLegacyFeature() {
return false;
}

@Override
public String getName() {
return name;

+ 6
- 25
server/sonar-server/src/main/java/org/sonar/server/ce/queue/BranchSupport.java View File

@@ -26,22 +26,19 @@ import javax.annotation.CheckForNull;
import javax.annotation.Nullable;
import javax.annotation.concurrent.Immutable;
import org.sonar.api.server.ServerSide;
import org.sonar.core.component.ComponentKeys;
import org.sonar.db.DbSession;
import org.sonar.db.component.BranchDto;
import org.sonar.db.component.BranchType;
import org.sonar.db.component.ComponentDto;
import org.sonar.db.organization.OrganizationDto;

import static com.google.common.base.Preconditions.checkArgument;
import static com.google.common.base.Preconditions.checkState;
import static java.util.Objects.requireNonNull;

/**
* Branch code for {@link ReportSubmitter}.
* <p>
* Does not support branches (except deprecated branch feature provided by "sonar.branch") unless an implementation of
* {@link BranchSupportDelegate} is available.
* Does not support branches unless an implementation of {@link BranchSupportDelegate} is available.
*/
@ServerSide
public class BranchSupport {
@@ -59,14 +56,13 @@ public class BranchSupport {
this.delegate = delegate;
}

ComponentKey createComponentKey(String projectKey, @Nullable String deprecatedBranch, Map<String, String> characteristics) {
ComponentKey createComponentKey(String projectKey, Map<String, String> characteristics) {
if (characteristics.isEmpty()) {
return new ComponentKeyImpl(projectKey, deprecatedBranch, ComponentKeys.createKey(projectKey, deprecatedBranch));
return new ComponentKeyImpl(projectKey, projectKey);
} else {
checkState(delegate != null, "Current edition does not support branch feature");
}

checkArgument(deprecatedBranch == null, "Deprecated branch feature can't be used at the same time as new branch support");
return delegate.createComponentKey(projectKey, characteristics);
}

@@ -82,16 +78,10 @@ public class BranchSupport {

public abstract String getDbKey();

public abstract Optional<String> getDeprecatedBranchName();

public abstract Optional<Branch> getBranch();

public abstract Optional<String> getPullRequestKey();

public final boolean isDeprecatedBranch() {
return getDeprecatedBranchName().isPresent();
}

public final boolean isMainBranch() {
return !getBranch().isPresent() && !getPullRequestKey().isPresent();
}
@@ -149,12 +139,9 @@ public class BranchSupport {
private static final class ComponentKeyImpl extends ComponentKey {
private final String key;
private final String dbKey;
@CheckForNull
private final String deprecatedBranchName;

public ComponentKeyImpl(String key, @Nullable String deprecatedBranchName, String dbKey) {
public ComponentKeyImpl(String key, String dbKey) {
this.key = key;
this.deprecatedBranchName = deprecatedBranchName;
this.dbKey = dbKey;
}

@@ -168,11 +155,6 @@ public class BranchSupport {
return dbKey;
}

@Override
public Optional<String> getDeprecatedBranchName() {
return Optional.ofNullable(deprecatedBranchName);
}

@Override
public Optional<Branch> getBranch() {
return Optional.empty();
@@ -198,13 +180,12 @@ public class BranchSupport {
}
ComponentKeyImpl that = (ComponentKeyImpl) o;
return Objects.equals(key, that.key) &&
Objects.equals(dbKey, that.dbKey) &&
Objects.equals(deprecatedBranchName, that.deprecatedBranchName);
Objects.equals(dbKey, that.dbKey);
}

@Override
public int hashCode() {
return Objects.hash(key, dbKey, deprecatedBranchName);
return Objects.hash(key, dbKey);
}
}
}

+ 3
- 4
server/sonar-server/src/main/java/org/sonar/server/ce/queue/ReportSubmitter.java View File

@@ -76,11 +76,11 @@ public class ReportSubmitter {
* @throws NotFoundException if the organization with the specified key does not exist
* @throws IllegalArgumentException if the organization with the specified key is not the organization of the specified project (when it already exists in DB)
*/
public CeTask submit(String organizationKey, String projectKey, @Nullable String deprecatedBranch, @Nullable String projectName,
public CeTask submit(String organizationKey, String projectKey, @Nullable String projectName,
Map<String, String> characteristics, InputStream reportInput) {
try (DbSession dbSession = dbClient.openSession(false)) {
OrganizationDto organizationDto = getOrganizationDtoOrFail(dbSession, organizationKey);
BranchSupport.ComponentKey componentKey = branchSupport.createComponentKey(projectKey, deprecatedBranch, characteristics);
BranchSupport.ComponentKey componentKey = branchSupport.createComponentKey(projectKey, characteristics);
Optional<ComponentDto> existingComponent = dbClient.componentDao().selectByKey(dbSession, componentKey.getDbKey());
validateProject(dbSession, existingComponent, projectKey);
ensureOrganizationIsConsistent(existingComponent, organizationDto);
@@ -138,7 +138,7 @@ public class ReportSubmitter {
}

private ComponentDto createComponent(DbSession dbSession, OrganizationDto organization, BranchSupport.ComponentKey componentKey, @Nullable String projectName) {
if (componentKey.isMainBranch() || componentKey.isDeprecatedBranch()) {
if (componentKey.isMainBranch()) {
ComponentDto project = createProject(dbSession, organization, componentKey, projectName);
componentUpdater.commitAndIndex(dbSession, project);
return project;
@@ -175,7 +175,6 @@ public class ReportSubmitter {
.setOrganizationUuid(organization.getUuid())
.setKey(componentKey.getKey())
.setName(defaultIfBlank(projectName, componentKey.getKey()))
.setDeprecatedBranch(componentKey.getDeprecatedBranchName().orElse(null))
.setQualifier(Qualifiers.PROJECT)
.setPrivate(newProjectPrivate)
.build();

+ 1
- 9
server/sonar-server/src/main/java/org/sonar/server/ce/ws/SubmitAction.java View File

@@ -44,7 +44,6 @@ public class SubmitAction implements CeWsAction {

private static final String PARAM_ORGANIZATION_KEY = "organization";
private static final String PARAM_PROJECT_KEY = "projectKey";
private static final String PARAM_PROJECT_BRANCH = "projectBranch";
private static final String PARAM_PROJECT_NAME = "projectName";
private static final String PARAM_REPORT_DATA = "report";
private static final String PARAM_ANALYSIS_CHARACTERISTIC = "characteristic";
@@ -81,12 +80,6 @@ public class SubmitAction implements CeWsAction {
.setDescription("Key of project")
.setExampleValue("my_project");

// deprecated branch (see scanner parameter sonar.branch)
action
.createParam(PARAM_PROJECT_BRANCH)
.setDescription("Optional branch of project")
.setExampleValue("branch-1.x");

action
.createParam(PARAM_PROJECT_NAME)
.setRequired(false)
@@ -112,13 +105,12 @@ public class SubmitAction implements CeWsAction {
.emptyAsNull()
.or(defaultOrganizationProvider.get()::getKey);
String projectKey = wsRequest.mandatoryParam(PARAM_PROJECT_KEY);
String deprecatedBranch = wsRequest.param(PARAM_PROJECT_BRANCH);
String projectName = abbreviate(defaultIfBlank(wsRequest.param(PARAM_PROJECT_NAME), projectKey), MAX_COMPONENT_NAME_LENGTH);

Map<String, String> characteristics = parseTaskCharacteristics(wsRequest);

try (InputStream report = new BufferedInputStream(wsRequest.mandatoryParamAsPart(PARAM_REPORT_DATA).getInputStream())) {
CeTask task = reportSubmitter.submit(organizationKey, projectKey, deprecatedBranch, projectName, characteristics, report);
CeTask task = reportSubmitter.submit(organizationKey, projectKey, projectName, characteristics, report);
Ce.SubmitResponse submitResponse = Ce.SubmitResponse.newBuilder()
.setTaskId(task.getUuid())
.setProjectId(task.getComponent().get().getUuid())

+ 3
- 11
server/sonar-server/src/main/java/org/sonar/server/component/ComponentUpdater.java View File

@@ -27,7 +27,6 @@ import javax.annotation.Nullable;
import org.sonar.api.resources.Qualifiers;
import org.sonar.api.resources.Scopes;
import org.sonar.api.utils.System2;
import org.sonar.core.component.ComponentKeys;
import org.sonar.core.i18n.I18n;
import org.sonar.core.util.Uuids;
import org.sonar.db.DbClient;
@@ -98,10 +97,8 @@ public class ComponentUpdater {
}

private ComponentDto createRootComponent(DbSession session, NewComponent newComponent) {
checkLegacyBranchFormat(newComponent.qualifier(), newComponent.deprecatedBranch());
String keyWithBranch = ComponentKeys.createKey(newComponent.key(), newComponent.deprecatedBranch());
checkRequest(!dbClient.componentDao().selectByKey(session, keyWithBranch).isPresent(),
"Could not create %s, key already exists: %s", getQualifierToDisplay(newComponent.qualifier()), keyWithBranch);
checkRequest(!dbClient.componentDao().selectByKey(session, newComponent.key()).isPresent(),
"Could not create %s, key already exists: %s", getQualifierToDisplay(newComponent.qualifier()), newComponent.key());

String uuid = Uuids.create();
ComponentDto component = new ComponentDto()
@@ -112,7 +109,7 @@ public class ComponentUpdater {
.setModuleUuid(null)
.setModuleUuidPath(ComponentDto.UUID_PATH_SEPARATOR + uuid + ComponentDto.UUID_PATH_SEPARATOR)
.setProjectUuid(uuid)
.setDbKey(keyWithBranch)
.setDbKey(newComponent.key())
.setName(newComponent.name())
.setLongName(newComponent.name())
.setScope(Scopes.PROJECT)
@@ -151,11 +148,6 @@ public class ComponentUpdater {
checkRequest(isValidProjectKey(key), "Malformed key for %s: '%s'. It cannot be empty nor contain whitespaces.", getQualifierToDisplay(qualifier), key);
}

private void checkLegacyBranchFormat(String qualifier, @Nullable String branch) {
checkRequest(branch == null || ComponentKeys.isValidLegacyBranch(branch),
"Malformed branch for %s: %s. Allowed characters are alphanumeric, '-', '_', '.' and '/', with at least one non-digit.", getQualifierToDisplay(qualifier), branch);
}

private String getQualifierToDisplay(String qualifier) {
return i18n.message(Locale.getDefault(), "qualifier." + qualifier, "Project");
}

+ 0
- 15
server/sonar-server/src/main/java/org/sonar/server/component/NewComponent.java View File

@@ -19,8 +19,6 @@
*/
package org.sonar.server.component;

import javax.annotation.CheckForNull;
import javax.annotation.Nullable;
import javax.annotation.concurrent.Immutable;

import static java.util.Objects.requireNonNull;
@@ -33,7 +31,6 @@ import static org.sonar.db.component.ComponentValidator.checkComponentQualifier;
public class NewComponent {
private final String organizationUuid;
private final String key;
private final String branch;
private final String qualifier;
private final String name;
private final boolean isPrivate;
@@ -41,7 +38,6 @@ public class NewComponent {
private NewComponent(NewComponent.Builder builder) {
this.organizationUuid = builder.organizationUuid;
this.key = builder.key;
this.branch = builder.branch;
this.qualifier = builder.qualifier;
this.name = builder.name;
this.isPrivate = builder.isPrivate;
@@ -63,11 +59,6 @@ public class NewComponent {
return name;
}

@CheckForNull
public String deprecatedBranch() {
return branch;
}

public String qualifier() {
return qualifier;
}
@@ -80,7 +71,6 @@ public class NewComponent {
private String organizationUuid;
private String key;
private String qualifier = PROJECT;
private String branch;
private String name;
private boolean isPrivate = false;

@@ -98,11 +88,6 @@ public class NewComponent {
return this;
}

public Builder setDeprecatedBranch(@Nullable String s) {
this.branch = s;
return this;
}

public Builder setQualifier(String qualifier) {
this.qualifier = qualifier;
return this;

+ 0
- 21
server/sonar-server/src/main/java/org/sonar/server/project/ws/CreateAction.java View File

@@ -44,7 +44,6 @@ import static org.sonar.server.project.ws.ProjectsWsSupport.PARAM_ORGANIZATION;
import static org.sonar.server.ws.KeyExamples.KEY_PROJECT_EXAMPLE_001;
import static org.sonar.server.ws.WsUtils.writeProtobuf;
import static org.sonarqube.ws.client.project.ProjectsWsParameters.ACTION_CREATE;
import static org.sonarqube.ws.client.project.ProjectsWsParameters.PARAM_BRANCH;
import static org.sonarqube.ws.client.project.ProjectsWsParameters.PARAM_NAME;
import static org.sonarqube.ws.client.project.ProjectsWsParameters.PARAM_PROJECT;
import static org.sonarqube.ws.client.project.ProjectsWsParameters.PARAM_VISIBILITY;
@@ -87,11 +86,6 @@ public class CreateAction implements ProjectsWsAction {
.setRequired(true)
.setExampleValue("SonarQube");

action.createParam(PARAM_BRANCH)
.setDeprecatedSince("7.8")
.setDescription("SCM Branch of the project. The key of the project will become key:branch, for instance 'SonarQube:branch-5.0'")
.setExampleValue("branch-5.0");

action.createParam(PARAM_VISIBILITY)
.setDescription("Whether the created project should be visible to everyone, or only specific user/groups.<br/>" +
"If no visibility is specified, the default project visibility of the organization will be used.")
@@ -120,7 +114,6 @@ public class CreateAction implements ProjectsWsAction {
.setOrganizationUuid(organization.getUuid())
.setKey(request.getProjectKey())
.setName(request.getName())
.setDeprecatedBranch(request.getBranch())
.setPrivate(changeToPrivate)
.setQualifier(PROJECT)
.build(),
@@ -134,7 +127,6 @@ public class CreateAction implements ProjectsWsAction {
.setOrganization(request.param(PARAM_ORGANIZATION))
.setProjectKey(request.mandatoryParam(PARAM_PROJECT))
.setName(abbreviate(request.mandatoryParam(PARAM_NAME), MAX_COMPONENT_NAME_LENGTH))
.setBranch(request.param(PARAM_BRANCH))
.setVisibility(request.param(PARAM_VISIBILITY))
.build();
}
@@ -154,7 +146,6 @@ public class CreateAction implements ProjectsWsAction {
private final String organization;
private final String projectKey;
private final String name;
private final String branch;
@CheckForNull
private final String visibility;

@@ -162,7 +153,6 @@ public class CreateAction implements ProjectsWsAction {
this.organization = builder.organization;
this.projectKey = builder.projectKey;
this.name = builder.name;
this.branch = builder.branch;
this.visibility = builder.visibility;
}

@@ -181,11 +171,6 @@ public class CreateAction implements ProjectsWsAction {
return name;
}

@CheckForNull
public String getBranch() {
return branch;
}

@CheckForNull
public String getVisibility() {
return visibility;
@@ -200,7 +185,6 @@ public class CreateAction implements ProjectsWsAction {
private String organization;
private String projectKey;
private String name;
private String branch;
@CheckForNull
private String visibility;

@@ -222,11 +206,6 @@ public class CreateAction implements ProjectsWsAction {
return this;
}

public Builder setBranch(@Nullable String branch) {
this.branch = branch;
return this;
}

public Builder setVisibility(@Nullable String visibility) {
this.visibility = visibility;
return this;

+ 6
- 28
server/sonar-server/src/test/java/org/sonar/server/ce/queue/BranchReportSubmitterTest.java View File

@@ -39,7 +39,6 @@ import org.sonar.api.utils.System2;
import org.sonar.ce.queue.CeQueue;
import org.sonar.ce.queue.CeQueueImpl;
import org.sonar.ce.queue.CeTaskSubmit;
import org.sonar.core.component.ComponentKeys;
import org.sonar.db.DbSession;
import org.sonar.db.DbTester;
import org.sonar.db.ce.CeTaskTypes;
@@ -109,7 +108,7 @@ public class BranchReportSubmitterTest {
mockSuccessfulPrepareSubmitCall();
InputStream reportInput = IOUtils.toInputStream("{binary}", StandardCharsets.UTF_8);

underTest.submit(organization.getKey(), project.getDbKey(), null, project.name(), emptyMap(), reportInput);
underTest.submit(organization.getKey(), project.getDbKey(), project.name(), emptyMap(), reportInput);

verifyZeroInteractions(branchSupportDelegate);
}
@@ -128,7 +127,7 @@ public class BranchReportSubmitterTest {
InputStream reportInput = IOUtils.toInputStream("{binary}", StandardCharsets.UTF_8);
String taskUuid = mockSuccessfulPrepareSubmitCall();

underTest.submit(organization.getKey(), project.getDbKey(), null, project.name(), randomCharacteristics, reportInput);
underTest.submit(organization.getKey(), project.getDbKey(), project.name(), randomCharacteristics, reportInput);

verifyZeroInteractions(permissionTemplateService);
verifyZeroInteractions(favoriteUpdater);
@@ -139,27 +138,6 @@ public class BranchReportSubmitterTest {
verifyQueueSubmit(project, branch, user, randomCharacteristics, taskUuid);
}

@Test
public void submit_a_report_on_existing_deprecated_branch() {
OrganizationDto organization = db.organizations().insert();
String projectKey = randomAlphabetic(10);
String deprecatedBranchName = randomAlphabetic(11);
ComponentDto deprecatedBranch = db.components().insertMainBranch(organization, cpt -> cpt.setDbKey(ComponentKeys.createKey(projectKey, deprecatedBranchName)));
UserDto user = db.users().insertUser();
userSession.logIn(user).addProjectPermission(SCAN_EXECUTION, deprecatedBranch);
Map<String, String> noCharacteristics = emptyMap();
InputStream reportInput = IOUtils.toInputStream("{binary}", StandardCharsets.UTF_8);
String taskUuid = mockSuccessfulPrepareSubmitCall();

underTest.submit(organization.getKey(), deprecatedBranch.getDbKey(), null, deprecatedBranch.name(), noCharacteristics, reportInput);

verifyZeroInteractions(permissionTemplateService);
verifyZeroInteractions(favoriteUpdater);
verify(branchSupport, times(0)).createBranchComponent(any(), any(), any(), any(), any());
verifyZeroInteractions(branchSupportDelegate);
verifyQueueSubmit(deprecatedBranch, deprecatedBranch, user, noCharacteristics, taskUuid);
}

@Test
public void submit_a_report_on_missing_branch_but_existing_project() {
OrganizationDto organization = db.organizations().insert();
@@ -177,7 +155,7 @@ public class BranchReportSubmitterTest {
InputStream reportInput = IOUtils.toInputStream("{binary}", StandardCharsets.UTF_8);
String taskUuid = mockSuccessfulPrepareSubmitCall();

underTest.submit(organization.getKey(), existingProject.getDbKey(), null, existingProject.name(), randomCharacteristics, reportInput);
underTest.submit(organization.getKey(), existingProject.getDbKey(), existingProject.name(), randomCharacteristics, reportInput);

verifyZeroInteractions(permissionTemplateService);
verifyZeroInteractions(favoriteUpdater);
@@ -212,7 +190,7 @@ public class BranchReportSubmitterTest {
String taskUuid = mockSuccessfulPrepareSubmitCall();
InputStream reportInput = IOUtils.toInputStream("{binary}", StandardCharsets.UTF_8);

underTest.submit(organization.getKey(), nonExistingProject.getDbKey(), null, nonExistingProject.name(), randomCharacteristics, reportInput);
underTest.submit(organization.getKey(), nonExistingProject.getDbKey(), nonExistingProject.name(), randomCharacteristics, reportInput);

BranchDto exitingProjectMainBranch = db.getDbClient().branchDao().selectByUuid(db.getSession(), nonExistingProject.uuid()).get();
verify(branchSupport).createBranchComponent(any(DbSession.class), same(componentKey), eq(organization), eq(nonExistingProject), eq(exitingProjectMainBranch));
@@ -235,7 +213,7 @@ public class BranchReportSubmitterTest {
when(branchSupportDelegate.createComponentKey(any(), any())).thenThrow(expected);

try {
underTest.submit(organization.getKey(), project.getDbKey(), null, project.name(), randomCharacteristics, reportInput);
underTest.submit(organization.getKey(), project.getDbKey(), project.name(), randomCharacteristics, reportInput);
fail("exception should have been thrown");
} catch (Exception e) {
assertThat(e).isSameAs(expected);
@@ -275,7 +253,7 @@ public class BranchReportSubmitterTest {
expectedException.expect(ForbiddenException.class);
expectedException.expectMessage("Insufficient privileges");

underTest.submit(organization.getKey(), nonExistingProject.getDbKey(), null, nonExistingProject.name(), randomCharacteristics, reportInput);
underTest.submit(organization.getKey(), nonExistingProject.getDbKey(), nonExistingProject.name(), randomCharacteristics, reportInput);
}

private static ComponentDto createButDoNotInsertBranch(ComponentDto project) {

+ 4
- 47
server/sonar-server/src/test/java/org/sonar/server/ce/queue/BranchSupportTest.java View File

@@ -21,7 +21,6 @@ package org.sonar.server.ce.queue;

import com.tngtech.java.junit.dataprovider.DataProvider;
import com.tngtech.java.junit.dataprovider.DataProviderRunner;
import com.tngtech.java.junit.dataprovider.UseDataProvider;
import java.util.Collections;
import java.util.Map;
import java.util.Random;
@@ -58,59 +57,17 @@ public class BranchSupportTest {
public void createComponentKey_of_main_branch() {
String projectKey = randomAlphanumeric(12);

ComponentKey componentKey = underTestNoBranch.createComponentKey(projectKey, null, NO_CHARACTERISTICS);
ComponentKey componentKey = underTestNoBranch.createComponentKey(projectKey, NO_CHARACTERISTICS);

assertThat(componentKey)
.isEqualTo(underTestWithBranch.createComponentKey(projectKey, null, NO_CHARACTERISTICS));
.isEqualTo(underTestWithBranch.createComponentKey(projectKey, NO_CHARACTERISTICS));
assertThat(componentKey.getKey()).isEqualTo(projectKey);
assertThat(componentKey.getDbKey()).isEqualTo(projectKey);
assertThat(componentKey.isDeprecatedBranch()).isFalse();
assertThat(componentKey.getMainBranchComponentKey()).isSameAs(componentKey);
assertThat(componentKey.getBranch()).isEmpty();
assertThat(componentKey.getPullRequestKey()).isEmpty();
}

@Test
public void createComponentKey_of_deprecated_branch() {
String projectKey = randomAlphanumeric(12);
String deprecatedBranchName = randomAlphanumeric(12);

ComponentKey componentKey = underTestNoBranch.createComponentKey(projectKey, deprecatedBranchName, NO_CHARACTERISTICS);

assertThat(componentKey)
.isEqualTo(underTestWithBranch.createComponentKey(projectKey, deprecatedBranchName, NO_CHARACTERISTICS));
assertThat(componentKey.getKey()).isEqualTo(projectKey);
assertThat(componentKey.getDbKey()).isEqualTo(projectKey + ":" + deprecatedBranchName);
assertThat(componentKey.isDeprecatedBranch()).isTrue();
assertThat(componentKey.getMainBranchComponentKey()).isSameAs(componentKey);
assertThat(componentKey.getBranch()).isEmpty();
assertThat(componentKey.getPullRequestKey()).isEmpty();
}

@Test
@UseDataProvider("nullOrNonEmpty")
public void createComponentKey_with_ISE_if_characteristics_is_not_empty_and_delegate_is_null(String deprecatedBranchName) {
String projectKey = randomAlphanumeric(12);
Map<String, String> nonEmptyMap = newRandomNonEmptyMap();

expectedException.expect(IllegalStateException.class);
expectedException.expectMessage("Current edition does not support branch feature");
underTestNoBranch.createComponentKey(projectKey, deprecatedBranchName, nonEmptyMap);
}

@Test
public void createComponentKey_fails_with_IAE_if_characteristics_is_not_empty_and_deprecatedBranchName_is_non_null() {
String projectKey = randomAlphanumeric(12);
String deprecatedBranchName = randomAlphanumeric(13);
Map<String, String> nonEmptyMap = newRandomNonEmptyMap();

expectedException.expect(IllegalArgumentException.class);
expectedException.expectMessage("Deprecated branch feature can't be used at the same time as new branch support");
underTestWithBranch.createComponentKey(projectKey, deprecatedBranchName, nonEmptyMap);
}

@Test
public void createComponentKey_delegates_to_delegate_if_characteristics_is_not_empty() {
String projectKey = randomAlphanumeric(12);
@@ -118,7 +75,7 @@ public class BranchSupportTest {
ComponentKey expected = mock(ComponentKey.class);
when(branchSupportDelegate.createComponentKey(projectKey, nonEmptyMap)).thenReturn(expected);

ComponentKey componentKey = underTestWithBranch.createComponentKey(projectKey, null, nonEmptyMap);
ComponentKey componentKey = underTestWithBranch.createComponentKey(projectKey, nonEmptyMap);

assertThat(componentKey).isSameAs(expected);
}
@@ -133,7 +90,7 @@ public class BranchSupportTest {

expectedException.expect(IllegalStateException.class);
expectedException.expectMessage("Current edition does not support branch feature");
underTestNoBranch.createBranchComponent(dbSession, componentKey, organization, mainComponentDto, mainComponentBranchDto);
}


+ 16
- 32
server/sonar-server/src/test/java/org/sonar/server/ce/queue/ReportSubmitterTest.java View File

@@ -34,7 +34,6 @@ import org.sonar.ce.queue.CeQueue;
import org.sonar.ce.queue.CeQueueImpl;
import org.sonar.ce.queue.CeTaskSubmit;
import org.sonar.core.i18n.I18n;
import org.sonar.core.permission.GlobalPermissions;
import org.sonar.db.DbSession;
import org.sonar.db.DbTester;
import org.sonar.db.ce.CeTaskTypes;
@@ -120,7 +119,7 @@ public class ReportSubmitterTest {
expectedException.expect(IllegalStateException.class);
expectedException.expectMessage("Current edition does not support branch feature");

underTest.submit(defaultOrganizationKey, PROJECT_KEY, null, PROJECT_NAME, nonEmptyCharacteristics, reportInput);
underTest.submit(defaultOrganizationKey, PROJECT_KEY, PROJECT_NAME, nonEmptyCharacteristics, reportInput);
}

@Test
@@ -132,7 +131,7 @@ public class ReportSubmitterTest {
when(permissionTemplateService.wouldUserHaveScanPermissionWithDefaultTemplate(any(), eq(defaultOrganizationUuid), any(), eq(PROJECT_KEY)))
.thenReturn(true);

underTest.submit(defaultOrganizationKey, PROJECT_KEY, null, PROJECT_NAME, emptyMap(), IOUtils.toInputStream("{binary}", UTF_8));
underTest.submit(defaultOrganizationKey, PROJECT_KEY, PROJECT_NAME, emptyMap(), IOUtils.toInputStream("{binary}", UTF_8));

verifyReportIsPersisted(TASK_UUID);
}
@@ -144,7 +143,7 @@ public class ReportSubmitterTest {
userSession.logIn(user).addProjectPermission(SCAN_EXECUTION, project);
mockSuccessfulPrepareSubmitCall();

underTest.submit(defaultOrganizationKey, project.getDbKey(), null, project.name(), emptyMap(), IOUtils.toInputStream("{binary}", StandardCharsets.UTF_8));
underTest.submit(defaultOrganizationKey, project.getDbKey(), project.name(), emptyMap(), IOUtils.toInputStream("{binary}", StandardCharsets.UTF_8));

verifyReportIsPersisted(TASK_UUID);
verifyZeroInteractions(permissionTemplateService);
@@ -164,7 +163,7 @@ public class ReportSubmitterTest {
when(permissionTemplateService.wouldUserHaveScanPermissionWithDefaultTemplate(any(DbSession.class), eq(organization.getUuid()), any(), eq(PROJECT_KEY))).thenReturn(true);
when(permissionTemplateService.hasDefaultTemplateWithPermissionOnProjectCreator(any(DbSession.class), any(ComponentDto.class))).thenReturn(true);

underTest.submit(organization.getKey(), PROJECT_KEY, null, PROJECT_NAME, emptyMap(), IOUtils.toInputStream("{binary}"));
underTest.submit(organization.getKey(), PROJECT_KEY, PROJECT_NAME, emptyMap(), IOUtils.toInputStream("{binary}"));

ComponentDto createdProject = db.getDbClient().componentDao().selectByKey(db.getSession(), PROJECT_KEY).get();
verifyReportIsPersisted(TASK_UUID);
@@ -185,7 +184,7 @@ public class ReportSubmitterTest {
when(permissionTemplateService.wouldUserHaveScanPermissionWithDefaultTemplate(any(DbSession.class), eq(organization.getUuid()), any(), eq(PROJECT_KEY))).thenReturn(true);
when(permissionTemplateService.hasDefaultTemplateWithPermissionOnProjectCreator(any(DbSession.class), any(ComponentDto.class))).thenReturn(true);

underTest.submit(organization.getKey(), PROJECT_KEY, null, PROJECT_NAME, emptyMap(), IOUtils.toInputStream("{binary}"));
underTest.submit(organization.getKey(), PROJECT_KEY, PROJECT_NAME, emptyMap(), IOUtils.toInputStream("{binary}"));

ComponentDto createdProject = db.getDbClient().componentDao().selectByKey(db.getSession(), PROJECT_KEY).get();
assertThat(db.favorites().hasFavorite(createdProject, user.getId())).isTrue();
@@ -201,7 +200,7 @@ public class ReportSubmitterTest {
when(permissionTemplateService.hasDefaultTemplateWithPermissionOnProjectCreator(any(DbSession.class), any(ComponentDto.class))).thenReturn(false);
mockSuccessfulPrepareSubmitCall();

underTest.submit(defaultOrganizationKey, PROJECT_KEY, null, PROJECT_NAME, emptyMap(), IOUtils.toInputStream("{binary}"));
underTest.submit(defaultOrganizationKey, PROJECT_KEY, PROJECT_NAME, emptyMap(), IOUtils.toInputStream("{binary}"));

ComponentDto createdProject = db.getDbClient().componentDao().selectByKey(db.getSession(), PROJECT_KEY).get();
assertThat(db.favorites().hasNoFavorite(createdProject)).isTrue();
@@ -220,7 +219,7 @@ public class ReportSubmitterTest {
when(permissionTemplateService.wouldUserHaveScanPermissionWithDefaultTemplate(any(DbSession.class), eq(organization.getUuid()), any(), eq(PROJECT_KEY))).thenReturn(true);
when(permissionTemplateService.hasDefaultTemplateWithPermissionOnProjectCreator(any(DbSession.class), any(ComponentDto.class))).thenReturn(true);

underTest.submit(organization.getKey(), PROJECT_KEY, null, PROJECT_NAME, emptyMap(), IOUtils.toInputStream("{binary}"));
underTest.submit(organization.getKey(), PROJECT_KEY, PROJECT_NAME, emptyMap(), IOUtils.toInputStream("{binary}"));

ComponentDto createdProject = db.getDbClient().componentDao().selectByKey(db.getSession(), PROJECT_KEY).get();
assertThat(db.favorites().hasNoFavorite(createdProject)).isTrue();
@@ -235,7 +234,7 @@ public class ReportSubmitterTest {
when(permissionTemplateService.wouldUserHaveScanPermissionWithDefaultTemplate(any(DbSession.class), eq(defaultOrganizationUuid), any(), eq(PROJECT_KEY)))
.thenReturn(true);

underTest.submit(defaultOrganizationKey, PROJECT_KEY, null, PROJECT_NAME, emptyMap(), IOUtils.toInputStream("{binary}"));
underTest.submit(defaultOrganizationKey, PROJECT_KEY, PROJECT_NAME, emptyMap(), IOUtils.toInputStream("{binary}"));

verify(queue).submit(any(CeTaskSubmit.class));
}
@@ -247,7 +246,7 @@ public class ReportSubmitterTest {
userSession.addPermission(SCAN, org);
mockSuccessfulPrepareSubmitCall();

underTest.submit(org.getKey(), project.getDbKey(), null, project.name(), emptyMap(), IOUtils.toInputStream("{binary}"));
underTest.submit(org.getKey(), project.getDbKey(), project.name(), emptyMap(), IOUtils.toInputStream("{binary}"));

verify(queue).submit(any(CeTaskSubmit.class));
}
@@ -258,32 +257,17 @@ public class ReportSubmitterTest {
userSession.addProjectPermission(SCAN_EXECUTION, project);
mockSuccessfulPrepareSubmitCall();

underTest.submit(defaultOrganizationKey, project.getDbKey(), null, project.name(), emptyMap(), IOUtils.toInputStream("{binary}"));
underTest.submit(defaultOrganizationKey, project.getDbKey(), project.name(), emptyMap(), IOUtils.toInputStream("{binary}"));

verify(queue).submit(any(CeTaskSubmit.class));
}

/**
* SONAR-8757
*/
@Test
public void project_branch_must_not_benefit_from_the_scan_permission_on_main_project() {
String branchName = "branchFoo";
ComponentDto mainProject = db.components().insertPrivateProject();
userSession.addProjectPermission(GlobalPermissions.SCAN_EXECUTION, mainProject);
// user does not have the "scan" permission on the branch, so it can't scan it
ComponentDto branchProject = db.components().insertPrivateProject(p -> p.setDbKey(mainProject.getDbKey() + ":" + branchName));

expectedException.expect(ForbiddenException.class);
underTest.submit(defaultOrganizationKey, mainProject.getDbKey(), branchName, PROJECT_NAME, emptyMap(), IOUtils.toInputStream("{binary}"));
}

@Test
public void fail_with_NotFoundException_if_organization_with_specified_key_does_not_exist() {
expectedException.expect(NotFoundException.class);
expectedException.expectMessage("Organization with key 'fop' does not exist");

underTest.submit("fop", PROJECT_KEY, null, null, emptyMap(), null /* method will fail before parameter is used */);
underTest.submit("fop", PROJECT_KEY, null, emptyMap(), null /* method will fail before parameter is used */);
}

@Test
@@ -293,7 +277,7 @@ public class ReportSubmitterTest {
ComponentDto project = db.components().insertPrivateProject(organization);
mockSuccessfulPrepareSubmitCall();

underTest.submit(organization.getKey(), project.getDbKey(), null, project.name(), emptyMap(), IOUtils.toInputStream("{binary}"));
underTest.submit(organization.getKey(), project.getDbKey(), project.name(), emptyMap(), IOUtils.toInputStream("{binary}"));
}

@Test
@@ -305,7 +289,7 @@ public class ReportSubmitterTest {
expectedException.expect(BadRequestException.class);
expectedException.expectMessage(format("Component '%s' is not a project", component.getKey()));

underTest.submit(defaultOrganizationKey, component.getDbKey(), null, component.name(), emptyMap(), IOUtils.toInputStream("{binary}"));
underTest.submit(defaultOrganizationKey, component.getDbKey(), component.name(), emptyMap(), IOUtils.toInputStream("{binary}"));
}

@Test
@@ -316,7 +300,7 @@ public class ReportSubmitterTest {
mockSuccessfulPrepareSubmitCall();

try {
underTest.submit(defaultOrganizationKey, module.getDbKey(), null, module.name(), emptyMap(), IOUtils.toInputStream("{binary}"));
underTest.submit(defaultOrganizationKey, module.getDbKey(), module.name(), emptyMap(), IOUtils.toInputStream("{binary}"));
fail();
} catch (BadRequestException e) {
assertThat(e.errors()).contains(
@@ -330,7 +314,7 @@ public class ReportSubmitterTest {
public void fail_with_forbidden_exception_when_no_scan_permission() {
expectedException.expect(ForbiddenException.class);

underTest.submit(defaultOrganizationKey, PROJECT_KEY, null, PROJECT_NAME, emptyMap(), IOUtils.toInputStream("{binary}"));
underTest.submit(defaultOrganizationKey, PROJECT_KEY, PROJECT_NAME, emptyMap(), IOUtils.toInputStream("{binary}"));
}

@Test
@@ -340,7 +324,7 @@ public class ReportSubmitterTest {
mockSuccessfulPrepareSubmitCall();

expectedException.expect(ForbiddenException.class);
underTest.submit(defaultOrganizationKey, PROJECT_KEY, null, PROJECT_NAME, emptyMap(), IOUtils.toInputStream("{binary}"));
underTest.submit(defaultOrganizationKey, PROJECT_KEY, PROJECT_NAME, emptyMap(), IOUtils.toInputStream("{binary}"));
}

private void verifyReportIsPersisted(String taskUuid) {

+ 9
- 20
server/sonar-server/src/test/java/org/sonar/server/ce/ws/SubmitActionTest.java View File

@@ -44,7 +44,6 @@ import static org.assertj.core.api.Assertions.entry;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.ArgumentMatchers.anyMap;
import static org.mockito.ArgumentMatchers.eq;
import static org.mockito.ArgumentMatchers.isNull;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
@@ -78,8 +77,7 @@ public class SubmitActionTest {

@Test
public void submit_task_to_the_queue_and_ask_for_immediate_processing() {
when(reportSubmitter.submit(eq(organizationKey), eq("my_project"), isNull(), eq("My Project"),
anyMap(), any())).thenReturn(A_CE_TASK);
when(reportSubmitter.submit(eq(organizationKey), eq("my_project"), eq("My Project"), anyMap(), any())).thenReturn(A_CE_TASK);

Ce.SubmitResponse submitResponse = tester.newRequest()
.setParam("projectKey", "my_project")
@@ -88,8 +86,7 @@ public class SubmitActionTest {
.setMethod("POST")
.executeProtobuf(Ce.SubmitResponse.class);

verify(reportSubmitter).submit(eq(organizationKey), eq("my_project"), isNull(), eq("My Project"),
anyMap(), any());
verify(reportSubmitter).submit(eq(organizationKey), eq("my_project"), eq("My Project"), anyMap(), any());

assertThat(submitResponse.getTaskId()).isEqualTo("TASK_1");
assertThat(submitResponse.getProjectId()).isEqualTo(PROJECT_UUID);
@@ -97,8 +94,7 @@ public class SubmitActionTest {

@Test
public void submit_task_with_characteristics() {
when(reportSubmitter.submit(eq(organizationKey), eq("my_project"), isNull(), eq("My Project"),
anyMap(), any())).thenReturn(A_CE_TASK);
when(reportSubmitter.submit(eq(organizationKey), eq("my_project"), eq("My Project"), anyMap(), any())).thenReturn(A_CE_TASK);

String[] characteristics = {"branch=foo", "pullRequest=123", "unsupported=bar"};
Ce.SubmitResponse submitResponse = tester.newRequest()
@@ -110,8 +106,7 @@ public class SubmitActionTest {
.executeProtobuf(Ce.SubmitResponse.class);

assertThat(submitResponse.getTaskId()).isEqualTo("TASK_1");
verify(reportSubmitter).submit(eq(organizationKey), eq("my_project"), isNull(), eq("My Project"),
map.capture(), any());
verify(reportSubmitter).submit(eq(organizationKey), eq("my_project"), eq("My Project"), map.capture(), any());

// unsupported characteristics are ignored
assertThat(map.getValue()).containsExactly(entry("branch", "foo"), entry("pullRequest", "123"));
@@ -121,8 +116,7 @@ public class SubmitActionTest {
public void abbreviate_long_name() {
String longName = Strings.repeat("a", 1_000);
String expectedName = Strings.repeat("a", 497) + "...";
when(reportSubmitter.submit(eq(organizationKey), eq("my_project"), isNull(), eq(expectedName),
anyMap(), any())).thenReturn(A_CE_TASK);
when(reportSubmitter.submit(eq(organizationKey), eq("my_project"), eq(expectedName), anyMap(), any())).thenReturn(A_CE_TASK);

Ce.SubmitResponse submitResponse = tester.newRequest()
.setParam("projectKey", "my_project")
@@ -131,8 +125,7 @@ public class SubmitActionTest {
.setMethod("POST")
.executeProtobuf(Ce.SubmitResponse.class);

verify(reportSubmitter).submit(eq(organizationKey), eq("my_project"), isNull(), eq(expectedName),
anyMap(), any());
verify(reportSubmitter).submit(eq(organizationKey), eq("my_project"), eq(expectedName), anyMap(), any());

assertThat(submitResponse.getTaskId()).isEqualTo("TASK_1");
assertThat(submitResponse.getProjectId()).isEqualTo(PROJECT_UUID);
@@ -140,8 +133,7 @@ public class SubmitActionTest {

@Test
public void test_example_json_response() {
when(reportSubmitter.submit(eq(organizationKey), eq("my_project"), isNull(), eq("My Project"),
anyMap(), any())).thenReturn(A_CE_TASK);
when(reportSubmitter.submit(eq(organizationKey), eq("my_project"), eq("My Project"), anyMap(), any())).thenReturn(A_CE_TASK);

TestResponse wsResponse = tester.newRequest()
.setParam("projectKey", "my_project")
@@ -159,8 +151,7 @@ public class SubmitActionTest {
*/
@Test
public void project_name_is_optional() {
when(reportSubmitter.submit(eq(organizationKey), eq("my_project"), isNull(), eq("my_project"),
anyMap(), any())).thenReturn(A_CE_TASK);
when(reportSubmitter.submit(eq(organizationKey), eq("my_project"), eq("my_project"), anyMap(), any())).thenReturn(A_CE_TASK);

tester.newRequest()
.setParam("projectKey", "my_project")
@@ -169,8 +160,6 @@ public class SubmitActionTest {
.setMethod("POST")
.execute();

verify(reportSubmitter).submit(eq(organizationKey), eq("my_project"), isNull(), eq("my_project"),
anyMap(), any());

verify(reportSubmitter).submit(eq(organizationKey), eq("my_project"), eq("my_project"), anyMap(), any());
}
}

+ 0
- 29
server/sonar-server/src/test/java/org/sonar/server/component/ComponentUpdaterTest.java View File

@@ -136,20 +136,6 @@ public class ComponentUpdaterTest {
assertThat(loaded.isPrivate()).isEqualTo(project.isPrivate());
}

@Test
public void create_project_with_deprecated_branch() {
ComponentDto project = underTest.create(db.getSession(),
NewComponent.newComponentBuilder()
.setKey(DEFAULT_PROJECT_KEY)
.setName(DEFAULT_PROJECT_NAME)
.setDeprecatedBranch("origin/master")
.setOrganizationUuid(db.getDefaultOrganization().getUuid())
.build(),
null);

assertThat(project.getDbKey()).isEqualTo("project-key:origin/master");
}

@Test
public void create_view() {
NewComponent view = NewComponent.newComponentBuilder()
@@ -328,19 +314,4 @@ public class ComponentUpdaterTest {
.build(),
null);
}

@Test
public void fail_to_create_new_component_on_invalid_branch() {
expectedException.expect(BadRequestException.class);
expectedException.expectMessage("Malformed branch for Project: origin?branch. Allowed characters are alphanumeric, '-', '_', '.' and '/', with at least one non-digit.");

underTest.create(db.getSession(),
NewComponent.newComponentBuilder()
.setKey(DEFAULT_PROJECT_KEY)
.setName(DEFAULT_PROJECT_NAME)
.setDeprecatedBranch("origin?branch")
.setOrganizationUuid(db.getDefaultOrganization().getUuid())
.build(),
null);
}
}

+ 1
- 22
server/sonar-server/src/test/java/org/sonar/server/project/ws/CreateActionTest.java View File

@@ -62,7 +62,6 @@ import static org.sonar.server.project.Visibility.PRIVATE;
import static org.sonar.server.project.ws.ProjectsWsSupport.PARAM_ORGANIZATION;
import static org.sonar.test.JsonAssert.assertJson;
import static org.sonarqube.ws.client.WsRequest.Method.POST;
import static org.sonarqube.ws.client.project.ProjectsWsParameters.PARAM_BRANCH;
import static org.sonarqube.ws.client.project.ProjectsWsParameters.PARAM_NAME;
import static org.sonarqube.ws.client.project.ProjectsWsParameters.PARAM_PROJECT;
import static org.sonarqube.ws.client.project.ProjectsWsParameters.PARAM_VISIBILITY;
@@ -111,21 +110,6 @@ public class CreateActionTest {
.containsOnly(DEFAULT_PROJECT_KEY, DEFAULT_PROJECT_NAME, "TRK", "PRJ", false, null);
}

@Test
public void create_project_with_branch() {
userSession.addPermission(PROVISION_PROJECTS, db.getDefaultOrganization());

CreateWsResponse response = call(CreateRequest.builder()
.setProjectKey(DEFAULT_PROJECT_KEY)
.setName(DEFAULT_PROJECT_NAME)
.setBranch("origin/master")
.build());

assertThat(response.getProject())
.extracting(Project::getKey, Project::getName, Project::getQualifier, Project::getVisibility)
.containsOnly(DEFAULT_PROJECT_KEY + ":origin/master", DEFAULT_PROJECT_NAME, "TRK", "public");
}

@Test
public void apply_project_visibility_public() {
OrganizationDto organization = db.organizations().insert();
@@ -352,8 +336,7 @@ public class CreateActionTest {
PARAM_VISIBILITY,
PARAM_ORGANIZATION,
PARAM_NAME,
PARAM_PROJECT,
PARAM_BRANCH);
PARAM_PROJECT);

WebService.Param organization = definition.param(PARAM_ORGANIZATION);
assertThat(organization.description()).isEqualTo("The key of the organization");
@@ -375,9 +358,6 @@ public class CreateActionTest {
WebService.Param name = definition.param(PARAM_NAME);
assertThat(name.isRequired()).isTrue();
assertThat(name.description()).isEqualTo("Name of the project. If name is longer than 500, it is abbreviated.");

WebService.Param branch = definition.param(PARAM_BRANCH);
assertThat(branch.deprecatedSince()).isNotNull();
}

private CreateWsResponse call(CreateRequest request) {
@@ -386,7 +366,6 @@ public class CreateActionTest {
ofNullable(request.getOrganization()).ifPresent(org -> httpRequest.setParam("organization", org));
ofNullable(request.getProjectKey()).ifPresent(key -> httpRequest.setParam("project", key));
ofNullable(request.getName()).ifPresent(name -> httpRequest.setParam("name", name));
ofNullable(request.getBranch()).ifPresent(branch -> httpRequest.setParam("branch", branch));
return httpRequest.executeProtobuf(CreateWsResponse.class);
}


+ 0
- 19
sonar-core/src/main/java/org/sonar/core/component/ComponentKeys.java View File

@@ -71,25 +71,6 @@ public final class ComponentKeys {
checkArgument(isValidProjectKey(keyCandidate), "Malformed key for '%s'. %s", keyCandidate, "Project key cannot be empty nor contain whitespaces.");
}

/**
* <p>Test if given parameter is valid for a branch. Valid format is:</p>
* <ul>
* <li>Allowed characters:
* <ul>
* <li>Uppercase ASCII letters A-Z</li>
* <li>Lowercase ASCII letters a-z</li>
* <li>ASCII digits 0-9</li>
* <li>Punctuation signs dash '-', underscore '_', period '.', and '/'</li>
* </ul>
* </li>
* </ul>
*
* @return <code>true</code> if <code>branchCandidate</code> can be used for a project
*/
public static boolean isValidLegacyBranch(String branchCandidate) {
return branchCandidate.matches(VALID_BRANCH_REGEXP);
}

/**
* Return the project key with potential branch
*/

+ 0
- 12
sonar-core/src/test/java/org/sonar/core/component/ComponentKeysTest.java View File

@@ -50,18 +50,6 @@ public class ComponentKeysTest {
assertThat(ComponentKeys.isValidProjectKey("ab ")).isFalse();
}

@Test
public void isValidBranchKey() {
assertThat(ComponentKeys.isValidLegacyBranch("")).isTrue();
assertThat(ComponentKeys.isValidLegacyBranch("abc")).isTrue();
assertThat(ComponentKeys.isValidLegacyBranch("0123")).isTrue();
assertThat(ComponentKeys.isValidLegacyBranch("ab 12")).isFalse();
assertThat(ComponentKeys.isValidLegacyBranch("ab_12")).isTrue();
assertThat(ComponentKeys.isValidLegacyBranch("ab/12")).isTrue();
assertThat(ComponentKeys.isValidLegacyBranch("ab\\12")).isFalse();
assertThat(ComponentKeys.isValidLegacyBranch("ab\n")).isFalse();
}

@Test
public void checkProjectKey_with_correct_keys() {
ComponentKeys.checkProjectKey("abc");

+ 0
- 16
sonar-plugin-api-impl/src/main/java/org/sonar/api/batch/fs/internal/AbstractProjectOrModule.java View File

@@ -45,8 +45,6 @@ public abstract class AbstractProjectOrModule extends DefaultInputComponent {
private final String name;
private final String originalName;
private final String description;
private final String keyWithBranch;
private final String branch;
private final Map<String, String> properties;

private final String key;
@@ -60,8 +58,6 @@ public abstract class AbstractProjectOrModule extends DefaultInputComponent {
this.name = definition.getName();
this.originalName = definition.getOriginalName();
this.description = definition.getDescription();
this.keyWithBranch = definition.getKeyWithBranch();
this.branch = definition.getBranch();
this.properties = Collections.unmodifiableMap(new HashMap<>(definition.properties()));

this.definition = definition;
@@ -104,9 +100,6 @@ public abstract class AbstractProjectOrModule extends DefaultInputComponent {
return workingDir;
}

/**
* Module key without branch
*/
@Override
public String key() {
return key;
@@ -129,15 +122,6 @@ public abstract class AbstractProjectOrModule extends DefaultInputComponent {
return workDir;
}

public String getKeyWithBranch() {
return keyWithBranch;
}

@CheckForNull
public String getBranch() {
return branch;
}

public Map<String, String> properties() {
return properties;
}

+ 0
- 4
sonar-plugin-api-impl/src/test/java/org/sonar/api/batch/fs/internal/fs/DefaultInputModuleTest.java View File

@@ -57,9 +57,7 @@ public class DefaultInputModuleTest {

assertThat(module.key()).isEqualTo("moduleKey");
assertThat(module.definition()).isEqualTo(def);
assertThat(module.getBranch()).isNull();
assertThat(module.getBaseDir()).isEqualTo(baseDir.toPath());
assertThat(module.getKeyWithBranch()).isEqualTo("moduleKey");
assertThat(module.getWorkDir()).isEqualTo(workDir.toPath());
assertThat(module.getEncoding()).isEqualTo(Charset.defaultCharset());
assertThat(module.getSourceDirsOrFiles().get()).containsExactlyInAnyOrder(src);
@@ -85,9 +83,7 @@ public class DefaultInputModuleTest {

assertThat(module.key()).isEqualTo("moduleKey");
assertThat(module.definition()).isEqualTo(def);
assertThat(module.getBranch()).isNull();
assertThat(module.getBaseDir()).isEqualTo(baseDir.toPath());
assertThat(module.getKeyWithBranch()).isEqualTo("moduleKey");
assertThat(module.getWorkDir()).isEqualTo(workDir.toPath());
assertThat(module.getEncoding()).isEqualTo(Charset.defaultCharset());
assertThat(module.getSourceDirsOrFiles()).isNotPresent();

+ 0
- 2
sonar-plugin-api-impl/src/test/java/org/sonar/api/batch/fs/internal/fs/DefaultInputProjectTest.java View File

@@ -55,9 +55,7 @@ public class DefaultInputProjectTest {
assertThat(project.getName()).isEqualTo("projectName");
assertThat(project.getOriginalName()).isEqualTo("projectName");
assertThat(project.definition()).isEqualTo(def);
assertThat(project.getBranch()).isNull();
assertThat(project.getBaseDir()).isEqualTo(baseDir.toPath());
assertThat(project.getKeyWithBranch()).isEqualTo("projectKey");
assertThat(project.getDescription()).isEqualTo("desc");
assertThat(project.getWorkDir()).isEqualTo(workDir.toPath());
assertThat(project.getEncoding()).isEqualTo(Charset.defaultCharset());

+ 0
- 6
sonar-plugin-api/src/main/java/org/sonar/api/CoreProperties.java View File

@@ -139,12 +139,6 @@ public interface CoreProperties {
/* Global settings */
String SONAR_HOME = "SONAR_HOME";

/**
* @deprecated since 6.7. This feature is deprecated in favor of the new branch feature.
* @see <a href="https://redirect.sonarsource.com/doc/branches.html">https://redirect.sonarsource.com/doc/branches.html/a>
*/
@Deprecated
String PROJECT_BRANCH_PROPERTY = "sonar.branch";
String PROJECT_VERSION_PROPERTY = "sonar.projectVersion";
String BUILD_STRING_PROPERTY = "sonar.buildString";


+ 0
- 23
sonar-plugin-api/src/main/java/org/sonar/api/batch/bootstrap/ProjectDefinition.java View File

@@ -166,29 +166,6 @@ public class ProjectDefinition {
return properties.get(CoreProperties.PROJECT_KEY_PROPERTY);
}

/**
* @since 4.5
*/
public String getKeyWithBranch() {
String branch = getBranch();
String projectKey = getKey();
if (StringUtils.isNotBlank(branch)) {
projectKey = String.format("%s:%s", projectKey, branch);
}
return projectKey;
}

@CheckForNull
public String getBranch() {
String branch = properties.get(CoreProperties.PROJECT_BRANCH_PROPERTY);
if (StringUtils.isNotBlank(branch)) {
return branch;
} else if (parent != null) {
return parent.getBranch();
}
return null;
}

/**
* @deprecated since 7.7, use {@link #getOriginalProjectVersion()} instead
*/

+ 0
- 30
sonar-plugin-api/src/main/java/org/sonar/api/batch/bootstrap/ProjectKey.java View File

@@ -1,30 +0,0 @@
/*
* SonarQube
* Copyright (C) 2009-2019 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.api.batch.bootstrap;

/**
* Provides root project key with branch
* @deprecated since 7.6
*/
@Deprecated
@FunctionalInterface
public interface ProjectKey {
String get();
}

+ 2
- 3
sonar-plugin-api/src/main/java/org/sonar/api/batch/bootstrap/ProjectReactor.java View File

@@ -19,10 +19,9 @@
*/
package org.sonar.api.batch.bootstrap;

import org.sonar.api.scanner.ScannerSide;

import java.util.ArrayList;
import java.util.List;
import org.sonar.api.scanner.ScannerSide;

/**
* Mutable project definitions that can be modified by {@link ProjectBuilder} extensions.
@@ -73,7 +72,7 @@ public class ProjectReactor {

public String get() {
if (root != null) {
return root.getKeyWithBranch();
return root.getKey();
}
return null;
}

+ 5
- 27
sonar-scanner-engine/src/main/java/org/sonar/scanner/bootstrap/ProcessedScannerProperties.java View File

@@ -22,19 +22,16 @@ package org.sonar.scanner.bootstrap;
import java.util.Collections;
import java.util.HashMap;
import java.util.Map;
import javax.annotation.CheckForNull;
import javax.annotation.concurrent.Immutable;
import org.sonar.api.CoreProperties;
import org.sonar.api.batch.bootstrap.ProjectKey;
import org.sonar.scanner.scan.ExternalProjectKeyAndOrganization;

import static org.apache.commons.lang.StringUtils.trimToNull;
import static org.sonar.api.CoreProperties.PROJECT_KEY_PROPERTY;

/**
* Properties that are coming from scanner.
*/
@Immutable
public class ProcessedScannerProperties implements ProjectKey {
public class ProcessedScannerProperties {

private final Map<String, String> properties;

@@ -44,7 +41,7 @@ public class ProcessedScannerProperties implements ProjectKey {
this.properties.putAll(rawScannerProperties.properties());

externalProjectKeyAndOrganization.getProjectKey()
.ifPresent(projectKey -> properties.put(CoreProperties.PROJECT_KEY_PROPERTY, projectKey));
.ifPresent(projectKey -> properties.put(PROJECT_KEY_PROPERTY, projectKey));
externalProjectKeyAndOrganization.getOrganization()
.ifPresent(organization -> properties.put(org.sonar.core.config.ScannerProperties.ORGANIZATION, organization));
}
@@ -57,26 +54,7 @@ public class ProcessedScannerProperties implements ProjectKey {
return properties.get(key);
}

@Override
public String get() {
return getKeyWithBranch();
}

private String getKey() {
return properties.get(CoreProperties.PROJECT_KEY_PROPERTY);
}

public String getKeyWithBranch() {
String branch = getBranch();
String projectKey = getKey();
if (branch == null) {
return projectKey;
}
return String.format("%s:%s", projectKey, branch);
}

@CheckForNull
private String getBranch() {
return trimToNull(properties.get(CoreProperties.PROJECT_BRANCH_PROPERTY));
public String getProjectKey() {
return this.properties.get(PROJECT_KEY_PROPERTY);
}
}

+ 2
- 7
sonar-scanner-engine/src/main/java/org/sonar/scanner/cpd/CpdSettings.java View File

@@ -19,7 +19,6 @@
*/
package org.sonar.scanner.cpd;

import org.apache.commons.lang.StringUtils;
import org.sonar.api.CoreProperties;
import org.sonar.api.config.Configuration;
import org.sonar.duplications.block.BlockChunker;
@@ -27,17 +26,13 @@ import org.sonar.api.batch.fs.internal.DefaultInputProject;

public class CpdSettings {
private final Configuration settings;
private final String branch;

public CpdSettings(Configuration config, DefaultInputProject project) {
public CpdSettings(Configuration config) {
this.settings = config;
this.branch = project.getBranch();
}

public boolean isCrossProjectDuplicationEnabled() {
return settings.getBoolean(CoreProperties.CPD_CROSS_PROJECT).orElse(false)
// No cross project duplication for branches
&& StringUtils.isBlank(branch);
return settings.getBoolean(CoreProperties.CPD_CROSS_PROJECT).orElse(false);
}

/**

+ 1
- 5
sonar-scanner-engine/src/main/java/org/sonar/scanner/report/ComponentsPublisher.java View File

@@ -139,11 +139,7 @@ public class ComponentsPublisher implements ReportPublisherStep {

@CheckForNull
private static String getName(AbstractProjectOrModule module) {
if (StringUtils.isNotEmpty(module.definition().getBranch())) {
return module.definition().getName() + " " + module.definition().getBranch();
} else {
return module.definition().getOriginalName();
}
return module.definition().getOriginalName();
}

@CheckForNull

+ 0
- 4
sonar-scanner-engine/src/main/java/org/sonar/scanner/report/MetadataPublisher.java View File

@@ -45,8 +45,6 @@ import org.sonar.scanner.scan.branch.BranchConfiguration;
import org.sonar.scanner.scm.ScmConfiguration;
import org.sonar.scanner.scm.ScmRevision;

import static java.util.Optional.ofNullable;

public class MetadataPublisher implements ReportPublisherStep {

private static final Logger LOG = Loggers.get(MetadataPublisher.class);
@@ -100,8 +98,6 @@ public class MetadataPublisher implements ReportPublisherStep {
addBranchInformation(builder);
}

ofNullable(rootProject.getBranch()).ifPresent(builder::setDeprecatedBranch);

addScmInformation(builder);

for (QProfile qp : qProfiles.findAll()) {

+ 3
- 4
sonar-scanner-engine/src/main/java/org/sonar/scanner/report/ReportPublisher.java View File

@@ -175,7 +175,6 @@ public class ReportPublisher implements Startable {
.setParam("organization", properties.organizationKey().orElse(null))
.setParam("projectKey", moduleHierarchy.root().key())
.setParam("projectName", moduleHierarchy.root().getOriginalName())
.setParam("projectBranch", moduleHierarchy.root().getBranch())
.setPart("report", filePart);

String branchName = branchConfiguration.branchName();
@@ -211,14 +210,14 @@ public class ReportPublisher implements Startable {
} else {

Map<String, String> metadata = new LinkedHashMap<>();
String effectiveKey = moduleHierarchy.root().getKeyWithBranch();
properties.organizationKey().ifPresent(org -> metadata.put("organization", org));
metadata.put("projectKey", effectiveKey);
metadata.put("projectKey", moduleHierarchy.root().key());
metadata.put("serverUrl", server.getPublicRootUrl());
metadata.put("serverVersion", server.getVersion());
properties.branch().ifPresent(branch -> metadata.put("branch", branch));

URL dashboardUrl = buildDashboardUrl(server.getPublicRootUrl(), effectiveKey);
URL dashboardUrl = buildDashboardUrl(server.getPublicRootUrl(), moduleHierarchy.root().key());
metadata.put("dashboardUrl", dashboardUrl.toExternalForm());

URL taskUrl = HttpUrl.parse(server.getPublicRootUrl()).newBuilder()

+ 1
- 1
sonar-scanner-engine/src/main/java/org/sonar/scanner/repository/ProjectRepositoriesSupplier.java View File

@@ -44,7 +44,7 @@ public class ProjectRepositoriesSupplier implements Supplier<ProjectRepositories
public ProjectRepositories get() {
if (project == null) {
Profiler profiler = Profiler.create(LOG).startInfo(LOG_MSG);
project = loader.load(scannerProperties.getKeyWithBranch(), branchConfig.longLivingSonarReferenceBranch());
project = loader.load(scannerProperties.getProjectKey(), branchConfig.longLivingSonarReferenceBranch());
profiler.stopInfo();
}


+ 1
- 1
sonar-scanner-engine/src/main/java/org/sonar/scanner/repository/QualityProfilesProvider.java View File

@@ -34,7 +34,7 @@ public class QualityProfilesProvider extends ProviderAdapter {
public QualityProfiles provide(QualityProfileLoader loader, ProcessedScannerProperties props) {
if (this.profiles == null) {
Profiler profiler = Profiler.create(LOG).startInfo(LOG_MSG);
profiles = new QualityProfiles(loader.load(props.getKeyWithBranch()));
profiles = new QualityProfiles(loader.load(props.getProjectKey()));
profiler.stopInfo();
}


+ 1
- 1
sonar-scanner-engine/src/main/java/org/sonar/scanner/repository/settings/DefaultProjectSettingsLoader.java View File

@@ -33,6 +33,6 @@ public class DefaultProjectSettingsLoader extends AbstractSettingsLoader impleme

@Override
public Map<String, String> loadProjectSettings() {
return load(scannerProperties.getKeyWithBranch());
return load(scannerProperties.getProjectKey());
}
}

+ 1
- 12
sonar-scanner-engine/src/main/java/org/sonar/scanner/scan/ProjectReactorValidator.java View File

@@ -69,17 +69,13 @@ public class ProjectReactorValidator {
validateModule(moduleDef, validationMessages);
}

String deprecatedBranchName = reactor.getRoot().getBranch();

if (isBranchFeatureAvailable()) {
branchParamsValidator.validate(validationMessages, deprecatedBranchName);
branchParamsValidator.validate(validationMessages);
} else {
validateBranchParamsWhenPluginAbsent(validationMessages);
validatePullRequestParamsWhenPluginAbsent(validationMessages);
}

validateLegacyBranch(validationMessages, deprecatedBranchName);

if (!validationMessages.isEmpty()) {
throw MessageException.of("Validation of project reactor failed:\n o " +
String.join("\n o ", validationMessages));
@@ -108,13 +104,6 @@ public class ProjectReactorValidator {
}
}

private static void validateLegacyBranch(List<String> validationMessages, @Nullable String branch) {
if (isNotEmpty(branch) && !ComponentKeys.isValidLegacyBranch(branch)) {
validationMessages.add(format("\"%s\" is not a valid branch name. "
+ "Allowed characters are alphanumeric, '-', '_', '.' and '/'.", branch));
}
}

private boolean isBranchFeatureAvailable() {
return branchParamsValidator != null;
}

+ 4
- 14
sonar-scanner-engine/src/main/java/org/sonar/scanner/scan/ProjectScanContainer.java View File

@@ -322,23 +322,13 @@ public class ProjectScanContainer extends ComponentContainer {
GlobalAnalysisMode analysisMode = getComponentByType(GlobalAnalysisMode.class);
InputModuleHierarchy tree = getComponentByType(InputModuleHierarchy.class);
ScanProperties properties = getComponentByType(ScanProperties.class);
SonarRuntime sonarRuntime = getComponentByType(SonarRuntime.class);
properties.validate();

properties.organizationKey().ifPresent(k -> LOG.info("Organization key: {}", k));
if (sonarRuntime.getEdition() == SonarEdition.SONARCLOUD) {
String branch = tree.root().definition().getBranch();
if (branch != null) {
LOG.info("Branch key: {}", branch);
LOG.warn("The use of \"sonar.branch\" is deprecated and replaced by \"{}\". See {}.",
ScannerProperties.BRANCH_NAME, ScannerProperties.BRANCHES_DOC_LINK);
}
} else {
properties.get("sonar.branch").ifPresent(deprecatedBranch -> {
throw MessageException.of("The 'sonar.branch' parameter is no longer supported. You should stop using it. " +
"Branch analysis is available in Developer Edition and above. See https://redirect.sonarsource.com/editions/developer.html for more information.");
});
}
properties.get("sonar.branch").ifPresent(deprecatedBranch -> {
throw MessageException.of("The 'sonar.branch' parameter is no longer supported. You should stop using it. " +
"Branch analysis is available in Developer Edition and above. See https://redirect.sonarsource.com/editions/developer.html for more information.");
});

BranchConfiguration branchConfig = getComponentByType(BranchConfiguration.class);
if (branchConfig.branchType() == BranchType.PULL_REQUEST) {

+ 1
- 1
sonar-scanner-engine/src/main/java/org/sonar/scanner/scan/branch/BranchParamsValidator.java View File

@@ -25,5 +25,5 @@ import org.sonar.api.scanner.ScannerSide;

@ScannerSide
public interface BranchParamsValidator {
void validate(List<String> validationMessages, @Nullable String deprecatedBranchName);
void validate(List<String> validationMessages);
}

+ 0
- 30
sonar-scanner-engine/src/main/java/org/sonar/scanner/scan/branch/DefaultBranchParamsValidator.java View File

@@ -1,30 +0,0 @@
/*
* SonarQube
* Copyright (C) 2009-2019 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.scan.branch;

import java.util.List;
import javax.annotation.Nullable;

public class DefaultBranchParamsValidator implements BranchParamsValidator {
@Override
public void validate(List<String> validationMessages, @Nullable String deprecatedBranchName) {
// no-op
}
}

+ 9
- 9
sonar-scanner-engine/src/main/java/org/sonar/scanner/scan/branch/ProjectBranchesProvider.java View File

@@ -19,13 +19,13 @@
*/
package org.sonar.scanner.scan.branch;

import java.util.Collections;
import com.google.common.collect.ImmutableList;
import org.picocontainer.annotations.Nullable;
import org.picocontainer.injectors.ProviderAdapter;
import org.sonar.api.batch.bootstrap.ProjectKey;
import org.sonar.api.utils.log.Logger;
import org.sonar.api.utils.log.Loggers;
import org.sonar.api.utils.log.Profiler;
import org.sonar.scanner.bootstrap.ProcessedScannerProperties;

public class ProjectBranchesProvider extends ProviderAdapter {

@@ -34,19 +34,19 @@ public class ProjectBranchesProvider extends ProviderAdapter {

private ProjectBranches branches = null;

public ProjectBranches provide(@Nullable ProjectBranchesLoader loader, ProjectKey projectKey) {
if (branches != null) {
return branches;
public ProjectBranches provide(@Nullable ProjectBranchesLoader loader, ProcessedScannerProperties scannerProperties) {
if (this.branches != null) {
return this.branches;
}

if (loader == null) {
branches = new ProjectBranches(Collections.emptyList());
return branches;
this.branches = new ProjectBranches(ImmutableList.of());
return this.branches;
}

Profiler profiler = Profiler.create(LOG).startInfo(LOG_MSG);
branches = loader.load(projectKey.get());
this.branches = loader.load(scannerProperties.getProjectKey());
profiler.stopInfo();
return branches;
return this.branches;
}
}

+ 3
- 3
sonar-scanner-engine/src/main/java/org/sonar/scanner/scan/branch/ProjectPullRequestsProvider.java View File

@@ -21,10 +21,10 @@ package org.sonar.scanner.scan.branch;

import java.util.Collections;
import org.picocontainer.injectors.ProviderAdapter;
import org.sonar.api.batch.bootstrap.ProjectKey;
import org.sonar.api.utils.log.Logger;
import org.sonar.api.utils.log.Loggers;
import org.sonar.api.utils.log.Profiler;
import org.sonar.scanner.bootstrap.ProcessedScannerProperties;

public class ProjectPullRequestsProvider extends ProviderAdapter {

@@ -33,7 +33,7 @@ public class ProjectPullRequestsProvider extends ProviderAdapter {

private ProjectPullRequests pullRequests = null;

public ProjectPullRequests provide(@org.picocontainer.annotations.Nullable ProjectPullRequestsLoader loader, ProjectKey projectKey) {
public ProjectPullRequests provide(@org.picocontainer.annotations.Nullable ProjectPullRequestsLoader loader, ProcessedScannerProperties scannerProperties) {
if (pullRequests != null) {
return pullRequests;
}
@@ -44,7 +44,7 @@ public class ProjectPullRequestsProvider extends ProviderAdapter {
}

Profiler profiler = Profiler.create(LOG).startInfo(LOG_MSG);
pullRequests = loader.load(projectKey.get());
pullRequests = loader.load(scannerProperties.getProjectKey());
profiler.stopInfo();
return pullRequests;
}

+ 1
- 1
sonar-scanner-engine/src/main/java/org/sonar/scanner/scan/filesystem/FileIndexer.java View File

@@ -131,7 +131,7 @@ public class FileIndexer {
projectRelativePath.toString(),
moduleRelativePath.toString(),
type, language, scannerComponentIdGenerator.getAsInt(), sensorStrategy);
DefaultInputFile inputFile = new DefaultInputFile(indexedFile, f -> metadataGenerator.setMetadata(module.getKeyWithBranch(), f, module.getEncoding()));
DefaultInputFile inputFile = new DefaultInputFile(indexedFile, f -> metadataGenerator.setMetadata(module.key(), f, module.getEncoding()));
if (language != null) {
inputFile.setPublished(true);
}

+ 1
- 1
sonar-scanner-engine/src/main/java/org/sonar/scanner/scm/ScmPublisher.java View File

@@ -96,7 +96,7 @@ public final class ScmPublisher {
if (configuration.forceReloadAll() || f.status() != Status.SAME) {
addIfNotEmpty(filesToBlame, f);
} else if (!branchConfiguration.isShortOrPullRequest()) {
FileData fileData = projectRepositoriesSupplier.get().fileData(componentStore.findModule(f).getKeyWithBranch(), f);
FileData fileData = projectRepositoriesSupplier.get().fileData(componentStore.findModule(f).key(), f);
if (fileData == null || StringUtils.isEmpty(fileData.revision())) {
addIfNotEmpty(filesToBlame, f);
} else {

+ 1
- 3
sonar-scanner-engine/src/test/java/org/sonar/scanner/cpd/CpdSettingsTest.java View File

@@ -33,13 +33,11 @@ import static org.mockito.Mockito.when;
public class CpdSettingsTest {
private CpdSettings cpdSettings;
private Configuration configuration;
private DefaultInputProject project;

@Before
public void setUp() {
project = mock(DefaultInputProject.class);
configuration = mock(Configuration.class);
cpdSettings = new CpdSettings(configuration, project);
cpdSettings = new CpdSettings(configuration);
}

@Test

+ 4
- 87
sonar-scanner-engine/src/test/java/org/sonar/scanner/mediumtest/branch/DeprecatedBranchMediumTest.java View File

@@ -22,8 +22,6 @@ package org.sonar.scanner.mediumtest.branch;
import com.google.common.collect.ImmutableMap;
import java.io.File;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.util.Map;
import org.apache.commons.io.FileUtils;
import org.junit.Before;
@@ -36,11 +34,11 @@ import org.sonar.api.batch.fs.internal.DefaultInputFile;
import org.sonar.api.utils.MessageException;
import org.sonar.scanner.mediumtest.AnalysisResult;
import org.sonar.scanner.mediumtest.ScannerMediumTester;
import org.sonar.api.utils.MessageException;
import org.sonar.scanner.mediumtest.ScannerMediumTester;
import org.sonar.xoo.XooPlugin;
import org.sonar.xoo.rule.XooRulesDefinition;

import static org.assertj.core.api.Assertions.assertThat;

public class DeprecatedBranchMediumTest {

@Rule
@@ -57,21 +55,12 @@ public class DeprecatedBranchMediumTest {
.addActiveRule("xoo", "xoo:OneIssuePerFile", null, "One Issue Per File", null, null, null)
.addDefaultQProfile("xoo", "Sonar Way");

@Rule
public ScannerMediumTester testerSC = new ScannerMediumTester()
.setEdition(SonarEdition.SONARCLOUD)
.registerPlugin("xoo", new XooPlugin())
.addRules(new XooRulesDefinition())
// active a rule just to be sure that xoo files are published
.addActiveRule("xoo", "xoo:OneIssuePerFile", null, "One Issue Per File", null, null, null)
.addDefaultQProfile("xoo", "Sonar Way");

private File baseDir;

private Map<String, String> commonProps;

@Before
public void prepare() throws IOException {
public void prepare() {
baseDir = temp.getRoot();

commonProps = ImmutableMap.<String, String>builder()
@@ -86,7 +75,7 @@ public class DeprecatedBranchMediumTest {
}

@Test
public void scanProjectWithBranchOnSonarQube() throws IOException {
public void scanProjectWithBranch() throws IOException {
File srcDir = new File(baseDir, "src");
srcDir.mkdir();

@@ -104,76 +93,4 @@ public class DeprecatedBranchMediumTest {
.build())
.execute();
}

@Test
public void scanProjectWithBranchOnSonarCloud() throws IOException {
File srcDir = new File(baseDir, "src");
srcDir.mkdir();

File xooFile = new File(srcDir, "sample.xoo");
FileUtils.write(xooFile, "Sample xoo\ncontent");

AnalysisResult result = testerSC.newAnalysis()
.properties(ImmutableMap.<String, String>builder()
.putAll(commonProps)
.put("sonar.branch", "branch")
.build())
.execute();

assertThat(result.inputFiles()).hasSize(1);
assertThat(result.inputFile("src/sample.xoo").key()).isEqualTo("com.foo.project:src/sample.xoo");

DefaultInputFile inputfile = (DefaultInputFile) result.inputFile("src/sample.xoo");
assertThat(result.getReportReader().readComponent(inputfile.scannerId()).getProjectRelativePath()).isEqualTo("src/sample.xoo");

assertThat(result.getReportReader().readMetadata().getDeprecatedBranch()).isEqualTo("branch");

result = testerSC.newAnalysis()
.properties(ImmutableMap.<String, String>builder()
.putAll(commonProps)
.put("sonar.branch", "")
.build())
.execute();

assertThat(result.inputFiles()).hasSize(1);
assertThat(result.inputFile("src/sample.xoo").key()).isEqualTo("com.foo.project:src/sample.xoo");
}

@Test
public void scanMultiModuleWithBranchOnSonarCloud() throws IOException {
Path srcDir = baseDir.toPath().resolve("moduleA").resolve("src");
Files.createDirectories(srcDir);

File xooFile = new File(srcDir.toFile(), "sample.xoo");
FileUtils.write(xooFile, "Sample xoo\ncontent");

AnalysisResult result = testerSC.newAnalysis()
.properties(ImmutableMap.<String, String>builder()
.putAll(commonProps)
.put("sonar.branch", "branch")
.put("sonar.modules", "moduleA")
.build())
.execute();

assertThat(result.inputFiles()).hasSize(1);
assertThat(result.inputFile("moduleA/src/sample.xoo").key()).isEqualTo("com.foo.project:moduleA/src/sample.xoo");

// no branch in the report
DefaultInputFile inputfile = (DefaultInputFile) result.inputFile("moduleA/src/sample.xoo");
assertThat(result.getReportReader().readComponent(inputfile.scannerId()).getProjectRelativePath()).isEqualTo("moduleA/src/sample.xoo");

assertThat(result.getReportReader().readMetadata().getDeprecatedBranch()).isEqualTo("branch");

result = testerSC.newAnalysis()
.properties(ImmutableMap.<String, String>builder()
.putAll(commonProps)
.put("sonar.branch", "")
.put("sonar.modules", "moduleA")
.build())
.execute();

assertThat(result.inputFiles()).hasSize(1);
assertThat(result.inputFile("moduleA/src/sample.xoo").key()).isEqualTo("com.foo.project:moduleA/src/sample.xoo");
}

}

+ 0
- 42
sonar-scanner-engine/src/test/java/org/sonar/scanner/mediumtest/fs/FileSystemMediumTest.java View File

@@ -111,48 +111,6 @@ public class FileSystemMediumTest {
assertThat(result.getReportComponent(file.scannerId())).isNotNull();
}

@Test
public void logProjectKeyAndOrganizationKey() throws IOException {
builder.put("sonar.organization", "my org");
builder.put("sonar.branch", "");
File srcDir = new File(baseDir, "src");
srcDir.mkdir();

File xooFile = new File(srcDir, "sample.xoo");
FileUtils.write(xooFile, "Sample xoo\ncontent", StandardCharsets.UTF_8);

tester.newAnalysis()
.properties(builder
.put("sonar.sources", "src")
.build())
.execute();

assertThat(logTester.logs()).contains("Project key: com.foo.project");
assertThat(logTester.logs()).contains("Organization key: my org");
assertThat(logTester.logs().stream().collect(joining("\n"))).doesNotContain("Branch key");
}

@Test
public void logBranchKey() throws IOException {
builder.put("sonar.branch", "my-branch");
File srcDir = new File(baseDir, "src");
assertThat(srcDir.mkdir()).isTrue();

File xooFile = new File(srcDir, "sample.xoo");
FileUtils.write(xooFile, "Sample xoo\ncontent", StandardCharsets.UTF_8);

tester.newAnalysis()
.properties(builder
.put("sonar.sources", "src")
.build())
.execute();

assertThat(logTester.logs()).contains("Project key: com.foo.project");
assertThat(logTester.logs()).contains("Branch key: my-branch");
assertThat(logTester.logs())
.contains("The use of \"sonar.branch\" is deprecated and replaced by \"sonar.branch.name\". See https://redirect.sonarsource.com/doc/branches.html.");
}

@Test
public void logBranchNameAndType() {
builder.put("sonar.branch.name", "my-branch");

+ 0
- 40
sonar-scanner-engine/src/test/java/org/sonar/scanner/mediumtest/fs/ProjectBuilderMediumTest.java View File

@@ -133,46 +133,6 @@ public class ProjectBuilderMediumTest {

}

@Test
// SONAR-6976
public void testProjectBuilderWithNewLine() throws IOException {
File baseDir = prepareProject();

exception.expect(MessageException.class);
exception.expectMessage("is not a valid branch name");
tester.newAnalysis()
.properties(ImmutableMap.<String, String>builder()
.put("sonar.projectBaseDir", baseDir.getAbsolutePath())
.put("sonar.projectKey", "com.foo.project")
.put("sonar.branch", "branch\n")
.put("sonar.sources", ".")
.put("sonar.xoo.enableProjectBuilder", "true")
.build())
.execute();
}

@Test
public void testProjectBuilderWithBranch() throws IOException {
File baseDir = prepareProject();

AnalysisResult result = tester.newAnalysis()
.properties(ImmutableMap.<String, String>builder()
.put("sonar.projectBaseDir", baseDir.getAbsolutePath())
.put("sonar.projectKey", "com.foo.project")
.put("sonar.branch", "my-branch")
.put("sonar.sources", ".")
.put("sonar.xoo.enableProjectBuilder", "true")
.build())
.execute();

List<Issue> issues = result.issuesFor(result.inputFile("module1/src/sample.xoo"));
assertThat(issues).hasSize(10);

assertThat(issues)
.extracting("msg", "textRange.startLine", "gap")
.contains(tuple("This issue is generated on each line", 1, 0.0));
}

private File prepareProject() throws IOException {
File baseDir = temp.newFolder();
File module1Dir = new File(baseDir, "module1");

+ 6
- 59
sonar-scanner-engine/src/test/java/org/sonar/scanner/mediumtest/scm/ScmMediumTest.java View File

@@ -194,7 +194,8 @@ public class ScmMediumTest {
// revision,author,dateTime
"1,foo,2013-01-04\n" +
"1,bar,2013-01-04\n" +
"2,biz,2014-01-04\n", StandardCharsets.UTF_8);
"2,biz,2014-01-04\n",
StandardCharsets.UTF_8);

File sameContentScmOnServer = new File(baseDir, SAME_CONTENT_SCM_ON_SERVER_XOO);
FileUtils.write(sameContentScmOnServer, SAMPLE_XOO_CONTENT, StandardCharsets.UTF_8);
@@ -210,7 +211,8 @@ public class ScmMediumTest {
FileUtils.write(xooScmFile,
// revision,author,dateTime
"1,foo,2013-01-04\n" +
"1,bar,2013-01-04\n", StandardCharsets.UTF_8);
"1,bar,2013-01-04\n",
StandardCharsets.UTF_8);

tester.newAnalysis()
.properties(ImmutableMap.<String, String>builder()
@@ -242,62 +244,6 @@ public class ScmMediumTest {
assertThat(logTester.logs()).containsSubsequence(MISSING_BLAME_INFORMATION_FOR_THE_FOLLOWING_FILES, " * src/no_blame_scm_on_server.xoo");
}

@Test
public void optimize_blame_for_deprecated_branch() throws IOException, URISyntaxException {

File baseDir = prepareProject();
File changedContentScmOnServer = new File(baseDir, CHANGED_CONTENT_SCM_ON_SERVER_XOO);
FileUtils.write(changedContentScmOnServer, SAMPLE_XOO_CONTENT + "\nchanged", StandardCharsets.UTF_8);
File xooScmFile = new File(baseDir, CHANGED_CONTENT_SCM_ON_SERVER_XOO + ".scm");
FileUtils.write(xooScmFile,
// revision,author,dateTime
"1,foo,2013-01-04\n" +
"1,bar,2013-01-04\n" +
"2,biz,2014-01-04\n", StandardCharsets.UTF_8);

File sameContentScmOnServer = new File(baseDir, SAME_CONTENT_SCM_ON_SERVER_XOO);
FileUtils.write(sameContentScmOnServer, SAMPLE_XOO_CONTENT, StandardCharsets.UTF_8);
// No need to write .scm file since this file should not be blamed

File noBlameScmOnServer = new File(baseDir, NO_BLAME_SCM_ON_SERVER_XOO);
FileUtils.write(noBlameScmOnServer, SAMPLE_XOO_CONTENT + "\nchanged", StandardCharsets.UTF_8);
// No .scm file to emulate a failure during blame

File sameContentNoScmOnServer = new File(baseDir, SAME_CONTENT_NO_SCM_ON_SERVER_XOO);
FileUtils.write(sameContentNoScmOnServer, SAMPLE_XOO_CONTENT, StandardCharsets.UTF_8);
xooScmFile = new File(baseDir, SAME_CONTENT_NO_SCM_ON_SERVER_XOO + ".scm");
FileUtils.write(xooScmFile,
// revision,author,dateTime
"1,foo,2013-01-04\n" +
"1,bar,2013-01-04\n", StandardCharsets.UTF_8);

tester.newAnalysis()
.properties(ImmutableMap.<String, String>builder()
.put("sonar.projectBaseDir", baseDir.getAbsolutePath())
.put("sonar.projectKey", "com.foo.project")
.put("sonar.branch", "mybranch")
.put("sonar.sources", "src")
.put("sonar.scm.provider", "xoo")
.build())
.execute();

assertThat(getChangesets(baseDir, "src/sample.xoo")).isNotNull();

assertThat(getChangesets(baseDir, CHANGED_CONTENT_SCM_ON_SERVER_XOO).getCopyFromPrevious()).isFalse();

assertThat(getChangesets(baseDir, SAME_CONTENT_SCM_ON_SERVER_XOO).getCopyFromPrevious()).isTrue();

assertThat(getChangesets(baseDir, SAME_CONTENT_NO_SCM_ON_SERVER_XOO).getCopyFromPrevious()).isFalse();

assertThat(getChangesets(baseDir, NO_BLAME_SCM_ON_SERVER_XOO)).isNull();

// 5 .xoo files + 3 .scm files, but only 4 marked for publishing. 1 file is SAME so not included in the total
assertThat(logTester.logs()).containsSubsequence("8 files indexed");
assertThat(logTester.logs()).containsSubsequence("SCM Publisher 4 source files to be analyzed");
assertThat(logTester.logs().stream().anyMatch(s -> Pattern.matches("SCM Publisher 3/4 source files have been analyzed \\(done\\) \\| time=[0-9]+ms", s))).isTrue();
assertThat(logTester.logs()).containsSubsequence(MISSING_BLAME_INFORMATION_FOR_THE_FOLLOWING_FILES, " * src/no_blame_scm_on_server.xoo");
}

@Test
public void forceReload() throws IOException, URISyntaxException {

@@ -308,7 +254,8 @@ public class ScmMediumTest {
FileUtils.write(xooScmFile,
// revision,author,dateTime
"1,foo,2013-01-04\n" +
"1,bar,2013-01-04\n", StandardCharsets.UTF_8);
"1,bar,2013-01-04\n",
StandardCharsets.UTF_8);

AnalysisBuilder analysisBuilder = tester.newAnalysis()
.properties(ImmutableMap.<String, String>builder()

+ 1
- 33
sonar-scanner-engine/src/test/java/org/sonar/scanner/report/ComponentsPublisherTest.java View File

@@ -22,7 +22,6 @@ package org.sonar.scanner.report;
import java.io.File;
import java.io.IOException;
import java.nio.file.Path;
import java.util.Collections;
import org.junit.Before;
import org.junit.Rule;
import org.junit.Test;
@@ -37,7 +36,6 @@ import org.sonar.api.batch.fs.internal.DefaultInputFile;
import org.sonar.api.batch.fs.internal.DefaultInputProject;
import org.sonar.api.batch.fs.internal.TestInputFileBuilder;
import org.sonar.scanner.protocol.output.FileStructure;
import org.sonar.scanner.protocol.output.ScannerReport;
import org.sonar.scanner.protocol.output.ScannerReport.Component;
import org.sonar.scanner.protocol.output.ScannerReport.Component.FileStatus;
import org.sonar.scanner.protocol.output.ScannerReport.ComponentLink.ComponentLinkType;
@@ -56,7 +54,6 @@ public class ComponentsPublisherTest {

private File outputDir;
private ScannerReportWriter writer;
private ScannerReportReader reader;
private BranchConfiguration branchConfiguration;

@Before
@@ -64,11 +61,6 @@ public class ComponentsPublisherTest {
branchConfiguration = mock(BranchConfiguration.class);
outputDir = temp.newFolder();
writer = new ScannerReportWriter(outputDir);
reader = new ScannerReportReader(outputDir);
}

private void writeIssue(int componentId) {
writer.writeComponentIssues(componentId, Collections.singleton(ScannerReport.Issue.newBuilder().build()));
}

@Test
@@ -135,29 +127,6 @@ public class ComponentsPublisherTest {
assertThat(reader.readComponent(7).getStatus()).isEqualTo(FileStatus.ADDED);
}

@Test
public void should_set_modified_name_with_branch() throws IOException {
ProjectInfo projectInfo = mock(ProjectInfo.class);
when(projectInfo.getAnalysisDate()).thenReturn(DateUtils.parseDate("2012-12-12"));

ProjectDefinition rootDef = ProjectDefinition.create()
.setKey("foo")
.setDescription("Root description")
.setBaseDir(temp.newFolder())
.setWorkDir(temp.newFolder())
.setProperty(CoreProperties.PROJECT_BRANCH_PROPERTY, "my_branch");

DefaultInputProject project = new DefaultInputProject(rootDef, 1);

InputComponentStore store = new InputComponentStore(branchConfiguration);

ComponentsPublisher publisher = new ComponentsPublisher(project, store);
publisher.publish(writer);
Component rootProtobuf = reader.readComponent(1);
assertThat(rootProtobuf.getKey()).isEqualTo("foo");
assertThat(rootProtobuf.getName()).isEqualTo("foo my_branch");
}

@Test
public void publish_unchanged_components_even_in_short_branches() throws IOException {
when(branchConfiguration.isShortOrPullRequest()).thenReturn(true);
@@ -226,14 +195,13 @@ public class ComponentsPublisherTest {
}

@Test
public void publish_project_with_links_and_branch() throws Exception {
public void publish_project_with_links() throws Exception {
ProjectInfo projectInfo = mock(ProjectInfo.class);
when(projectInfo.getAnalysisDate()).thenReturn(DateUtils.parseDate("2012-12-12"));

ProjectDefinition rootDef = ProjectDefinition.create()
.setKey("foo")
.setProperty(CoreProperties.PROJECT_VERSION_PROPERTY, "1.0")
.setProperty(CoreProperties.PROJECT_BRANCH_PROPERTY, "my_branch")
.setName("Root project")
.setProperty(CoreProperties.LINKS_HOME_PAGE, "http://home")
.setProperty(CoreProperties.LINKS_CI, "http://ci")

+ 1
- 25
sonar-scanner-engine/src/test/java/org/sonar/scanner/report/MetadataPublisherTest.java View File

@@ -37,7 +37,6 @@ import org.junit.Rule;
import org.junit.Test;
import org.junit.rules.TemporaryFolder;
import org.junit.runner.RunWith;
import org.sonar.api.CoreProperties;
import org.sonar.api.batch.bootstrap.ProjectDefinition;
import org.sonar.api.batch.scm.ScmProvider;
import org.sonar.scanner.ProjectInfo;
@@ -58,7 +57,6 @@ import org.sonar.scanner.scan.branch.BranchType;
import org.sonar.scanner.scm.ScmConfiguration;
import org.sonar.scanner.scm.ScmRevision;

import static java.util.Arrays.asList;
import static java.util.Collections.emptyMap;
import static org.apache.commons.lang.RandomStringUtils.randomAlphabetic;
import static org.assertj.core.api.Assertions.assertThat;
@@ -123,7 +121,7 @@ public class MetadataPublisherTest {
@Test
public void write_metadata() throws Exception {
Date date = new Date();
when(qProfiles.findAll()).thenReturn(asList(new QProfile("q1", "Q1", "java", date)));
when(qProfiles.findAll()).thenReturn(Collections.singletonList(new QProfile("q1", "Q1", "java", date)));
when(pluginRepository.getPluginsByKey()).thenReturn(ImmutableMap.of(
"java", new ScannerPlugin("java", 12345L, null),
"php", new ScannerPlugin("php", 45678L, null)));
@@ -154,28 +152,6 @@ public class MetadataPublisherTest {
.build()));
}

@Test
public void write_project_branch() throws Exception {
when(cpdSettings.isCrossProjectDuplicationEnabled()).thenReturn(false);

ProjectDefinition projectDef = ProjectDefinition.create()
.setKey("foo")
.setProperty(CoreProperties.PROJECT_BRANCH_PROPERTY, "myBranch");
createPublisher(projectDef);

File outputDir = temp.newFolder();
ScannerReportWriter writer = new ScannerReportWriter(outputDir);

underTest.publish(writer);

ScannerReportReader reader = new ScannerReportReader(outputDir);
ScannerReport.Metadata metadata = reader.readMetadata();
assertThat(metadata.getAnalysisDate()).isEqualTo(1234567L);
assertThat(metadata.getProjectKey()).isEqualTo("root");
assertThat(metadata.getDeprecatedBranch()).isEqualTo("myBranch");
assertThat(metadata.getCrossProjectDuplicationActivated()).isFalse();
}

@Test
public void write_project_organization() throws Exception {
when(properties.organizationKey()).thenReturn(Optional.of("SonarSource"));

+ 2
- 2
sonar-scanner-engine/src/test/java/org/sonar/scanner/repository/ProjectRepositoriesSupplierTest.java View File

@@ -47,7 +47,7 @@ public class ProjectRepositoriesSupplierTest {
underTest = new ProjectRepositoriesSupplier(loader, props, branchConfiguration);
Map<String, FileData> fileMap = Maps.newHashMap();
project = new SingleProjectRepository(fileMap);
when(props.getKeyWithBranch()).thenReturn("key");
when(props.getProjectKey()).thenReturn("key");
}

@Test
@@ -63,7 +63,7 @@ public class ProjectRepositoriesSupplierTest {

assertThat(repo.exists()).isEqualTo(true);

verify(props).getKeyWithBranch();
verify(props).getProjectKey();
verify(loader).load(eq("key"), eq(null));
verifyNoMoreInteractions(loader, props);
}

+ 1
- 1
sonar-scanner-engine/src/test/java/org/sonar/scanner/repository/QualityProfileProviderTest.java View File

@@ -54,7 +54,7 @@ public class QualityProfileProviderTest {
public void setUp() {
qualityProfileProvider = new QualityProfilesProvider();

when(props.getKeyWithBranch()).thenReturn("project");
when(props.getProjectKey()).thenReturn("project");

response = new ArrayList<>(1);
response.add(QualityProfile.newBuilder().setKey("profile").setName("profile").setLanguage("lang").setRulesUpdatedAt(DateUtils.formatDateTime(new Date())).build());

+ 1
- 1
sonar-scanner-engine/src/test/java/org/sonar/scanner/repository/settings/DefaultProjectSettingsLoaderTest.java View File

@@ -61,7 +61,7 @@ public class DefaultProjectSettingsLoaderTest {
out.close();
when(response.contentStream()).thenReturn(in);
when(wsClient.call(any())).thenReturn(response);
when(properties.getKeyWithBranch()).thenReturn("project_key");
when(properties.getProjectKey()).thenReturn("project_key");

Map<String, String> result = underTest.loadProjectSettings();


+ 1
- 7
sonar-scanner-engine/src/test/java/org/sonar/scanner/scan/ModuleIndexerTest.java View File

@@ -33,10 +33,9 @@ import static org.mockito.Mockito.when;
public class ModuleIndexerTest {
private ModuleIndexer indexer;
private DefaultInputModuleHierarchy moduleHierarchy;
private InputComponentStore componentStore;

public void createIndexer() {
componentStore = new InputComponentStore(mock(BranchConfiguration.class));
InputComponentStore componentStore = new InputComponentStore(mock(BranchConfiguration.class));
moduleHierarchy = mock(DefaultInputModuleHierarchy.class);
indexer = new ModuleIndexer(componentStore, moduleHierarchy);
}
@@ -58,11 +57,6 @@ public class ModuleIndexerTest {
when(mod2.key()).thenReturn("mod2");
when(mod3.key()).thenReturn("mod3");

when(root.getKeyWithBranch()).thenReturn("root");
when(mod1.getKeyWithBranch()).thenReturn("mod1");
when(mod2.getKeyWithBranch()).thenReturn("mod2");
when(mod3.getKeyWithBranch()).thenReturn("mod3");

when(root.definition()).thenReturn(rootDef);
when(mod1.definition()).thenReturn(def);
when(mod2.definition()).thenReturn(def);

+ 0
- 44
sonar-scanner-engine/src/test/java/org/sonar/scanner/scan/ProjectReactorValidatorTest.java View File

@@ -94,45 +94,6 @@ public class ProjectReactorValidatorTest {
underTest.validate(reactor);
}

@Test
@UseDataProvider("validBranches")
public void not_fail_with_valid_branch(String validBranch) {
ProjectReactor reactor = createProjectReactor("foo", validBranch);

underTest.validate(reactor);
}

@DataProvider
public static Object[][] validBranches() {
return new Object[][] {
{"branch"},
{"Branch2"},
{"bra.nch"},
{"bra-nch"},
{"1"},
{"bra_nch"}
};
}

@Test
@UseDataProvider("invalidBranches")
public void fail_with_invalid_branch(String invalidBranch) {
ProjectReactor reactor = createProjectReactor("foo", invalidBranch);

thrown.expect(MessageException.class);
thrown.expectMessage("\"" + invalidBranch + "\" is not a valid branch name");

underTest.validate(reactor);
}

@DataProvider
public static Object[][] invalidBranches() {
return new Object[][] {
{"bran#ch"},
{"bran:ch"}
};
}

@Test
public void fail_when_branch_name_is_specified_but_branch_plugin_not_present() {
ProjectDefinition def = ProjectDefinition.create().setProperty(CoreProperties.PROJECT_KEY_PROPERTY, "foo");
@@ -234,11 +195,6 @@ public class ProjectReactorValidatorTest {
};
}

private ProjectReactor createProjectReactor(String projectKey, String branch) {
return createProjectReactor(projectKey, def -> def
.setProperty(CoreProperties.PROJECT_BRANCH_PROPERTY, branch));
}

private ProjectReactor createProjectReactor(String projectKey, Consumer<ProjectDefinition>... consumers) {
ProjectDefinition def = ProjectDefinition.create()
.setProperty(CoreProperties.PROJECT_KEY_PROPERTY, projectKey);

+ 10
- 5
sonar-scanner-engine/src/test/java/org/sonar/scanner/scan/branch/ProjectBranchesProviderTest.java View File

@@ -21,9 +21,9 @@ package org.sonar.scanner.scan.branch;

import org.junit.Before;
import org.junit.Test;
import org.sonar.scanner.bootstrap.ProcessedScannerProperties;

import static org.assertj.core.api.Assertions.assertThat;
import static org.mockito.ArgumentMatchers.anyString;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.when;

@@ -31,30 +31,35 @@ public class ProjectBranchesProviderTest {
private ProjectBranchesProvider provider = new ProjectBranchesProvider();
private ProjectBranchesLoader mockLoader;
private ProjectBranches mockBranches;
private ProcessedScannerProperties scannerProperties;

@Before
public void setUp() {
mockLoader = mock(ProjectBranchesLoader.class);
mockBranches = mock(ProjectBranches.class);
scannerProperties = mock(ProcessedScannerProperties.class);

}

@Test
public void should_cache_branches() {
ProjectBranches branches = provider.provide(null, () -> "project");
assertThat(provider.provide(null, () -> "project")).isSameAs(branches);
when(scannerProperties.getProjectKey()).thenReturn("project");
ProjectBranches branches = provider.provide(null, scannerProperties);
assertThat(provider.provide(null, scannerProperties)).isSameAs(branches);
}

@Test
public void should_use_loader() {
when(scannerProperties.getProjectKey()).thenReturn("key");
when(mockLoader.load("key")).thenReturn(mockBranches);
ProjectBranches branches = provider.provide(mockLoader, () -> "key");
ProjectBranches branches = provider.provide(mockLoader, scannerProperties);

assertThat(branches).isSameAs(mockBranches);
}

@Test
public void should_return_default_if_no_loader() {
ProjectBranches branches = provider.provide(null, () -> "project");
ProjectBranches branches = provider.provide(null, scannerProperties);
assertThat(branches.isEmpty()).isTrue();
}
}

+ 10
- 4
sonar-scanner-engine/src/test/java/org/sonar/scanner/scan/branch/ProjectPullRequestsProviderTest.java View File

@@ -21,6 +21,7 @@ package org.sonar.scanner.scan.branch;

import org.junit.Before;
import org.junit.Test;
import org.sonar.scanner.bootstrap.ProcessedScannerProperties;

import static java.util.Collections.emptyList;
import static org.assertj.core.api.Assertions.assertThat;
@@ -31,32 +32,37 @@ public class ProjectPullRequestsProviderTest {
private ProjectPullRequestsProvider provider = new ProjectPullRequestsProvider();
private ProjectPullRequestsLoader mockLoader;
private ProjectPullRequests pullRequests;
private ProcessedScannerProperties scannerProperties;

@Before
public void setUp() {
mockLoader = mock(ProjectPullRequestsLoader.class);
pullRequests = new ProjectPullRequests(emptyList());
scannerProperties = mock(ProcessedScannerProperties.class);
}

@Test
public void cache_pull_requests() {
ProjectPullRequests pullRequests = provider.provide(null, () -> "project");
when(scannerProperties.getProjectKey()).thenReturn("project");
ProjectPullRequests pullRequests = provider.provide(null, scannerProperties);

assertThat(provider.provide(null, () -> "project")).isSameAs(pullRequests);
assertThat(provider.provide(null, scannerProperties)).isSameAs(pullRequests);
}

@Test
public void should_use_loader() {
when(scannerProperties.getProjectKey()).thenReturn("key");
when(mockLoader.load("key")).thenReturn(pullRequests);

ProjectPullRequests result = provider.provide(mockLoader, () -> "key");
ProjectPullRequests result = provider.provide(mockLoader, scannerProperties);

assertThat(result).isSameAs(pullRequests);
}

@Test
public void should_return_default_if_no_loader() {
ProjectPullRequests result = provider.provide(null, () -> "project");
when(scannerProperties.getProjectKey()).thenReturn("project");
ProjectPullRequests result = provider.provide(null, scannerProperties);

assertThat(result.isEmpty()).isTrue();
}

+ 11
- 10
sonar-scanner-protocol/src/main/protobuf/scanner_report.proto View File

@@ -33,8 +33,9 @@ message Metadata {
string organization_key = 2;
// TODO should we keep this project_key here or not ? Because it's a duplication of Component.key
string project_key = 3;
// maps the property sonar.branch
string deprecated_branch = 4;

reserved 4; // deprecated_branch (legacy branches feature)

int32 root_component_ref = 5;
bool cross_project_duplication_activated = 6;
map<string, QProfile> qprofiles_per_language = 7;
@@ -61,7 +62,7 @@ message Metadata {
string language = 3;
int64 rulesUpdatedAt = 4;
}
message Plugin {
string key = 1;
int64 updatedAt = 2;
@@ -93,7 +94,7 @@ message ActiveRule {
message ComponentLink {
ComponentLinkType type = 1;
string href = 2;
enum ComponentLinkType {
UNSET = 0;
HOME = 1;
@@ -151,27 +152,27 @@ message Measure {
DoubleValue double_value = 5;
StringValue string_value = 6;
}
message BoolValue {
bool value = 1;
string data = 2;
}
message IntValue {
int32 value = 1;
string data = 2;
}
message LongValue {
int64 value = 1;
string data = 2;
}
message DoubleValue {
double value = 1;
string data = 2;
}
message StringValue {
string value = 1;
}
@@ -310,7 +311,7 @@ message LineCoverage {
message SyntaxHighlightingRule {
TextRange range = 1;
HighlightingType type = 2;
enum HighlightingType {
UNSET = 0;
ANNOTATION = 1;

Loading…
Cancel
Save