Skip to content

Commit

Permalink
feat(CI/CD): add a maven wrapper and update documentation
Browse files Browse the repository at this point in the history
  • Loading branch information
Tony-Proum committed Sep 11, 2020
1 parent da7d345 commit 543c605
Show file tree
Hide file tree
Showing 8 changed files with 660 additions and 21 deletions.
117 changes: 117 additions & 0 deletions .mvn/wrapper/MavenWrapperDownloader.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,117 @@
/*
* Copyright 2007-present the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import java.net.*;
import java.io.*;
import java.nio.channels.*;
import java.util.Properties;

public class MavenWrapperDownloader {

private static final String WRAPPER_VERSION = "0.5.6";
/**
* Default URL to download the maven-wrapper.jar from, if no 'downloadUrl' is provided.
*/
private static final String DEFAULT_DOWNLOAD_URL = "https://repo.maven.apache.org/maven2/io/takari/maven-wrapper/"
+ WRAPPER_VERSION + "/maven-wrapper-" + WRAPPER_VERSION + ".jar";

/**
* Path to the maven-wrapper.properties file, which might contain a downloadUrl property to
* use instead of the default one.
*/
private static final String MAVEN_WRAPPER_PROPERTIES_PATH =
".mvn/wrapper/maven-wrapper.properties";

/**
* Path where the maven-wrapper.jar will be saved to.
*/
private static final String MAVEN_WRAPPER_JAR_PATH =
".mvn/wrapper/maven-wrapper.jar";

/**
* Name of the property which should be used to override the default download url for the wrapper.
*/
private static final String PROPERTY_NAME_WRAPPER_URL = "wrapperUrl";

public static void main(String args[]) {
System.out.println("- Downloader started");
File baseDirectory = new File(args[0]);
System.out.println("- Using base directory: " + baseDirectory.getAbsolutePath());

// If the maven-wrapper.properties exists, read it and check if it contains a custom
// wrapperUrl parameter.
File mavenWrapperPropertyFile = new File(baseDirectory, MAVEN_WRAPPER_PROPERTIES_PATH);
String url = DEFAULT_DOWNLOAD_URL;
if(mavenWrapperPropertyFile.exists()) {
FileInputStream mavenWrapperPropertyFileInputStream = null;
try {
mavenWrapperPropertyFileInputStream = new FileInputStream(mavenWrapperPropertyFile);
Properties mavenWrapperProperties = new Properties();
mavenWrapperProperties.load(mavenWrapperPropertyFileInputStream);
url = mavenWrapperProperties.getProperty(PROPERTY_NAME_WRAPPER_URL, url);
} catch (IOException e) {
System.out.println("- ERROR loading '" + MAVEN_WRAPPER_PROPERTIES_PATH + "'");
} finally {
try {
if(mavenWrapperPropertyFileInputStream != null) {
mavenWrapperPropertyFileInputStream.close();
}
} catch (IOException e) {
// Ignore ...
}
}
}
System.out.println("- Downloading from: " + url);

File outputFile = new File(baseDirectory.getAbsolutePath(), MAVEN_WRAPPER_JAR_PATH);
if(!outputFile.getParentFile().exists()) {
if(!outputFile.getParentFile().mkdirs()) {
System.out.println(
"- ERROR creating output directory '" + outputFile.getParentFile().getAbsolutePath() + "'");
}
}
System.out.println("- Downloading to: " + outputFile.getAbsolutePath());
try {
downloadFileFromURL(url, outputFile);
System.out.println("Done");
System.exit(0);
} catch (Throwable e) {
System.out.println("- Error downloading");
e.printStackTrace();
System.exit(1);
}
}

private static void downloadFileFromURL(String urlString, File destination) throws Exception {
if (System.getenv("MVNW_USERNAME") != null && System.getenv("MVNW_PASSWORD") != null) {
String username = System.getenv("MVNW_USERNAME");
char[] password = System.getenv("MVNW_PASSWORD").toCharArray();
Authenticator.setDefault(new Authenticator() {
@Override
protected PasswordAuthentication getPasswordAuthentication() {
return new PasswordAuthentication(username, password);
}
});
}
URL website = new URL(urlString);
ReadableByteChannel rbc;
rbc = Channels.newChannel(website.openStream());
FileOutputStream fos = new FileOutputStream(destination);
fos.getChannel().transferFrom(rbc, 0, Long.MAX_VALUE);
fos.close();
rbc.close();
}

}
Binary file added .mvn/wrapper/maven-wrapper.jar
Binary file not shown.
2 changes: 2 additions & 0 deletions .mvn/wrapper/maven-wrapper.properties
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
distributionUrl=https://repo.maven.apache.org/maven2/org/apache/maven/apache-maven/3.6.3/apache-maven-3.6.3-bin.zip
wrapperUrl=https://repo.maven.apache.org/maven2/io/takari/maven-wrapper/0.5.6/maven-wrapper-0.5.6.jar
27 changes: 13 additions & 14 deletions Makefile
Original file line number Diff line number Diff line change
@@ -1,20 +1,11 @@
run-test: ## Allows to run all unit tests
@docker run --mount type=bind,src=$$(pwd),target=/usr/src -w /usr/src maven:alpine mvn test

run-integration-platform: ## Allows to run local integrations test with docker
@docker network create sonar || \
docker build --build-arg VERSION=$$VERSION --tag test-instance . && \
docker run -p 9000:9000 --name sonar-instance --net sonar test-instance

