diff --git a/maven-plugins/maven-assemble-plugin/pom.xml b/maven-plugins/maven-assemble-plugin/pom.xml index 175d32fd5e..c17f8eb5a4 100644 --- a/maven-plugins/maven-assemble-plugin/pom.xml +++ b/maven-plugins/maven-assemble-plugin/pom.xml @@ -10,6 +10,11 @@ Maven Assemble Plugin 1.0-SNAPSHOT + + org.apache.maven + maven-artifact + 2.0-SNAPSHOT + plexus plexus-archiver diff --git a/maven-plugins/maven-assemble-plugin/src/main/java/org/apache/maven/plugin/assemble/AssembleMojo.java b/maven-plugins/maven-assemble-plugin/src/main/java/org/apache/maven/plugin/assemble/AssembleMojo.java index 27683978e2..e9ddca07f2 100755 --- a/maven-plugins/maven-assemble-plugin/src/main/java/org/apache/maven/plugin/assemble/AssembleMojo.java +++ b/maven-plugins/maven-assemble-plugin/src/main/java/org/apache/maven/plugin/assemble/AssembleMojo.java @@ -16,12 +16,17 @@ * limitations under the License. */ +import org.apache.maven.artifact.Artifact; +import org.apache.maven.artifact.resolver.filter.ArtifactFilter; +import org.apache.maven.artifact.resolver.filter.ScopeArtifactFilter; import org.apache.maven.plugin.AbstractPlugin; import org.apache.maven.plugin.PluginExecutionException; import org.apache.maven.plugins.assemble.model.Assembly; +import org.apache.maven.plugins.assemble.model.DependencySet; import org.apache.maven.plugins.assemble.model.FileSet; import org.apache.maven.plugins.assemble.model.io.xpp3.AssemblyXpp3Reader; import org.codehaus.plexus.archiver.Archiver; +import org.codehaus.plexus.archiver.ArchiverException; import org.codehaus.plexus.archiver.jar.JarArchiver; import org.codehaus.plexus.archiver.tar.TarArchiver; import org.codehaus.plexus.archiver.zip.ZipArchiver; @@ -32,18 +37,23 @@ import java.io.InputStream; import java.io.InputStreamReader; import java.io.Reader; +import java.util.ArrayList; import java.util.Iterator; +import java.util.List; +import java.util.Set; /** * @author Brett Porter * @version $Id$ * @goal assemble + * @requiresDependencyResolution test * @description assemble an application bundle or distribution * @parameter name="basedir" type="String" required="true" validator="" expression="#basedir" description="" * @parameter name="outputDirectory" type="java.io.File" required="true" validator="" expression="#project.build.directory" description="" * @parameter name="descriptor" type="java.io.File" required="false" validator="" expression="#maven.assemble.descriptor" description="" * @parameter name="finalName" type="String" required="true" validator="" expression="#project.build.finalName" description="" * @parameter name="descriptorId" type="String" required="false" validator="" expression="#maven.assemble.descriptorId" description="" + * @parameter name="dependencies" type="java.util.Set" required="false" validator="" expression="#project.artifacts" description="" */ public class AssembleMojo extends AbstractPlugin @@ -63,6 +73,8 @@ public class AssembleMojo private String finalName; + private Set dependencies; + public void execute() throws PluginExecutionException { @@ -108,7 +120,7 @@ else if ( descriptorId != null ) Assembly assembly = reader.read( r ); // TODO: include dependencies marked for distribution under certain formats - // TODO: how, might we plugin this into an installer, such as NSIS? + // TODO: how, might we plug this into an installer, such as NSIS? // TODO: allow file mode specifications? String fullName = finalName + "-" + assembly.getId(); @@ -120,88 +132,10 @@ else if ( descriptorId != null ) String filename = fullName + "." + format; // TODO: use component roles? Can we do that in a mojo? - Archiver archiver; - if ( format.startsWith( "tar" ) ) - { - TarArchiver tarArchiver = new TarArchiver(); - archiver = tarArchiver; - int index = format.indexOf( '.' ); - if ( index >= 0 ) - { - // TODO: this needs a cleanup in plexus archiver - use a real typesafe enum - TarArchiver.TarCompressionMethod tarCompressionMethod = new TarArchiver.TarCompressionMethod(); - // TODO: this should accept gz and bz2 as well so we can skip over the switch - String compression = format.substring( index + 1 ); - if ( compression.equals( "gz" ) ) - { - tarCompressionMethod.setValue( "gzip" ); - } - else if ( compression.equals( "bz2" ) ) - { - tarCompressionMethod.setValue( "bzip2" ); - } - else - { - // TODO: better handling - throw new IllegalArgumentException( "Unknown compression format: " + compression ); - } - tarArchiver.setCompression( tarCompressionMethod ); - } - } - else if ( format.startsWith( "zip" ) ) - { - archiver = new ZipArchiver(); - } - else if ( format.startsWith( "jar" ) ) - { - // TODO: use MavenArchiver for manifest? - archiver = new JarArchiver(); - } - else - { - // TODO: better handling - throw new IllegalArgumentException( "Unknown format: " + format ); - } + Archiver archiver = createArchiver( format ); - for ( Iterator j = assembly.getFilesets().iterator(); j.hasNext(); ) - { - FileSet fileset = (FileSet) j.next(); - String directory = fileset.getDirectory(); - String output = fileset.getOutputDirectory(); - if ( directory == null ) - { - directory = basedir; - if ( output == null ) - { - output = "/"; - } - } - else - { - if ( output == null ) - { - output = directory; - } - } - if ( !output.endsWith( "/" ) && !output.endsWith( "\\" ) ) - { - // TODO: shouldn't archiver do this? - output += '/'; - } - - String[] includes = (String[]) fileset.getIncludes().toArray( EMPTY_STRING_ARRAY ); - if ( includes.length == 0 ) - { - includes = null; - } - String[] excludes = null; - if ( !fileset.getExcludes().isEmpty() ) - { - excludes = (String[]) fileset.getExcludes().toArray( EMPTY_STRING_ARRAY ); - } - // TODO: default excludes? - archiver.addDirectory( new File( directory ), output, includes, excludes ); - } + processFileSets( archiver, assembly.getFileSets() ); + processDependencySets( archiver, assembly.getDependencySets() ); archiver.setDestFile( new File( outputDirectory, filename ) ); archiver.createArchive(); @@ -212,4 +146,246 @@ else if ( format.startsWith( "jar" ) ) IOUtil.close( r ); } } + + private void processDependencySets( Archiver archiver, List dependencySets ) + throws ArchiverException + { + for ( Iterator i = dependencySets.iterator(); i.hasNext(); ) + { + DependencySet depedencySet = (DependencySet) i.next(); + String output = depedencySet.getOutputDirectory(); + output = getOutputDirectory( output ); + + AndArtifactFilter filter = new AndArtifactFilter(); + filter.add( new ScopeArtifactFilter( depedencySet.getScope() ) ); + if ( !depedencySet.getIncludes().isEmpty() ) + { + filter.add( new IncludesArtifactFilter( depedencySet.getIncludes() ) ); + } + if ( !depedencySet.getExcludes().isEmpty() ) + { + filter.add( new ExcludesArtifactFilter( depedencySet.getExcludes() ) ); + } + + // TODO: includes and excludes + for ( Iterator j = dependencies.iterator(); j.hasNext(); ) + { + Artifact artifact = (Artifact) j.next(); + + if ( filter.include( artifact ) ) + { + archiver.addFile( artifact.getFile(), output + artifact.getFile().getName() ); + } + } + } + } + + private String getOutputDirectory( String output ) + { + if ( output == null ) + { + output = ""; + } + if ( !output.endsWith( "/" ) && !output.endsWith( "\\" ) ) + { + // TODO: shouldn't archiver do this? + output += '/'; + } + + if ( output.startsWith( "/" ) ) + { + output = finalName + output; + } + else + { + output = finalName + "/" + output; + } + return output; + } + + private Archiver createArchiver( String format ) + throws ArchiverException + { + Archiver archiver; + if ( format.startsWith( "tar" ) ) + { + TarArchiver tarArchiver = new TarArchiver(); + archiver = tarArchiver; + int index = format.indexOf( '.' ); + if ( index >= 0 ) + { + // TODO: this needs a cleanup in plexus archiver - use a real typesafe enum + TarArchiver.TarCompressionMethod tarCompressionMethod = new TarArchiver.TarCompressionMethod(); + // TODO: this should accept gz and bz2 as well so we can skip over the switch + String compression = format.substring( index + 1 ); + if ( compression.equals( "gz" ) ) + { + tarCompressionMethod.setValue( "gzip" ); + } + else if ( compression.equals( "bz2" ) ) + { + tarCompressionMethod.setValue( "bzip2" ); + } + else + { + // TODO: better handling + throw new IllegalArgumentException( "Unknown compression format: " + compression ); + } + tarArchiver.setCompression( tarCompressionMethod ); + } + } + else if ( format.startsWith( "zip" ) ) + { + archiver = new ZipArchiver(); + } + else if ( format.startsWith( "jar" ) ) + { + // TODO: use MavenArchiver for manifest? + archiver = new JarArchiver(); + } + else + { + // TODO: better handling + throw new IllegalArgumentException( "Unknown format: " + format ); + } + return archiver; + } + + private void processFileSets( Archiver archiver, java.util.List fileSets ) + throws ArchiverException + { + for ( Iterator i = fileSets.iterator(); i.hasNext(); ) + { + FileSet fileSet = (FileSet) i.next(); + String directory = fileSet.getDirectory(); + String output = fileSet.getOutputDirectory(); + if ( directory == null ) + { + directory = basedir; + if ( output == null ) + { + output = ""; + } + } + else + { + if ( output == null ) + { + output = directory; + } + } + output = getOutputDirectory( output ); + + String[] includes = (String[]) fileSet.getIncludes().toArray( EMPTY_STRING_ARRAY ); + if ( includes.length == 0 ) + { + includes = null; + } + + List excludesList = fileSet.getExcludes(); + excludesList.addAll( getDefaultExcludes() ); + String[] excludes = (String[]) excludesList.toArray( EMPTY_STRING_ARRAY ); + + // TODO: default excludes should be in the archiver? + archiver.addDirectory( new File( directory ), output, includes, excludes ); + } + } + + public List getDefaultExcludes() + { + List defaultExcludes = new ArrayList(); + defaultExcludes.add( "**/*~" ); + defaultExcludes.add( "**/#*#" ); + defaultExcludes.add( "**/.#*" ); + defaultExcludes.add( "**/%*%" ); + defaultExcludes.add( "**/._*" ); + + // CVS + defaultExcludes.add( "**/CVS" ); + defaultExcludes.add( "**/CVS/**" ); + defaultExcludes.add( "**/.cvsignore" ); + + // SCCS + defaultExcludes.add( "**/SCCS" ); + defaultExcludes.add( "**/SCCS/**" ); + + // Visual SourceSafe + defaultExcludes.add( "**/vssver.scc" ); + + // Subversion + defaultExcludes.add( "**/.svn" ); + defaultExcludes.add( "**/.svn/**" ); + + // Mac + defaultExcludes.add( "**/.DS_Store" ); + + return defaultExcludes; + } + + // TODO: move to maven-artifact - generally useful + private static class AndArtifactFilter + implements ArtifactFilter + { + private final List filters = new ArrayList(); + + public boolean include( Artifact artifact ) + { + boolean include = true; + for ( Iterator i = filters.iterator(); i.hasNext() && include; ) + { + ArtifactFilter filter = (ArtifactFilter) i.next(); + if ( !filter.include( artifact ) ) + { + include = false; + } + } + return include; + } + + public void add( ArtifactFilter artifactFilter ) + { + filters.add( artifactFilter ); + } + } + + private static class IncludesArtifactFilter + implements ArtifactFilter + { + private final List patterns; + + public IncludesArtifactFilter( List patterns ) + { + this.patterns = patterns; + } + + public boolean include( Artifact artifact ) + { + String id = artifact.getGroupId() + ":" + artifact.getArtifactId(); + + boolean matched = false; + for ( Iterator i = patterns.iterator(); i.hasNext() & !matched; ) + { + // TODO: what about wildcards? Just specifying groups? versions? + if ( id.equals( i.next() ) ) + { + matched = true; + } + } + return matched; + } + } + + private static class ExcludesArtifactFilter + extends IncludesArtifactFilter + { + public ExcludesArtifactFilter( List patterns ) + { + super( patterns ); + } + + public boolean include( Artifact artifact ) + { + return !super.include( artifact ); + } + } } diff --git a/maven-plugins/maven-assemble-plugin/src/main/mdo/descriptor.mdo b/maven-plugins/maven-assemble-plugin/src/main/mdo/descriptor.mdo index be911143c2..01ec99da69 100644 --- a/maven-plugins/maven-assemble-plugin/src/main/mdo/descriptor.mdo +++ b/maven-plugins/maven-assemble-plugin/src/main/mdo/descriptor.mdo @@ -30,14 +30,21 @@ - filesets + fileSets 1.0.0 - true FileSet * + + dependencySets + 1.0.0 + + DependencySet + * + + @@ -73,6 +80,40 @@ + + DependencySet + 1.0.0 + + + outputDirectory + 1.0.0 + String + + + scope + 1.0.0 + String + runtime + true + + + includes + 1.0.0 + + String + * + + + + excludes + 1.0.0 + + String + * + + + + diff --git a/maven-plugins/maven-assemble-plugin/src/main/resources/assemblies/bin.xml b/maven-plugins/maven-assemble-plugin/src/main/resources/assemblies/bin.xml index 1a3e7ddeff..e2650b4fe1 100644 --- a/maven-plugins/maven-assemble-plugin/src/main/resources/assemblies/bin.xml +++ b/maven-plugins/maven-assemble-plugin/src/main/resources/assemblies/bin.xml @@ -5,22 +5,22 @@ tar.bz2 zip - - + + README* LICENSE* NOTICE* - + - + target - / + *.jar - - + + diff --git a/maven-plugins/maven-assemble-plugin/src/main/resources/assemblies/src.xml b/maven-plugins/maven-assemble-plugin/src/main/resources/assemblies/src.xml index 9f75f77ecf..ee1a0d62f0 100644 --- a/maven-plugins/maven-assemble-plugin/src/main/resources/assemblies/src.xml +++ b/maven-plugins/maven-assemble-plugin/src/main/resources/assemblies/src.xml @@ -5,18 +5,18 @@ tar.bz2 zip - - + + README* LICENSE* NOTICE* pom.xml - - + + src - - + +