Skip to content

Commit

Permalink
SONAR-11631 read and persist codePeriodVersion from report
Browse files Browse the repository at this point in the history
  • Loading branch information
sns-seb authored and sonartech committed Feb 11, 2019
1 parent c61b594 commit 9d3e384
Show file tree
Hide file tree
Showing 17 changed files with 357 additions and 127 deletions.
Expand Up @@ -34,21 +34,18 @@
import org.sonar.ce.task.projectanalysis.analysis.Branch; import org.sonar.ce.task.projectanalysis.analysis.Branch;
import org.sonar.ce.task.projectanalysis.issue.IssueRelocationToRoot; import org.sonar.ce.task.projectanalysis.issue.IssueRelocationToRoot;
import org.sonar.core.util.stream.MoreCollectors; import org.sonar.core.util.stream.MoreCollectors;
import org.sonar.db.component.SnapshotDto;
import org.sonar.scanner.protocol.output.ScannerReport; import org.sonar.scanner.protocol.output.ScannerReport;
import org.sonar.scanner.protocol.output.ScannerReport.Component.FileStatus; import org.sonar.scanner.protocol.output.ScannerReport.Component.FileStatus;
import org.sonar.server.project.Project; import org.sonar.server.project.Project;


import static com.google.common.base.MoreObjects.firstNonNull;
import static com.google.common.base.Preconditions.checkArgument; import static com.google.common.base.Preconditions.checkArgument;
import static java.lang.String.format; import static java.lang.String.format;
import static java.util.Objects.requireNonNull;
import static org.apache.commons.lang.StringUtils.removeStart; import static org.apache.commons.lang.StringUtils.removeStart;
import static org.apache.commons.lang.StringUtils.trimToNull; import static org.apache.commons.lang.StringUtils.trimToNull;


