Index: parrotbug =================================================================== --- parrotbug (revision 37047) +++ parrotbug (working copy) @@ -1,824 +1,19 @@ #!/usr/bin/perl # -# Copyright (C) 2004-2009, Parrot Foundation. +# Copyright (C) 2009, Parrot Foundation. # $Id$ # -eval 'exec perl -w -S $0 ${1+"$@"}' - if $running_under_some_shell; - use strict; use warnings; -use Config; -use File::Spec; -use Getopt::Long; +print <<'END' +We no longer use parrotbug for bug reports; please submit +reports via the web interface at http://trac.parrot.org/ . -my $VERSION = "1.0"; +Thanks, + The Parrot Team -# These are the standard addresses for reporting bugs. -my %std_to = - ( bug => 'parrotbug@parrotcode.org', - ok => 'parrotstatus-ok@parrotcode.org', - nok => 'parrotstatus-nok@parrotcode.org', - ); +END -my $parrotdir = File::Spec->curdir(); -my ( %opts, %parrot, %report ); -my ( $editor, $user, $domain, $msgid, $tmpfile ); -my ( $is_linux, $is_macos, $is_mswin32, $is_os2, $is_vms ); -my @categories = qw[ core docs install library utilities languages ]; -my @severities = qw[ critical high medium low wishlist none ]; - - -#------------------------------------------------------------# -# Main program. # - -init(); -help() if $opts{help}; -version() if $opts{version}; -explain_parrotbug() unless $opts{quiet}; -query_missing_info(); -what_next(); -unlink $tmpfile; -exit; - - - -# Explain what C is. -sub explain_parrotbug { - print <lists.parrot.org. - - - -EOT -} - - - - -#------------------------------------------------------------# -# Utils subs. # - -# Generate random filename to edit report. -sub generate_filename { - my $dir = File::Spec->tmpdir(); - my $filename = "bugrep0$$"; - $filename++ while -e File::Spec->catfile($dir, $filename); - $filename = File::Spec->catfile($dir, $filename); - return $filename; -} - - -# Check whether a subject is trivial. A subject is not considered trivial -# if it's an ok or a nok report. -# Return 1 if trivial, 0 otherwise (subject acceptable). -sub trivial_subject { - my $subject = shift; - - return 0 if $opts{ok} || $opts{nok}; - if ( $subject =~ - /^(y(es)?|no?|help|parrot( (bug|problem))?|bug|problem)$/i || - length($subject) < 4 || - $subject !~ /\s/ ) { - return 1; - } - else { - return 0; - } -} - - - - -#------------------------------------------------------------# -# Init subs. # - -# Initialize the program. -# -# Get parrot information, process the options, create the message -# information (subject, to, body, etc.) depending on the type of report -# (ok, nok or bug report). -sub init { - $is_linux = lc($^O) eq 'linux'; - $is_mswin32 = $^O eq 'MSWin32'; - $is_os2 = $^O eq 'os2'; - $is_vms = $^O eq 'VMS'; - - ## - ## Fetch Parrot information. - ## - - # Get parrot version. - # There will always be an up-to-date $parrot/VERSION - my $filename = File::Spec->catfile($parrotdir, "VERSION"); - open(VERSION, "<$filename") or die "Cannot open '$filename': $!"; - $parrot{version} = ; - chomp $parrot{version}; - close(VERSION) or die "Cannot close '$filename': $!"; - - # Get parrot configuration, stored in $parrot/myconfig - $filename = File::Spec->catfile($parrotdir, "myconfig"); - open(MYCONFIG, "<$filename") or die "Cannot open '$filename': $!"; - { - local $/; - $parrot{myconfig} = ; - } - close(MYCONFIG) or die "Cannot close '$filename': $!"; - - - ## - ## Process options. - ## - Getopt::Long::Configure("no_bundling", "no_ignore_case", "auto_abbrev"); - help() unless GetOptions - ( \%opts, - "help|h", "version|V", - "send", "dump", "save", - "from|f=s", "to|test|t=s", "editor|e=s", - "subject|s=s", "category|C=s", "severity|S=s", - "input|input-file|i=s", "output|output-file|o=s", - "ok", "nok", "ack!", "quiet|q!" ); - - ## - ## Report to be sent. - ## - sw: { - ok_report: { - last ok_report unless defined $opts{ok}; - - # This is an ok report, woohoo! - $report{to} = $std_to{ok}; - $report{subject} = "OK: parrot $parrot{version} " - . "on $Config{archname} $Config{osvers}"; - $report{body} = "Parrot reported to build OK on this system.\n"; - $report{category} = "install"; - $report{severity} = "none"; - $report{body} = ""; - last sw; - }; - - # Ok reports do not need body, but nok and bug reports do need - # a body. - if ( $opts{input} ) { - # Report was pre-written, slurp it. - open BODY, "<$opts{input}" or die "Can't open '$opts{input}': $!"; - local $/; - $report{body} = ; - close BODY or die "Can't close '$opts{input}': $!"; - } - else { - # No file provided... - $report{body} = ""; - } - - nok_report: { - last nok_report unless defined $opts{nok}; - - # This a nok report, how sad... :-( - $report{to} = $std_to{nok}; - $report{subject} = "Not OK: parrot $parrot{version} " - . "on $Config{archname} $Config{osvers}"; - $report{category} = "install"; - $report{severity} = "none"; - last sw; - }; - - # Neither an ok nor a nok. - $report{to} = $std_to{bug}; - $report{subject} = $opts{subject} || ""; - $report{category} = $opts{category} || ""; - $report{severity} = $opts{severity} || ""; - }; - - # Test message, shortcuting recipent. - $report{to} = $opts{to} if $opts{to}; - - ## - ## User information. - ## - - # Username. - $user = $is_mswin32 ? $ENV{USERNAME} - : $is_os2 ? $ENV{USER} || $ENV{LOGNAME} - : $is_macos ? $ENV{USER} - : eval { getpwuid($<) }; # May be missing - - # User address, used in message and in Reply-To header. - $report{from} = $opts{from} || ""; - - # Editor - $editor = $ENV{VISUAL} || $ENV{EDITOR} || $ENV{EDIT} - || ( $is_vms && "edit/tpu" ) - || ( $is_mswin32 && "notepad" ) - || ( $is_macos && "" ) - || "vi"; - - - ## - ## Mail information. - ## - - # Message-Id. - eval "use Mail::Util;"; - if ( $@ eq "" ) { - $domain = Mail::Util::maildomain(); - } - elsif ($is_mswin32) { - $domain = $ENV{USERDOMAIN}; - } - else { - require Sys::Hostname; - $domain = Sys::Hostname::hostname(); - } - $msgid = ""; -} - - - -#------------------------------------------------------------# -# Querying subs. # - -# Query missing information in order to have a complete report. -sub query_missing_info { - $report{subject} = "" if trivial_subject( $report{subject} ); - $report{subject} = ask_for_subject() unless $report{subject}; - $report{category} = ask_for_alternative( "category", \@categories) - unless $report{category}; - $report{severity} = ask_for_alternative( "severity", \@severities) - unless $report{severity}; - $report{from} = ask_for_return_address() unless $report{from}; - $report{body} = ask_for_body() unless $report{body}; -} - - -# Prompt for alternatives from a set of choices. -# -# The arguments are: the name of alternative, the choices (as an array -# ref), and the default answer. (first element if undef) -# -# Return the lowercased alternative chosen. -# -# Die if more than 5 wrong answers. -sub ask_for_alternative { - my ( $what, $choices, $default ) = @_; - - print <[0]; - my $alt; - my $err = 0; - do { - die "Invalid $alt: aborting.\n" if $err++ > 5; - print "Please enter a $what [$default]: "; - $alt = ; - chomp $alt; - $alt = $default if $alt =~ /^\s*$/; - } until ( ($alt) = grep /^$alt/i, @$choices ); - - print "\n\n\n"; - return lc $alt; -} - - -# Prompt for a body, through an external editor. -sub ask_for_body { - unless ( $opts{quiet} ) { - print <; - } - - # Prompt for editor to use if none supplied. - if ( $opts{editor} ) { - $editor = $opts{editor}; - - } - else { - ask_for_editor($opts{quiet} ? "" : <; - } - close BODY or die "Can't close '$tmpfile': $!"; - unless ( $body ) { - print "\nYou provided an empty bug report!\n"; - print "Press 'Enter' to continue...\n"; - scalar ; - } - die "Aborting.\n" if $err++ == 5; - } until ( $body ); - - return $body; -} - - -# Prompt for editor to use. -sub ask_for_editor { - print shift() . "Editor [$editor]: "; - my $entry = ; - chomp $entry; - $editor = $entry if $entry ne ""; - $opts{editor} = $editor; -} - - -# Prompt for return address, return it. -sub ask_for_return_address { - print <; - chomp $from; - $from = $guess if $from eq ""; - print "\n\n\n"; - return $from; -} - - -# Prompt for subject of message. -# -# Return the subject chosen. -# -# Die if more than 5 wrong subjects. -sub ask_for_subject { - print <; - $subject = q{} unless defined $subject; - chomp $subject; - die "Aborting.\n" if $err++ == 5; - } while ( trivial_subject($subject) ); - print "\n\n\n"; - return $subject; -} - - -# Launch an editor in which to edit the bug report. -sub edit_bug_report { - my $filename = shift; - - # Launch editor. - my $retval; - $retval = system($editor, $filename); - - # Check whether editor run was successful. - die < Dumping message...\n"; - print format_message(); -} - - -# Last chance to edit report. -sub edit_report { - # Prompt for editor to use if none supplied. - unless ( $opts{editor} ) { - ask_for_editor(<; - } - close BODY or die "Can't close '$tmpfile': $!"; - unless ( $body ) { - print "\nYou provided an empty bug report!\n"; - print "Press 'Enter' to continue...\n"; - scalar ; - } - die "Aborting.\n" if $err++ == 5; - } until ( $body ); - - $report{body} = $body; -} - - -# Format the message with everything collected and return it. -sub format_message { - my $report = ""; - - # OS, arch, compiler... - $report .= < Subject to include with the message. - --category Category of the bug report. - --severity Severity of the bug report. - --from
Your email address. - --editor Editor to use for editing the bug report. - --ack, --noack Don't send a bug received acknowledgement. - --input-file File containing the body of the report. Use this - to quickly send a prepared message. - --output-file File where parrotbug will save its bug report. - --to
Email address to send report to. (testing only) - - Note: you will be prompted if the program miss some information. - -Actions: - --dump Dump message. - --save Save message. - --send Send message. - --help Print this help message and exit. - --version Print version information and exit. - -EOT - exit; -} - - -# Save message to file. -sub save_report { - print "\n==> Saving message to file...\n"; - if ( ! $opts{output} ) { - print "Enter filename to save bug report: "; - $opts{output} = ; - } - - open OUTPUT, ">$opts{output}" or die "Cannot open '$opts{output}': $!"; - print OUTPUT format_message(); - close OUTPUT or die "Cannot open '$opts{output}': $!"; - - print "Message saved.\n"; -} - - -# Send message to final recipient. -sub send_report { - print "==> Sending message to recipient...\n"; - - # On linux certain mail implementations won't accept the subject - # as "~s subject" and thus the Subject header will be corrupted - # so don't use Mail::Send to be safe - eval "require Mail::Send"; - if ( $@ eq "" && !$is_linux) { - my $msg = new Mail::Send Subject => $report{subject}, To => $report{to}; - $msg->add( "Reply-To", $report{from} ); - - my $fh = $msg->open; - print $fh format_message(); - $fh->close; - - print "\nMessage sent.\n"; - - } - else { - my $sendmail = ""; - for ( qw[ /usr/lib/sendmail /usr/sbin/sendmail - /usr/ucblib/sendmail /var/qmail/bin/sendmail ] ) { - $sendmail = $_, last if -e $_; - } - - die <> 8, "'\n"; - } - } -} - - -# Print version information (of the parrotbug program) and exit. -sub version { - print <<"EOT"; - -This is $0, version $VERSION. - -EOT - exit; -} - - -# Check whether actions have been provided on comand-line, otherwise -# prompt for what to do with bug report. -sub what_next { - dump_report() if $opts{dump}; - save_report() if $opts{save}; - send_report() if $opts{send}; - - return if $opts{dump} || $opts{save} || $opts{send}; - - # No actions provided on command-line, prompt for action. - - my $action; - do { - print "Action (send,display,edit,save,quit): "; - $action = ; - sw: for ($action) { - dump_report(), last sw if /^d/i; - edit_report(), last sw if /^e/i; - save_report(), last sw if /^sa/i; - send_report(), last sw if /^se/i; - print "Uh?\n" unless /^q/i; - }; - } until ( $action =~ /^q/i ); -} - - -__END__ - -=head1 NAME - -parrotbug - Parrot Bug Reporter - -=head1 SYNOPSIS - - % ./parrotbug [options] [actions] - -=head1 DESCRIPTION - -A program to help generate bug reports about parrot, and mail them. -It is designed to be used interactively. Normally no arguments will -be needed. - - -=head1 COMMAND-LINE SWITCHES - - -=head2 Options - -Note: you will be prompted if the program miss some information. - -=over 4 - -=item B<--nok> - -Report unsuccessful build on this system to parrot developers. - -=item B<--ok> - -Report successful build on this system to parrot developers Only use -C<--ok> if B was ok; if there were B problems at all, -use C<--nok>. - -=item B<--subject> - -Subject of the report. You will be prompted if you don't supply one on -the command-line. - -=item B<--category> - -Category of the bug report. You will be prompted if you don't supply -one on the command-line. - -=item B<--severity> - -Severity of the bug report. You will be prompted if you don't supply -one on the command-line. - -=item B<--address> - -Your email address. The program will try to guess one if you don't -provide one, but you'll still need to validate it. - -=item B<--editor> - -Editor to use for editing the bug report. - -=item B<--ack>, B<--noack> - -Don't send a bug received acknowledgement. - -=item B<--input-file> - -File containing the body of the report. Use this to quickly send a -prepared message. - -=item B<--output-file> - -File where parrotbug will save its bug report, if you ask it to do so. - -=item B<--to> - -Email address to send report to. (for testing purposes only) - -=back - - -=head2 Actions - -You can provide more than one action on the command-line. If none is -supplied, then you will be prompted for what to do. - -=over 4 - -=item B<--dump> - -Dump formatted report on standard output. - -=item B<--save> - -Save message to a file, in order for you to send it later from your -own. See C<--output> flag. - -=item B<--send> - -Try to send a mail with the report. - -=item B<--help> - -Print a short synopsis and exit. - -=item B<--version> - -Print version information and exit. - -=back - - -=head1 AUTHORS - -Jerome Quelin (Ejquelin@cpan.orgE), with lots of good stuff taken from perlbug. - - -=head1 SEE ALSO - -perlbug(1), parrot(1), diff(1), patch(1) - -=cut - -# Local Variables: -# mode: cperl -# cperl-indent-level: 4 -# fill-column: 100 -# End: -# vim: expandtab shiftwidth=4: