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 public class HelpMojo
20 extends AbstractMojo
21 {
22
23
24
25
26
27 private boolean detail;
28
29
30
31
32
33
34 private java.lang.String goal;
35
36
37
38
39
40
41 private int lineLength;
42
43
44
45
46
47
48 private int indentSize;
49
50
51
52 public void execute()
53 throws MojoExecutionException
54 {
55 if ( lineLength <= 0 )
56 {
57 getLog().warn( "The parameter 'lineLength' should be positive, using '80' as default." );
58 lineLength = 80;
59 }
60 if ( indentSize <= 0 )
61 {
62 getLog().warn( "The parameter 'indentSize' should be positive, using '2' as default." );
63 indentSize = 2;
64 }
65
66 StringBuffer sb = new StringBuffer();
67
68 append( sb, "org.apache.maven.plugins:maven-changes-plugin:2.5", 0 );
69 append( sb, "", 0 );
70
71 append( sb, "Maven Changes Report Plugin", 0 );
72 append( sb, "Creates a release history for inclusion into the site and assists in generating an announcement mail.", 1 );
73 append( sb, "", 0 );
74
75 if ( goal == null || goal.length() <= 0 )
76 {
77 append( sb, "This plugin has 8 goals:", 0 );
78 append( sb, "", 0 );
79 }
80
81 if ( goal == null || goal.length() <= 0 || "announcement-generate".equals( goal ) )
82 {
83 append( sb, "changes:announcement-generate", 0 );
84 append( sb, "Goal which generate the template for an announcement.", 1 );
85 append( sb, "", 0 );
86 if ( detail )
87 {
88 append( sb, "Available parameters:", 1 );
89 append( sb, "", 0 );
90
91 append( sb, "announcementFile", 2 );
92 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 );
93 append( sb, "Expression: ${changes.announcementFile}", 3 );
94 append( sb, "", 0 );
95
96 append( sb, "announceParameters", 2 );
97 append( sb, "Map of custom parameters for the announcement. This Map will be passed to the template.", 3 );
98 append( sb, "", 0 );
99
100 append( sb, "basedir", 2 );
101 append( sb, "The current project base directory.", 3 );
102 append( sb, "Required: Yes", 3 );
103 append( sb, "Expression: ${basedir}", 3 );
104 append( sb, "", 0 );
105
106 append( sb, "developmentTeam (Default: ${project.name} team)", 2 );
107 append( sb, "Name of the team that develops the artifact. This parameter will be passed to the template.", 3 );
108 append( sb, "Required: Yes", 3 );
109 append( sb, "Expression: ${changes.developmentTeam}", 3 );
110 append( sb, "", 0 );
111
112 append( sb, "filter", 2 );
113 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 );
114 append( sb, "", 0 );
115
116 append( sb, "finalName (Default: ${project.build.finalName})", 2 );
117 append( sb, "The name of the artifact to be used in the announcement.", 3 );
118 append( sb, "Required: Yes", 3 );
119 append( sb, "Expression: ${changes.finalName}", 3 );
120 append( sb, "", 0 );
121
122 append( sb, "generateJiraAnnouncement (Default: false)", 2 );
123 append( sb, "Deprecated. Since version 2.4 this parameter has been deprecated. Please use the issueManagementSystems parameter instead.", 3 );
124 append( sb, "", 0 );
125 append( sb, "Flag to determine if the plugin will generate a JIRA announcement.", 3 );
126 append( sb, "Required: Yes", 3 );
127 append( sb, "Expression: ${generateJiraAnnouncement}", 3 );
128 append( sb, "", 0 );
129
130 append( sb, "introduction (Default: ${project.description})", 2 );
131 append( sb, "Short description or introduction of the released artifact. This parameter will be passed to the template.", 3 );
132 append( sb, "", 0 );
133
134 append( sb, "issueManagementSystems", 2 );
135 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 );
136 append( sb, "", 0 );
137
138 append( sb, "jiraMerge (Default: false)", 2 );
139 append( sb, "Deprecated. Since version 2.4 this parameter has been deprecated. Please use the issueManagementSystems parameter instead.", 3 );
140 append( sb, "", 0 );
141 append( sb, "If releases from JIRA should be merged with the releases from a changes.xml file.", 3 );
142 append( sb, "Expression: ${changes.jiraMerge}", 3 );
143 append( sb, "", 0 );
144
145 append( sb, "jiraPassword", 2 );
146 append( sb, "Defines the JIRA password for authentication into a private JIRA installation.", 3 );
147 append( sb, "Expression: ${changes.jiraPassword}", 3 );
148 append( sb, "", 0 );
149
150 append( sb, "jiraUser", 2 );
151 append( sb, "Defines the JIRA username for authentication into a private JIRA installation.", 3 );
152 append( sb, "Expression: ${changes.jiraUser}", 3 );
153 append( sb, "", 0 );
154
155 append( sb, "maxEntries (Default: 25)", 2 );
156 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 );
157 append( sb, "Required: Yes", 3 );
158 append( sb, "Expression: ${changes.maxEntries}", 3 );
159 append( sb, "", 0 );
160
161 append( sb, "outputDirectory", 2 );
162 append( sb, "Directory where the template file will be generated.", 3 );
163 append( sb, "Required: Yes", 3 );
164 append( sb, "Expression: ${project.build.directory}/announcement", 3 );
165 append( sb, "", 0 );
166
167 append( sb, "resolutionIds (Default: Fixed)", 2 );
168 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 );
169 append( sb, "Expression: ${changes.resolutionIds}", 3 );
170 append( sb, "", 0 );
171
172 append( sb, "runOnlyAtExecutionRoot (Default: false)", 2 );
173 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 );
174 append( sb, "Expression: ${announcement.runOnlyAtExecutionRoot}", 3 );
175 append( sb, "", 0 );
176
177 append( sb, "statusIds (Default: Closed)", 2 );
178 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 );
179 append( sb, "Expression: ${changes.statusIds}", 3 );
180 append( sb, "", 0 );
181
182 append( sb, "template (Default: announcement.vm)", 2 );
183 append( sb, "The Velocity template used to format the announcement.", 3 );
184 append( sb, "Required: Yes", 3 );
185 append( sb, "Expression: ${changes.template}", 3 );
186 append( sb, "", 0 );
187
188 append( sb, "templateDirectory (Default: org/apache/maven/plugin/announcement)", 2 );
189 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 );
190 append( sb, "Required: Yes", 3 );
191 append( sb, "Expression: ${changes.templateDirectory}", 3 );
192 append( sb, "", 0 );
193
194 append( sb, "templateEncoding (Default: ${project.build.sourceEncoding})", 2 );
195 append( sb, "The template encoding.", 3 );
196 append( sb, "Expression: ${changes.templateEncoding}", 3 );
197 append( sb, "", 0 );
198
199 append( sb, "tracPassword", 2 );
200 append( sb, "Defines the Trac password for authentication into a private Trac installation.", 3 );
201 append( sb, "Expression: ${changes.tracPassword}", 3 );
202 append( sb, "", 0 );
203
204 append( sb, "tracQuery (Default: order=id)", 2 );
205 append( sb, "Defines the Trac query for searching for tickets.", 3 );
206 append( sb, "", 0 );
207
208 append( sb, "tracUser", 2 );
209 append( sb, "Defines the Trac username for authentication into a private Trac installation.", 3 );
210 append( sb, "Expression: ${changes.tracUser}", 3 );
211 append( sb, "", 0 );
212
213 append( sb, "url", 2 );
214 append( sb, "Distribution URL of the artifact. This parameter will be passed to the template.", 3 );
215 append( sb, "Expression: ${project.url}", 3 );
216 append( sb, "", 0 );
217
218 append( sb, "urlDownload", 2 );
219 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 );
220 append( sb, "", 0 );
221
222 append( sb, "version (Default: ${project.version})", 2 );
223 append( sb, "Version of the artifact.", 3 );
224 append( sb, "Required: Yes", 3 );
225 append( sb, "Expression: ${changes.version}", 3 );
226 append( sb, "", 0 );
227
228 append( sb, "versionPrefix", 2 );
229 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 );
230 append( sb, "", 0 );
231
232 append( sb, "webPassword", 2 );
233 append( sb, "Defines the http password for basic authentication into the JIRA webserver.", 3 );
234 append( sb, "", 0 );
235
236 append( sb, "webUser", 2 );
237 append( sb, "Defines the http user for basic authentication into the JIRA webserver.", 3 );
238 append( sb, "", 0 );
239
240 append( sb, "xmlPath", 2 );
241 append( sb, "The path of the changes.xml file.", 3 );
242 append( sb, "Required: Yes", 3 );
243 append( sb, "Expression: ${basedir}/src/changes/changes.xml", 3 );
244 append( sb, "", 0 );
245 }
246 }
247
248 if ( goal == null || goal.length() <= 0 || "announcement-mail".equals( goal ) )
249 {
250 append( sb, "changes:announcement-mail", 0 );
251 append( sb, "Goal which sends an announcement through email.", 1 );
252 append( sb, "", 0 );
253 if ( detail )
254 {
255 append( sb, "Available parameters:", 1 );
256 append( sb, "", 0 );
257
258 append( sb, "basedir", 2 );
259 append( sb, "The current project base directory.", 3 );
260 append( sb, "Required: Yes", 3 );
261 append( sb, "Expression: ${basedir}", 3 );
262 append( sb, "", 0 );
263
264 append( sb, "bccAddresses", 2 );
265 append( sb, "Recipient bcc email address.", 3 );
266 append( sb, "Required: Yes", 3 );
267 append( sb, "", 0 );
268
269 append( sb, "ccAddresses", 2 );
270 append( sb, "Recipient cc email address.", 3 );
271 append( sb, "Required: Yes", 3 );
272 append( sb, "", 0 );
273
274 append( sb, "fromDeveloperId", 2 );
275 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 );
276 append( sb, "Expression: ${changes.fromDeveloperId}", 3 );
277 append( sb, "", 0 );
278
279 append( sb, "mailContentType (Default: text/plain)", 2 );
280 append( sb, "Mail content type to use.", 3 );
281 append( sb, "Required: Yes", 3 );
282 append( sb, "", 0 );
283
284 append( sb, "mailSender", 2 );
285 append( sb, "Defines the sender of the announcement if the list of developer is empty or if the sender is not a member of the development team.", 3 );
286 append( sb, "Expression: ${changes.mailSender}", 3 );
287 append( sb, "", 0 );
288
289 append( sb, "password", 2 );
290 append( sb, "The password used to send the email.", 3 );
291 append( sb, "Expression: ${changes.password}", 3 );
292 append( sb, "", 0 );
293
294 append( sb, "runOnlyAtExecutionRoot (Default: false)", 2 );
295 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 );
296 append( sb, "Expression: ${announcement.runOnlyAtExecutionRoot}", 3 );
297 append( sb, "", 0 );
298
299 append( sb, "smtpHost", 2 );
300 append( sb, "Smtp Server.", 3 );
301 append( sb, "Required: Yes", 3 );
302 append( sb, "Expression: ${changes.smtpHost}", 3 );
303 append( sb, "", 0 );
304
305 append( sb, "smtpPort (Default: 25)", 2 );
306 append( sb, "Port.", 3 );
307 append( sb, "Required: Yes", 3 );
308 append( sb, "Expression: ${changes.smtpPort}", 3 );
309 append( sb, "", 0 );
310
311 append( sb, "sslMode (Default: false)", 2 );
312 append( sb, "If the email should be sent in SSL mode.", 3 );
313 append( sb, "Expression: ${changes.sslMode}", 3 );
314 append( sb, "", 0 );
315
316 append( sb, "subject (Default: [ANNOUNCEMENT] - ${project.name} ${project.version} released)", 2 );
317 append( sb, "Subject for the email.", 3 );
318 append( sb, "Required: Yes", 3 );
319 append( sb, "Expression: ${changes.subject}", 3 );
320 append( sb, "", 0 );
321
322 append( sb, "template (Default: announcement.vm)", 2 );
323 append( sb, "The Velocity template used to format the announcement.", 3 );
324 append( sb, "Required: Yes", 3 );
325 append( sb, "Expression: ${changes.template}", 3 );
326 append( sb, "", 0 );
327
328 append( sb, "templateOutputDirectory", 2 );
329 append( sb, "Directory which contains the template for announcement email.", 3 );
330 append( sb, "Required: Yes", 3 );
331 append( sb, "Expression: ${project.build.directory}/announcement", 3 );
332 append( sb, "", 0 );
333
334 append( sb, "toAddresses", 2 );
335 append( sb, "Recipient email address.", 3 );
336 append( sb, "Required: Yes", 3 );
337 append( sb, "", 0 );
338
339 append( sb, "username", 2 );
340 append( sb, "The username used to send the email.", 3 );
341 append( sb, "Expression: ${changes.username}", 3 );
342 append( sb, "", 0 );
343 }
344 }
345
346 if ( goal == null || goal.length() <= 0 || "changes-check".equals( goal ) )
347 {
348 append( sb, "changes:changes-check", 0 );
349 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 );
350 append( sb, "", 0 );
351 if ( detail )
352 {
353 append( sb, "Available parameters:", 1 );
354 append( sb, "", 0 );
355
356 append( sb, "releaseDateFormat (Default: yyyy-MM-dd)", 2 );
357 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 );
358 append( sb, "Expression: ${changes.releaseDateFormat}", 3 );
359 append( sb, "", 0 );
360
361 append( sb, "version (Default: ${project.version})", 2 );
362 append( sb, "Version of the artifact.", 3 );
363 append( sb, "Required: Yes", 3 );
364 append( sb, "Expression: ${changes.version}", 3 );
365 append( sb, "", 0 );
366
367 append( sb, "xmlPath (Default: src/changes/changes.xml)", 2 );
368 append( sb, "The path of the changes.xml file that will be checked.", 3 );
369 append( sb, "Expression: ${changes.xmlPath}", 3 );
370 append( sb, "", 0 );
371 }
372 }
373
374 if ( goal == null || goal.length() <= 0 || "changes-report".equals( goal ) )
375 {
376 append( sb, "changes:changes-report", 0 );
377 append( sb, "Goal which creates a nicely formatted Changes Report in html format from a changes.xml file.", 1 );
378 append( sb, "", 0 );
379 if ( detail )
380 {
381 append( sb, "Available parameters:", 1 );
382 append( sb, "", 0 );
383
384 append( sb, "addActionDate (Default: false)", 2 );
385 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 );
386 append( sb, "Expression: ${changes.addActionDate}", 3 );
387 append( sb, "", 0 );
388
389 append( sb, "escapeHTML (Default: true)", 2 );
390 append( sb, "Deprecated. using markup inside CDATA sections does not work for all output formats!", 3 );
391 append( sb, "", 0 );
392 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 );
393 append( sb, "", 0 );
394
395 append( sb, "filteringChanges (Default: false)", 2 );
396 append( sb, "applying filtering filtering \'a la\' resources plugin", 3 );
397 append( sb, "", 0 );
398
399 append( sb, "issueLinkTemplate (Default: %URL%/ViewIssue.jspa?key=%ISSUE%)", 2 );
400 append( sb, "Deprecated. As of 2.1 use issueLinkTemplatePerSystem : this one will be with system default", 3 );
401 append( sb, "", 0 );
402 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 );
403 append( sb, "Expression: ${changes.issueLinkTemplate}", 3 );
404 append( sb, "", 0 );
405
406 append( sb, "issueLinkTemplatePerSystem", 2 );
407 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 );
408 append( sb, "", 0 );
409
410 append( sb, "outputDirectory (Default: ${project.reporting.outputDirectory})", 2 );
411 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 );
412 append( sb, "", 0 );
413
414 append( sb, "outputEncoding (Default: ${project.reporting.outputEncoding})", 2 );
415 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 );
416 append( sb, "Expression: ${outputEncoding}", 3 );
417 append( sb, "", 0 );
418
419 append( sb, "publishDateFormat (Default: yyyy-MM-dd)", 2 );
420 append( sb, "Format to use for publishDate. The value will be available with the following expression ${publishDate}", 3 );
421 append( sb, "", 0 );
422
423 append( sb, "publishDateLocale (Default: en)", 2 );
424 append( sb, "Locale to use for publishDate when formatting", 3 );
425 append( sb, "", 0 );
426
427 append( sb, "teamlist (Default: team-list.html)", 2 );
428 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 );
429 append( sb, "", 0 );
430
431 append( sb, "xmlPath (Default: src/changes/changes.xml)", 2 );
432 append( sb, "The path of the changes.xml file that will be converted into an HTML report.", 3 );
433 append( sb, "Expression: ${changes.xmlPath}", 3 );
434 append( sb, "", 0 );
435 }
436 }
437
438 if ( goal == null || goal.length() <= 0 || "changes-validate".equals( goal ) )
439 {
440 append( sb, "changes:changes-validate", 0 );
441 append( sb, "Goal which validate the changes.xml file.", 1 );
442 append( sb, "", 0 );
443 if ( detail )
444 {
445 append( sb, "Available parameters:", 1 );
446 append( sb, "", 0 );
447
448 append( sb, "changesXsdVersion (Default: 1.0.0)", 2 );
449 append( sb, "The changes xsd version.", 3 );
450 append( sb, "Expression: ${changes.xsdVersion}", 3 );
451 append( sb, "", 0 );
452
453 append( sb, "failOnError (Default: false)", 2 );
454 append( sb, "Mojo failure if validation failed. If not and validation failed only a warning will be logged.", 3 );
455 append( sb, "Expression: ${changes.validate.failed}", 3 );
456 append( sb, "", 0 );
457
458 append( sb, "xmlPath (Default: src/changes/changes.xml)", 2 );
459 append( sb, "The path of the changes.xml file that will be converted into an HTML report.", 3 );
460 append( sb, "Expression: ${changes.xmlPath}", 3 );
461 append( sb, "", 0 );
462 }
463 }
464
465 if ( goal == null || goal.length() <= 0 || "help".equals( goal ) )
466 {
467 append( sb, "changes:help", 0 );
468 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 );
469 append( sb, "", 0 );
470 if ( detail )
471 {
472 append( sb, "Available parameters:", 1 );
473 append( sb, "", 0 );
474
475 append( sb, "detail (Default: false)", 2 );
476 append( sb, "If true, display all settable properties for each goal.", 3 );
477 append( sb, "Expression: ${detail}", 3 );
478 append( sb, "", 0 );
479
480 append( sb, "goal", 2 );
481 append( sb, "The name of the goal for which to show help. If unspecified, all goals will be displayed.", 3 );
482 append( sb, "Expression: ${goal}", 3 );
483 append( sb, "", 0 );
484
485 append( sb, "indentSize (Default: 2)", 2 );
486 append( sb, "The number of spaces per indentation level, should be positive.", 3 );
487 append( sb, "Expression: ${indentSize}", 3 );
488 append( sb, "", 0 );
489
490 append( sb, "lineLength (Default: 80)", 2 );
491 append( sb, "The maximum length of a display line, should be positive.", 3 );
492 append( sb, "Expression: ${lineLength}", 3 );
493 append( sb, "", 0 );
494 }
495 }
496
497 if ( goal == null || goal.length() <= 0 || "jira-report".equals( goal ) )
498 {
499 append( sb, "changes:jira-report", 0 );
500 append( sb, "Goal which downloads issues from the Issue Tracking System and generates a report.", 1 );
501 append( sb, "", 0 );
502 if ( detail )
503 {
504 append( sb, "Available parameters:", 1 );
505 append( sb, "", 0 );
506
507 append( sb, "columnNames (Default: Key,Summary,Status,Resolution,Assignee)", 2 );
508 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 );
509 append( sb, "", 0 );
510
511 append( sb, "component", 2 );
512 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 );
513 append( sb, "", 0 );
514
515 append( sb, "filter", 2 );
516 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 );
517 append( sb, "", 0 );
518
519 append( sb, "fixVersionIds", 2 );
520 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 );
521 append( sb, "", 0 );
522
523 append( sb, "jiraDatePattern (Default: EEE, d MMM yyyy HH:mm:ss Z)", 2 );
524 append( sb, "The pattern used by dates in the JIRA XML-file. This is used to parse the Created and Updated fields.", 3 );
525 append( sb, "", 0 );
526
527 append( sb, "jiraPassword", 2 );
528 append( sb, "Defines the JIRA password for authentication into a private JIRA installation.", 3 );
529 append( sb, "", 0 );
530
531 append( sb, "jiraUser", 2 );
532 append( sb, "Defines the JIRA username for authentication into a private JIRA installation.", 3 );
533 append( sb, "", 0 );
534
535 append( sb, "maxEntries (Default: 100)", 2 );
536 append( sb, "Maximum number of entries to be fetched from JIRA.", 3 );
537 append( sb, "", 0 );
538
539 append( sb, "onlyCurrentVersion (Default: false)", 2 );
540 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 );
541 append( sb, "", 0 );
542
543 append( sb, "outputDirectory (Default: ${project.reporting.outputDirectory})", 2 );
544 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 );
545 append( sb, "", 0 );
546
547 append( sb, "outputEncoding (Default: ${project.reporting.outputEncoding})", 2 );
548 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 );
549 append( sb, "Expression: ${outputEncoding}", 3 );
550 append( sb, "", 0 );
551
552 append( sb, "priorityIds", 2 );
553 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 );
554 append( sb, "", 0 );
555
556 append( sb, "resolutionIds (Default: Fixed)", 2 );
557 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 );
558 append( sb, "", 0 );
559
560 append( sb, "sortColumnNames (Default: Priority DESC, Created DESC)", 2 );
561 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 );
562 append( sb, "", 0 );
563
564 append( sb, "statusIds (Default: Closed)", 2 );
565 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.\nNote: In versions 2.0-beta-3 and earlier this parameter had no default value.\n", 3 );
566 append( sb, "", 0 );
567
568 append( sb, "typeIds", 2 );
569 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 );
570 append( sb, "", 0 );
571
572 append( sb, "versionPrefix", 2 );
573 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 );
574 append( sb, "", 0 );
575
576 append( sb, "webPassword", 2 );
577 append( sb, "Defines the http password for basic authentication into the JIRA webserver.", 3 );
578 append( sb, "", 0 );
579
580 append( sb, "webUser", 2 );
581 append( sb, "Defines the http user for basic authentication into the JIRA webserver.", 3 );
582 append( sb, "", 0 );
583 }
584 }
585
586 if ( goal == null || goal.length() <= 0 || "trac-report".equals( goal ) )
587 {
588 append( sb, "changes:trac-report", 0 );
589 append( sb, "Goal which downloads issues from the Issue Tracking System and generates a report.", 1 );
590 append( sb, "", 0 );
591 if ( detail )
592 {
593 append( sb, "Available parameters:", 1 );
594 append( sb, "", 0 );
595
596 append( sb, "columnNames (Default: Id,Type,Summary,Assignee,Reporter,Priority,Status,Resolution,Created,Updated)", 2 );
597 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 );
598 append( sb, "", 0 );
599
600 append( sb, "outputDirectory (Default: ${project.reporting.outputDirectory})", 2 );
601 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 );
602 append( sb, "", 0 );
603
604 append( sb, "outputEncoding (Default: ${project.reporting.outputEncoding})", 2 );
605 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 );
606 append( sb, "Expression: ${outputEncoding}", 3 );
607 append( sb, "", 0 );
608
609 append( sb, "query (Default: order=id)", 2 );
610 append( sb, "Defines the Trac query for searching ticket.", 3 );
611 append( sb, "", 0 );
612
613 append( sb, "tracPassword", 2 );
614 append( sb, "Defines the Trac password for authentication into a private Trac installation.", 3 );
615 append( sb, "", 0 );
616
617 append( sb, "tracUser", 2 );
618 append( sb, "Defines the Trac username for authentication into a private Trac installation.", 3 );
619 append( sb, "", 0 );
620 }
621 }
622
623 if ( getLog().isInfoEnabled() )
624 {
625 getLog().info( sb.toString() );
626 }
627 }
628
629
630
631
632
633
634
635
636
637
638 private static String repeat( String str, int repeat )
639 {
640 StringBuffer buffer = new StringBuffer( repeat * str.length() );
641
642 for ( int i = 0; i < repeat; i++ )
643 {
644 buffer.append( str );
645 }
646
647 return buffer.toString();
648 }
649
650
651
652
653
654
655
656
657
658 private void append( StringBuffer sb, String description, int indent )
659 {
660 for ( Iterator it = toLines( description, indent, indentSize, lineLength ).iterator(); it.hasNext(); )
661 {
662 sb.append( it.next().toString() ).append( '\n' );
663 }
664 }
665
666
667
668
669
670
671
672
673
674
675
676 private static List toLines( String text, int indent, int indentSize, int lineLength )
677 {
678 List lines = new ArrayList();
679
680 String ind = repeat( "\t", indent );
681 String[] plainLines = text.split( "(\r\n)|(\r)|(\n)" );
682 for ( int i = 0; i < plainLines.length; i++ )
683 {
684 toLines( lines, ind + plainLines[i], indentSize, lineLength );
685 }
686
687 return lines;
688 }
689
690
691
692
693
694
695
696
697
698 private static void toLines( List lines, String line, int indentSize, int lineLength )
699 {
700 int lineIndent = getIndentLevel( line );
701 StringBuffer buf = new StringBuffer( 256 );
702 String[] tokens = line.split( " +" );
703 for ( int i = 0; i < tokens.length; i++ )
704 {
705 String token = tokens[i];
706 if ( i > 0 )
707 {
708 if ( buf.length() + token.length() >= lineLength )
709 {
710 lines.add( buf.toString() );
711 buf.setLength( 0 );
712 buf.append( repeat( " ", lineIndent * indentSize ) );
713 }
714 else
715 {
716 buf.append( ' ' );
717 }
718 }
719 for ( int j = 0; j < token.length(); j++ )
720 {
721 char c = token.charAt( j );
722 if ( c == '\t' )
723 {
724 buf.append( repeat( " ", indentSize - buf.length() % indentSize ) );
725 }
726 else if ( c == '\u00A0' )
727 {
728 buf.append( ' ' );
729 }
730 else
731 {
732 buf.append( c );
733 }
734 }
735 }
736 lines.add( buf.toString() );
737 }
738
739
740
741
742
743
744
745 private static int getIndentLevel( String line )
746 {
747 int level = 0;
748 for ( int i = 0; i < line.length() && line.charAt( i ) == '\t'; i++ )
749 {
750 level++;
751 }
752 for ( int i = level + 1; i <= level + 4 && i < line.length(); i++ )
753 {
754 if ( line.charAt( i ) == '\t' )
755 {
756 level++;
757 break;
758 }
759 }
760 return level;
761 }
762 }