All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.apache.maven.plugins.invoker.InstallMojo Maven / Gradle / Ivy

Go to download

The Maven Invoker Plugin is used to run a set of Maven projects. The plugin can determine whether each project execution is successful, and optionally can verify the output generated from a given project execution.

The newest version!
/*
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you under the Apache License, Version 2.0 (the
 * "License"); you may not use this file except in compliance
 * with the License.  You may obtain a copy of the License at
 *
 *   http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing,
 * software distributed under the License is distributed on an
 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 * KIND, either express or implied.  See the License for the
 * specific language governing permissions and limitations
 * under the License.
 */
package org.apache.maven.plugins.invoker;

import java.io.File;
import java.io.IOException;
import java.io.UncheckedIOException;
import java.util.Collections;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.Optional;
import java.util.stream.Collectors;

import org.apache.maven.RepositoryUtils;
import org.apache.maven.execution.MavenSession;
import org.apache.maven.model.DependencyManagement;
import org.apache.maven.model.Model;
import org.apache.maven.model.Parent;
import org.apache.maven.plugin.AbstractMojo;
import org.apache.maven.plugin.MojoExecutionException;
import org.apache.maven.plugins.annotations.Component;
import org.apache.maven.plugins.annotations.LifecyclePhase;
import org.apache.maven.plugins.annotations.Mojo;
import org.apache.maven.plugins.annotations.Parameter;
import org.apache.maven.plugins.annotations.ResolutionScope;
import org.apache.maven.project.MavenProject;
import org.apache.maven.project.artifact.ProjectArtifact;
import org.eclipse.aether.DefaultRepositoryCache;
import org.eclipse.aether.DefaultRepositorySystemSession;
import org.eclipse.aether.RepositorySystem;
import org.eclipse.aether.RepositorySystemSession;
import org.eclipse.aether.artifact.Artifact;
import org.eclipse.aether.artifact.ArtifactType;
import org.eclipse.aether.artifact.ArtifactTypeRegistry;
import org.eclipse.aether.artifact.DefaultArtifact;
import org.eclipse.aether.collection.CollectRequest;
import org.eclipse.aether.graph.DefaultDependencyNode;
import org.eclipse.aether.graph.Dependency;
import org.eclipse.aether.graph.DependencyFilter;
import org.eclipse.aether.installation.InstallRequest;
import org.eclipse.aether.installation.InstallationException;
import org.eclipse.aether.repository.LocalRepository;
import org.eclipse.aether.repository.LocalRepositoryManager;
import org.eclipse.aether.repository.RemoteRepository;
import org.eclipse.aether.resolution.ArtifactRequest;
import org.eclipse.aether.resolution.ArtifactResolutionException;
import org.eclipse.aether.resolution.ArtifactResult;
import org.eclipse.aether.resolution.DependencyRequest;
import org.eclipse.aether.resolution.DependencyResolutionException;
import org.eclipse.aether.resolution.DependencyResult;
import org.eclipse.aether.util.artifact.ArtifactIdUtils;
import org.eclipse.aether.util.artifact.JavaScopes;
import org.eclipse.aether.util.artifact.SubArtifact;
import org.eclipse.aether.util.filter.DependencyFilterUtils;

/**
 * Installs the project artifacts of the main build into the local repository as a preparation to run the sub projects.
 * More precisely, all artifacts of the project itself, all its locally reachable parent POMs and all its dependencies
 * from the reactor will be installed to the local repository.
 *
 * @author Paul Gier
 * @author Benjamin Bentmann
 * @since 1.2
 */
@Mojo(
        name = "install",
        defaultPhase = LifecyclePhase.PRE_INTEGRATION_TEST,
        requiresDependencyResolution = ResolutionScope.TEST,
        threadSafe = true)
public class InstallMojo extends AbstractMojo {

    // components used in Mojo

    @Component
    private RepositorySystem repositorySystem;

    @Parameter(defaultValue = "${session}", readonly = true, required = true)
    private MavenSession session;

    @Parameter(defaultValue = "${project}", readonly = true, required = true)
    private MavenProject project;

    /**
     * The path to the local repository into which the project artifacts should be installed for the integration tests.
     * If not set, the regular local repository will be used. To prevent soiling of your regular local repository with
     * possibly broken artifacts, it is strongly recommended to use an isolated repository for the integration tests
     * (e.g. ${project.build.directory}/it-repo).
     */
    @Parameter(
            property = "invoker.localRepositoryPath",
            defaultValue = "${session.localRepository.basedir}",
            required = true)
    private File localRepositoryPath;

    /**
     * A flag used to disable the installation procedure. This is primarily intended for usage from the command line to
     * occasionally adjust the build.
     *
     * @since 1.4
     */
    @Parameter(property = "invoker.skip", defaultValue = "false")
    private boolean skipInstallation;

