]> source.dussan.org Git - sonarqube.git/commitdiff
SONAR-12182 drop "sonar.branch" from SQ
authorMichal Duda <michal.duda@sonarsource.com>
Thu, 13 Jun 2019 15:27:43 +0000 (17:27 +0200)
committerSonarTech <sonartech@sonarsource.com>
Sat, 15 Jun 2019 18:21:05 +0000 (20:21 +0200)
13 files changed:
build.gradle
server/sonar-docs/src/pages/analysis/analysis-parameters.md
server/sonar-docs/src/pages/branches/branches-faq.md
server/sonar-server/src/main/java/org/sonar/server/project/ws/CreateAction.java
server/sonar-server/src/test/java/org/sonar/server/project/ws/CreateActionTest.java
sonar-scanner-engine/src/main/java/org/sonar/scanner/bootstrap/GlobalContainer.java
sonar-scanner-engine/src/main/java/org/sonar/scanner/scan/ProjectScanContainer.java
sonar-scanner-engine/src/main/java/org/sonar/scanner/scan/ScanProperties.java
sonar-scanner-engine/src/test/java/org/sonar/scanner/mediumtest/ScannerMediumTester.java
sonar-scanner-engine/src/test/java/org/sonar/scanner/mediumtest/branch/DeprecatedBranchMediumTest.java
sonar-scanner-engine/src/test/java/org/sonar/scanner/mediumtest/fs/FileSystemMediumTest.java
sonar-scanner-engine/src/test/java/org/sonar/scanner/mediumtest/fs/ProjectBuilderMediumTest.java
sonar-scanner-engine/src/test/java/org/sonar/scanner/mediumtest/scm/ScmMediumTest.java

