diff --git a/pom.xml b/pom.xml index 7430747..e556d80 100644 --- a/pom.xml +++ b/pom.xml @@ -63,10 +63,10 @@ - 3.2.5 - 1.7.32 - 1.1.0 7 + 3.2.5 + 1.0.0.v20140518 + 1.7.5 2020-04-07T21:04:00Z @@ -97,9 +97,20 @@ provided - org.apache.maven.shared - maven-artifact-transfer - 0.13.1 + org.eclipse.aether + aether-api + ${aetherVersion} + provided + + + org.eclipse.aether + aether-util + ${aetherVersion} + compile + + + org.codehaus.plexus + plexus-utils @@ -145,18 +156,6 @@ ${slf4jVersion} test - - org.eclipse.aether - aether-api - ${aetherVersion} - test - - - org.eclipse.aether - aether-util - ${aetherVersion} - test - org.eclipse.aether aether-impl diff --git a/src/it/install-file-minstall-121-targz/invoker.properties b/src/it/install-file-minstall-121-targz/invoker.properties new file mode 100644 index 0000000..0413238 --- /dev/null +++ b/src/it/install-file-minstall-121-targz/invoker.properties @@ -0,0 +1,18 @@ +# 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 = org.apache.maven.plugins:maven-install-plugin:${project.version}:install-file diff --git a/src/it/install-file-minstall-121-targz/pom.xml b/src/it/install-file-minstall-121-targz/pom.xml new file mode 100644 index 0000000..72009e3 --- /dev/null +++ b/src/it/install-file-minstall-121-targz/pom.xml @@ -0,0 +1,46 @@ + + + + + + 4.0.0 + + org.apache.maven.its.install.121 + test-targz + 1.0 + jar + + + Test to install a file via install:install-file using + packaging and expected having a different file extension. + + + + + + org.apache.maven.plugins + maven-install-plugin + @project.version@ + + + + + diff --git a/src/it/install-file-minstall-121-targz/setup.bsh b/src/it/install-file-minstall-121-targz/setup.bsh new file mode 100644 index 0000000..44849e7 --- /dev/null +++ b/src/it/install-file-minstall-121-targz/setup.bsh @@ -0,0 +1,29 @@ +/* + * 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.*; +import java.util.*; + +import org.codehaus.plexus.util.*; + +File file = new File( localRepositoryPath, "org/apache/maven/its/install/121/test-targz" ); +System.out.println( "Deleting " + file ); +FileUtils.deleteDirectory( file ); + +return true; diff --git a/src/it/install-file-minstall-121-targz/test-0.1.pom b/src/it/install-file-minstall-121-targz/test-0.1.pom new file mode 100644 index 0000000..fe478fe --- /dev/null +++ b/src/it/install-file-minstall-121-targz/test-0.1.pom @@ -0,0 +1,35 @@ + + + + + + 4.0.0 + + + org.apache.maven.its.install.121 + parent + 1.0 + + + + test-targz + + diff --git a/src/it/install-file-minstall-121-targz/test-0.1.tar.gz b/src/it/install-file-minstall-121-targz/test-0.1.tar.gz new file mode 100644 index 0000000..226277c Binary files /dev/null and b/src/it/install-file-minstall-121-targz/test-0.1.tar.gz differ diff --git a/src/it/install-file-minstall-121-targz/test.properties b/src/it/install-file-minstall-121-targz/test.properties new file mode 100644 index 0000000..8485d14 --- /dev/null +++ b/src/it/install-file-minstall-121-targz/test.properties @@ -0,0 +1,20 @@ +# 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 = test-0.1.tar.gz +pomFile = test-0.1.pom +packaging = war diff --git a/src/it/install-file-minstall-121-targz/verify.bsh b/src/it/install-file-minstall-121-targz/verify.bsh new file mode 100644 index 0000000..b3f31de --- /dev/null +++ b/src/it/install-file-minstall-121-targz/verify.bsh @@ -0,0 +1,52 @@ +/* + * 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.*; +import java.util.*; + +String[] paths = +{ + "org/apache/maven/its/install/121/test-targz/maven-metadata-local.xml", + "org/apache/maven/its/install/121/test-targz/1.0/test-targz-1.0.pom", + "org/apache/maven/its/install/121/test-targz/1.0/test-targz-1.0.tar.gz", +}; + +for ( String path : paths ) +{ + File file = new File( localRepositoryPath, path ); + System.out.println( "Checking for existence of " + file ); + if ( !file.isFile() ) + { + throw new FileNotFoundException( "Missing: " + file.getAbsolutePath() ); + } +} + +File file = new File( basedir, "test-0.1.pom" ); +if ( !file.isFile() ) +{ + throw new FileNotFoundException( "Missing: " + file.getAbsolutePath() ); +} + +File file = new File( basedir, "test-0.1.tar.gz" ); +if ( !file.isFile() ) +{ + throw new FileNotFoundException( "Missing: " + file.getAbsolutePath() ); +} + +return true; diff --git a/src/main/java/org/apache/maven/plugins/install/AbstractInstallMojo.java b/src/main/java/org/apache/maven/plugins/install/AbstractInstallMojo.java deleted file mode 100644 index 96d0f53..0000000 --- a/src/main/java/org/apache/maven/plugins/install/AbstractInstallMojo.java +++ /dev/null @@ -1,76 +0,0 @@ -package org.apache.maven.plugins.install; - -/* - * 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.File; - -import org.apache.maven.artifact.Artifact; -import org.apache.maven.execution.MavenSession; -import org.apache.maven.plugin.AbstractMojo; -import org.apache.maven.plugins.annotations.Component; -import org.apache.maven.plugins.annotations.Parameter; -import org.apache.maven.project.ProjectBuildingRequest; -import org.apache.maven.project.artifact.ProjectArtifactMetadata; -import org.apache.maven.shared.transfer.repository.RepositoryManager; - -/** - * Common fields for installation mojos. - * - * @author Brett Porter - */ -public abstract class AbstractInstallMojo - extends AbstractMojo -{ - - @Component - protected RepositoryManager repositoryManager; - - @Parameter( defaultValue = "${session}", required = true, readonly = true ) - protected MavenSession session; - - /** - * Gets the path of the specified artifact within the local repository. Note that the returned path need not exist - * (yet). - * - * @param buildingRequest {@link ProjectBuildingRequest}. - * @param artifact The artifact whose local repo path should be determined, must not be null. - * @return The absolute path to the artifact when installed, never null. - */ - protected File getLocalRepoFile( ProjectBuildingRequest buildingRequest, Artifact artifact ) - { - String path = repositoryManager.getPathForLocalArtifact( buildingRequest, artifact ); - return new File( repositoryManager.getLocalRepositoryBasedir( buildingRequest ), path ); - } - - /** - * Gets the path of the specified artifact metadata within the local repository. Note that the returned path need - * not exist (yet). - * - * @param buildingRequest {@link ProjectBuildingRequest}. - * @param metadata The artifact metadata whose local repo path should be determined, must not be null. - * @return The absolute path to the artifact metadata when installed, never null. - */ - protected File getLocalRepoFile( ProjectBuildingRequest buildingRequest, ProjectArtifactMetadata metadata ) - { - String path = repositoryManager.getPathForLocalMetadata( buildingRequest, metadata ); - return new File( repositoryManager.getLocalRepositoryBasedir( buildingRequest ), path ); - } - -} diff --git a/src/main/java/org/apache/maven/plugins/install/InstallFileMojo.java b/src/main/java/org/apache/maven/plugins/install/InstallFileMojo.java index 32865b2..aab859f 100644 --- a/src/main/java/org/apache/maven/plugins/install/InstallFileMojo.java +++ b/src/main/java/org/apache/maven/plugins/install/InstallFileMojo.java @@ -21,46 +21,46 @@ import java.io.File; import java.io.FileNotFoundException; -import java.io.FileOutputStream; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; import java.io.Reader; import java.io.Writer; +import java.nio.file.Files; import java.util.Enumeration; import java.util.jar.JarEntry; import java.util.jar.JarFile; import java.util.regex.Pattern; -import org.apache.maven.artifact.Artifact; -import org.apache.maven.artifact.handler.DefaultArtifactHandler; +import org.apache.maven.execution.MavenSession; import org.apache.maven.model.Model; import org.apache.maven.model.Parent; -import org.apache.maven.model.building.ModelBuildingException; -import org.apache.maven.model.building.ModelSource; -import org.apache.maven.model.building.StringModelSource; import org.apache.maven.model.io.xpp3.MavenXpp3Reader; import org.apache.maven.model.io.xpp3.MavenXpp3Writer; +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.MavenProject; -import org.apache.maven.project.MavenProjectHelper; -import org.apache.maven.project.ProjectBuilder; -import org.apache.maven.project.ProjectBuildingException; -import org.apache.maven.project.ProjectBuildingRequest; -import org.apache.maven.project.artifact.ProjectArtifactMetadata; -import org.apache.maven.shared.transfer.project.install.ProjectInstaller; -import org.apache.maven.shared.transfer.project.install.ProjectInstallerRequest; -import org.apache.maven.shared.utils.Os; -import org.apache.maven.shared.utils.ReaderFactory; -import org.apache.maven.shared.utils.WriterFactory; -import org.apache.maven.shared.utils.io.IOUtil; import org.codehaus.plexus.util.FileUtils; +import org.codehaus.plexus.util.IOUtil; +import org.codehaus.plexus.util.StringUtils; +import org.codehaus.plexus.util.xml.XmlStreamReader; +import org.codehaus.plexus.util.xml.XmlStreamWriter; import org.codehaus.plexus.util.xml.pull.XmlPullParserException; +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.DefaultArtifact; +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.util.artifact.SubArtifact; /** * Installs a file in the local repository. @@ -69,8 +69,15 @@ */ @Mojo( name = "install-file", requiresProject = false, aggregator = true, threadSafe = true ) public class InstallFileMojo - extends AbstractInstallMojo + extends AbstractMojo { + private static final String LS = System.getProperty( "line.separator" ); + + @Component + private RepositorySystem repositorySystem; + + @Parameter( defaultValue = "${session}", required = true, readonly = true ) + private MavenSession session; /** * GroupId of the artifact to be installed. Retrieved from POM file if one is specified or extracted from @@ -158,31 +165,10 @@ public class InstallFileMojo @Parameter( property = "localRepositoryPath" ) private File localRepositoryPath; - /** - * Used for attaching the artifacts to install to the project. - */ - @Component - private MavenProjectHelper projectHelper; - - /** - * Used for creating the project to which the artifacts to install will be attached. - */ - @Component - private ProjectBuilder projectBuilder; - - /** - * Used to install the project created. - */ - @Component - private ProjectInstaller installer; - - /** - * @see org.apache.maven.plugin.Mojo#execute() - */ + @Override public void execute() throws MojoExecutionException, MojoFailureException { - if ( !file.exists() ) { String message = "The specified file '" + file.getPath() + "' does not exist"; @@ -190,16 +176,25 @@ public void execute() throw new MojoFailureException( message ); } - ProjectBuildingRequest buildingRequest = session.getProjectBuildingRequest(); - - // ---------------------------------------------------------------------- - // Override the default localRepository variable - // ---------------------------------------------------------------------- + RepositorySystemSession repositorySystemSession = session.getRepositorySession(); if ( localRepositoryPath != null ) { - buildingRequest = repositoryManager.setLocalRepositoryBasedir( buildingRequest, localRepositoryPath ); - - getLog().debug( "localRepoPath: " + repositoryManager.getLocalRepositoryBasedir( buildingRequest ) ); + // "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() ); } File temporaryPom = null; @@ -214,65 +209,63 @@ public void execute() pomFile = temporaryPom; } - MavenProject project = createMavenProject(); - - // We need to set a new ArtifactHandler otherwise - // the extension will be set to the packaging type - // which is sometimes wrong. - DefaultArtifactHandler ah = new DefaultArtifactHandler( packaging ); - ah.setExtension( FileUtils.getExtension( file.getName() ) ); - - project.getArtifact().setArtifactHandler( ah ); - Artifact artifact = project.getArtifact(); + if ( groupId == null || artifactId == null || version == null || packaging == null ) + { + throw new MojoExecutionException( "The artifact information is incomplete: 'groupId', 'artifactId', " + + "'version' and 'packaging' are required." ); + } - if ( file.equals( getLocalRepoFile( buildingRequest, artifact ) ) ) + if ( !isValidId( groupId ) + || !isValidId( artifactId ) + || !isValidVersion( version ) ) { - throw new MojoFailureException( "Cannot install artifact. " - + "Artifact is already in the local repository.\n\nFile in question is: " + file + "\n" ); + throw new MojoExecutionException( "The artifact information is not valid: uses invalid characters." ); } - if ( classifier == null ) + InstallRequest installRequest = new InstallRequest(); + + boolean isFilePom = classifier == null && "pom".equals( packaging ); + if ( !isFilePom ) { - artifact.setFile( file ); - if ( "pom".equals( packaging ) ) + ArtifactType artifactType = repositorySystemSession.getArtifactTypeRegistry().get( packaging ); + if ( artifactType != null + && StringUtils.isEmpty( classifier ) + && !StringUtils.isEmpty( artifactType.getClassifier() ) ) { - project.setFile( file ); + classifier = artifactType.getClassifier(); } } - else + Artifact mainArtifact = new DefaultArtifact( + groupId, + artifactId, + classifier, + isFilePom ? "pom" : getExtension( file ), + version + ).setFile( file ); + installRequest.addArtifact( mainArtifact ); + + File artifactLocalFile = getLocalRepositoryFile( session.getRepositorySession(), mainArtifact ); + File pomLocalFile = getPomLocalRepositoryFile( session.getRepositorySession(), mainArtifact ); + + if ( file.equals( artifactLocalFile ) ) { - projectHelper.attachArtifact( project, packaging, classifier, file ); + throw new MojoFailureException( "Cannot install artifact. " + + "Artifact is already in the local repository." + LS + LS + "File in question is: " + file + LS ); } if ( !"pom".equals( packaging ) ) { if ( pomFile != null ) { - if ( classifier == null ) - { - artifact.addMetadata( new ProjectArtifactMetadata( artifact, pomFile ) ); - } - else - { - project.setFile( pomFile ); - } + installRequest.addArtifact( new SubArtifact( mainArtifact, "", "pom", pomFile ) ); } else { - temporaryPom = generatePomFile(); - ProjectArtifactMetadata pomMetadata = new ProjectArtifactMetadata( artifact, temporaryPom ); - if ( Boolean.TRUE.equals( generatePom ) - || ( generatePom == null && !getLocalRepoFile( buildingRequest, pomMetadata ).exists() ) ) + if ( Boolean.TRUE.equals( generatePom ) || ( generatePom == null && !pomLocalFile.exists() ) ) { + temporaryPom = generatePomFile(); getLog().debug( "Installing generated POM" ); - if ( classifier == null ) - { - artifact.addMetadata( pomMetadata ); - } - else - { - project.setFile( temporaryPom ); - } + installRequest.addArtifact( new SubArtifact( mainArtifact, "", "pom", temporaryPom ) ); } else if ( generatePom == null ) { @@ -283,24 +276,19 @@ else if ( generatePom == null ) if ( sources != null ) { - projectHelper.attachArtifact( project, "jar", "sources", sources ); + installRequest.addArtifact( new SubArtifact( mainArtifact, "sources", "jar", sources ) ); } if ( javadoc != null ) { - projectHelper.attachArtifact( project, "jar", "javadoc", javadoc ); + installRequest.addArtifact( new SubArtifact( mainArtifact, "javadoc", "jar", javadoc ) ); } try { - // CHECKSTYLE_OFF: LineLength - ProjectInstallerRequest projectInstallerRequest = - new ProjectInstallerRequest().setProject( project ); - // CHECKSTYLE_ON: LineLength - - installer.install( buildingRequest, projectInstallerRequest ); + repositorySystem.install( repositorySystemSession, installRequest ); } - catch ( Exception e ) + catch ( InstallationException e ) { throw new MojoExecutionException( e.getMessage(), e ); } @@ -314,43 +302,6 @@ else if ( generatePom == null ) } } - /** - * Creates a Maven project in-memory from the user-supplied groupId, artifactId and version. When a classifier is - * supplied, the packaging must be POM because the project with only have attachments. This project serves as basis - * to attach the artifacts to install to. - * - * @return The created Maven project, never null. - * @throws MojoExecutionException When the model of the project could not be built. - * @throws MojoFailureException When building the project failed. - */ - private MavenProject createMavenProject() - throws MojoExecutionException, MojoFailureException - { - if ( groupId == null || artifactId == null || version == null || packaging == null ) - { - throw new MojoExecutionException( "The artifact information is incomplete: 'groupId', 'artifactId', " - + "'version' and 'packaging' are required." ); - } - ModelSource modelSource = new StringModelSource( "4.0.0" - + groupId + "" + artifactId + "" + version - + "" + ( classifier == null ? packaging : "pom" ) + "" ); - ProjectBuildingRequest pbr = new DefaultProjectBuildingRequest( session.getProjectBuildingRequest() ); - pbr.setProcessPlugins( false ); - try - { - return projectBuilder.build( modelSource, pbr ).getProject(); - } - catch ( ProjectBuildingException e ) - { - if ( e.getCause() instanceof ModelBuildingException ) - { - throw new MojoExecutionException( "The artifact information is not valid:" + Os.LINE_SEP - + e.getCause().getMessage() ); - } - throw new MojoFailureException( "Unable to create the project.", e ); - } - } - private File readingPomFromJarFile() throws MojoExecutionException { @@ -387,7 +338,7 @@ private File readingPomFromJarFile() } pomFile = File.createTempFile( base, ".pom" ); - pomOutputStream = new FileOutputStream( pomFile ); + pomOutputStream = Files.newOutputStream( pomFile.toPath() ); IOUtil.copy( pomInputStream, pomOutputStream ); @@ -448,7 +399,7 @@ private Model readModel( File pomFile ) Reader reader = null; try { - reader = ReaderFactory.newXmlReader( pomFile ); + reader = new XmlStreamReader( pomFile ); final Model model = new MavenXpp3Reader().read( reader ); reader.close(); reader = null; @@ -545,7 +496,7 @@ private File generatePomFile() { File pomFile = File.createTempFile( "mvninstall", ".pom" ); - writer = WriterFactory.newXmlWriter( pomFile ); + writer = new XmlStreamWriter( pomFile ); new MavenXpp3Writer().write( writer, model ); writer.close(); writer = null; @@ -562,4 +513,85 @@ private File generatePomFile() } } + /** + * Gets the path of the specified artifact within the local repository. Note that the returned path need not exist + * (yet). + */ + private File getLocalRepositoryFile( RepositorySystemSession session, Artifact artifact ) + { + String path = session.getLocalRepositoryManager().getPathForLocalArtifact( artifact ); + return new File( session.getLocalRepository().getBasedir(), path ); + } + + /** + * Gets the path of the specified artifact POM within the local repository. Note that the returned path need + * not exist (yet). + */ + private File getPomLocalRepositoryFile( RepositorySystemSession session, Artifact artifact ) + { + SubArtifact pomArtifact = new SubArtifact( artifact, "", "pom" ); + String path = session.getLocalRepositoryManager().getPathForLocalArtifact( pomArtifact ); + return new File( session.getLocalRepository().getBasedir(), path ); + } + + // these below should be shared (duplicated in m-install-p, m-deploy-p) + + /** + * Specialization of {@link FileUtils#getExtension(String)} that honors various {@code tar.xxx} combinations. + */ + private String getExtension( final File file ) + { + String filename = file.getName(); + if ( filename.contains( ".tar." ) ) + { + return "tar." + FileUtils.getExtension( filename ); + } + else + { + return FileUtils.getExtension( filename ); + } + } + + /** + * Returns {@code true} if passed in string is "valid Maven ID" (groupId or artifactId). + */ + private boolean isValidId( String id ) + { + if ( id == null ) + { + return false; + } + for ( int i = 0; i < id.length(); i++ ) + { + char c = id.charAt( i ); + if ( !( c >= 'a' && c <= 'z' || c >= 'A' && c <= 'Z' + || c >= '0' && c <= '9' || c == '-' || c == '_' || c == '.' ) ) + { + return false; + } + } + return true; + } + + private static final String ILLEGAL_VERSION_CHARS = "\\/:\"<>|?*[](){},"; + + /** + * Returns {@code true} if passed in string is "valid Maven (simple. non range, expression, etc) version". + */ + private boolean isValidVersion( String version ) + { + if ( version == null ) + { + return false; + } + for ( int i = version.length() - 1; i >= 0; i-- ) + { + if ( ILLEGAL_VERSION_CHARS.indexOf( version.charAt( i ) ) >= 0 ) + { + return false; + } + } + return true; + } + } diff --git a/src/main/java/org/apache/maven/plugins/install/InstallMojo.java b/src/main/java/org/apache/maven/plugins/install/InstallMojo.java index 8ea2f30..a6c694b 100644 --- a/src/main/java/org/apache/maven/plugins/install/InstallMojo.java +++ b/src/main/java/org/apache/maven/plugins/install/InstallMojo.java @@ -19,10 +19,13 @@ * under the License. */ -import java.io.IOException; +import java.io.File; import java.util.List; import java.util.Map; +import org.apache.maven.RepositoryUtils; +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.plugin.descriptor.PluginDescriptor; @@ -31,10 +34,13 @@ import org.apache.maven.plugins.annotations.Mojo; import org.apache.maven.plugins.annotations.Parameter; import org.apache.maven.project.MavenProject; -import org.apache.maven.shared.transfer.artifact.install.ArtifactInstallerException; -import org.apache.maven.shared.transfer.project.NoFileAssignedException; -import org.apache.maven.shared.transfer.project.install.ProjectInstaller; -import org.apache.maven.shared.transfer.project.install.ProjectInstallerRequest; +import org.apache.maven.project.artifact.ProjectArtifact; +import org.apache.maven.project.artifact.ProjectArtifactMetadata; +import org.eclipse.aether.RepositorySystem; +import org.eclipse.aether.artifact.Artifact; +import org.eclipse.aether.installation.InstallRequest; +import org.eclipse.aether.installation.InstallationException; +import org.eclipse.aether.util.artifact.SubArtifact; /** * Installs the project's main artifact, and any other artifacts attached by other plugins in the lifecycle, to the @@ -44,8 +50,14 @@ */ @Mojo( name = "install", defaultPhase = LifecyclePhase.INSTALL, threadSafe = true ) public class InstallMojo - extends AbstractInstallMojo + extends AbstractMojo { + @Component + private RepositorySystem repositorySystem; + + @Parameter( defaultValue = "${session}", required = true, readonly = true ) + private MavenSession session; + @Parameter( defaultValue = "${project}", readonly = true, required = true ) private MavenProject project; @@ -74,9 +86,6 @@ public class InstallMojo @Parameter( property = "maven.install.skip", defaultValue = "false" ) private boolean skip; - @Component - private ProjectInstaller installer; - private enum State { SKIPPED, INSTALLED, TO_BE_INSTALLED @@ -101,6 +110,7 @@ private boolean hasState( MavenProject project ) return pluginContext.containsKey( INSTALL_PROCESSED_MARKER ); } + @Override public void execute() throws MojoExecutionException, MojoFailureException { @@ -118,7 +128,8 @@ public void execute() } else { - getLog().info( "Deferring install for " + getProjectReferenceId( project ) + " at end" ); + getLog().info( "Deferring install for " + project.getGroupId() + + ":" + project.getArtifactId() + ":" + project.getVersion() + " at end" ); putState( State.TO_BE_INSTALLED ); } } @@ -136,11 +147,6 @@ public void execute() } } - private String getProjectReferenceId( MavenProject mavenProject ) - { - return mavenProject.getGroupId() + ":" + mavenProject.getArtifactId() + ":" + mavenProject.getVersion(); - } - private boolean allProjectsMarked() { for ( MavenProject reactorProject : reactorProjects ) @@ -153,31 +159,90 @@ private boolean allProjectsMarked() return true; } - private void installProject( MavenProject pir ) - throws MojoFailureException, MojoExecutionException + private void installProject( MavenProject project ) throws MojoExecutionException, MojoFailureException { try { - installer.install( session.getProjectBuildingRequest(), new ProjectInstallerRequest().setProject( pir ) ); + repositorySystem.install( session.getRepositorySession(), processProject( project ) ); } - catch ( IOException e ) + catch ( IllegalArgumentException e ) { - throw new MojoFailureException( "IOException", e ); + throw new MojoFailureException( e.getMessage(), e ); } - catch ( ArtifactInstallerException e ) + catch ( InstallationException e ) { - throw new MojoExecutionException( "ArtifactInstallerException", e ); + throw new MojoExecutionException( e.getMessage(), e ); } - catch ( NoFileAssignedException e ) + } + + /** + * Processes passed in {@link MavenProject} and produces {@link InstallRequest} out of it. + * + * @throws IllegalArgumentException if project is badly set up. + */ + private InstallRequest processProject( MavenProject project ) + { + InstallRequest request = new InstallRequest(); + org.apache.maven.artifact.Artifact mavenMainArtifact = project.getArtifact(); + String packaging = project.getPackaging(); + File pomFile = project.getFile(); + boolean isPomArtifact = "pom".equals( packaging ); + boolean pomArtifactAttached = false; + + if ( pomFile != null ) { - throw new MojoExecutionException( "NoFileAssignedException", e ); + request.addArtifact( RepositoryUtils.toArtifact( new ProjectArtifact( project ) ) ); + pomArtifactAttached = true; } - } + if ( !isPomArtifact ) + { + File file = mavenMainArtifact.getFile(); + if ( file != null && file.isFile() ) + { + Artifact mainArtifact = RepositoryUtils.toArtifact( mavenMainArtifact ); + request.addArtifact( mainArtifact ); - public void setSkip( boolean skip ) - { - this.skip = skip; + if ( !pomArtifactAttached ) + { + for ( Object metadata : mavenMainArtifact.getMetadataList() ) + { + if ( metadata instanceof ProjectArtifactMetadata ) + { + request.addArtifact( new SubArtifact( + mainArtifact, + "", + "pom" + ).setFile( ( (ProjectArtifactMetadata) metadata ).getFile() ) ); + pomArtifactAttached = true; + } + } + } + } + else if ( !project.getAttachedArtifacts().isEmpty() ) + { + throw new IllegalArgumentException( "The packaging plugin for this project did not assign " + + "a main file to the project but it has attachments. Change packaging to 'pom'." ); + } + else + { + throw new IllegalArgumentException( "The packaging for this project did not assign " + + "a file to the build artifact" ); + } + } + + if ( !pomArtifactAttached ) + { + throw new IllegalArgumentException( "The POM could not be attached" ); + } + + for ( org.apache.maven.artifact.Artifact attached : project.getAttachedArtifacts() ) + { + getLog().debug( "Attaching for install: " + attached.getId() ); + request.addArtifact( RepositoryUtils.toArtifact( attached ) ); + } + + return request; } } diff --git a/src/test/java/org/apache/maven/plugins/install/InstallFileMojoTest.java b/src/test/java/org/apache/maven/plugins/install/InstallFileMojoTest.java index bf040b1..c135d95 100644 --- a/src/test/java/org/apache/maven/plugins/install/InstallFileMojoTest.java +++ b/src/test/java/org/apache/maven/plugins/install/InstallFileMojoTest.java @@ -28,8 +28,8 @@ import org.apache.maven.plugin.testing.AbstractMojoTestCase; import org.apache.maven.project.DefaultProjectBuildingRequest; import org.apache.maven.project.ProjectBuildingRequest; -import org.apache.maven.shared.utils.ReaderFactory; -import org.apache.maven.shared.utils.io.FileUtils; +import org.codehaus.plexus.util.FileUtils; +import org.codehaus.plexus.util.xml.XmlStreamReader; import org.eclipse.aether.DefaultRepositorySystemSession; import org.eclipse.aether.internal.impl.EnhancedLocalRepositoryManagerFactory; import org.eclipse.aether.repository.LocalRepository; @@ -159,7 +159,7 @@ public void testInstallFileWithGeneratePom() File installedPom = new File( getBasedir(), LOCAL_REPO + groupId + "/" + artifactId + "/" + version + "/" + artifactId + "-" + version + "." + "pom" ); - try ( Reader reader = ReaderFactory.newXmlReader( installedPom ) ) { + try ( Reader reader = new XmlStreamReader( installedPom ) ) { Model model = new MavenXpp3Reader().read( reader ); assertEquals( "4.0.0", model.getModelVersion() ); @@ -258,7 +258,7 @@ public void testInstallFile() assertTrue( installedArtifact.exists() ); - assertEquals( 5, FileUtils.getFiles( new File( LOCAL_REPO ), null, null ).size() ); + assertEquals( FileUtils.getFiles( new File( LOCAL_REPO ), null, null ).toString(), 5, FileUtils.getFiles( new File( LOCAL_REPO ), null, null ).size() ); } private void assignValuesForParameter( Object obj ) @@ -294,6 +294,7 @@ repositorySession, new LocalRepository( LOCAL_REPO ) ProjectBuildingRequest buildingRequest = new DefaultProjectBuildingRequest(); buildingRequest.setRepositorySession( repositorySession ); when( session.getProjectBuildingRequest() ).thenReturn( buildingRequest ); + when( session.getRepositorySession() ).thenReturn( repositorySession ); return session; } } diff --git a/src/test/java/org/apache/maven/plugins/install/InstallMojoTest.java b/src/test/java/org/apache/maven/plugins/install/InstallMojoTest.java index 1347e4b..57fe471 100644 --- a/src/test/java/org/apache/maven/plugins/install/InstallMojoTest.java +++ b/src/test/java/org/apache/maven/plugins/install/InstallMojoTest.java @@ -31,7 +31,9 @@ import org.apache.maven.artifact.Artifact; import org.apache.maven.artifact.metadata.ArtifactMetadata; 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.plugin.descriptor.PluginDescriptor; import org.apache.maven.plugin.testing.AbstractMojoTestCase; import org.apache.maven.plugins.install.stubs.AttachedArtifactStub0; @@ -39,9 +41,9 @@ import org.apache.maven.project.DefaultProjectBuildingRequest; import org.apache.maven.project.MavenProject; import org.apache.maven.project.ProjectBuildingRequest; -import org.apache.maven.shared.transfer.repository.RepositoryManager; -import org.apache.maven.shared.utils.io.FileUtils; +import org.codehaus.plexus.util.FileUtils; import org.eclipse.aether.DefaultRepositorySystemSession; +import org.eclipse.aether.artifact.DefaultArtifact; import org.eclipse.aether.internal.impl.EnhancedLocalRepositoryManagerFactory; import org.eclipse.aether.repository.LocalRepository; import org.eclipse.aether.repository.NoLocalRepositoryManagerException; @@ -71,7 +73,7 @@ public void testInstallTestEnvironment() { File testPom = new File( getBasedir(), "target/test-classes/unit/basic-install-test/plugin-config.xml" ); - AbstractInstallMojo mojo = (AbstractInstallMojo) lookupMojo( "install", testPom ); + AbstractMojo mojo = (AbstractMojo) lookupMojo( "install", testPom ); assertNotNull( mojo ); } @@ -81,7 +83,7 @@ public void testBasicInstall() { File testPom = new File( getBasedir(), "target/test-classes/unit/basic-install-test/plugin-config.xml" ); - AbstractInstallMojo mojo = (AbstractInstallMojo) lookupMojo( "install", testPom ); + AbstractMojo mojo = (AbstractMojo) lookupMojo( "install", testPom ); assertNotNull( mojo ); @@ -118,7 +120,7 @@ public void testBasicInstallWithAttachedArtifacts() File testPom = new File( getBasedir(), "target/test-classes/unit/basic-install-test-with-attached-artifacts/" + "plugin-config.xml" ); - AbstractInstallMojo mojo = (AbstractInstallMojo) lookupMojo( "install", testPom ); + AbstractMojo mojo = (AbstractMojo) lookupMojo( "install", testPom ); assertNotNull( mojo ); @@ -159,7 +161,7 @@ public void testUpdateReleaseParamSetToTrue() { File testPom = new File( getBasedir(), "target/test-classes/unit/configured-install-test/plugin-config.xml" ); - AbstractInstallMojo mojo = (AbstractInstallMojo) lookupMojo( "install", testPom ); + AbstractMojo mojo = (AbstractMojo) lookupMojo( "install", testPom ); assertNotNull( mojo ); @@ -190,7 +192,7 @@ public void testInstallIfArtifactFileIsNull() { File testPom = new File( getBasedir(), "target/test-classes/unit/basic-install-test/plugin-config.xml" ); - AbstractInstallMojo mojo = (AbstractInstallMojo) lookupMojo( "install", testPom ); + AbstractMojo mojo = (AbstractMojo) lookupMojo( "install", testPom ); assertNotNull( mojo ); @@ -214,7 +216,7 @@ public void testInstallIfArtifactFileIsNull() fail( "Did not throw mojo execution exception" ); } - catch ( MojoExecutionException e ) + catch ( MojoFailureException e ) { //expected } @@ -228,7 +230,7 @@ public void testInstallIfPackagingIsPom() File testPom = new File( getBasedir(), "target/test-classes/unit/basic-install-test-packaging-pom/" + "plugin-config.xml" ); - AbstractInstallMojo mojo = (AbstractInstallMojo) lookupMojo( "install", testPom ); + AbstractMojo mojo = (AbstractMojo) lookupMojo( "install", testPom ); assertNotNull( mojo ); @@ -263,7 +265,7 @@ public void testBasicInstallAndCreate() { File testPom = new File( getBasedir(), "target/test-classes/unit/basic-install-checksum/plugin-config.xml" ); - AbstractInstallMojo mojo = (AbstractInstallMojo) lookupMojo( "install", testPom ); + AbstractMojo mojo = (AbstractMojo) lookupMojo( "install", testPom ); assertNotNull( mojo ); @@ -294,12 +296,7 @@ public void testBasicInstallAndCreate() } } - RepositoryManager repoManager = (RepositoryManager) getVariableValueFromObject( mojo, "repositoryManager" ); - - ProjectBuildingRequest pbr = mavenSession.getProjectBuildingRequest(); - - File pom = new File( repoManager.getLocalRepositoryBasedir( pbr ), - repoManager.getPathForLocalMetadata( pbr, metadata ) ); + File pom = new File( new File( LOCAL_REPO ), mavenSession.getRepositorySession().getLocalRepositoryManager().getPathForLocalArtifact( new DefaultArtifact( artifact.getGroupId(), artifact.getArtifactId(), "pom", artifact.getVersion() ) ) ); assertTrue( pom.exists() ); @@ -335,13 +332,12 @@ public void testSkip() setVariableValueToObject( mojo, "pluginDescriptor", new PluginDescriptor() ); setVariableValueToObject( mojo, "reactorProjects", Collections.singletonList( project ) ); setVariableValueToObject( mojo, "session", createMavenSession() ); + setVariableValueToObject( mojo, "skip", Boolean.TRUE ); artifact = (InstallArtifactStub) project.getArtifact(); artifact.setFile( file ); - mojo.setSkip( true ); - mojo.execute(); String groupId = dotToSlashReplacer( artifact.getGroupId() ); @@ -374,6 +370,7 @@ repositorySession, new LocalRepository( LOCAL_REPO ) ProjectBuildingRequest buildingRequest = new DefaultProjectBuildingRequest(); buildingRequest.setRepositorySession( repositorySession ); when( session.getProjectBuildingRequest() ).thenReturn( buildingRequest ); + when( session.getRepositorySession() ).thenReturn( repositorySession ); when( session.getPluginContext(any(PluginDescriptor.class), any(MavenProject.class))) .thenReturn( new ConcurrentHashMap() ); return session;