Skip to content

Commit

Permalink
enhancement: Replace Sonarqube server URL with installation name
Browse files Browse the repository at this point in the history
  • Loading branch information
reda-alaoui committed Jan 2, 2022
1 parent 0bd9880 commit 33583c8
Show file tree
Hide file tree
Showing 43 changed files with 1,538 additions and 97 deletions.
8 changes: 4 additions & 4 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -74,9 +74,9 @@ There are the next sections:

#### SonarQube Settings

![alt text](doc/sonar-url-conf.png "Sonar URL configuration")
![alt text](doc/sonar-qube-installation.png "SonarQube installation")

1. Server URL - URL of SonarQube instance used for analysis. It is also used to provide a link to a SonarQube rule in Gerrit comments. Default value: http://localhost:9000
1. SonarQube installation - The SonarQube installation (see https://plugins.jenkins.io/sonar/) to be used for analysis. It is also used to provide a link to a SonarQube rule in Gerrit comments.

#### Project Settings

Expand Down Expand Up @@ -136,7 +136,7 @@ This section allows user to customise text, intended to use as review title and
3. \<message> - will be replaced with issue message;
4. \<severity> - will be replaced with issue severity;
5. \<rule> - will be replaced with issue rule name;
6. \<rule_url> - will be replaced with link to rule description on SonarQube if SonarQube URL is provided in SonarQube settings section or rule name if URL is not provided;
6. \<rule_url> - will be replaced with link to rule description on SonarQube;
7. \<status> - will be replaced with issue status;
8. \<creation_date> - will be replaced with issue creation date.

Expand Down Expand Up @@ -236,7 +236,7 @@ node {
```groovy
sonarToGerrit (
inspectionConfig: [
serverURL: 'http://localhost:9000',
sonarQubeInstallationName: 'My SonarQube Installation',
baseConfig: [
projectPath: '',
sonarReportPath: 'target/sonar/sonar-report.json',
Expand Down
Binary file added doc/sonar-qube-installation.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file removed doc/sonar-url-conf.png
Binary file not shown.
93 changes: 87 additions & 6 deletions pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -24,8 +24,21 @@
~ hpi-plugin.version: The HPI Maven Plugin version used by the plugin..
~ stapler-plugin.version: The Stapler Maven plugin version required by the plugin.
-->
<httpclient.version>4.5.13</httpclient.version>
<gson.version>2.8.8</gson.version>
<gerrit-trigger.version>2.35.0</gerrit-trigger.version>
<guava.version>31.0.1-jre</guava.version>
<gerrit-rest-java-client.version>0.9.4.2</gerrit-rest-java-client.version>
<junit.jupiter.version>5.8.2</junit.jupiter.version>
<testcontainers.version>1.16.2</testcontainers.version>
<jgit.version>5.13.0.202109080827-r</jgit.version>
<okhttp.version>4.9.2</okhttp.version>
<jackson.version>2.13.0</jackson.version>
<sonar.version>2.13.1</sonar.version>

<git-code-format-maven-plugin.version>2.7</git-code-format-maven-plugin.version>
<assertj-core.version>3.21.0</assertj-core.version>
<logback-classic.version>1.2.3</logback-classic.version>
</properties>

<name>Sonar Gerrit Plugin</name>
Expand All @@ -43,12 +56,27 @@
<dependency>
<groupId>org.apache.httpcomponents</groupId>
<artifactId>httpclient</artifactId>
<version>4.5.13</version>
<version>${httpclient.version}</version>
</dependency>
<dependency>
<groupId>com.google.code.gson</groupId>
<artifactId>gson</artifactId>
<version>2.8.5</version>
<version>${gson.version}</version>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
<version>1.7.32</version>
</dependency>
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-compress</artifactId>
<version>1.21</version>
</dependency>
<dependency>
<groupId>org.jetbrains.kotlin</groupId>
<artifactId>kotlin-stdlib-common</artifactId>
<version>1.4.10</version>
</dependency>
</dependencies>
</dependencyManagement>
Expand All @@ -61,7 +89,12 @@
<dependency>
<groupId>com.sonyericsson.hudson.plugins.gerrit</groupId>
<artifactId>gerrit-trigger</artifactId>
<version>2.35.0</version>
<version>${gerrit-trigger.version}</version>
</dependency>
<dependency>
<groupId>org.jenkins-ci.plugins</groupId>
<artifactId>sonar</artifactId>
<version>${sonar.version}</version>
</dependency>
<dependency>
<groupId>com.google.code.gson</groupId>
Expand All @@ -70,12 +103,12 @@
<dependency>
<groupId>com.google.guava</groupId>
<artifactId>guava</artifactId>
<version>18.0</version>
<version>${guava.version}</version>
</dependency>
<dependency>
<groupId>com.urswolfer.gerrit.client.rest</groupId>
<groupId>me.redaalaoui.gerrit.client.rest</groupId>
<artifactId>gerrit-rest-java-client</artifactId>
<version>0.9.3</version>
<version>${gerrit-rest-java-client.version}</version>
</dependency>
<dependency>
<groupId>org.junit.jupiter</groupId>
Expand All @@ -90,6 +123,54 @@
<version>${junit.jupiter.version}</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.testcontainers</groupId>
<artifactId>testcontainers</artifactId>
<version>${testcontainers.version}</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.eclipse.jgit</groupId>
<artifactId>org.eclipse.jgit</artifactId>
<version>${jgit.version}</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>com.squareup.okhttp3</groupId>
<artifactId>okhttp</artifactId>
<version>${okhttp.version}</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<version>${jackson.version}</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-core</artifactId>
<version>${jackson.version}</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-annotations</artifactId>
<version>${jackson.version}</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>ch.qos.logback</groupId>
<artifactId>logback-classic</artifactId>
<version>${logback-classic.version}</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.assertj</groupId>
<artifactId>assertj-core</artifactId>
<version>${assertj-core.version}</version>
<scope>test</scope>
</dependency>
</dependencies>

<licenses>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,24 +3,40 @@
import static org.jenkinsci.plugins.sonargerrit.util.Localization.getLocalized;

import com.google.common.base.MoreObjects;
import edu.umd.cs.findbugs.annotations.SuppressFBWarnings;
import hudson.Extension;
import hudson.Util;
import hudson.model.AbstractDescribableImpl;
import hudson.model.Descriptor;
import hudson.plugins.sonar.SonarGlobalConfiguration;
import hudson.plugins.sonar.SonarInstallation;
import hudson.util.FormValidation;
import hudson.util.ListBoxModel;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.*;
import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
import java.util.HashSet;
import java.util.LinkedList;
import java.util.Optional;
import java.util.Set;
import java.util.stream.Collectors;
import java.util.stream.Stream;
import javax.annotation.Nonnull;
import javax.annotation.Nullable;
import org.apache.commons.lang3.StringUtils;
import org.jenkinsci.plugins.sonargerrit.SonarToGerritPublisher;
import org.kohsuke.stapler.DataBoundConstructor;
import org.kohsuke.stapler.DataBoundSetter;
import org.kohsuke.stapler.QueryParameter;

/** Project: Sonar-Gerrit Plugin Author: Tatiana Didik Created: 07.12.2017 13:45 $Id$ */
public class InspectionConfig extends AbstractDescribableImpl<InspectionConfig> {
@Nonnull private String serverURL = DescriptorImpl.SONAR_URL;

// Only kept for backward compatibility purpose
private transient String serverURL;

private String sonarQubeInstallationName;

private SubJobConfig baseConfig;

Expand All @@ -30,37 +46,45 @@ public class InspectionConfig extends AbstractDescribableImpl<InspectionConfig>

@DataBoundConstructor
public InspectionConfig() {
this(DescriptorImpl.SONAR_URL, null, null, DescriptorImpl.BASE_TYPE); // set default values
}

@SuppressFBWarnings(
value = "NP_NONNULL_FIELD_NOT_INITIALIZED_IN_CONSTRUCTOR") // subJobConfigs is initialized in
// setter
private InspectionConfig(
@Nonnull String serverURL,
SubJobConfig baseConfig,
List<SubJobConfig> subJobConfigs,
String type) {
setServerURL(serverURL);
setBaseConfig(baseConfig);
setSubJobConfigs(subJobConfigs);
setType(type);
setBaseConfig(null);
setSubJobConfigs(null);
setType(DescriptorImpl.BASE_TYPE);
}

@Override
public DescriptorImpl getDescriptor() {
return new DescriptorImpl();
}

@Nullable
public String getSonarQubeInstallationName() {
return sonarQubeInstallationName;
}

@DataBoundSetter
public void setSonarQubeInstallationName(String name) {
this.sonarQubeInstallationName = StringUtils.defaultIfBlank(name, null);
}

/** @deprecated Use {@link #getSonarQubeInstallationName()} */
@Deprecated
@Nonnull
public String getServerURL() {
return serverURL;
return Optional.ofNullable(sonarQubeInstallationName)
.flatMap(name -> SonarQubeInstallations.get().byName(name))
.map(SonarInstallation::getServerUrl)
.orElse(DescriptorImpl.SONAR_URL);
}

/** @deprecated Use {@link #setSonarQubeInstallationName(String)} */
@DataBoundSetter
public void setServerURL(String serverURL) {
this.serverURL =
MoreObjects.firstNonNull(Util.fixEmptyAndTrim(serverURL), DescriptorImpl.SONAR_URL);
this.sonarQubeInstallationName =
Optional.ofNullable(serverURL)
.filter(StringUtils::isNotBlank)
.map(name -> SonarQubeInstallations.get().findOrCreate(name))
.map(SonarInstallation::getName)
.orElse(null);
}

public SubJobConfig getBaseConfig() {
Expand Down Expand Up @@ -124,6 +148,13 @@ public boolean isPathCorrectionNeeded() {
return isAutoMatch();
}

protected Object readResolve() {
if (serverURL != null) {
sonarQubeInstallationName = SonarQubeInstallations.get().findOrCreate(serverURL).getName();
}
return this;
}

@Extension
public static class DescriptorImpl extends Descriptor<InspectionConfig> {
public static final String SONAR_URL = SonarToGerritPublisher.DescriptorImpl.SONAR_URL;
Expand All @@ -137,14 +168,8 @@ public static class DescriptorImpl extends Descriptor<InspectionConfig> {
private static final Set<String> ALLOWED_TYPES =
new HashSet<>(Arrays.asList(BASE_TYPE, MULTI_TYPE));

/**
* Performs on-the-fly validation of the form field 'serverURL'.
*
* @param value This parameter receives the value that the user has typed.
* @return Indicates the outcome of the validation. This is sent to the browser.
* <p>Note that returning {@link FormValidation#error(String)} does not prevent the form
* from being saved. It just means that a message will be displayed to the user.
*/
/** @deprecated Replaced with "sonar installation name" */
@Deprecated
@SuppressWarnings(value = "unused")
public FormValidation doCheckServerURL(@QueryParameter String value) {
if (Util.fixEmptyAndTrim(value) == null) {
Expand All @@ -158,6 +183,19 @@ public FormValidation doCheckServerURL(@QueryParameter String value) {
return FormValidation.ok();
}

@SuppressWarnings(value = "unused")
public FormValidation doCheckSonarQubeInstallationName(@QueryParameter String value) {
return FormValidation.validateRequired(value);
}

@SuppressWarnings("unused")
public ListBoxModel doFillSonarQubeInstallationNameItems() {
return Stream.of(SonarGlobalConfiguration.get().getInstallations())
.map(SonarInstallation::getName)
.map(ListBoxModel.Option::new)
.collect(Collectors.collectingAndThen(Collectors.toList(), ListBoxModel::new));
}

@Override
public String getDisplayName() {
return "InspectionConfig";
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
package org.jenkinsci.plugins.sonargerrit.config;

import hudson.plugins.sonar.SonarGlobalConfiguration;
import hudson.plugins.sonar.SonarInstallation;
import java.util.Optional;
import java.util.UUID;
import java.util.stream.Stream;
import org.apache.commons.lang3.ArrayUtils;

/** @author Réda Housni Alaoui */
class SonarQubeInstallations {

private SonarQubeInstallations() {}

public static SonarQubeInstallations get() {
return new SonarQubeInstallations();
}

public SonarInstallation findOrCreate(String serverUrl) {
return Stream.of(SonarGlobalConfiguration.get().getInstallations())
.filter(installation -> serverUrl.equals(installation.getServerUrl()))
.findFirst()
.orElseGet(() -> create(serverUrl));
}

public Optional<SonarInstallation> byName(String name) {
return Stream.of(SonarGlobalConfiguration.get().getInstallations())
.filter(installation -> name.equals(installation.getName()))
.findFirst();
}

public SonarInstallation create(String serverUrl) {
SonarInstallation sonarInstallation =
new SonarInstallation(
UUID.randomUUID().toString(), serverUrl, null, null, null, null, null, null, null);

SonarGlobalConfiguration.get()
.setInstallations(
ArrayUtils.add(SonarGlobalConfiguration.get().getInstallations(), sonarInstallation));
return sonarInstallation;
}
}
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
<?jelly escape-by-default='true'?>
<j:jelly xmlns:j="jelly:core" xmlns:f="/lib/form">
<f:entry title="${%jenkins.plugin.settings.inspection.server.url}" field="serverURL">
<f:textbox default="${descriptor.SONAR_URL}" placeholder="${descriptor.SONAR_URL}"/>

<f:entry title="${%jenkins.plugin.settings.inspection.sonar-qube.installation}" field="sonarQubeInstallationName">
<f:select />
</f:entry>

<f:radioBlock name="type"
Expand Down Expand Up @@ -38,4 +39,4 @@
</f:entry>
</f:nested>
</f:radioBlock>
</j:jelly>
</j:jelly>
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
jenkins.plugin.settings.inspection.server.url=Server URL
jenkins.plugin.settings.inspection.sonar-qube.installation=SonarQube installation
jenkins.plugin.settings.inspection.base.config=Project configuration
jenkins.plugin.settings.inspection.base.config.allow.auto.match=Allow auto match
jenkins.plugin.settings.inspection.list.configs=Sub-project configurations

This file was deleted.

Loading

0 comments on commit 33583c8

Please sign in to comment.