    /**
     * Extra dependencies that need to be installed on the local repository.
     * 

* Format: *

     * groupId:artifactId:version:type:classifier
     * 
*

* Examples: *

     * org.apache.maven.plugins:maven-clean-plugin:2.4:maven-plugin
     * org.apache.maven.plugins:maven-clean-plugin:2.4:jar:javadoc
     * 
*

* If the type is 'maven-plugin' the plugin will try to resolve the artifact using plugin remote repositories, * instead of using artifact remote repositories. *

* NOTICE all dependencies will be resolved with transitive dependencies in runtime scope. * * @since 1.6 */ @Parameter private String[] extraArtifacts; /** * Scope to resolve project artifacts. * * @since 3.5.0 */ @Parameter(property = "invoker.install.scope", defaultValue = "runtime") private String scope; /** * Performs this mojo's tasks. * * @throws MojoExecutionException If the artifacts could not be installed. */ public void execute() throws MojoExecutionException { if (skipInstallation) { getLog().info("Skipping artifact installation per configuration."); return; } Map resolvedArtifacts = new LinkedHashMap<>(); try { resolveProjectArtifacts(resolvedArtifacts); resolveProjectPoms(project, resolvedArtifacts); resolveProjectDependencies(resolvedArtifacts); resolveExtraArtifacts(resolvedArtifacts); installArtifacts(resolvedArtifacts); } catch (DependencyResolutionException | InstallationException | ArtifactResolutionException e) { throw new MojoExecutionException(e.getMessage(), e); } } private void resolveProjectArtifacts(Map resolvedArtifacts) { // pom packaging doesn't have a main artifact if (project.getArtifact() != null && project.getArtifact().getFile() != null) { Artifact artifact = RepositoryUtils.toArtifact(project.getArtifact()); resolvedArtifacts.put(ArtifactIdUtils.toId(artifact), artifact); } project.getAttachedArtifacts().stream() .map(RepositoryUtils::toArtifact) .forEach(a -> resolvedArtifacts.put(ArtifactIdUtils.toId(a), a)); } private void resolveProjectPoms(MavenProject project, Map resolvedArtifacts) throws ArtifactResolutionException { if (project == null) { return; } Artifact projectPom = RepositoryUtils.toArtifact(new ProjectArtifact(project)); if (projectPom.getFile() != null) { resolvedArtifacts.put(projectPom.toString(), projectPom); } else { Artifact artifact = resolveArtifact(projectPom, project.getRemoteProjectRepositories()); resolvedArtifacts.put(ArtifactIdUtils.toId(artifact), artifact); } resolveProjectPoms(project.getParent(), resolvedArtifacts); } private void resolveProjectDependencies(Map resolvedArtifacts) throws ArtifactResolutionException, MojoExecutionException, DependencyResolutionException { DependencyFilter classpathFilter = DependencyFilterUtils.classpathFilter(scope); ArtifactTypeRegistry artifactTypeRegistry = session.getRepositorySession().getArtifactTypeRegistry(); List managedDependencies = Optional.ofNullable(project.getDependencyManagement()) .map(DependencyManagement::getDependencies) .orElseGet(Collections::emptyList) .stream() .map(d -> RepositoryUtils.toDependency(d, artifactTypeRegistry)) .collect(Collectors.toList()); List dependencies = project.getDependencies().stream() .map(d -> RepositoryUtils.toDependency(d, artifactTypeRegistry)) .filter(d -> classpathFilter.accept(new DefaultDependencyNode(d), null)) .collect(Collectors.toList()); CollectRequest collectRequest = new CollectRequest(); collectRequest.setRootArtifact(RepositoryUtils.toArtifact(project.getArtifact())); collectRequest.setDependencies(dependencies); collectRequest.setManagedDependencies(managedDependencies); collectRequest.setRepositories(project.getRemoteProjectRepositories()); DependencyRequest request = new DependencyRequest(collectRequest, classpathFilter); DependencyResult dependencyResult = repositorySystem.resolveDependencies(session.getRepositorySession(), request); List artifacts = dependencyResult.getArtifactResults().stream() .map(ArtifactResult::getArtifact) .collect(Collectors.toList()); artifacts.forEach(a -> resolvedArtifacts.put(ArtifactIdUtils.toId(a), a)); resolvePomsForArtifacts(artifacts, resolvedArtifacts, collectRequest.getRepositories()); } /** * Resolve extra artifacts. */ private void resolveExtraArtifacts(Map resolvedArtifacts) throws MojoExecutionException, DependencyResolutionException, ArtifactResolutionException { if (extraArtifacts == null) { return; } DependencyFilter classpathFilter = DependencyFilterUtils.classpathFilter(JavaScopes.RUNTIME); for (String extraArtifact : extraArtifacts) { String[] gav = extraArtifact.split(":"); if (gav.length < 3 || gav.length > 5) { throw new MojoExecutionException("Invalid artifact " + extraArtifact); } String groupId = gav[0]; String artifactId = gav[1]; String version = gav[2]; String type = "jar"; if (gav.length > 3) { type = gav[3]; } String classifier = null; if (gav.length == 5) { classifier = gav[4]; } ArtifactType artifactType = session.getRepositorySession().getArtifactTypeRegistry().get(type); List remoteRepositories = artifactType != null && "maven-plugin".equals(artifactType.getId()) ? project.getRemotePluginRepositories() : project.getRemoteProjectRepositories(); Artifact artifact = new DefaultArtifact(groupId, artifactId, classifier, null, version, artifactType); resolvePomsForArtifacts(Collections.singletonList(artifact), resolvedArtifacts, remoteRepositories); CollectRequest collectRequest = new CollectRequest(); Dependency root = new Dependency(artifact, JavaScopes.COMPILE); collectRequest.setRoot(root); collectRequest.setRepositories(remoteRepositories); DependencyRequest request = new DependencyRequest(collectRequest, classpathFilter); DependencyResult dependencyResult = repositorySystem.resolveDependencies(session.getRepositorySession(), request); List artifacts = dependencyResult.getArtifactResults().stream() .map(ArtifactResult::getArtifact) .collect(Collectors.toList()); artifacts.forEach(a -> resolvedArtifacts.put(ArtifactIdUtils.toId(a), a)); resolvePomsForArtifacts(artifacts, resolvedArtifacts, collectRequest.getRepositories()); } } private void resolvePomsForArtifacts( List artifacts, Map resolvedArtifacts, List remoteRepositories) throws ArtifactResolutionException, MojoExecutionException { for (Artifact a : artifacts) { Artifact artifactResult = resolveArtifact(new SubArtifact(a, "", "pom"), remoteRepositories); resolvePomWithParents(artifactResult, resolvedArtifacts, remoteRepositories); } } private void resolvePomWithParents( Artifact artifact, Map resolvedArtifacts, List remoteRepositories) throws MojoExecutionException, ArtifactResolutionException { if (resolvedArtifacts.containsKey(ArtifactIdUtils.toId(artifact))) { return; } Model model = PomUtils.loadPom(artifact.getFile()); Parent parent = model.getParent(); if (parent != null) { DefaultArtifact pom = new DefaultArtifact(parent.getGroupId(), parent.getArtifactId(), "", "pom", parent.getVersion()); Artifact resolvedPom = resolveArtifact(pom, remoteRepositories); resolvePomWithParents(resolvedPom, resolvedArtifacts, remoteRepositories); } resolvedArtifacts.put(ArtifactIdUtils.toId(artifact), artifact); } private Artifact resolveArtifact(Artifact artifact, List remoteRepositories) throws ArtifactResolutionException { ArtifactRequest request = new ArtifactRequest(); request.setArtifact(artifact); request.setRepositories(remoteRepositories); ArtifactResult artifactResult = repositorySystem.resolveArtifact(session.getRepositorySession(), request); return artifactResult.getArtifact(); } /** * Install list of artifacts into local repository. */ private void installArtifacts(Map resolvedArtifacts) throws InstallationException { RepositorySystemSession systemSessionForLocalRepo = createSystemSessionForLocalRepo(); // we can have on dependency two artifacts with the same groupId:artifactId // with different version, in such case when we install both in one request // metadata will contain only one version Map> collect = resolvedArtifacts.values().stream() .filter(a -> !hasTheSamePathAsTarget(a, systemSessionForLocalRepo)) .collect(Collectors.groupingBy( a -> String.format("%s:%s:%s", a.getGroupId(), a.getArtifactId(), a.getVersion()), LinkedHashMap::new, Collectors.toList())); for (List artifacts : collect.values()) { InstallRequest request = new InstallRequest(); request.setArtifacts(artifacts); repositorySystem.install(systemSessionForLocalRepo, request); } } private boolean hasTheSamePathAsTarget(Artifact artifact, RepositorySystemSession systemSession) { try { LocalRepositoryManager lrm = systemSession.getLocalRepositoryManager(); File targetBasedir = lrm.getRepository().getBasedir(); if (targetBasedir == null) { return false; } File targetFile = new File(targetBasedir, lrm.getPathForLocalArtifact(artifact)).getCanonicalFile(); File sourceFile = artifact.getFile().getCanonicalFile(); if (Objects.equals(targetFile, sourceFile)) { getLog().debug("Skip install the same target " + sourceFile); return true; } return false; } catch (IOException e) { throw new UncheckedIOException(e); } } /** * Create a new {@link RepositorySystemSession} connected with local repo. */ private RepositorySystemSession createSystemSessionForLocalRepo() { RepositorySystemSession repositorySystemSession = session.getRepositorySession(); if (localRepositoryPath != null) { // "clone" repository session and replace localRepository DefaultRepositorySystemSession newSession = new DefaultRepositorySystemSession(session.getRepositorySession()); // Clear cache, since we're using a new local repository newSession.setCache(new DefaultRepositoryCache()); // keep same repositoryType String contentType = newSession.getLocalRepository().getContentType(); if ("enhanced".equals(contentType)) { contentType = "default"; } LocalRepositoryManager localRepositoryManager = repositorySystem.newLocalRepositoryManager( newSession, new LocalRepository(localRepositoryPath, contentType)); newSession.setLocalRepositoryManager(localRepositoryManager); repositorySystemSession = newSession; getLog().debug("localRepoPath: " + localRepositoryManager.getRepository().getBasedir()); } return repositorySystemSession; } }





© 2015 - 2024 Weber Informatics LLC | Privacy Policy