public class ComponentTreeBuilder { public class ComponentTreeBuilder {


private static final String DEFAULT_PROJECT_VERSION = "not provided";

private final ComponentKeyGenerator keyGenerator; private final ComponentKeyGenerator keyGenerator;
private final ComponentKeyGenerator publicKeyGenerator; private final ComponentKeyGenerator publicKeyGenerator;
/** /**
Expand All @@ -69,9 +66,7 @@ public class ComponentTreeBuilder {
private final Project project; private final Project project;
private final Branch branch; private final Branch branch;
@Nullable @Nullable
private final SnapshotDto baseAnalysis; private final ProjectAttributes projectAttributes;
@Nullable
private final String projectVersion;
private final IssueRelocationToRoot issueRelocationToRoot; private final IssueRelocationToRoot issueRelocationToRoot;


private ScannerReport.Component rootComponent; private ScannerReport.Component rootComponent;
Expand All @@ -83,8 +78,8 @@ public ComponentTreeBuilder(
Function<String, String> uuidSupplier, Function<String, String> uuidSupplier,
Function<Integer, ScannerReport.Component> scannerComponentSupplier, Function<Integer, ScannerReport.Component> scannerComponentSupplier,
Project project, Project project,
Branch branch, @Nullable SnapshotDto baseAnalysis, Branch branch,
@Nullable String projectVersion, ProjectAttributes projectAttributes,
IssueRelocationToRoot issueRelocationToRoot) { IssueRelocationToRoot issueRelocationToRoot) {


this.keyGenerator = keyGenerator; this.keyGenerator = keyGenerator;
Expand All @@ -93,8 +88,7 @@ public ComponentTreeBuilder(
this.scannerComponentSupplier = scannerComponentSupplier; this.scannerComponentSupplier = scannerComponentSupplier;
this.project = project; this.project = project;
this.branch = branch; this.branch = branch;
this.baseAnalysis = baseAnalysis; this.projectAttributes = requireNonNull(projectAttributes, "projectAttributes can't be null");
this.projectVersion = projectVersion;
this.issueRelocationToRoot = issueRelocationToRoot; this.issueRelocationToRoot = issueRelocationToRoot;
} }


Expand Down Expand Up @@ -198,7 +192,7 @@ private Component buildProject(List<Component> children) {
.setDbKey(projectKey) .setDbKey(projectKey)
.setKey(projectPublicKey) .setKey(projectPublicKey)
.setStatus(convertStatus(rootComponent.getStatus())) .setStatus(convertStatus(rootComponent.getStatus()))
.setProjectAttributes(new ProjectAttributes(createProjectVersion())) .setProjectAttributes(projectAttributes)
.setReportAttributes(createAttributesBuilder(rootComponent.getRef(), rootComponent.getProjectRelativePath(), scmBasePath).build()) .setReportAttributes(createAttributesBuilder(rootComponent.getRef(), rootComponent.getProjectRelativePath(), scmBasePath).build())
.addChildren(children); .addChildren(children);
setNameAndDescription(rootComponent, builder); setNameAndDescription(rootComponent, builder);
Expand Down Expand Up @@ -269,7 +263,7 @@ private static Component buildChangedComponentTree(Component component) {


private static Component buildChangedProject(Component component) { private static Component buildChangedProject(Component component) {
return changedComponentBuilder(component) return changedComponentBuilder(component)
.setProjectAttributes(new ProjectAttributes(component.getProjectAttributes().getVersion())) .setProjectAttributes(new ProjectAttributes(component.getProjectAttributes()))
.addChildren(buildChangedComponentChildren(component)) .addChildren(buildChangedComponentChildren(component))
.build(); .build();
} }
Expand Down Expand Up @@ -339,18 +333,6 @@ private String nameOfProject(ScannerReport.Component component) {
return project.getName(); return project.getName();
} }


private String createProjectVersion() {
String cleanedProjectVersion = trimToNull(this.projectVersion);
if (cleanedProjectVersion != null) {
return cleanedProjectVersion;
}
// FIXME SONAR-11631 code below applies to the analysisVersion, not the project version, fix it
if (baseAnalysis != null) {
return firstNonNull(baseAnalysis.getCodePeriodVersion(), DEFAULT_PROJECT_VERSION);
}
return DEFAULT_PROJECT_VERSION;
}

private static ReportAttributes.Builder createAttributesBuilder(@Nullable Integer ref, String path, @Nullable String scmBasePath) { private static ReportAttributes.Builder createAttributesBuilder(@Nullable Integer ref, String path, @Nullable String scmBasePath) {
return ReportAttributes.newBuilder(ref) return ReportAttributes.newBuilder(ref)
.setScmPath(computeScmPath(scmBasePath, path)); .setScmPath(computeScmPath(scmBasePath, path));
Expand Down
Expand Up @@ -19,23 +19,38 @@
*/ */
package org.sonar.ce.task.projectanalysis.component; package org.sonar.ce.task.projectanalysis.component;


import java.util.Objects; import java.util.Optional;
import javax.annotation.Nullable;

import static java.util.Objects.requireNonNull;


public class ProjectAttributes { public class ProjectAttributes {
private final String version; private final String projectVersion;
private final String codePeriodVersion;

public ProjectAttributes(@Nullable String projectVersion, String codePeriodVersion) {
this.projectVersion = projectVersion;
this.codePeriodVersion = requireNonNull(codePeriodVersion, "codePeriod version can't be null");
}

public ProjectAttributes(ProjectAttributes projectAttributes) {
this.projectVersion = projectAttributes.projectVersion;
this.codePeriodVersion = projectAttributes.codePeriodVersion;
}


public ProjectAttributes(String version) { public Optional<String> getProjectVersion() {
this.version = Objects.requireNonNull(version, "version can't be null"); return Optional.ofNullable(projectVersion);
} }


public String getVersion() { public String getCodePeriodVersion() {
return version; return codePeriodVersion;
} }


@Override @Override
public String toString() { public String toString() {
return "ProjectAttributes{" + return "ProjectAttributes{" +
"version='" + version + '\'' + "projectVersion='" + projectVersion + '\'' +
"codePeriodVersion='" + codePeriodVersion + '\'' +
'}'; '}';
} }
} }
Expand Up @@ -32,6 +32,7 @@
import org.sonar.ce.task.projectanalysis.component.ComponentUuidFactoryWithMigration; import org.sonar.ce.task.projectanalysis.component.ComponentUuidFactoryWithMigration;
import org.sonar.ce.task.projectanalysis.component.DefaultBranchImpl; import org.sonar.ce.task.projectanalysis.component.DefaultBranchImpl;
import org.sonar.ce.task.projectanalysis.component.MutableTreeRootHolder; import org.sonar.ce.task.projectanalysis.component.MutableTreeRootHolder;
import org.sonar.ce.task.projectanalysis.component.ProjectAttributes;
import org.sonar.ce.task.projectanalysis.component.ReportModulesPath; import org.sonar.ce.task.projectanalysis.component.ReportModulesPath;
import org.sonar.ce.task.projectanalysis.issue.IssueRelocationToRoot; import org.sonar.ce.task.projectanalysis.issue.IssueRelocationToRoot;
import org.sonar.ce.task.step.ComputationStep; import org.sonar.ce.task.step.ComputationStep;
Expand All @@ -41,11 +42,16 @@
import org.sonar.db.component.SnapshotQuery; import org.sonar.db.component.SnapshotQuery;
import org.sonar.scanner.protocol.output.ScannerReport; import org.sonar.scanner.protocol.output.ScannerReport;


import static com.google.common.base.MoreObjects.firstNonNull;
import static org.apache.commons.lang.StringUtils.trimToNull;

/** /**
* Populates the {@link MutableTreeRootHolder} and {@link MutableAnalysisMetadataHolder} from the {@link BatchReportReader} * Populates the {@link MutableTreeRootHolder} and {@link MutableAnalysisMetadataHolder} from the {@link BatchReportReader}
*/ */
public class BuildComponentTreeStep implements ComputationStep { public class BuildComponentTreeStep implements ComputationStep {


private static final String DEFAULT_PROJECT_VERSION = "not provided";

private final DbClient dbClient; private final DbClient dbClient;
private final BatchReportReader reportReader; private final BatchReportReader reportReader;
private final MutableTreeRootHolder treeRootHolder; private final MutableTreeRootHolder treeRootHolder;
Expand Down Expand Up @@ -90,8 +96,7 @@ public void execute(ComputationStep.Context context) {
reportReader::readComponent, reportReader::readComponent,
analysisMetadataHolder.getProject(), analysisMetadataHolder.getProject(),
analysisMetadataHolder.getBranch(), analysisMetadataHolder.getBranch(),
baseAnalysis, createProjectAttributes(metadata, baseAnalysis),
metadata.getProjectVersion(),
issueRelocationToRoot); issueRelocationToRoot);
String relativePathFromScmRoot = metadata.getRelativePathFromScmRoot(); String relativePathFromScmRoot = metadata.getRelativePathFromScmRoot();


Expand All @@ -110,6 +115,27 @@ public void execute(ComputationStep.Context context) {
} }
} }


