View Javadoc

1   package org.apache.maven.plugins.shade.mojo;
2   
3   import java.util.ArrayList;
4   import java.util.Iterator;
5   import java.util.List;
6   
7   import org.apache.maven.plugin.AbstractMojo;
8   import org.apache.maven.plugin.MojoExecutionException;
9   
10  /**
11   * Display help information on maven-shade-plugin.<br/> Call <pre>  mvn shade:help -Ddetail=true -Dgoal=&lt;goal-name&gt;</pre> to display parameter details.
12   *
13   * @version generated on Wed Jun 27 07:47:29 EDT 2012
14   * @author org.apache.maven.tools.plugin.generator.PluginHelpGenerator (version 2.8)
15   * @goal help
16   * @requiresProject false
17   * @threadSafe
18   */
19  @SuppressWarnings( "all" )
20  public class HelpMojo
21      extends AbstractMojo
22  {
23      /**
24       * If <code>true</code>, display all settable properties for each goal.
25       * 
26       * @parameter expression="${detail}" default-value="false"
27       */
28      private boolean detail;
29  
30      /**
31       * The name of the goal for which to show help. If unspecified, all goals will be displayed.
32       * 
33       * @parameter expression="${goal}"
34       */
35      private java.lang.String goal;
36  
37      /**
38       * The maximum length of a display line, should be positive.
39       * 
40       * @parameter expression="${lineLength}" default-value="80"
41       */
42      private int lineLength;
43  
44      /**
45       * The number of spaces per indentation level, should be positive.
46       * 
47       * @parameter expression="${indentSize}" default-value="2"
48       */
49      private int indentSize;
50  
51  
52      /** {@inheritDoc} */
53      public void execute()
54          throws MojoExecutionException
55      {
56          if ( lineLength <= 0 )
57          {
58              getLog().warn( "The parameter 'lineLength' should be positive, using '80' as default." );
59              lineLength = 80;
60          }
61          if ( indentSize <= 0 )
62          {
63              getLog().warn( "The parameter 'indentSize' should be positive, using '2' as default." );
64              indentSize = 2;
65          }
66  
67          StringBuffer sb = new StringBuffer();
68  
69          append( sb, "org.apache.maven.plugins:maven-shade-plugin:1.7.1", 0 );
70          append( sb, "", 0 );
71  
72          append( sb, "Maven Shade Plugin", 0 );
73          append( sb, "Repackages the project classes together with their dependencies into a single uber-jar, optionally renaming classes or removing unused classes.", 1 );
74          append( sb, "", 0 );
75  
76          if ( goal == null || goal.length() <= 0 )
77          {
78              append( sb, "This plugin has 2 goals:", 0 );
79              append( sb, "", 0 );
80          }
81  
82          if ( goal == null || goal.length() <= 0 || "help".equals( goal ) )
83          {
84              append( sb, "shade:help", 0 );
85              append( sb, "Display help information on maven-shade-plugin.\nCall\n\u00a0\u00a0mvn\u00a0shade:help\u00a0-Ddetail=true\u00a0-Dgoal=<goal-name>\nto display parameter details.", 1 );
86              append( sb, "", 0 );
87              if ( detail )
88              {
89                  append( sb, "Available parameters:", 1 );
90                  append( sb, "", 0 );
91  
92                  append( sb, "detail (Default: false)", 2 );
93                  append( sb, "If true, display all settable properties for each goal.", 3 );
94                  append( sb, "Expression: ${detail}", 3 );
95                  append( sb, "", 0 );
96  
97                  append( sb, "goal", 2 );
98                  append( sb, "The name of the goal for which to show help. If unspecified, all goals will be displayed.", 3 );
99                  append( sb, "Expression: ${goal}", 3 );
100                 append( sb, "", 0 );
101 
102                 append( sb, "indentSize (Default: 2)", 2 );
103                 append( sb, "The number of spaces per indentation level, should be positive.", 3 );
104                 append( sb, "Expression: ${indentSize}", 3 );
105                 append( sb, "", 0 );
106 
107                 append( sb, "lineLength (Default: 80)", 2 );
108                 append( sb, "The maximum length of a display line, should be positive.", 3 );
109                 append( sb, "Expression: ${lineLength}", 3 );
110                 append( sb, "", 0 );
111             }
112         }
113 
114         if ( goal == null || goal.length() <= 0 || "shade".equals( goal ) )
115         {
116             append( sb, "shade:shade", 0 );
117             append( sb, "Mojo that performs shading delegating to the Shader component.", 1 );
118             append( sb, "", 0 );
119             if ( detail )
120             {
121                 append( sb, "Available parameters:", 1 );
122                 append( sb, "", 0 );
123 
124                 append( sb, "artifactSet", 2 );
125                 append( sb, "Artifacts to include/exclude from the final artifact. Artifacts are denoted by composite identifiers of the general form groupId:artifactId:type:classifier. Since version 1.3, the wildcard characters \'*\' and \'?\' can be used within the sub parts of those composite identifiers to do pattern matching. For convenience, the syntax groupId is equivalent to groupId:*:*:*, groupId:artifactId is equivalent to groupId:artifactId:*:* and groupId:artifactId:classifier is equivalent to groupId:artifactId:*:classifier. For example:\n<artifactSet>\n\u00a0\u00a0<includes>\n\u00a0\u00a0\u00a0\u00a0<include>org.apache.maven:*</include>\n\u00a0\u00a0</includes>\n\u00a0\u00a0<excludes>\n\u00a0\u00a0\u00a0\u00a0<exclude>*:maven-core</exclude>\n\u00a0\u00a0</excludes>\n</artifactSet>\n", 3 );
126                 append( sb, "", 0 );
127 
128                 append( sb, "createDependencyReducedPom (Default: true)", 2 );
129                 append( sb, "Flag whether to generate a simplified POM for the shaded artifact. If set to true, dependencies that have been included into the uber JAR will be removed from the <dependencies> section of the generated POM. The reduced POM will be named dependency-reduced-pom.xml and is stored into the same directory as the shaded artifact. Unless you also specify dependencyReducedPomLocation, the plugin will create a temporary file named dependency-reduced-pom.xml in the project basedir.", 3 );
130                 append( sb, "Expression: ${createDependencyReducedPom}", 3 );
131                 append( sb, "", 0 );
132 
133                 append( sb, "createSourcesJar (Default: false)", 2 );
134                 append( sb, "When true, it will attempt to create a sources jar as well", 3 );
135                 append( sb, "Expression: ${createSourcesJar}", 3 );
136                 append( sb, "", 0 );
137 
138                 append( sb, "dependencyReducedPomLocation", 2 );
139                 append( sb, "(no description available)", 3 );
140                 append( sb, "Expression: ${dependencyReducedPomLocation}", 3 );
141                 append( sb, "", 0 );
142 
143                 append( sb, "filters", 2 );
144                 append( sb, "Archive Filters to be used. Allows you to specify an artifact in the form of a composite identifier as used by artifactSet and a set of include/exclude file patterns for filtering which contents of the archive are added to the shaded jar. From a logical perspective, includes are processed before excludes, thus it\'s possible to use an include to collect a set of files from the archive then use excludes to further reduce the set. By default, all files are included and no files are excluded. If multiple filters apply to an artifact, the intersection of the matched files will be included in the final JAR. For example:\n<filters>\n\u00a0\u00a0<filter>\n\u00a0\u00a0\u00a0\u00a0<artifact>junit:junit</artifact>\n\u00a0\u00a0\u00a0\u00a0<includes>\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0<include>org/junit/**</include>\n\u00a0\u00a0\u00a0\u00a0</includes>\n\u00a0\u00a0\u00a0\u00a0<excludes>\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0<exclude>org/junit/experimental/**</exclude>\n\u00a0\u00a0\u00a0\u00a0</excludes>\n\u00a0\u00a0</filter>\n</filters>\n", 3 );
145                 append( sb, "", 0 );
146 
147                 append( sb, "finalName", 2 );
148                 append( sb, "The name of the shaded artifactId. If you like to change the name of the native artifact, you may use the <build><finalName> setting. If this is set to something different than <build><finalName>, no file replacement will be performed, even if shadedArtifactAttached is being used.", 3 );
149                 append( sb, "Expression: ${finalName}", 3 );
150                 append( sb, "", 0 );
151 
152                 append( sb, "keepDependenciesWithProvidedScope (Default: false)", 2 );
153                 append( sb, "When true, dependencies are kept in the pom but with scope \'provided\'; when false, the dependency is removed.", 3 );
154                 append( sb, "Expression: ${keepDependenciesWithProvidedScope}", 3 );
155                 append( sb, "", 0 );
156 
157                 append( sb, "minimizeJar (Default: false)", 2 );
158                 append( sb, "When true, dependencies will be stripped down on the class level to only the transitive hull required for the artifact. Note: Usage of this feature requires Java 1.5 or higher.", 3 );
159                 append( sb, "", 0 );
160 
161                 append( sb, "outputDirectory (Default: ${project.build.directory})", 2 );
162                 append( sb, "The destination directory for the shaded artifact.", 3 );
163                 append( sb, "", 0 );
164 
165                 append( sb, "outputFile", 2 );
166                 append( sb, "The path to the output file for the shaded artifact. When this parameter is set, the created archive will neither replace the project\'s main artifact nor will it be attached. Hence, this parameter causes the parameters finalName, shadedArtifactAttached, shadedClassifierName and createDependencyReducedPom to be ignored when used.", 3 );
167                 append( sb, "", 0 );
168 
169                 append( sb, "promoteTransitiveDependencies (Default: false)", 2 );
170                 append( sb, "When true, transitive deps of removed dependencies are promoted to direct dependencies. This should allow the drop in replacement of the removed deps with the new shaded jar and everything should still work.", 3 );
171                 append( sb, "Expression: ${promoteTransitiveDependencies}", 3 );
172                 append( sb, "", 0 );
173 
174                 append( sb, "relocations", 2 );
175                 append( sb, "Packages to be relocated. For example:\n<relocations>\n\u00a0\u00a0<relocation>\n\u00a0\u00a0\u00a0\u00a0<pattern>org.apache</pattern>\n\u00a0\u00a0\u00a0\u00a0<shadedPattern>hidden.org.apache</shadedPattern>\n\u00a0\u00a0\u00a0\u00a0<includes>\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0<include>org.apache.maven.*</include>\n\u00a0\u00a0\u00a0\u00a0</includes>\n\u00a0\u00a0\u00a0\u00a0<excludes>\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0<exclude>org.apache.maven.Public*</exclude>\n\u00a0\u00a0\u00a0\u00a0</excludes>\n\u00a0\u00a0</relocation>\n</relocations>\nNote: Support for includes exists only since version 1.4.", 3 );
176                 append( sb, "", 0 );
177 
178                 append( sb, "shadedArtifactAttached (Default: false)", 2 );
179                 append( sb, "Defines whether the shaded artifact should be attached as classifier to the original artifact. If false, the shaded jar will be the main artifact of the project", 3 );
180                 append( sb, "Expression: ${shadedArtifactAttached}", 3 );
181                 append( sb, "", 0 );
182 
183                 append( sb, "shadedArtifactId (Default: ${project.artifactId})", 2 );
184                 append( sb, "The name of the shaded artifactId. So you may want to use a different artifactId and keep the standard version. If the original artifactId was \'foo\' then the final artifact would be something like foo-1.0.jar. So if you change the artifactId you might have something like foo-special-1.0.jar.", 3 );
185                 append( sb, "Expression: ${shadedArtifactId}", 3 );
186                 append( sb, "", 0 );
187 
188                 append( sb, "shadedClassifierName (Default: shaded)", 2 );
189                 append( sb, "The name of the classifier used in case the shaded artifact is attached.", 3 );
190                 append( sb, "Expression: ${shadedClassifierName}", 3 );
191                 append( sb, "", 0 );
192 
193                 append( sb, "shadedGroupFilter", 2 );
194                 append( sb, "If specified, this will include only artifacts which have groupIds which start with this.", 3 );
195                 append( sb, "Expression: ${shadedGroupFilter}", 3 );
196                 append( sb, "", 0 );
197 
198                 append( sb, "shaderHint", 2 );
199                 append( sb, "You can pass here the roleHint about your own Shader implementation plexus component.", 3 );
200                 append( sb, "", 0 );
201 
202                 append( sb, "transformers", 2 );
203                 append( sb, "Resource transformers to be used. Please see the \'Examples\' section for more information on available transformers and their configuration.", 3 );
204                 append( sb, "", 0 );
205             }
206         }
207 
208         if ( getLog().isInfoEnabled() )
209         {
210             getLog().info( sb.toString() );
211         }
212     }
213 
214     /**
215      * <p>Repeat a String <code>n</code> times to form a new string.</p>
216      *
217      * @param str String to repeat
218      * @param repeat number of times to repeat str
219      * @return String with repeated String
220      * @throws NegativeArraySizeException if <code>repeat < 0</code>
221      * @throws NullPointerException if str is <code>null</code>
222      */
223     private static String repeat( String str, int repeat )
224     {
225         StringBuffer buffer = new StringBuffer( repeat * str.length() );
226 
227         for ( int i = 0; i < repeat; i++ )
228         {
229             buffer.append( str );
230         }
231 
232         return buffer.toString();
233     }
234 
235     /** 
236      * Append a description to the buffer by respecting the indentSize and lineLength parameters.
237      * <b>Note</b>: The last character is always a new line.
238      * 
239      * @param sb The buffer to append the description, not <code>null</code>.
240      * @param description The description, not <code>null</code>.
241      * @param indent The base indentation level of each line, must not be negative.
242      */
243     private void append( StringBuffer sb, String description, int indent )
244     {
245         for ( Iterator it = toLines( description, indent, indentSize, lineLength ).iterator(); it.hasNext(); )
246         {
247             sb.append( it.next().toString() ).append( '\n' );
248         }
249     }
250 
251     /** 
252      * Splits the specified text into lines of convenient display length.
253      * 
254      * @param text The text to split into lines, must not be <code>null</code>.
255      * @param indent The base indentation level of each line, must not be negative.
256      * @param indentSize The size of each indentation, must not be negative.
257      * @param lineLength The length of the line, must not be negative.
258      * @return The sequence of display lines, never <code>null</code>.
259      * @throws NegativeArraySizeException if <code>indent < 0</code>
260      */
261     private static List toLines( String text, int indent, int indentSize, int lineLength )
262     {
263         List<String> lines = new ArrayList<String>();
264 
265         String ind = repeat( "\t", indent );
266         String[] plainLines = text.split( "(\r\n)|(\r)|(\n)" );
267         for ( int i = 0; i < plainLines.length; i++ )
268         {
269             toLines( lines, ind + plainLines[i], indentSize, lineLength );
270         }
271 
272         return lines;
273     }
274 
275     /** 
276      * Adds the specified line to the output sequence, performing line wrapping if necessary.
277      * 
278      * @param lines The sequence of display lines, must not be <code>null</code>.
279      * @param line The line to add, must not be <code>null</code>.
280      * @param indentSize The size of each indentation, must not be negative.
281      * @param lineLength The length of the line, must not be negative.
282      */
283     private static void toLines( List<String> lines, String line, int indentSize, int lineLength )
284     {
285         int lineIndent = getIndentLevel( line );
286         StringBuffer buf = new StringBuffer( 256 );
287         String[] tokens = line.split( " +" );
288         for ( int i = 0; i < tokens.length; i++ )
289         {
290             String token = tokens[i];
291             if ( i > 0 )
292             {
293                 if ( buf.length() + token.length() >= lineLength )
294                 {
295                     lines.add( buf.toString() );
296                     buf.setLength( 0 );
297                     buf.append( repeat( " ", lineIndent * indentSize ) );
298                 }
299                 else
300                 {
301                     buf.append( ' ' );
302                 }
303             }
304             for ( int j = 0; j < token.length(); j++ )
305             {
306                 char c = token.charAt( j );
307                 if ( c == '\t' )
308                 {
309                     buf.append( repeat( " ", indentSize - buf.length() % indentSize ) );
310                 }
311                 else if ( c == '\u00A0' )
312                 {
313                     buf.append( ' ' );
314                 }
315                 else
316                 {
317                     buf.append( c );
318                 }
319             }
320         }
321         lines.add( buf.toString() );
322     }
323 
324     /** 
325      * Gets the indentation level of the specified line.
326      * 
327      * @param line The line whose indentation level should be retrieved, must not be <code>null</code>.
328      * @return The indentation level of the line.
329      */
330     private static int getIndentLevel( String line )
331     {
332         int level = 0;
333         for ( int i = 0; i < line.length() && line.charAt( i ) == '\t'; i++ )
334         {
335             level++;
336         }
337         for ( int i = level + 1; i <= level + 4 && i < line.length(); i++ )
338         {
339             if ( line.charAt( i ) == '\t' )
340             {
341                 level++;
342                 break;
343             }
344         }
345         return level;
346     }
347 }