diff --git a/.gitignore b/.gitignore index 7c274b6a6..30088585b 100644 --- a/.gitignore +++ b/.gitignore @@ -7,6 +7,7 @@ bin/ # Intellij *.ipr *.iml +*.versionsBackup .idea out/ .DS_Store diff --git a/pom.xml b/pom.xml index e3a43c00c..cea122f54 100644 --- a/pom.xml +++ b/pom.xml @@ -254,7 +254,7 @@ under the License. org.apache.commons commons-lang3 - 3.6 + 3.8.1 diff --git a/src/it/projects/list-plugin-repositories-verbose/invoker.properties b/src/it/projects/list-plugin-repositories-verbose/invoker.properties new file mode 100644 index 000000000..b0f317486 --- /dev/null +++ b/src/it/projects/list-plugin-repositories-verbose/invoker.properties @@ -0,0 +1,19 @@ +# 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. + +invoker.goals = ${project.groupId}:${project.artifactId}:${project.version}:list-plugin-repositories +invoker.debug = true \ No newline at end of file diff --git a/src/it/projects/list-plugin-repositories-verbose/pom.xml b/src/it/projects/list-plugin-repositories-verbose/pom.xml new file mode 100644 index 000000000..e871ea85a --- /dev/null +++ b/src/it/projects/list-plugin-repositories-verbose/pom.xml @@ -0,0 +1,47 @@ + + + + + 4.0.0 + + org.apache.maven.its.dependency + test + 1.0-SNAPSHOT + + Test + + Test dependency:list-plugin-repositories + + + + UTF-8 + + + + + org.apache.maven + maven-project + 2.0.6 + + + + diff --git a/src/it/projects/list-plugin-repositories-verbose/verify.groovy b/src/it/projects/list-plugin-repositories-verbose/verify.groovy new file mode 100644 index 000000000..a9209294d --- /dev/null +++ b/src/it/projects/list-plugin-repositories-verbose/verify.groovy @@ -0,0 +1,26 @@ +/* + * 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. + */ + +File file = new File( basedir, "build.log" ); +assert file.exists(); + +String buildLog = file.getText( "UTF-8" ); +assert buildLog.contains( 'location: Maven settings (user/global)' ); + +return true; diff --git a/src/it/projects/list-plugin-repositories/invoker.properties b/src/it/projects/list-plugin-repositories/invoker.properties new file mode 100644 index 000000000..351b30480 --- /dev/null +++ b/src/it/projects/list-plugin-repositories/invoker.properties @@ -0,0 +1,19 @@ +# 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. + +invoker.goals = ${project.groupId}:${project.artifactId}:${project.version}:list-plugin-repositories +invoker.debug = false \ No newline at end of file diff --git a/src/it/projects/list-plugin-repositories/pom.xml b/src/it/projects/list-plugin-repositories/pom.xml new file mode 100644 index 000000000..e871ea85a --- /dev/null +++ b/src/it/projects/list-plugin-repositories/pom.xml @@ -0,0 +1,47 @@ + + + + + 4.0.0 + + org.apache.maven.its.dependency + test + 1.0-SNAPSHOT + + Test + + Test dependency:list-plugin-repositories + + + + UTF-8 + + + + + org.apache.maven + maven-project + 2.0.6 + + + + diff --git a/src/it/projects/list-plugin-repositories/verify.groovy b/src/it/projects/list-plugin-repositories/verify.groovy new file mode 100644 index 000000000..8f58002a8 --- /dev/null +++ b/src/it/projects/list-plugin-repositories/verify.groovy @@ -0,0 +1,26 @@ +/* + * 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. + */ + +File file = new File( basedir, "build.log" ); +assert file.exists(); + +String buildLog = file.getText( "UTF-8" ); +assert !buildLog.contains( 'location:' ); + +return true; diff --git a/src/main/java/org/apache/maven/plugins/dependency/AbstractDependencyMojo.java b/src/main/java/org/apache/maven/plugins/dependency/AbstractDependencyMojo.java index 2f7a2ce2b..07df9f631 100644 --- a/src/main/java/org/apache/maven/plugins/dependency/AbstractDependencyMojo.java +++ b/src/main/java/org/apache/maven/plugins/dependency/AbstractDependencyMojo.java @@ -90,6 +90,12 @@ public abstract class AbstractDependencyMojo @Parameter( defaultValue = "${project.remoteArtifactRepositories}", readonly = true, required = true ) private List remoteRepositories; + /** + * Remote repositories which will be searched for plugins. + */ + @Parameter( defaultValue = "${project.pluginArtifactRepositories}", readonly = true, required = true ) + private List remotePluginRepositories; + /** * Contains the full list of projects in the reactor. */ @@ -345,11 +351,25 @@ private void silenceUnarchiver( UnArchiver unArchiver ) * repositories, used to resolve artifacts. */ public ProjectBuildingRequest newResolveArtifactProjectBuildingRequest() + { + return newProjectBuildingRequest( remoteRepositories ); + } + + /** + * @return Returns a new ProjectBuildingRequest populated from the current session and the current project remote + * repositories, used to resolve plugins. + */ + protected ProjectBuildingRequest newResolvePluginProjectBuildingRequest() + { + return newProjectBuildingRequest( remotePluginRepositories ); + } + + private ProjectBuildingRequest newProjectBuildingRequest( List repositories ) { ProjectBuildingRequest buildingRequest = new DefaultProjectBuildingRequest( session.getProjectBuildingRequest() ); - buildingRequest.setRemoteRepositories( remoteRepositories ); + buildingRequest.setRemoteRepositories( repositories ); return buildingRequest; } diff --git a/src/main/java/org/apache/maven/plugins/dependency/GetMojo.java b/src/main/java/org/apache/maven/plugins/dependency/GetMojo.java index f5a1b630b..9ddbff35b 100644 --- a/src/main/java/org/apache/maven/plugins/dependency/GetMojo.java +++ b/src/main/java/org/apache/maven/plugins/dependency/GetMojo.java @@ -65,15 +65,9 @@ public class GetMojo @Parameter( defaultValue = "${session}", required = true, readonly = true ) private MavenSession session; - /** - * - */ @Component private ArtifactResolver artifactResolver; - /** - * - */ @Component private DependencyResolver dependencyResolver; diff --git a/src/main/java/org/apache/maven/plugins/dependency/ListClassesMojo.java b/src/main/java/org/apache/maven/plugins/dependency/ListClassesMojo.java new file mode 100644 index 000000000..fa33031a8 --- /dev/null +++ b/src/main/java/org/apache/maven/plugins/dependency/ListClassesMojo.java @@ -0,0 +1,326 @@ +package org.apache.maven.plugins.dependency; + +/* + * 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. + */ + +import java.io.IOException; +import java.util.ArrayList; +import java.util.Enumeration; +import java.util.List; +import java.util.Map; +import java.util.jar.JarEntry; +import java.util.jar.JarFile; +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +import org.apache.maven.artifact.handler.ArtifactHandler; +import org.apache.maven.artifact.handler.manager.ArtifactHandlerManager; +import org.apache.maven.artifact.repository.ArtifactRepository; +import org.apache.maven.artifact.repository.ArtifactRepositoryPolicy; +import org.apache.maven.artifact.repository.MavenArtifactRepository; +import org.apache.maven.artifact.repository.layout.ArtifactRepositoryLayout; +import org.apache.maven.execution.MavenSession; +import org.apache.maven.plugin.AbstractMojo; +import org.apache.maven.plugin.MojoExecutionException; +import org.apache.maven.plugin.MojoFailureException; +import org.apache.maven.plugins.annotations.Component; +import org.apache.maven.plugins.annotations.Mojo; +import org.apache.maven.plugins.annotations.Parameter; +import org.apache.maven.project.DefaultProjectBuildingRequest; +import org.apache.maven.project.ProjectBuildingRequest; +import org.apache.maven.repository.RepositorySystem; +import org.apache.maven.settings.Settings; +import org.apache.maven.shared.transfer.artifact.ArtifactCoordinate; +import org.apache.maven.shared.transfer.artifact.DefaultArtifactCoordinate; +import org.apache.maven.shared.transfer.artifact.resolve.ArtifactResolver; +import org.apache.maven.shared.transfer.artifact.resolve.ArtifactResolverException; +import org.apache.maven.shared.transfer.artifact.resolve.ArtifactResult; +import org.apache.maven.shared.transfer.dependencies.DefaultDependableCoordinate; +import org.apache.maven.shared.transfer.dependencies.DependableCoordinate; +import org.apache.maven.shared.transfer.dependencies.resolve.DependencyResolver; +import org.apache.maven.shared.transfer.dependencies.resolve.DependencyResolverException; + + +/** + * Retrieves and lists all classes contained in the specified artifact from the specified remote repositories. + */ +@Mojo( name = "list-classes", requiresProject = false, threadSafe = true ) +public class ListClassesMojo + extends AbstractMojo +{ + private static final Pattern ALT_REPO_SYNTAX_PATTERN = Pattern.compile( "(.+)::(.*)::(.+)" ); + + @Parameter( defaultValue = "${session}", required = true, readonly = true ) + private MavenSession session; + + @Component + private ArtifactResolver artifactResolver; + + @Component + private DependencyResolver dependencyResolver; + + @Component + private ArtifactHandlerManager artifactHandlerManager; + + /** + * Map that contains the layouts. + */ + @Component( role = ArtifactRepositoryLayout.class ) + private Map repositoryLayouts; + + /** + * The repository system. + */ + @Component + private RepositorySystem repositorySystem; + + private DefaultDependableCoordinate coordinate = new DefaultDependableCoordinate(); + + /** + * The group ID of the artifact to download. Ignored if {@link #artifact} is used. + */ + @Parameter( property = "groupId" ) + private String groupId; + + /** + * The artifact ID of the artifact to download. Ignored if {@link #artifact} is used. + */ + @Parameter( property = "artifactId" ) + private String artifactId; + + /** + * The version of the artifact to download. Ignored if {@link #artifact} is used. + */ + @Parameter( property = "version" ) + private String version; + + /** + * The classifier of the artifact to download. Ignored if {@link #artifact} is used. + * + * @since 2.3 + */ + @Parameter( property = "classifier" ) + private String classifier; + + /** + * The packaging of the artifact to download. Ignored if {@link #artifact} is used. + */ + @Parameter( property = "packaging", defaultValue = "jar" ) + private String packaging = "jar"; + + /** + * Repositories in the format id::[layout]::url or just URLs, separated by comma. That is, + * central::default::https://repo.maven.apache.org/maven2,myrepo::::https://repo.acme.com,https://repo.acme2.com + */ + @Parameter( property = "remoteRepositories" ) + private String remoteRepositories; + + /** + * A string of the form groupId:artifactId:version[:packaging[:classifier]]. + */ + @Parameter( property = "artifact" ) + private String artifact; + + @Parameter( defaultValue = "${project.remoteArtifactRepositories}", readonly = true, required = true ) + private List pomRemoteRepositories; + + /** + * Download transitively, retrieving the specified artifact and all of its dependencies. + */ + @Parameter( property = "transitive", defaultValue = "false" ) + private boolean transitive = false; + + /** + * Skip plugin execution completely. + */ + @Parameter( property = "mdep.skip", defaultValue = "false" ) + private boolean skip; + + @Override + public void execute() throws MojoExecutionException, MojoFailureException + { + ProjectBuildingRequest buildingRequest = makeBuildingRequest(); + + try + { + if ( transitive ) + { + Iterable artifacts = dependencyResolver + .resolveDependencies( buildingRequest, coordinate, null ); + + for ( ArtifactResult result : artifacts ) + { + printClassesFromArtifactResult( result ); + } + } + else + { + ArtifactResult result = artifactResolver + .resolveArtifact( buildingRequest, toArtifactCoordinate( coordinate ) ); + + printClassesFromArtifactResult( result ); + } + } + catch ( ArtifactResolverException | DependencyResolverException | IOException e ) + { + throw new MojoExecutionException( "Couldn't download artifact: " + e.getMessage(), e ); + } + } + + private void printClassesFromArtifactResult( ArtifactResult result ) + throws IOException + { + // open jar file in try-with-resources statement to guarantee the file closes after use regardless of errors + try ( JarFile jarFile = new JarFile( result.getArtifact().getFile() ) ) + { + Enumeration entries = jarFile.entries(); + + while ( entries.hasMoreElements() ) + { + JarEntry entry = (JarEntry) entries.nextElement(); + String entryName = entry.getName(); + + // filter out files that do not end in .class + if ( !entryName.endsWith( ".class" ) ) + { + continue; + } + + // remove .class from the end and change format to use periods instead of forward slashes + String className = entryName.substring( 0, entryName.length() - 6 ).replace( '/', '.' ); + getLog().info( className ); + } + } + } + + private ProjectBuildingRequest makeBuildingRequest() + throws MojoExecutionException, MojoFailureException + { + if ( artifact == null ) + { + throw new MojoFailureException( "You must specify an artifact, " + + "e.g. -Dartifact=org.apache.maven.plugins:maven-downloader-plugin:1.0" ); + } + if ( artifact != null ) + { + String[] tokens = artifact.split( ":" ); + if ( tokens.length < 3 || tokens.length > 5 ) + { + throw new MojoFailureException( "Invalid artifact, you must specify " + + "groupId:artifactId:version[:packaging[:classifier]] " + artifact ); + } + coordinate.setGroupId( tokens[0] ); + coordinate.setArtifactId( tokens[1] ); + coordinate.setVersion( tokens[2] ); + if ( tokens.length >= 4 ) + { + coordinate.setType( tokens[3] ); + } + if ( tokens.length == 5 ) + { + coordinate.setClassifier( tokens[4] ); + } + } + + ArtifactRepositoryPolicy always = + new ArtifactRepositoryPolicy( true, ArtifactRepositoryPolicy.UPDATE_POLICY_ALWAYS, + ArtifactRepositoryPolicy.CHECKSUM_POLICY_WARN ); + + List repoList = new ArrayList<>(); + + if ( pomRemoteRepositories != null ) + { + repoList.addAll( pomRemoteRepositories ); + } + + if ( remoteRepositories != null ) + { + // Use the same format as in the deploy plugin id::layout::url + String[] repos = remoteRepositories.split( "," ); + for ( String repo : repos ) + { + repoList.add( parseRepository( repo, always ) ); + } + } + + ProjectBuildingRequest buildingRequest = + new DefaultProjectBuildingRequest( session.getProjectBuildingRequest() ); + + Settings settings = session.getSettings(); + repositorySystem.injectMirror( repoList, settings.getMirrors() ); + repositorySystem.injectProxy( repoList, settings.getProxies() ); + repositorySystem.injectAuthentication( repoList, settings.getServers() ); + + buildingRequest.setRemoteRepositories( repoList ); + + return buildingRequest; + } + + protected ArtifactCoordinate toArtifactCoordinate( DependableCoordinate dependableCoordinate ) + { + ArtifactHandler artifactHandler = artifactHandlerManager.getArtifactHandler( dependableCoordinate.getType() ); + DefaultArtifactCoordinate artifactCoordinate = new DefaultArtifactCoordinate(); + artifactCoordinate.setGroupId( dependableCoordinate.getGroupId() ); + artifactCoordinate.setArtifactId( dependableCoordinate.getArtifactId() ); + artifactCoordinate.setVersion( dependableCoordinate.getVersion() ); + artifactCoordinate.setClassifier( dependableCoordinate.getClassifier() ); + artifactCoordinate.setExtension( artifactHandler.getExtension() ); + return artifactCoordinate; + } + + protected ArtifactRepository parseRepository( String repo, ArtifactRepositoryPolicy policy ) + throws MojoFailureException + { + // if it's a simple url + String id = "temp"; + ArtifactRepositoryLayout layout = getLayout( "default" ); + + // if it's an extended repo URL of the form id::layout::url + if ( repo.contains( "::" ) ) + { + Matcher matcher = ALT_REPO_SYNTAX_PATTERN.matcher( repo ); + if ( !matcher.matches() ) + { + throw new MojoFailureException( repo, "Invalid syntax for repository: " + repo, + "Invalid syntax for repository. Use \"id::layout::url\" or \"URL\"." ); + } + + id = matcher.group( 1 ).trim(); + if ( !( matcher.group( 2 ) == null || matcher.group( 2 ).trim().isEmpty() ) ) + { + layout = getLayout( matcher.group( 2 ).trim() ); + } + repo = matcher.group( 3 ).trim(); + } + return new MavenArtifactRepository( id, repo, layout, policy, policy ); + } + + private ArtifactRepositoryLayout getLayout( String id ) + throws MojoFailureException + { + ArtifactRepositoryLayout layout = repositoryLayouts.get( id ); + + if ( layout == null ) + { + throw new MojoFailureException( id, "Invalid repository layout", "Invalid repository layout: " + id ); + } + + return layout; + } +} diff --git a/src/main/java/org/apache/maven/plugins/dependency/analyze/AnalyzeDepMgt.java b/src/main/java/org/apache/maven/plugins/dependency/analyze/AnalyzeDepMgt.java index b2c0ca91a..b6c1264ed 100644 --- a/src/main/java/org/apache/maven/plugins/dependency/analyze/AnalyzeDepMgt.java +++ b/src/main/java/org/apache/maven/plugins/dependency/analyze/AnalyzeDepMgt.java @@ -41,10 +41,8 @@ /** * This mojo looks at the dependencies after final resolution and looks for mismatches in your dependencyManagement - * section. In versions of maven prior to 2.0.6, it was possible to inherit versions that didn't match your - * dependencyManagement. See MNG-1577 for more info. This - * mojo is also useful for just detecting projects that override the dependencyManagement directly. Set ignoreDirect to - * false to detect these otherwise normal conditions. + * section. This mojo is also useful for detecting projects that override the dependencyManagement directly. + * Set ignoreDirect to false to detect these otherwise normal conditions. * * @author Brian Fox * @since 2.0-alpha-3 diff --git a/src/main/java/org/apache/maven/plugins/dependency/resolvers/GoOfflineMojo.java b/src/main/java/org/apache/maven/plugins/dependency/resolvers/GoOfflineMojo.java index b12dd6f58..e0e8b1f92 100644 --- a/src/main/java/org/apache/maven/plugins/dependency/resolvers/GoOfflineMojo.java +++ b/src/main/java/org/apache/maven/plugins/dependency/resolvers/GoOfflineMojo.java @@ -20,11 +20,11 @@ */ import org.apache.maven.artifact.Artifact; +import org.apache.maven.artifact.repository.ArtifactRepository; import org.apache.maven.model.Dependency; import org.apache.maven.plugin.MojoExecutionException; import org.apache.maven.plugins.dependency.utils.DependencyUtil; import org.apache.maven.plugins.annotations.Mojo; -import org.apache.maven.project.DefaultProjectBuildingRequest; import org.apache.maven.project.ProjectBuildingRequest; import org.apache.maven.shared.artifact.filter.collection.ArtifactsFilter; import org.apache.maven.shared.artifact.filter.resolve.TransformableFilter; @@ -49,7 +49,6 @@ public class GoOfflineMojo extends AbstractResolveMojo { - /** * Main entry into mojo. Gets the list of dependencies, resolves all that are not in the Reactor, and iterates * through displaying the resolved versions. @@ -101,25 +100,32 @@ protected Set resolveDependencyArtifacts() { final Collection dependencies = getProject().getDependencies(); final Set dependableCoordinates = new HashSet<>(); - final ProjectBuildingRequest buildingRequest = - new DefaultProjectBuildingRequest( session.getProjectBuildingRequest() ); + + final ProjectBuildingRequest buildingRequest = newResolveArtifactProjectBuildingRequest(); for ( Dependency dependency : dependencies ) { dependableCoordinates.add( createDependendableCoordinateFromDependency( dependency ) ); } - return resolveDependableCoordinate( buildingRequest, dependableCoordinates ); + return resolveDependableCoordinate( buildingRequest, dependableCoordinates, "dependencies" ); } private Set resolveDependableCoordinate( final ProjectBuildingRequest buildingRequest, - final Collection dependableCoordinates ) + final Collection dependableCoordinates, + final String type ) throws DependencyResolverException { final TransformableFilter filter = getTransformableFilter(); final Set results = new HashSet<>(); + this.getLog().debug( "Resolving '" + type + "' with following repositories:" ); + for ( ArtifactRepository repo : buildingRequest.getRemoteRepositories() ) + { + getLog().debug( repo.getId() + " (" + repo.getUrl() + ")" ); + } + for ( DependableCoordinate dependableCoordinate : dependableCoordinates ) { final Iterable artifactResults = getDependencyResolver().resolveDependencies( @@ -164,15 +170,14 @@ protected Set resolvePluginArtifacts() artifacts.addAll( reports ); artifacts.addAll( plugins ); - final ProjectBuildingRequest buildingRequest = - new DefaultProjectBuildingRequest( session.getProjectBuildingRequest() ); + final ProjectBuildingRequest buildingRequest = newResolvePluginProjectBuildingRequest(); for ( Artifact artifact : artifacts ) { dependableCoordinates.add( createDependendableCoordinateFromArtifact( artifact ) ); } - return resolveDependableCoordinate( buildingRequest, dependableCoordinates ); + return resolveDependableCoordinate( buildingRequest, dependableCoordinates, "plugins" ); } private DependableCoordinate createDependendableCoordinateFromArtifact( final Artifact artifact ) diff --git a/src/main/java/org/apache/maven/plugins/dependency/resolvers/ListPluginRepositoriesMojo.java b/src/main/java/org/apache/maven/plugins/dependency/resolvers/ListPluginRepositoriesMojo.java new file mode 100644 index 000000000..893ba8e98 --- /dev/null +++ b/src/main/java/org/apache/maven/plugins/dependency/resolvers/ListPluginRepositoriesMojo.java @@ -0,0 +1,323 @@ +package org.apache.maven.plugins.dependency.resolvers; + +/* + * 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. + */ + +import java.util.HashSet; +import java.util.List; +import java.util.Set; + +import org.apache.maven.artifact.Artifact; +import org.apache.maven.artifact.ArtifactUtils; +import org.apache.maven.artifact.repository.ArtifactRepository; +import org.apache.maven.model.Model; +import org.apache.maven.model.Repository; +import org.apache.maven.model.building.ModelBuildingRequest; +import org.apache.maven.plugin.MojoExecutionException; +import org.apache.maven.plugins.annotations.Component; +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.plugins.dependency.AbstractDependencyMojo; +import org.apache.maven.project.DefaultProjectBuildingRequest; +import org.apache.maven.project.MavenProject; +import org.apache.maven.project.ProjectBuilder; +import org.apache.maven.project.ProjectBuildingException; +import org.apache.maven.project.ProjectBuildingRequest; +import org.apache.maven.settings.Mirror; +import org.apache.maven.settings.Settings; +import org.apache.maven.shared.transfer.artifact.ArtifactCoordinate; +import org.apache.maven.shared.transfer.artifact.DefaultArtifactCoordinate; +import org.apache.maven.shared.transfer.artifact.resolve.ArtifactResolver; +import org.apache.maven.shared.transfer.artifact.resolve.ArtifactResolverException; + +/** + * Goal that resolves all project plugin dependencies and then lists the repositories used by the build + * + * @author Pim Moerenhout + * @since 3.1.2 + */ +@Mojo( name = "list-plugin-repositories", requiresDependencyResolution = ResolutionScope.TEST, threadSafe = true ) +public class ListPluginRepositoriesMojo + extends AbstractDependencyMojo +{ + /** + * Maven Project Builder component. + */ + @Component + private ProjectBuilder projectBuilder; + + /** + * Component used to resolve artifacts and download their files from remote repositories. + */ + @Component + private ArtifactResolver artifactResolver; + + /** + * The system settings for Maven. This is the instance resulting from + * merging global and user-level settings files. + */ + @Parameter( defaultValue = "${settings}", readonly = true, required = true ) + private Settings settings; + + /** + * Plugin repositories used for the project. + */ + @Parameter( defaultValue = "${project.pluginArtifactRepositories}", readonly = true, required = true ) + private List pluginRepositories; + + /** + * Sets whether the plugin runs in verbose mode. As of plugin version 2.3, the default value is derived from Maven's + * global debug flag (compare command line switch -X). + * + * @since 3.1.2 + */ + @Parameter( property = "verbose" ) + private boolean verbose; + + /** + * Displays a list of the plugin repositories used by this build. + * + * @throws MojoExecutionException with a message if an error occurs + */ + @Override + protected void doExecute() + throws MojoExecutionException + { + final List repositories = pluginRepositories; + final Set artifacts = getProject().getPluginArtifacts(); + + this.getLog().info( "Plugin repositories used by this build:" ); + for ( ArtifactRepository repo : repositories ) + { + if ( isVerbose() ) + { + Set locations = new HashSet<>(); + for ( Mirror mirror : settings.getMirrors() ) + { + if ( mirror.getId().equals( repo.getId() ) + && ( mirror.getUrl().equals( repo.getUrl() ) ) ) + { + locations.add( "Maven settings (user/global)" ); + } + } + + Artifact projectArtifact = getProject().getArtifact(); + MavenProject project = getMavenProject( ArtifactUtils.key( projectArtifact ) ); + traversePom( repo, projectArtifact, project, locations ); + + for ( Artifact artifact : artifacts ) + { + MavenProject artifactProject = getMavenProject( ArtifactUtils.key( artifact ) ); + traversePom( repo, artifact, artifactProject, locations ); + } + writeRepository( repo, locations ); + } + else + { + this.getLog().info( repo.toString() ); + } + } + } + + private void writeRepository( ArtifactRepository artifactRepository, Set locations ) + { + StringBuilder sb = new StringBuilder( 256 ); + sb.append( artifactRepository.toString() ); + for ( String location : locations ) + { + sb.append( " location: " ).append( location ).append( System.lineSeparator() ); + } + this.getLog().info( sb.toString() ); + } + + /** + * Parses the given String into GAV artifact coordinate information, adding the given type. + * + * @param artifactString should respect the format groupId:artifactId[:version] + * @param type the extension for the artifact, must not be null + * @return the Artifact object for the artifactString parameter + * @throws MojoExecutionException if the artifactString doesn't respect the format + */ + private ArtifactCoordinate getArtifactCoordinate( String artifactString, String type ) + throws MojoExecutionException + { + if ( org.codehaus.plexus.util.StringUtils.isEmpty( artifactString ) ) + { + throw new IllegalArgumentException( "artifact parameter is empty" ); + } + + String groupId; // required + String artifactId; // required + String version; // optional + + String[] artifactParts = artifactString.split( ":" ); + switch ( artifactParts.length ) + { + case 2: + groupId = artifactParts[0]; + artifactId = artifactParts[1]; + version = Artifact.LATEST_VERSION; + break; + case 3: + groupId = artifactParts[0]; + artifactId = artifactParts[1]; + version = artifactParts[2]; + break; + default: + throw new MojoExecutionException( "The artifact parameter '" + artifactString + + "' should be conform to: " + "'groupId:artifactId[:version]'." ); + } + return getArtifactCoordinate( groupId, artifactId, version, type ); + } + + private ArtifactCoordinate getArtifactCoordinate( String groupId, String artifactId, String version, String type ) + { + DefaultArtifactCoordinate coordinate = new DefaultArtifactCoordinate(); + coordinate.setGroupId( groupId ); + coordinate.setArtifactId( artifactId ); + coordinate.setVersion( version ); + coordinate.setExtension( type ); + return coordinate; + } + + /** + * Retrieves the Maven Project associated with the given artifact String, in the form of + * groupId:artifactId[:version]. This resolves the POM artifact at those coordinates and then builds + * the Maven project from it. + * + * @param artifactString coordinates of the Maven project to get + * @return new Maven project + * @throws MojoExecutionException if there was an error while getting the Maven project + */ + private MavenProject getMavenProject( String artifactString ) + throws MojoExecutionException + { + ArtifactCoordinate coordinate = getArtifactCoordinate( artifactString, "pom" ); + try + { + ProjectBuildingRequest pbr = new DefaultProjectBuildingRequest( session.getProjectBuildingRequest() ); + pbr.setRemoteRepositories( pluginRepositories ); + pbr.setProject( null ); + pbr.setValidationLevel( ModelBuildingRequest.VALIDATION_LEVEL_MINIMAL ); + pbr.setResolveDependencies( false ); + Artifact artifact = artifactResolver.resolveArtifact( pbr, coordinate ).getArtifact(); + return projectBuilder.build( artifact.getFile(), pbr ).getProject(); + } + catch ( ArtifactResolverException | ProjectBuildingException | IllegalArgumentException e ) + { + throw new MojoExecutionException( "Unable to get the POM for the artifact '" + artifactString + + "'. Verify the artifact parameter.", e ); + } + } + + private void traversePom( ArtifactRepository artifactRepository, + Artifact artifact, MavenProject mavenProject, Set locations ) + throws MojoExecutionException + { + getLog().debug( "Looking for locations for repository " + repositoryAsString( artifactRepository ) + + " for " + artifact ); + if ( mavenProject != null ) + { + for ( Repository pluginRepository : mavenProject.getOriginalModel().getPluginRepositories() ) + { + getLog().debug( "Found plugin repository: " + repositoryAsString( pluginRepository ) + + " @ " + artifact + ":" + mavenProject.getOriginalModel().getPomFile() ); + if ( isRepositoryEqual( pluginRepository, artifactRepository ) ) + { + locations.add( mavenProject.getModel().getPomFile().toString() ); + } + } + traverseParentPom( artifactRepository, mavenProject, locations ); + } + else + { + throw new MojoExecutionException( "No POM for the artifact '" + artifact + "'" ); + } + } + + private void traverseParentPom( ArtifactRepository artifactRepository, + MavenProject mavenProject, Set locations ) + throws MojoExecutionException + { + MavenProject parent = mavenProject.getParent(); + if ( parent != null ) + { + Model originalModel = parent.getOriginalModel(); + if ( originalModel.getRepositories().size() != 0 + || originalModel.getPluginRepositories().size() != 0 ) + { + String artifactKey = + ArtifactUtils.key( parent.getGroupId(), parent.getArtifactId(), parent.getVersion() ); + MavenProject parentPom = getMavenProject( artifactKey ); + + for ( Repository pluginRepository : originalModel.getPluginRepositories() ) + { + verbose( "Found parent plugin repository: " + repositoryAsString( pluginRepository ) + + " @ " + parentPom.getArtifact() + ":" + parentPom.getFile() ); + if ( isRepositoryEqual( pluginRepository, artifactRepository ) ) + { + locations.add( parentPom.getFile().toString() ); + } + } + } + traverseParentPom( artifactRepository, parent, locations ); + } + } + + private String repositoryAsString( Repository repository ) + { + StringBuilder sb = new StringBuilder( 32 ); + sb.append( repository.getId() ); + sb.append( " (" ); + sb.append( repository.getUrl() ); + sb.append( ")" ); + return sb.toString(); + } + + private String repositoryAsString( ArtifactRepository repository ) + { + StringBuilder sb = new StringBuilder( 32 ); + sb.append( repository.getId() ); + sb.append( " (" ); + sb.append( repository.getUrl() ); + sb.append( ")" ); + return sb.toString(); + } + + private boolean isVerbose() + { + return ( verbose || getLog().isDebugEnabled() ); + } + + private void verbose( String message ) + { + if ( isVerbose() ) + { + getLog().info( message ); + } + } + + private boolean isRepositoryEqual( Repository repository, ArtifactRepository artifactRepository ) + { + return repository.getId().equals( artifactRepository.getId() ) + && repository.getUrl().equals( artifactRepository.getUrl() ); + } + +} diff --git a/src/main/java/org/apache/maven/plugins/dependency/resolvers/ResolveDependenciesMojo.java b/src/main/java/org/apache/maven/plugins/dependency/resolvers/ResolveDependenciesMojo.java index 135580fc8..e745b62cf 100644 --- a/src/main/java/org/apache/maven/plugins/dependency/resolvers/ResolveDependenciesMojo.java +++ b/src/main/java/org/apache/maven/plugins/dependency/resolvers/ResolveDependenciesMojo.java @@ -134,10 +134,10 @@ protected ArtifactsFilter getMarkedArtifactFilter() } /** - * @param outputAbsoluteArtifactFilename absolute artfiact filename. - * @param theOutputScope The output scope. - * @param theSort sort yes/no. - * @return The output. + * @param outputAbsoluteArtifactFilename absolute artifact filename + * @param theOutputScope the output scope + * @param theSort sort yes/no + * @return the output */ public String getOutput( boolean outputAbsoluteArtifactFilename, boolean theOutputScope, boolean theSort ) { diff --git a/src/main/java/org/apache/maven/plugins/dependency/resolvers/ResolvePluginsMojo.java b/src/main/java/org/apache/maven/plugins/dependency/resolvers/ResolvePluginsMojo.java index 33f774bac..0f45e90f3 100644 --- a/src/main/java/org/apache/maven/plugins/dependency/resolvers/ResolvePluginsMojo.java +++ b/src/main/java/org/apache/maven/plugins/dependency/resolvers/ResolvePluginsMojo.java @@ -21,17 +21,13 @@ import java.io.IOException; import java.util.LinkedHashSet; -import java.util.List; import java.util.Set; import org.apache.maven.artifact.Artifact; -import org.apache.maven.artifact.repository.ArtifactRepository; import org.apache.maven.plugin.MojoExecutionException; 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.dependency.utils.DependencyUtil; -import org.apache.maven.project.DefaultProjectBuildingRequest; import org.apache.maven.project.ProjectBuildingRequest; import org.apache.maven.shared.artifact.filter.collection.ArtifactFilterException; import org.apache.maven.shared.artifact.filter.collection.ArtifactsFilter; @@ -51,12 +47,6 @@ public class ResolvePluginsMojo extends AbstractResolveMojo { - /** - * Remote repositories which will be searched for plugins. - */ - @Parameter( defaultValue = "${project.pluginArtifactRepositories}", readonly = true, required = true ) - private List remotePluginRepositories; - /** * Main entry into mojo. Gets the list of dependencies and iterates through displaying the resolved version. * @@ -194,10 +184,7 @@ protected Set resolvePluginArtifacts() // continue; // } - ProjectBuildingRequest buildingRequest = - new DefaultProjectBuildingRequest( session.getProjectBuildingRequest() ); - - buildingRequest.setRemoteRepositories( this.remotePluginRepositories ); + ProjectBuildingRequest buildingRequest = newResolvePluginProjectBuildingRequest(); // resolve the new artifact resolvedArtifacts.add( getArtifactResolver().resolveArtifact( buildingRequest, artifact ).getArtifact() ); diff --git a/src/main/java/org/apache/maven/plugins/dependency/tree/TreeMojo.java b/src/main/java/org/apache/maven/plugins/dependency/tree/TreeMojo.java index ab1e7b201..3643b0730 100644 --- a/src/main/java/org/apache/maven/plugins/dependency/tree/TreeMojo.java +++ b/src/main/java/org/apache/maven/plugins/dependency/tree/TreeMojo.java @@ -479,9 +479,12 @@ public static boolean containsVersion( VersionRange allowedRange, ArtifactVersio return true; } } + return false; + } + else + { + // only singular versions ever have a recommendedVersion + return recommendedVersion.compareTo( theVersion ) <= 0; } - - // only singular versions ever have a recommendedVersion - return recommendedVersion.compareTo( theVersion ) <= 0; } } diff --git a/src/main/resources/analyze-report_en.properties b/src/main/resources/analyze-report_en.properties index e91332326..607b4bf3a 100644 --- a/src/main/resources/analyze-report_en.properties +++ b/src/main/resources/analyze-report_en.properties @@ -17,6 +17,6 @@ # NOTE: # This bundle is intentionally empty because English strings are provided by the base bundle via the parent chain. It -# must be provided nevertheless such that a request for locale "en" will not errorneously pick up the bundle for the +# must be provided nevertheless such that a request for locale "en" will not erroneously pick up the bundle for the # JVM's default locale (which need not be "en"). See the method javadoc about # ResourceBundle.getBundle(String, Locale, ClassLoader) diff --git a/src/site/apt/index.apt.vm b/src/site/apt/index.apt.vm index 5ce6848ef..f70ff32db 100644 --- a/src/site/apt/index.apt.vm +++ b/src/site/apt/index.apt.vm @@ -74,6 +74,8 @@ ${project.name} *{{{./list-repositories-mojo.html}dependency:list-repositories}} displays all project dependencies and then lists the repositories used. + *{{{./list-plugin-repositories-mojo.html}dependency:list-plugin-repositories}} lists the plugin repositories used. + *{{{./properties-mojo.html}dependency:properties}} set a property for each project dependency containing the to the artifact on the file system. diff --git a/src/site/apt/usage.apt.vm b/src/site/apt/usage.apt.vm index f14c46f78..08ae520c6 100644 --- a/src/site/apt/usage.apt.vm +++ b/src/site/apt/usage.apt.vm @@ -684,10 +684,28 @@ mvn dependency:build-classpath -Dmdep.outputFile=cp.txt * <<>> - This goal is used to list all the repositories that this build depends upon. It will show repositories defined in your settings, + This goal lists all the repositories that this build depends upon. It shows repositories defined in your settings, poms and declared in transitive dependency poms. +* <<>> + + This goal lists all the plugin repositories that this build depends upon. It shows plugin repositories defined in your settings, + poms and declared in transitive dependency poms. + + This goal can be executed from the command line: + ++-----+ +mvn dependency:list-plugin-repositories ++-----+ + + Optionally, in verbose or debug mode it displays the location of the listed plugin repository: + ++-----+ +mvn dependency:list-plugin-repositories -Dverbose ++-----+ + + * <<>> This goal is used to fetch an artifact and (optionally) its dependencies from remote repositories using its Maven coordinates. diff --git a/src/test/java/org/apache/maven/plugins/dependency/AbstractDependencyMojoTest.java b/src/test/java/org/apache/maven/plugins/dependency/AbstractDependencyMojoTest.java new file mode 100644 index 000000000..861ca478c --- /dev/null +++ b/src/test/java/org/apache/maven/plugins/dependency/AbstractDependencyMojoTest.java @@ -0,0 +1,148 @@ +package org.apache.maven.plugins.dependency; + +/* + * 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. + */ + +import junit.framework.TestCase; +import org.apache.maven.artifact.repository.ArtifactRepository; +import org.apache.maven.execution.MavenSession; +import org.apache.maven.project.ProjectBuildingRequest; + +import java.lang.reflect.Field; +import java.util.ArrayList; +import java.util.List; + +import static org.apache.maven.plugins.dependency.AbstractDependencyMojoTest.ConcreteDependencyMojo.createConcreteDependencyMojoWithArtifactRepositories; +import static org.apache.maven.plugins.dependency.AbstractDependencyMojoTest.ConcreteDependencyMojo.createConcreteDependencyMojoWithPluginRepositories; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.when; + +public class AbstractDependencyMojoTest extends TestCase +{ + private MavenSession session = mock( MavenSession.class ); + + private ProjectBuildingRequest buildingRequest = mock( ProjectBuildingRequest.class ); + + private ArrayList artifactRepos = new ArrayList<>(); + + private ArrayList pluginRepos = new ArrayList<>(); + + static class ConcreteDependencyMojo extends AbstractDependencyMojo + { + static ConcreteDependencyMojo createConcreteDependencyMojoWithArtifactRepositories( + MavenSession mavenSession, List artifactRepos ) + throws NoSuchFieldException, IllegalAccessException + { + ConcreteDependencyMojo cdm = new ConcreteDependencyMojo(); + cdm.session = mavenSession; + + Field par = AbstractDependencyMojo.class.getDeclaredField( "remoteRepositories" ); + par.setAccessible( true ); + par.set( cdm, artifactRepos ); + + return cdm; + } + + static ConcreteDependencyMojo createConcreteDependencyMojoWithPluginRepositories( + MavenSession mavenSession, List pluginRepos ) + throws NoSuchFieldException, IllegalAccessException + { + ConcreteDependencyMojo cdm = new ConcreteDependencyMojo(); + cdm.session = mavenSession; + + Field par = AbstractDependencyMojo.class.getDeclaredField( "remotePluginRepositories" ); + par.setAccessible( true ); + par.set( cdm, pluginRepos ); + + return cdm; + } + + @Override + protected void doExecute() + { + } + } + + @Override + protected void setUp() throws Exception + { + pluginRepos.add( newRepositoryWithId( "pr-central" ) ); + pluginRepos.add( newRepositoryWithId( "pr-plugins" ) ); + + artifactRepos.add( newRepositoryWithId( "ar-central" ) ); + artifactRepos.add( newRepositoryWithId( "ar-snapshots" ) ); + artifactRepos.add( newRepositoryWithId( "ar-staging" ) ); + + when( session.getProjectBuildingRequest() ).thenReturn( buildingRequest ); + } + + private static ArtifactRepository newRepositoryWithId( String id ) + { + ArtifactRepository repo = mock( ArtifactRepository.class ); + when( repo.getId() ).thenReturn( id ); + return repo; + } + + public void testNewResolveArtifactProjectBuildingRequestRemoteRepositoriesSize() + throws NoSuchFieldException, IllegalAccessException + { + AbstractDependencyMojo mojo = createConcreteDependencyMojoWithArtifactRepositories( session, artifactRepos ); + + ProjectBuildingRequest pbr = mojo.newResolveArtifactProjectBuildingRequest(); + List rrepos = pbr.getRemoteRepositories(); + + assertEquals( 3, rrepos.size() ); + } + + public void testNewResolveArtifactProjectBuildingRequestRemoteRepositoriesContents() + throws NoSuchFieldException, IllegalAccessException + { + AbstractDependencyMojo mojo = createConcreteDependencyMojoWithArtifactRepositories( session, artifactRepos ); + + ProjectBuildingRequest pbr = mojo.newResolveArtifactProjectBuildingRequest(); + List rrepos = pbr.getRemoteRepositories(); + + assertEquals( "ar-central", rrepos.get( 0 ).getId() ); + assertEquals( "ar-snapshots", rrepos.get( 1 ).getId() ); + assertEquals( "ar-staging", rrepos.get( 2 ).getId() ); + } + + public void testNewResolvePluginProjectBuildingRequestRemoteRepositoriesSize() + throws NoSuchFieldException, IllegalAccessException + { + AbstractDependencyMojo mojo = createConcreteDependencyMojoWithPluginRepositories( session, pluginRepos ); + + ProjectBuildingRequest pbr = mojo.newResolvePluginProjectBuildingRequest(); + List rrepos = pbr.getRemoteRepositories(); + + assertEquals( 2, rrepos.size() ); + } + + public void testNewResolvePluginProjectBuildingRequestRemoteRepositoriesContents() + throws NoSuchFieldException, IllegalAccessException + { + AbstractDependencyMojo mojo = createConcreteDependencyMojoWithPluginRepositories( session, pluginRepos ); + + ProjectBuildingRequest pbr = mojo.newResolvePluginProjectBuildingRequest(); + List rrepos = pbr.getRemoteRepositories(); + + assertEquals( "pr-central", rrepos.get( 0 ).getId() ); + assertEquals( "pr-plugins", rrepos.get( 1 ).getId() ); + } +} \ No newline at end of file diff --git a/src/test/java/org/apache/maven/plugins/dependency/TestGetClassesMojo.java b/src/test/java/org/apache/maven/plugins/dependency/TestGetClassesMojo.java new file mode 100644 index 000000000..6139ed747 --- /dev/null +++ b/src/test/java/org/apache/maven/plugins/dependency/TestGetClassesMojo.java @@ -0,0 +1,87 @@ +package org.apache.maven.plugins.dependency; + +/* + * 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. + */ + +import org.apache.maven.execution.MavenSession; +import org.apache.maven.plugin.LegacySupport; +import org.apache.maven.plugin.testing.stubs.MavenProjectStub; +import org.apache.maven.settings.Server; +import org.apache.maven.settings.Settings; +import org.junit.Assert; +import org.sonatype.aether.impl.internal.SimpleLocalRepositoryManager; +import org.sonatype.aether.util.DefaultRepositorySystemSession; + +import java.io.File; + +public class TestGetClassesMojo + extends AbstractDependencyMojoTestCase +{ + private ListClassesMojo mojo; + + protected void setUp() + throws Exception + { + // required for mojo lookups to work + super.setUp( "markers", false ); + + File testPom = new File( getBasedir(), "target/test-classes/unit/get-test/plugin-config.xml" ); + assertTrue(testPom.exists()); + mojo = (ListClassesMojo) lookupMojo( "list-classes", testPom ); + + assertNotNull( mojo ); + + LegacySupport legacySupport = lookup( LegacySupport.class ); + MavenSession session = newMavenSession( new MavenProjectStub() ); + Settings settings = session.getSettings(); + Server server = new Server(); + server.setId( "myserver" ); + server.setUsername( "foo" ); + server.setPassword( "bar" ); + settings.addServer( server ); + legacySupport.setSession( session ); + DefaultRepositorySystemSession repoSession = + (DefaultRepositorySystemSession) legacySupport.getRepositorySession(); + repoSession.setLocalRepositoryManager( new SimpleLocalRepositoryManager( testDir.getAbsolutePath() ) ); + + setVariableValueToObject( mojo, "session", legacySupport.getSession() ); + } + + public void testGetClassesNotTransitive() + throws Exception + { + setVariableValueToObject( mojo, "remoteRepositories", "central::default::https://repo.maven.apache.org/maven2," + + "central::::https://repo.maven.apache.org/maven2," + "https://repo.maven.apache.org/maven2" ); + setVariableValueToObject( mojo, "artifact", "org.apache.commons:commons-lang3:3.6" ); + setVariableValueToObject( mojo, "transitive", Boolean.FALSE ); + + mojo.execute(); + } + + public void testGetClassesTransitive() + throws Exception + { + setVariableValueToObject( mojo, "remoteRepositories", "central::default::https://repo.maven.apache.org/maven2," + + "central::::https://repo.maven.apache.org/maven2," + "https://repo.maven.apache.org/maven2" ); + setVariableValueToObject( mojo, "artifact", "org.apache.commons:commons-lang3:3.6" ); + setVariableValueToObject( mojo, "transitive", Boolean.TRUE ); + + mojo.execute(); + } +} diff --git a/src/test/java/org/apache/maven/plugins/dependency/analyze/TestAnalyzeDepMgt.java b/src/test/java/org/apache/maven/plugins/dependency/analyze/TestAnalyzeDepMgt.java index 268ac1d13..d3392a2d7 100644 --- a/src/test/java/org/apache/maven/plugins/dependency/analyze/TestAnalyzeDepMgt.java +++ b/src/test/java/org/apache/maven/plugins/dependency/analyze/TestAnalyzeDepMgt.java @@ -34,6 +34,8 @@ import org.apache.maven.model.Dependency; import org.apache.maven.model.DependencyManagement; import org.apache.maven.model.Exclusion; +import org.apache.maven.plugin.MojoExecutionException; +import org.apache.maven.plugin.MojoFailureException; import org.apache.maven.plugins.dependency.testUtils.DependencyArtifactStubFactory; import org.apache.maven.plugins.dependency.testUtils.stubs.DependencyProjectStub; import org.apache.maven.project.MavenProject; @@ -192,60 +194,30 @@ public void testGetMismatch() } public void testMojo() - throws IOException + throws IOException, MojoExecutionException, MojoFailureException { mojo.setIgnoreDirect( false ); - try - { - // test with nothing in depMgt - mojo.execute(); - } - catch ( Exception e ) - { - e.printStackTrace(); - fail( "Caught Unexpected Exception:" + e.getLocalizedMessage() ); - } + // test with nothing in depMgt + mojo.execute(); - try - { - DependencyProjectStub project = (DependencyProjectStub) mojo.getProject(); - project.setDependencyManagement( depMgt ); - // test with exclusion - mojo.execute(); - } - catch ( Exception e ) - { - e.printStackTrace(); - fail( "Caught Unexpected Exception:" + e.getLocalizedMessage() ); - } + DependencyProjectStub project = (DependencyProjectStub) mojo.getProject(); + project.setDependencyManagement( depMgt ); + // test with exclusion + mojo.execute(); try { - DependencyProjectStub project = (DependencyProjectStub) mojo.getProject(); - project.setDependencyManagement( depMgt ); // test with exclusion mojo.setFailBuild( true ); mojo.execute(); fail( "Expected exception to fail the build." ); } - catch ( Exception e ) + catch ( MojoExecutionException e ) { - System.out.println( "Caught Expected Exception:" + e.getLocalizedMessage() ); } - try - { - DependencyProjectStub project = (DependencyProjectStub) mojo.getProject(); - project.setDependencyManagement( depMgt ); - // test with exclusion - mojo.setFailBuild( true ); - mojo.setIgnoreDirect( true ); - mojo.execute(); - } - catch ( Exception e ) - { - e.printStackTrace(); - fail( "Caught Unexpected Exception:" + e.getLocalizedMessage() ); - } + mojo.setFailBuild( true ); + mojo.setIgnoreDirect( true ); + mojo.execute(); } } diff --git a/src/test/java/org/apache/maven/plugins/dependency/resolvers/ExcludeReactorProjectsDependencyFilterTest.java b/src/test/java/org/apache/maven/plugins/dependency/resolvers/ExcludeReactorProjectsDependencyFilterTest.java index ee6687560..9a23afd55 100644 --- a/src/test/java/org/apache/maven/plugins/dependency/resolvers/ExcludeReactorProjectsDependencyFilterTest.java +++ b/src/test/java/org/apache/maven/plugins/dependency/resolvers/ExcludeReactorProjectsDependencyFilterTest.java @@ -34,6 +34,7 @@ import java.util.Set; import static java.util.Collections.singletonList; + import static org.mockito.Mockito.mock; import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; diff --git a/src/test/java/org/apache/maven/plugins/dependency/testUtils/stubs/DependencyProjectStub.java b/src/test/java/org/apache/maven/plugins/dependency/testUtils/stubs/DependencyProjectStub.java index f8bafdb79..f8127150b 100644 --- a/src/test/java/org/apache/maven/plugins/dependency/testUtils/stubs/DependencyProjectStub.java +++ b/src/test/java/org/apache/maven/plugins/dependency/testUtils/stubs/DependencyProjectStub.java @@ -96,10 +96,6 @@ public class DependencyProjectStub private List pluginArtifactRepositories; - // private ArtifactRepository releaseArtifactRepository; - - // private ArtifactRepository snapshotArtifactRepository; - private List activeProfiles; private Set dependencyArtifacts; @@ -108,20 +104,8 @@ public class DependencyProjectStub private Artifact artifact; - // private Map artifactMap; - private Model originalModel; - // private Map pluginArtifactMap; - - // private Map reportArtifactMap; - - // private Map extensionArtifactMap; - - // private Map projectReferences; - - // private Build buildOverlay; - private boolean executionRoot; private List compileArtifacts; @@ -422,36 +406,6 @@ public void setScriptSourceRoots( List scriptSourceRoots ) this.scriptSourceRoots = scriptSourceRoots; } - public void setArtifactMap( Map artifactMap ) - { - // this.artifactMap = artifactMap; - } - - public void setPluginArtifactMap( Map pluginArtifactMap ) - { - // this.pluginArtifactMap = pluginArtifactMap; - } - - public void setReportArtifactMap( Map reportArtifactMap ) - { - // this.reportArtifactMap = reportArtifactMap; - } - - public void setExtensionArtifactMap( Map extensionArtifactMap ) - { - // this.extensionArtifactMap = extensionArtifactMap; - } - - public void setProjectReferences( Map projectReferences ) - { - // this.projectReferences = projectReferences; - } - - public void setBuildOverlay( Build buildOverlay ) - { - // this.buildOverlay = buildOverlay; - } - public void setCompileDependencies( List compileDependencies ) { this.compileDependencies = compileDependencies; @@ -657,7 +611,8 @@ public Scm getScm() return null; } - public void setMailingLists( List list ) + @Override + public void setMailingLists( List list ) { } @@ -672,7 +627,8 @@ public void addMailingList( MailingList mailingList ) } - public void setDevelopers( List list ) + @Override + public void setDevelopers( List list ) { } @@ -742,7 +698,7 @@ public Reporting getReporting() return null; } - public void setLicenses( List list ) + public void setLicenses( List list ) { } @@ -993,6 +949,7 @@ public List getBuildExtensions() return Collections.emptyList(); } + @Override public Set createArtifacts( ArtifactFactory artifactFactory, String string, ArtifactFilter artifactFilter ) throws InvalidDependencyVersionException { diff --git a/src/test/java/org/apache/maven/plugins/dependency/tree/TestTreeMojo_ContainsVersion.java b/src/test/java/org/apache/maven/plugins/dependency/tree/TestTreeMojo_ContainsVersion.java new file mode 100644 index 000000000..4c9815a52 --- /dev/null +++ b/src/test/java/org/apache/maven/plugins/dependency/tree/TestTreeMojo_ContainsVersion.java @@ -0,0 +1,51 @@ +package org.apache.maven.plugins.dependency.tree; + +/* + * 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. + */ + +import junit.framework.TestCase; +import org.apache.maven.artifact.versioning.ArtifactVersion; +import org.apache.maven.artifact.versioning.Restriction; +import org.apache.maven.artifact.versioning.VersionRange; + +import java.util.Collections; + +import static org.apache.maven.plugins.dependency.tree.TreeMojo.containsVersion; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.when; + +/** + * Tests TreeMojo.containsVersion. + */ +public class TestTreeMojo_ContainsVersion extends TestCase +{ + private VersionRange range = mock( VersionRange.class ); + + private ArtifactVersion version = mock( ArtifactVersion.class ); + + public void testWhenRecommendedVersionIsNullAndNoRestrictions() + { + when( range.getRecommendedVersion() ).thenReturn( null ); + when( range.getRestrictions() ).thenReturn( Collections.emptyList() ); + + boolean doesItContain = containsVersion( range, version ); + + assertFalse( doesItContain ); + } +} diff --git a/src/test/java/org/apache/maven/plugins/dependency/utils/translators/TestClassifierTypeTranslator.java b/src/test/java/org/apache/maven/plugins/dependency/utils/translators/TestClassifierTypeTranslator.java index 5c202a651..5e7769885 100644 --- a/src/test/java/org/apache/maven/plugins/dependency/utils/translators/TestClassifierTypeTranslator.java +++ b/src/test/java/org/apache/maven/plugins/dependency/utils/translators/TestClassifierTypeTranslator.java @@ -55,7 +55,6 @@ public class TestClassifierTypeTranslator Log log = new SilentLog(); - private ArtifactHandlerManager artifactHandlerManager; @Override @@ -75,7 +74,6 @@ protected void setUp() DependencyArtifactStubFactory factory = new DependencyArtifactStubFactory( null, false ); artifacts = factory.getMixedArtifacts(); - MavenSession session = newMavenSession( new MavenProjectStub() ); DefaultRepositorySystemSession repoSession = (DefaultRepositorySystemSession) session.getRepositorySession();