View Javadoc
1   package org.apache.maven.plugins.repository;
2   
3   /*
4    * Licensed to the Apache Software Foundation (ASF) under one
5    * or more contributor license agreements.  See the NOTICE file
6    * distributed with this work for additional information
7    * regarding copyright ownership.  The ASF licenses this file
8    * to you under the Apache License, Version 2.0 (the
9    * "License"); you may not use this file except in compliance
10   * with the License.  You may obtain a copy of the License at
11   *
12   *   http://www.apache.org/licenses/LICENSE-2.0
13   *
14   * Unless required by applicable law or agreed to in writing,
15   * software distributed under the License is distributed on an
16   * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
17   * KIND, either express or implied.  See the License for the
18   * specific language governing permissions and limitations
19   * under the License.
20   */
21  
22  import org.apache.maven.plugin.AbstractMojo;
23  import org.apache.maven.plugin.MojoExecutionException;
24  import org.apache.maven.plugins.annotations.Component;
25  import org.apache.maven.plugins.annotations.Execute;
26  import org.apache.maven.plugins.annotations.LifecyclePhase;
27  import org.apache.maven.plugins.annotations.Mojo;
28  import org.apache.maven.plugins.annotations.Parameter;
29  import org.apache.maven.project.MavenProject;
30  import org.apache.maven.settings.Settings;
31  import org.codehaus.plexus.archiver.Archiver;
32  import org.codehaus.plexus.archiver.jar.JarArchiver;
33  import org.codehaus.plexus.components.interactivity.InputHandler;
34  import org.codehaus.plexus.util.StringUtils;
35  
36  import java.io.File;
37  import java.io.IOException;
38  import java.util.List;
39  
40  /**
41   * Goal which creates an upload bundle for a project built with Maven.
42   *
43   * @since 2.0
44   */
45  @Mojo( name = "bundle-create" )
46  @Execute( phase = LifecyclePhase.PACKAGE )
47  public class BundleCreateMojo
48      extends AbstractMojo
49  {
50      public static final String POM = "pom.xml";
51  
52      /**
53       * Output directory.
54       */
55      @Parameter( defaultValue = "${project.build.directory}", readonly = true )
56      private File outputDirectory;
57  
58      /**
59       * The current Maven project.
60       */
61      @Parameter( defaultValue = "${project}", readonly = true, required = true )
62      private MavenProject project;
63  
64      /**
65       * Disable validations to make sure bundle supports project materialization.
66       * <br/>
67       * <b>WARNING: This means your project will be MUCH harder to use.</b>
68       */
69      @Parameter( property = "bundle.disableMaterialization", defaultValue = "false" )
70      private boolean disableMaterialization;
71  
72      /**
73       * Jar archiver.
74       */
75      @Component( role = Archiver.class, hint = "jar" )
76      private JarArchiver jarArchiver;
77  
78      /**
79       */
80      @Component
81      protected InputHandler inputHandler;
82  
83      /**
84       */
85      @Parameter( defaultValue = "${settings}", readonly = true, required = true )
86      protected Settings settings;
87  
88      public void execute()
89          throws MojoExecutionException
90      {
91          // ----------------------------------------------------------------------
92          // Check the mandatory elements of the POM
93          //
94          // modelVersion
95          // groupId
96          // artifactId
97          // packaging
98          // name
99          // version
100         // description
101         // url
102         // licenses
103         // dependencies
104         // ----------------------------------------------------------------------
105 
106         // We don't have to validate modelVersion, groupId, artifactId or version here,
107         // it is done by DefaultMaven and maven-artifact
108 
109         validate( project.getName(), "project.name" );
110 
111         validate( project.getDescription(), "project.description" );
112 
113         validate( project.getUrl(), "project.url" );
114 
115         if ( project.getLicenses().isEmpty() )
116         {
117             throw new MojoExecutionException( "At least one license must be defined." );
118         }
119         
120         if ( disableMaterialization )
121         {
122             getLog().warn( "Validations to confirm support for project materialization have been DISABLED."
123                    + "\n\nYour project may not provide the POM elements necessary to allow users to retrieve sources "
124                    + "on-demand,"
125                    + "\nor to easily checkout your project in an IDE. THIS CAN SERIOUSLY INCONVENIENCE YOUR USERS."
126                    + "\n\nContinue? [y/N]" );
127             
128             try
129             {
130                 if ( 'y' != inputHandler.readLine().toLowerCase().charAt( 0 ) )
131                 {
132                     disableMaterialization = false;
133                 }
134             }
135             catch ( IOException e )
136             {
137                 getLog().debug( "Error reading confirmation: " + e.getMessage(), e );
138             }
139             
140         }
141         
142         if ( !disableMaterialization )
143         {
144             if ( project.getScm() == null )
145             {
146                 throw new MojoExecutionException( "You must supply a valid <scm> section, with at least "
147                     + "<url> (viewing URL) and <connection> (read-only tooling connection) specified." );
148             }
149             else
150             {
151                 validate( project.getScm().getUrl(), "project.scm.url" );
152                 
153                 validate( project.getScm().getConnection(), "project.scm.connection" );
154             }
155         }
156 
157         // ----------------------------------------------------------------------
158         // Create the bundle archive
159         // ----------------------------------------------------------------------
160 
161         File pom = project.getFile();
162 
163         final String finalName = project.getBuild().getFinalName();
164 
165         boolean batchMode = settings == null ? false : !settings.isInteractiveMode();
166         List<File> files =
167             BundleUtils.selectProjectFiles( outputDirectory, inputHandler, finalName, pom, getLog(), batchMode );
168 
169         File bundle = new File( outputDirectory, finalName + "-bundle.jar" );
170 
171         try
172         {
173             jarArchiver.addFile( pom, POM );
174 
175             boolean artifactChecks = !"pom".equals( project.getPackaging() );
176             boolean sourcesFound = false;
177             boolean javadocsFound = false;
178             
179             for ( File f : files )
180             {
181                 if ( artifactChecks && f.getName().endsWith( finalName + "-sources.jar" ) )
182                 {
183                     sourcesFound = true;
184                 }
185                 else if ( artifactChecks && f.getName().equals( finalName + "-javadoc.jar" ) )
186                 {
187                     javadocsFound = true;
188                 }
189                 
190                 jarArchiver.addFile( f, f.getName() );
191             }
192             
193             if ( artifactChecks && !sourcesFound )
194             {
195                 getLog().warn( "Sources not included in upload bundle. In order to add sources please run"
196                     + " \"mvn source:jar javadoc:jar repository:bundle-create\"" );
197             }
198 
199             if ( artifactChecks && !javadocsFound )
200             {
201                 getLog().warn( "Javadoc not included in upload bundle. In order to add javadocs please run"
202                     + " \"mvn source:jar javadoc:jar repository:bundle-create\"" );
203             }
204 
205             jarArchiver.setDestFile( bundle );
206 
207             jarArchiver.createArchive();
208         }
209         catch ( Exception e )
210         {
211             throw new MojoExecutionException( "Error creating upload bundle archive.", e );
212         }
213     }
214 
215     private void validate( String data, String expression )
216         throws MojoExecutionException
217     {
218         if ( StringUtils.isEmpty( data ) )
219         {
220             throw new MojoExecutionException( expression + " must be present." );
221         }
222     }
223 }