private static ProjectAttributes createProjectAttributes(ScannerReport.Metadata metadata, @Nullable SnapshotDto baseAnalysis) {
String projectVersion = trimToNull(metadata.getProjectVersion());
String codePeriodVersion = computeCodePeriodVersion(metadata.getCodePeriodVersion(), projectVersion, baseAnalysis);
return new ProjectAttributes(projectVersion, codePeriodVersion);
}

private static String computeCodePeriodVersion(String rawCodePeriodVersion, @Nullable String projectVersion, @Nullable SnapshotDto baseAnalysis) {
String codePeriodVersion = trimToNull(rawCodePeriodVersion);
if (codePeriodVersion != null) {
return codePeriodVersion;
}
// support case (legacy but not forbidden) where only projectVersion is set
if (projectVersion != null) {
return projectVersion;
}
if (baseAnalysis != null) {
return firstNonNull(baseAnalysis.getCodePeriodVersion(), DEFAULT_PROJECT_VERSION);
}
return DEFAULT_PROJECT_VERSION;
}

private ComponentKeyGenerator loadKeyGenerator() { private ComponentKeyGenerator loadKeyGenerator() {
return analysisMetadataHolder.getBranch(); return analysisMetadataHolder.getBranch();
} }
Expand Down
Expand Up @@ -105,7 +105,7 @@ public void execute(ComputationStep.Context context) {
} }


