1 package org.apache.maven.plugin.changes;
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
12
13
14
15
16
17
18
19 @SuppressWarnings( "all" )
20 public class HelpMojo
21 extends AbstractMojo
22 {
23
24
25
26
27
28 private boolean detail;
29
30
31
32
33
34
35 private java.lang.String goal;
36
37
38
39
40
41
42 private int lineLength;
43
44
45
46
47
48
49 private int indentSize;
50
51
52
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-changes-plugin:2.7", 0 );
70 append( sb, "", 0 );
71
72 append( sb, "Maven Changes Report Plugin", 0 );
73 append( sb, "Creates a release history for inclusion into the site and assists in generating an announcement mail.", 1 );
74 append( sb, "", 0 );
75
76 if ( goal == null || goal.length() <= 0 )
77 {
78 append( sb, "This plugin has 8 goals:", 0 );
79 append( sb, "", 0 );
80 }
81
82 if ( goal == null || goal.length() <= 0 || "announcement-generate".equals( goal ) )
83 {
84 append( sb, "changes:announcement-generate", 0 );
85 append( sb, "Goal which generate the template for an announcement.", 1 );
86 append( sb, "", 0 );
87 if ( detail )
88 {
89 append( sb, "Available parameters:", 1 );
90 append( sb, "", 0 );
91
92 append( sb, "announcementFile", 2 );
93 append( sb, "The name of the file which will contain the generated announcement. If no value is specified the plugin will use the name of the template.", 3 );
94 append( sb, "Expression: ${changes.announcementFile}", 3 );
95 append( sb, "", 0 );
96
97 append( sb, "announceParameters", 2 );
98 append( sb, "Map of custom parameters for the announcement. This Map will be passed to the template.", 3 );
99 append( sb, "", 0 );
100
101 append( sb, "basedir", 2 );
102 append( sb, "The current project base directory.", 3 );
103 append( sb, "Required: Yes", 3 );
104 append( sb, "Expression: ${basedir}", 3 );
105 append( sb, "", 0 );
106
107 append( sb, "developmentTeam (Default: ${project.name} team)", 2 );
108 append( sb, "Name of the team that develops the artifact. This parameter will be passed to the template.", 3 );
109 append( sb, "Required: Yes", 3 );
110 append( sb, "Expression: ${changes.developmentTeam}", 3 );
111 append( sb, "", 0 );
112
113 append( sb, "filter", 2 );
114 append( sb, "Defines the filter parameters to restrict which issues are retrieved from JIRA. The filter parameter uses the same format of url parameters that is used in a JIRA search.", 3 );
115 append( sb, "", 0 );
116
117 append( sb, "finalName (Default: ${project.build.finalName})", 2 );
118 append( sb, "The name of the artifact to be used in the announcement.", 3 );
119 append( sb, "Required: Yes", 3 );
120 append( sb, "Expression: ${changes.finalName}", 3 );
121 append( sb, "", 0 );
122
123 append( sb, "generateJiraAnnouncement (Default: false)", 2 );
124 append( sb, "Deprecated. Since version 2.4 this parameter has been deprecated. Please use the issueManagementSystems parameter instead.", 3 );
125 append( sb, "", 0 );
126 append( sb, "Flag to determine if the plugin will generate a JIRA announcement.", 3 );
127 append( sb, "Required: Yes", 3 );
128 append( sb, "Expression: ${generateJiraAnnouncement}", 3 );
129 append( sb, "", 0 );
130
131 append( sb, "introduction (Default: ${project.description})", 2 );
132 append( sb, "Short description or introduction of the released artifact. This parameter will be passed to the template.", 3 );
133 append( sb, "", 0 );
134
135 append( sb, "issueManagementSystems", 2 );
136 append( sb, "A list of issue management systems to fetch releases from. This parameter replaces the parameters generateJiraAnnouncement and jiraMerge.\nValid values are: changes.xml and JIRA.\nNote: Only one issue management system that is configured in <project>/<issueManagement> can be used. This currently means that you can combine a changes.xml file with one other issue management system.", 3 );
137 append( sb, "", 0 );
138
139 append( sb, "issueTypes", 2 );
140 append( sb, "Maps issues types to action types for grouping issues in announcements. If issue types are not defined for a action type then the default issue type will be applied.\nValid action types: add, fix and update.\n", 3 );
141 append( sb, "", 0 );
142
143 append( sb, "jiraMerge (Default: false)", 2 );
144 append( sb, "Deprecated. Since version 2.4 this parameter has been deprecated. Please use the issueManagementSystems parameter instead.", 3 );
145 append( sb, "", 0 );
146 append( sb, "If releases from JIRA should be merged with the releases from a changes.xml file.", 3 );
147 append( sb, "Expression: ${changes.jiraMerge}", 3 );
148 append( sb, "", 0 );
149
150 append( sb, "jiraPassword", 2 );
151 append( sb, "Defines the JIRA password for authentication into a private JIRA installation.", 3 );
152 append( sb, "Expression: ${changes.jiraPassword}", 3 );
153 append( sb, "", 0 );
154
155 append( sb, "jiraUser", 2 );
156 append( sb, "Defines the JIRA username for authentication into a private JIRA installation.", 3 );
157 append( sb, "Expression: ${changes.jiraUser}", 3 );
158 append( sb, "", 0 );
159
160 append( sb, "maxEntries (Default: 25)", 2 );
161 append( sb, "The maximum number of issues to fetch from JIRA.\nNote: In versions 2.0-beta-3 and earlier this parameter was called \'nbEntries\'.\n", 3 );
162 append( sb, "Required: Yes", 3 );
163 append( sb, "Expression: ${changes.maxEntries}", 3 );
164 append( sb, "", 0 );
165
166 append( sb, "outputDirectory", 2 );
167 append( sb, "Directory where the template file will be generated.", 3 );
168 append( sb, "Required: Yes", 3 );
169 append( sb, "Expression: ${project.build.directory}/announcement", 3 );
170 append( sb, "", 0 );
171
172 append( sb, "resolutionIds (Default: Fixed)", 2 );
173 append( sb, "Include issues from JIRA with these resolution ids. Multiple resolution ids can be specified as a comma separated list of ids.\nNote: In versions 2.0-beta-3 and earlier this parameter was called \'resolutionId\'.\n", 3 );
174 append( sb, "Expression: ${changes.resolutionIds}", 3 );
175 append( sb, "", 0 );
176
177 append( sb, "runOnlyAtExecutionRoot (Default: false)", 2 );
178 append( sb, "This will cause the execution to be run only at the top of a given module tree. That is, run in the project contained in the same folder where the mvn execution was launched.", 3 );
179 append( sb, "Expression: ${announcement.runOnlyAtExecutionRoot}", 3 );
180 append( sb, "", 0 );
181
182 append( sb, "statusIds (Default: Closed)", 2 );
183 append( sb, "Include issues from JIRA with these status ids. Multiple status ids can be specified as a comma separated list of ids.\nNote: In versions 2.0-beta-3 and earlier this parameter was called \'statusId\'.\n", 3 );
184 append( sb, "Expression: ${changes.statusIds}", 3 );
185 append( sb, "", 0 );
186
187 append( sb, "template (Default: announcement.vm)", 2 );
188 append( sb, "The Velocity template used to format the announcement.", 3 );
189 append( sb, "Required: Yes", 3 );
190 append( sb, "Expression: ${changes.template}", 3 );
191 append( sb, "", 0 );
192
193 append( sb, "templateDirectory (Default: org/apache/maven/plugin/announcement)", 2 );
194 append( sb, "Directory that contains the template.\nNote: This directory must be a subdirectory of /src/main/resources/ or current project base directory.\n", 3 );
195 append( sb, "Required: Yes", 3 );
196 append( sb, "Expression: ${changes.templateDirectory}", 3 );
197 append( sb, "", 0 );
198
199 append( sb, "templateEncoding (Default: ${project.build.sourceEncoding})", 2 );
200 append( sb, "The template encoding.", 3 );
201 append( sb, "Expression: ${changes.templateEncoding}", 3 );
202 append( sb, "", 0 );
203
204 append( sb, "tracPassword", 2 );
205 append( sb, "Defines the Trac password for authentication into a private Trac installation.", 3 );
206 append( sb, "Expression: ${changes.tracPassword}", 3 );
207 append( sb, "", 0 );
208
209 append( sb, "tracQuery (Default: order=id)", 2 );
210 append( sb, "Defines the Trac query for searching for tickets.", 3 );
211 append( sb, "", 0 );
212
213 append( sb, "tracUser", 2 );
214 append( sb, "Defines the Trac username for authentication into a private Trac installation.", 3 );
215 append( sb, "Expression: ${changes.tracUser}", 3 );
216 append( sb, "", 0 );
217
218 append( sb, "url", 2 );
219 append( sb, "Distribution URL of the artifact. This parameter will be passed to the template.", 3 );
220 append( sb, "Expression: ${project.url}", 3 );
221 append( sb, "", 0 );
222
223 append( sb, "urlDownload", 2 );
224 append( sb, "URL where the artifact can be downloaded. If not specified, no URL is used. This parameter will be passed to the template.", 3 );
225 append( sb, "", 0 );
226
227 append( sb, "version (Default: ${project.version})", 2 );
228 append( sb, "Version of the artifact.", 3 );
229 append( sb, "Required: Yes", 3 );
230 append( sb, "Expression: ${changes.version}", 3 );
231 append( sb, "", 0 );
232
233 append( sb, "versionPrefix", 2 );
234 append( sb, "The prefix used when naming versions in JIRA.\nIf you have a project in JIRA with several components that have different release cycles, it is an often used pattern to prefix the version with the name of the component, e.g. maven-filtering-1.0 etc. To fetch issues from JIRA for a release of the \'maven-filtering\' component you would need to set this parameter to \'maven-filtering-\'.\n", 3 );
235 append( sb, "Expression: ${changes.versionPrefix}", 3 );
236 append( sb, "", 0 );
237
238 append( sb, "webPassword", 2 );
239 append( sb, "Defines the http password for basic authentication into the JIRA webserver.", 3 );
240 append( sb, "Expression: ${changes.webPassword}", 3 );
241 append( sb, "", 0 );
242
243 append( sb, "webUser", 2 );
244 append( sb, "Defines the http user for basic authentication into the JIRA webserver.", 3 );
245 append( sb, "Expression: ${changes.webUser}", 3 );
246 append( sb, "", 0 );
247
248 append( sb, "xmlPath", 2 );
249 append( sb, "The path of the changes.xml file.", 3 );
250 append( sb, "Required: Yes", 3 );
251 append( sb, "Expression: ${basedir}/src/changes/changes.xml", 3 );
252 append( sb, "", 0 );
253 }
254 }
255
256 if ( goal == null || goal.length() <= 0 || "announcement-mail".equals( goal ) )
257 {
258 append( sb, "changes:announcement-mail", 0 );
259 append( sb, "Goal which sends an announcement through email.", 1 );
260 append( sb, "", 0 );
261 if ( detail )
262 {
263 append( sb, "Available parameters:", 1 );
264 append( sb, "", 0 );
265
266 append( sb, "basedir", 2 );
267 append( sb, "The current project base directory.", 3 );
268 append( sb, "Required: Yes", 3 );
269 append( sb, "Expression: ${basedir}", 3 );
270 append( sb, "", 0 );
271
272 append( sb, "bccAddresses", 2 );
273 append( sb, "Recipient bcc email address.", 3 );
274 append( sb, "", 0 );
275
276 append( sb, "ccAddresses", 2 );
277 append( sb, "Recipient cc email address.", 3 );
278 append( sb, "", 0 );
279
280 append( sb, "fromDeveloperId", 2 );
281 append( sb, "The id of the developer sending the announcement mail. Only used if the mailSender attribute is not set. In this case, this should match the id of one of the developers in the pom. If a matching developer is not found, then the first developer in the pom will be used.", 3 );
282 append( sb, "Expression: ${changes.fromDeveloperId}", 3 );
283 append( sb, "", 0 );
284
285 append( sb, "mailContentType (Default: text/plain)", 2 );
286 append( sb, "Mail content type to use.", 3 );
287 append( sb, "Required: Yes", 3 );
288 append( sb, "", 0 );
289
290 append( sb, "mailSender", 2 );
291 append( sb, "Defines the sender of the announcement email. This takes precedence over the list of developers specified in the POM. if the sender is not a member of the development team. Note that since this is a bean type, you cannot specify it from command level with\n-D\n. Use\n-Dchanges.sender=\'Your\u00a0Name\u00a0<you@domain>\'\ninstead.", 3 );
292 append( sb, "Expression: ${changes.mailSender}", 3 );
293 append( sb, "", 0 );
294
295 append( sb, "password", 2 );
296 append( sb, "The password used to send the email.", 3 );
297 append( sb, "Expression: ${changes.password}", 3 );
298 append( sb, "", 0 );
299
300 append( sb, "runOnlyAtExecutionRoot (Default: false)", 2 );
301 append( sb, "This will cause the execution to be run only at the top of a given module tree. That is, run in the project contained in the same folder where the mvn execution was launched.", 3 );
302 append( sb, "Expression: ${announcement.runOnlyAtExecutionRoot}", 3 );
303 append( sb, "", 0 );
304
305 append( sb, "senderString", 2 );
306 append( sb, "Defines the sender of the announcement. This takes precedence over both ${changes.mailSender} and the list of developers in the POM. This parameter parses an email address in standard RFC822 format, e.g.\n-Dchanges.sender=\'Your\u00a0Name\u00a0<you@domain>\'\n.", 3 );
307 append( sb, "Expression: ${changes.sender}", 3 );
308 append( sb, "", 0 );
309
310 append( sb, "smtpHost", 2 );
311 append( sb, "Smtp Server.", 3 );
312 append( sb, "Required: Yes", 3 );
313 append( sb, "Expression: ${changes.smtpHost}", 3 );
314 append( sb, "", 0 );
315
316 append( sb, "smtpPort (Default: 25)", 2 );
317 append( sb, "Port.", 3 );
318 append( sb, "Required: Yes", 3 );
319 append( sb, "Expression: ${changes.smtpPort}", 3 );
320 append( sb, "", 0 );
321
322 append( sb, "sslMode (Default: false)", 2 );
323 append( sb, "If the email should be sent in SSL mode.", 3 );
324 append( sb, "Expression: ${changes.sslMode}", 3 );
325 append( sb, "", 0 );
326
327 append( sb, "subject (Default: [ANNOUNCEMENT] - ${project.name} ${project.version} released)", 2 );
328 append( sb, "Subject for the email.", 3 );
329 append( sb, "Required: Yes", 3 );
330 append( sb, "Expression: ${changes.subject}", 3 );
331 append( sb, "", 0 );
332
333 append( sb, "template (Default: announcement.vm)", 2 );
334 append( sb, "The Velocity template used to format the announcement.", 3 );
335 append( sb, "Required: Yes", 3 );
336 append( sb, "Expression: ${changes.template}", 3 );
337 append( sb, "", 0 );
338
339 append( sb, "templateOutputDirectory", 2 );
340 append( sb, "Directory which contains the template for announcement email.", 3 );
341 append( sb, "Required: Yes", 3 );
342 append( sb, "Expression: ${project.build.directory}/announcement", 3 );
343 append( sb, "", 0 );
344
345 append( sb, "toAddresses", 2 );
346 append( sb, "Recipient email address.", 3 );
347 append( sb, "Required: Yes", 3 );
348 append( sb, "", 0 );
349
350 append( sb, "username", 2 );
351 append( sb, "The username used to send the email.", 3 );
352 append( sb, "Expression: ${changes.username}", 3 );
353 append( sb, "", 0 );
354 }
355 }
356
357 if ( goal == null || goal.length() <= 0 || "changes-check".equals( goal ) )
358 {
359 append( sb, "changes:changes-check", 0 );
360 append( sb, "Goal which checks that the changes.xml file has the necessary data to generate an announcement or a report for the current release.", 1 );
361 append( sb, "", 0 );
362 if ( detail )
363 {
364 append( sb, "Available parameters:", 1 );
365 append( sb, "", 0 );
366
367 append( sb, "releaseDateFormat (Default: yyyy-MM-dd)", 2 );
368 append( sb, "The format that a correct release date should have. This value will be used as a pattern to try to create a date.", 3 );
369 append( sb, "Expression: ${changes.releaseDateFormat}", 3 );
370 append( sb, "", 0 );
371
372 append( sb, "skipSnapshots (Default: false)", 2 );
373 append( sb, "Flag controlling snapshot processing. If set, versions ending with -SNAPSHOT won\'t be checked.", 3 );
374 append( sb, "Expression: ${changes.skipSnapshots}", 3 );
375 append( sb, "", 0 );
376
377 append( sb, "version (Default: ${project.version})", 2 );
378 append( sb, "Version of the artifact.", 3 );
379 append( sb, "Required: Yes", 3 );
380 append( sb, "Expression: ${changes.version}", 3 );
381 append( sb, "", 0 );
382
383 append( sb, "xmlPath (Default: src/changes/changes.xml)", 2 );
384 append( sb, "The path of the changes.xml file that will be checked.", 3 );
385 append( sb, "Expression: ${changes.xmlPath}", 3 );
386 append( sb, "", 0 );
387 }
388 }
389
390 if ( goal == null || goal.length() <= 0 || "changes-report".equals( goal ) )
391 {
392 append( sb, "changes:changes-report", 0 );
393 append( sb, "Goal which creates a nicely formatted Changes Report in html format from a changes.xml file.", 1 );
394 append( sb, "", 0 );
395 if ( detail )
396 {
397 append( sb, "Available parameters:", 1 );
398 append( sb, "", 0 );
399
400 append( sb, "addActionDate (Default: false)", 2 );
401 append( sb, "A flag whether the report should also include the dates of individual actions. If set to false, only the dates of releases will be written to the report.", 3 );
402 append( sb, "Expression: ${changes.addActionDate}", 3 );
403 append( sb, "", 0 );
404
405 append( sb, "aggregated (Default: false)", 2 );
406 append( sb, "A flag whether the report should also include changes from child modules. If set to false, only the changes from current project will be written to the report.", 3 );
407 append( sb, "", 0 );
408
409 append( sb, "escapeHTML (Default: true)", 2 );
410 append( sb, "Deprecated. using markup inside CDATA sections does not work for all output formats!", 3 );
411 append( sb, "", 0 );
412 append( sb, "Whether HTML code within an action should be escaped. By changing this to false you can restore the behavior that was in version 2.2 of this plugin, allowing you to use HTML code to format the content of an action.\nNote: If you use HTML code in an action you need to place it inside a CDATA section.\nNote: Putting any kind of markup inside a CDATA section might mess up the Changes Report or other generated documents, such as PDFs, that are based on your changes.xml file if you are not careful.", 3 );
413 append( sb, "", 0 );
414
415 append( sb, "filteringChanges (Default: false)", 2 );
416 append( sb, "applying filtering filtering \'a la\' resources plugin", 3 );
417 append( sb, "", 0 );
418
419 append( sb, "issueLinkTemplate (Default: %URL%/ViewIssue.jspa?key=%ISSUE%)", 2 );
420 append( sb, "Deprecated. As of 2.1 use issueLinkTemplatePerSystem : this one will be with system default", 3 );
421 append( sb, "", 0 );
422 append( sb, "Template string that is used to discover the URL to use to display an issue report. There are 2 template tokens you can use. %URL%: this is computed by getting the <issueManagement>/<url> value from the POM, and removing the last \'/\' and everything that comes after it. %ISSUE%: this is the issue number.\nNote: In versions of this plugin prior to 2.0-beta-2 this parameter was called link_template.\n", 3 );
423 append( sb, "Expression: ${changes.issueLinkTemplate}", 3 );
424 append( sb, "", 0 );
425
426 append( sb, "issueLinkTemplatePerSystem", 2 );
427 append( sb, "Template strings per system that is used to discover the URL to use to display an issue report. Each key in this map denotes the (case-insensitive) identifier of the issue tracking system and its value gives the URL template.\nThere are 2 template tokens you can use. %URL%: this is computed by getting the <issueManagement>/<url> value from the POM, and removing the last \'/\' and everything that comes after it. %ISSUE%: this is the issue number.\n\nNote: The deprecated issueLinkTemplate will be used for a system called \'default\'.\n\nNote: Starting with version 2.4 you usually don\'t need to specify this, unless you need to link to an issue management system in your Changes report that isn\'t supported out of the box. See the Usage page for more information.\n", 3 );
428 append( sb, "", 0 );
429
430 append( sb, "outputDirectory (Default: ${project.reporting.outputDirectory})", 2 );
431 append( sb, "Report output directory. Note that this parameter is only relevant if the goal is run from the command line or from the default build lifecycle. If the goal is run indirectly as part of a site generation, the output directory configured in the Maven Site Plugin is used instead.", 3 );
432 append( sb, "", 0 );
433
434 append( sb, "outputEncoding (Default: ${project.reporting.outputEncoding})", 2 );
435 append( sb, "Report output encoding. Note that this parameter is only relevant if the goal is run from the command line or from the default build lifecycle. If the goal is run indirectly as part of a site generation, the output encoding configured in the Maven Site Plugin is used instead.", 3 );
436 append( sb, "Expression: ${outputEncoding}", 3 );
437 append( sb, "", 0 );
438
439 append( sb, "publishDateFormat (Default: yyyy-MM-dd)", 2 );
440 append( sb, "Format to use for publishDate. The value will be available with the following expression ${publishDate}", 3 );
441 append( sb, "", 0 );
442
443 append( sb, "publishDateLocale (Default: en)", 2 );
444 append( sb, "Locale to use for publishDate when formatting", 3 );
445 append( sb, "", 0 );
446
447 append( sb, "teamlist (Default: team-list.html)", 2 );
448 append( sb, "The URI of a file containing all the team members. If this is set to the special value \'none\', no links will be generated for the team members.", 3 );
449 append( sb, "", 0 );
450
451 append( sb, "xmlPath (Default: src/changes/changes.xml)", 2 );
452 append( sb, "The path of the changes.xml file that will be converted into an HTML report.", 3 );
453 append( sb, "Expression: ${changes.xmlPath}", 3 );
454 append( sb, "", 0 );
455 }
456 }
457
458 if ( goal == null || goal.length() <= 0 || "changes-validate".equals( goal ) )
459 {
460 append( sb, "changes:changes-validate", 0 );
461 append( sb, "Goal which validate the changes.xml file.", 1 );
462 append( sb, "", 0 );
463 if ( detail )
464 {
465 append( sb, "Available parameters:", 1 );
466 append( sb, "", 0 );
467
468 append( sb, "changesXsdVersion (Default: 1.0.0)", 2 );
469 append( sb, "The changes xsd version.", 3 );
470 append( sb, "Expression: ${changes.xsdVersion}", 3 );
471 append( sb, "", 0 );
472
473 append( sb, "failOnError (Default: false)", 2 );
474 append( sb, "Mojo failure if validation failed. If not and validation failed only a warning will be logged.", 3 );
475 append( sb, "Expression: ${changes.validate.failed}", 3 );
476 append( sb, "", 0 );
477
478 append( sb, "xmlPath (Default: src/changes/changes.xml)", 2 );
479 append( sb, "The path of the changes.xml file that will be converted into an HTML report.", 3 );
480 append( sb, "Expression: ${changes.xmlPath}", 3 );
481 append( sb, "", 0 );
482 }
483 }
484
485 if ( goal == null || goal.length() <= 0 || "help".equals( goal ) )
486 {
487 append( sb, "changes:help", 0 );
488 append( sb, "Display help information on maven-changes-plugin.\nCall\n\u00a0\u00a0mvn\u00a0changes:help\u00a0-Ddetail=true\u00a0-Dgoal=<goal-name>\nto display parameter details.", 1 );
489 append( sb, "", 0 );
490 if ( detail )
491 {
492 append( sb, "Available parameters:", 1 );
493 append( sb, "", 0 );
494
495 append( sb, "detail (Default: false)", 2 );
496 append( sb, "If true, display all settable properties for each goal.", 3 );
497 append( sb, "Expression: ${detail}", 3 );
498 append( sb, "", 0 );
499
500 append( sb, "goal", 2 );
501 append( sb, "The name of the goal for which to show help. If unspecified, all goals will be displayed.", 3 );
502 append( sb, "Expression: ${goal}", 3 );
503 append( sb, "", 0 );
504
505 append( sb, "indentSize (Default: 2)", 2 );
506 append( sb, "The number of spaces per indentation level, should be positive.", 3 );
507 append( sb, "Expression: ${indentSize}", 3 );
508 append( sb, "", 0 );
509
510 append( sb, "lineLength (Default: 80)", 2 );
511 append( sb, "The maximum length of a display line, should be positive.", 3 );
512 append( sb, "Expression: ${lineLength}", 3 );
513 append( sb, "", 0 );
514 }
515 }
516
517 if ( goal == null || goal.length() <= 0 || "jira-report".equals( goal ) )
518 {
519 append( sb, "changes:jira-report", 0 );
520 append( sb, "Goal which downloads issues from the Issue Tracking System and generates a report.", 1 );
521 append( sb, "", 0 );
522 if ( detail )
523 {
524 append( sb, "Available parameters:", 1 );
525 append( sb, "", 0 );
526
527 append( sb, "columnNames (Default: Key,Summary,Status,Resolution,Assignee)", 2 );
528 append( sb, "Sets the names of the columns that you want in the report. The columns will appear in the report in the same order as you specify them here. Multiple values can be separated by commas.\nValid columns are: Assignee, Component, Created, Fix Version, Id, Key, Priority, Reporter, Resolution, Status, Summary, Type, Updated and Version.\n", 3 );
529 append( sb, "", 0 );
530
531 append( sb, "component", 2 );
532 append( sb, "Sets the component(s) that you want to limit your report to include. Multiple values can be separated by commas (such as 10011,10012). If this is set to empty - that means all components will be included.", 3 );
533 append( sb, "", 0 );
534
535 append( sb, "filter", 2 );
536 append( sb, "Defines the filter parameters to restrict which issues are retrieved from JIRA. The filter parameter uses the same format of url parameters that is used in a JIRA search.", 3 );
537 append( sb, "", 0 );
538
539 append( sb, "fixVersionIds", 2 );
540 append( sb, "Sets the fix version id(s) that you want to limit your report to include. These are JIRA\'s internal version ids, NOT the human readable display ones. Multiple fix versions can be separated by commas. If this is set to empty - that means all fix versions will be included.", 3 );
541 append( sb, "", 0 );
542
543 append( sb, "jiraDatePattern (Default: EEE, d MMM yyyy HH:mm:ss Z)", 2 );
544 append( sb, "The pattern used by dates in the JIRA XML-file. This is used to parse the Created and Updated fields.", 3 );
545 append( sb, "", 0 );
546
547 append( sb, "jiraPassword", 2 );
548 append( sb, "Defines the JIRA password for authentication into a private JIRA installation.", 3 );
549 append( sb, "", 0 );
550
551 append( sb, "jiraUser", 2 );
552 append( sb, "Defines the JIRA username for authentication into a private JIRA installation.", 3 );
553 append( sb, "", 0 );
554
555 append( sb, "maxEntries (Default: 100)", 2 );
556 append( sb, "Maximum number of entries to be fetched from JIRA.", 3 );
557 append( sb, "", 0 );
558
559 append( sb, "onlyCurrentVersion (Default: false)", 2 );
560 append( sb, "If you only want to show issues for the current version in the report. The current version being used is ${project.version} minus any \'-SNAPSHOT\' suffix.", 3 );
561 append( sb, "", 0 );
562
563 append( sb, "outputDirectory (Default: ${project.reporting.outputDirectory})", 2 );
564 append( sb, "Report output directory. Note that this parameter is only relevant if the goal is run from the command line or from the default build lifecycle. If the goal is run indirectly as part of a site generation, the output directory configured in the Maven Site Plugin is used instead.", 3 );
565 append( sb, "", 0 );
566
567 append( sb, "outputEncoding (Default: ${project.reporting.outputEncoding})", 2 );
568 append( sb, "Report output encoding. Note that this parameter is only relevant if the goal is run from the command line or from the default build lifecycle. If the goal is run indirectly as part of a site generation, the output encoding configured in the Maven Site Plugin is used instead.", 3 );
569 append( sb, "Expression: ${outputEncoding}", 3 );
570 append( sb, "", 0 );
571
572 append( sb, "priorityIds", 2 );
573 append( sb, "Sets the priority(s) that you want to limit your report to include. Valid statuses are Blocker, Critical, Major, Minor and Trivial. Multiple values can be separated by commas. If this is set to empty - that means all priorities will be included.", 3 );
574 append( sb, "", 0 );
575
576 append( sb, "resolutionIds (Default: Fixed)", 2 );
577 append( sb, "Sets the resolution(s) that you want to fetch from JIRA. Valid resolutions are: Unresolved, Fixed, Won\'t Fix, Duplicate, Incomplete and Cannot Reproduce. Multiple values can be separated by commas.\nNote: In versions 2.0-beta-3 and earlier this parameter had no default value.\n", 3 );
578 append( sb, "", 0 );
579
580 append( sb, "sortColumnNames (Default: Priority DESC, Created DESC)", 2 );
581 append( sb, "Sets the column names that you want to sort the report by. Add DESC following the column name to specify descending sequence. For example Fix Version DESC, Type sorts first by the Fix Version in descending order and then by Type in ascending order. By default sorting is done in ascending order, but is possible to specify ASC for consistency. The previous example would then become Fix Version DESC, Type ASC.\nValid columns are: Assignee, Component, Created, Fix Version, Id, Key, Priority, Reporter, Resolution, Status, Summary, Type, Updated and Version.\n\nNote: If you are using JIRA 4 you need to put your sort column names in the reverse order. The handling of this changed between JIRA 3 and JIRA 4. The current default value is suitable for JIRA 3. This may change in the future, so please configure your sort column names in an order that works for your own JIRA version.\n", 3 );
582 append( sb, "", 0 );
583
584 append( sb, "statusIds (Default: Closed)", 2 );
585 append( sb, "Sets the status(es) that you want to fetch from JIRA. Valid statuses are: Open, In Progress, Reopened, Resolved and Closed. Multiple values can be separated by commas.\nIf your installation of JIRA uses custom status IDs, you can reference them here by their numeric values. You can obtain them on the Statuses page (in 4.0.2 it\'s under Administration > Issue Settings > Statuses) - just hover over the Edit link for the status you want and you\'ll see something like <your JIRA URL>/secure/admin/EditStatus!default.jspa?id=12345; in this case the value is 12345.\n\nNote: In versions 2.0-beta-3 and earlier this parameter had no default value.\n", 3 );
586 append( sb, "", 0 );
587
588 append( sb, "typeIds", 2 );
589 append( sb, "Sets the types(s) that you want to limit your report to include. Valid types are: Bug, New Feature, Task, Improvement, Wish, Test and Sub-task. Multiple values can be separated by commas. If this is set to empty - that means all types will be included.", 3 );
590 append( sb, "", 0 );
591
592 append( sb, "versionPrefix", 2 );
593 append( sb, "The prefix used when naming versions in JIRA.\nIf you have a project in JIRA with several components that have different release cycles, it is an often used pattern to prefix the version with the name of the component, e.g. maven-filtering-1.0 etc. To fetch issues from JIRA for a release of the \'maven-filtering\' component you would need to set this parameter to \'maven-filtering-\'.\n", 3 );
594 append( sb, "", 0 );
595
596 append( sb, "webPassword", 2 );
597 append( sb, "Defines the http password for basic authentication into the JIRA webserver.", 3 );
598 append( sb, "", 0 );
599
600 append( sb, "webUser", 2 );
601 append( sb, "Defines the http user for basic authentication into the JIRA webserver.", 3 );
602 append( sb, "", 0 );
603 }
604 }
605
606 if ( goal == null || goal.length() <= 0 || "trac-report".equals( goal ) )
607 {
608 append( sb, "changes:trac-report", 0 );
609 append( sb, "Goal which downloads issues from the Issue Tracking System and generates a report.", 1 );
610 append( sb, "", 0 );
611 if ( detail )
612 {
613 append( sb, "Available parameters:", 1 );
614 append( sb, "", 0 );
615
616 append( sb, "columnNames (Default: Id,Type,Summary,Assignee,Reporter,Priority,Status,Resolution,Created,Updated)", 2 );
617 append( sb, "Sets the column names that you want to show in the report. The columns will appear in the report in the same order as you specify them here. Multiple values can be separated by commas.\nValid columns are: Assignee, Component, Created, Fix Version, Id, Priority, Reporter, Resolution, Status, Summary, Type and Updated.\n", 3 );
618 append( sb, "", 0 );
619
620 append( sb, "outputDirectory (Default: ${project.reporting.outputDirectory})", 2 );
621 append( sb, "Report output directory. Note that this parameter is only relevant if the goal is run from the command line or from the default build lifecycle. If the goal is run indirectly as part of a site generation, the output directory configured in the Maven Site Plugin is used instead.", 3 );
622 append( sb, "", 0 );
623
624 append( sb, "outputEncoding (Default: ${project.reporting.outputEncoding})", 2 );
625 append( sb, "Report output encoding. Note that this parameter is only relevant if the goal is run from the command line or from the default build lifecycle. If the goal is run indirectly as part of a site generation, the output encoding configured in the Maven Site Plugin is used instead.", 3 );
626 append( sb, "Expression: ${outputEncoding}", 3 );
627 append( sb, "", 0 );
628
629 append( sb, "query (Default: order=id)", 2 );
630 append( sb, "Defines the Trac query for searching ticket.", 3 );
631 append( sb, "", 0 );
632
633 append( sb, "tracPassword", 2 );
634 append( sb, "Defines the Trac password for authentication into a private Trac installation.", 3 );
635 append( sb, "", 0 );
636
637 append( sb, "tracUser", 2 );
638 append( sb, "Defines the Trac username for authentication into a private Trac installation.", 3 );
639 append( sb, "", 0 );
640 }
641 }
642
643 if ( getLog().isInfoEnabled() )
644 {
645 getLog().info( sb.toString() );
646 }
647 }
648
649
650
651
652
653
654
655
656
657
658 private static String repeat( String str, int repeat )
659 {
660 StringBuffer buffer = new StringBuffer( repeat * str.length() );
661
662 for ( int i = 0; i < repeat; i++ )
663 {
664 buffer.append( str );
665 }
666
667 return buffer.toString();
668 }
669
670
671
672
673
674
675
676
677
678 private void append( StringBuffer sb, String description, int indent )
679 {
680 for ( Iterator it = toLines( description, indent, indentSize, lineLength ).iterator(); it.hasNext(); )
681 {
682 sb.append( it.next().toString() ).append( '\n' );
683 }
684 }
685
686
687
688
689
690
691
692
693
694
695
696 private static List toLines( String text, int indent, int indentSize, int lineLength )
697 {
698 List<String> lines = new ArrayList<String>();
699
700 String ind = repeat( "\t", indent );
701 String[] plainLines = text.split( "(\r\n)|(\r)|(\n)" );
702 for ( int i = 0; i < plainLines.length; i++ )
703 {
704 toLines( lines, ind + plainLines[i], indentSize, lineLength );
705 }
706
707 return lines;
708 }
709
710
711
712
713
714
715
716
717
718 private static void toLines( List<String> lines, String line, int indentSize, int lineLength )
719 {
720 int lineIndent = getIndentLevel( line );
721 StringBuffer buf = new StringBuffer( 256 );
722 String[] tokens = line.split( " +" );
723 for ( int i = 0; i < tokens.length; i++ )
724 {
725 String token = tokens[i];
726 if ( i > 0 )
727 {
728 if ( buf.length() + token.length() >= lineLength )
729 {
730 lines.add( buf.toString() );
731 buf.setLength( 0 );
732 buf.append( repeat( " ", lineIndent * indentSize ) );
733 }
734 else
735 {
736 buf.append( ' ' );
737 }
738 }
739 for ( int j = 0; j < token.length(); j++ )
740 {
741 char c = token.charAt( j );
742 if ( c == '\t' )
743 {
744 buf.append( repeat( " ", indentSize - buf.length() % indentSize ) );
745 }
746 else if ( c == '\u00A0' )
747 {
748 buf.append( ' ' );
749 }
750 else
751 {
752 buf.append( c );
753 }
754 }
755 }
756 lines.add( buf.toString() );
757 }
758
759
760
761
762
763
764
765 private static int getIndentLevel( String line )
766 {
767 int level = 0;
768 for ( int i = 0; i < line.length() && line.charAt( i ) == '\t'; i++ )
769 {
770 level++;
771 }
772 for ( int i = level + 1; i <= level + 4 && i < line.length(); i++ )
773 {
774 if ( line.charAt( i ) == '\t' )
775 {
776 level++;
777 break;
778 }
779 }
780 return level;
781 }
782 }