import org.sonar.scanner.protocol.output.ScannerReport.Duplicate;
import org.sonar.scanner.protocol.output.ScannerReport.Duplication;
import org.sonar.scanner.report.ReportPublisher;
+import org.sonar.scanner.scan.BranchConfiguration;
+import org.sonar.scanner.scan.BranchConfiguration.BranchType;
import org.sonar.scanner.scan.filesystem.InputComponentStore;
import org.sonar.scanner.util.ProgressReport;
private final InputComponentStore componentStore;
private final ProgressReport progressReport;
private final CpdSettings settings;
+ private final BranchConfiguration branchConfiguration;
private int count;
private int total;
- public CpdExecutor(CpdSettings settings, SonarCpdBlockIndex index, ReportPublisher publisher, InputComponentStore inputComponentCache) {
+ public CpdExecutor(CpdSettings settings, SonarCpdBlockIndex index, ReportPublisher publisher, InputComponentStore inputComponentCache,
+ BranchConfiguration branchConfiguration) {
this.settings = settings;
this.index = index;
this.publisher = publisher;
this.componentStore = inputComponentCache;
+ this.branchConfiguration = branchConfiguration;
this.progressReport = new ProgressReport("CPD computation", TimeUnit.SECONDS.toMillis(10));
}
public void execute() {
+ if (branchConfiguration.branchType() == BranchType.SHORT) {
+ LOG.info("Skipping CPD calculation for short living branch");
+ return;
+ }
execute(TIMEOUT);
}
import org.sonar.api.resources.ResourceUtils;
import org.sonar.core.component.ComponentKeys;
import org.sonar.scanner.index.DefaultIndex;
+import org.sonar.scanner.scan.BranchConfiguration;
import org.sonar.scanner.sensor.DefaultSensorContext;
public class DeprecatedSensorContext extends DefaultSensorContext implements SensorContext {
private final InputModule module;
public DeprecatedSensorContext(InputModule module, DefaultIndex index, Configuration config, org.sonar.api.config.Settings mutableSettings,
- FileSystem fs, ActiveRules activeRules,
- AnalysisMode analysisMode, SensorStorage sensorStorage, SonarRuntime sonarRuntime) {
- super(module, config, mutableSettings, fs, activeRules, analysisMode, sensorStorage, sonarRuntime);
+ FileSystem fs, ActiveRules activeRules, AnalysisMode analysisMode, SensorStorage sensorStorage, SonarRuntime sonarRuntime,
+ BranchConfiguration branchConfiguration) {
+ super(module, config, mutableSettings, fs, activeRules, analysisMode, sensorStorage, sonarRuntime, branchConfiguration);
this.index = index;
this.module = module;
}
import org.sonar.scanner.rule.QProfile;
import org.sonar.scanner.scan.BranchConfiguration;
-import static org.sonar.core.config.ScannerProperties.BRANCH_NAME;
import static org.sonar.core.config.ScannerProperties.ORGANIZATION;
public class MetadataPublisher implements ReportPublisherStep {
.setIncremental(mode.isIncremental());
settings.get(ORGANIZATION).ifPresent(builder::setOrganizationKey);
- settings.get(BRANCH_NAME).ifPresent(branch -> {
- builder.setBranchName(branch);
+
+ if (branchConfiguration.branchName() != null) {
+ builder.setBranchName(branchConfiguration.branchName());
builder.setBranchType(toProtobufBranchType(branchConfiguration.branchType()));
String branchTarget = branchConfiguration.branchTarget();
if (branchTarget != null) {
builder.setMergeBranchName(branchTarget);
}
- });
+ }
Optional.ofNullable(rootDef.getBranch()).ifPresent(builder::setDeprecatedBranch);
for (QProfile qp : qProfiles.findAll()) {
*/
@CheckForNull
String branchTarget();
+
+ /**
+ * The name of the branch.
+ */
+ @CheckForNull
+ String branchName();
}
public BranchConfiguration provide(@Nullable BranchConfigurationLoader loader, ProjectKey projectKey, GlobalConfiguration globalConfiguration) {
if (branchConfiguration == null) {
- Profiler profiler = Profiler.create(LOG).startInfo(LOG_MSG);
if (loader == null) {
branchConfiguration = new DefaultBranchConfiguration();
} else {
+ Profiler profiler = Profiler.create(LOG).startInfo(LOG_MSG);
branchConfiguration = loader.load(projectKey.get(), globalConfiguration);
+ profiler.stopInfo();
}
- profiler.stopInfo();
}
return branchConfiguration;
}
public String branchTarget() {
return null;
}
+
+ @CheckForNull
+ @Override
+ public String branchName() {
+ return null;
+ }
}
import org.sonar.api.config.Configuration;
import org.sonar.api.config.Settings;
import org.sonar.api.utils.Version;
+import org.sonar.scanner.scan.BranchConfiguration;
+import org.sonar.scanner.scan.BranchConfiguration.BranchType;
import org.sonar.scanner.sensor.noop.NoOpNewAnalysisError;
+import org.sonar.scanner.sensor.noop.NoOpNewCoverage;
import org.sonar.scanner.sensor.noop.NoOpNewCpdTokens;
import org.sonar.scanner.sensor.noop.NoOpNewHighlighting;
import org.sonar.scanner.sensor.noop.NoOpNewSymbolTable;
private static final NoOpNewHighlighting NO_OP_NEW_HIGHLIGHTING = new NoOpNewHighlighting();
private static final NoOpNewSymbolTable NO_OP_NEW_SYMBOL_TABLE = new NoOpNewSymbolTable();
- private static final NoOpNewCpdTokens NO_OP_NEW_CPD_TOKENS = new NoOpNewCpdTokens();
+ static final NoOpNewCpdTokens NO_OP_NEW_CPD_TOKENS = new NoOpNewCpdTokens();
private static final NoOpNewAnalysisError NO_OP_NEW_ANALYSIS_ERROR = new NoOpNewAnalysisError();
+ static final NoOpNewCoverage NO_OP_NEW_COVERAGE = new NoOpNewCoverage();
private final Settings mutableSettings;
private final FileSystem fs;
private final InputModule module;
private final SonarRuntime sonarRuntime;
private final Configuration config;
+ private final BranchConfiguration branchConfiguration;
public DefaultSensorContext(InputModule module, Configuration config, Settings mutableSettings, FileSystem fs, ActiveRules activeRules,
- AnalysisMode analysisMode, SensorStorage sensorStorage,
- SonarRuntime sonarRuntime) {
+ AnalysisMode analysisMode, SensorStorage sensorStorage, SonarRuntime sonarRuntime, BranchConfiguration branchConfiguration) {
this.module = module;
this.config = config;
this.mutableSettings = mutableSettings;
this.analysisMode = analysisMode;
this.sensorStorage = sensorStorage;
this.sonarRuntime = sonarRuntime;
+ this.branchConfiguration = branchConfiguration;
}
@Override
@Override
public NewCoverage newCoverage() {
+ if (branchConfiguration.branchType() == BranchType.SHORT) {
+ return NO_OP_NEW_COVERAGE;
+ }
return new DefaultCoverage(sensorStorage);
}
@Override
public NewCpdTokens newCpdTokens() {
- if (analysisMode.isIssues()) {
+ if (analysisMode.isIssues() || branchConfiguration.branchType() == BranchType.SHORT) {
return NO_OP_NEW_CPD_TOKENS;
}
return new DefaultCpdTokens(config, sensorStorage);
--- /dev/null
+/*
+ * SonarQube
+ * Copyright (C) 2009-2017 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.sensor.noop;
+
+import org.sonar.api.batch.fs.InputFile;
+import org.sonar.api.batch.sensor.coverage.CoverageType;
+import org.sonar.api.batch.sensor.coverage.NewCoverage;
+
+public class NoOpNewCoverage implements NewCoverage {
+
+ @Override
+ public NewCoverage onFile(InputFile inputFile) {
+ // no op
+ return this;
+ }
+
+ @Override
+ public NewCoverage ofType(CoverageType type) {
+ // no op
+ return this;
+ }
+
+ @Override
+ public NewCoverage lineHits(int line, int hits) {
+ // no op
+ return this;
+ }
+
+ @Override
+ public NewCoverage conditions(int line, int conditions, int coveredConditions) {
+ // no op
+ return this;
+ }
+
+ @Override
+ public void save() {
+ // no op
+ }
+}
import org.sonar.scanner.protocol.output.ScannerReportReader;
import org.sonar.scanner.protocol.output.ScannerReportWriter;
import org.sonar.scanner.report.ReportPublisher;
+import org.sonar.scanner.scan.BranchConfiguration;
+import org.sonar.scanner.scan.BranchConfiguration.BranchType;
import org.sonar.scanner.scan.filesystem.InputComponentStore;
import static org.assertj.core.api.Assertions.assertThat;
import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.verifyZeroInteractions;
import static org.mockito.Mockito.when;
public class CpdExecutorTest {
@Rule
public ExpectedException thrown = ExpectedException.none();
+ private BranchConfiguration branchConfig;
private CpdExecutor executor;
private CpdSettings settings;
private SonarCpdBlockIndex index;
File outputDir = temp.newFolder();
baseDir = temp.newFolder();
+ branchConfig = mock(BranchConfiguration.class);
settings = mock(CpdSettings.class);
publisher = mock(ReportPublisher.class);
when(publisher.getWriter()).thenReturn(new ScannerReportWriter(outputDir));
index = new SonarCpdBlockIndex(publisher, settings);
DefaultInputModule inputModule = TestInputFileBuilder.newDefaultInputModule("foo", baseDir);
componentStore = new InputComponentStore(inputModule, mock(AnalysisMode.class));
- executor = new CpdExecutor(settings, index, publisher, componentStore);
+ executor = new CpdExecutor(settings, index, publisher, componentStore, branchConfig);
reader = new ScannerReportReader(outputDir);
batchComponent1 = createComponent("src/Foo.php", 5);
batchComponent3 = createComponent("src/Foo3.php", 5);
}
+ @Test
+ public void skipIfShortBranch() {
+ when(branchConfig.branchType()).thenReturn(BranchType.SHORT);
+ index = mock(SonarCpdBlockIndex.class);
+ executor = new CpdExecutor(settings, index, publisher, componentStore, branchConfig);
+
+ executor.execute();
+
+ verifyZeroInteractions(index);
+ }
+
private DefaultInputFile createComponent(String relativePath, int lines) {
DefaultInputFile file = new TestInputFileBuilder("foo", relativePath)
.setModuleBaseDir(baseDir.toPath())
@Test
public void write_long_lived_branch_info() throws Exception {
String branchName = "long-lived";
- settings.setProperty(ScannerProperties.BRANCH_NAME, branchName);
-
+ when(branches.branchName()).thenReturn(branchName);
when(branches.branchType()).thenReturn(BranchConfiguration.BranchType.LONG);
File outputDir = temp.newFolder();
public void write_short_lived_branch_info() throws Exception {
String branchName = "feature";
String branchTarget = "short-lived";
- settings.setProperty(ScannerProperties.BRANCH_NAME, branchName);
- settings.setProperty(ScannerProperties.BRANCH_TARGET, branchTarget);
-
+ when(branches.branchName()).thenReturn(branchName);
when(branches.branchTarget()).thenReturn(branchTarget);
File outputDir = temp.newFolder();
import org.sonar.api.internal.SonarRuntimeImpl;
import org.sonar.api.measures.CoreMetrics;
import org.sonar.api.utils.Version;
+import org.sonar.scanner.scan.BranchConfiguration;
import static org.assertj.core.api.Assertions.assertThat;
import static org.mockito.Mockito.mock;
private SensorStorage sensorStorage;
private AnalysisMode analysisMode;
private SonarRuntime runtime;
+ private BranchConfiguration branchConfig;
@Before
public void prepare() throws Exception {
when(metricFinder.<Integer>findByKey(CoreMetrics.NCLOC_KEY)).thenReturn(CoreMetrics.NCLOC);
when(metricFinder.<String>findByKey(CoreMetrics.FUNCTION_COMPLEXITY_DISTRIBUTION_KEY)).thenReturn(CoreMetrics.FUNCTION_COMPLEXITY_DISTRIBUTION);
settings = new MapSettings();
+ branchConfig = mock(BranchConfiguration.class);
sensorStorage = mock(SensorStorage.class);
analysisMode = mock(AnalysisMode.class);
runtime = SonarRuntimeImpl.forSonarQube(Version.parse("5.5"), SonarQubeSide.SCANNER);
- adaptor = new DefaultSensorContext(mock(InputModule.class), settings.asConfig(), settings, fs, activeRules, analysisMode, sensorStorage, runtime);
+ adaptor = new DefaultSensorContext(mock(InputModule.class), settings.asConfig(), settings, fs, activeRules, analysisMode, sensorStorage, runtime, branchConfig);
}
@Test
assertThat(adaptor.isCancelled()).isFalse();
}
+ @Test
+ public void shouldSkipDupsAndCoverageOnShortBranches() {
+ when(branchConfig.branchType()).thenReturn(BranchConfiguration.BranchType.SHORT);
+ assertThat(adaptor.newCpdTokens()).isEqualTo(DefaultSensorContext.NO_OP_NEW_CPD_TOKENS);
+ assertThat(adaptor.newCoverage()).isEqualTo(DefaultSensorContext.NO_OP_NEW_COVERAGE);
+ }
}