Skip to content

Commit

Permalink
#1: Only error when no branches exist and non-master branch specified
Browse files Browse the repository at this point in the history
SonarQube returns an empty branch list if the project doesn't already exist, which results in an error being thrown telling the user to re-run the scan with no branch parameters set, even if no branch analysis parameters were specified. However, when a project is created through the Web interface, SonarQube automatically creates a default branch named `master` which the scanner picks up as the primary branch and targets if no other parameters are specified. This inconsistency means users can't have SonarQube automatically create projects, but have to use the Web interface to set-up any projects first.

To make the setup consistent, the check for no branches existing is extended to also check if any of the branch parameters have also been specified. This way, if no branches exist but no branch parameters were specified then a `DefaultBranchConfiguration` instance is returned which points the analysis at the a default `master` branch which SonarQube will automatically create. Similarly, if no branches exist but a source branch of master is specified then a `DefaultBranchConfiguration` is also returned, providing a target branch either isn't specified or also points at master.
  • Loading branch information
mc1arke authored Mar 27, 2019
1 parent 409c4ad commit d02f248
Show file tree
Hide file tree
Showing 2 changed files with 101 additions and 6 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
*/
package com.github.mc1arke.sonarqube.plugin.scanner;

import org.apache.commons.lang.StringUtils;
import org.sonar.api.CoreProperties;
import org.sonar.api.utils.MessageException;
import org.sonar.core.config.ScannerProperties;
Expand Down Expand Up @@ -54,10 +55,14 @@ public class CommunityBranchConfigurationLoader implements BranchConfigurationLo
public BranchConfiguration load(Map<String, String> localSettings, Supplier<Map<String, String>> supplier,
ProjectBranches projectBranches, ProjectPullRequests projectPullRequests) {
if (projectBranches.isEmpty()) {
// it would be nice to identify the 'primary' branch directly, but different projects work differently: using any of master, develop, main etc as primary
// A project/global configuration entry could be used to drive this in the future, but the current documented SonarQube parameters need followed for now
throw MessageException
.of("No branches currently exist in this project. Please scan the main branch without passing any branch parameters.");
if (isTargetingDefaultBranch(localSettings)) {
return new DefaultBranchConfiguration();
} else {
// it would be nice to identify the 'primary' branch directly, but different projects work differently: using any of master, develop, main etc as primary
// A project/global configuration entry could be used to drive this in the future, but the current documented SonarQube parameters need followed for now
throw MessageException
.of("No branches currently exist in this project. Please scan the main branch without passing any branch parameters.");
}
}
if (BRANCH_ANALYSIS_PARAMETERS.stream().anyMatch(localSettings::containsKey)) {
return createBranchConfiguration(localSettings.get(ScannerProperties.BRANCH_NAME),
Expand All @@ -73,6 +78,13 @@ public BranchConfiguration load(Map<String, String> localSettings, Supplier<Map<
return new DefaultBranchConfiguration();
}

private static boolean isTargetingDefaultBranch(Map<String, String> localSettings) {
String name = StringUtils.trimToNull(localSettings.get(ScannerProperties.BRANCH_NAME));
String target = StringUtils.trimToNull(localSettings.get(ScannerProperties.BRANCH_TARGET));

return (null == name || "master".equals(name)) && (null == target || target.equals(name));
}

private static BranchConfiguration createBranchConfiguration(String branchName, String branchTarget,
Supplier<Map<String, String>> settingsSupplier,
ProjectBranches branches) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -58,16 +58,99 @@ public ExpectedException expectedException() {
}

@Test
public void testExceptionWhenNoExistingBranch() {
public void testExceptionWhenNoExistingBranchAndBranchParamsPresent() {
CommunityBranchConfigurationLoader testCase = new CommunityBranchConfigurationLoader();
ProjectBranches branchInfo = mock(ProjectBranches.class);
when(branchInfo.isEmpty()).thenReturn(true);

Map<String, String> parameters = new HashMap<>();
parameters.put("sonar.branch.name", "dummy");

expectedException.expect(MessageException.class);
expectedException.expectMessage(IsEqual.equalTo(
"No branches currently exist in this project. Please scan the main branch without passing any branch parameters."));

testCase.load(parameters, supplier, branchInfo, mock(ProjectPullRequests.class));
}

@Test
public void testDefaultConfigWhenNoExistingBranchAndBranchNameParamMaster() {
CommunityBranchConfigurationLoader testCase = new CommunityBranchConfigurationLoader();
ProjectBranches branchInfo = mock(ProjectBranches.class);
when(branchInfo.isEmpty()).thenReturn(true);

Map<String, String> parameters = new HashMap<>();
parameters.put("sonar.branch.name", "master");

assertEquals(DefaultBranchConfiguration.class,
testCase.load(parameters, supplier, branchInfo, mock(ProjectPullRequests.class)).getClass());
}

@Test
public void testErrorWhenNoExistingBranchAndBranchTargetMasterButNoSourceBranch() {
CommunityBranchConfigurationLoader testCase = new CommunityBranchConfigurationLoader();
ProjectBranches branchInfo = mock(ProjectBranches.class);
when(branchInfo.isEmpty()).thenReturn(true);

Map<String, String> parameters = new HashMap<>();
parameters.put("sonar.branch.source", null);
parameters.put("sonar.branch.target", "master");


expectedException.expect(MessageException.class);
expectedException.expectMessage(IsEqual.equalTo(
"No branches currently exist in this project. Please scan the main branch without passing any branch parameters."));

testCase.load(parameters, supplier, branchInfo, mock(ProjectPullRequests.class));
}


@Test
public void testDefaultConfigWhenNoExistingBranchAndBranchParamsAllMaster() {
CommunityBranchConfigurationLoader testCase = new CommunityBranchConfigurationLoader();
ProjectBranches branchInfo = mock(ProjectBranches.class);
when(branchInfo.isEmpty()).thenReturn(true);

Map<String, String> parameters = new HashMap<>();
parameters.put("sonar.branch.name", "master");
parameters.put("sonar.branch.target", "master");

assertEquals(DefaultBranchConfiguration.class,
testCase.load(parameters, supplier, branchInfo, mock(ProjectPullRequests.class)).getClass());
}

@Test
public void testExceptionWhenNoExistingBranchAndPullRequestAndBranchParametersPresent() {
CommunityBranchConfigurationLoader testCase = new CommunityBranchConfigurationLoader();
ProjectBranches branchInfo = mock(ProjectBranches.class);
when(branchInfo.isEmpty()).thenReturn(true);


Map<String, String> parameters = new HashMap<>();
parameters.put("sonar.branch.name", "dummy");
parameters.put("sonar.pullrequest.branch", "dummy2");


expectedException.expect(MessageException.class);
expectedException.expectMessage(IsEqual.equalTo(
"No branches currently exist in this project. Please scan the main branch without passing any branch parameters."));

testCase.load(new HashMap<>(), supplier, branchInfo, mock(ProjectPullRequests.class));
testCase.load(parameters, supplier, branchInfo, mock(ProjectPullRequests.class));
}

@Test
public void testDefaultBranchInfoWhenNoBranchParametersSpecifiedAndNoBranchesExist() {
CommunityBranchConfigurationLoader testCase = new CommunityBranchConfigurationLoader();

ProjectBranches branchInfo = mock(ProjectBranches.class);
when(branchInfo.isEmpty()).thenReturn(true);

Map<String, String> parameters = new HashMap<>();
parameters.put("dummy", "dummy");


assertEquals(DefaultBranchConfiguration.class,
testCase.load(parameters, supplier, branchInfo, mock(ProjectPullRequests.class)).getClass());
}

@Test
Expand Down

0 comments on commit d02f248

Please sign in to comment.