private Optional<Period> resolvePeriod(Component projectOrView) { private Optional<Period> resolvePeriod(Component projectOrView) {
String currentVersion = projectOrView.getProjectAttributes().getVersion(); String currentVersion = projectOrView.getProjectAttributes().getCodePeriodVersion();
Optional<String> propertyValue = configRepository.getConfiguration().get(LEAK_PERIOD) Optional<String> propertyValue = configRepository.getConfiguration().get(LEAK_PERIOD)
.filter(t -> !t.isEmpty()); .filter(t -> !t.isEmpty());
checkPeriodProperty(propertyValue.isPresent(), "", "property is undefined or value is empty"); checkPeriodProperty(propertyValue.isPresent(), "", "property is undefined or value is empty");
Expand Down
Expand Up @@ -33,6 +33,8 @@
import org.sonar.db.DbSession; import org.sonar.db.DbSession;
import org.sonar.db.component.SnapshotDto; import org.sonar.db.component.SnapshotDto;


import static org.sonar.ce.task.projectanalysis.component.Component.Type.PROJECT;

/** /**
* Persist analysis * Persist analysis
*/ */
Expand Down Expand Up @@ -100,11 +102,12 @@ private void updateSnapshotPeriods(SnapshotDto snapshotDto) {


private SnapshotDto createAnalysis(String snapshotUuid, Component component) { private SnapshotDto createAnalysis(String snapshotUuid, Component component) {
String componentUuid = component.getUuid(); String componentUuid = component.getUuid();
String version = component.getType() == Component.Type.PROJECT ? component.getProjectAttributes().getVersion() : null; String codePeriodVersion = component.getType() == PROJECT ? component.getProjectAttributes().getCodePeriodVersion() : null;
String projectVersion = component.getType() == PROJECT ? component.getProjectAttributes().getProjectVersion().orElse(null) : null;
return new SnapshotDto() return new SnapshotDto()
.setUuid(snapshotUuid) .setUuid(snapshotUuid)
.setCodePeriodVersion(version) .setCodePeriodVersion(codePeriodVersion)
.setProjectVersion(version) .setProjectVersion(projectVersion)
.setComponentUuid(componentUuid) .setComponentUuid(componentUuid)
.setLast(false) .setLast(false)
.setStatus(SnapshotDto.STATUS_UNPROCESSED) .setStatus(SnapshotDto.STATUS_UNPROCESSED)
Expand Down
Expand Up @@ -101,10 +101,10 @@ private void processEvents(DbSession session, Component component, Long analysis
} }


private void saveVersionEvent(DbSession session, Component component, Long analysisDate) { private void saveVersionEvent(DbSession session, Component component, Long analysisDate) {
String version = component.getProjectAttributes().getVersion(); String codePeriodVersion = component.getProjectAttributes().getCodePeriodVersion();
deletePreviousEventsHavingSameVersion(session, version, component); deletePreviousEventsHavingSameVersion(session, codePeriodVersion, component);
dbClient.eventDao().insert(session, newBaseEvent(component, analysisDate) dbClient.eventDao().insert(session, newBaseEvent(component, analysisDate)
.setName(version) .setName(codePeriodVersion)
.setCategory(EventDto.CATEGORY_VERSION)); .setCategory(EventDto.CATEGORY_VERSION));
} }


Expand Down
Expand Up @@ -132,7 +132,7 @@ private void notifyUsers(Component project, String label, QualityGateStatus rawS
.setDefaultMessage(String.format("Alert on %s: %s", project.getName(), label)) .setDefaultMessage(String.format("Alert on %s: %s", project.getName(), label))
.setFieldValue("projectName", project.getName()) .setFieldValue("projectName", project.getName())
.setFieldValue("projectKey", project.getKey()) .setFieldValue("projectKey", project.getKey())
.setFieldValue("projectVersion", project.getProjectAttributes().getVersion()) .setFieldValue("projectVersion", project.getProjectAttributes().getCodePeriodVersion())
.setFieldValue("alertName", label) .setFieldValue("alertName", label)
.setFieldValue("alertText", rawStatus.getText()) .setFieldValue("alertText", rawStatus.getText())
.setFieldValue("alertLevel", rawStatus.getStatus().toString()) .setFieldValue("alertLevel", rawStatus.getStatus().toString())
Expand Down
Expand Up @@ -165,7 +165,7 @@ private void sendNewIssuesNotification(NewIssuesStatistics statistics, Component
NewIssuesNotification notification = newIssuesNotificationFactory NewIssuesNotification notification = newIssuesNotificationFactory
.newNewIssuesNotification() .newNewIssuesNotification()
.setProject(project.getKey(), project.getName(), getBranchName(), getPullRequest()) .setProject(project.getKey(), project.getName(), getBranchName(), getPullRequest())
.setProjectVersion(project.getProjectAttributes().getVersion()) .setProjectVersion(project.getProjectAttributes().getCodePeriodVersion())
.setAnalysisDate(new Date(analysisDate)) .setAnalysisDate(new Date(analysisDate))
.setStatistics(project.getName(), globalStatistics) .setStatistics(project.getName(), globalStatistics)
.setDebt(Duration.create(globalStatistics.effort().getOnLeak())); .setDebt(Duration.create(globalStatistics.effort().getOnLeak()));
Expand All @@ -186,7 +186,7 @@ private void sendMyNewIssuesNotification(NewIssuesStatistics statistics, Compone
.setAssignee(userDtoByUuid.get(assigneeUuid)); .setAssignee(userDtoByUuid.get(assigneeUuid));
myNewIssuesNotification myNewIssuesNotification
.setProject(project.getKey(), project.getName(), getBranchName(), getPullRequest()) .setProject(project.getKey(), project.getName(), getBranchName(), getPullRequest())
.setProjectVersion(project.getProjectAttributes().getVersion()) .setProjectVersion(project.getProjectAttributes().getCodePeriodVersion())
.setAnalysisDate(new Date(analysisDate)) .setAnalysisDate(new Date(analysisDate))
.setStatistics(project.getName(), assigneeStatistics) .setStatistics(project.getName(), assigneeStatistics)
.setDebt(Duration.create(assigneeStatistics.effort().getOnLeak())); .setDebt(Duration.create(assigneeStatistics.effort().getOnLeak()));
Expand Down
Expand Up @@ -246,7 +246,7 @@ private static ComponentImpl.Builder buildSimpleComponent(Component.Type type, S
.setUuid("uuid_" + dbKey) .setUuid("uuid_" + dbKey)
.setReportAttributes(ReportAttributes.newBuilder(dbKey.hashCode()).build()); .setReportAttributes(ReportAttributes.newBuilder(dbKey.hashCode()).build());
if (type == PROJECT) { if (type == PROJECT) {
builder.setProjectAttributes(new ProjectAttributes("version_1")); builder.setProjectAttributes(new ProjectAttributes(null, "version_1"));
} }
return builder; return builder;
} }
Expand Down

0 comments on commit 9d3e384

Please sign in to comment.