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 Thu Mar 15 09:17:20 CET 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.6", 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.", 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, "filters", 2 );
139                 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 );
140                 append( sb, "", 0 );
141 
142                 append( sb, "finalName", 2 );
143                 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 );
144                 append( sb, "Expression: ${finalName}", 3 );
145                 append( sb, "", 0 );
146 
147                 append( sb, "keepDependenciesWithProvidedScope (Default: false)", 2 );
148                 append( sb, "When true, dependencies are kept in the pom but with scope \'provided\'; when false, the dependency is removed.", 3 );
149                 append( sb, "Expression: ${keepDependenciesWithProvidedScope}", 3 );
150                 append( sb, "", 0 );
151 
152                 append( sb, "minimizeJar (Default: false)", 2 );
153                 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 );
154                 append( sb, "", 0 );
155 
156                 append( sb, "outputDirectory (Default: ${project.build.directory})", 2 );
157                 append( sb, "The destination directory for the shaded artifact.", 3 );
158                 append( sb, "", 0 );
159 
160                 append( sb, "outputFile", 2 );
161                 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 );
162                 append( sb, "", 0 );
163 
164                 append( sb, "promoteTransitiveDependencies (Default: false)", 2 );
165                 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 );
166                 append( sb, "Expression: ${promoteTransitiveDependencies}", 3 );
167                 append( sb, "", 0 );
168 
169                 append( sb, "relocations", 2 );
170                 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 );
171                 append( sb, "", 0 );
172 
173                 append( sb, "shadedArtifactAttached (Default: false)", 2 );
174                 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 );
175                 append( sb, "Expression: ${shadedArtifactAttached}", 3 );
176                 append( sb, "", 0 );
177 
178                 append( sb, "shadedArtifactId (Default: ${project.artifactId})", 2 );
179                 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 );
180                 append( sb, "Expression: ${shadedArtifactId}", 3 );
181                 append( sb, "", 0 );
182 
183                 append( sb, "shadedClassifierName (Default: shaded)", 2 );
184                 append( sb, "The name of the classifier used in case the shaded artifact is attached.", 3 );
185                 append( sb, "Expression: ${shadedClassifierName}", 3 );
186                 append( sb, "", 0 );
187 
188                 append( sb, "shadedGroupFilter", 2 );
189                 append( sb, "If specified, this will include only artifacts which have groupIds which start with this.", 3 );
190                 append( sb, "Expression: ${shadedGroupFilter}", 3 );
191                 append( sb, "", 0 );
192 
193                 append( sb, "shaderHint", 2 );
194                 append( sb, "You can pass here the roleHint about your own Shader implementation plexus component.", 3 );
195                 append( sb, "", 0 );
196 
197                 append( sb, "transformers", 2 );
198                 append( sb, "Resource transformers to be used. Please see the \'Examples\' section for more information on available transformers and their configuration.", 3 );
199                 append( sb, "", 0 );
200             }
201         }
202 
203         if ( getLog().isInfoEnabled() )
204         {
205             getLog().info( sb.toString() );
206         }
207     }
208 
209     /**
210      * <p>Repeat a String <code>n</code> times to form a new string.</p>
211      *
212      * @param str String to repeat
213      * @param repeat number of times to repeat str
214      * @return String with repeated String
215      * @throws NegativeArraySizeException if <code>repeat < 0</code>
216      * @throws NullPointerException if str is <code>null</code>
217      */
218     private static String repeat( String str, int repeat )
219     {
220         StringBuffer buffer = new StringBuffer( repeat * str.length() );
221 
222         for ( int i = 0; i < repeat; i++ )
223         {
224             buffer.append( str );
225         }
226 
227         return buffer.toString();
228     }
229 
230     /** 
231      * Append a description to the buffer by respecting the indentSize and lineLength parameters.
232      * <b>Note</b>: The last character is always a new line.
233      * 
234      * @param sb The buffer to append the description, not <code>null</code>.
235      * @param description The description, not <code>null</code>.
236      * @param indent The base indentation level of each line, must not be negative.
237      */
238     private void append( StringBuffer sb, String description, int indent )
239     {
240         for ( Iterator it = toLines( description, indent, indentSize, lineLength ).iterator(); it.hasNext(); )
241         {
242             sb.append( it.next().toString() ).append( '\n' );
243         }
244     }
245 
246     /** 
247      * Splits the specified text into lines of convenient display length.
248      * 
249      * @param text The text to split into lines, must not be <code>null</code>.
250      * @param indent The base indentation level of each line, must not be negative.
251      * @param indentSize The size of each indentation, must not be negative.
252      * @param lineLength The length of the line, must not be negative.
253      * @return The sequence of display lines, never <code>null</code>.
254      * @throws NegativeArraySizeException if <code>indent < 0</code>
255      */
256     private static List toLines( String text, int indent, int indentSize, int lineLength )
257     {
258         List<String> lines = new ArrayList<String>();
259 
260         String ind = repeat( "\t", indent );
261         String[] plainLines = text.split( "(\r\n)|(\r)|(\n)" );
262         for ( int i = 0; i < plainLines.length; i++ )
263         {
264             toLines( lines, ind + plainLines[i], indentSize, lineLength );
265         }
266 
267         return lines;
268     }
269 
270     /** 
271      * Adds the specified line to the output sequence, performing line wrapping if necessary.
272      * 
273      * @param lines The sequence of display lines, must not be <code>null</code>.
274      * @param line The line to add, must not be <code>null</code>.
275      * @param indentSize The size of each indentation, must not be negative.
276      * @param lineLength The length of the line, must not be negative.
277      */
278     private static void toLines( List<String> lines, String line, int indentSize, int lineLength )
279     {
280         int lineIndent = getIndentLevel( line );
281         StringBuffer buf = new StringBuffer( 256 );
282         String[] tokens = line.split( " +" );
283         for ( int i = 0; i < tokens.length; i++ )
284         {
285             String token = tokens[i];
286             if ( i > 0 )
287             {
288                 if ( buf.length() + token.length() >= lineLength )
289                 {
290                     lines.add( buf.toString() );
291                     buf.setLength( 0 );
292                     buf.append( repeat( " ", lineIndent * indentSize ) );
293                 }
294                 else
295                 {
296                     buf.append( ' ' );
297                 }
298             }
299             for ( int j = 0; j < token.length(); j++ )
300             {
301                 char c = token.charAt( j );
302                 if ( c == '\t' )
303                 {
304                     buf.append( repeat( " ", indentSize - buf.length() % indentSize ) );
305                 }
306                 else if ( c == '\u00A0' )
307                 {
308                     buf.append( ' ' );
309                 }
310                 else
311                 {
312                     buf.append( c );
313                 }
314             }
315         }
316         lines.add( buf.toString() );
317     }
318 
319     /** 
320      * Gets the indentation level of the specified line.
321      * 
322      * @param line The line whose indentation level should be retrieved, must not be <code>null</code>.
323      * @return The indentation level of the line.
324      */
325     private static int getIndentLevel( String line )
326     {
327         int level = 0;
328         for ( int i = 0; i < line.length() && line.charAt( i ) == '\t'; i++ )
329         {
330             level++;
331         }
332         for ( int i = level + 1; i <= level + 4 && i < line.length(); i++ )
333         {
334             if ( line.charAt( i ) == '\t' )
335             {
336                 level++;
337                 break;
338             }
339         }
340         return level;
341     }
342 }