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