<version>${maven.version}</version>
<scope>provided</scope>
</dependency>
+
+ <!-- unit tests -->
+ <dependency>
+ <groupId>org.codehaus.sonar</groupId>
+ <artifactId>sonar-testing-harness</artifactId>
+ <scope>test</scope>
+ </dependency>
</dependencies>
<build>
public final class MavenBatchPlugin extends SonarPlugin {
public List getExtensions() {
- return ImmutableList.builder().add(SonarMavenProjectBuilder.class, MavenPluginExecutor.class)
- .build();
+ return ImmutableList.of(SonarMavenProjectBuilder.class, RealMavenPluginExecutor.class);
}
}
+++ /dev/null
-/*
- * 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());
- }
-
-}
--- /dev/null
+/*
+ * 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.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;
+import org.apache.maven.model.CiManagement;
+import org.apache.maven.model.IssueManagement;
+import org.apache.maven.model.Scm;
+import org.apache.maven.project.MavenProject;
+import org.sonar.api.CoreProperties;
+import org.sonar.api.batch.bootstrap.ProjectDefinition;
+import org.sonar.api.batch.maven.MavenUtils;
+import org.sonar.api.utils.SonarException;
+import org.sonar.batch.scan.filesystem.DefaultModuleFileSystem;
+import org.sonar.java.api.JavaUtils;
+
+import java.io.File;
+import java.io.IOException;
+import java.util.Arrays;
+import java.util.List;
+import java.util.Map;
+
+public class MavenProjectConverter {
+
+ private static final String UNABLE_TO_DETERMINE_PROJECT_STRUCTURE_EXCEPTION_MESSAGE = "Unable to determine structure of project." +
+ " Probably you use Maven Advanced Reactor Options, which is not supported by Sonar and should not be used.";
+
+ private MavenProjectConverter() {
+ // only static methods
+ }
+
+ 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();
+
+ try {
+ for (MavenProject pom : poms) {
+ paths.put(pom.getFile().getCanonicalPath(), pom);
+ ProjectDefinition def = pom == root ? rootProjectDefinition : ProjectDefinition.create();
+ merge(pom, def);
+ defs.put(pom, def);
+ }
+
+ for (Map.Entry<String, MavenProject> entry : paths.entrySet()) {
+ MavenProject pom = entry.getValue();
+ for (Object m : pom.getModules()) {
+ String moduleId = (String) m;
+ File modulePath = new File(pom.getBasedir(), moduleId);
+ MavenProject module = findMavenProject(modulePath, paths);
+
+ ProjectDefinition parentProject = defs.get(pom);
+ if (parentProject == null) {
+ throw new IllegalStateException(UNABLE_TO_DETERMINE_PROJECT_STRUCTURE_EXCEPTION_MESSAGE);
+ }
+ ProjectDefinition subProject = defs.get(module);
+ if (subProject == null) {
+ throw new IllegalStateException(UNABLE_TO_DETERMINE_PROJECT_STRUCTURE_EXCEPTION_MESSAGE);
+ }
+ parentProject.addSubProject(subProject);
+ }
+ }
+ } catch (IOException e) {
+ throw new SonarException(e);
+ }
+
+ ProjectDefinition rootProject = defs.get(root);
+ if (rootProject == null) {
+ throw new IllegalStateException(UNABLE_TO_DETERMINE_PROJECT_STRUCTURE_EXCEPTION_MESSAGE);
+ }
+ }
+
+ private static MavenProject findMavenProject(final File modulePath, Map<String, MavenProject> paths) throws IOException {
+ if (modulePath.exists() && modulePath.isDirectory()) {
+ for (Map.Entry<String, MavenProject> entry : paths.entrySet()) {
+ String pomFileParentDir = new File(entry.getKey()).getParent();
+ if (pomFileParentDir.equals(modulePath.getCanonicalPath())) {
+ return entry.getValue();
+ }
+ }
+ return null;
+ } else {
+ return paths.get(modulePath.getCanonicalPath());
+ }
+ }
+
+ @VisibleForTesting
+ 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);
+ guessJavaVersion(pom, definition);
+ guessEncoding(pom, definition);
+ convertMavenLinksToProperties(definition, pom);
+ synchronizeFileSystem(pom, 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
+ String encoding = MavenUtils.getSourceEncoding(pom);
+ if (encoding != null) {
+ definition.setProperty(CoreProperties.ENCODING_PROPERTY, encoding);
+ }
+ }
+
+ private static void guessJavaVersion(MavenProject pom, ProjectDefinition definition) {
+ // See http://jira.codehaus.org/browse/SONAR-2148
+ // Get Java source and target versions from maven-compiler-plugin.
+ String version = MavenUtils.getJavaSourceVersion(pom);
+ if (version != null) {
+ definition.setProperty(JavaUtils.JAVA_SOURCE_PROPERTY, version);
+ }
+ version = MavenUtils.getJavaVersion(pom);
+ if (version != null) {
+ definition.setProperty(JavaUtils.JAVA_TARGET_PROPERTY, version);
+ }
+ }
+
+ /**
+ * For SONAR-3676
+ */
+ private static void convertMavenLinksToProperties(ProjectDefinition definition, MavenProject pom) {
+ setPropertyIfNotAlreadyExists(definition, CoreProperties.LINKS_HOME_PAGE, pom.getUrl());
+
+ Scm scm = pom.getScm();
+ if (scm == null) {
+ scm = new Scm();
+ }
+ setPropertyIfNotAlreadyExists(definition, CoreProperties.LINKS_SOURCES, scm.getUrl());
+ setPropertyIfNotAlreadyExists(definition, CoreProperties.LINKS_SOURCES_DEV, scm.getDeveloperConnection());
+
+ CiManagement ci = pom.getCiManagement();
+ if (ci == null) {
+ ci = new CiManagement();
+ }
+ setPropertyIfNotAlreadyExists(definition, CoreProperties.LINKS_CI, ci.getUrl());
+
+ IssueManagement issues = pom.getIssueManagement();
+ if (issues == null) {
+ issues = new IssueManagement();
+ }
+ setPropertyIfNotAlreadyExists(definition, CoreProperties.LINKS_ISSUE_TRACKER, issues.getUrl());
+ }
+
+ private static void setPropertyIfNotAlreadyExists(ProjectDefinition definition, String propertyKey, String propertyValue) {
+ if (StringUtils.isBlank(definition.getProperties().getProperty(propertyKey))) {
+ definition.setProperty(propertyKey, StringUtils.defaultString(propertyValue));
+ }
+ }
+
+ public static void synchronizeFileSystem(MavenProject pom, ProjectDefinition into) {
+ into.setBaseDir(pom.getBasedir());
+ File buildDir = getBuildDir(pom);
+ if (buildDir != null) {
+ into.setBuildDir(buildDir);
+ into.setWorkDir(getSonarWorkDir(pom));
+ }
+ 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(),
+ 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) {
+ if (path != null) {
+ File file = new File(path);
+ if (!file.isAbsolute()) {
+ try {
+ file = new File(basedir, path).getCanonicalFile();
+ } catch (IOException e) {
+ throw new SonarException("Unable to resolve path '" + path + "'", e);
+ }
+ }
+ return file;
+ }
+ return null;
+ }
+
+ static List<File> resolvePaths(List<String> paths, File basedir) {
+ List<File> result = Lists.newArrayList();
+ for (String path : paths) {
+ File dir = resolvePath(path, basedir);
+ if (dir != null) {
+ result.add(dir);
+ }
+ }
+ return result;
+ }
+}
--- /dev/null
+/*
+ * 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.batch.maven.MavenPlugin;
+import org.sonar.api.batch.maven.MavenPluginHandler;
+import org.sonar.api.resources.Project;
+import org.sonar.api.utils.SonarException;
+import org.sonar.api.utils.TimeProfiler;
+import org.sonar.batch.scan.filesystem.DefaultModuleFileSystem;
+import org.sonar.batch.scan.maven.MavenPluginExecutor;
+
+import java.lang.reflect.Method;
+import java.util.Arrays;
+
+@SupportedEnvironment("maven")
+public class RealMavenPluginExecutor implements MavenPluginExecutor {
+
+ private LifecycleExecutor lifecycleExecutor;
+ private MavenSession mavenSession;
+
+ public RealMavenPluginExecutor(LifecycleExecutor le, MavenSession mavenSession) {
+ this.lifecycleExecutor = le;
+ this.mavenSession = mavenSession;
+ }
+
+ @Override
+ public final MavenPluginHandler execute(Project project, DefaultModuleFileSystem fs, MavenPluginHandler handler) {
+ for (String goal : handler.getGoals()) {
+ MavenPlugin plugin = MavenPlugin.getPlugin(project.getPom(), handler.getGroupId(), handler.getArtifactId());
+ execute(project,
+ fs,
+ getGoal(handler.getGroupId(), handler.getArtifactId(), (plugin != null && plugin.getPlugin() != null ? plugin.getPlugin().getVersion() : null), goal));
+ }
+ return handler;
+ }
+
+ @Override
+ public final void execute(Project project, DefaultModuleFileSystem fs, String goal) {
+ if (project.getPom() != null) {
+ TimeProfiler profiler = new TimeProfiler().start("Execute " + goal);
+ ClassLoader currentClassLoader = Thread.currentThread().getContextClassLoader();
+ try {
+ concreteExecute(project.getPom(), goal);
+ } catch (Exception e) {
+ throw new SonarException("Unable to execute maven plugin", e);
+ } finally {
+ // Reset original ClassLoader that may have been changed during Maven Execution (see SONAR-1800)
+ Thread.currentThread().setContextClassLoader(currentClassLoader);
+ profiler.stop();
+ }
+
+ MavenProjectConverter.synchronizeFileSystem(project.getPom(), fs);
+ }
+ }
+
+ static String getGoal(String groupId, String artifactId, String version, String goal) {
+ String defaultVersion = (version == null ? "" : version);
+ return new StringBuilder()
+ .append(groupId).append(":")
+ .append(artifactId).append(":")
+ .append(defaultVersion)
+ .append(":")
+ .append(goal)
+ .toString();
+ }
+
+ 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());
+ }
+
+}
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;
--- /dev/null
+/*
+ * 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.commons.io.FileUtils;
+import org.apache.maven.model.Model;
+import org.apache.maven.model.io.xpp3.MavenXpp3Reader;
+import org.apache.maven.project.MavenProject;
+import org.codehaus.plexus.util.xml.pull.XmlPullParserException;
+import org.hamcrest.core.Is;
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.rules.TemporaryFolder;
+import org.sonar.api.CoreProperties;
+import org.sonar.api.batch.bootstrap.ProjectDefinition;
+import org.sonar.test.TestUtils;
+
+import java.io.File;
+import java.io.IOException;
+import java.io.StringReader;
+import java.net.URISyntaxException;
+import java.util.Arrays;
+import java.util.Properties;
+
+import static org.fest.assertions.Assertions.assertThat;
+import static org.hamcrest.Matchers.containsString;
+import static org.hamcrest.Matchers.is;
+import static org.junit.Assert.assertNull;
+import static org.junit.Assert.assertThat;
+import static org.junit.Assert.fail;
+
+public class MavenProjectConverterTest {
+
+ @Rule
+ public TemporaryFolder temp = new TemporaryFolder();
+
+ /**
+ * See SONAR-2681
+ */
+ @Test
+ public void shouldThrowExceptionWhenUnableToDetermineProjectStructure() {
+ MavenProject root = new MavenProject();
+ root.setFile(new File("/foo/pom.xml"));
+ root.getBuild().setDirectory("target");
+ root.getModules().add("module/pom.xml");
+
+ try {
+ MavenProjectConverter.convert(Arrays.asList(root), root);
+ fail();
+ } catch (IllegalStateException e) {
+ assertThat(e.getMessage(), containsString("Advanced Reactor Options"));
+ }
+ }
+
+ @Test
+ public void shouldConvertModules() throws IOException {
+ File basedir = temp.newFolder();
+
+ MavenProject root = newMavenProject("com.foo", "parent", "1.0-SNAPSHOT");
+ root.setFile(new File(basedir, "pom.xml"));
+ root.getBuild().setDirectory("target");
+ root.getBuild().setOutputDirectory("target/classes");
+ root.getModules().add("module/pom.xml");
+ MavenProject module = newMavenProject("com.foo", "moduleA", "1.0-SNAPSHOT");
+ module.setFile(new File(basedir, "module/pom.xml"));
+ module.getBuild().setDirectory("target");
+ module.getBuild().setOutputDirectory("target/classes");
+ ProjectDefinition project = MavenProjectConverter.convert(Arrays.asList(root, module), root);
+
+ assertThat(project.getSubProjects().size(), is(1));
+ }
+
+ private MavenProject newMavenProject(String groupId, String artifactId, String version) {
+ Model model = new Model();
+ model.setGroupId(groupId);
+ model.setArtifactId(artifactId);
+ model.setVersion(version);
+ return new MavenProject(model);
+ }
+
+ @Test
+ public void shouldConvertProperties() {
+ MavenProject pom = new MavenProject();
+ pom.setGroupId("foo");
+ pom.setArtifactId("bar");
+ pom.setVersion("1.0.1");
+ pom.setName("Test");
+ pom.setDescription("just test");
+ pom.setFile(new File("/foo/pom.xml"));
+ pom.getBuild().setDirectory("target");
+ ProjectDefinition project = ProjectDefinition.create();
+ MavenProjectConverter.merge(pom, project);
+
+ Properties properties = project.getProperties();
+ assertThat(properties.getProperty(CoreProperties.PROJECT_KEY_PROPERTY), is("foo:bar"));
+ assertThat(properties.getProperty(CoreProperties.PROJECT_VERSION_PROPERTY), is("1.0.1"));
+ assertThat(properties.getProperty(CoreProperties.PROJECT_NAME_PROPERTY), is("Test"));
+ assertThat(properties.getProperty(CoreProperties.PROJECT_DESCRIPTION_PROPERTY), is("just test"));
+ }
+
+ @Test
+ public void moduleNameShouldEqualArtifactId() throws Exception {
+ File rootDir = TestUtils.getResource("/org/sonar/plugins/maven/MavenProjectConverterTest/moduleNameShouldEqualArtifactId/");
+ MavenProject parent = loadPom("/org/sonar/plugins/maven/MavenProjectConverterTest/moduleNameShouldEqualArtifactId/pom.xml", true);
+ MavenProject module1 = loadPom("/org/sonar/plugins/maven/MavenProjectConverterTest/moduleNameShouldEqualArtifactId/module1/pom.xml", false);
+ MavenProject module2 = loadPom("/org/sonar/plugins/maven/MavenProjectConverterTest/moduleNameShouldEqualArtifactId/module2/pom.xml", false);
+
+ ProjectDefinition rootDef = MavenProjectConverter.convert(Arrays.asList(parent, module1, module2), parent);
+
+ assertThat(rootDef.getSubProjects().size(), Is.is(2));
+ assertThat(rootDef.getKey(), Is.is("org.test:parent"));
+ assertNull(rootDef.getParent());
+ assertThat(rootDef.getBaseDir(), is(rootDir));
+
+ ProjectDefinition module1Def = rootDef.getSubProjects().get(0);
+ assertThat(module1Def.getKey(), Is.is("org.test:module1"));
+ assertThat(module1Def.getParent(), Is.is(rootDef));
+ assertThat(module1Def.getBaseDir(), Is.is(new File(rootDir, "module1")));
+ assertThat(module1Def.getSubProjects().size(), Is.is(0));
+ }
+
+ @Test
+ public void moduleNameDifferentThanArtifactId() throws Exception {
+ File rootDir = TestUtils.getResource("/org/sonar/plugins/maven/MavenProjectConverterTest/moduleNameDifferentThanArtifactId/");
+ MavenProject parent = loadPom("/org/sonar/plugins/maven/MavenProjectConverterTest/moduleNameDifferentThanArtifactId/pom.xml", true);
+ MavenProject module1 = loadPom("/org/sonar/plugins/maven/MavenProjectConverterTest/moduleNameDifferentThanArtifactId/path1/pom.xml", false);
+ MavenProject module2 = loadPom("/org/sonar/plugins/maven/MavenProjectConverterTest/moduleNameDifferentThanArtifactId/path2/pom.xml", false);
+
+ ProjectDefinition rootDef = MavenProjectConverter.convert(Arrays.asList(parent, module1, module2), parent);
+
+ assertThat(rootDef.getSubProjects().size(), is(2));
+ assertThat(rootDef.getKey(), is("org.test:parent"));
+ assertNull(rootDef.getParent());
+ assertThat(rootDef.getBaseDir(), is(rootDir));
+
+ ProjectDefinition module1Def = rootDef.getSubProjects().get(0);
+ assertThat(module1Def.getKey(), Is.is("org.test:module1"));
+ assertThat(module1Def.getParent(), Is.is(rootDef));
+ assertThat(module1Def.getBaseDir(), Is.is(new File(rootDir, "path1")));
+ assertThat(module1Def.getSubProjects().size(), Is.is(0));
+ }
+
+ @Test
+ public void should_find_module_with_maven_project_file_naming_different_from_pom_xml() throws Exception {
+ File rootDir = TestUtils.getResource("/org/sonar/plugins/maven/MavenProjectConverterTest/mavenProjectFileNameNotEqualsToPomXml/");
+ MavenProject parent = loadPom("/org/sonar/plugins/maven/MavenProjectConverterTest/mavenProjectFileNameNotEqualsToPomXml/pom.xml", true);
+ MavenProject module = loadPom("/org/sonar/plugins/maven/MavenProjectConverterTest/mavenProjectFileNameNotEqualsToPomXml/module/pom_having_different_name.xml", false);
+
+ ProjectDefinition rootDef = MavenProjectConverter.convert(Arrays.asList(parent, module), parent);
+
+ assertThat(rootDef.getSubProjects().size(), Is.is(1));
+ assertThat(rootDef.getKey(), Is.is("org.test:parent"));
+ assertNull(rootDef.getParent());
+ assertThat(rootDef.getBaseDir(), is(rootDir));
+
+ ProjectDefinition module1Def = rootDef.getSubProjects().get(0);
+ assertThat(module1Def.getKey(), Is.is("org.test:module"));
+ assertThat(module1Def.getParent(), Is.is(rootDef));
+ assertThat(module1Def.getBaseDir(), Is.is(new File(rootDir, "module")));
+ assertThat(module1Def.getSubProjects().size(), Is.is(0));
+ }
+
+ @Test
+ public void testSingleProjectWithoutModules() throws Exception {
+ File rootDir = TestUtils.getResource("/org/sonar/plugins/maven/MavenProjectConverterTest/singleProjectWithoutModules/");
+ MavenProject pom = loadPom("/org/sonar/plugins/maven/MavenProjectConverterTest/singleProjectWithoutModules/pom.xml", true);
+
+ ProjectDefinition rootDef = MavenProjectConverter.convert(Arrays.asList(pom), pom);
+
+ assertThat(rootDef.getKey(), is("org.test:parent"));
+ assertThat(rootDef.getSubProjects().size(), is(0));
+ assertNull(rootDef.getParent());
+ assertThat(rootDef.getBaseDir(), is(rootDir));
+ }
+
+ @Test
+ public void shouldConvertLinksToProperties() throws Exception {
+ MavenProject pom = loadPom("/org/sonar/plugins/maven/MavenProjectConverterTest/projectWithLinks/pom.xml", true);
+
+ ProjectDefinition rootDef = MavenProjectConverter.convert(Arrays.asList(pom), pom);
+
+ Properties props = rootDef.getProperties();
+ assertThat(props.getProperty(CoreProperties.LINKS_HOME_PAGE)).isEqualTo("http://home.com");
+ assertThat(props.getProperty(CoreProperties.LINKS_CI)).isEqualTo("http://ci.com");
+ assertThat(props.getProperty(CoreProperties.LINKS_ISSUE_TRACKER)).isEqualTo("http://issues.com");
+ assertThat(props.getProperty(CoreProperties.LINKS_SOURCES)).isEqualTo("http://sources.com");
+ assertThat(props.getProperty(CoreProperties.LINKS_SOURCES_DEV)).isEqualTo("http://sources-dev.com");
+ }
+
+ @Test
+ public void shouldNotConvertLinksToPropertiesIfPropertyAlreadyDefined() throws Exception {
+ MavenProject pom = loadPom("/org/sonar/plugins/maven/MavenProjectConverterTest/projectWithLinksAndProperties/pom.xml", true);
+
+ ProjectDefinition rootDef = MavenProjectConverter.convert(Arrays.asList(pom), pom);
+
+ Properties props = rootDef.getProperties();
+
+ // Those properties have been fed by the POM elements <ciManagement>, <issueManagement>, ...
+ assertThat(props.getProperty(CoreProperties.LINKS_CI)).isEqualTo("http://ci.com");
+ assertThat(props.getProperty(CoreProperties.LINKS_ISSUE_TRACKER)).isEqualTo("http://issues.com");
+ assertThat(props.getProperty(CoreProperties.LINKS_SOURCES_DEV)).isEqualTo("http://sources-dev.com");
+
+ // ... but those ones have been overridden by <properties> in the POM
+ assertThat(props.getProperty(CoreProperties.LINKS_SOURCES)).isEqualTo("http://sources.com-OVERRIDEN-BY-PROPS");
+ assertThat(props.getProperty(CoreProperties.LINKS_HOME_PAGE)).isEqualTo("http://home.com-OVERRIDEN-BY-PROPS");
+ }
+
+ @Test
+ public void shouldLoadSourceEncoding() throws Exception {
+ MavenProject pom = loadPom("/org/sonar/plugins/maven/MavenProjectConverterTest/sourceEncoding/pom.xml", true);
+
+ ProjectDefinition rootDef = MavenProjectConverter.convert(Arrays.asList(pom), pom);
+
+ assertThat(rootDef.getProperties().getProperty(CoreProperties.ENCODING_PROPERTY)).isEqualTo("Shift_JIS");
+ }
+
+ private MavenProject loadPom(String pomPath, boolean isRoot) throws URISyntaxException, IOException, XmlPullParserException {
+ File pomFile = new File(getClass().getResource(pomPath).toURI());
+ Model model = new MavenXpp3Reader().read(new StringReader(FileUtils.readFileToString(pomFile)));
+ MavenProject pom = new MavenProject(model);
+ pom.setFile(pomFile);
+ pom.getBuild().setDirectory("target");
+ pom.setExecutionRoot(isRoot);
+ return pom;
+ }
+}
--- /dev/null
+package org.sonar.plugins.maven;
+
+/*
+ * 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.
+ */
+
+import org.apache.maven.project.MavenProject;
+import org.junit.Test;
+import org.sonar.api.batch.maven.MavenPlugin;
+import org.sonar.api.batch.maven.MavenPluginHandler;
+import org.sonar.api.resources.Project;
+import org.sonar.batch.scan.filesystem.DefaultModuleFileSystem;
+
+import java.io.File;
+
+import static org.hamcrest.CoreMatchers.is;
+import static org.junit.Assert.assertThat;
+import static org.mockito.Matchers.any;
+import static org.mockito.Matchers.anyList;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.never;
+import static org.mockito.Mockito.verify;
+
+public class RealMavenPluginExecutorTest {
+
+ @Test
+ public void plugin_version_should_be_optional() {
+ assertThat(RealMavenPluginExecutor.getGoal("group", "artifact", null, "goal"), is("group:artifact::goal"));
+ }
+
+ @Test
+ public void test_plugin_version() {
+ assertThat(RealMavenPluginExecutor.getGoal("group", "artifact", "3.54", "goal"), is("group:artifact:3.54:goal"));
+ }
+
+ /**
+ * The maven plugin sometimes changes the project structure (for example mvn build-helper:add-source). These changes
+ * must be applied to the internal structure.
+ */
+ @Test
+ public void should_reset_file_system_after_execution() {
+ RealMavenPluginExecutor executor = new RealMavenPluginExecutor(null, null) {
+ @Override
+ public void concreteExecute(MavenProject pom, String goal) throws Exception {
+ pom.addCompileSourceRoot("src/java");
+ }
+ };
+ MavenProject pom = new MavenProject();
+ pom.setFile(new File("target/AbstractMavenPluginExecutorTest/pom.xml"));
+ pom.getBuild().setDirectory("target");
+ Project foo = new Project("foo");
+ foo.setPom(pom);
+ DefaultModuleFileSystem fs = mock(DefaultModuleFileSystem.class);
+ executor.execute(foo, fs, new AddSourceMavenPluginHandler());
+
+ verify(fs).resetDirs(any(File.class), any(File.class), anyList(), anyList(), anyList());
+ }
+
+ @Test
+ public void should_ignore_non_maven_projects() {
+ RealMavenPluginExecutor executor = new RealMavenPluginExecutor(null, null) {
+ @Override
+ public void concreteExecute(MavenProject pom, String goal) throws Exception {
+ pom.addCompileSourceRoot("src/java");
+ }
+ };
+ Project foo = new Project("foo");
+ DefaultModuleFileSystem fs = mock(DefaultModuleFileSystem.class);
+ executor.execute(foo, fs, new AddSourceMavenPluginHandler());
+
+ verify(fs, never()).resetDirs(any(File.class), any(File.class), anyList(), anyList(), anyList());
+ }
+
+ static class AddSourceMavenPluginHandler implements MavenPluginHandler {
+ public String getGroupId() {
+ return "fake";
+ }
+
+ public String getArtifactId() {
+ return "fake";
+ }
+
+ public String getVersion() {
+ return "2.2";
+ }
+
+ public boolean isFixedVersion() {
+ return false;
+ }
+
+ public String[] getGoals() {
+ return new String[] {"fake"};
+ }
+
+ public void configure(Project project, MavenPlugin plugin) {
+ }
+ }
+
+}
--- /dev/null
+<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.test</groupId>
+ <artifactId>parent</artifactId>
+ <version>0.1-SNAPSHOT</version>
+ </parent>
+ <artifactId>module</artifactId>
+ <packaging>jar</packaging>
+</project>
\ No newline at end of file
--- /dev/null
+<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.test</groupId>
+ <artifactId>parent</artifactId>
+ <version>0.1-SNAPSHOT</version>
+ </parent>
+ <artifactId>module</artifactId>
+ <packaging>jar</packaging>
+</project>
\ No newline at end of file
--- /dev/null
+<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>
+ <groupId>org.test</groupId>
+ <artifactId>parent</artifactId>
+ <version>0.1-SNAPSHOT</version>
+ <packaging>pom</packaging>
+ <modules>
+ <module>module</module>
+ </modules>
+</project>
\ No newline at end of file
--- /dev/null
+<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.test</groupId>
+ <artifactId>parent</artifactId>
+ <version>0.1-SNAPSHOT</version>
+ </parent>
+ <artifactId>module1</artifactId>
+ <packaging>jar</packaging>
+</project>
\ No newline at end of file
--- /dev/null
+<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.test</groupId>
+ <artifactId>parent</artifactId>
+ <version>0.1-SNAPSHOT</version>
+ </parent>
+ <artifactId>module2</artifactId>
+ <packaging>jar</packaging>
+</project>
\ No newline at end of file
--- /dev/null
+<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>
+ <groupId>org.test</groupId>
+ <artifactId>parent</artifactId>
+ <version>0.1-SNAPSHOT</version>
+ <packaging>pom</packaging>
+ <modules>
+ <module>path1</module>
+ <module>path2</module>
+ </modules>
+</project>
\ No newline at end of file
--- /dev/null
+<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.test</groupId>
+ <artifactId>parent</artifactId>
+ <version>0.1-SNAPSHOT</version>
+ </parent>
+ <artifactId>module1</artifactId>
+ <packaging>jar</packaging>
+</project>
\ No newline at end of file
--- /dev/null
+<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.test</groupId>
+ <artifactId>parent</artifactId>
+ <version>0.1-SNAPSHOT</version>
+ </parent>
+ <artifactId>module2</artifactId>
+ <packaging>jar</packaging>
+</project>
\ No newline at end of file
--- /dev/null
+<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>
+ <groupId>org.test</groupId>
+ <artifactId>parent</artifactId>
+ <version>0.1-SNAPSHOT</version>
+ <packaging>pom</packaging>
+ <modules>
+ <module>module1</module>
+ <module>module2</module>
+ </modules>
+</project>
\ No newline at end of file
--- /dev/null
+<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>
+ <groupId>org.test</groupId>
+ <artifactId>parent</artifactId>
+ <version>0.1-SNAPSHOT</version>
+ <packaging>pom</packaging>
+ <url>http://home.com</url>
+ <ciManagement>
+ <url>http://ci.com</url>
+ </ciManagement>
+ <issueManagement>
+ <url>http://issues.com</url>
+ </issueManagement>
+ <scm>
+ <url>http://sources.com</url>
+ <developerConnection>http://sources-dev.com</developerConnection>
+ </scm>
+</project>
\ No newline at end of file
--- /dev/null
+<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>
+ <groupId>org.test</groupId>
+ <artifactId>parent</artifactId>
+ <version>0.1-SNAPSHOT</version>
+ <packaging>pom</packaging>
+ <url>http://home.com</url>
+ <ciManagement>
+ <url>http://ci.com</url>
+ </ciManagement>
+ <issueManagement>
+ <url>http://issues.com</url>
+ </issueManagement>
+ <scm>
+ <url>http://sources.com</url>
+ <developerConnection>http://sources-dev.com</developerConnection>
+ </scm>
+
+
+
+ <properties>
+ <sonar.links.homepage>http://home.com-OVERRIDEN-BY-PROPS</sonar.links.homepage>
+ <sonar.links.scm>http://sources.com-OVERRIDEN-BY-PROPS</sonar.links.scm>
+ </properties>
+
+
+</project>
\ No newline at end of file
--- /dev/null
+<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>
+ <groupId>org.test</groupId>
+ <artifactId>parent</artifactId>
+ <version>0.1-SNAPSHOT</version>
+ <packaging>pom</packaging>
+</project>
\ No newline at end of file
--- /dev/null
+<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>
+ <groupId>org.test</groupId>
+ <artifactId>parent</artifactId>
+ <version>0.1-SNAPSHOT</version>
+ <packaging>pom</packaging>
+ <url>http://home.com</url>
+ <properties>
+ <project.build.sourceEncoding>Shift_JIS</project.build.sourceEncoding>
+ </properties>
+</project>
\ No newline at end of file
+++ /dev/null
-/*
- * 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.batch.scan.maven;
-
-import org.apache.maven.project.MavenProject;
-import org.sonar.api.batch.maven.MavenPlugin;
-import org.sonar.api.batch.maven.MavenPluginHandler;
-import org.sonar.api.resources.Project;
-import org.sonar.api.utils.SonarException;
-import org.sonar.api.utils.TimeProfiler;
-import org.sonar.batch.scan.filesystem.DefaultModuleFileSystem;
-
-/**
- * Abstract implementation of {@link org.sonar.batch.scan.maven.MavenPluginExecutor} to reduce duplications in concrete implementations for different Maven versions.
- */
-public abstract class AbstractMavenPluginExecutor implements MavenPluginExecutor {
-
- public final MavenPluginHandler execute(Project project, DefaultModuleFileSystem fs, MavenPluginHandler handler) {
- for (String goal : handler.getGoals()) {
- MavenPlugin plugin = MavenPlugin.getPlugin(project.getPom(), handler.getGroupId(), handler.getArtifactId());
- execute(project,
- fs,
- getGoal(handler.getGroupId(), handler.getArtifactId(), (plugin != null && plugin.getPlugin() != null ? plugin.getPlugin().getVersion() : null), goal));
- }
- return handler;
- }
-
- public final void execute(Project project, DefaultModuleFileSystem fs, String goal) {
- if (project.getPom() != null) {
- TimeProfiler profiler = new TimeProfiler().start("Execute " + goal);
- ClassLoader currentClassLoader = Thread.currentThread().getContextClassLoader();
- try {
- concreteExecute(project.getPom(), goal);
- } catch (Exception e) {
- throw new SonarException("Unable to execute maven plugin", e);
- } finally {
- // Reset original ClassLoader that may have been changed during Maven Execution (see SONAR-1800)
- Thread.currentThread().setContextClassLoader(currentClassLoader);
- profiler.stop();
- }
-
- MavenProjectConverter.synchronizeFileSystem(project.getPom(), fs);
- }
- }
-
- public abstract void concreteExecute(MavenProject pom, String goal) throws Exception;
-
- static String getGoal(String groupId, String artifactId, String version, String goal) {
- String defaultVersion = (version == null ? "" : version);
- return new StringBuilder()
- .append(groupId).append(":")
- .append(artifactId).append(":")
- .append(defaultVersion)
- .append(":")
- .append(goal)
- .toString();
- }
-
-}
import org.sonar.api.batch.maven.MavenPluginHandler;
import org.sonar.api.resources.Project;
import org.sonar.batch.scan.filesystem.DefaultModuleFileSystem;
-import org.sonar.batch.scan.maven.MavenPluginExecutor;
public final class FakeMavenPluginExecutor implements MavenPluginExecutor {
+
+ @Override
public void execute(Project project, DefaultModuleFileSystem fs, String goal) {
// do nothing
}
+ @Override
public MavenPluginHandler execute(Project project, DefaultModuleFileSystem fs, MavenPluginHandler handler) {
// do nothing
return handler;
}
-}
\ No newline at end of file
+}
*/
package org.sonar.batch.scan.maven;
-import org.sonar.api.BatchComponent;
import org.sonar.api.batch.maven.MavenPluginHandler;
import org.sonar.api.resources.Project;
+import org.sonar.api.task.TaskExtension;
import org.sonar.batch.scan.filesystem.DefaultModuleFileSystem;
-public interface MavenPluginExecutor extends BatchComponent {
+public interface MavenPluginExecutor extends TaskExtension {
void execute(Project project, DefaultModuleFileSystem def, String goal);
+++ /dev/null
-/*
- * 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.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;
-import org.apache.maven.model.CiManagement;
-import org.apache.maven.model.IssueManagement;
-import org.apache.maven.model.Scm;
-import org.apache.maven.project.MavenProject;
-import org.sonar.api.CoreProperties;
-import org.sonar.api.batch.bootstrap.ProjectDefinition;
-import org.sonar.api.batch.maven.MavenUtils;
-import org.sonar.api.utils.SonarException;
-import org.sonar.batch.scan.filesystem.DefaultModuleFileSystem;
-import org.sonar.java.api.JavaUtils;
-
-import java.io.File;
-import java.io.IOException;
-import java.util.Arrays;
-import java.util.List;
-import java.util.Map;
-
-public class MavenProjectConverter {
-
- private static final String UNABLE_TO_DETERMINE_PROJECT_STRUCTURE_EXCEPTION_MESSAGE = "Unable to determine structure of project." +
- " Probably you use Maven Advanced Reactor Options, which is not supported by Sonar and should not be used.";
-
- private MavenProjectConverter() {
- // only static methods
- }
-
- 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();
-
- try {
- for (MavenProject pom : poms) {
- paths.put(pom.getFile().getCanonicalPath(), pom);
- ProjectDefinition def = pom == root ? rootProjectDefinition : ProjectDefinition.create();
- merge(pom, def);
- defs.put(pom, def);
- }
-
- for (Map.Entry<String, MavenProject> entry : paths.entrySet()) {
- MavenProject pom = entry.getValue();
- for (Object m : pom.getModules()) {
- String moduleId = (String) m;
- File modulePath = new File(pom.getBasedir(), moduleId);
- MavenProject module = findMavenProject(modulePath, paths);
-
- ProjectDefinition parentProject = defs.get(pom);
- if (parentProject == null) {
- throw new IllegalStateException(UNABLE_TO_DETERMINE_PROJECT_STRUCTURE_EXCEPTION_MESSAGE);
- }
- ProjectDefinition subProject = defs.get(module);
- if (subProject == null) {
- throw new IllegalStateException(UNABLE_TO_DETERMINE_PROJECT_STRUCTURE_EXCEPTION_MESSAGE);
- }
- parentProject.addSubProject(subProject);
- }
- }
- } catch (IOException e) {
- throw new SonarException(e);
- }
-
- ProjectDefinition rootProject = defs.get(root);
- if (rootProject == null) {
- throw new IllegalStateException(UNABLE_TO_DETERMINE_PROJECT_STRUCTURE_EXCEPTION_MESSAGE);
- }
- }
-
- private static MavenProject findMavenProject(final File modulePath, Map<String, MavenProject> paths) throws IOException {
- if (modulePath.exists() && modulePath.isDirectory()) {
- for (Map.Entry<String, MavenProject> entry : paths.entrySet()) {
- String pomFileParentDir = new File(entry.getKey()).getParent();
- if (pomFileParentDir.equals(modulePath.getCanonicalPath())) {
- return entry.getValue();
- }
- }
- return null;
- } else {
- return paths.get(modulePath.getCanonicalPath());
- }
- }
-
- @VisibleForTesting
- 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);
- guessJavaVersion(pom, definition);
- guessEncoding(pom, definition);
- convertMavenLinksToProperties(definition, pom);
- synchronizeFileSystem(pom, 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
- String encoding = MavenUtils.getSourceEncoding(pom);
- if (encoding != null) {
- definition.setProperty(CoreProperties.ENCODING_PROPERTY, encoding);
- }
- }
-
- private static void guessJavaVersion(MavenProject pom, ProjectDefinition definition) {
- // See http://jira.codehaus.org/browse/SONAR-2148
- // Get Java source and target versions from maven-compiler-plugin.
- String version = MavenUtils.getJavaSourceVersion(pom);
- if (version != null) {
- definition.setProperty(JavaUtils.JAVA_SOURCE_PROPERTY, version);
- }
- version = MavenUtils.getJavaVersion(pom);
- if (version != null) {
- definition.setProperty(JavaUtils.JAVA_TARGET_PROPERTY, version);
- }
- }
-
- /**
- * For SONAR-3676
- */
- private static void convertMavenLinksToProperties(ProjectDefinition definition, MavenProject pom) {
- setPropertyIfNotAlreadyExists(definition, CoreProperties.LINKS_HOME_PAGE, pom.getUrl());
-
- Scm scm = pom.getScm();
- if (scm == null) {
- scm = new Scm();
- }
- setPropertyIfNotAlreadyExists(definition, CoreProperties.LINKS_SOURCES, scm.getUrl());
- setPropertyIfNotAlreadyExists(definition, CoreProperties.LINKS_SOURCES_DEV, scm.getDeveloperConnection());
-
- CiManagement ci = pom.getCiManagement();
- if (ci == null) {
- ci = new CiManagement();
- }
- setPropertyIfNotAlreadyExists(definition, CoreProperties.LINKS_CI, ci.getUrl());
-
- IssueManagement issues = pom.getIssueManagement();
- if (issues == null) {
- issues = new IssueManagement();
- }
- setPropertyIfNotAlreadyExists(definition, CoreProperties.LINKS_ISSUE_TRACKER, issues.getUrl());
- }
-
- private static void setPropertyIfNotAlreadyExists(ProjectDefinition definition, String propertyKey, String propertyValue) {
- if (StringUtils.isBlank(definition.getProperties().getProperty(propertyKey))) {
- definition.setProperty(propertyKey, StringUtils.defaultString(propertyValue));
- }
- }
-
- public static void synchronizeFileSystem(MavenProject pom, ProjectDefinition into) {
- into.setBaseDir(pom.getBasedir());
- File buildDir = getBuildDir(pom);
- if (buildDir != null) {
- into.setBuildDir(buildDir);
- into.setWorkDir(getSonarWorkDir(pom));
- }
- 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(),
- 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) {
- if (path != null) {
- File file = new File(path);
- if (!file.isAbsolute()) {
- try {
- file = new File(basedir, path).getCanonicalFile();
- } catch (IOException e) {
- throw new SonarException("Unable to resolve path '" + path + "'", e);
- }
- }
- return file;
- }
- return null;
- }
-
- static List<File> resolvePaths(List<String> paths, File basedir) {
- List<File> result = Lists.newArrayList();
- for (String path : paths) {
- File dir = resolvePath(path, basedir);
- if (dir != null) {
- result.add(dir);
- }
- }
- return result;
- }
-}
+++ /dev/null
-/*
- * 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.batch.scan.maven;
-
-import org.apache.maven.project.MavenProject;
-import org.junit.Test;
-import org.sonar.api.batch.maven.MavenPlugin;
-import org.sonar.api.batch.maven.MavenPluginHandler;
-import org.sonar.api.resources.Project;
-import org.sonar.batch.scan.filesystem.DefaultModuleFileSystem;
-
-import java.io.File;
-
-import static org.hamcrest.CoreMatchers.is;
-import static org.junit.Assert.assertThat;
-import static org.mockito.Matchers.any;
-import static org.mockito.Matchers.anyList;
-import static org.mockito.Mockito.mock;
-import static org.mockito.Mockito.never;
-import static org.mockito.Mockito.verify;
-
-public class AbstractMavenPluginExecutorTest {
-
- @Test
- public void plugin_version_should_be_optional() {
- assertThat(AbstractMavenPluginExecutor.getGoal("group", "artifact", null, "goal"), is("group:artifact::goal"));
- }
-
- @Test
- public void test_plugin_version() {
- assertThat(AbstractMavenPluginExecutor.getGoal("group", "artifact", "3.54", "goal"), is("group:artifact:3.54:goal"));
- }
-
- /**
- * The maven plugin sometimes changes the project structure (for example mvn build-helper:add-source). These changes
- * must be applied to the internal structure.
- */
- @Test
- public void should_reset_file_system_after_execution() {
- AbstractMavenPluginExecutor executor = new AbstractMavenPluginExecutor() {
- @Override
- public void concreteExecute(MavenProject pom, String goal) throws Exception {
- pom.addCompileSourceRoot("src/java");
- }
- };
- MavenProject pom = new MavenProject();
- pom.setFile(new File("target/AbstractMavenPluginExecutorTest/pom.xml"));
- pom.getBuild().setDirectory("target");
- Project foo = new Project("foo");
- foo.setPom(pom);
- DefaultModuleFileSystem fs = mock(DefaultModuleFileSystem.class);
- executor.execute(foo, fs, new AddSourceMavenPluginHandler());
-
- verify(fs).resetDirs(any(File.class), any(File.class), anyList(), anyList(), anyList());
- }
-
- @Test
- public void should_ignore_non_maven_projects() {
- AbstractMavenPluginExecutor executor = new AbstractMavenPluginExecutor() {
- @Override
- public void concreteExecute(MavenProject pom, String goal) throws Exception {
- pom.addCompileSourceRoot("src/java");
- }
- };
- Project foo = new Project("foo");
- DefaultModuleFileSystem fs = mock(DefaultModuleFileSystem.class);
- executor.execute(foo, fs, new AddSourceMavenPluginHandler());
-
- verify(fs, never()).resetDirs(any(File.class), any(File.class), anyList(), anyList(), anyList());
- }
-
- static class AddSourceMavenPluginHandler implements MavenPluginHandler {
- public String getGroupId() {
- return "fake";
- }
-
- public String getArtifactId() {
- return "fake";
- }
-
- public String getVersion() {
- return "2.2";
- }
-
- public boolean isFixedVersion() {
- return false;
- }
-
- public String[] getGoals() {
- return new String[]{"fake"};
- }
-
- public void configure(Project project, MavenPlugin plugin) {
- }
- }
-
-}
+++ /dev/null
-/*
- * 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.batch.scan.maven;
-
-import org.apache.commons.io.FileUtils;
-import org.apache.maven.model.Model;
-import org.apache.maven.model.io.xpp3.MavenXpp3Reader;
-import org.apache.maven.project.MavenProject;
-import org.codehaus.plexus.util.xml.pull.XmlPullParserException;
-import org.hamcrest.core.Is;
-import org.junit.Rule;
-import org.junit.Test;
-import org.junit.rules.TemporaryFolder;
-import org.sonar.api.CoreProperties;
-import org.sonar.api.batch.bootstrap.ProjectDefinition;
-import org.sonar.test.TestUtils;
-
-import java.io.File;
-import java.io.IOException;
-import java.io.StringReader;
-import java.net.URISyntaxException;
-import java.util.Arrays;
-import java.util.Properties;
-
-import static org.fest.assertions.Assertions.assertThat;
-import static org.hamcrest.Matchers.containsString;
-import static org.hamcrest.Matchers.is;
-import static org.junit.Assert.assertNull;
-import static org.junit.Assert.assertThat;
-import static org.junit.Assert.fail;
-
-public class MavenProjectConverterTest {
-
- @Rule
- public TemporaryFolder temp = new TemporaryFolder();
-
- /**
- * See SONAR-2681
- */
- @Test
- public void shouldThrowExceptionWhenUnableToDetermineProjectStructure() {
- MavenProject root = new MavenProject();
- root.setFile(new File("/foo/pom.xml"));
- root.getBuild().setDirectory("target");
- root.getModules().add("module/pom.xml");
-
- try {
- MavenProjectConverter.convert(Arrays.asList(root), root);
- fail();
- } catch (IllegalStateException e) {
- assertThat(e.getMessage(), containsString("Advanced Reactor Options"));
- }
- }
-
- @Test
- public void shouldConvertModules() throws IOException {
- File basedir = temp.newFolder();
-
- MavenProject root = newMavenProject("com.foo", "parent", "1.0-SNAPSHOT");
- root.setFile(new File(basedir, "pom.xml"));
- root.getBuild().setDirectory("target");
- root.getBuild().setOutputDirectory("target/classes");
- root.getModules().add("module/pom.xml");
- MavenProject module = newMavenProject("com.foo", "moduleA", "1.0-SNAPSHOT");
- module.setFile(new File(basedir, "module/pom.xml"));
- module.getBuild().setDirectory("target");
- module.getBuild().setOutputDirectory("target/classes");
- ProjectDefinition project = MavenProjectConverter.convert(Arrays.asList(root, module), root);
-
- assertThat(project.getSubProjects().size(), is(1));
- }
-
- private MavenProject newMavenProject(String groupId, String artifactId, String version) {
- Model model = new Model();
- model.setGroupId(groupId);
- model.setArtifactId(artifactId);
- model.setVersion(version);
- return new MavenProject(model);
- }
-
- @Test
- public void shouldConvertProperties() {
- MavenProject pom = new MavenProject();
- pom.setGroupId("foo");
- pom.setArtifactId("bar");
- pom.setVersion("1.0.1");
- pom.setName("Test");
- pom.setDescription("just test");
- pom.setFile(new File("/foo/pom.xml"));
- pom.getBuild().setDirectory("target");
- ProjectDefinition project = ProjectDefinition.create();
- MavenProjectConverter.merge(pom, project);
-
- Properties properties = project.getProperties();
- assertThat(properties.getProperty(CoreProperties.PROJECT_KEY_PROPERTY), is("foo:bar"));
- assertThat(properties.getProperty(CoreProperties.PROJECT_VERSION_PROPERTY), is("1.0.1"));
- assertThat(properties.getProperty(CoreProperties.PROJECT_NAME_PROPERTY), is("Test"));
- assertThat(properties.getProperty(CoreProperties.PROJECT_DESCRIPTION_PROPERTY), is("just test"));
- }
-
- @Test
- public void moduleNameShouldEqualArtifactId() throws Exception {
- File rootDir = TestUtils.getResource("/org/sonar/batch/scan/maven/MavenProjectConverterTest/moduleNameShouldEqualArtifactId/");
- MavenProject parent = loadPom("/org/sonar/batch/scan/maven/MavenProjectConverterTest/moduleNameShouldEqualArtifactId/pom.xml", true);
- MavenProject module1 = loadPom("/org/sonar/batch/scan/maven/MavenProjectConverterTest/moduleNameShouldEqualArtifactId/module1/pom.xml", false);
- MavenProject module2 = loadPom("/org/sonar/batch/scan/maven/MavenProjectConverterTest/moduleNameShouldEqualArtifactId/module2/pom.xml", false);
-
- ProjectDefinition rootDef = MavenProjectConverter.convert(Arrays.asList(parent, module1, module2), parent);
-
- assertThat(rootDef.getSubProjects().size(), Is.is(2));
- assertThat(rootDef.getKey(), Is.is("org.test:parent"));
- assertNull(rootDef.getParent());
- assertThat(rootDef.getBaseDir(), is(rootDir));
-
- ProjectDefinition module1Def = rootDef.getSubProjects().get(0);
- assertThat(module1Def.getKey(), Is.is("org.test:module1"));
- assertThat(module1Def.getParent(), Is.is(rootDef));
- assertThat(module1Def.getBaseDir(), Is.is(new File(rootDir, "module1")));
- assertThat(module1Def.getSubProjects().size(), Is.is(0));
- }
-
- @Test
- public void moduleNameDifferentThanArtifactId() throws Exception {
- File rootDir = TestUtils.getResource("/org/sonar/batch/scan/maven/MavenProjectConverterTest/moduleNameDifferentThanArtifactId/");
- MavenProject parent = loadPom("/org/sonar/batch/scan/maven/MavenProjectConverterTest/moduleNameDifferentThanArtifactId/pom.xml", true);
- MavenProject module1 = loadPom("/org/sonar/batch/scan/maven/MavenProjectConverterTest/moduleNameDifferentThanArtifactId/path1/pom.xml", false);
- MavenProject module2 = loadPom("/org/sonar/batch/scan/maven/MavenProjectConverterTest/moduleNameDifferentThanArtifactId/path2/pom.xml", false);
-
- ProjectDefinition rootDef = MavenProjectConverter.convert(Arrays.asList(parent, module1, module2), parent);
-
- assertThat(rootDef.getSubProjects().size(), is(2));
- assertThat(rootDef.getKey(), is("org.test:parent"));
- assertNull(rootDef.getParent());
- assertThat(rootDef.getBaseDir(), is(rootDir));
-
- ProjectDefinition module1Def = rootDef.getSubProjects().get(0);
- assertThat(module1Def.getKey(), Is.is("org.test:module1"));
- assertThat(module1Def.getParent(), Is.is(rootDef));
- assertThat(module1Def.getBaseDir(), Is.is(new File(rootDir, "path1")));
- assertThat(module1Def.getSubProjects().size(), Is.is(0));
- }
-
- @Test
- public void should_find_module_with_maven_project_file_naming_different_from_pom_xml() throws Exception {
- File rootDir = TestUtils.getResource("/org/sonar/batch/scan/maven/MavenProjectConverterTest/mavenProjectFileNameNotEqualsToPomXml/");
- MavenProject parent = loadPom("/org/sonar/batch/scan/maven/MavenProjectConverterTest/mavenProjectFileNameNotEqualsToPomXml/pom.xml", true);
- MavenProject module = loadPom("/org/sonar/batch/scan/maven/MavenProjectConverterTest/mavenProjectFileNameNotEqualsToPomXml/module/pom_having_different_name.xml", false);
-
- ProjectDefinition rootDef = MavenProjectConverter.convert(Arrays.asList(parent, module), parent);
-
- assertThat(rootDef.getSubProjects().size(), Is.is(1));
- assertThat(rootDef.getKey(), Is.is("org.test:parent"));
- assertNull(rootDef.getParent());
- assertThat(rootDef.getBaseDir(), is(rootDir));
-
- ProjectDefinition module1Def = rootDef.getSubProjects().get(0);
- assertThat(module1Def.getKey(), Is.is("org.test:module"));
- assertThat(module1Def.getParent(), Is.is(rootDef));
- assertThat(module1Def.getBaseDir(), Is.is(new File(rootDir, "module")));
- assertThat(module1Def.getSubProjects().size(), Is.is(0));
- }
-
- @Test
- public void testSingleProjectWithoutModules() throws Exception {
- File rootDir = TestUtils.getResource("/org/sonar/batch/scan/maven/MavenProjectConverterTest/singleProjectWithoutModules/");
- MavenProject pom = loadPom("/org/sonar/batch/scan/maven/MavenProjectConverterTest/singleProjectWithoutModules/pom.xml", true);
-
- ProjectDefinition rootDef = MavenProjectConverter.convert(Arrays.asList(pom), pom);
-
- assertThat(rootDef.getKey(), is("org.test:parent"));
- assertThat(rootDef.getSubProjects().size(), is(0));
- assertNull(rootDef.getParent());
- assertThat(rootDef.getBaseDir(), is(rootDir));
- }
-
- @Test
- public void shouldConvertLinksToProperties() throws Exception {
- MavenProject pom = loadPom("/org/sonar/batch/scan/maven/MavenProjectConverterTest/projectWithLinks/pom.xml", true);
-
- ProjectDefinition rootDef = MavenProjectConverter.convert(Arrays.asList(pom), pom);
-
- Properties props = rootDef.getProperties();
- assertThat(props.getProperty(CoreProperties.LINKS_HOME_PAGE)).isEqualTo("http://home.com");
- assertThat(props.getProperty(CoreProperties.LINKS_CI)).isEqualTo("http://ci.com");
- assertThat(props.getProperty(CoreProperties.LINKS_ISSUE_TRACKER)).isEqualTo("http://issues.com");
- assertThat(props.getProperty(CoreProperties.LINKS_SOURCES)).isEqualTo("http://sources.com");
- assertThat(props.getProperty(CoreProperties.LINKS_SOURCES_DEV)).isEqualTo("http://sources-dev.com");
- }
-
- @Test
- public void shouldNotConvertLinksToPropertiesIfPropertyAlreadyDefined() throws Exception {
- MavenProject pom = loadPom("/org/sonar/batch/scan/maven/MavenProjectConverterTest/projectWithLinksAndProperties/pom.xml", true);
-
- ProjectDefinition rootDef = MavenProjectConverter.convert(Arrays.asList(pom), pom);
-
- Properties props = rootDef.getProperties();
-
- // Those properties have been fed by the POM elements <ciManagement>, <issueManagement>, ...
- assertThat(props.getProperty(CoreProperties.LINKS_CI)).isEqualTo("http://ci.com");
- assertThat(props.getProperty(CoreProperties.LINKS_ISSUE_TRACKER)).isEqualTo("http://issues.com");
- assertThat(props.getProperty(CoreProperties.LINKS_SOURCES_DEV)).isEqualTo("http://sources-dev.com");
-
- // ... but those ones have been overridden by <properties> in the POM
- assertThat(props.getProperty(CoreProperties.LINKS_SOURCES)).isEqualTo("http://sources.com-OVERRIDEN-BY-PROPS");
- assertThat(props.getProperty(CoreProperties.LINKS_HOME_PAGE)).isEqualTo("http://home.com-OVERRIDEN-BY-PROPS");
- }
-
- @Test
- public void shouldLoadSourceEncoding() throws Exception {
- MavenProject pom = loadPom("/org/sonar/batch/scan/maven/MavenProjectConverterTest/sourceEncoding/pom.xml", true);
-
- ProjectDefinition rootDef = MavenProjectConverter.convert(Arrays.asList(pom), pom);
-
- assertThat(rootDef.getProperties().getProperty(CoreProperties.ENCODING_PROPERTY)).isEqualTo("Shift_JIS");
- }
-
- private MavenProject loadPom(String pomPath, boolean isRoot) throws URISyntaxException, IOException, XmlPullParserException {
- File pomFile = new File(getClass().getResource(pomPath).toURI());
- Model model = new MavenXpp3Reader().read(new StringReader(FileUtils.readFileToString(pomFile)));
- MavenProject pom = new MavenProject(model);
- pom.setFile(pomFile);
- pom.getBuild().setDirectory("target");
- pom.setExecutionRoot(isRoot);
- return pom;
- }
-}
+++ /dev/null
-<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.test</groupId>
- <artifactId>parent</artifactId>
- <version>0.1-SNAPSHOT</version>
- </parent>
- <artifactId>module</artifactId>
- <packaging>jar</packaging>
-</project>
\ No newline at end of file
+++ /dev/null
-<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.test</groupId>
- <artifactId>parent</artifactId>
- <version>0.1-SNAPSHOT</version>
- </parent>
- <artifactId>module</artifactId>
- <packaging>jar</packaging>
-</project>
\ No newline at end of file
+++ /dev/null
-<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>
- <groupId>org.test</groupId>
- <artifactId>parent</artifactId>
- <version>0.1-SNAPSHOT</version>
- <packaging>pom</packaging>
- <modules>
- <module>module</module>
- </modules>
-</project>
\ No newline at end of file
+++ /dev/null
-<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.test</groupId>
- <artifactId>parent</artifactId>
- <version>0.1-SNAPSHOT</version>
- </parent>
- <artifactId>module1</artifactId>
- <packaging>jar</packaging>
-</project>
\ No newline at end of file
+++ /dev/null
-<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.test</groupId>
- <artifactId>parent</artifactId>
- <version>0.1-SNAPSHOT</version>
- </parent>
- <artifactId>module2</artifactId>
- <packaging>jar</packaging>
-</project>
\ No newline at end of file
+++ /dev/null
-<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>
- <groupId>org.test</groupId>
- <artifactId>parent</artifactId>
- <version>0.1-SNAPSHOT</version>
- <packaging>pom</packaging>
- <modules>
- <module>path1</module>
- <module>path2</module>
- </modules>
-</project>
\ No newline at end of file
+++ /dev/null
-<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.test</groupId>
- <artifactId>parent</artifactId>
- <version>0.1-SNAPSHOT</version>
- </parent>
- <artifactId>module1</artifactId>
- <packaging>jar</packaging>
-</project>
\ No newline at end of file
+++ /dev/null
-<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.test</groupId>
- <artifactId>parent</artifactId>
- <version>0.1-SNAPSHOT</version>
- </parent>
- <artifactId>module2</artifactId>
- <packaging>jar</packaging>
-</project>
\ No newline at end of file
+++ /dev/null
-<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>
- <groupId>org.test</groupId>
- <artifactId>parent</artifactId>
- <version>0.1-SNAPSHOT</version>
- <packaging>pom</packaging>
- <modules>
- <module>module1</module>
- <module>module2</module>
- </modules>
-</project>
\ No newline at end of file
+++ /dev/null
-<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>
- <groupId>org.test</groupId>
- <artifactId>parent</artifactId>
- <version>0.1-SNAPSHOT</version>
- <packaging>pom</packaging>
- <url>http://home.com</url>
- <ciManagement>
- <url>http://ci.com</url>
- </ciManagement>
- <issueManagement>
- <url>http://issues.com</url>
- </issueManagement>
- <scm>
- <url>http://sources.com</url>
- <developerConnection>http://sources-dev.com</developerConnection>
- </scm>
-</project>
\ No newline at end of file
+++ /dev/null
-<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>
- <groupId>org.test</groupId>
- <artifactId>parent</artifactId>
- <version>0.1-SNAPSHOT</version>
- <packaging>pom</packaging>
- <url>http://home.com</url>
- <ciManagement>
- <url>http://ci.com</url>
- </ciManagement>
- <issueManagement>
- <url>http://issues.com</url>
- </issueManagement>
- <scm>
- <url>http://sources.com</url>
- <developerConnection>http://sources-dev.com</developerConnection>
- </scm>
-
-
-
- <properties>
- <sonar.links.homepage>http://home.com-OVERRIDEN-BY-PROPS</sonar.links.homepage>
- <sonar.links.scm>http://sources.com-OVERRIDEN-BY-PROPS</sonar.links.scm>
- </properties>
-
-
-</project>
\ No newline at end of file
+++ /dev/null
-<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>
- <groupId>org.test</groupId>
- <artifactId>parent</artifactId>
- <version>0.1-SNAPSHOT</version>
- <packaging>pom</packaging>
-</project>
\ No newline at end of file
+++ /dev/null
-<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>
- <groupId>org.test</groupId>
- <artifactId>parent</artifactId>
- <version>0.1-SNAPSHOT</version>
- <packaging>pom</packaging>
- <url>http://home.com</url>
- <properties>
- <project.build.sourceEncoding>Shift_JIS</project.build.sourceEncoding>
- </properties>
-</project>
\ No newline at end of file