public class ScannerProperties {
+ public static final String BRANCHES_DOC_LINK = "https://redirect.sonarsource.com/doc/branches.html";
+
public static final String BRANCH_NAME = "sonar.branch.name";
public static final String BRANCH_TARGET = "sonar.branch.target";
public static final String ORGANIZATION = "sonar.organization";
import com.google.common.base.Joiner;
import java.util.ArrayList;
+import java.util.Arrays;
import java.util.List;
import javax.annotation.Nullable;
import org.apache.commons.lang.StringUtils;
import org.sonar.api.batch.bootstrap.ProjectReactor;
import org.sonar.api.utils.MessageException;
import org.sonar.core.component.ComponentKeys;
+import org.sonar.core.config.ScannerProperties;
+import org.sonar.scanner.bootstrap.GlobalConfiguration;
import org.sonar.scanner.scan.branch.BranchParamsValidator;
-import org.sonar.scanner.scan.branch.DefaultBranchParamsValidator;
/**
* This class aims at validating project reactor
*/
public class ProjectReactorValidator {
private final AnalysisMode mode;
+ private final GlobalConfiguration settings;
+
+ // null = branch plugin is not available
+ @Nullable
private final BranchParamsValidator branchParamsValidator;
- public ProjectReactorValidator(AnalysisMode mode, BranchParamsValidator branchParamsValidator) {
+ public ProjectReactorValidator(AnalysisMode mode, GlobalConfiguration settings, @Nullable BranchParamsValidator branchParamsValidator) {
this.mode = mode;
+ this.settings = settings;
this.branchParamsValidator = branchParamsValidator;
}
- public ProjectReactorValidator(AnalysisMode mode) {
- this(mode, new DefaultBranchParamsValidator());
+ public ProjectReactorValidator(AnalysisMode mode, GlobalConfiguration settings) {
+ this(mode, settings, null);
}
public void validate(ProjectReactor reactor) {
String deprecatedBranchName = reactor.getRoot().getBranch();
- branchParamsValidator.validate(validationMessages, deprecatedBranchName);
+ if (branchParamsValidator != null) {
+ // branch plugin is present
+ branchParamsValidator.validate(validationMessages, deprecatedBranchName);
+ } else {
+ validateBranchParamsWhenPluginAbsent(validationMessages);
+ }
+
validateBranch(validationMessages, deprecatedBranchName);
if (!validationMessages.isEmpty()) {
}
}
+ private void validateBranchParamsWhenPluginAbsent(List<String> validationMessages) {
+ for (String param : Arrays.asList(ScannerProperties.BRANCH_NAME, ScannerProperties.BRANCH_TARGET)) {
+ if (StringUtils.isNotEmpty(settings.get(param).orElse(null))) {
+ validationMessages.add(String.format("To use the property \"%s\", the branch plugin is required but not installed. "
+ + "See the documentation of branch support: %s.", param, ScannerProperties.BRANCHES_DOC_LINK));
+ }
+ }
+ }
+
private static void validateModuleIssuesMode(ProjectDefinition moduleDef, List<String> validationMessages) {
if (!ComponentKeys.isValidModuleKeyIssuesMode(moduleDef.getKey())) {
validationMessages.add(String.format("\"%s\" is not a valid project or module key. "
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 \"sonar.branch.name\". See https://redirect.sonarsource.com/doc/branches.html.");
+ LOG.warn("The use of \"sonar.branch\" is deprecated and replaced by \"{}\". See {}.",
+ ScannerProperties.BRANCH_NAME, ScannerProperties.BRANCHES_DOC_LINK);
}
String branchName = props.property(ScannerProperties.BRANCH_NAME);
File srcDir = new File(baseDir, "src");
assertThat(srcDir.mkdir()).isTrue();
+ // Using sonar.branch.name when the branch plugin is not installed is an error.
+ // IllegalStateException is expected here, because this test is in a bit artificial,
+ // the fail-fast mechanism in the scanner should have prevented reaching this point.
+ thrown.expect(IllegalStateException.class);
+
tester.newTask()
.properties(builder
.put("sonar.sources", "src")
.build())
.execute();
-
- assertThat(logs.getAllAsString()).contains("Project key: com.foo.project");
- assertThat(logs.getAllAsString()).contains("Branch name: my-branch, type: long living");
}
@Test
*/
package org.sonar.scanner.scan;
+import java.util.Optional;
import org.junit.Before;
import org.junit.Rule;
import org.junit.Test;
import org.sonar.api.batch.bootstrap.ProjectDefinition;
import org.sonar.api.batch.bootstrap.ProjectReactor;
import org.sonar.api.utils.MessageException;
+import org.sonar.core.config.ScannerProperties;
+import org.sonar.scanner.bootstrap.GlobalConfiguration;
+import static org.mockito.Matchers.anyString;
+import static org.mockito.Matchers.eq;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.when;
private AnalysisMode mode;
private ProjectReactorValidator validator;
+ private GlobalConfiguration settings;
@Before
public void prepare() {
mode = mock(AnalysisMode.class);
- validator = new ProjectReactorValidator(mode);
+ settings = mock(GlobalConfiguration.class);
+ when(settings.get(anyString())).thenReturn(Optional.empty());
+ validator = new ProjectReactorValidator(mode, settings);
}
@Test
validator.validate(reactor);
}
+ @Test
+ public void fail_when_branch_name_is_specified_but_branch_plugin_not_present() {
+ ProjectDefinition def = ProjectDefinition.create().setProperty(CoreProperties.PROJECT_KEY_PROPERTY, "foo");
+ ProjectReactor reactor = new ProjectReactor(def);
+
+ when(settings.get(eq(ScannerProperties.BRANCH_NAME))).thenReturn(Optional.of("feature1"));
+
+ thrown.expect(MessageException.class);
+ thrown.expectMessage("the branch plugin is required but not installed");
+
+ validator.validate(reactor);
+ }
+
+ @Test
+ public void fail_when_branch_target_is_specified_but_branch_plugin_not_present() {
+ ProjectDefinition def = ProjectDefinition.create().setProperty(CoreProperties.PROJECT_KEY_PROPERTY, "foo");
+ ProjectReactor reactor = new ProjectReactor(def);
+
+ when(settings.get(eq(ScannerProperties.BRANCH_TARGET))).thenReturn(Optional.of("feature1"));
+
+ thrown.expect(MessageException.class);
+ thrown.expectMessage("the branch plugin is required but not installed");
+
+ validator.validate(reactor);
+ }
+
private ProjectReactor createProjectReactor(String projectKey) {
ProjectDefinition def = ProjectDefinition.create().setProperty(CoreProperties.PROJECT_KEY_PROPERTY, projectKey);
ProjectReactor reactor = new ProjectReactor(def);