diff options
Diffstat (limited to 'subprojects/sonar-update-center/sonar-packaging-maven-plugin')
36 files changed, 1623 insertions, 0 deletions
diff --git a/subprojects/sonar-update-center/sonar-packaging-maven-plugin/pom.xml b/subprojects/sonar-update-center/sonar-packaging-maven-plugin/pom.xml new file mode 100644 index 00000000000..05a30c9925d --- /dev/null +++ b/subprojects/sonar-update-center/sonar-packaging-maven-plugin/pom.xml @@ -0,0 +1,132 @@ +<?xml version="1.0" encoding="UTF-8"?> +<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> + <modelVersion>4.0.0</modelVersion> + + <parent> + <groupId>org.codehaus.sonar</groupId> + <artifactId>sonar-update-center</artifactId> + <version>0.3-SNAPSHOT</version> + </parent> + <artifactId>sonar-packaging-maven-plugin</artifactId> + <packaging>maven-plugin</packaging> + <name>Sonar :: Update Center :: Maven Plugin</name> + + <properties> + <mavenVersion>2.0.9</mavenVersion> + </properties> + + <dependencies> + <dependency> + <groupId>org.codehaus.sonar</groupId> + <artifactId>sonar-update-center-common</artifactId> + </dependency> + + <!-- maven --> + <dependency> + <groupId>org.apache.maven</groupId> + <artifactId>maven-archiver</artifactId> + <version>2.2</version> + </dependency> + <dependency> + <groupId>org.apache.maven</groupId> + <artifactId>maven-artifact</artifactId> + <version>${mavenVersion}</version> + </dependency> + <dependency> + <groupId>org.apache.maven</groupId> + <artifactId>maven-project</artifactId> + <version>${mavenVersion}</version> + </dependency> + <dependency> + <groupId>org.apache.maven</groupId> + <artifactId>maven-model</artifactId> + <version>${mavenVersion}</version> + </dependency> + <dependency> + <groupId>org.apache.maven</groupId> + <artifactId>maven-plugin-api</artifactId> + <version>${mavenVersion}</version> + </dependency> + <dependency> + <groupId>org.apache.maven.shared</groupId> + <artifactId>maven-dependency-tree</artifactId> + <version>1.2</version> + </dependency> + + + <dependency> + <groupId>org.codehaus.plexus</groupId> + <artifactId>plexus-utils</artifactId> + <version>1.5.6</version> + </dependency> + + + <!-- unit tests --> + <dependency> + <groupId>junit</groupId> + <artifactId>junit</artifactId> + <scope>test</scope> + </dependency> + <dependency> + <groupId>org.hamcrest</groupId> + <artifactId>hamcrest-all</artifactId> + <scope>test</scope> + </dependency> + </dependencies> + + <build> + <plugins> + <plugin> + <groupId>org.apache.maven.plugins</groupId> + <artifactId>maven-plugin-plugin</artifactId> + <executions> + <execution> + <id>generated-helpmojo</id> + <goals> + <goal>helpmojo</goal> + </goals> + </execution> + </executions> + </plugin> + </plugins> + </build> + + <profiles> + <profile> + <id>run-its</id> + <build> + <plugins> + <plugin> + <groupId>org.apache.maven.plugins</groupId> + <artifactId>maven-invoker-plugin</artifactId> + <configuration> + <projectsDirectory>src/it</projectsDirectory> + <cloneProjectsTo>${project.build.directory}/it</cloneProjectsTo> + <pomIncludes> + <pomInclude>*/pom.xml</pomInclude> + </pomIncludes> + <postBuildHookScript>verify</postBuildHookScript> + <localRepositoryPath>${project.build.directory}/local-repo</localRepositoryPath> + <goals> + <goal>clean</goal> + <goal>install</goal> + </goals> + <settingsFile>src/it/settings.xml</settingsFile> + <!--<debug>true</debug>--> + </configuration> + <executions> + <execution> + <id>integration-test</id> + <goals> + <goal>install</goal> + <goal>run</goal> + </goals> + </execution> + </executions> + </plugin> + </plugins> + </build> + </profile> + </profiles> + +</project> diff --git a/subprojects/sonar-update-center/sonar-packaging-maven-plugin/src/it/basic/invoker.properties b/subprojects/sonar-update-center/sonar-packaging-maven-plugin/src/it/basic/invoker.properties new file mode 100644 index 00000000000..e69de29bb2d --- /dev/null +++ b/subprojects/sonar-update-center/sonar-packaging-maven-plugin/src/it/basic/invoker.properties diff --git a/subprojects/sonar-update-center/sonar-packaging-maven-plugin/src/it/basic/pom.xml b/subprojects/sonar-update-center/sonar-packaging-maven-plugin/src/it/basic/pom.xml new file mode 100644 index 00000000000..5d84396b8d8 --- /dev/null +++ b/subprojects/sonar-update-center/sonar-packaging-maven-plugin/src/it/basic/pom.xml @@ -0,0 +1,61 @@ +<?xml version="1.0" encoding="UTF-8"?> +<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd"> + <modelVersion>4.0.0</modelVersion> + + <groupId>org.codehaus.sonar</groupId> + <artifactId>test</artifactId> + <version>1.0</version> + <packaging>sonar-plugin</packaging> + + <name>Basic</name> + <description>Plugin description.</description> + <url>http://sonar-plugins.codehaus.org</url> + <organization> + <name>SonarSource</name> + <url>http://www.sonarsource.com</url> + </organization> + + <properties> + <sonar.version>2.1</sonar.version> + + <!-- sonar.pluginKey = project.artifactId by default --> + <sonar.pluginKey>test</sonar.pluginKey> + <!-- sonar.pluginName = project.name by default --> + <sonar.pluginName>Test Plugin</sonar.pluginName> + <sonar.pluginCategory>Test</sonar.pluginCategory> + <sonar.pluginClass>org.sonar.plugins.sample.SamplePlugin</sonar.pluginClass> + </properties> + + <dependencies> + <dependency> + <groupId>org.codehaus.sonar</groupId> + <artifactId>sonar-plugin-api</artifactId> + <version>${sonar.version}</version> + </dependency> + + <!-- unit tests --> + <dependency> + <groupId>org.codehaus.sonar</groupId> + <artifactId>sonar-testing-harness</artifactId> + <version>${sonar.version}</version> + <scope>test</scope> + </dependency> + </dependencies> + + <build> + <plugins> + <plugin> + <groupId>@project.groupId@</groupId> + <artifactId>@project.artifactId@</artifactId> + <version>@project.version@</version> + <extensions>true</extensions> + </plugin> + <plugin> + <groupId>org.apache.maven.plugins</groupId> + <artifactId>maven-compiler-plugin</artifactId> + <version>2.3.1</version> + </plugin> + </plugins> + </build> +</project> diff --git a/subprojects/sonar-update-center/sonar-packaging-maven-plugin/src/it/basic/src/main/java/org/sonar/plugins/sample/SampleMetrics.java b/subprojects/sonar-update-center/sonar-packaging-maven-plugin/src/it/basic/src/main/java/org/sonar/plugins/sample/SampleMetrics.java new file mode 100644 index 00000000000..f5481527763 --- /dev/null +++ b/subprojects/sonar-update-center/sonar-packaging-maven-plugin/src/it/basic/src/main/java/org/sonar/plugins/sample/SampleMetrics.java @@ -0,0 +1,26 @@ +package org.sonar.plugins.sample; + +import org.sonar.api.measures.CoreMetrics; +import org.sonar.api.measures.Metric; +import org.sonar.api.measures.Metrics; + +import java.util.Arrays; +import java.util.List; + +public class SampleMetrics implements Metrics { + + public static final Metric MESSAGE = new Metric("message_key", "Message", + "This is a metric to store a well known message", Metric.ValueType.STRING, -1, false, + CoreMetrics.DOMAIN_GENERAL); + + + public static final Metric RANDOM = new Metric("random", "Random", + "Random value", Metric.ValueType.FLOAT, Metric.DIRECTION_BETTER, false, + CoreMetrics.DOMAIN_GENERAL); + + // getMetrics() method is defined in the Metrics interface and is used by + // Sonar to retrieve the list of new Metric + public List<Metric> getMetrics() { + return Arrays.asList(MESSAGE, RANDOM); + } +} diff --git a/subprojects/sonar-update-center/sonar-packaging-maven-plugin/src/it/basic/src/main/java/org/sonar/plugins/sample/SamplePlugin.java b/subprojects/sonar-update-center/sonar-packaging-maven-plugin/src/it/basic/src/main/java/org/sonar/plugins/sample/SamplePlugin.java new file mode 100644 index 00000000000..adabe49c0bf --- /dev/null +++ b/subprojects/sonar-update-center/sonar-packaging-maven-plugin/src/it/basic/src/main/java/org/sonar/plugins/sample/SamplePlugin.java @@ -0,0 +1,45 @@ +package org.sonar.plugins.sample; + +import org.sonar.api.Extension; +import org.sonar.api.Plugin; + +import java.util.ArrayList; +import java.util.List; + +/** + * This class is the container for all others extensions + */ +public class SamplePlugin implements Plugin { + + // The key which uniquely identifies your plugin among all others Sonar plugins + + public String getKey() { + return "sample"; + } + + public String getName() { + return "My first Sonar plugin"; + } + + // This description will be displayed in the Configuration > Settings web page + + public String getDescription() { + return "You shouldn't expect too much from this plugin except displaying the Hello World message."; + } + + // This is where you're going to declare all your Sonar extensions + + public List<Class<? extends Extension>> getExtensions() { + List<Class<? extends Extension>> list = new ArrayList<Class<? extends Extension>>(); + + list.add(SampleMetrics.class); + list.add(SampleSensor.class); + + return list; + } + + @Override + public String toString() { + return getKey(); + } +} diff --git a/subprojects/sonar-update-center/sonar-packaging-maven-plugin/src/it/basic/src/main/java/org/sonar/plugins/sample/SampleSensor.java b/subprojects/sonar-update-center/sonar-packaging-maven-plugin/src/it/basic/src/main/java/org/sonar/plugins/sample/SampleSensor.java new file mode 100644 index 00000000000..6e0deb74656 --- /dev/null +++ b/subprojects/sonar-update-center/sonar-packaging-maven-plugin/src/it/basic/src/main/java/org/sonar/plugins/sample/SampleSensor.java @@ -0,0 +1,30 @@ +package org.sonar.plugins.sample; + +import org.apache.commons.lang.math.RandomUtils; +import org.sonar.api.batch.Sensor; +import org.sonar.api.batch.SensorContext; +import org.sonar.api.measures.Measure; +import org.sonar.api.resources.Project; + +public class SampleSensor implements Sensor { + + public boolean shouldExecuteOnProject(Project project) { + // this sensor is executed on any type of project + return true; + } + + public void analyse(Project project, SensorContext sensorContext) { + saveLabelMeasure(sensorContext); + saveNumericMeasure(sensorContext); + } + + private void saveNumericMeasure(SensorContext context) { + // Sonar API includes many libraries like commons-lang and google-collections + context.saveMeasure(SampleMetrics.RANDOM, RandomUtils.nextDouble()); + } + + private void saveLabelMeasure(SensorContext context) { + Measure measure = new Measure(SampleMetrics.MESSAGE, "Hello World!"); + context.saveMeasure(measure); + } +} diff --git a/subprojects/sonar-update-center/sonar-packaging-maven-plugin/src/it/basic/verify.bsh b/subprojects/sonar-update-center/sonar-packaging-maven-plugin/src/it/basic/verify.bsh new file mode 100644 index 00000000000..6e3cd1b3f83 --- /dev/null +++ b/subprojects/sonar-update-center/sonar-packaging-maven-plugin/src/it/basic/verify.bsh @@ -0,0 +1,7 @@ +import java.io.*; + +File file = new File( basedir, "target/test-1.0.jar" ); +if ( !file.isFile() ) +{ + throw new FileNotFoundException( "Could not find generated JAR: " + file ); +} diff --git a/subprojects/sonar-update-center/sonar-packaging-maven-plugin/src/it/doNotAddMavenDescriptor/invoker.properties b/subprojects/sonar-update-center/sonar-packaging-maven-plugin/src/it/doNotAddMavenDescriptor/invoker.properties new file mode 100644 index 00000000000..e69de29bb2d --- /dev/null +++ b/subprojects/sonar-update-center/sonar-packaging-maven-plugin/src/it/doNotAddMavenDescriptor/invoker.properties diff --git a/subprojects/sonar-update-center/sonar-packaging-maven-plugin/src/it/doNotAddMavenDescriptor/pom.xml b/subprojects/sonar-update-center/sonar-packaging-maven-plugin/src/it/doNotAddMavenDescriptor/pom.xml new file mode 100644 index 00000000000..b81734eab6c --- /dev/null +++ b/subprojects/sonar-update-center/sonar-packaging-maven-plugin/src/it/doNotAddMavenDescriptor/pom.xml @@ -0,0 +1,46 @@ +<?xml version="1.0" encoding="UTF-8"?> +<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd"> + <modelVersion>4.0.0</modelVersion> + + <groupId>org.codehaus.sonar</groupId> + <artifactId>test</artifactId> + <version>1.0</version> + <packaging>sonar-plugin</packaging> + + <name>Do Not Add Maven Description</name> + + <properties> + <sonar.version>2.1</sonar.version> + <sonar.pluginKey>test</sonar.pluginKey> + <sonar.pluginClass>org.sonar.plugins.sample.SamplePlugin</sonar.pluginClass> + </properties> + + <dependencies> + <dependency> + <groupId>org.codehaus.sonar</groupId> + <artifactId>sonar-plugin-api</artifactId> + <version>${sonar.version}</version> + <scope>provided</scope> + </dependency> + </dependencies> + + <build> + <plugins> + <plugin> + <groupId>@project.groupId@</groupId> + <artifactId>@project.artifactId@</artifactId> + <version>@project.version@</version> + <extensions>true</extensions> + <configuration> + <addMavenDescriptor>false</addMavenDescriptor> + </configuration> + </plugin> + <plugin> + <groupId>org.apache.maven.plugins</groupId> + <artifactId>maven-compiler-plugin</artifactId> + <version>2.3.1</version> + </plugin> + </plugins> + </build> +</project> diff --git a/subprojects/sonar-update-center/sonar-packaging-maven-plugin/src/it/doNotAddMavenDescriptor/src/main/java/org/sonar/plugins/sample/SamplePlugin.java b/subprojects/sonar-update-center/sonar-packaging-maven-plugin/src/it/doNotAddMavenDescriptor/src/main/java/org/sonar/plugins/sample/SamplePlugin.java new file mode 100644 index 00000000000..31710c3a0e6 --- /dev/null +++ b/subprojects/sonar-update-center/sonar-packaging-maven-plugin/src/it/doNotAddMavenDescriptor/src/main/java/org/sonar/plugins/sample/SamplePlugin.java @@ -0,0 +1,30 @@ +package org.sonar.plugins.sample; + +import org.sonar.api.Extension; +import org.sonar.api.Plugin; + +import java.util.Collections; +import java.util.List; + +public class SamplePlugin implements Plugin { + public String getKey() { + return "sample"; + } + + public String getName() { + return "My first Sonar plugin"; + } + + public String getDescription() { + return "You shouldn't expect too much from this plugin."; + } + + public List<Class<? extends Extension>> getExtensions() { + return Collections.emptyList(); + } + + @Override + public String toString() { + return getKey(); + } +} diff --git a/subprojects/sonar-update-center/sonar-packaging-maven-plugin/src/it/doNotAddMavenDescriptor/verify.bsh b/subprojects/sonar-update-center/sonar-packaging-maven-plugin/src/it/doNotAddMavenDescriptor/verify.bsh new file mode 100644 index 00000000000..57c863aa7e9 --- /dev/null +++ b/subprojects/sonar-update-center/sonar-packaging-maven-plugin/src/it/doNotAddMavenDescriptor/verify.bsh @@ -0,0 +1,22 @@ +import java.io.*; +import java.util.zip.*; + +File file = new File( basedir, "target/test-1.0.jar" ); +if (!file.isFile()) { + throw new FileNotFoundException( "Could not find generated JAR: " + file ); +} + +ZipFile zipFile = new ZipFile(file); +try { + if (zipFile.getEntry("META-INF/MANIFEST.MF")==null) { + throw new FileNotFoundException("Could not find manifest"); + } + if (zipFile.getEntry("META-INF/maven/org.codehaus.sonar/test/pom.xml")!=null) { + throw new FileNotFoundException("The maven descriptor (pom.xml) has not been removed"); + } + if (zipFile.getEntry("META-INF/maven/org.codehaus.sonar/test/pom.properties")!=null) { + throw new FileNotFoundException("The maven descriptor (pom.properties) has not been removed"); + } +} finally { + zipFile.close(); +}
\ No newline at end of file diff --git a/subprojects/sonar-update-center/sonar-packaging-maven-plugin/src/it/doNotPackageDepsProvidedBySonar/invoker.properties b/subprojects/sonar-update-center/sonar-packaging-maven-plugin/src/it/doNotPackageDepsProvidedBySonar/invoker.properties new file mode 100644 index 00000000000..e69de29bb2d --- /dev/null +++ b/subprojects/sonar-update-center/sonar-packaging-maven-plugin/src/it/doNotPackageDepsProvidedBySonar/invoker.properties diff --git a/subprojects/sonar-update-center/sonar-packaging-maven-plugin/src/it/doNotPackageDepsProvidedBySonar/pom.xml b/subprojects/sonar-update-center/sonar-packaging-maven-plugin/src/it/doNotPackageDepsProvidedBySonar/pom.xml new file mode 100644 index 00000000000..f794a50f99e --- /dev/null +++ b/subprojects/sonar-update-center/sonar-packaging-maven-plugin/src/it/doNotPackageDepsProvidedBySonar/pom.xml @@ -0,0 +1,44 @@ +<?xml version="1.0" encoding="UTF-8"?> +<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd"> + <modelVersion>4.0.0</modelVersion> + + <groupId>org.codehaus.sonar</groupId> + <artifactId>test</artifactId> + <version>1.0</version> + <packaging>sonar-plugin</packaging> + + <name>Do not package dependencies provided by Sonar</name> + + <dependencies> + <dependency> + <groupId>org.codehaus.sonar</groupId> + <artifactId>sonar-plugin-api</artifactId> + <version>2.1</version> + </dependency> + <dependency> + <groupId>commons-lang</groupId> + <artifactId>commons-lang</artifactId> + <version>2.5</version> + </dependency> + </dependencies> + + <build> + <plugins> + <plugin> + <groupId>@project.groupId@</groupId> + <artifactId>@project.artifactId@</artifactId> + <version>@project.version@</version> + <extensions>true</extensions> + <configuration> + <pluginClass>org.sonar.plugins.sample.SamplePlugin</pluginClass> + </configuration> + </plugin> + <plugin> + <groupId>org.apache.maven.plugins</groupId> + <artifactId>maven-compiler-plugin</artifactId> + <version>2.3.1</version> + </plugin> + </plugins> + </build> +</project> diff --git a/subprojects/sonar-update-center/sonar-packaging-maven-plugin/src/it/doNotPackageDepsProvidedBySonar/src/main/java/org/sonar/plugins/sample/SamplePlugin.java b/subprojects/sonar-update-center/sonar-packaging-maven-plugin/src/it/doNotPackageDepsProvidedBySonar/src/main/java/org/sonar/plugins/sample/SamplePlugin.java new file mode 100644 index 00000000000..31710c3a0e6 --- /dev/null +++ b/subprojects/sonar-update-center/sonar-packaging-maven-plugin/src/it/doNotPackageDepsProvidedBySonar/src/main/java/org/sonar/plugins/sample/SamplePlugin.java @@ -0,0 +1,30 @@ +package org.sonar.plugins.sample; + +import org.sonar.api.Extension; +import org.sonar.api.Plugin; + +import java.util.Collections; +import java.util.List; + +public class SamplePlugin implements Plugin { + public String getKey() { + return "sample"; + } + + public String getName() { + return "My first Sonar plugin"; + } + + public String getDescription() { + return "You shouldn't expect too much from this plugin."; + } + + public List<Class<? extends Extension>> getExtensions() { + return Collections.emptyList(); + } + + @Override + public String toString() { + return getKey(); + } +} diff --git a/subprojects/sonar-update-center/sonar-packaging-maven-plugin/src/it/doNotPackageDepsProvidedBySonar/verify.bsh b/subprojects/sonar-update-center/sonar-packaging-maven-plugin/src/it/doNotPackageDepsProvidedBySonar/verify.bsh new file mode 100644 index 00000000000..13993b92ccd --- /dev/null +++ b/subprojects/sonar-update-center/sonar-packaging-maven-plugin/src/it/doNotPackageDepsProvidedBySonar/verify.bsh @@ -0,0 +1,16 @@ +import java.io.*; +import java.util.zip.*; + +File file = new File( basedir, "target/test-1.0.jar" ); +if (!file.isFile()) { + throw new FileNotFoundException( "Could not find generated JAR: " + file ); +} + +ZipFile zipFile = new ZipFile(file); +try { + if (zipFile.getEntry("META-INF/lib/commons-lang-2.5.jar")!=null) { + throw new FileNotFoundException("The dependency commons-lang must not be copied in the plugin"); + } +} finally { + zipFile.close(); +}
\ No newline at end of file diff --git a/subprojects/sonar-update-center/sonar-packaging-maven-plugin/src/it/packageDependencies/invoker.properties b/subprojects/sonar-update-center/sonar-packaging-maven-plugin/src/it/packageDependencies/invoker.properties new file mode 100644 index 00000000000..e69de29bb2d --- /dev/null +++ b/subprojects/sonar-update-center/sonar-packaging-maven-plugin/src/it/packageDependencies/invoker.properties diff --git a/subprojects/sonar-update-center/sonar-packaging-maven-plugin/src/it/packageDependencies/pom.xml b/subprojects/sonar-update-center/sonar-packaging-maven-plugin/src/it/packageDependencies/pom.xml new file mode 100644 index 00000000000..2c7c1af0bd7 --- /dev/null +++ b/subprojects/sonar-update-center/sonar-packaging-maven-plugin/src/it/packageDependencies/pom.xml @@ -0,0 +1,45 @@ +<?xml version="1.0" encoding="UTF-8"?> +<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd"> + <modelVersion>4.0.0</modelVersion> + + <groupId>org.codehaus.sonar</groupId> + <artifactId>test</artifactId> + <version>1.0</version> + <packaging>sonar-plugin</packaging> + <name>Package dependencies</name> + + <dependencies> + <dependency> + <groupId>org.codehaus.sonar</groupId> + <artifactId>sonar-plugin-api</artifactId> + <version>1.12</version> + </dependency> + + <!-- Should be included into jar --> + <dependency> + <groupId>org.apache.commons</groupId> + <artifactId>commons-email</artifactId> + <version>1.2</version> + </dependency> + </dependencies> + + <build> + <plugins> + <plugin> + <groupId>@project.groupId@</groupId> + <artifactId>@project.artifactId@</artifactId> + <version>@project.version@</version> + <extensions>true</extensions> + <configuration> + <pluginClass>org.sonar.plugins.sample.SamplePlugin</pluginClass> + </configuration> + </plugin> + <plugin> + <groupId>org.apache.maven.plugins</groupId> + <artifactId>maven-compiler-plugin</artifactId> + <version>2.3.1</version> + </plugin> + </plugins> + </build> +</project> diff --git a/subprojects/sonar-update-center/sonar-packaging-maven-plugin/src/it/packageDependencies/src/main/java/org/sonar/plugins/sample/SamplePlugin.java b/subprojects/sonar-update-center/sonar-packaging-maven-plugin/src/it/packageDependencies/src/main/java/org/sonar/plugins/sample/SamplePlugin.java new file mode 100644 index 00000000000..31710c3a0e6 --- /dev/null +++ b/subprojects/sonar-update-center/sonar-packaging-maven-plugin/src/it/packageDependencies/src/main/java/org/sonar/plugins/sample/SamplePlugin.java @@ -0,0 +1,30 @@ +package org.sonar.plugins.sample; + +import org.sonar.api.Extension; +import org.sonar.api.Plugin; + +import java.util.Collections; +import java.util.List; + +public class SamplePlugin implements Plugin { + public String getKey() { + return "sample"; + } + + public String getName() { + return "My first Sonar plugin"; + } + + public String getDescription() { + return "You shouldn't expect too much from this plugin."; + } + + public List<Class<? extends Extension>> getExtensions() { + return Collections.emptyList(); + } + + @Override + public String toString() { + return getKey(); + } +} diff --git a/subprojects/sonar-update-center/sonar-packaging-maven-plugin/src/it/packageDependencies/verify.bsh b/subprojects/sonar-update-center/sonar-packaging-maven-plugin/src/it/packageDependencies/verify.bsh new file mode 100644 index 00000000000..8847454f986 --- /dev/null +++ b/subprojects/sonar-update-center/sonar-packaging-maven-plugin/src/it/packageDependencies/verify.bsh @@ -0,0 +1,17 @@ +import java.io.*; +import java.util.zip.*; + +File file = new File( basedir, "target/test-1.0.jar" ); +if ( !file.isFile() ) +{ + throw new FileNotFoundException( "Could not find generated JAR: " + file ); +} + +ZipFile zipFile = new ZipFile(file); +try { + if (zipFile.getEntry("META-INF/lib/commons-email-1.2.jar")!=null) { + throw new FileNotFoundException("The dependency commons-email must be copied in JAR"); + } +} finally { + zipFile.close(); +}
\ No newline at end of file diff --git a/subprojects/sonar-update-center/sonar-packaging-maven-plugin/src/it/pluginClassNotDefined/invoker.properties b/subprojects/sonar-update-center/sonar-packaging-maven-plugin/src/it/pluginClassNotDefined/invoker.properties new file mode 100644 index 00000000000..c21e972fc6b --- /dev/null +++ b/subprojects/sonar-update-center/sonar-packaging-maven-plugin/src/it/pluginClassNotDefined/invoker.properties @@ -0,0 +1 @@ +invoker.buildResult = failure diff --git a/subprojects/sonar-update-center/sonar-packaging-maven-plugin/src/it/pluginClassNotDefined/pom.xml b/subprojects/sonar-update-center/sonar-packaging-maven-plugin/src/it/pluginClassNotDefined/pom.xml new file mode 100644 index 00000000000..58915369b4b --- /dev/null +++ b/subprojects/sonar-update-center/sonar-packaging-maven-plugin/src/it/pluginClassNotDefined/pom.xml @@ -0,0 +1,40 @@ +<?xml version="1.0" encoding="UTF-8"?> +<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd"> + <modelVersion>4.0.0</modelVersion> + + <groupId>org.codehaus.sonar</groupId> + <artifactId>test</artifactId> + <version>1.0</version> + <packaging>sonar-plugin</packaging> + + <name>PluginClass not defined</name> + + <dependencies> + <dependency> + <groupId>org.codehaus.sonar</groupId> + <artifactId>sonar-plugin-api</artifactId> + <version>1.12</version> + <scope>provided</scope> + </dependency> + </dependencies> + + <build> + <plugins> + <plugin> + <groupId>@project.groupId@</groupId> + <artifactId>@project.artifactId@</artifactId> + <version>@project.version@</version> + <extensions>true</extensions> + <configuration> + <!-- MISSING <pluginClass>org.sonar.plugins.sample.SamplePlugin</pluginClass> --> + </configuration> + </plugin> + <plugin> + <groupId>org.apache.maven.plugins</groupId> + <artifactId>maven-compiler-plugin</artifactId> + <version>2.3.1</version> + </plugin> + </plugins> + </build> +</project> diff --git a/subprojects/sonar-update-center/sonar-packaging-maven-plugin/src/it/pluginClassNotDefined/src/main/java/org/sonar/plugins/sample/SampleMetrics.java b/subprojects/sonar-update-center/sonar-packaging-maven-plugin/src/it/pluginClassNotDefined/src/main/java/org/sonar/plugins/sample/SampleMetrics.java new file mode 100644 index 00000000000..f5481527763 --- /dev/null +++ b/subprojects/sonar-update-center/sonar-packaging-maven-plugin/src/it/pluginClassNotDefined/src/main/java/org/sonar/plugins/sample/SampleMetrics.java @@ -0,0 +1,26 @@ +package org.sonar.plugins.sample; + +import org.sonar.api.measures.CoreMetrics; +import org.sonar.api.measures.Metric; +import org.sonar.api.measures.Metrics; + +import java.util.Arrays; +import java.util.List; + +public class SampleMetrics implements Metrics { + + public static final Metric MESSAGE = new Metric("message_key", "Message", + "This is a metric to store a well known message", Metric.ValueType.STRING, -1, false, + CoreMetrics.DOMAIN_GENERAL); + + + public static final Metric RANDOM = new Metric("random", "Random", + "Random value", Metric.ValueType.FLOAT, Metric.DIRECTION_BETTER, false, + CoreMetrics.DOMAIN_GENERAL); + + // getMetrics() method is defined in the Metrics interface and is used by + // Sonar to retrieve the list of new Metric + public List<Metric> getMetrics() { + return Arrays.asList(MESSAGE, RANDOM); + } +} diff --git a/subprojects/sonar-update-center/sonar-packaging-maven-plugin/src/it/pluginClassNotDefined/src/main/java/org/sonar/plugins/sample/SamplePlugin.java b/subprojects/sonar-update-center/sonar-packaging-maven-plugin/src/it/pluginClassNotDefined/src/main/java/org/sonar/plugins/sample/SamplePlugin.java new file mode 100644 index 00000000000..adabe49c0bf --- /dev/null +++ b/subprojects/sonar-update-center/sonar-packaging-maven-plugin/src/it/pluginClassNotDefined/src/main/java/org/sonar/plugins/sample/SamplePlugin.java @@ -0,0 +1,45 @@ +package org.sonar.plugins.sample; + +import org.sonar.api.Extension; +import org.sonar.api.Plugin; + +import java.util.ArrayList; +import java.util.List; + +/** + * This class is the container for all others extensions + */ +public class SamplePlugin implements Plugin { + + // The key which uniquely identifies your plugin among all others Sonar plugins + + public String getKey() { + return "sample"; + } + + public String getName() { + return "My first Sonar plugin"; + } + + // This description will be displayed in the Configuration > Settings web page + + public String getDescription() { + return "You shouldn't expect too much from this plugin except displaying the Hello World message."; + } + + // This is where you're going to declare all your Sonar extensions + + public List<Class<? extends Extension>> getExtensions() { + List<Class<? extends Extension>> list = new ArrayList<Class<? extends Extension>>(); + + list.add(SampleMetrics.class); + list.add(SampleSensor.class); + + return list; + } + + @Override + public String toString() { + return getKey(); + } +} diff --git a/subprojects/sonar-update-center/sonar-packaging-maven-plugin/src/it/pluginClassNotDefined/src/main/java/org/sonar/plugins/sample/SampleSensor.java b/subprojects/sonar-update-center/sonar-packaging-maven-plugin/src/it/pluginClassNotDefined/src/main/java/org/sonar/plugins/sample/SampleSensor.java new file mode 100644 index 00000000000..6e0deb74656 --- /dev/null +++ b/subprojects/sonar-update-center/sonar-packaging-maven-plugin/src/it/pluginClassNotDefined/src/main/java/org/sonar/plugins/sample/SampleSensor.java @@ -0,0 +1,30 @@ +package org.sonar.plugins.sample; + +import org.apache.commons.lang.math.RandomUtils; +import org.sonar.api.batch.Sensor; +import org.sonar.api.batch.SensorContext; +import org.sonar.api.measures.Measure; +import org.sonar.api.resources.Project; + +public class SampleSensor implements Sensor { + + public boolean shouldExecuteOnProject(Project project) { + // this sensor is executed on any type of project + return true; + } + + public void analyse(Project project, SensorContext sensorContext) { + saveLabelMeasure(sensorContext); + saveNumericMeasure(sensorContext); + } + + private void saveNumericMeasure(SensorContext context) { + // Sonar API includes many libraries like commons-lang and google-collections + context.saveMeasure(SampleMetrics.RANDOM, RandomUtils.nextDouble()); + } + + private void saveLabelMeasure(SensorContext context) { + Measure measure = new Measure(SampleMetrics.MESSAGE, "Hello World!"); + context.saveMeasure(measure); + } +} diff --git a/subprojects/sonar-update-center/sonar-packaging-maven-plugin/src/it/pluginClassNotFound/invoker.properties b/subprojects/sonar-update-center/sonar-packaging-maven-plugin/src/it/pluginClassNotFound/invoker.properties new file mode 100644 index 00000000000..c21e972fc6b --- /dev/null +++ b/subprojects/sonar-update-center/sonar-packaging-maven-plugin/src/it/pluginClassNotFound/invoker.properties @@ -0,0 +1 @@ +invoker.buildResult = failure diff --git a/subprojects/sonar-update-center/sonar-packaging-maven-plugin/src/it/pluginClassNotFound/pom.xml b/subprojects/sonar-update-center/sonar-packaging-maven-plugin/src/it/pluginClassNotFound/pom.xml new file mode 100644 index 00000000000..31d3b0efa2c --- /dev/null +++ b/subprojects/sonar-update-center/sonar-packaging-maven-plugin/src/it/pluginClassNotFound/pom.xml @@ -0,0 +1,41 @@ +<?xml version="1.0" encoding="UTF-8"?> +<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd"> + <modelVersion>4.0.0</modelVersion> + + <groupId>org.codehaus.sonar</groupId> + <artifactId>test</artifactId> + <version>1.0</version> + <packaging>sonar-plugin</packaging> + + <name>PluginClass not found</name> + + <dependencies> + <dependency> + <groupId>org.codehaus.sonar</groupId> + <artifactId>sonar-plugin-api</artifactId> + <version>1.12</version> + <scope>provided</scope> + </dependency> + </dependencies> + + <build> + <plugins> + <plugin> + <groupId>@project.groupId@</groupId> + <artifactId>@project.artifactId@</artifactId> + <version>@project.version@</version> + <extensions>true</extensions> + <configuration> + <pluginClass>org.sonar.plugins.sample.SamplePlugin</pluginClass> + </configuration> + </plugin> + <plugin> + <groupId>org.apache.maven.plugins</groupId> + <artifactId>maven-compiler-plugin</artifactId> + <version>2.3.1</version> + </plugin> + </plugins> + </build> + +</project> diff --git a/subprojects/sonar-update-center/sonar-packaging-maven-plugin/src/it/settings.xml b/subprojects/sonar-update-center/sonar-packaging-maven-plugin/src/it/settings.xml new file mode 100644 index 00000000000..8890c85392c --- /dev/null +++ b/subprojects/sonar-update-center/sonar-packaging-maven-plugin/src/it/settings.xml @@ -0,0 +1,35 @@ +<?xml version="1.0" encoding="UTF-8"?> +<settings> + <profiles> + <profile> + <id>it-repo</id> + <activation> + <activeByDefault>true</activeByDefault> + </activation> + <repositories> + <repository> + <id>local.central</id> + <url>@localRepositoryUrl@</url> + <releases> + <enabled>true</enabled> + </releases> + <snapshots> + <enabled>true</enabled> + </snapshots> + </repository> + </repositories> + <pluginRepositories> + <pluginRepository> + <id>local.central</id> + <url>@localRepositoryUrl@</url> + <releases> + <enabled>true</enabled> + </releases> + <snapshots> + <enabled>true</enabled> + </snapshots> + </pluginRepository> + </pluginRepositories> + </profile> + </profiles> +</settings> diff --git a/subprojects/sonar-update-center/sonar-packaging-maven-plugin/src/it/sonarPluginApiNotFound/invoker.properties b/subprojects/sonar-update-center/sonar-packaging-maven-plugin/src/it/sonarPluginApiNotFound/invoker.properties new file mode 100644 index 00000000000..c21e972fc6b --- /dev/null +++ b/subprojects/sonar-update-center/sonar-packaging-maven-plugin/src/it/sonarPluginApiNotFound/invoker.properties @@ -0,0 +1 @@ +invoker.buildResult = failure diff --git a/subprojects/sonar-update-center/sonar-packaging-maven-plugin/src/it/sonarPluginApiNotFound/pom.xml b/subprojects/sonar-update-center/sonar-packaging-maven-plugin/src/it/sonarPluginApiNotFound/pom.xml new file mode 100644 index 00000000000..9b4704a142a --- /dev/null +++ b/subprojects/sonar-update-center/sonar-packaging-maven-plugin/src/it/sonarPluginApiNotFound/pom.xml @@ -0,0 +1,42 @@ +<?xml version="1.0" encoding="UTF-8"?> +<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd"> + <modelVersion>4.0.0</modelVersion> + + <groupId>org.codehaus.sonar</groupId> + <artifactId>test</artifactId> + <version>1.0</version> + <packaging>sonar-plugin</packaging> + + <name>sonar-plugin-api not found</name> + + <dependencies> + <!-- MISSING + <dependency> + <groupId>org.codehaus.sonar</groupId> + <artifactId>sonar-plugin-api</artifactId> + <version>1.12</version> + </dependency> + --> + </dependencies> + + <build> + <plugins> + <plugin> + <groupId>@project.groupId@</groupId> + <artifactId>@project.artifactId@</artifactId> + <version>@project.version@</version> + <extensions>true</extensions> + <configuration> + <pluginClass>org.sonar.plugins.sample.SamplePlugin</pluginClass> + </configuration> + </plugin> + <plugin> + <groupId>org.apache.maven.plugins</groupId> + <artifactId>maven-compiler-plugin</artifactId> + <version>2.3.1</version> + </plugin> + </plugins> + </build> + +</project> diff --git a/subprojects/sonar-update-center/sonar-packaging-maven-plugin/src/it/sonarPluginApiNotFound/src/main/java/org/sonar/plugins/sample/SamplePlugin.java b/subprojects/sonar-update-center/sonar-packaging-maven-plugin/src/it/sonarPluginApiNotFound/src/main/java/org/sonar/plugins/sample/SamplePlugin.java new file mode 100644 index 00000000000..31710c3a0e6 --- /dev/null +++ b/subprojects/sonar-update-center/sonar-packaging-maven-plugin/src/it/sonarPluginApiNotFound/src/main/java/org/sonar/plugins/sample/SamplePlugin.java @@ -0,0 +1,30 @@ +package org.sonar.plugins.sample; + +import org.sonar.api.Extension; +import org.sonar.api.Plugin; + +import java.util.Collections; +import java.util.List; + +public class SamplePlugin implements Plugin { + public String getKey() { + return "sample"; + } + + public String getName() { + return "My first Sonar plugin"; + } + + public String getDescription() { + return "You shouldn't expect too much from this plugin."; + } + + public List<Class<? extends Extension>> getExtensions() { + return Collections.emptyList(); + } + + @Override + public String toString() { + return getKey(); + } +} diff --git a/subprojects/sonar-update-center/sonar-packaging-maven-plugin/src/main/java/org/sonar/updatecenter/mavenplugin/AbstractSonarPluginMojo.java b/subprojects/sonar-update-center/sonar-packaging-maven-plugin/src/main/java/org/sonar/updatecenter/mavenplugin/AbstractSonarPluginMojo.java new file mode 100644 index 00000000000..fe6f4733348 --- /dev/null +++ b/subprojects/sonar-update-center/sonar-packaging-maven-plugin/src/main/java/org/sonar/updatecenter/mavenplugin/AbstractSonarPluginMojo.java @@ -0,0 +1,251 @@ +/* + * Sonar, open source software quality management tool. + * Copyright (C) 2009 SonarSource SA + * mailto:contact AT sonarsource DOT com + * + * Sonar 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. + * + * Sonar 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 Sonar; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02 + */ +package org.sonar.updatecenter.mavenplugin; + +import org.apache.maven.artifact.Artifact; +import org.apache.maven.artifact.resolver.filter.ScopeArtifactFilter; +import org.apache.maven.plugin.AbstractMojo; +import org.apache.maven.project.MavenProject; +import org.apache.maven.project.MavenProjectHelper; + +import java.io.File; +import java.util.HashSet; +import java.util.List; +import java.util.Set; + +/** + * Base class for Sonar-plugin-packaging related tasks. + * + * @author Evgeny Mandrikov + */ +public abstract class AbstractSonarPluginMojo extends AbstractMojo { + public static final String SONAR_GROUPID = "org.codehaus.sonar"; + public static final String SONAR_PLUGIN_API_ARTIFACTID = "sonar-plugin-api"; + public static final String SONAR_PLUGIN_API_TYPE = "jar"; + + /** + * The Maven project. + * + * @parameter expression="${project}" + * @required + * @readonly + */ + private MavenProject project; + + /** + * Directory containing the generated JAR. + * + * @parameter expression="${project.build.directory}" + * @required + */ + private File outputDirectory; + + /** + * Directory containing the classes and resource files that should be packaged into the JAR. + * + * @parameter expression="${project.build.outputDirectory}" + * @required + */ + private File classesDirectory; + + /** + * The directory where the app is built. + * + * @parameter expression="${project.build.directory}/${project.build.finalName}" + * @required + */ + private File appDirectory; + + /** + * Name of the generated JAR. + * + * @parameter alias="jarName" expression="${jar.finalName}" default-value="${project.build.finalName}" + * @required + */ + private String finalName; + + /** + * Classifier to add to the artifact generated. If given, the artifact will be an attachment instead. + * + * @parameter + */ + private String classifier; + + /** + * @component + */ + protected MavenProjectHelper projectHelper; + + /** + * Plugin key. + * + * @parameter expression="${sonar.pluginKey}" default-value="${project.artifactId}" + */ + private String pluginKey; + + /** + * @parameter expression="${sonar.pluginTermsConditionsUrl}" + */ + private String pluginTermsConditionsUrl; + + /** + * Name of plugin class. + * + * @parameter expression="${sonar.pluginClass}" + * @required + */ + private String pluginClass; + + /** + * @parameter expression="${sonar.pluginName}" default-value="${project.name}" + */ + private String pluginName; + + /** + * @parameter default-value="${project.description}" + */ + private String pluginDescription; + + /** + * @parameter default-value="${project.url}" + */ + private String pluginUrl; + + /** + * @parameter default-value="${project.issueManagement.url}" + */ + private String pluginIssueTrackerUrl; + + /** + * @parameter expression="${sonar.skipDependenciesPackaging}" + */ + private boolean skipDependenciesPackaging = false; + + protected final MavenProject getProject() { + return project; + } + + protected final File getOutputDirectory() { + return outputDirectory; + } + + /** + * @return the main classes directory, so it's used as the root of the jar. + */ + protected final File getClassesDirectory() { + return classesDirectory; + } + + public File getAppDirectory() { + return appDirectory; + } + + protected final String getFinalName() { + return finalName; + } + + protected final String getClassifier() { + return classifier; + } + + public String getPluginKey() { + return pluginKey; + } + + protected final String getPluginClass() { + return pluginClass; + } + + protected final String getPluginName() { + return pluginName; + } + + protected final String getPluginDescription() { + return pluginDescription; + } + + protected final String getPluginUrl() { + return pluginUrl; + } + + protected String getPluginTermsConditionsUrl() { + return pluginTermsConditionsUrl; + } + + protected String getPluginIssueTrackerUrl() { + return pluginIssueTrackerUrl; + } + + protected boolean isSkipDependenciesPackaging() { + return skipDependenciesPackaging; + } + + @SuppressWarnings({"unchecked"}) + protected Set<Artifact> getDependencyArtifacts() { + return getProject().getDependencyArtifacts(); + } + + protected Set<Artifact> getDependencyArtifacts(String scope) { + Set<Artifact> result = new HashSet<Artifact>(); + for (Artifact dep : getDependencyArtifacts()) { + if (scope.equals(dep.getScope())) { + result.add(dep); + } + } + return result; + } + + @SuppressWarnings({"unchecked"}) + protected Set<Artifact> getIncludedArtifacts() { + Set<Artifact> result = new HashSet<Artifact>(); + Set<Artifact> artifacts = getProject().getArtifacts(); + ScopeArtifactFilter filter = new ScopeArtifactFilter(Artifact.SCOPE_RUNTIME); + for (Artifact artifact : artifacts) { + if (filter.include(artifact)) { + result.add(artifact); + } + } + return result; + } + + protected final Artifact getSonarPluginApiArtifact() { + Set<Artifact> dependencies = getDependencyArtifacts(); + if (dependencies != null) { + for (Artifact dep : dependencies) { + if (SONAR_GROUPID.equals(dep.getGroupId()) + && SONAR_PLUGIN_API_ARTIFACTID.equals(dep.getArtifactId()) + && SONAR_PLUGIN_API_TYPE.equals(dep.getType())) { + return dep; + } + } + } + return null; + } + + protected String getMessage(String title, List<String> ids) { + StringBuilder message = new StringBuilder(); + message.append(title); + message.append("\n\n"); + for (String id : ids) { + message.append("\t").append(id).append("\n"); + } + return message.toString(); + } +} diff --git a/subprojects/sonar-update-center/sonar-packaging-maven-plugin/src/main/java/org/sonar/updatecenter/mavenplugin/CheckDependenciesMojo.java b/subprojects/sonar-update-center/sonar-packaging-maven-plugin/src/main/java/org/sonar/updatecenter/mavenplugin/CheckDependenciesMojo.java new file mode 100644 index 00000000000..d6051802ea0 --- /dev/null +++ b/subprojects/sonar-update-center/sonar-packaging-maven-plugin/src/main/java/org/sonar/updatecenter/mavenplugin/CheckDependenciesMojo.java @@ -0,0 +1,88 @@ +/* + * Sonar, open source software quality management tool. + * Copyright (C) 2009 SonarSource SA + * mailto:contact AT sonarsource DOT com + * + * Sonar 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. + * + * Sonar 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 Sonar; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02 + */ +package org.sonar.updatecenter.mavenplugin; + +import org.apache.commons.lang.ArrayUtils; +import org.apache.commons.lang.StringUtils; +import org.apache.maven.artifact.Artifact; +import org.apache.maven.plugin.MojoExecutionException; +import org.apache.maven.plugin.MojoFailureException; + +import java.util.ArrayList; +import java.util.List; + +/** + * @author Evgeny Mandrikov + * @goal check-dependencies + * @requiresDependencyResolution runtime + * @phase initialize + */ +public class CheckDependenciesMojo extends AbstractSonarPluginMojo { + + private static final String[] GWT_ARTIFACT_IDS = {"gwt-user", "gwt-dev", "sonar-gwt-api"}; + private static final String[] LOG_GROUP_IDS = {"log4j", "commons-logging"}; + + public void execute() throws MojoExecutionException, MojoFailureException { + if (!isSkipDependenciesPackaging()) { + checkApiDependency(); + checkLogDependencies(); + checkGwtDependencies(); + } + } + + private void checkApiDependency() throws MojoExecutionException { + Artifact sonarApi = getSonarPluginApiArtifact(); + + if (sonarApi == null) { + throw new MojoExecutionException( + SONAR_GROUPID + ":" + SONAR_PLUGIN_API_ARTIFACTID + " should be declared in dependencies" + ); + } + } + + private void checkLogDependencies() throws MojoExecutionException { + List<String> ids = new ArrayList<String>(); + for (Artifact dep : getIncludedArtifacts()) { + if (ArrayUtils.contains(LOG_GROUP_IDS, dep.getGroupId())) { + ids.add(dep.getDependencyConflictId()); + } + } + if (!ids.isEmpty()) { + StringBuilder message = new StringBuilder(); + message.append("Dependencies on the following log libraries should be excluded or declared with scope 'provided':") + .append("\n\t") + .append(StringUtils.join(ids, ", ")) + .append('\n'); + getLog().warn(message.toString()); + } + } + + private void checkGwtDependencies() { + List<String> ids = new ArrayList<String>(); + for (Artifact dep : getDependencyArtifacts(Artifact.SCOPE_COMPILE)) { + if (ArrayUtils.contains(GWT_ARTIFACT_IDS, dep.getArtifactId())) { + ids.add(dep.getDependencyConflictId()); + } + } + if (!ids.isEmpty()) { + getLog().warn(getMessage("GWT dependencies should be defined with scope 'provided':", ids)); + } + } +} diff --git a/subprojects/sonar-update-center/sonar-packaging-maven-plugin/src/main/java/org/sonar/updatecenter/mavenplugin/SonarPluginMojo.java b/subprojects/sonar-update-center/sonar-packaging-maven-plugin/src/main/java/org/sonar/updatecenter/mavenplugin/SonarPluginMojo.java new file mode 100644 index 00000000000..2caa56b4582 --- /dev/null +++ b/subprojects/sonar-update-center/sonar-packaging-maven-plugin/src/main/java/org/sonar/updatecenter/mavenplugin/SonarPluginMojo.java @@ -0,0 +1,337 @@ +/* + * Sonar, open source software quality management tool. + * Copyright (C) 2009 SonarSource SA + * mailto:contact AT sonarsource DOT com + * + * Sonar 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. + * + * Sonar 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 Sonar; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02 + */ +package org.sonar.updatecenter.mavenplugin; + +import org.apache.commons.lang.StringUtils; +import org.apache.maven.archiver.MavenArchiveConfiguration; +import org.apache.maven.archiver.MavenArchiver; +import org.apache.maven.artifact.Artifact; +import org.apache.maven.artifact.factory.ArtifactFactory; +import org.apache.maven.artifact.metadata.ArtifactMetadataSource; +import org.apache.maven.artifact.repository.ArtifactRepository; +import org.apache.maven.artifact.resolver.ArtifactCollector; +import org.apache.maven.artifact.resolver.filter.ArtifactFilter; +import org.apache.maven.artifact.resolver.filter.ScopeArtifactFilter; +import org.apache.maven.model.License; +import org.apache.maven.plugin.MojoExecutionException; +import org.apache.maven.plugin.MojoFailureException; +import org.apache.maven.shared.dependency.tree.DependencyNode; +import org.apache.maven.shared.dependency.tree.DependencyTreeBuilder; +import org.apache.maven.shared.dependency.tree.DependencyTreeBuilderException; +import org.apache.maven.shared.dependency.tree.traversal.BuildingDependencyNodeVisitor; +import org.codehaus.plexus.archiver.jar.JarArchiver; +import org.codehaus.plexus.util.FileUtils; +import org.sonar.updatecenter.common.FormatUtils; +import org.sonar.updatecenter.common.PluginManifest; + +import java.io.File; +import java.io.IOException; +import java.util.*; + +/** + * Build a Sonar Plugin from the current project. + * + * @author Evgeny Mandrikov + * @goal sonar-plugin + * @phase package + * @requiresProject + * @requiresDependencyResolution runtime + */ +public class SonarPluginMojo extends AbstractSonarPluginMojo { + private static final String LIB_DIR = "META-INF/lib/"; + private static final String[] DEFAULT_EXCLUDES = new String[]{"**/package.html"}; + private static final String[] DEFAULT_INCLUDES = new String[]{"**/**"}; + + /** + * List of files to include. Specified as fileset patterns which are relative to the input directory whose contents + * is being packaged into the JAR. + * + * @parameter + */ + private String[] includes; + + /** + * List of files to exclude. Specified as fileset patterns which are relative to the input directory whose contents + * is being packaged into the JAR. + * + * @parameter + */ + private String[] excludes; + + /** + * The Jar archiver. + * + * @component role="org.codehaus.plexus.archiver.Archiver" role-hint="jar" + */ + protected JarArchiver jarArchiver; + + /** + * The archive configuration to use. + * See <a href="http://maven.apache.org/shared/maven-archiver/index.html">Maven Archiver Reference</a>. + * + * @parameter + */ + private MavenArchiveConfiguration archive = new MavenArchiveConfiguration(); + + /** + * @component + * @required + * @readonly + */ + private DependencyTreeBuilder dependencyTreeBuilder; + + /** + * The artifact repository to use. + * + * @parameter expression="${localRepository}" + * @required + * @readonly + */ + private ArtifactRepository localRepository; + + /** + * The artifact factory to use. + * + * @component + * @required + * @readonly + */ + private ArtifactFactory artifactFactory; + + /** + * The artifact metadata source to use. + * + * @component + * @required + * @readonly + */ + private ArtifactMetadataSource artifactMetadataSource; + + /** + * The artifact collector to use. + * + * @component + * @required + * @readonly + */ + private ArtifactCollector artifactCollector; + + /** + * @parameter expression="${sonar.addMavenDescriptor}" + */ + private boolean addMavenDescriptor = true; + + public void execute() throws MojoExecutionException, MojoFailureException { + File jarFile = createArchive(); + String classifier = getClassifier(); + if (classifier != null) { + projectHelper.attachArtifact(getProject(), "jar", classifier, jarFile); + } else { + getProject().getArtifact().setFile(jarFile); + } + } + + public File createArchive() throws MojoExecutionException { + checkPluginClass(); + + File jarFile = getJarFile(getOutputDirectory(), getFinalName(), getClassifier()); + MavenArchiver archiver = new MavenArchiver(); + archiver.setArchiver(jarArchiver); + archiver.setOutputFile(jarFile); + + try { + archiver.getArchiver().addDirectory(getClassesDirectory(), getIncludes(), getExcludes()); + archive.setAddMavenDescriptor(addMavenDescriptor); + getLog().info("-------------------------------------------------------"); + getLog().info("Plugin definition in update center"); + addManifestProperty("Key", PluginManifest.KEY, getPluginKey()); + addManifestProperty("Name", PluginManifest.NAME, getPluginName()); + addManifestProperty("Description", PluginManifest.DESCRIPTION, getPluginDescription()); + addManifestProperty("Version", PluginManifest.VERSION, getProject().getVersion()); + addManifestProperty("Main class", PluginManifest.MAIN_CLASS, getPluginClass()); + addManifestProperty("Homepage", PluginManifest.HOMEPAGE, getPluginUrl()); + addManifestProperty("Sonar version", PluginManifest.SONAR_VERSION, getSonarPluginApiArtifact().getVersion()); + addManifestProperty("License", PluginManifest.LICENSE, getPluginLicense()); + addManifestProperty("Organization", PluginManifest.ORGANIZATION, getPluginOrganization()); + addManifestProperty("Organization URL", PluginManifest.ORGANIZATION_URL, getPluginOrganizationUrl()); + addManifestProperty("Terms & Conditions URL", PluginManifest.TERMS_CONDITIONS_URL, getPluginTermsConditionsUrl()); + addManifestProperty("Issue Tracker URL", PluginManifest.ISSUE_TRACKER_URL, getPluginIssueTrackerUrl()); + addManifestProperty("Build date", PluginManifest.BUILD_DATE, FormatUtils.toString(new Date(), true)); + getLog().info("-------------------------------------------------------"); + + if (isSkipDependenciesPackaging()) { + getLog().info("Skip packaging of dependencies"); + + } else { + List<String> libs = copyDependencies(); + if (!libs.isEmpty()) { + archiver.getArchiver().addDirectory(getAppDirectory(), getIncludes(), getExcludes()); + archive.addManifestEntry(PluginManifest.DEPENDENCIES, StringUtils.join(libs, " ")); + } + } + + archiver.createArchive(getProject(), archive); + return jarFile; + + } catch (Exception e) { + throw new MojoExecutionException("Error assembling Sonar-plugin: " + e.getMessage(), e); + } + } + + private void addManifestProperty(String label, String key, String value) { + getLog().info(" " + label + ": " + StringUtils.defaultString(value)); + archive.addManifestEntry(key, value); + } + + private String getPluginLicense() { + List<String> licenses = new ArrayList<String>(); + if (getProject().getLicenses() != null) { + for (Object license : getProject().getLicenses()) { + License l = (License) license; + if (l.getName() != null) { + licenses.add(l.getName()); + } + } + } + return StringUtils.join(licenses, " "); + } + + private String getPluginOrganization() { + if (getProject().getOrganization() != null) { + return getProject().getOrganization().getName(); + } + return null; + } + + private String getPluginOrganizationUrl() { + if (getProject().getOrganization() != null) { + return getProject().getOrganization().getUrl(); + } + return null; + } + + + private void checkPluginClass() throws MojoExecutionException { + if (!new File(getClassesDirectory(), getPluginClass().replace('.', '/') + ".class").exists()) { + throw new MojoExecutionException("Error assembling Sonar-plugin: Plugin-Class '" + getPluginClass() + "' not found"); + } + } + + protected static File getJarFile(File basedir, String finalName, String classifier) { + if (classifier == null) { + classifier = ""; + } else if (classifier.trim().length() > 0 && !classifier.startsWith("-")) { + classifier = "-" + classifier; + } + return new File(basedir, finalName + classifier + ".jar"); + } + + + private List<String> copyDependencies() throws IOException, DependencyTreeBuilderException { + List<String> ids = new ArrayList<String>(); + List<String> libs = new ArrayList<String>(); + File libDirectory = new File(getAppDirectory(), LIB_DIR); + Set<Artifact> artifacts = getNotProvidedDependencies(); + for (Artifact artifact : artifacts) { + String targetFileName = getDefaultFinalName(artifact); + FileUtils.copyFileIfModified(artifact.getFile(), new File(libDirectory, targetFileName)); + libs.add(LIB_DIR + targetFileName); + ids.add(artifact.getDependencyConflictId()); + } + + if (!ids.isEmpty()) { + getLog().info(getMessage("Following dependencies are packaged in the plugin:", ids)); + getLog().info(new StringBuilder() + .append("See following page for more details about plugin dependencies:\n") + .append("\n\thttp://docs.codehaus.org/display/SONAR/Coding+a+plugin\n") + .toString() + ); + } + return libs; + } + + private String getDefaultFinalName(Artifact artifact) { + return artifact.getArtifactId() + "-" + artifact.getVersion() + "." + artifact.getArtifactHandler().getExtension(); + } + + + private Set<Artifact> getNotProvidedDependencies() throws DependencyTreeBuilderException { + Set<Artifact> result = new HashSet<Artifact>(); + Set<Artifact> providedArtifacts = getSonarProvidedArtifacts(); + for (Artifact artifact : getIncludedArtifacts()) { + if (!Artifact.SCOPE_PROVIDED.equals(artifact.getScope()) && !Artifact.SCOPE_TEST.equals(artifact.getScope()) && !containsArtifact(providedArtifacts, artifact)) { + result.add(artifact); + } + } + return result; + } + + private boolean containsArtifact(Set<Artifact> artifacts, Artifact artifact) { + for (Artifact a : artifacts) { + if (StringUtils.equals(a.getGroupId(), artifact.getGroupId()) && + StringUtils.equals(a.getArtifactId(), artifact.getArtifactId())) { + return true; + } + } + return false; + } + + + private Set<Artifact> getSonarProvidedArtifacts() throws DependencyTreeBuilderException { + Set<Artifact> result = new HashSet<Artifact>(); + ArtifactFilter artifactFilter = new ScopeArtifactFilter(Artifact.SCOPE_RUNTIME); + DependencyNode rootNode = dependencyTreeBuilder.buildDependencyTree(getProject(), localRepository, artifactFactory, + artifactMetadataSource, artifactFilter, artifactCollector); + rootNode.accept(new BuildingDependencyNodeVisitor()); + searchForSonarProvidedArtifacts(rootNode, result, false); + return result; + } + + private void searchForSonarProvidedArtifacts(DependencyNode dependency, Set<Artifact> sonarArtifacts, boolean isProvidedBySonar) { + if (dependency != null) { + isProvidedBySonar = isProvidedBySonar || ("org.codehaus.sonar".equals(dependency.getArtifact().getGroupId()) && !Artifact.SCOPE_TEST.equals(dependency.getArtifact().getScope())); + + if (isProvidedBySonar) { + sonarArtifacts.add(dependency.getArtifact()); + } + + if (!Artifact.SCOPE_TEST.equals(dependency.getArtifact().getScope())) { + for (Object childDep : dependency.getChildren()) { + searchForSonarProvidedArtifacts((DependencyNode) childDep, sonarArtifacts, isProvidedBySonar); + } + } + } + } + + private String[] getIncludes() { + if (includes != null && includes.length > 0) { + return includes; + } + return DEFAULT_INCLUDES; + } + + private String[] getExcludes() { + if (excludes != null && excludes.length > 0) { + return excludes; + } + return DEFAULT_EXCLUDES; + } + +} diff --git a/subprojects/sonar-update-center/sonar-packaging-maven-plugin/src/main/resources/META-INF/plexus/components.xml b/subprojects/sonar-update-center/sonar-packaging-maven-plugin/src/main/resources/META-INF/plexus/components.xml new file mode 100644 index 00000000000..cd580be9914 --- /dev/null +++ b/subprojects/sonar-update-center/sonar-packaging-maven-plugin/src/main/resources/META-INF/plexus/components.xml @@ -0,0 +1,43 @@ +<component-set> + <components> + <component> + <role>org.apache.maven.lifecycle.mapping.LifecycleMapping</role> + <role-hint>sonar-plugin</role-hint> + <implementation>org.apache.maven.lifecycle.mapping.DefaultLifecycleMapping</implementation> + <configuration> + <lifecycles> + <lifecycle> + <id>default</id> + <phases> + <!-- Sonar specific step --> + <initialize>org.codehaus.sonar:sonar-packaging-maven-plugin:check-dependencies</initialize> + + <process-resources>org.apache.maven.plugins:maven-resources-plugin:resources</process-resources> + <compile>org.apache.maven.plugins:maven-compiler-plugin:compile</compile> + <process-test-resources>org.apache.maven.plugins:maven-resources-plugin:testResources</process-test-resources> + <test-compile>org.apache.maven.plugins:maven-compiler-plugin:testCompile</test-compile> + <test>org.apache.maven.plugins:maven-surefire-plugin:test</test> + + <!-- Sonar specific step --> + <package>org.codehaus.sonar:sonar-packaging-maven-plugin:sonar-plugin</package> + + <install>org.apache.maven.plugins:maven-install-plugin:install</install> + <deploy>org.apache.maven.plugins:maven-deploy-plugin:deploy</deploy> + </phases> + </lifecycle> + </lifecycles> + </configuration> + </component> + <component> + <role>org.apache.maven.artifact.handler.ArtifactHandler</role> + <role-hint>sonar-plugin</role-hint> + <implementation>org.apache.maven.artifact.handler.DefaultArtifactHandler</implementation> + <configuration> + <type>sonar-plugin</type> + <extension>jar</extension> + <language>java</language> + <addedToClasspath>true</addedToClasspath> + </configuration> + </component> + </components> +</component-set> diff --git a/subprojects/sonar-update-center/sonar-packaging-maven-plugin/src/main/resources/license/AL2.txt b/subprojects/sonar-update-center/sonar-packaging-maven-plugin/src/main/resources/license/AL2.txt new file mode 100644 index 00000000000..2550cc485b1 --- /dev/null +++ b/subprojects/sonar-update-center/sonar-packaging-maven-plugin/src/main/resources/license/AL2.txt @@ -0,0 +1,14 @@ +Copyright (C) ${year} ${name} +mailto: ${mail} + +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. diff --git a/subprojects/sonar-update-center/sonar-packaging-maven-plugin/src/main/resources/license/LGPL3.txt b/subprojects/sonar-update-center/sonar-packaging-maven-plugin/src/main/resources/license/LGPL3.txt new file mode 100644 index 00000000000..e7f3cc3e5ad --- /dev/null +++ b/subprojects/sonar-update-center/sonar-packaging-maven-plugin/src/main/resources/license/LGPL3.txt @@ -0,0 +1,17 @@ +Sonar, open source software quality management tool. +Copyright (C) ${year} ${name} +mailto: ${mail} + +Sonar 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. + +Sonar 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 Sonar; if not, write to the Free Software +Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02 |