* now use Sonar Runner embedded to run Sonar * also updated Maven plugins to make Sonar build pass with Maven 3.1tags/3.7
@@ -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/xsd/maven-4.0.0.xsd"> | |||
<modelVersion>4.0.0</modelVersion> | |||
<parent> | |||
<groupId>org.codehaus.sonar</groupId> | |||
<artifactId>sonar</artifactId> | |||
<version>3.7-SNAPSHOT</version> | |||
</parent> | |||
<groupId>org.codehaus.sonar.plugins</groupId> | |||
<artifactId>sonar-maven-batch-plugin</artifactId> | |||
<packaging>sonar-plugin</packaging> | |||
<name>Sonar :: Maven Batch Plugin</name> | |||
<properties> | |||
<maven.api.version>3.0</maven.api.version> | |||
</properties> | |||
<dependencies> | |||
<dependency> | |||
<groupId>org.codehaus.sonar</groupId> | |||
<artifactId>sonar-batch</artifactId> | |||
<version>${project.version}</version> | |||
<scope>provided</scope> | |||
</dependency> | |||
<dependency> | |||
<groupId>org.codehaus.sonar</groupId> | |||
<artifactId>sonar-plugin-api</artifactId> | |||
<scope>provided</scope> | |||
</dependency> | |||
<dependency> | |||
<groupId>org.apache.maven</groupId> | |||
<artifactId>maven-plugin-api</artifactId> | |||
<scope>provided</scope> | |||
</dependency> | |||
<dependency> | |||
<groupId>org.apache.maven</groupId> | |||
<artifactId>maven-core</artifactId> | |||
<scope>provided</scope> | |||
</dependency> | |||
<!-- <dependency> | |||
<groupId>org.apache.maven</groupId> | |||
<artifactId>maven-project</artifactId> | |||
<scope>provided</scope> | |||
</dependency> --> | |||
</dependencies> | |||
<build> | |||
<plugins> | |||
<plugin> | |||
<groupId>org.codehaus.sonar</groupId> | |||
<artifactId>sonar-packaging-maven-plugin</artifactId> | |||
<configuration> | |||
<pluginName>Maven Batch Plugin</pluginName> | |||
<pluginClass>org.sonar.plugins.maven.MavenBatchPlugin</pluginClass> | |||
</configuration> | |||
</plugin> | |||
</plugins> | |||
</build> | |||
</project> |
@@ -0,0 +1,33 @@ | |||
/* | |||
* SonarQube, open source software quality management tool. | |||
* Copyright (C) 2008-2013 SonarSource | |||
* mailto:contact AT sonarsource DOT com | |||
* | |||
* SonarQube 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. | |||
* | |||
* SonarQube 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 this program; if not, write to the Free Software Foundation, | |||
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. | |||
*/ | |||
package org.sonar.plugins.maven; | |||
import com.google.common.collect.ImmutableList; | |||
import org.sonar.api.SonarPlugin; | |||
import java.util.List; | |||
public final class MavenBatchPlugin extends SonarPlugin { | |||
public List getExtensions() { | |||
return ImmutableList.builder().add(SonarMavenProjectBuilder.class, MavenPluginExecutor.class) | |||
.build(); | |||
} | |||
} |
@@ -0,0 +1,96 @@ | |||
/* | |||
* SonarQube, open source software quality management tool. | |||
* Copyright (C) 2008-2013 SonarSource | |||
* mailto:contact AT sonarsource DOT com | |||
* | |||
* SonarQube 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. | |||
* | |||
* SonarQube 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 this program; if not, write to the Free Software Foundation, | |||
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. | |||
*/ | |||
package org.sonar.plugins.maven; | |||
import org.apache.maven.execution.MavenSession; | |||
import org.apache.maven.execution.ReactorManager; | |||
import org.apache.maven.lifecycle.LifecycleExecutor; | |||
import org.apache.maven.project.MavenProject; | |||
import org.sonar.api.batch.SupportedEnvironment; | |||
import org.sonar.api.task.TaskExtension; | |||
import org.sonar.api.utils.SonarException; | |||
import org.sonar.batch.scan.maven.AbstractMavenPluginExecutor; | |||
import java.lang.reflect.Method; | |||
import java.util.Arrays; | |||
@SupportedEnvironment("maven") | |||
public class MavenPluginExecutor extends AbstractMavenPluginExecutor implements TaskExtension { | |||
private LifecycleExecutor lifecycleExecutor; | |||
private MavenSession mavenSession; | |||
public MavenPluginExecutor(LifecycleExecutor le, MavenSession mavenSession) { | |||
this.lifecycleExecutor = le; | |||
this.mavenSession = mavenSession; | |||
} | |||
@Override | |||
public void concreteExecute(MavenProject pom, String goal) throws Exception { | |||
Method executeMethod = null; | |||
for (Method m : lifecycleExecutor.getClass().getMethods()) { | |||
if (m.getName().equals("execute")) { | |||
executeMethod = m; | |||
break; | |||
} | |||
} | |||
if (executeMethod == null) { | |||
throw new SonarException("Unable to find execute method on Maven LifecycleExecutor. Please check your Maven version."); | |||
} | |||
if (executeMethod.getParameterTypes().length == 1) { | |||
concreteExecuteMaven3(pom, goal); | |||
} | |||
else if (executeMethod.getParameterTypes().length == 3) { | |||
concreteExecuteMaven2(executeMethod, pom, goal); | |||
} | |||
else { | |||
throw new SonarException("Unexpected parameter count on Maven LifecycleExecutor#execute method. Please check your Maven version."); | |||
} | |||
} | |||
public void concreteExecuteMaven3(MavenProject pom, String goal) { | |||
MavenSession projectSession = mavenSession.clone(); | |||
projectSession.setCurrentProject(pom); | |||
projectSession.setProjects(Arrays.asList(pom)); | |||
projectSession.getRequest().setRecursive(false); | |||
projectSession.getRequest().setPom(pom.getFile()); | |||
projectSession.getRequest().setGoals(Arrays.asList(goal)); | |||
projectSession.getRequest().setInteractiveMode(false); | |||
lifecycleExecutor.execute(projectSession); | |||
if (projectSession.getResult().hasExceptions()) { | |||
throw new SonarException("Exception during execution of " + goal); | |||
} | |||
} | |||
public void concreteExecuteMaven2(Method executeMethod, MavenProject pom, String goal) throws Exception { | |||
ReactorManager reactor = new ReactorManager(Arrays.asList(pom)); | |||
MavenSession clonedSession = new MavenSession(mavenSession.getContainer(), | |||
mavenSession.getSettings(), | |||
mavenSession.getLocalRepository(), | |||
mavenSession.getEventDispatcher(), | |||
reactor, | |||
Arrays.asList(goal), | |||
mavenSession.getExecutionRootDirectory(), | |||
mavenSession.getExecutionProperties(), | |||
mavenSession.getStartTime()); | |||
executeMethod.invoke(lifecycleExecutor, clonedSession, reactor, clonedSession.getEventDispatcher()); | |||
} | |||
} |
@@ -0,0 +1,53 @@ | |||
/* | |||
* SonarQube, open source software quality management tool. | |||
* Copyright (C) 2008-2013 SonarSource | |||
* mailto:contact AT sonarsource DOT com | |||
* | |||
* SonarQube 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. | |||
* | |||
* SonarQube 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 this program; if not, write to the Free Software Foundation, | |||
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. | |||
*/ | |||
package org.sonar.plugins.maven; | |||
import org.apache.maven.execution.MavenSession; | |||
import org.apache.maven.project.MavenProject; | |||
import org.sonar.api.batch.SupportedEnvironment; | |||
import org.sonar.api.batch.bootstrap.ProjectBuilder; | |||
import org.sonar.api.batch.bootstrap.ProjectBuilderContext; | |||
import org.sonar.batch.scan.maven.MavenProjectConverter; | |||
import java.util.List; | |||
@SupportedEnvironment("maven") | |||
public class SonarMavenProjectBuilder extends ProjectBuilder { | |||
private MavenSession session; | |||
public SonarMavenProjectBuilder(MavenSession session) { | |||
this.session = session; | |||
} | |||
@Override | |||
public void build(ProjectBuilderContext context) { | |||
List<MavenProject> sortedProjects = session.getSortedProjects(); | |||
MavenProject topLevelProject = null; | |||
for (MavenProject project : sortedProjects) { | |||
if (project.isExecutionRoot()) { | |||
topLevelProject = project; | |||
break; | |||
} | |||
} | |||
MavenProjectConverter.configure(context.getProjectReactor().getRoot(), sortedProjects, topLevelProject); | |||
} | |||
} |
@@ -38,6 +38,7 @@ | |||
<module>plugins/sonar-design-plugin</module> | |||
<module>plugins/sonar-l10n-en-plugin</module> | |||
<module>plugins/sonar-email-notifications-plugin</module> | |||
<module>plugins/sonar-maven-batch-plugin</module> | |||
</modules> | |||
<organization> | |||
@@ -77,6 +78,7 @@ | |||
<jetty.version>7.6.11.v20130520</jetty.version> | |||
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> | |||
<maven.min.version>2.2.1</maven.min.version> | |||
<maven.api.version>2.2.0</maven.api.version> | |||
<jdk.min.version>1.6</jdk.min.version> | |||
<timestamp>${maven.build.timestamp}</timestamp> | |||
<maven.build.timestamp.format>yyyy-MM-dd'T'HH:mm:ssZ</maven.build.timestamp.format> | |||
@@ -153,13 +155,12 @@ | |||
<plugin> | |||
<groupId>org.apache.maven.plugins</groupId> | |||
<artifactId>maven-compiler-plugin</artifactId> | |||
<version>3.0</version> | |||
<version>3.1</version> | |||
</plugin> | |||
<plugin> | |||
<!-- not thread safe --> | |||
<groupId>org.apache.maven.plugins</groupId> | |||
<artifactId>maven-dependency-plugin</artifactId> | |||
<version>2.5.1</version> | |||
<version>2.7</version> | |||
</plugin> | |||
<plugin> | |||
<groupId>org.apache.maven.plugins</groupId> | |||
@@ -174,7 +175,7 @@ | |||
<plugin> | |||
<groupId>org.apache.maven.plugins</groupId> | |||
<artifactId>maven-failsafe-plugin</artifactId> | |||
<version>2.12</version> | |||
<version>2.15</version> | |||
</plugin> | |||
<plugin> | |||
<groupId>org.apache.maven.plugins</groupId> | |||
@@ -219,7 +220,7 @@ | |||
<plugin> | |||
<groupId>org.apache.maven.plugins</groupId> | |||
<artifactId>maven-plugin-plugin</artifactId> | |||
<version>2.9</version> | |||
<version>3.2</version> | |||
</plugin> | |||
<plugin> | |||
<groupId>org.apache.maven.plugins</groupId> | |||
@@ -250,12 +251,12 @@ | |||
<plugin> | |||
<groupId>org.apache.maven.plugins</groupId> | |||
<artifactId>maven-surefire-plugin</artifactId> | |||
<version>2.12.4</version> | |||
<version>2.14.1</version> | |||
</plugin> | |||
<plugin> | |||
<groupId>org.apache.maven.plugins</groupId> | |||
<artifactId>maven-war-plugin</artifactId> | |||
<version>2.1.1</version> | |||
<version>2.3</version> | |||
</plugin> | |||
<plugin> | |||
<!-- not thread safe --> | |||
@@ -266,7 +267,7 @@ | |||
<plugin> | |||
<groupId>org.codehaus.sonar</groupId> | |||
<artifactId>sonar-packaging-maven-plugin</artifactId> | |||
<version>1.6</version> | |||
<version>1.7</version> | |||
</plugin> | |||
</plugins> | |||
</pluginManagement> | |||
@@ -902,7 +903,7 @@ | |||
<dependency> | |||
<groupId>org.apache.maven</groupId> | |||
<artifactId>maven-core</artifactId> | |||
<version>2.0.7</version> | |||
<version>${maven.api.version}</version> | |||
<exclusions> | |||
<exclusion> | |||
<!-- See SONAR-2455 --> | |||
@@ -914,17 +915,17 @@ | |||
<dependency> | |||
<groupId>org.apache.maven</groupId> | |||
<artifactId>maven-plugin-api</artifactId> | |||
<version>2.0.7</version> | |||
<version>${maven.api.version}</version> | |||
</dependency> | |||
<dependency> | |||
<groupId>org.apache.maven</groupId> | |||
<artifactId>maven-artifact</artifactId> | |||
<version>2.0.7</version> | |||
<version>${maven.api.version}</version> | |||
</dependency> | |||
<dependency> | |||
<groupId>org.apache.maven</groupId> | |||
<artifactId>maven-project</artifactId> | |||
<version>2.0.7</version> | |||
<version>${maven.api.version}</version> | |||
<exclusions> | |||
<exclusion> | |||
<!-- See SONAR-2455 --> | |||
@@ -936,7 +937,7 @@ | |||
<dependency> | |||
<groupId>org.apache.maven.shared</groupId> | |||
<artifactId>maven-dependency-tree</artifactId> | |||
<version>1.2</version> | |||
<version>2.1</version> | |||
<exclusions> | |||
<exclusion> | |||
<!-- See SONAR-2455 --> | |||
@@ -948,7 +949,7 @@ | |||
<dependency> | |||
<groupId>org.apache.maven.shared</groupId> | |||
<artifactId>maven-common-artifact-filters</artifactId> | |||
<version>1.2</version> | |||
<version>1.4</version> | |||
</dependency> | |||
<dependency> | |||
<groupId>org.jruby</groupId> |
@@ -146,6 +146,13 @@ | |||
<artifactId>sonar-java-plugin</artifactId> | |||
<scope>runtime</scope> | |||
</dependency> | |||
<dependency> | |||
<groupId>org.codehaus.sonar.plugins</groupId> | |||
<artifactId>sonar-maven-batch-plugin</artifactId> | |||
<version>${project.version}</version> | |||
<scope>runtime</scope> | |||
</dependency> | |||
<dependency> | |||
<groupId>org.sonatype.jsw-binaries</groupId> | |||
<artifactId>jsw-binaries</artifactId> |
@@ -55,7 +55,7 @@ public final class Batch { | |||
} | |||
projectReactor = builder.projectReactor; | |||
if (builder.isEnableLoggingConfiguration()) { | |||
logging = LoggingConfiguration.create().setProperties(bootstrapProperties); | |||
logging = LoggingConfiguration.create(builder.environment).setProperties(bootstrapProperties); | |||
} | |||
} | |||
@@ -19,10 +19,13 @@ | |||
*/ | |||
package org.sonar.batch.bootstrapper; | |||
import com.google.common.annotations.VisibleForTesting; | |||
import com.google.common.collect.Maps; | |||
import org.apache.commons.lang.StringUtils; | |||
import org.sonar.core.config.Logback; | |||
import javax.annotation.Nullable; | |||
import java.io.File; | |||
import java.util.Map; | |||
@@ -43,19 +46,26 @@ public final class LoggingConfiguration { | |||
public static final String LEVEL_SQL_RESULTS_VERBOSE = "DEBUG"; | |||
public static final String LEVEL_SQL_RESULTS_DEFAULT = "WARN"; | |||
public static final String FORMAT_DEFAULT = "%d{HH:mm:ss.SSS} %-5level - %msg%n"; | |||
public static final String FORMAT_MAVEN = "[%level] [%d{HH:mm:ss.SSS}] %msg%n"; | |||
@VisibleForTesting | |||
static final String FORMAT_DEFAULT = "%d{HH:mm:ss.SSS} %-5level - %msg%n"; | |||
@VisibleForTesting | |||
static final String FORMAT_MAVEN = "[%level] [%d{HH:mm:ss.SSS}] %msg%n"; | |||
private Map<String, String> substitutionVariables = Maps.newHashMap(); | |||
private LoggingConfiguration() { | |||
private LoggingConfiguration(@Nullable EnvironmentInformation environment) { | |||
setVerbose(false); | |||
setShowSql(false); | |||
setFormat(FORMAT_DEFAULT); | |||
if (environment != null && "maven".equalsIgnoreCase(environment.getKey())) { | |||
setFormat(FORMAT_MAVEN); | |||
} | |||
else { | |||
setFormat(FORMAT_DEFAULT); | |||
} | |||
} | |||
static LoggingConfiguration create() { | |||
return new LoggingConfiguration(); | |||
static LoggingConfiguration create(@Nullable EnvironmentInformation environment) { | |||
return new LoggingConfiguration(environment); | |||
} | |||
public LoggingConfiguration setProperties(Map<String, String> properties) { | |||
@@ -89,7 +99,8 @@ public final class LoggingConfiguration { | |||
return addSubstitutionVariable(PROPERTY_SQL_RESULTS_LOGGER_LEVEL, level); | |||
} | |||
public LoggingConfiguration setFormat(String format) { | |||
@VisibleForTesting | |||
LoggingConfiguration setFormat(String format) { | |||
return addSubstitutionVariable(PROPERTY_FORMAT, StringUtils.defaultIfBlank(format, FORMAT_DEFAULT)); | |||
} | |||
@@ -20,6 +20,8 @@ | |||
package org.sonar.batch.scan.maven; | |||
import com.google.common.annotations.VisibleForTesting; | |||
import com.google.common.base.Predicate; | |||
import com.google.common.collect.Collections2; | |||
import com.google.common.collect.Lists; | |||
import com.google.common.collect.Maps; | |||
import org.apache.commons.lang.StringUtils; | |||
@@ -50,6 +52,12 @@ public class MavenProjectConverter { | |||
} | |||
public static ProjectDefinition convert(List<MavenProject> poms, MavenProject root) { | |||
ProjectDefinition def = ProjectDefinition.create(); | |||
configure(def, poms, root); | |||
return def; | |||
} | |||
public static void configure(ProjectDefinition rootProjectDefinition, List<MavenProject> poms, MavenProject root) { | |||
// projects by canonical path to pom.xml | |||
Map<String, MavenProject> paths = Maps.newHashMap(); | |||
Map<MavenProject, ProjectDefinition> defs = Maps.newHashMap(); | |||
@@ -57,7 +65,9 @@ public class MavenProjectConverter { | |||
try { | |||
for (MavenProject pom : poms) { | |||
paths.put(pom.getFile().getCanonicalPath(), pom); | |||
defs.put(pom, convert(pom)); | |||
ProjectDefinition def = pom == root ? rootProjectDefinition : ProjectDefinition.create(); | |||
merge(pom, def); | |||
defs.put(pom, def); | |||
} | |||
for (Map.Entry<String, MavenProject> entry : paths.entrySet()) { | |||
@@ -86,7 +96,6 @@ public class MavenProjectConverter { | |||
if (rootProject == null) { | |||
throw new IllegalStateException(UNABLE_TO_DETERMINE_PROJECT_STRUCTURE_EXCEPTION_MESSAGE); | |||
} | |||
return rootProject; | |||
} | |||
private static MavenProject findMavenProject(final File modulePath, Map<String, MavenProject> paths) throws IOException { | |||
@@ -104,27 +113,29 @@ public class MavenProjectConverter { | |||
} | |||
@VisibleForTesting | |||
static ProjectDefinition convert(MavenProject pom) { | |||
String key = new StringBuilder().append(pom.getGroupId()).append(":").append(pom.getArtifactId()).toString(); | |||
ProjectDefinition definition = ProjectDefinition.create(); | |||
static void merge(MavenProject pom, ProjectDefinition definition) { | |||
String key = getSonarKey(pom); | |||
// IMPORTANT NOTE : reference on properties from POM model must not be saved, | |||
// instead they should be copied explicitly - see SONAR-2896 | |||
definition | |||
.setProperties(pom.getModel().getProperties()) | |||
.setKey(key) | |||
.setVersion(pom.getVersion()) | |||
.setName(pom.getName()) | |||
.setDescription(pom.getDescription()) | |||
.addContainerExtension(pom); | |||
.setProperties(pom.getModel().getProperties()) | |||
.setKey(key) | |||
.setVersion(pom.getVersion()) | |||
.setName(pom.getName()) | |||
.setDescription(pom.getDescription()) | |||
.addContainerExtension(pom); | |||
guessJavaVersion(pom, definition); | |||
guessEncoding(pom, definition); | |||
convertMavenLinksToProperties(definition, pom); | |||
synchronizeFileSystem(pom, definition); | |||
return definition; | |||
} | |||
public static String getSonarKey(MavenProject pom) { | |||
return new StringBuilder().append(pom.getGroupId()).append(":").append(pom.getArtifactId()).toString(); | |||
} | |||
private static void guessEncoding(MavenProject pom, ProjectDefinition definition) { | |||
//See http://jira.codehaus.org/browse/SONAR-2151 | |||
// See http://jira.codehaus.org/browse/SONAR-2151 | |||
String encoding = MavenUtils.getSourceEncoding(pom); | |||
if (encoding != null) { | |||
definition.setProperty(CoreProperties.ENCODING_PROPERTY, encoding); | |||
@@ -178,27 +189,47 @@ public class MavenProjectConverter { | |||
public static void synchronizeFileSystem(MavenProject pom, ProjectDefinition into) { | |||
into.setBaseDir(pom.getBasedir()); | |||
File buildDir = resolvePath(pom.getBuild().getDirectory(), pom.getBasedir()); | |||
File buildDir = getBuildDir(pom); | |||
if (buildDir != null) { | |||
into.setBuildDir(buildDir); | |||
into.setWorkDir(new File(buildDir, "sonar")); | |||
into.setWorkDir(getSonarWorkDir(pom)); | |||
} | |||
into.setSourceDirs((String[]) pom.getCompileSourceRoots().toArray(new String[pom.getCompileSourceRoots().size()])); | |||
into.setTestDirs((String[]) pom.getTestCompileSourceRoots().toArray(new String[pom.getTestCompileSourceRoots().size()])); | |||
List<String> filteredCompileSourceRoots = filterExisting(pom.getCompileSourceRoots(), pom.getBasedir()); | |||
List<String> filteredTestCompileSourceRoots = filterExisting(pom.getTestCompileSourceRoots(), pom.getBasedir()); | |||
into.setSourceDirs((String[]) filteredCompileSourceRoots.toArray(new String[filteredCompileSourceRoots.size()])); | |||
into.setTestDirs((String[]) filteredTestCompileSourceRoots.toArray(new String[filteredTestCompileSourceRoots.size()])); | |||
File binaryDir = resolvePath(pom.getBuild().getOutputDirectory(), pom.getBasedir()); | |||
if (binaryDir != null) { | |||
into.addBinaryDir(binaryDir); | |||
} | |||
} | |||
public static File getSonarWorkDir(MavenProject pom) { | |||
return new File(getBuildDir(pom), "sonar"); | |||
} | |||
private static File getBuildDir(MavenProject pom) { | |||
return resolvePath(pom.getBuild().getDirectory(), pom.getBasedir()); | |||
} | |||
private static List<String> filterExisting(List<String> filePaths, final File baseDir) { | |||
return Lists.newArrayList(Collections2.filter(filePaths, new Predicate<String>() { | |||
@Override | |||
public boolean apply(String filePath) { | |||
File file = resolvePath(filePath, baseDir); | |||
return file != null && file.exists(); | |||
} | |||
})); | |||
} | |||
public static void synchronizeFileSystem(MavenProject pom, DefaultModuleFileSystem into) { | |||
into.resetDirs( | |||
pom.getBasedir(), | |||
resolvePath(pom.getBuild().getDirectory(), pom.getBasedir()), | |||
resolvePaths((List<String>) pom.getCompileSourceRoots(), pom.getBasedir()), | |||
resolvePaths((List<String>) pom.getTestCompileSourceRoots(), pom.getBasedir()), | |||
Arrays.asList(resolvePath(pom.getBuild().getOutputDirectory(), pom.getBasedir())) | |||
); | |||
pom.getBasedir(), | |||
getBuildDir(pom), | |||
resolvePaths((List<String>) pom.getCompileSourceRoots(), pom.getBasedir()), | |||
resolvePaths((List<String>) pom.getTestCompileSourceRoots(), pom.getBasedir()), | |||
Arrays.asList(resolvePath(pom.getBuild().getOutputDirectory(), pom.getBasedir())) | |||
); | |||
} | |||
static File resolvePath(String path, File basedir) { |
@@ -20,102 +20,107 @@ | |||
package org.sonar.batch.bootstrapper; | |||
import com.google.common.collect.Maps; | |||
import org.hamcrest.core.Is; | |||
import org.junit.Test; | |||
import java.util.Map; | |||
import static org.junit.Assert.assertThat; | |||
import static org.fest.assertions.Assertions.assertThat; | |||
public class LoggingConfigurationTest { | |||
@Test | |||
public void testSqlLevel() { | |||
assertThat(LoggingConfiguration.create().setShowSql(true) | |||
.getSubstitutionVariable(LoggingConfiguration.PROPERTY_SQL_LOGGER_LEVEL), Is.is(LoggingConfiguration.LEVEL_SQL_VERBOSE)); | |||
assertThat(LoggingConfiguration.create(null).setShowSql(true) | |||
.getSubstitutionVariable(LoggingConfiguration.PROPERTY_SQL_LOGGER_LEVEL)).isEqualTo(LoggingConfiguration.LEVEL_SQL_VERBOSE); | |||
assertThat(LoggingConfiguration.create().setShowSql(false) | |||
.getSubstitutionVariable(LoggingConfiguration.PROPERTY_SQL_LOGGER_LEVEL), Is.is(LoggingConfiguration.LEVEL_SQL_DEFAULT)); | |||
assertThat(LoggingConfiguration.create(null).setShowSql(false) | |||
.getSubstitutionVariable(LoggingConfiguration.PROPERTY_SQL_LOGGER_LEVEL)).isEqualTo(LoggingConfiguration.LEVEL_SQL_DEFAULT); | |||
assertThat(LoggingConfiguration.create().setSqlLevel("ERROR") | |||
.getSubstitutionVariable(LoggingConfiguration.PROPERTY_SQL_LOGGER_LEVEL), Is.is("ERROR")); | |||
assertThat(LoggingConfiguration.create(null).setSqlLevel("ERROR") | |||
.getSubstitutionVariable(LoggingConfiguration.PROPERTY_SQL_LOGGER_LEVEL)).isEqualTo("ERROR"); | |||
} | |||
@Test | |||
public void shouldNotShowSqlByDefault() { | |||
assertThat(LoggingConfiguration.create() | |||
.getSubstitutionVariable(LoggingConfiguration.PROPERTY_SQL_LOGGER_LEVEL), Is.is(LoggingConfiguration.LEVEL_SQL_DEFAULT)); | |||
assertThat(LoggingConfiguration.create(null) | |||
.getSubstitutionVariable(LoggingConfiguration.PROPERTY_SQL_LOGGER_LEVEL)).isEqualTo(LoggingConfiguration.LEVEL_SQL_DEFAULT); | |||
} | |||
@Test | |||
public void testSetVerbose() { | |||
assertThat(LoggingConfiguration.create().setVerbose(true) | |||
.getSubstitutionVariable(LoggingConfiguration.PROPERTY_ROOT_LOGGER_LEVEL), Is.is(LoggingConfiguration.LEVEL_ROOT_VERBOSE)); | |||
assertThat(LoggingConfiguration.create(null).setVerbose(true) | |||
.getSubstitutionVariable(LoggingConfiguration.PROPERTY_ROOT_LOGGER_LEVEL)).isEqualTo(LoggingConfiguration.LEVEL_ROOT_VERBOSE); | |||
assertThat(LoggingConfiguration.create().setVerbose(false) | |||
.getSubstitutionVariable(LoggingConfiguration.PROPERTY_ROOT_LOGGER_LEVEL), Is.is(LoggingConfiguration.LEVEL_ROOT_DEFAULT)); | |||
assertThat(LoggingConfiguration.create(null).setVerbose(false) | |||
.getSubstitutionVariable(LoggingConfiguration.PROPERTY_ROOT_LOGGER_LEVEL)).isEqualTo(LoggingConfiguration.LEVEL_ROOT_DEFAULT); | |||
assertThat(LoggingConfiguration.create().setRootLevel("ERROR") | |||
.getSubstitutionVariable(LoggingConfiguration.PROPERTY_ROOT_LOGGER_LEVEL), Is.is("ERROR")); | |||
assertThat(LoggingConfiguration.create(null).setRootLevel("ERROR") | |||
.getSubstitutionVariable(LoggingConfiguration.PROPERTY_ROOT_LOGGER_LEVEL)).isEqualTo("ERROR"); | |||
} | |||
@Test | |||
public void shouldNotBeVerboseByDefault() { | |||
assertThat(LoggingConfiguration.create() | |||
.getSubstitutionVariable(LoggingConfiguration.PROPERTY_ROOT_LOGGER_LEVEL), Is.is(LoggingConfiguration.LEVEL_ROOT_DEFAULT)); | |||
assertThat(LoggingConfiguration.create(null) | |||
.getSubstitutionVariable(LoggingConfiguration.PROPERTY_ROOT_LOGGER_LEVEL)).isEqualTo(LoggingConfiguration.LEVEL_ROOT_DEFAULT); | |||
} | |||
@Test | |||
public void testSetVerboseProperty() { | |||
Map<String, String> properties = Maps.newHashMap(); | |||
assertThat(LoggingConfiguration.create().setProperties(properties) | |||
.getSubstitutionVariable(LoggingConfiguration.PROPERTY_ROOT_LOGGER_LEVEL), Is.is(LoggingConfiguration.LEVEL_ROOT_DEFAULT)); | |||
assertThat(LoggingConfiguration.create(null).setProperties(properties) | |||
.getSubstitutionVariable(LoggingConfiguration.PROPERTY_ROOT_LOGGER_LEVEL)).isEqualTo(LoggingConfiguration.LEVEL_ROOT_DEFAULT); | |||
properties.put("sonar.verbose", "true"); | |||
assertThat(LoggingConfiguration.create().setProperties(properties) | |||
.getSubstitutionVariable(LoggingConfiguration.PROPERTY_ROOT_LOGGER_LEVEL), Is.is(LoggingConfiguration.LEVEL_ROOT_VERBOSE)); | |||
assertThat(LoggingConfiguration.create(null).setProperties(properties) | |||
.getSubstitutionVariable(LoggingConfiguration.PROPERTY_ROOT_LOGGER_LEVEL)).isEqualTo(LoggingConfiguration.LEVEL_ROOT_VERBOSE); | |||
properties.put("sonar.verbose", "false"); | |||
assertThat(LoggingConfiguration.create().setProperties(properties) | |||
.getSubstitutionVariable(LoggingConfiguration.PROPERTY_ROOT_LOGGER_LEVEL), Is.is(LoggingConfiguration.LEVEL_ROOT_DEFAULT)); | |||
assertThat(LoggingConfiguration.create(null).setProperties(properties) | |||
.getSubstitutionVariable(LoggingConfiguration.PROPERTY_ROOT_LOGGER_LEVEL)).isEqualTo(LoggingConfiguration.LEVEL_ROOT_DEFAULT); | |||
} | |||
@Test | |||
public void testSetShowSqlProperty() { | |||
Map<String, String> properties = Maps.newHashMap(); | |||
assertThat(LoggingConfiguration.create().setProperties(properties) | |||
.getSubstitutionVariable(LoggingConfiguration.PROPERTY_SQL_LOGGER_LEVEL), Is.is(LoggingConfiguration.LEVEL_SQL_DEFAULT)); | |||
assertThat(LoggingConfiguration.create(null).setProperties(properties) | |||
.getSubstitutionVariable(LoggingConfiguration.PROPERTY_SQL_LOGGER_LEVEL)).isEqualTo(LoggingConfiguration.LEVEL_SQL_DEFAULT); | |||
properties.put("sonar.showSql", "true"); | |||
assertThat(LoggingConfiguration.create().setProperties(properties) | |||
.getSubstitutionVariable(LoggingConfiguration.PROPERTY_SQL_LOGGER_LEVEL), Is.is(LoggingConfiguration.LEVEL_SQL_VERBOSE)); | |||
assertThat(LoggingConfiguration.create(null).setProperties(properties) | |||
.getSubstitutionVariable(LoggingConfiguration.PROPERTY_SQL_LOGGER_LEVEL)).isEqualTo(LoggingConfiguration.LEVEL_SQL_VERBOSE); | |||
properties.put("sonar.showSql", "false"); | |||
assertThat(LoggingConfiguration.create().setProperties(properties) | |||
.getSubstitutionVariable(LoggingConfiguration.PROPERTY_SQL_LOGGER_LEVEL), Is.is(LoggingConfiguration.LEVEL_SQL_DEFAULT)); | |||
assertThat(LoggingConfiguration.create(null).setProperties(properties) | |||
.getSubstitutionVariable(LoggingConfiguration.PROPERTY_SQL_LOGGER_LEVEL)).isEqualTo(LoggingConfiguration.LEVEL_SQL_DEFAULT); | |||
} | |||
@Test | |||
public void testDefaultFormat() { | |||
assertThat(LoggingConfiguration.create() | |||
.getSubstitutionVariable(LoggingConfiguration.PROPERTY_FORMAT), Is.is(LoggingConfiguration.FORMAT_DEFAULT)); | |||
assertThat(LoggingConfiguration.create(null) | |||
.getSubstitutionVariable(LoggingConfiguration.PROPERTY_FORMAT)).isEqualTo(LoggingConfiguration.FORMAT_DEFAULT); | |||
} | |||
@Test | |||
public void testMavenFormat() { | |||
assertThat(LoggingConfiguration.create(new EnvironmentInformation("maven", "1.0")) | |||
.getSubstitutionVariable(LoggingConfiguration.PROPERTY_FORMAT)).isEqualTo(LoggingConfiguration.FORMAT_MAVEN); | |||
} | |||
@Test | |||
public void testSetFormat() { | |||
assertThat(LoggingConfiguration.create().setFormat("%d %level") | |||
.getSubstitutionVariable(LoggingConfiguration.PROPERTY_FORMAT), Is.is("%d %level")); | |||
assertThat(LoggingConfiguration.create(null).setFormat("%d %level") | |||
.getSubstitutionVariable(LoggingConfiguration.PROPERTY_FORMAT)).isEqualTo("%d %level"); | |||
} | |||
@Test | |||
public void shouldNotSetBlankFormat() { | |||
assertThat(LoggingConfiguration.create().setFormat(null) | |||
.getSubstitutionVariable(LoggingConfiguration.PROPERTY_FORMAT), Is.is(LoggingConfiguration.FORMAT_DEFAULT)); | |||
assertThat(LoggingConfiguration.create(null).setFormat(null) | |||
.getSubstitutionVariable(LoggingConfiguration.PROPERTY_FORMAT)).isEqualTo(LoggingConfiguration.FORMAT_DEFAULT); | |||
assertThat(LoggingConfiguration.create().setFormat("") | |||
.getSubstitutionVariable(LoggingConfiguration.PROPERTY_FORMAT), Is.is(LoggingConfiguration.FORMAT_DEFAULT)); | |||
assertThat(LoggingConfiguration.create(null).setFormat("") | |||
.getSubstitutionVariable(LoggingConfiguration.PROPERTY_FORMAT)).isEqualTo(LoggingConfiguration.FORMAT_DEFAULT); | |||
assertThat(LoggingConfiguration.create().setFormat(" ") | |||
.getSubstitutionVariable(LoggingConfiguration.PROPERTY_FORMAT), Is.is(LoggingConfiguration.FORMAT_DEFAULT)); | |||
assertThat(LoggingConfiguration.create(null).setFormat(" ") | |||
.getSubstitutionVariable(LoggingConfiguration.PROPERTY_FORMAT)).isEqualTo(LoggingConfiguration.FORMAT_DEFAULT); | |||
} | |||
} |
@@ -105,7 +105,8 @@ public class MavenProjectConverterTest { | |||
pom.setDescription("just test"); | |||
pom.setFile(new File("/foo/pom.xml")); | |||
pom.getBuild().setDirectory("target"); | |||
ProjectDefinition project = MavenProjectConverter.convert(pom); | |||
ProjectDefinition project = ProjectDefinition.create(); | |||
MavenProjectConverter.merge(pom, project); | |||
Properties properties = project.getProperties(); | |||
assertThat(properties.getProperty(CoreProperties.PROJECT_KEY_PROPERTY), is("foo:bar")); |
@@ -10,45 +10,29 @@ | |||
<packaging>maven-plugin</packaging> | |||
<name>Sonar :: Maven2 Plugin</name> | |||
<properties> | |||
<maven.version>2.0.7</maven.version> | |||
</properties> | |||
<dependencies> | |||
<dependency> | |||
<groupId>org.apache.maven.shared</groupId> | |||
<artifactId>maven-dependency-tree</artifactId> | |||
<version>1.2</version> | |||
</dependency> | |||
<dependency> | |||
<groupId>org.codehaus.sonar</groupId> | |||
<artifactId>sonar-batch</artifactId> | |||
<version>${project.version}</version> | |||
</dependency> | |||
<dependency> | |||
<groupId>org.slf4j</groupId> | |||
<artifactId>slf4j-api</artifactId> | |||
</dependency> | |||
<dependency> | |||
<groupId>ch.qos.logback</groupId> | |||
<artifactId>logback-classic</artifactId> | |||
<groupId>org.codehaus.sonar.runner</groupId> | |||
<artifactId>sonar-runner-api</artifactId> | |||
<version>2.3-SNAPSHOT</version> | |||
</dependency> | |||
<dependency> | |||
<groupId>org.apache.maven</groupId> | |||
<artifactId>maven-plugin-api</artifactId> | |||
<version>${maven.version}</version> | |||
<scope>provided</scope> | |||
</dependency> | |||
<dependency> | |||
<groupId>org.apache.maven</groupId> | |||
<artifactId>maven-core</artifactId> | |||
<version>${maven.version}</version> | |||
<scope>provided</scope> | |||
</dependency> | |||
<dependency> | |||
<groupId>org.apache.maven</groupId> | |||
<artifactId>maven-project</artifactId> | |||
<version>${maven.version}</version> | |||
<scope>provided</scope> | |||
</dependency> | |||
</dependencies> |
@@ -1,55 +0,0 @@ | |||
/* | |||
* SonarQube, open source software quality management tool. | |||
* Copyright (C) 2008-2013 SonarSource | |||
* mailto:contact AT sonarsource DOT com | |||
* | |||
* SonarQube 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. | |||
* | |||
* SonarQube 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 this program; if not, write to the Free Software Foundation, | |||
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. | |||
*/ | |||
package org.sonar.maven; | |||
import org.apache.maven.execution.MavenSession; | |||
import org.apache.maven.execution.ReactorManager; | |||
import org.apache.maven.lifecycle.LifecycleExecutor; | |||
import org.apache.maven.project.MavenProject; | |||
import org.sonar.batch.scan.maven.AbstractMavenPluginExecutor; | |||
import java.util.Arrays; | |||
public class Maven2PluginExecutor extends AbstractMavenPluginExecutor { | |||
private LifecycleExecutor lifecycleExecutor; | |||
private MavenSession mavenSession; | |||
public Maven2PluginExecutor(LifecycleExecutor le, MavenSession mavenSession) { | |||
this.lifecycleExecutor = le; | |||
this.mavenSession = mavenSession; | |||
} | |||
@Override | |||
public void concreteExecute(MavenProject pom, String goal) throws Exception { | |||
ReactorManager reactor = new ReactorManager(Arrays.asList(pom)); | |||
MavenSession clonedSession = new MavenSession(mavenSession.getContainer(), | |||
mavenSession.getSettings(), | |||
mavenSession.getLocalRepository(), | |||
mavenSession.getEventDispatcher(), | |||
reactor, | |||
Arrays.asList(goal), | |||
mavenSession.getExecutionRootDirectory(), | |||
mavenSession.getExecutionProperties(), | |||
mavenSession.getStartTime()); | |||
lifecycleExecutor.execute(clonedSession, reactor, clonedSession.getEventDispatcher()); | |||
} | |||
} |
@@ -19,7 +19,6 @@ | |||
*/ | |||
package org.sonar.maven; | |||
import com.google.common.collect.Maps; | |||
import org.apache.maven.artifact.factory.ArtifactFactory; | |||
import org.apache.maven.artifact.metadata.ArtifactMetadataSource; | |||
import org.apache.maven.artifact.repository.ArtifactRepository; | |||
@@ -30,16 +29,17 @@ import org.apache.maven.lifecycle.LifecycleExecutor; | |||
import org.apache.maven.plugin.AbstractMojo; | |||
import org.apache.maven.plugin.MojoExecutionException; | |||
import org.apache.maven.plugin.MojoFailureException; | |||
import org.apache.maven.plugin.PluginManager; | |||
import org.apache.maven.project.MavenProject; | |||
import org.apache.maven.project.MavenProjectBuilder; | |||
import org.apache.maven.shared.dependency.tree.DependencyTreeBuilder; | |||
import org.sonar.api.batch.bootstrap.ProjectDefinition; | |||
import org.sonar.api.batch.bootstrap.ProjectReactor; | |||
import org.sonar.batch.scan.maven.MavenProjectConverter; | |||
import org.sonar.batch.bootstrapper.Batch; | |||
import org.sonar.batch.bootstrapper.EnvironmentInformation; | |||
import org.sonar.batch.bootstrapper.LoggingConfiguration; | |||
import org.sonar.runner.api.EmbeddedRunner; | |||
import org.sonar.runner.api.RunnerProperties; | |||
import org.sonar.runner.api.ScanProperties; | |||
import java.io.File; | |||
import java.io.IOException; | |||
import java.util.Map.Entry; | |||
import java.util.Set; | |||
/** | |||
* @goal sonar | |||
@@ -68,12 +68,6 @@ public final class SonarMojo extends AbstractMojo { | |||
*/ | |||
private LifecycleExecutor lifecycleExecutor; | |||
/** | |||
* @component | |||
* @required | |||
*/ | |||
private PluginManager pluginManager; | |||
/** | |||
* The artifact factory to use. | |||
* | |||
@@ -134,32 +128,82 @@ public final class SonarMojo extends AbstractMojo { | |||
private RuntimeInformation runtimeInformation; | |||
public void execute() throws MojoExecutionException, MojoFailureException { | |||
ProjectDefinition def = MavenProjectConverter.convert(session.getSortedProjects(), project); | |||
ProjectReactor reactor = new ProjectReactor(def); | |||
Batch batch = Batch.builder() | |||
.setEnvironment(getEnvironmentInformation()) | |||
.setProjectReactor(reactor) | |||
.addComponents( | |||
session, getLog(), lifecycleExecutor, pluginManager, artifactFactory, | |||
localRepository, artifactMetadataSource, artifactCollector, dependencyTreeBuilder, | |||
projectBuilder, Maven2PluginExecutor.class) | |||
.build(); | |||
configureLogging(batch.getLoggingConfiguration()); | |||
batch.execute(); | |||
} | |||
private void configureLogging(LoggingConfiguration logging) { | |||
logging.setProperties(Maps.fromProperties(session.getExecutionProperties())); | |||
logging.setFormat(LoggingConfiguration.FORMAT_MAVEN); | |||
EmbeddedRunner runner = EmbeddedRunner.create() | |||
.setApp("Maven", getMavenVersion()); | |||
Set<Entry<Object, Object>> properties = project.getModel().getProperties().entrySet(); | |||
for (Entry<Object, Object> entry : properties) { | |||
runner.setProperty(toString(entry.getKey()), toString(entry.getValue())); | |||
} | |||
String encoding = getSourceEncoding(project); | |||
if (encoding != null) { | |||
runner.setProperty(ScanProperties.PROJECT_SOURCE_ENCODING, encoding); | |||
} | |||
runner | |||
.setProperty(ScanProperties.PROJECT_KEY, getSonarKey(project)) | |||
.setProperty(RunnerProperties.WORK_DIR, getSonarWorkDir(project).getAbsolutePath()) | |||
.setProperty(ScanProperties.PROJECT_BASEDIR, project.getBasedir().getAbsolutePath()) | |||
.setProperty(ScanProperties.PROJECT_VERSION, toString(project.getVersion())) | |||
.setProperty(ScanProperties.PROJECT_NAME, toString(project.getName())) | |||
.setProperty(ScanProperties.PROJECT_DESCRIPTION, toString(project.getDescription())) | |||
.setProperty(ScanProperties.PROJECT_SOURCE_DIRS, "."); | |||
// Exclude log implementation to not conflict with Maven 3.1 logging impl | |||
runner.mask("org.slf4j.LoggerFactory") | |||
// Include slf4j Logger that is exposed by some Sonar components | |||
.unmask("org.slf4j.Logger") | |||
.unmask("org.slf4j.ILoggerFactory") | |||
// Exclude other slf4j classes | |||
// .unmask("org.slf4j.impl.") | |||
.mask("org.slf4j.") | |||
// Exclude logback | |||
.mask("ch.qos.logback."); | |||
runner.mask("org.sonar."); | |||
// Include everything else | |||
runner.unmask("") | |||
.addExtensions(session, getLog(), lifecycleExecutor, artifactFactory, localRepository, artifactMetadataSource, artifactCollector, | |||
dependencyTreeBuilder, projectBuilder); | |||
if (getLog().isDebugEnabled()) { | |||
logging.setVerbose(true); | |||
runner.setProperty("sonar.verbose", "true"); | |||
} | |||
runner.execute(); | |||
} | |||
private String getMavenVersion() { | |||
return runtimeInformation.getApplicationVersion().toString(); | |||
} | |||
private EnvironmentInformation getEnvironmentInformation() { | |||
String mavenVersion = runtimeInformation.getApplicationVersion().toString(); | |||
return new EnvironmentInformation("Maven", mavenVersion); | |||
public static String toString(Object obj) { | |||
return obj == null ? "" : obj.toString(); | |||
} | |||
public static String getSourceEncoding(MavenProject pom) { | |||
return pom.getProperties().getProperty("project.build.sourceEncoding"); | |||
} | |||
public static String getSonarKey(MavenProject pom) { | |||
return new StringBuilder().append(pom.getGroupId()).append(":").append(pom.getArtifactId()).toString(); | |||
} | |||
public static File getSonarWorkDir(MavenProject pom) { | |||
return new File(getBuildDir(pom), "sonar"); | |||
} | |||
private static File getBuildDir(MavenProject pom) { | |||
return resolvePath(pom.getBuild().getDirectory(), pom.getBasedir()); | |||
} | |||
static File resolvePath(String path, File basedir) { | |||
if (path != null) { | |||
File file = new File(path); | |||
if (!file.isAbsolute()) { | |||
try { | |||
file = new File(basedir, path).getCanonicalFile(); | |||
} catch (IOException e) { | |||
throw new RuntimeException("Unable to resolve path '" + path + "'", e); | |||
} | |||
} | |||
return file; | |||
} | |||
return null; | |||
} | |||
} |
@@ -0,0 +1,46 @@ | |||
/* | |||
* Sonar Eclipse | |||
* Copyright (C) 2010-2013 SonarSource | |||
* dev@sonar.codehaus.org | |||
* | |||
* This program 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. | |||
* | |||
* This program 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 this program; if not, write to the Free Software | |||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02 | |||
*/ | |||
package org.sonar.maven; | |||
public interface SonarProperties { | |||
String PROJECT_BRANCH_PROPERTY = "sonar.branch"; | |||
String PROJECT_VERSION_PROPERTY = "sonar.projectVersion"; | |||
String PROJECT_KEY_PROPERTY = "sonar.projectKey"; | |||
String PROJECT_NAME_PROPERTY = "sonar.projectName"; | |||
String PROJECT_DESCRIPTION_PROPERTY = "sonar.projectDescription"; | |||
String PROJECT_LANGUAGE_PROPERTY = "sonar.language"; | |||
String ENCODING_PROPERTY = "sonar.sourceEncoding"; | |||
String DRY_RUN_PROPERTY = "sonar.dryRun"; | |||
String DRY_RUN_OUTPUT_PROPERTY = "sonar.dryRun.export.path"; | |||
String REPORT_OUTPUT_PROPERTY = "sonar.report.export.path"; | |||
String SONAR_URL = "sonar.host.url"; | |||
String SONAR_LOGIN = "sonar.login"; | |||
String SONAR_PASSWORD = "sonar.password"; | |||
String PROJECT_BASEDIR = "sonar.projectBaseDir"; | |||
String WORK_DIR = "sonar.working.directory"; | |||
String VERBOSE_PROPERTY = "sonar.verbose"; | |||
char SEPARATOR = ','; | |||
} |
@@ -7,55 +7,13 @@ | |||
<version>3.7-SNAPSHOT</version> | |||
</parent> | |||
<artifactId>sonar-maven3-plugin</artifactId> | |||
<packaging>maven-plugin</packaging> | |||
<packaging>pom</packaging> | |||
<name>Sonar :: Maven3 Plugin</name> | |||
<properties> | |||
<maven.version>3.0</maven.version> | |||
</properties> | |||
<dependencies> | |||
<dependency> | |||
<groupId>org.apache.maven.shared</groupId> | |||
<artifactId>maven-dependency-tree</artifactId> | |||
<version>1.2</version> | |||
</dependency> | |||
<dependency> | |||
<groupId>org.codehaus.sonar</groupId> | |||
<artifactId>sonar-batch</artifactId> | |||
<version>${project.version}</version> | |||
</dependency> | |||
<dependency> | |||
<groupId>org.slf4j</groupId> | |||
<artifactId>slf4j-api</artifactId> | |||
</dependency> | |||
<dependency> | |||
<groupId>ch.qos.logback</groupId> | |||
<artifactId>logback-classic</artifactId> | |||
</dependency> | |||
<dependency> | |||
<groupId>org.apache.maven</groupId> | |||
<artifactId>maven-plugin-api</artifactId> | |||
<version>${maven.version}</version> | |||
<scope>provided</scope> | |||
</dependency> | |||
<dependency> | |||
<groupId>org.apache.maven</groupId> | |||
<artifactId>maven-core</artifactId> | |||
<version>${maven.version}</version> | |||
<scope>provided</scope> | |||
</dependency> | |||
<dependency> | |||
<groupId>org.apache.maven</groupId> | |||
<artifactId>maven-compat</artifactId> | |||
<version>${maven.version}</version> | |||
<scope>provided</scope> | |||
</dependency> | |||
<dependency> | |||
<groupId>org.apache.maven</groupId> | |||
<artifactId>maven-settings</artifactId> | |||
<version>${maven.version}</version> | |||
<scope>provided</scope> | |||
</dependency> | |||
</dependencies> | |||
<!-- Since Sonar 3.7 there is no more difference between Maven 2 and Maven 3 so relocate to Maven 2 plugin to avoid duplication --> | |||
<distributionManagement> | |||
<relocation> | |||
<artifactId>sonar-maven-plugin</artifactId> | |||
</relocation> | |||
</distributionManagement> | |||
</project> |
@@ -1,55 +0,0 @@ | |||
/* | |||
* SonarQube, open source software quality management tool. | |||
* Copyright (C) 2008-2013 SonarSource | |||
* mailto:contact AT sonarsource DOT com | |||
* | |||
* SonarQube 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. | |||
* | |||
* SonarQube 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 this program; if not, write to the Free Software Foundation, | |||
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. | |||
*/ | |||
package org.sonar.maven3; | |||
import java.util.Arrays; | |||
import org.apache.maven.execution.MavenSession; | |||
import org.apache.maven.lifecycle.LifecycleExecutor; | |||
import org.apache.maven.project.MavenProject; | |||
import org.sonar.api.utils.SonarException; | |||
import org.sonar.batch.scan.maven.AbstractMavenPluginExecutor; | |||
public class Maven3PluginExecutor extends AbstractMavenPluginExecutor { | |||
private LifecycleExecutor lifecycleExecutor; | |||
private MavenSession mavenSession; | |||
public Maven3PluginExecutor(LifecycleExecutor le, MavenSession mavenSession) { | |||
this.lifecycleExecutor = le; | |||
this.mavenSession = mavenSession; | |||
} | |||
@Override | |||
public void concreteExecute(MavenProject pom, String goal) { | |||
MavenSession projectSession = mavenSession.clone(); | |||
projectSession.setCurrentProject(pom); | |||
projectSession.setProjects(Arrays.asList(pom)); | |||
projectSession.getRequest().setRecursive(false); | |||
projectSession.getRequest().setPom(pom.getFile()); | |||
projectSession.getRequest().setGoals(Arrays.asList(goal)); | |||
projectSession.getRequest().setInteractiveMode(false); | |||
lifecycleExecutor.execute(projectSession); | |||
if (projectSession.getResult().hasExceptions()) { | |||
throw new SonarException("Exception during execution of " + goal); | |||
} | |||
} | |||
} |
@@ -1,158 +0,0 @@ | |||
/* | |||
* SonarQube, open source software quality management tool. | |||
* Copyright (C) 2008-2013 SonarSource | |||
* mailto:contact AT sonarsource DOT com | |||
* | |||
* SonarQube 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. | |||
* | |||
* SonarQube 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 this program; if not, write to the Free Software Foundation, | |||
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. | |||
*/ | |||
package org.sonar.maven3; | |||
import com.google.common.collect.Maps; | |||
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.execution.MavenSession; | |||
import org.apache.maven.execution.RuntimeInformation; | |||
import org.apache.maven.lifecycle.LifecycleExecutor; | |||
import org.apache.maven.plugin.AbstractMojo; | |||
import org.apache.maven.plugin.MojoExecutionException; | |||
import org.apache.maven.plugin.MojoFailureException; | |||
import org.apache.maven.project.MavenProject; | |||
import org.apache.maven.project.MavenProjectBuilder; | |||
import org.apache.maven.shared.dependency.tree.DependencyTreeBuilder; | |||
import org.sonar.api.batch.bootstrap.ProjectDefinition; | |||
import org.sonar.api.batch.bootstrap.ProjectReactor; | |||
import org.sonar.batch.scan.maven.MavenProjectConverter; | |||
import org.sonar.batch.bootstrapper.Batch; | |||
import org.sonar.batch.bootstrapper.EnvironmentInformation; | |||
import org.sonar.batch.bootstrapper.LoggingConfiguration; | |||
/** | |||
* @goal sonar | |||
* @aggregator | |||
* @requiresDependencyResolution test | |||
*/ | |||
public final class SonarMojo extends AbstractMojo { | |||
/** | |||
* @parameter expression="${session}" | |||
* @required | |||
* @readonly | |||
*/ | |||
private MavenSession session; | |||
/** | |||
* @parameter expression="${project}" | |||
* @required | |||
* @readonly | |||
*/ | |||
private MavenProject project; | |||
/** | |||
* @component | |||
* @required | |||
*/ | |||
private LifecycleExecutor lifecycleExecutor; | |||
/** | |||
* The artifact factory to use. | |||
* | |||
* @component | |||
* @required | |||
* @readonly | |||
*/ | |||
private ArtifactFactory artifactFactory; | |||
/** | |||
* The artifact repository to use. | |||
* | |||
* @parameter expression="${localRepository}" | |||
* @required | |||
* @readonly | |||
*/ | |||
private ArtifactRepository localRepository; | |||
/** | |||
* The artifact metadata source to use. | |||
* | |||
* @component | |||
* @required | |||
* @readonly | |||
*/ | |||
private ArtifactMetadataSource artifactMetadataSource; | |||
/** | |||
* The artifact collector to use. | |||
* | |||
* @component | |||
* @required | |||
* @readonly | |||
*/ | |||
private ArtifactCollector artifactCollector; | |||
/** | |||
* The dependency tree builder to use. | |||
* | |||
* @component | |||
* @required | |||
* @readonly | |||
*/ | |||
private DependencyTreeBuilder dependencyTreeBuilder; | |||
/** | |||
* @component | |||
* @required | |||
* @readonly | |||
*/ | |||
private MavenProjectBuilder projectBuilder; | |||
/** | |||
* @component | |||
* @required | |||
* @readonly | |||
*/ | |||
private RuntimeInformation runtimeInformation; | |||
public void execute() throws MojoExecutionException, MojoFailureException { | |||
ProjectDefinition def = MavenProjectConverter.convert(session.getProjects(), project); | |||
ProjectReactor reactor = new ProjectReactor(def); | |||
Batch batch = Batch.builder() | |||
.setEnvironment(getEnvironmentInformation()) | |||
.setProjectReactor(reactor) | |||
.addComponents( | |||
session, getLog(), lifecycleExecutor, artifactFactory, localRepository, artifactMetadataSource, artifactCollector, | |||
dependencyTreeBuilder, projectBuilder, Maven3PluginExecutor.class) | |||
.build(); | |||
configureLogging(batch.getLoggingConfiguration()); | |||
batch.execute(); | |||
} | |||
private void configureLogging(LoggingConfiguration logging) { | |||
logging.setProperties(Maps.fromProperties(session.getSystemProperties())); | |||
logging.setFormat(LoggingConfiguration.FORMAT_MAVEN); | |||
if (getLog().isDebugEnabled()) { | |||
logging.setVerbose(true); | |||
} | |||
} | |||
private EnvironmentInformation getEnvironmentInformation() { | |||
String mavenVersion = runtimeInformation.getApplicationVersion().toString(); | |||
return new EnvironmentInformation("Maven", mavenVersion); | |||
} | |||
} |