@Deprecated
String PROJECT_BRANCH_PROPERTY = "sonar.branch";
String PROJECT_VERSION_PROPERTY = "sonar.projectVersion";
+ String CODE_PERIOD_VERSION_PROPERTY = "sonar.codePeriodVersion";
/**
* @since 2.6
import java.time.Clock;
import java.util.Date;
import java.util.Optional;
-import javax.annotation.CheckForNull;
+import java.util.function.Predicate;
+import org.apache.commons.lang.StringUtils;
import org.picocontainer.Startable;
import org.sonar.api.CoreProperties;
import org.sonar.api.config.Configuration;
import org.sonar.api.utils.MessageException;
import static java.lang.String.format;
+import static org.sonar.api.CoreProperties.CODE_PERIOD_VERSION_PROPERTY;
+import static org.sonar.api.CoreProperties.PROJECT_VERSION_PROPERTY;
/**
* @since 6.3
private Date analysisDate;
private String projectVersion;
+ private String codePeriodVersion;
public ProjectInfo(Configuration settings, Clock clock) {
this.settings = settings;
this.clock = clock;
}
- public Date analysisDate() {
+ public Date getAnalysisDate() {
return analysisDate;
}
- @CheckForNull
- public String projectVersion() {
- return projectVersion;
+ public Optional<String> getProjectVersion() {
+ return Optional.ofNullable(projectVersion);
+ }
+
+ public Optional<String> getCodePeriodVersion() {
+ return Optional.ofNullable(codePeriodVersion);
}
private Date loadAnalysisDate() {
}
}
- @CheckForNull
- private String loadProjectVersion() {
- return settings.get(CoreProperties.PROJECT_VERSION_PROPERTY)
- .filter(version -> {
- if (version.length() > 100) {
- throw MessageException.of(format("\"%s\" is not a valid project version. " +
- "The maximum length for version numbers is 100 characters.", version));
- }
- return true;
- })
- .orElse(null);
- }
-
@Override
public void start() {
this.analysisDate = loadAnalysisDate();
- this.projectVersion = loadProjectVersion();
+ this.projectVersion = settings.get(PROJECT_VERSION_PROPERTY)
+ .map(StringUtils::trimToNull)
+ .filter(validateVersion("project"))
+ .orElse(null);
+ this.codePeriodVersion = settings.get(CODE_PERIOD_VERSION_PROPERTY)
+ .map(StringUtils::trimToNull)
+ .filter(validateVersion("codePeriod"))
+ .orElse(projectVersion);
+ }
+
+ private static Predicate<String> validateVersion(String versionLabel) {
+ return version -> {
+ if (version.length() > 100) {
+ throw MessageException.of(format("\"%s\" is not a valid %s version. " +
+ "The maximum length is 100 characters.", version, versionLabel));
+ }
+ return true;
+ };
}
@Override
@Override
public Date creationDate() {
- return projectInfo.analysisDate();
+ return projectInfo.getAnalysisDate();
}
@Override
private final LocalIssueTracking localIssueTracking;
public IssueTransition(InputComponentStore inputComponentCache, ProjectInfo projectInfo, IssueCache issueCache, ReportPublisher reportPublisher,
- @Nullable LocalIssueTracking localIssueTracking) {
+ @Nullable LocalIssueTracking localIssueTracking) {
this.inputComponentStore = inputComponentCache;
this.issueCache = issueCache;
this.reportPublisher = reportPublisher;
this.localIssueTracking = localIssueTracking;
- this.analysisDate = projectInfo.analysisDate();
+ this.analysisDate = projectInfo.getAnalysisDate();
}
public IssueTransition(InputComponentStore inputComponentCache, ProjectInfo projectInfo, IssueCache issueCache, ReportPublisher reportPublisher) {
import org.sonar.scanner.scm.ScmConfiguration;
import static java.util.Optional.ofNullable;
-import static org.apache.commons.lang.StringUtils.trimToNull;
public class MetadataPublisher implements ReportPublisherStep {
public void publish(ScannerReportWriter writer) {
AbstractProjectOrModule rootProject = moduleHierarchy.root();
ScannerReport.Metadata.Builder builder = ScannerReport.Metadata.newBuilder()
- .setAnalysisDate(projectInfo.analysisDate().getTime())
+ .setAnalysisDate(projectInfo.getAnalysisDate().getTime())
// Here we want key without branch
.setProjectKey(rootProject.key())
.setCrossProjectDuplicationActivated(cpdSettings.isCrossProjectDuplicationEnabled())
.setRootComponentRef(rootProject.scannerId());
- ofNullable(trimToNull(projectInfo.projectVersion())).ifPresent(builder::setProjectVersion);
+ projectInfo.getProjectVersion().ifPresent(builder::setProjectVersion);
+ projectInfo.getCodePeriodVersion().ifPresent(builder::setCodePeriodVersion);
properties.organizationKey().ifPresent(builder::setOrganizationKey);
*/
package org.sonar.scanner;
+import com.tngtech.java.junit.dataprovider.DataProvider;
+import com.tngtech.java.junit.dataprovider.DataProviderRunner;
+import com.tngtech.java.junit.dataprovider.UseDataProvider;
import java.time.Clock;
import java.time.LocalDate;
import java.time.OffsetDateTime;
import java.time.ZoneId;
import java.time.ZoneOffset;
import java.util.Date;
+import javax.annotation.Nullable;
+import org.apache.commons.lang.RandomStringUtils;
import org.junit.Rule;
import org.junit.Test;
import org.junit.rules.ExpectedException;
+import org.junit.runner.RunWith;
import org.sonar.api.CoreProperties;
import org.sonar.api.config.internal.MapSettings;
import org.sonar.api.utils.MessageException;
import static org.assertj.core.api.Assertions.assertThat;
import static org.mockito.Mockito.mock;
+@RunWith(DataProviderRunner.class)
public class ProjectInfoTest {
@Rule
- public ExpectedException thrown = ExpectedException.none();
+ public ExpectedException expectedException = ExpectedException.none();
private MapSettings settings = new MapSettings();
private Clock clock = mock(Clock.class);
underTest.start();
- assertThat(underTest.analysisDate()).isEqualTo(Date.from(date.toInstant()));
- assertThat(underTest.projectVersion()).isEqualTo("version");
+ assertThat(underTest.getAnalysisDate()).isEqualTo(Date.from(date.toInstant()));
+ assertThat(underTest.getProjectVersion()).contains("version");
}
@Test
underTest.start();
- assertThat(underTest.analysisDate())
+ assertThat(underTest.getAnalysisDate())
.isEqualTo(Date.from(date.atStartOfDay().atZone(ZoneId.systemDefault()).toInstant()));
}
@Test
public void emptyDate() {
- settings.appendProperty(CoreProperties.PROJECT_DATE_PROPERTY, "");
- settings.appendProperty(CoreProperties.PROJECT_VERSION_PROPERTY, "version");
+ settings.setProperty(CoreProperties.PROJECT_DATE_PROPERTY, "");
+ settings.setProperty(CoreProperties.PROJECT_VERSION_PROPERTY, "version");
- thrown.expect(RuntimeException.class);
+ expectedException.expect(RuntimeException.class);
underTest.start();
}
@Test
public void fail_with_too_long_version() {
String version = randomAlphabetic(101);
- settings.appendProperty(CoreProperties.PROJECT_DATE_PROPERTY, "2017-01-01");
- settings.appendProperty(CoreProperties.PROJECT_VERSION_PROPERTY, version);
+ settings.setProperty(CoreProperties.PROJECT_DATE_PROPERTY, "2017-01-01");
+ settings.setProperty(CoreProperties.PROJECT_VERSION_PROPERTY, version);
+
+ expectedException.expect(MessageException.class);
+ expectedException.expectMessage("\"" + version + "\" is not a valid project version. " +
+ "The maximum length is 100 characters.");
+
+ underTest.start();
+ }
+
+ @Test
+ @UseDataProvider("projectVersions")
+ public void getCodePeriodVersion_has_value_of_projectVersion_if_property_is_unset(@Nullable String projectVersion) {
+ settings.setProperty(CoreProperties.PROJECT_DATE_PROPERTY, "2017-01-01");
+ settings.setProperty(CoreProperties.PROJECT_VERSION_PROPERTY, projectVersion);
+
+ underTest.start();
+
+ if (projectVersion == null) {
+ assertThat(underTest.getCodePeriodVersion()).isEmpty();
+ } else {
+ assertThat(underTest.getCodePeriodVersion()).contains(projectVersion);
+ }
+ }
- thrown.expect(MessageException.class);
- thrown.expectMessage("\"" + version +"\" is not a valid project version. " +
- "The maximum length for version numbers is 100 characters.");
+ @Test
+ @UseDataProvider("projectVersions")
+ public void getCodePeriodVersion_is_empty_if_property_is_empty(@Nullable String projectVersion) {
+ settings.setProperty(CoreProperties.PROJECT_DATE_PROPERTY, "2017-01-01");
+ settings.setProperty(CoreProperties.PROJECT_VERSION_PROPERTY, projectVersion);
+ settings.setProperty(CoreProperties.CODE_PERIOD_VERSION_PROPERTY, "");
underTest.start();
+
+ if (projectVersion == null) {
+ assertThat(underTest.getCodePeriodVersion()).isEmpty();
+ } else {
+ assertThat(underTest.getCodePeriodVersion()).contains(projectVersion);
+ }
+ }
+
+ @Test
+ @UseDataProvider("projectVersions")
+ public void getCodePeriodVersion_contains_value_of_property(@Nullable String projectVersion) {
+ String version = RandomStringUtils.randomAlphabetic(10);
+ settings.setProperty(CoreProperties.PROJECT_DATE_PROPERTY, "2017-01-01");
+ settings.setProperty(CoreProperties.PROJECT_VERSION_PROPERTY, projectVersion);
+ settings.setProperty(CoreProperties.CODE_PERIOD_VERSION_PROPERTY, version);
+
+ underTest.start();
+
+ assertThat(underTest.getCodePeriodVersion()).contains(version);
+ }
+
+ @DataProvider
+ public static Object[][] projectVersions() {
+ return new Object[][] {
+ {null},
+ {randomAlphabetic(12)}
+ };
}
}
rawIssue = createIssue();
issue = new DefaultFilterableIssue(mockedProject, projectInfo, rawIssue, component);
- when(projectInfo.analysisDate()).thenReturn(new Date(10_000));
+ when(projectInfo.getAnalysisDate()).thenReturn(new Date(10_000));
when(mockedProject.key()).thenReturn("projectKey");
assertThat(issue.componentKey()).isEqualTo(component.key());
@Test
public void add_components_to_report() throws Exception {
ProjectInfo projectInfo = mock(ProjectInfo.class);
- when(projectInfo.analysisDate()).thenReturn(DateUtils.parseDate("2012-12-12"));
+ when(projectInfo.getAnalysisDate()).thenReturn(DateUtils.parseDate("2012-12-12"));
ProjectDefinition rootDef = ProjectDefinition.create()
.setKey("foo")
@Test
public void should_set_modified_name_with_branch() throws IOException {
ProjectInfo projectInfo = mock(ProjectInfo.class);
- when(projectInfo.analysisDate()).thenReturn(DateUtils.parseDate("2012-12-12"));
+ when(projectInfo.getAnalysisDate()).thenReturn(DateUtils.parseDate("2012-12-12"));
ProjectDefinition rootDef = ProjectDefinition.create()
.setKey("foo")
public void publish_unchanged_components_even_in_short_branches() throws IOException {
when(branchConfiguration.isShortOrPullRequest()).thenReturn(true);
ProjectInfo projectInfo = mock(ProjectInfo.class);
- when(projectInfo.analysisDate()).thenReturn(DateUtils.parseDate("2012-12-12"));
+ when(projectInfo.getAnalysisDate()).thenReturn(DateUtils.parseDate("2012-12-12"));
Path baseDir = temp.newFolder().toPath();
ProjectDefinition rootDef = ProjectDefinition.create()
@Test
public void publish_project_without_version_and_name() throws IOException {
ProjectInfo projectInfo = mock(ProjectInfo.class);
- when(projectInfo.analysisDate()).thenReturn(DateUtils.parseDate("2012-12-12"));
+ when(projectInfo.getAnalysisDate()).thenReturn(DateUtils.parseDate("2012-12-12"));
ProjectDefinition rootDef = ProjectDefinition.create()
.setKey("foo")
@Test
public void publish_project_with_links_and_branch() throws Exception {
ProjectInfo projectInfo = mock(ProjectInfo.class);
- when(projectInfo.analysisDate()).thenReturn(DateUtils.parseDate("2012-12-12"));
+ when(projectInfo.getAnalysisDate()).thenReturn(DateUtils.parseDate("2012-12-12"));
ProjectDefinition rootDef = ProjectDefinition.create()
.setKey("foo")
import static java.util.Arrays.asList;
import static java.util.Collections.emptyMap;
+import static org.apache.commons.lang.RandomStringUtils.randomAlphabetic;
import static org.assertj.core.api.Assertions.assertThat;
import static org.assertj.core.api.Assertions.entry;
import static org.mockito.ArgumentMatchers.any;
@Before
public void prepare() throws IOException {
- when(projectInfo.analysisDate()).thenReturn(new Date(1234567L));
+ when(projectInfo.getAnalysisDate()).thenReturn(new Date(1234567L));
when(scmProvider.relativePathFromScmRoot(any(Path.class))).thenReturn(Paths.get("dummy/path"));
when(scmProvider.revisionId(any(Path.class))).thenReturn("dummy-sha1");
assertThat(metadata.getAnalysisDate()).isEqualTo(1234567L);
assertThat(metadata.getProjectKey()).isEqualTo("root");
assertThat(metadata.getModulesProjectRelativePathByKeyMap()).containsOnly(entry("module", "modulePath"), entry("root", ""));
+ assertThat(metadata.getProjectVersion()).isEmpty();
assertThat(metadata.getQprofilesPerLanguageMap()).containsOnly(entry("java", org.sonar.scanner.protocol.output.ScannerReport.Metadata.QProfile.newBuilder()
.setKey("q1")
.setName("Q1")
@Test
@UseDataProvider("projectVersions")
public void write_project_version(@Nullable String projectVersion, String expected) throws Exception {
- when(projectInfo.projectVersion()).thenReturn(projectVersion);
+ when(projectInfo.getProjectVersion()).thenReturn(Optional.ofNullable(projectVersion));
when(properties.organizationKey()).thenReturn(Optional.of("SonarSource"));
File outputDir = temp.newFolder();
@DataProvider
public static Object[][] projectVersions() {
+ String version = randomAlphabetic(15);
return new Object[][] {
{null, ""},
{"", ""},
- {"5.6.3", "5.6.3"}
+ {"5.6.3", "5.6.3"},
+ {version, version}
+ };
+ }
+
+ @Test
+ @UseDataProvider("codePeriodVersions")
+ public void write_codePeriod_version(@Nullable String codePeriodVersion, String expected) throws Exception {
+ when(projectInfo.getCodePeriodVersion()).thenReturn(Optional.ofNullable(codePeriodVersion));
+ when(properties.organizationKey()).thenReturn(Optional.of("SonarSource"));
+
+ File outputDir = temp.newFolder();
+ ScannerReportWriter writer = new ScannerReportWriter(outputDir);
+
+ underTest.publish(writer);
+
+ ScannerReportReader reader = new ScannerReportReader(outputDir);
+ ScannerReport.Metadata metadata = reader.readMetadata();
+ assertThat(metadata.getCodePeriodVersion()).isEqualTo(expected);
+ }
+
+ @DataProvider
+ public static Object[][] codePeriodVersions() {
+ String randomVersion = randomAlphabetic(15);
+ return new Object[][] {
+ {null, ""},
+ {"", ""},
+ {"5.6.3", "5.6.3"},
+ {randomVersion, randomVersion}
};
}
@Test
@UseDataProvider("validVersions")
public void not_fail_with_valid_version(String validVersion) {
- when(projectInfo.projectVersion()).thenReturn(validVersion);
+ when(projectInfo.getProjectVersion()).thenReturn(Optional.ofNullable(validVersion));
underTest.validate(createProjectReactor("foo"));
}
@DataProvider
public static Object[][] validVersions() {
return new Object[][] {
+ {null},
{"1.0"},
{"2017-10-16"},
{randomAscii(100)}
map<string, string> modules_project_relative_path_by_key = 15;
string projectVersion = 16;
+ string codePeriodVersion = 17;
message QProfile {
string key = 1;