index c2b993e2bdbe716c50624f1f156b6e0eb47c6bb3..aa04813445d1fe920fbb8bd25b6b30d343b03373 100644 (file)
@@ -236,7 +236,7 @@ subprojects {
       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'  
index 0c893b8108137ff49df6ee611895604df47648cf..03f1825b8a538a71577a9ad78fb0327a8af56e2c 100644 (file)
@@ -99,7 +99,6 @@ Key | Description | Default
 | ![](/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 -->
index ea6d8855a5e1762a5d9c58c565061a0af3ac0788..009839e45165541f6a051158f6618a6ea3c6f5fb 100644 (file)
@@ -21,10 +21,6 @@ No, you don't need to be connected to a SCM. But if you use Git or SVN we can be
 ## 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.
 
index 5f5877c402af151934a8848c2f2f8e9cd9afbd8f..490593a6e2bc7aceccfbfc2017e8b6edd79b7253 100644 (file)
@@ -93,6 +93,7 @@ public class CreateAction implements ProjectsWsAction {
       .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");
 
index ebae2a8d2078fb81f58a2912e1faa377eef8dad4..cddc20157bd518c2af2eb5ceed6723c167f7fe75 100644 (file)
@@ -392,6 +392,9 @@ 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) {
index 9b407ba2a3d02a3e1769a0d78eab2b4c9d18c124..e600bf3b3b75daa73fb3e2263bdae246cdaaf842 100644 (file)
@@ -28,6 +28,7 @@ import org.sonar.api.Plugin;
 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;
@@ -100,9 +101,7 @@ public class GlobalContainer extends ComponentContainer {
       PluginClassloaderFactory.class,
       ScannerPluginJarExploder.class,
       ExtensionInstaller.class,
-
       new SonarQubeVersion(apiVersion),
-      SonarRuntimeImpl.forSonarQube(apiVersion, SonarQubeSide.SCANNER, edition),
       new GlobalServerSettingsProvider(),
       new GlobalConfigurationProvider(),
       new ScannerWsClientProvider(),
@@ -115,6 +114,7 @@ public class GlobalContainer extends ComponentContainer {
       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);
@@ -138,7 +138,6 @@ public class GlobalContainer extends ComponentContainer {
     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));
index c9f85f3111d039a318eef29ac47f5519fc6fdeea..71ab90450b8222ca666c7f66b98de366bbdb6516 100644 (file)
@@ -21,6 +21,8 @@ package org.sonar.scanner.scan;
 
 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;
@@ -30,6 +32,7 @@ import org.sonar.api.issue.NoSonarFilter;
 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;
@@ -321,15 +324,22 @@ 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));
-
-    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);
index 1033292a4b863004a9a98d6816aca06b39651932..22a7751c0355379030248991fe71e30f3ecb1902 100644 (file)
@@ -66,6 +66,10 @@ public class ScanProperties {
     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()) {
index 28cb9ba3ed8b79b6cecf2753f74d3f50f4ccef22..2eb7a188e8ba9bd2b882a1e81ba054fea14e5560 100644 (file)
@@ -41,12 +41,17 @@ import javax.annotation.Nullable;
 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;
@@ -89,6 +94,7 @@ public class ScannerMediumTester extends ExternalResource {
   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 {
@@ -220,7 +226,7 @@ public class ScannerMediumTester extends ExternalResource {
   }
 
   @Override
-  protected void before() throws Throwable {
+  protected void before() {
     try {
       createWorkingDirs();
     } catch (IOException e) {
@@ -287,6 +293,7 @@ public class ScannerMediumTester extends ExternalResource {
           tester.activeRules,
           tester.globalSettingsLoader,
           tester.projectSettingsLoader,
+          tester.sonarRuntime,
           result)
         .setLogOutput(tester.logOutput)
         .build().execute();
@@ -404,6 +411,39 @@ public class ScannerMediumTester extends ExternalResource {
     }
   }
 
+  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;
@@ -424,6 +464,11 @@ public class ScannerMediumTester extends ExternalResource {
     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) {
index 41ea161bc72d773df39d139fd5caf96159d54f77..627e285af3a0710aa3fce7a4a9ad6de0245ebd7a 100644 (file)
@@ -31,9 +31,11 @@ import org.junit.Rule;
 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;
 
@@ -55,6 +57,15 @@ 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;
@@ -75,14 +86,34 @@ public class DeprecatedBranchMediumTest {
   }
 
   @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")
@@ -97,7 +128,7 @@ public class DeprecatedBranchMediumTest {
 
     assertThat(result.getReportReader().readMetadata().getDeprecatedBranch()).isEqualTo("branch");
 
-    result = tester.newAnalysis()
+    result = testerSC.newAnalysis()
       .properties(ImmutableMap.<String, String>builder()
         .putAll(commonProps)
         .put("sonar.branch", "")
@@ -109,14 +140,14 @@ public class DeprecatedBranchMediumTest {
   }
 
   @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")
@@ -133,7 +164,7 @@ public class DeprecatedBranchMediumTest {
 
     assertThat(result.getReportReader().readMetadata().getDeprecatedBranch()).isEqualTo("branch");
 
-    result = tester.newAnalysis()
+    result = testerSC.newAnalysis()
       .properties(ImmutableMap.<String, String>builder()
         .putAll(commonProps)
         .put("sonar.branch", "")
index af07368194464f9d6f20b909954e695866e74ea9..cb1537ae00ceb1efef742b34c50624603a51e505 100644 (file)
@@ -34,6 +34,7 @@ import org.junit.Test;
 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;
@@ -65,6 +66,7 @@ public class FileSystemMediumTest {
 
   @Rule
   public ScannerMediumTester tester = new ScannerMediumTester()
+    .setEdition(SonarEdition.SONARCLOUD)
     .registerPlugin("xoo", new XooPlugin())
     .addDefaultQProfile("xoo", "Sonar Way")
     .addDefaultQProfile("xoo2", "Sonar Way");
@@ -152,7 +154,7 @@ public class FileSystemMediumTest {
   }
 
   @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();
@@ -1065,7 +1067,8 @@ public class FileSystemMediumTest {
       .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
index f61411b4898cae23496005e3310809e4abfb8d66..b90b24d96e7648849b486efd8e6afef3865283a0 100644 (file)
@@ -30,6 +30,7 @@ import org.junit.Rule;
 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;
@@ -56,6 +57,7 @@ public class ProjectBuilderMediumTest {
 
   @Rule
   public ScannerMediumTester tester = new ScannerMediumTester()
+    .setEdition(SonarEdition.SONARCLOUD)
     .registerPlugin("xoo", new XooPluginWithBuilder(projectBuilder))
     .addRules(new XooRulesDefinition())
     .addDefaultQProfile("xoo", "Sonar Way")
index b317ac1c4cbc48aadfd0769946e6dc8d8297fcca..16d3e528e914b3fa8888deed88ed9d2a6aed35f4 100644 (file)
@@ -31,6 +31,7 @@ import org.junit.Rule;
 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;
@@ -64,6 +65,7 @@ public class ScmMediumTest {
 
   @Rule
   public ScannerMediumTester tester = new ScannerMediumTester()
+    .setEdition(SonarEdition.SONARCLOUD)
     .registerPlugin("xoo", new XooPlugin())
     .addDefaultQProfile("xoo", "Sonar Way")
     .addRules(new XooRulesDefinition())