dependency 'org.postgresql:postgresql:42.2.5'
dependency 'org.reflections:reflections:0.9.9'
dependency 'org.simpleframework:simple:4.1.21'
- dependency 'org.sonarsource.orchestrator:sonar-orchestrator:3.24.0.1993'
+ dependency 'org.sonarsource.orchestrator:sonar-orchestrator:3.25.0.2071'
dependency 'org.sonarsource.update-center:sonar-update-center-common:1.18.0.487'
dependency 'org.subethamail:subethasmtp:3.1.7'
dependency 'xml-apis:xml-apis:1.4.01'
| ![](/images/cross.svg) These parameters are listed for completeness, but are deprecated and should not be used in new analyses.
Key | Description
----|----|---
-`sonar.branch` **![](/images/cross.svg)Deprecated since SQ 6.7** | _The Developer Edition provides fuller-featured branch functionality._ Manage SCM branches. Two branches of the same project are considered to be different projects in SonarQube. As a consequence issues found in a project A in a branch B1 are not linked to issues found for this project A in a branch B2. There is no way to automatically resolve issues from B2 when they are resolved in B1 as again A-B1 & A-B2 are considered separated projects.
+---|----|---
`sonar.links.scm_dev` **![](/images/cross.svg)Deprecated since SQ 7.1** | Developer connection. | `<scm><developerConnection>` for Maven projects
<!-- /sonarqube -->
## What if I mark an Issue "Won't Fix" or "False-Positive" in a branch?
It be replicated as such when merging my short-lived branch into the Master. Each time there is an analysis of a long-lived branch, we look at the issues on the short-lived branches and try to synchronize them with the newly raised issues on the long-lived branch. In case you made some changes on the issues (false-positive, won't fix), these changes will be reported on the long-lived branch.
-## Can I still use 'sonar.branch'?
-`sonar.branch` is deprecated. You can still use it but it will behave the same way it always has: a separate project will be created. We encourage you to smoothly migrate your users to the new parameter `sonar.branch.name`.
-Please note you cannot use `sonar.branch` together with `sonar.branch.name`.
-
## Can I manually delete a branch?
This can be achieved by going into the Administration menu at Project's level, then Branches.
.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");
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) {
import org.sonar.api.SonarEdition;
import org.sonar.api.SonarQubeSide;
import org.sonar.api.SonarQubeVersion;
+import org.sonar.api.SonarRuntime;
import org.sonar.api.internal.MetadataLoader;
import org.sonar.api.internal.SonarRuntimeImpl;
import org.sonar.api.utils.MessageException;
PluginClassloaderFactory.class,
ScannerPluginJarExploder.class,
ExtensionInstaller.class,
-
new SonarQubeVersion(apiVersion),
- SonarRuntimeImpl.forSonarQube(apiVersion, SonarQubeSide.SCANNER, edition),
new GlobalServerSettingsProvider(),
new GlobalConfigurationProvider(),
new ScannerWsClientProvider(),
Clock.systemDefaultZone(),
new MetricsRepositoryProvider(),
UuidFactoryImpl.INSTANCE);
+ addIfMissing(SonarRuntimeImpl.forSonarQube(apiVersion, SonarQubeSide.SCANNER, edition), SonarRuntime.class);
addIfMissing(ScannerPluginInstaller.class, PluginInstaller.class);
add(CoreExtensionRepositoryImpl.class, CoreExtensionsLoader.class, ScannerCoreExtensionsInstaller.class);
addIfMissing(DefaultGlobalSettingsLoader.class, GlobalSettingsLoader.class);
if (!analysisMode.equals("publish")) {
throw MessageException.of("The preview mode, along with the 'sonar.analysis.mode' parameter, is no more supported. You should stop using this parameter.");
}
-
new ProjectScanContainer(this).execute();
LOG.info("Analysis total time: {}", formatTime(System.currentTimeMillis() - startTime));
import com.google.common.annotations.VisibleForTesting;
import javax.annotation.Nullable;
+import org.sonar.api.SonarEdition;
+import org.sonar.api.SonarRuntime;
import org.sonar.api.batch.fs.internal.DefaultInputModule;
import org.sonar.api.batch.fs.internal.FileMetadata;
import org.sonar.api.batch.fs.internal.InputModuleHierarchy;
import org.sonar.api.resources.Languages;
import org.sonar.api.resources.ResourceTypes;
import org.sonar.api.scan.filesystem.PathResolver;
+import org.sonar.api.utils.MessageException;
import org.sonar.api.utils.log.Logger;
import org.sonar.api.utils.log.Loggers;
import org.sonar.core.config.ScannerProperties;
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));
-
- 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);
+ 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.");
+ });
}
BranchConfiguration branchConfig = getComponentByType(BranchConfiguration.class);
return configuration.get(BRANCH_NAME);
}
+ public Optional<String> get(String propertyKey) {
+ return configuration.get(propertyKey);
+ }
+
public Path metadataFilePath() {
Optional<String> metadataFilePath = configuration.get(METADATA_FILE_PATH_KEY);
if (metadataFilePath.isPresent()) {
import org.apache.commons.io.FileUtils;
import org.junit.rules.ExternalResource;
import org.sonar.api.Plugin;
+import org.sonar.api.SonarEdition;
+import org.sonar.api.SonarProduct;
+import org.sonar.api.SonarQubeSide;
+import org.sonar.api.SonarRuntime;
import org.sonar.api.measures.CoreMetrics;
import org.sonar.api.measures.Metric;
import org.sonar.api.rule.RuleKey;
import org.sonar.api.server.rule.RulesDefinition;
import org.sonar.api.server.rule.RulesDefinition.Repository;
import org.sonar.api.utils.DateUtils;
+import org.sonar.api.utils.Version;
import org.sonar.batch.bootstrapper.Batch;
import org.sonar.batch.bootstrapper.EnvironmentInformation;
import org.sonar.batch.bootstrapper.LogOutput;
private final FakeRulesLoader rulesLoader = new FakeRulesLoader();
private final FakeQualityProfileLoader qualityProfiles = new FakeQualityProfileLoader();
private final FakeActiveRulesLoader activeRules = new FakeActiveRulesLoader();
+ private final FakeSonarRuntime sonarRuntime = new FakeSonarRuntime();
private LogOutput logOutput = null;
private static void createWorkingDirs() throws IOException {
}
@Override
- protected void before() throws Throwable {
+ protected void before() {
try {
createWorkingDirs();
} catch (IOException e) {
tester.activeRules,
tester.globalSettingsLoader,
tester.projectSettingsLoader,
+ tester.sonarRuntime,
result)
.setLogOutput(tester.logOutput)
.build().execute();
}
}
+ private static class FakeSonarRuntime implements SonarRuntime {
+
+ private SonarEdition edition;
+
+ FakeSonarRuntime() {
+ this.edition = SonarEdition.COMMUNITY;
+ }
+
+ @Override
+ public Version getApiVersion() {
+ return Version.create(7, 8);
+ }
+
+ @Override
+ public SonarProduct getProduct() {
+ return SonarProduct.SONARQUBE;
+ }
+
+ @Override
+ public SonarQubeSide getSonarQubeSide() {
+ return SonarQubeSide.SCANNER;
+ }
+
+ @Override
+ public SonarEdition getEdition() {
+ return edition;
+ }
+
+ public void setEdition(SonarEdition edition) {
+ this.edition = edition;
+ }
+ }
+
public ScannerMediumTester setBranchType(BranchType branchType) {
branchConfiguration.branchType = branchType;
return this;
return this;
}
+ public ScannerMediumTester setEdition(SonarEdition edition) {
+ this.sonarRuntime.setEdition(edition);
+ return this;
+ }
+
private class FakeBranchConfigurationLoader implements BranchConfigurationLoader {
@Override
public BranchConfiguration load(Map<String, String> localSettings, Supplier<Map<String, String>> settingsSupplier, ProjectBranches branches, ProjectPullRequests pullRequests) {
import org.junit.Test;
import org.junit.rules.ExpectedException;
import org.junit.rules.TemporaryFolder;
+import org.sonar.api.SonarEdition;
import org.sonar.api.batch.fs.internal.DefaultInputFile;
-import org.sonar.scanner.mediumtest.ScannerMediumTester;
+import org.sonar.api.utils.MessageException;
import org.sonar.scanner.mediumtest.AnalysisResult;
+import org.sonar.scanner.mediumtest.ScannerMediumTester;
import org.sonar.xoo.XooPlugin;
import org.sonar.xoo.rule.XooRulesDefinition;
.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;
}
@Test
- public void scanProjectWithBranch() throws IOException {
+ public void scanProjectWithBranchOnSonarQube() throws IOException {
+ File srcDir = new File(baseDir, "src");
+ srcDir.mkdir();
+
+ File xooFile = new File(srcDir, "sample.xoo");
+ FileUtils.write(xooFile, "Sample xoo\ncontent");
+
+ thrown.expect(MessageException.class);
+ thrown.expectMessage("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.");
+
+ tester.newAnalysis()
+ .properties(ImmutableMap.<String, String>builder()
+ .putAll(commonProps)
+ .put("sonar.branch", "branch")
+ .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 = tester.newAnalysis()
+ AnalysisResult result = testerSC.newAnalysis()
.properties(ImmutableMap.<String, String>builder()
.putAll(commonProps)
.put("sonar.branch", "branch")
assertThat(result.getReportReader().readMetadata().getDeprecatedBranch()).isEqualTo("branch");
- result = tester.newAnalysis()
+ result = testerSC.newAnalysis()
.properties(ImmutableMap.<String, String>builder()
.putAll(commonProps)
.put("sonar.branch", "")
}
@Test
- public void scanMultiModuleWithBranch() throws IOException {
+ 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 = tester.newAnalysis()
+ AnalysisResult result = testerSC.newAnalysis()
.properties(ImmutableMap.<String, String>builder()
.putAll(commonProps)
.put("sonar.branch", "branch")
assertThat(result.getReportReader().readMetadata().getDeprecatedBranch()).isEqualTo("branch");
- result = tester.newAnalysis()
+ result = testerSC.newAnalysis()
.properties(ImmutableMap.<String, String>builder()
.putAll(commonProps)
.put("sonar.branch", "")
import org.junit.rules.ExpectedException;
import org.junit.rules.TemporaryFolder;
import org.sonar.api.CoreProperties;
+import org.sonar.api.SonarEdition;
import org.sonar.api.batch.fs.InputFile;
import org.sonar.api.batch.fs.internal.DefaultInputFile;
import org.sonar.api.utils.MessageException;
@Rule
public ScannerMediumTester tester = new ScannerMediumTester()
+ .setEdition(SonarEdition.SONARCLOUD)
.registerPlugin("xoo", new XooPlugin())
.addDefaultQProfile("xoo", "Sonar Way")
.addDefaultQProfile("xoo2", "Sonar Way");
}
@Test
- public void logBranchNameAndType() throws IOException {
+ public void logBranchNameAndType() {
builder.put("sonar.branch.name", "my-branch");
File srcDir = new File(baseDir, "src");
assertThat(srcDir.mkdir()).isTrue();
.execute();
assertThat(result.inputFiles()).hasSize(1);
- assertThat(logTester.logs(LoggerLevel.WARN)).contains("File '" + xooFile2.getAbsolutePath() + "' is ignored. It is not located in module basedir '" + new File(baseDir, "moduleA") + "'.");
+ assertThat(logTester.logs(LoggerLevel.WARN))
+ .contains("File '" + xooFile2.getAbsolutePath() + "' is ignored. It is not located in module basedir '" + new File(baseDir, "moduleA") + "'.");
}
@Test
import org.junit.Test;
import org.junit.rules.ExpectedException;
import org.junit.rules.TemporaryFolder;
+import org.sonar.api.SonarEdition;
import org.sonar.api.batch.bootstrap.ProjectBuilder;
import org.sonar.api.utils.MessageException;
import org.sonar.scanner.mediumtest.AnalysisResult;
@Rule
public ScannerMediumTester tester = new ScannerMediumTester()
+ .setEdition(SonarEdition.SONARCLOUD)
.registerPlugin("xoo", new XooPluginWithBuilder(projectBuilder))
.addRules(new XooRulesDefinition())
.addDefaultQProfile("xoo", "Sonar Way")
import org.junit.Test;
import org.junit.rules.ExpectedException;
import org.junit.rules.TemporaryFolder;
+import org.sonar.api.SonarEdition;
import org.sonar.api.utils.log.LogTester;
import org.sonar.scanner.mediumtest.ScannerMediumTester;
import org.sonar.scanner.mediumtest.ScannerMediumTester.AnalysisBuilder;
@Rule
public ScannerMediumTester tester = new ScannerMediumTester()
+ .setEdition(SonarEdition.SONARCLOUD)
.registerPlugin("xoo", new XooPlugin())
.addDefaultQProfile("xoo", "Sonar Way")
.addRules(new XooRulesDefinition())