27 | | my $parrotdir = File::Spec->curdir(); |
28 | | my ( %opts, %parrot, %report ); |
29 | | my ( $editor, $user, $domain, $msgid, $tmpfile ); |
30 | | my ( $is_linux, $is_macos, $is_mswin32, $is_os2, $is_vms ); |
31 | | my @categories = qw[ core docs install library utilities languages ]; |
32 | | my @severities = qw[ critical high medium low wishlist none ]; |
33 | | |
34 | | |
35 | | #------------------------------------------------------------# |
36 | | # Main program. # |
37 | | |
38 | | init(); |
39 | | help() if $opts{help}; |
40 | | version() if $opts{version}; |
41 | | explain_parrotbug() unless $opts{quiet}; |
42 | | query_missing_info(); |
43 | | what_next(); |
44 | | unlink $tmpfile; |
45 | | exit; |
46 | | |
47 | | |
48 | | |
49 | | # Explain what C<parrotbug> is. |
50 | | sub explain_parrotbug { |
51 | | print <<EOT; |
52 | | |
53 | | This program provides an easy way to create a message reporting a bug |
54 | | in parrot, and e-mail it to the parrot developers. |
55 | | |
56 | | It is *NOT* intended for: |
57 | | - sending test messages, |
58 | | - or reporting bugs in languages targetting parrot, |
59 | | - or reporting bugs in some library bindings for parrot, |
60 | | - or simply verifying that parrot works. |
61 | | |
62 | | It is *ONLY* a mean of reporting verifiable problems with the core |
63 | | parrot distribution, and any solutions to such problems, to parrot |
64 | | developers. |
65 | | |
66 | | If you're just looking for help with parrot, subscribe to the parrot |
67 | | mailing list, parrot-dev<at>lists.parrot.org. |
68 | | |
69 | | |
70 | | |
71 | | EOT |
72 | | } |
73 | | |
74 | | |
75 | | |
76 | | |
77 | | #------------------------------------------------------------# |
78 | | # Utils subs. # |
79 | | |
80 | | # Generate random filename to edit report. |
81 | | sub generate_filename { |
82 | | my $dir = File::Spec->tmpdir(); |
83 | | my $filename = "bugrep0$$"; |
84 | | $filename++ while -e File::Spec->catfile($dir, $filename); |
85 | | $filename = File::Spec->catfile($dir, $filename); |
86 | | return $filename; |
87 | | } |
88 | | |
89 | | |
90 | | # Check whether a subject is trivial. A subject is not considered trivial |
91 | | # if it's an ok or a nok report. |
92 | | # Return 1 if trivial, 0 otherwise (subject acceptable). |
93 | | sub trivial_subject { |
94 | | my $subject = shift; |
95 | | |
96 | | return 0 if $opts{ok} || $opts{nok}; |
97 | | if ( $subject =~ |
98 | | /^(y(es)?|no?|help|parrot( (bug|problem))?|bug|problem)$/i || |
99 | | length($subject) < 4 || |
100 | | $subject !~ /\s/ ) { |
101 | | return 1; |
102 | | } |
103 | | else { |
104 | | return 0; |
105 | | } |
106 | | } |
107 | | |
108 | | |
109 | | |
110 | | |
111 | | #------------------------------------------------------------# |
112 | | # Init subs. # |
113 | | |
114 | | # Initialize the program. |
115 | | # |
116 | | # Get parrot information, process the options, create the message |
117 | | # information (subject, to, body, etc.) depending on the type of report |
118 | | # (ok, nok or bug report). |
119 | | sub init { |
120 | | $is_linux = lc($^O) eq 'linux'; |
121 | | $is_mswin32 = $^O eq 'MSWin32'; |
122 | | $is_os2 = $^O eq 'os2'; |
123 | | $is_vms = $^O eq 'VMS'; |
124 | | |
125 | | ## |
126 | | ## Fetch Parrot information. |
127 | | ## |
128 | | |
129 | | # Get parrot version. |
130 | | # There will always be an up-to-date $parrot/VERSION |
131 | | my $filename = File::Spec->catfile($parrotdir, "VERSION"); |
132 | | open(VERSION, "<$filename") or die "Cannot open '$filename': $!"; |
133 | | $parrot{version} = <VERSION>; |
134 | | chomp $parrot{version}; |
135 | | close(VERSION) or die "Cannot close '$filename': $!"; |
136 | | |
137 | | # Get parrot configuration, stored in $parrot/myconfig |
138 | | $filename = File::Spec->catfile($parrotdir, "myconfig"); |
139 | | open(MYCONFIG, "<$filename") or die "Cannot open '$filename': $!"; |
140 | | { |
141 | | local $/; |
142 | | $parrot{myconfig} = <MYCONFIG>; |
143 | | } |
144 | | close(MYCONFIG) or die "Cannot close '$filename': $!"; |
145 | | |
146 | | |
147 | | ## |
148 | | ## Process options. |
149 | | ## |
150 | | Getopt::Long::Configure("no_bundling", "no_ignore_case", "auto_abbrev"); |
151 | | help() unless GetOptions |
152 | | ( \%opts, |
153 | | "help|h", "version|V", |
154 | | "send", "dump", "save", |
155 | | "from|f=s", "to|test|t=s", "editor|e=s", |
156 | | "subject|s=s", "category|C=s", "severity|S=s", |
157 | | "input|input-file|i=s", "output|output-file|o=s", |
158 | | "ok", "nok", "ack!", "quiet|q!" ); |
159 | | |
160 | | ## |
161 | | ## Report to be sent. |
162 | | ## |
163 | | sw: { |
164 | | ok_report: { |
165 | | last ok_report unless defined $opts{ok}; |
166 | | |
167 | | # This is an ok report, woohoo! |
168 | | $report{to} = $std_to{ok}; |
169 | | $report{subject} = "OK: parrot $parrot{version} " |
170 | | . "on $Config{archname} $Config{osvers}"; |
171 | | $report{body} = "Parrot reported to build OK on this system.\n"; |
172 | | $report{category} = "install"; |
173 | | $report{severity} = "none"; |
174 | | $report{body} = ""; |
175 | | last sw; |
176 | | }; |
177 | | |
178 | | # Ok reports do not need body, but nok and bug reports do need |
179 | | # a body. |
180 | | if ( $opts{input} ) { |
181 | | # Report was pre-written, slurp it. |
182 | | open BODY, "<$opts{input}" or die "Can't open '$opts{input}': $!"; |
183 | | local $/; |
184 | | $report{body} = <BODY>; |
185 | | close BODY or die "Can't close '$opts{input}': $!"; |
186 | | } |
187 | | else { |
188 | | # No file provided... |
189 | | $report{body} = ""; |
190 | | } |
191 | | |
192 | | nok_report: { |
193 | | last nok_report unless defined $opts{nok}; |
194 | | |
195 | | # This a nok report, how sad... :-( |
196 | | $report{to} = $std_to{nok}; |
197 | | $report{subject} = "Not OK: parrot $parrot{version} " |
198 | | . "on $Config{archname} $Config{osvers}"; |
199 | | $report{category} = "install"; |
200 | | $report{severity} = "none"; |
201 | | last sw; |
202 | | }; |
203 | | |
204 | | # Neither an ok nor a nok. |
205 | | $report{to} = $std_to{bug}; |
206 | | $report{subject} = $opts{subject} || ""; |
207 | | $report{category} = $opts{category} || ""; |
208 | | $report{severity} = $opts{severity} || ""; |
209 | | }; |
210 | | |
211 | | # Test message, shortcuting recipent. |
212 | | $report{to} = $opts{to} if $opts{to}; |
213 | | |
214 | | ## |
215 | | ## User information. |
216 | | ## |
217 | | |
218 | | # Username. |
219 | | $user = $is_mswin32 ? $ENV{USERNAME} |
220 | | : $is_os2 ? $ENV{USER} || $ENV{LOGNAME} |
221 | | : $is_macos ? $ENV{USER} |
222 | | : eval { getpwuid($<) }; # May be missing |
223 | | |
224 | | # User address, used in message and in Reply-To header. |
225 | | $report{from} = $opts{from} || ""; |
226 | | |
227 | | # Editor |
228 | | $editor = $ENV{VISUAL} || $ENV{EDITOR} || $ENV{EDIT} |
229 | | || ( $is_vms && "edit/tpu" ) |
230 | | || ( $is_mswin32 && "notepad" ) |
231 | | || ( $is_macos && "" ) |
232 | | || "vi"; |
233 | | |
234 | | |
235 | | ## |
236 | | ## Mail information. |
237 | | ## |
238 | | |
239 | | # Message-Id. |
240 | | eval "use Mail::Util;"; |
241 | | if ( $@ eq "" ) { |
242 | | $domain = Mail::Util::maildomain(); |
243 | | } |
244 | | elsif ($is_mswin32) { |
245 | | $domain = $ENV{USERDOMAIN}; |
246 | | } |
247 | | else { |
248 | | require Sys::Hostname; |
249 | | $domain = Sys::Hostname::hostname(); |
250 | | } |
251 | | $msgid = "<parrotbug_${VERSION}_${$}_".time."\@$domain>"; |
252 | | } |
253 | | |
254 | | |
255 | | |
256 | | #------------------------------------------------------------# |
257 | | # Querying subs. # |
258 | | |
259 | | # Query missing information in order to have a complete report. |
260 | | sub query_missing_info { |
261 | | $report{subject} = "" if trivial_subject( $report{subject} ); |
262 | | $report{subject} = ask_for_subject() unless $report{subject}; |
263 | | $report{category} = ask_for_alternative( "category", \@categories) |
264 | | unless $report{category}; |
265 | | $report{severity} = ask_for_alternative( "severity", \@severities) |
266 | | unless $report{severity}; |
267 | | $report{from} = ask_for_return_address() unless $report{from}; |
268 | | $report{body} = ask_for_body() unless $report{body}; |
269 | | } |
270 | | |
271 | | |
272 | | # Prompt for alternatives from a set of choices. |
273 | | # |
274 | | # The arguments are: the name of alternative, the choices (as an array |
275 | | # ref), and the default answer. (first element if undef) |
276 | | # |
277 | | # Return the lowercased alternative chosen. |
278 | | # |
279 | | # Die if more than 5 wrong answers. |
280 | | sub ask_for_alternative { |
281 | | my ( $what, $choices, $default ) = @_; |
282 | | |
283 | | print <<EOT unless $opts{quiet}; |
284 | | Please pick a $what from the following: |
285 | | @{$choices} |
286 | | |
287 | | EOT |
288 | | |
289 | | $default ||= $choices->[0]; |
290 | | my $alt; |
291 | | my $err = 0; |
292 | | do { |
293 | | die "Invalid $alt: aborting.\n" if $err++ > 5; |
294 | | print "Please enter a $what [$default]: "; |
295 | | $alt = <STDIN>; |
296 | | chomp $alt; |
297 | | $alt = $default if $alt =~ /^\s*$/; |
298 | | } until ( ($alt) = grep /^$alt/i, @$choices ); |
299 | | |
300 | | print "\n\n\n"; |
301 | | return lc $alt; |
302 | | } |
303 | | |
304 | | |
305 | | # Prompt for a body, through an external editor. |
306 | | sub ask_for_body { |
307 | | unless ( $opts{quiet} ) { |
308 | | print <<EOT; |
309 | | Now you need to supply the bug report. Try to make the report concise |
310 | | but descriptive. Include any relevant detail. If you are reporting |
311 | | something that does not work as you think it should, please try to |
312 | | include example of both the actual result, and what you expected. |
313 | | |
314 | | Some information about your local parrot configuration will |
315 | | automatically be included at the end of the report. If you are using |
316 | | any unusual version of parrot, please try and confirm exactly which |
317 | | versions are relevant. |
318 | | |
319 | | EOT |
320 | | |
321 | | print "Press 'Enter' to continue...\n"; |
322 | | scalar <STDIN>; |
323 | | } |
324 | | |
325 | | # Prompt for editor to use if none supplied. |
326 | | if ( $opts{editor} ) { |
327 | | $editor = $opts{editor}; |
328 | | |
329 | | } |
330 | | else { |
331 | | ask_for_editor($opts{quiet} ? "" : <<EOT); |
332 | | You will probably want to use an editor to enter the report. If the |
333 | | default editor proposed below is the editor you want to use, then just |
334 | | press the 'Enter' key, otherwise type in the name of the editor you |
335 | | would like to use. |
336 | | EOT |
337 | | } |
338 | | |
339 | | # Launch editor. |
340 | | $tmpfile = generate_filename(); |
341 | | my $body = ""; |
342 | | my $err = 0; |
343 | | do { |
344 | | edit_bug_report( $tmpfile ); |
345 | | # Slurp bug report. |
346 | | open BODY, "<$tmpfile" or die "Can't open '$tmpfile': $!"; |
347 | | { |
348 | | local $/; |
349 | | $body = <BODY>; |
350 | | } |
351 | | close BODY or die "Can't close '$tmpfile': $!"; |
352 | | unless ( $body ) { |
353 | | print "\nYou provided an empty bug report!\n"; |
354 | | print "Press 'Enter' to continue...\n"; |
355 | | scalar <STDIN>; |
356 | | } |
357 | | die "Aborting.\n" if $err++ == 5; |
358 | | } until ( $body ); |
359 | | |
360 | | return $body; |
361 | | } |
362 | | |
363 | | |
364 | | # Prompt for editor to use. |
365 | | sub ask_for_editor { |
366 | | print shift() . "Editor [$editor]: "; |
367 | | my $entry = <STDIN>; |
368 | | chomp $entry; |
369 | | $editor = $entry if $entry ne ""; |
370 | | $opts{editor} = $editor; |
371 | | } |
372 | | |
373 | | |
374 | | # Prompt for return address, return it. |
375 | | sub ask_for_return_address { |
376 | | print <<EOT unless $opts{quiet}; |
377 | | Your e-mail address will be useful if you need to be contacted. If the |
378 | | default shown below is not your full internet e-mail address, please |
379 | | correct it. |
380 | | EOT |
381 | | |
382 | | # Try and guess return address |
383 | | my ($from, $guess); |
384 | | $guess = $ENV{'REPLY-TO'} || $ENV{REPLYTO} || ""; |
385 | | |
386 | | if ( ! $guess ) { |
387 | | # Use $domain if we can. |
388 | | if ( $domain ) { |
389 | | $guess = $is_vms && !$Config{d_socket} ? |
390 | | "$domain\:\:$user" : "$user\@$domain"; |
391 | | } |
392 | | } |
393 | | |
394 | | # Verify our guess. |
395 | | print "Your address [$guess]: "; |
396 | | $from = <STDIN>; |
397 | | chomp $from; |
398 | | $from = $guess if $from eq ""; |
399 | | print "\n\n\n"; |
400 | | return $from; |
401 | | } |
402 | | |
403 | | |
404 | | # Prompt for subject of message. |
405 | | # |
406 | | # Return the subject chosen. |
407 | | # |
408 | | # Die if more than 5 wrong subjects. |
409 | | sub ask_for_subject { |
410 | | print <<EOT unless $opts{quiet}; |
411 | | First of all, please provide a subject for the message. It should be a |
412 | | concise description of the bug or problem. "parrot bug" or "parrot |
413 | | problem" is not a concise description. |
414 | | |
415 | | EOT |
416 | | |
417 | | my $subject; |
418 | | my $err = 0; |
419 | | do { |
420 | | $err and print "\nThat doesn't look like a good subject. " |
421 | | . "Please be more verbose.\n"; |
422 | | print "Subject: "; |
423 | | $subject = <STDIN>; |
424 | | $subject = q{} unless defined $subject; |
425 | | chomp $subject; |
426 | | die "Aborting.\n" if $err++ == 5; |
427 | | } while ( trivial_subject($subject) ); |
428 | | print "\n\n\n"; |
429 | | return $subject; |
430 | | } |
431 | | |
432 | | |
433 | | # Launch an editor in which to edit the bug report. |
434 | | sub edit_bug_report { |
435 | | my $filename = shift; |
436 | | |
437 | | # Launch editor. |
438 | | my $retval; |
439 | | $retval = system($editor, $filename); |
440 | | |
441 | | # Check whether editor run was successful. |
442 | | die <<EOT if $retval; |
443 | | The editor you chose ('$editor') could apparently not be run! Did you |
444 | | mistype the name of your editor? |
445 | | |
446 | | EOT |
447 | | |
448 | | } |
449 | | |
450 | | |
451 | | |
452 | | #------------------------------------------------------------# |
453 | | # Action subs. # |
454 | | |
455 | | |
456 | | # Display everything collected. |
457 | | sub dump_report { |
458 | | print "==> Dumping message...\n"; |
459 | | print format_message(); |
460 | | } |
461 | | |
462 | | |
463 | | # Last chance to edit report. |
464 | | sub edit_report { |
465 | | # Prompt for editor to use if none supplied. |
466 | | unless ( $opts{editor} ) { |
467 | | ask_for_editor(<<EOT); |
468 | | You will probably want to use an editor to modify the report. If the |
469 | | default editor proposed below is the editor you want to use, then just |
470 | | press the 'Enter' key, otherwise type in the name of the editor you |
471 | | would like to use. |
472 | | EOT |
473 | | } |
474 | | |
475 | | $tmpfile ||= $opts{input}; |
476 | | my $err = 0; |
477 | | my $body; |
478 | | do { |
479 | | edit_bug_report( $tmpfile ); |
480 | | # Slurp bug report. |
481 | | open BODY, "<$tmpfile" or die "Can't open '$tmpfile': $!"; |
482 | | { |
483 | | local $/; |
484 | | $body = <BODY>; |
485 | | } |
486 | | close BODY or die "Can't close '$tmpfile': $!"; |
487 | | unless ( $body ) { |
488 | | print "\nYou provided an empty bug report!\n"; |
489 | | print "Press 'Enter' to continue...\n"; |
490 | | scalar <STDIN>; |
491 | | } |
492 | | die "Aborting.\n" if $err++ == 5; |
493 | | } until ( $body ); |
494 | | |
495 | | $report{body} = $body; |
496 | | } |
497 | | |
498 | | |
499 | | # Format the message with everything collected and return it. |
500 | | sub format_message { |
501 | | my $report = ""; |
502 | | |
503 | | # OS, arch, compiler... |
504 | | $report .= <<EOT; |
505 | | --- |
506 | | osname= $Config{osname} |
507 | | osvers= $Config{osvers} |
508 | | arch= $Config{archname} |
509 | | EOT |
510 | | |
511 | | my $cc = $Config{cc}; |
512 | | #$report .= "cc= $cc $Config{${cc}.'version'}\n"; |
513 | | $report .= "cc= $cc\n"; |
514 | | |
515 | | |
516 | | # ... flags... |
517 | | $report .= <<EOT; |
518 | | --- |
519 | | Flags: |
520 | | category=$report{category} |
521 | | severity=$report{severity} |
522 | | EOT |
523 | | $report .= " ack=no\n" if ! $opts{ack}; |
524 | | |
525 | | # ... bug report ... |
526 | | $report .= "---\n$report{body}\n"; |
527 | | |
528 | | # ... myconfig ... |
529 | | $report .= "---\n$parrot{myconfig}\n---\n"; |
530 | | |
531 | | # ... and environment. |
532 | | $report .= "Environment:\n"; |
533 | | my @env = qw[ PATH LD_LIBRARY_PATH LANG SHELL HOME LOGDIR LANGUAGE ]; |
534 | | push @env, $Config{ldlibpthname} if $Config{ldlibpthname} ne ''; |
535 | | push @env, grep /^(?:PERL|LC_|LANG|CYGWIN)/, keys %ENV; |
536 | | my %env; |
537 | | @env{@env} = @env; |
538 | | for my $env (sort keys %env) { |
539 | | my $env_value = exists $ENV{$env} ? "=$ENV{$env}\n" : " (unset)\n"; |
540 | | $report .= " $env $env_value"; |
541 | | } |
542 | | |
543 | | return $report; |
544 | | } |
545 | | |
546 | | |
547 | | # Print synopsis + help message and exit. |
548 | | sub help { |
549 | | print <<EOT; |
550 | | |
551 | | A program to help generate bug reports about parrot, and mail them. |
552 | | It is designed to be used interactively. Normally no arguments will |
553 | | be needed. |
554 | | |
555 | | Simplest usage: run '$0', and follow the prompts. |
556 | | Usage: $0 [OPTIONS] [ACTIONS] |
557 | | |
558 | | Options: |
559 | | --ok Report successful build on this system to parrot |
560 | | developers. Only use --ok if *everything* was ok: |
561 | | if there were *any* problems at all, use --nok. |
562 | | --nok Report unsuccessful build on this system. |
563 | | --subject <subject> Subject to include with the message. |
564 | | --category <category> Category of the bug report. |
565 | | --severity <severity> Severity of the bug report. |
566 | | --from <address> Your email address. |
567 | | --editor <editor> Editor to use for editing the bug report. |
568 | | --ack, --noack Don't send a bug received acknowledgement. |
569 | | --input-file File containing the body of the report. Use this |
570 | | to quickly send a prepared message. |
571 | | --output-file File where parrotbug will save its bug report. |
572 | | --to <address> Email address to send report to. (testing only) |
573 | | |
574 | | Note: you will be prompted if the program miss some information. |
575 | | |
576 | | Actions: |
577 | | --dump Dump message. |
578 | | --save Save message. |
579 | | --send Send message. |
580 | | --help Print this help message and exit. |
581 | | --version Print version information and exit. |
582 | | |
583 | | EOT |
584 | | exit; |
585 | | } |
586 | | |
587 | | |
588 | | # Save message to file. |
589 | | sub save_report { |
590 | | print "\n==> Saving message to file...\n"; |
591 | | if ( ! $opts{output} ) { |
592 | | print "Enter filename to save bug report: "; |
593 | | $opts{output} = <STDIN>; |
594 | | } |
595 | | |
596 | | open OUTPUT, ">$opts{output}" or die "Cannot open '$opts{output}': $!"; |
597 | | print OUTPUT format_message(); |
598 | | close OUTPUT or die "Cannot open '$opts{output}': $!"; |
599 | | |
600 | | print "Message saved.\n"; |
601 | | } |
602 | | |
603 | | |
604 | | # Send message to final recipient. |
605 | | sub send_report { |
606 | | print "==> Sending message to recipient...\n"; |
607 | | |
608 | | # On linux certain mail implementations won't accept the subject |
609 | | # as "~s subject" and thus the Subject header will be corrupted |
610 | | # so don't use Mail::Send to be safe |
611 | | eval "require Mail::Send"; |
612 | | if ( $@ eq "" && !$is_linux) { |
613 | | my $msg = new Mail::Send Subject => $report{subject}, To => $report{to}; |
614 | | $msg->add( "Reply-To", $report{from} ); |
615 | | |
616 | | my $fh = $msg->open; |
617 | | print $fh format_message(); |
618 | | $fh->close; |
619 | | |
620 | | print "\nMessage sent.\n"; |
621 | | |
622 | | } |
623 | | else { |
624 | | my $sendmail = ""; |
625 | | for ( qw[ /usr/lib/sendmail /usr/sbin/sendmail |
626 | | /usr/ucblib/sendmail /var/qmail/bin/sendmail ] ) { |
627 | | $sendmail = $_, last if -e $_; |
628 | | } |
629 | | |
630 | | die <<EOT if $sendmail eq ""; |
631 | | I am terribly sorry, but I cannot find sendmail, or a close |
632 | | equivalent, and the perl package Mail::Send has not been installed, so |
633 | | I can't send your bug report. We apologize for the inconvenience. |
634 | | |
635 | | So you may attempt to find some way of sending your message, it has |
636 | | been left in the file '$tmpfile'. |
637 | | EOT |
638 | | |
639 | | open(SENDMAIL, "|$sendmail -t -oi") || die "'|$sendmail -t -oi' failed: $!"; |
640 | | |
641 | | print SENDMAIL <<EOT; |
642 | | To: $report{to} |
643 | | Subject: $report{subject} |
644 | | Reply-To: $report{from} |
645 | | Message-Id: $msgid |
646 | | |
647 | | EOT |
648 | | |
649 | | print SENDMAIL format_message(); |
650 | | if (close(SENDMAIL)) { |
651 | | printf "\nMessage sent.\n"; |
652 | | } |
653 | | else { |
654 | | warn "\nSendmail returned status '", $? >> 8, "'\n"; |
655 | | } |
656 | | } |
657 | | } |
658 | | |
659 | | |
660 | | # Print version information (of the parrotbug program) and exit. |
661 | | sub version { |
662 | | print <<"EOT"; |
663 | | |
664 | | This is $0, version $VERSION. |
665 | | |
666 | | EOT |
667 | | exit; |
668 | | } |
669 | | |
670 | | |
671 | | # Check whether actions have been provided on comand-line, otherwise |
672 | | # prompt for what to do with bug report. |
673 | | sub what_next { |
674 | | dump_report() if $opts{dump}; |
675 | | save_report() if $opts{save}; |
676 | | send_report() if $opts{send}; |
677 | | |
678 | | return if $opts{dump} || $opts{save} || $opts{send}; |
679 | | |
680 | | # No actions provided on command-line, prompt for action. |
681 | | |
682 | | my $action; |
683 | | do { |
684 | | print "Action (send,display,edit,save,quit): "; |
685 | | $action = <STDIN>; |
686 | | sw: for ($action) { |
687 | | dump_report(), last sw if /^d/i; |
688 | | edit_report(), last sw if /^e/i; |
689 | | save_report(), last sw if /^sa/i; |
690 | | send_report(), last sw if /^se/i; |
691 | | print "Uh?\n" unless /^q/i; |
692 | | }; |
693 | | } until ( $action =~ /^q/i ); |
694 | | } |
695 | | |
696 | | |
697 | | __END__ |
698 | | |
699 | | =head1 NAME |
700 | | |
701 | | parrotbug - Parrot Bug Reporter |
702 | | |
703 | | =head1 SYNOPSIS |
704 | | |
705 | | % ./parrotbug [options] [actions] |
706 | | |
707 | | =head1 DESCRIPTION |
708 | | |
709 | | A program to help generate bug reports about parrot, and mail them. |
710 | | It is designed to be used interactively. Normally no arguments will |
711 | | be needed. |
712 | | |
713 | | |
714 | | =head1 COMMAND-LINE SWITCHES |
715 | | |
716 | | |
717 | | =head2 Options |
718 | | |
719 | | Note: you will be prompted if the program miss some information. |
720 | | |
721 | | =over 4 |
722 | | |
723 | | =item B<--nok> |
724 | | |
725 | | Report unsuccessful build on this system to parrot developers. |
726 | | |
727 | | =item B<--ok> |
728 | | |
729 | | Report successful build on this system to parrot developers Only use |
730 | | C<--ok> if B<everything> was ok; if there were B<any> problems at all, |
731 | | use C<--nok>. |
732 | | |
733 | | =item B<--subject> |
734 | | |
735 | | Subject of the report. You will be prompted if you don't supply one on |
736 | | the command-line. |
737 | | |
738 | | =item B<--category> |
739 | | |
740 | | Category of the bug report. You will be prompted if you don't supply |
741 | | one on the command-line. |
742 | | |
743 | | =item B<--severity> |
744 | | |
745 | | Severity of the bug report. You will be prompted if you don't supply |
746 | | one on the command-line. |
747 | | |
748 | | =item B<--address> |
749 | | |
750 | | Your email address. The program will try to guess one if you don't |
751 | | provide one, but you'll still need to validate it. |
752 | | |
753 | | =item B<--editor> |
754 | | |
755 | | Editor to use for editing the bug report. |
756 | | |
757 | | =item B<--ack>, B<--noack> |
758 | | |
759 | | Don't send a bug received acknowledgement. |
760 | | |
761 | | =item B<--input-file> |
762 | | |
763 | | File containing the body of the report. Use this to quickly send a |
764 | | prepared message. |
765 | | |
766 | | =item B<--output-file> |
767 | | |
768 | | File where parrotbug will save its bug report, if you ask it to do so. |
769 | | |
770 | | =item B<--to> |
771 | | |
772 | | Email address to send report to. (for testing purposes only) |
773 | | |
774 | | =back |
775 | | |
776 | | |
777 | | =head2 Actions |
778 | | |
779 | | You can provide more than one action on the command-line. If none is |
780 | | supplied, then you will be prompted for what to do. |
781 | | |
782 | | =over 4 |
783 | | |
784 | | =item B<--dump> |
785 | | |
786 | | Dump formatted report on standard output. |
787 | | |
788 | | =item B<--save> |
789 | | |
790 | | Save message to a file, in order for you to send it later from your |
791 | | own. See C<--output> flag. |
792 | | |
793 | | =item B<--send> |
794 | | |
795 | | Try to send a mail with the report. |
796 | | |
797 | | =item B<--help> |
798 | | |
799 | | Print a short synopsis and exit. |
800 | | |
801 | | =item B<--version> |
802 | | |
803 | | Print version information and exit. |
804 | | |
805 | | =back |
806 | | |
807 | | |
808 | | =head1 AUTHORS |
809 | | |
810 | | Jerome Quelin (E<lt>jquelin@cpan.orgE<gt>), with lots of good stuff taken from perlbug. |
811 | | |
812 | | |
813 | | =head1 SEE ALSO |
814 | | |
815 | | perlbug(1), parrot(1), diff(1), patch(1) |
816 | | |
817 | | =cut |
818 | | |
819 | | # Local Variables: |
820 | | # mode: cperl |
821 | | # cperl-indent-level: 4 |
822 | | # fill-column: 100 |
823 | | # End: |
824 | | # vim: expandtab shiftwidth=4: |