Return-Path: Delivered-To: apmail-maven-commits-archive@www.apache.org Received: (qmail 17540 invoked from network); 28 Oct 2006 19:39:09 -0000 Received: from hermes.apache.org (HELO mail.apache.org) (140.211.11.2) by minotaur.apache.org with SMTP; 28 Oct 2006 19:39:09 -0000 Received: (qmail 21016 invoked by uid 500); 28 Oct 2006 19:39:20 -0000 Delivered-To: apmail-maven-commits-archive@maven.apache.org Received: (qmail 20776 invoked by uid 500); 28 Oct 2006 19:39:20 -0000 Mailing-List: contact commits-help@maven.apache.org; run by ezmlm Precedence: bulk List-Help: List-Unsubscribe: List-Post: List-Id: Reply-To: dev@maven.apache.org Delivered-To: mailing list commits@maven.apache.org Received: (qmail 20763 invoked by uid 99); 28 Oct 2006 19:39:19 -0000 Received: from herse.apache.org (HELO herse.apache.org) (140.211.11.133) by apache.org (qpsmtpd/0.29) with ESMTP; Sat, 28 Oct 2006 12:39:19 -0700 X-ASF-Spam-Status: No, hits=0.6 required=10.0 tests=NO_REAL_NAME X-Spam-Check-By: apache.org Received: from [140.211.11.3] (HELO eris.apache.org) (140.211.11.3) by apache.org (qpsmtpd/0.29) with ESMTP; Sat, 28 Oct 2006 12:39:06 -0700 Received: by eris.apache.org (Postfix, from userid 65534) id F2ECC1A9846; Sat, 28 Oct 2006 12:38:44 -0700 (PDT) Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit Subject: svn commit: r468729 - /maven/plugins/trunk/maven-eclipse-plugin/src/main/java/org/apache/maven/plugin/eclipse/MakeArtifactsMojo.java Date: Sat, 28 Oct 2006 19:38:44 -0000 To: commits@maven.apache.org From: fgiust@apache.org X-Mailer: svnmailer-1.1.0 Message-Id: <20061028193844.F2ECC1A9846@eris.apache.org> X-Virus-Checked: Checked by ClamAV on apache.org Author: fgiust Date: Sat Oct 28 12:38:44 2006 New Revision: 468729 URL: http://svn.apache.org/viewvc?view=rev&rev=468729 Log: added the ability to directly deploy generated artifacts to a remote repository (plus handling of missing version number in osgi dependencies) Modified: maven/plugins/trunk/maven-eclipse-plugin/src/main/java/org/apache/maven/plugin/eclipse/MakeArtifactsMojo.java Modified: maven/plugins/trunk/maven-eclipse-plugin/src/main/java/org/apache/maven/plugin/eclipse/MakeArtifactsMojo.java URL: http://svn.apache.org/viewvc/maven/plugins/trunk/maven-eclipse-plugin/src/main/java/org/apache/maven/plugin/eclipse/MakeArtifactsMojo.java?view=diff&rev=468729&r1=468728&r2=468729 ============================================================================== --- maven/plugins/trunk/maven-eclipse-plugin/src/main/java/org/apache/maven/plugin/eclipse/MakeArtifactsMojo.java (original) +++ maven/plugins/trunk/maven-eclipse-plugin/src/main/java/org/apache/maven/plugin/eclipse/MakeArtifactsMojo.java Sat Oct 28 12:38:44 2006 @@ -27,25 +27,37 @@ import java.util.jar.Attributes; import java.util.jar.JarFile; import java.util.jar.Manifest; +import java.util.regex.Matcher; +import java.util.regex.Pattern; import java.util.zip.ZipEntry; import org.apache.maven.artifact.Artifact; +import org.apache.maven.artifact.deployer.ArtifactDeployer; +import org.apache.maven.artifact.deployer.ArtifactDeploymentException; import org.apache.maven.artifact.factory.ArtifactFactory; import org.apache.maven.artifact.installer.ArtifactInstallationException; import org.apache.maven.artifact.installer.ArtifactInstaller; import org.apache.maven.artifact.metadata.ArtifactMetadata; import org.apache.maven.artifact.repository.ArtifactRepository; +import org.apache.maven.artifact.repository.DefaultArtifactRepository; +import org.apache.maven.artifact.repository.layout.ArtifactRepositoryLayout; import org.apache.maven.model.Dependency; +import org.apache.maven.model.License; import org.apache.maven.model.Model; -import org.apache.maven.model.Parent; 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.project.artifact.ProjectArtifactMetadata; +import org.codehaus.plexus.PlexusConstants; +import org.codehaus.plexus.PlexusContainer; import org.codehaus.plexus.archiver.ArchiverException; import org.codehaus.plexus.archiver.jar.JarArchiver; +import org.codehaus.plexus.component.repository.exception.ComponentLookupException; import org.codehaus.plexus.components.interactivity.InputHandler; +import org.codehaus.plexus.context.Context; +import org.codehaus.plexus.context.ContextException; +import org.codehaus.plexus.personality.plexus.lifecycle.phase.Contextualizable; import org.codehaus.plexus.util.IOUtil; import org.codehaus.plexus.util.StringUtils; @@ -61,9 +73,20 @@ */ public class MakeArtifactsMojo extends AbstractMojo + implements Contextualizable { /** + * A pattern te deployTo param should match. + */ + private static final Pattern DEPLOYTO_PATTERN = Pattern.compile( "(.+)::(.+)::(.+)" ); + + /** + * Plexus container, needed to manually lookup components for deploy of artifacts. + */ + private PlexusContainer container; + + /** * Local maven repository. * * @parameter expression="${localRepository}" @@ -85,6 +108,12 @@ protected ArtifactInstaller installer; /** + * ArtifactDeployer component. + * @component + */ + private ArtifactDeployer deployer; + + /** * Eclipse installation dir. If not set, a value for this parameter will be asked on the command line. * * @parameter expression="${eclipseDir}" @@ -109,6 +138,15 @@ private boolean stripQualifier; /** + * Specifies a remote repository to which generated artifacts should be deployed to. If this property is specified, + * artifacts are also deployed to the remote repo. + * The format for this parameter is id::layout::url + * + * @parameter expression="${deployTo}" + */ + private String deployTo; + + /** * @see org.apache.maven.plugin.Mojo#execute() */ public void execute() @@ -142,195 +180,284 @@ throw new MojoFailureException( "Plugin directory " + pluginDir.getAbsolutePath() + " doesn't exists" ); } - File[] files = pluginDir.listFiles( ); + File[] files = pluginDir.listFiles(); + + ArtifactRepository remoteRepo = resolveRemoteRepo(); + + if ( remoteRepo != null ) + { + getLog().info( "Will deploy artifacts to remote repository " + deployTo ); + } for ( int j = 0; j < files.length; j++ ) { + processSingleFile( files[j], remoteRepo ); - File file = files[j]; + } - getLog().info( "Processing file " + file.getAbsolutePath() ); + } - Manifest manifest = null; - Properties pluginProperties = new Properties(); - boolean wasUnpacked = false; + /** + * Process a single plugin jar/dir found in the target dir. + * @param file plugin jar or dir + * @param remoteRepo remote repository (if set) + * @throws MojoExecutionException if anything bad happens while parsing files + */ + private void processSingleFile( File file, ArtifactRepository remoteRepo ) + throws MojoExecutionException + { - /* package directories in a temp jar */ - if ( file.isDirectory() ) - { - try - { - File manifestFile = new File( file, "META-INF/MANIFEST.MF" ); - if ( !manifestFile.exists() ) - { - getLog().warn( - "Plugin in folder " + file.getAbsolutePath() - + " does not have a manifest; skipping.." ); - continue; - } - - File tmpJar = File.createTempFile( "mvn-eclipse", null ); - tmpJar.deleteOnExit(); - - JarArchiver jarArchiver = new JarArchiver(); - - jarArchiver.setDestFile( tmpJar ); - jarArchiver.addDirectory( file ); - jarArchiver.setManifest( manifestFile ); - jarArchiver.createArchive(); + getLog().info( "Processing file " + file.getAbsolutePath() ); - file = tmpJar; - wasUnpacked = true; - } - catch ( ArchiverException e ) - { - throw new MojoExecutionException( "Unable to jar plugin in folder " + file.getAbsolutePath(), e ); - } - catch ( IOException e ) - { - throw new MojoExecutionException( "Unable to jar plugin in folder " + file.getAbsolutePath(), e ); - } - } + Manifest manifest = null; + Properties pluginProperties = new Properties(); + boolean wasUnpacked = false; - if ( file.getName().endsWith( ".jar" ) || wasUnpacked ) + // package directories in a temp jar + if ( file.isDirectory() ) + { + try { - try - { - JarFile jar = new JarFile( file ); - manifest = jar.getManifest(); - pluginProperties = loadPluginProperties( jar ); - } - catch ( IOException e ) + File manifestFile = new File( file, "META-INF/MANIFEST.MF" ); + if ( !manifestFile.exists() ) { - throw new MojoFailureException( "Unable to read manifest or plugin properties for " - + file.getAbsolutePath() ); + getLog().warn( + "Plugin in folder " + file.getAbsolutePath() + + " does not have a manifest; skipping.." ); + return; } + + File tmpJar = File.createTempFile( "mvn-eclipse", null ); + tmpJar.deleteOnExit(); + + JarArchiver jarArchiver = new JarArchiver(); + + jarArchiver.setDestFile( tmpJar ); + jarArchiver.addDirectory( file ); + jarArchiver.setManifest( manifestFile ); + jarArchiver.createArchive(); + + file = tmpJar; + wasUnpacked = true; } - else + catch ( ArchiverException e ) { - getLog().debug( "Ignoring file " + file.getAbsolutePath() ); - continue; + throw new MojoExecutionException( "Unable to jar plugin in folder " + file.getAbsolutePath(), e ); } + catch ( IOException e ) + { + throw new MojoExecutionException( "Unable to jar plugin in folder " + file.getAbsolutePath(), e ); + } + } - - if ( manifest == null ) + if ( file.getName().endsWith( ".jar" ) || wasUnpacked ) + { + try { - getLog().warn( "Jar " + file.getAbsolutePath() + " does not have a manifest; skipping.." ); - continue; + JarFile jar = new JarFile( file ); + manifest = jar.getManifest(); + pluginProperties = loadPluginProperties( jar ); } + catch ( IOException e ) + { + throw new MojoExecutionException( "Unable to read manifest or plugin properties for " + + file.getAbsolutePath() ); + } + } + else + { + getLog().debug( "Ignoring file " + file.getAbsolutePath() ); + return; + } - Attributes manifestEntries = manifest.getMainAttributes(); + if ( manifest == null ) + { + getLog().warn( "Jar " + file.getAbsolutePath() + " does not have a manifest; skipping.." ); + return; + } - String artifactId = manifestEntries.getValue( "Bundle-SymbolicName" ); + Attributes manifestEntries = manifest.getMainAttributes(); - int separator = artifactId.indexOf( ";" ); - if ( separator > 0 ) - { - artifactId = StringUtils.substring( artifactId, 0, separator ); - } - artifactId = StringUtils.trim( artifactId ); + String artifactId = manifestEntries.getValue( "Bundle-SymbolicName" ); - String version = manifestEntries.getValue( "Bundle-Version" ); + int separator = artifactId.indexOf( ";" ); + if ( separator > 0 ) + { + artifactId = StringUtils.substring( artifactId, 0, separator ); + } + artifactId = StringUtils.trim( artifactId ); - if ( artifactId == null || version == null ) - { - getLog().error( "Unable to read artifact/version from manifest, skipping..." ); - continue; - } + String version = manifestEntries.getValue( "Bundle-Version" ); - if ( stripQualifier && StringUtils.countMatches( version, "." ) > 2 ) - { - version = StringUtils.substring( version, 0, version.lastIndexOf( "." ) ); - } + if ( artifactId == null || version == null ) + { + getLog().error( "Unable to read artifact/version from manifest, skipping..." ); + return; + } - String name = manifestEntries.getValue( "Bundle-Name" ); + if ( stripQualifier && StringUtils.countMatches( version, "." ) > 2 ) + { + version = StringUtils.substring( version, 0, version.lastIndexOf( "." ) ); + } - // if Bundle-Name is %pluginName fetch the full name from plugin.properties - if ( name != null && name.startsWith( "%" ) ) + String name = manifestEntries.getValue( "Bundle-Name" ); + + // if Bundle-Name is %pluginName fetch the full name from plugin.properties + if ( name != null && name.startsWith( "%" ) ) + { + String nameFromProperties = pluginProperties.getProperty( name.substring( 1 ) ); + if ( nameFromProperties != null ) { - String nameFromProperties = pluginProperties.getProperty( name.substring( 1 ) ); - if ( nameFromProperties != null ) - { - name = nameFromProperties; - } + name = nameFromProperties; } + } - String requireBundle = manifestEntries.getValue( "Require-Bundle" ); - Dependency[] deps = parseDependencies( requireBundle ); + String requireBundle = manifestEntries.getValue( "Require-Bundle" ); + Dependency[] deps = parseDependencies( requireBundle ); - String groupId = null; - groupId = createGroupId( artifactId ); + String groupId = null; + groupId = createGroupId( artifactId ); - Model model = new Model(); - model.setModelVersion( "4.0.0" ); - model.setGroupId( groupId ); - model.setArtifactId( artifactId ); - model.setName( name ); - model.setVersion( version ); + Model model = new Model(); + model.setModelVersion( "4.0.0" ); + model.setGroupId( groupId ); + model.setArtifactId( artifactId ); + model.setName( name ); + model.setVersion( version ); - /* set the pom property to install unpacked if it was unpacked */ - if ( wasUnpacked ) - { - Properties properties = new Properties(); - properties.setProperty( InstallPluginsMojo.PROP_UNPACK_PLUGIN, Boolean.TRUE.toString() ); - model.setProperties( properties ); - } + /* set the pom property to install unpacked if it was unpacked */ + if ( wasUnpacked ) + { + Properties properties = new Properties(); + properties.setProperty( InstallPluginsMojo.PROP_UNPACK_PLUGIN, Boolean.TRUE.toString() ); + model.setProperties( properties ); + } + + if ( groupId.startsWith( "org.eclipse" ) ) + { + // why do we need a parent? + + // Parent parent = new Parent(); + // parent.setGroupId( "org.eclipse" ); + // parent.setArtifactId( "eclipse" ); + // parent.setVersion( "1" ); + // model.setParent( parent ); + + // infer license for know projects, everything at eclipse is licensed under EPL + // maybe too simplicistic, but better than nothing + License license = new License(); + license.setName( "Eclipse Public License - v 1.0" ); + license.setUrl( "http://www.eclipse.org/org/documents/epl-v10.html" ); + model.addLicense( license ); + } - if ( groupId.startsWith( "org.eclipse" ) ) + if ( deps.length > 0 ) + { + for ( int k = 0; k < deps.length; k++ ) { - Parent parent = new Parent(); - parent.setGroupId( "org.eclipse" ); - parent.setArtifactId( "eclipse" ); - parent.setVersion( "1" ); - model.setParent( parent ); + model.getDependencies().add( deps[k] ); } - if ( deps.length > 0 ) - { - for ( int k = 0; k < deps.length; k++ ) - { - model.getDependencies().add( deps[k] ); - } + } - } + FileWriter fw = null; + ArtifactMetadata metadata = null; + File pomFile = null; + Artifact pomArtifact = artifactFactory.createArtifact( groupId, artifactId, version, null, "pom" ); + Artifact artifact = artifactFactory.createArtifact( groupId, artifactId, version, null, "jar" ); + try + { + pomFile = File.createTempFile( "pom", ".xml" ); + pomFile.deleteOnExit(); - FileWriter fw = null; - ArtifactMetadata metadata = null; - File pomFile = null; - Artifact pomArtifact = artifactFactory.createArtifact( groupId, artifactId, version, null, "pom" ); - Artifact artifact = artifactFactory.createArtifact( groupId, artifactId, version, null, "jar" ); - try - { - pomFile = File.createTempFile( "pom", ".xml" ); - pomFile.deleteOnExit(); + fw = new FileWriter( pomFile ); + pomFile.deleteOnExit(); + new MavenXpp3Writer().write( fw, model ); + metadata = new ProjectArtifactMetadata( pomArtifact, pomFile ); + pomArtifact.addMetadata( metadata ); + } + catch ( IOException e ) + { + throw new MojoExecutionException( "Error writing temporary pom file: " + e.getMessage(), e ); + } + finally + { + IOUtil.close( fw ); + } - fw = new FileWriter( pomFile ); - pomFile.deleteOnExit(); - new MavenXpp3Writer().write( fw, model ); - metadata = new ProjectArtifactMetadata( pomArtifact, pomFile ); - pomArtifact.addMetadata( metadata ); - } - catch ( IOException e ) + if ( remoteRepo != null ) + { + + try { - throw new MojoExecutionException( "Error writing temporary pom file: " + e.getMessage(), e ); + deployer.deploy( pomFile, pomArtifact, remoteRepo, localRepository ); + deployer.deploy( pomFile, artifact, remoteRepo, localRepository ); } - finally + catch ( ArtifactDeploymentException e ) { - IOUtil.close( fw ); + throw new MojoExecutionException( "Unable to deploy artifact to repository.", e ); } + } + try + { + installer.install( pomFile, pomArtifact, localRepository ); + installer.install( file, artifact, localRepository ); + } + catch ( ArtifactInstallationException e ) + { + throw new MojoExecutionException( "Unable to install artifact to repository.", e ); + } - try + } + + /** + * Resolves the deploydeployTo parameter to an ArtifactRepository instance (if set). + * + * @throws MojoFailureException + * @throws MojoExecutionException + * @return ArtifactRepository instance of null if deployTo is not set. + */ + private ArtifactRepository resolveRemoteRepo() + throws MojoFailureException, MojoExecutionException + { + if ( deployTo != null ) + { + Matcher matcher = DEPLOYTO_PATTERN.matcher( deployTo ); + + if ( !matcher.matches() ) { - installer.install( pomFile, pomArtifact, localRepository ); - installer.install( file, artifact, localRepository ); + throw new MojoFailureException( deployTo, "Invalid syntax for repository.", + "Invalid syntax for remote repository. Use \"id::layout::url\"." ); } - catch ( ArtifactInstallationException e ) + else { - throw new MojoFailureException( "Unable to install artifact to local repository." ); - } + String id = matcher.group( 1 ).trim(); + String layout = matcher.group( 2 ).trim(); + String url = matcher.group( 3 ).trim(); + + ArtifactRepositoryLayout repoLayout; + try + { + repoLayout = (ArtifactRepositoryLayout) container.lookup( ArtifactRepositoryLayout.ROLE, layout ); + } + catch ( ComponentLookupException e ) + { + throw new MojoExecutionException( "Cannot find repository layout: " + layout, e ); + } + return new DefaultArtifactRepository( id, url, repoLayout ); + } } + return null; + } + /** + * {@inheritDoc} + */ + public void contextualize( Context context ) + throws ContextException + { + this.container = (PlexusContainer) context.get( PlexusConstants.PLEXUS_KEY ); } /** @@ -404,8 +531,8 @@ if ( version == null ) { - getLog().warn( "Missing version for artifact " + artifactId + ", skipping" ); - continue; + getLog().info( "Missing version for artifact " + artifactId + ", assuming any version > 0" ); + version = "[0,)"; } Dependency dep = new Dependency(); @@ -421,6 +548,12 @@ } + /** + * Loads the plugin.properties file from a jar, usually needed in order to resolve the artifact name. + * @param file jar file + * @return loaded Properties (or an empty properties if no plugin.properties is found) + * @throws IOException for exceptions while reading the jar file + */ private Properties loadPluginProperties( JarFile file ) throws IOException {