run-integration-test: ## Allows to push a report in integration platform
@docker run --mount type=bind,src=$$(pwd)/its/integration,target=/usr/src -w /usr/src --net sonar maven:alpine \
mvn clean clover:setup test clover:aggregate clover:clover sonar:sonar -Dsonar.sources=src -Dsonar.host.url=http://sonar-instance:9000

build-package: ## Allows to build artifacts
@docker run --mount type=bind,src=$$(pwd),target=/usr/src -w /usr/src maven:alpine mvn package
@./mvnw package

quality-analysis: build-package ## Allows to run static quality analyis
@docker run --mount type=bind,src=$$(pwd),target=/usr/src -w /usr/src maven:alpine mvn sonar:sonar \
@./mvnw sonar:sonar \
-Dsonar.host.url=$$SONAR_HOST_URL \
-Dsonar.login=$$SONAR_TOKEN \
-Dsonar.projectKey=$$SONAR_PROJECT_KEY \
Expand All @@ -24,12 +15,20 @@ quality-analysis: build-package ## Allows to run static quality analyis
-Dsonar.analysis.sha1=$$TRAVIS_COMMIT \
-Dsonar.analysis.repository=$$TRAVIS_REPO_SLUG

run-integration-platform: build-package ## Allows to run local integrations test with docker
@docker network create sonar || \
docker build --build-arg VERSION=$$VERSION --tag test-instance . && \
docker run -p 9000:9000 --name sonar-instance --net sonar --rm test-instance

run-integration-test: ## Allows to push a report in integration platform
@docker run --mount type=bind,src=$$(pwd)/its/integration,target=/usr/src -w /usr/src --net sonar maven:alpine \
mvn clean clover:setup test clover:aggregate clover:clover sonar:sonar -Dsonar.sources=src -Dsonar.host.url=http://sonar-instance:9000

deploy-package: ## Allows to deploy artifacts to our registry
@docker run --mount type=bind,src=$$(pwd),target=/usr/src -w /usr/src \
-e BINTRAY_USER -e BINTRAY_PASSWORD maven:alpine mvn deploy --settings travis.settings.xml
@./mvnw deploy --settings travis.settings.xml


.DEFAULT_GOAL := help
.DEFAULT_GOAL := help run-integration-platform
.PHONY: test help
help:
@grep -E '^[a-zA-Z_-]+:.*?## .*$$' $(MAKEFILE_LIST) | sort | awk 'BEGIN {FS = ":.*?## "}; {printf "\033[36m%-30s\033[0m %s\n", $$1, $$2}'
43 changes: 36 additions & 7 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,15 +3,44 @@ Sonar Clover
[![Build Status](https://travis-ci.org/sfeir-open-source/sonar-clover.svg?branch=master)](https://travis-ci.org/sfeir-open-source/sonar-clover)

## Description / Features
It provides the ability to feed SonarQube with code coverage data coming from Atlassian Clover or it's new open source version: [OpenClover](http://openclover.org/).
This project provides the ability to feed a SonarQube server with some code coverage data coming from Atlassian Clover Project or it's new open source version: [OpenClover](http://openclover.org/).
This plugin is responsible of the parsing of the clover report to make it usable in sonarqube.
Coverage report generation is handle by this project : https://github.com/openclover/clover

## Usage
To display code coverage data:
To display code coverage data in sonarqube you can install this plugin using sonarqube marketplace
![marketplace](./img/marketplace.gif)
Searching clover in the search bar should allows you to find this plugin

1. Prior to the SonarQube analysis, execute your unit tests and generate the [Clover report](http://openclover.org/doc/manual/latest/maven--quick-start-guide.html).
After installing the plugin, your sonarqube server should be able to ingest clover coverage report
generated by one of the plugin listed here https://github.com/openclover/clover (e.g: [maven](https://github.com/openclover/clover-maven-plugin), [gradle](https://github.com/openclover/gradle-clover-plugin))

1. Import this report while running the SonarQube analysis by setting the sonar.clover.reportPath (using prior version to sonarQube version 6)
or sonar.coverageReportPaths (sonarQube v7 or higher, FYI with this version, only the xml format is supported) property to the path to the Clover report.
The path may be absolute or relative to the project base directory.
Prior to be able to display coverage data from the SonarQube Server, execute your unit tests and generate the Clover report
e.g using [maven](http://openclover.org/doc/manual/latest/maven--quick-start-guide.html).
then you can use the sonar plugin to upload the report to your sonarqube instance and see the result in sonarqube

Those 2 steps can be resume by this command:
```bash
mvn clean clover:setup test clover:aggregate clover:clover sonar:sonar -Dsonar.sources=src -Dsonar.host.url=http://sonar-instance:9000
```

you can find a full example in this folder https://github.com/sfeir-open-source/sonar-clover/tree/master/its/integration

## Testing

To test the compatibility of this plugin with a specific version of sonarqube locally:
You should be able to test this integration using docker.

First start a fresh instance of sonarqube in the desired version
```bash
VERSION=<sonarqube_docker_tag> make run-integration-platform
```
This command allows to create an integration platform locally using a specific [sonarqube_docker_tag](https://hub.docker.com/_/sonarqube/?tab=tags)
This command stay on foreground, just wait for sonarqube server to be up and running (you can check that the server is running going to http://localhost:9000)

Step 2 : in another terminal run
```bash
make run-integration-test
```
this second command will build an example project and upload the clover coverage report to the sonarqube instance.

##
Binary file added img/marketplace.gif
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading

0 comments on commit 543c605

Please sign in to comment.