]> source.dussan.org Git - sonarqube.git/commitdiff
SONAR-3979, SONAR-4047 Fix Sonar Maven goal to support Maven 3.1
authorJulien HENRY <julien.henry@sonarsource.com>
Mon, 17 Jun 2013 08:34:10 +0000 (10:34 +0200)
committerJulien HENRY <julien.henry@sonarsource.com>
Wed, 19 Jun 2013 11:49:11 +0000 (13:49 +0200)
  * now use Sonar Runner embedded to run Sonar
  * also updated Maven plugins to make Sonar build pass with Maven 3.1

18 files changed:
plugins/sonar-maven-batch-plugin/pom.xml [new file with mode: 0644]
plugins/sonar-maven-batch-plugin/src/main/java/org/sonar/plugins/maven/MavenBatchPlugin.java [new file with mode: 0644]
plugins/sonar-maven-batch-plugin/src/main/java/org/sonar/plugins/maven/MavenPluginExecutor.java [new file with mode: 0644]
plugins/sonar-maven-batch-plugin/src/main/java/org/sonar/plugins/maven/SonarMavenProjectBuilder.java [new file with mode: 0644]
pom.xml
sonar-application/pom.xml
sonar-batch/src/main/java/org/sonar/batch/bootstrapper/Batch.java
sonar-batch/src/main/java/org/sonar/batch/bootstrapper/LoggingConfiguration.java
sonar-batch/src/main/java/org/sonar/batch/scan/maven/MavenProjectConverter.java
sonar-batch/src/test/java/org/sonar/batch/bootstrapper/LoggingConfigurationTest.java
sonar-batch/src/test/java/org/sonar/batch/scan/maven/MavenProjectConverterTest.java
sonar-maven-plugin/pom.xml
sonar-maven-plugin/src/main/java/org/sonar/maven/Maven2PluginExecutor.java [deleted file]
sonar-maven-plugin/src/main/java/org/sonar/maven/SonarMojo.java
sonar-maven-plugin/src/main/java/org/sonar/maven/SonarProperties.java [new file with mode: 0644]
sonar-maven3-plugin/pom.xml
sonar-maven3-plugin/src/main/java/org/sonar/maven3/Maven3PluginExecutor.java [deleted file]
sonar-maven3-plugin/src/main/java/org/sonar/maven3/SonarMojo.java [deleted file]

diff --git a/plugins/sonar-maven-batch-plugin/pom.xml b/plugins/sonar-maven-batch-plugin/pom.xml
new file mode 100644 (file)
index 0000000..8fc9fe1
--- /dev/null
@@ -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>
diff --git a/plugins/sonar-maven-batch-plugin/src/main/java/org/sonar/plugins/maven/MavenBatchPlugin.java b/plugins/sonar-maven-batch-plugin/src/main/java/org/sonar/plugins/maven/MavenBatchPlugin.java
new file mode 100644 (file)
index 0000000..d8a44dd
--- /dev/null
@@ -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();
+  }
+}
diff --git a/plugins/sonar-maven-batch-plugin/src/main/java/org/sonar/plugins/maven/MavenPluginExecutor.java b/plugins/sonar-maven-batch-plugin/src/main/java/org/sonar/plugins/maven/MavenPluginExecutor.java
new file mode 100644 (file)
index 0000000..d11003c
--- /dev/null
@@ -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());
+  }
+
+}
diff --git a/plugins/sonar-maven-batch-plugin/src/main/java/org/sonar/plugins/maven/SonarMavenProjectBuilder.java b/plugins/sonar-maven-batch-plugin/src/main/java/org/sonar/plugins/maven/SonarMavenProjectBuilder.java
new file mode 100644 (file)
index 0000000..d8b66f6
--- /dev/null
@@ -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);
+  }
+
+}
diff --git a/pom.xml b/pom.xml
index 101d01f31c805935d69e61a263c44ce7ee47f858..5ab551506997c9ff121daf3a391834baa3d554b4 100644 (file)
--- a/pom.xml
+++ b/pom.xml
@@ -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>
         <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>
         <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>
         <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>
         <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 -->
         <plugin>
           <groupId>org.codehaus.sonar</groupId>
           <artifactId>sonar-packaging-maven-plugin</artifactId>
-          <version>1.6</version>
+          <version>1.7</version>
         </plugin>
       </plugins>
     </pluginManagement>
       <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 -->
       <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 -->
       <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 -->
       <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>
index 81e7e9a90a37c0031a352b77f20f1a0188957647..7f271b3e6bec65976ab724f611be5b92953f2ae4 100644 (file)
       <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>
index dfd4fcb2bc16fd36fc2f7c2e371f6085184af712..5503d5f03defcebe1f60d8ed582cb0b00c7d22a3 100644 (file)
@@ -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);
     }
   }
 
index fc654057d2aeca0fbf834c7a9cfacf11063c9fa1..0f87fd7990bbe73544ae3b9dfea19497637b7d09 100644 (file)
  */
 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));
   }
 
index 47659b43aced06f6940b387a04509461f703c63d..41f0e8f72e19168c5b1c3f545409b2d81018eaf3 100644 (file)
@@ -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) {
index d091aac62a56e91a59df4aee3c5fcb76febc4fb4..1f818ea82e9741d7715141d2036b32ab08aa1209 100644 (file)
 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);
   }
 }
index bdb65b90861b2153eabcf08f408673cb31c4f4be..f4fc136cab937d808639aa10917e46d5a117f9df 100644 (file)
@@ -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"));
index 6efe191c675b74dcad44985686356094cfdb7d91..e6136ee79d87a797ab7d9744db4960f6a4c68976 100644 (file)
   <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>
diff --git a/sonar-maven-plugin/src/main/java/org/sonar/maven/Maven2PluginExecutor.java b/sonar-maven-plugin/src/main/java/org/sonar/maven/Maven2PluginExecutor.java
deleted file mode 100644 (file)
index c9f0690..0000000
+++ /dev/null
@@ -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());
-  }
-
-}
index ffce333b4c3b1898be6748cdfd2e59dca2dfbc36..0a184927385e723918bbb8bf6cb14ad321b8b392 100644 (file)
@@ -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;
   }
 }
diff --git a/sonar-maven-plugin/src/main/java/org/sonar/maven/SonarProperties.java b/sonar-maven-plugin/src/main/java/org/sonar/maven/SonarProperties.java
new file mode 100644 (file)
index 0000000..530c601
--- /dev/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 = ',';
+
+}
index 2e5cf98cd49bd10f4fe4beb8a9afde67343348a5..18dd0a9c87eb92f1ee8bd20817b3a915fab7fd50 100644 (file)
@@ -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>
diff --git a/sonar-maven3-plugin/src/main/java/org/sonar/maven3/Maven3PluginExecutor.java b/sonar-maven3-plugin/src/main/java/org/sonar/maven3/Maven3PluginExecutor.java
deleted file mode 100644 (file)
index 10dee62..0000000
+++ /dev/null
@@ -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);
-    }
-  }
-
-}
diff --git a/sonar-maven3-plugin/src/main/java/org/sonar/maven3/SonarMojo.java b/sonar-maven3-plugin/src/main/java/org/sonar/maven3/SonarMojo.java
deleted file mode 100644 (file)
index 63ee50d..0000000
+++ /dev/null
@@ -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);
-  }
-
-}