From 5e18dc96bf01d38542c7efddfec990dbe83fdca4 Mon Sep 17 00:00:00 2001 From: Don Armstrong Date: Sat, 9 Aug 2008 14:02:03 -0700 Subject: [PATCH] * Add the summary feature --- Debbugs/Control.pm | 165 ++++++++++++++++++++++++++++++++++++++++++- Debbugs/Status.pm | 2 + scripts/service | 32 ++++++++- t/06_mail_handling.t | 12 +++- 4 files changed, 208 insertions(+), 3 deletions(-) diff --git a/Debbugs/Control.pm b/Debbugs/Control.pm index 30a642b..81dd621 100644 --- a/Debbugs/Control.pm +++ b/Debbugs/Control.pm @@ -78,7 +78,8 @@ BEGIN{ $DEBUG = 0 unless defined $DEBUG; @EXPORT = (); - %EXPORT_TAGS = (owner => [qw(owner)], + %EXPORT_TAGS = (summary => [qw(summary)], + owner => [qw(owner)], archive => [qw(bug_archive bug_unarchive), ], log => [qw(append_action_to_log), @@ -184,6 +185,168 @@ my %append_action_options = # ); # } +=head1 SUMMARY FUNCTIONS + +=head2 summary + + eval { + summary(bug => $ref, + transcript => $transcript, + ($dl > 0 ? (debug => $transcript):()), + requester => $header{from}, + request_addr => $controlrequestaddr, + message => \@log, + affected_packages => \%affected_packages, + recipients => \%recipients, + summary => undef, + ); + }; + if ($@) { + $errors++; + print {$transcript} "Failed to mark $ref with summary foo: $@"; + } + +Handles all setting of summary fields + +If summary is undef, unsets the summary + +If summary is 0, sets the summary to the first paragraph contained in +the message passed. + +If summary is numeric, sets the summary to the message specified. + + +=cut + + +sub summary { + my %param = validate_with(params => \@_, + spec => {bug => {type => SCALAR, + regex => qr/^\d+$/, + }, + # specific options here + summary => {type => SCALAR|UNDEF, + default => 0, + }, + %common_options, + %append_action_options, + }, + ); + croak "summary must be numeric or undef" if + defined $param{summary} and not $param{summary} =~ /^\d+$/; + our $locks = 0; + $locks = 0; + local $SIG{__DIE__} = sub { + if ($locks) { + for (1..$locks) { unfilelock(); } + $locks = 0; + } + }; + my ($debug,$transcript) = __handle_debug_transcript(%param); + my (@data); + ($locks, @data) = lock_read_all_merged_bugs($param{bug}); + __handle_affected_packages(data => \@data,%param); + add_recipients(data => \@data, + recipients => $param{recipients} + ); + # figure out the log that we're going to use + my $summary = ''; + my $summary_msg = ''; + my $action = ''; + if (not defined $param{summary}) { + # do nothing + print {$debug} "Removing summary fields"; + $action = 'Removed summary'; + } + else { + my $log = []; + my @records = Debbugs::Log::read_log_records(bug_num => $param{bug}); + if ($param{summary} == 0) { + $log = $param{log}; + $summary_msg = @records + 1; + } + else { + if (($param{summary} - 1 ) > $#records) { + die "Message number '$param{summary}' exceeds the maximum message '$#records'"; + } + my $record = $records[($param{summary} - 1 )]; + if ($record->{type} !~ /incoming-recv|recips/) { + die "Message number '$param{summary}' is a invalid message type '$record->{type}'"; + } + $summary_msg = $param{summary}; + $log = [$record->{text}]; + } + my $p_o = Debbugs::MIME::parse(join('',@{$log})); + my $body = $p_o->{body}; + my $in_pseudoheaders = 0; + my $paragraph = ''; + # walk through body until we get non-blank lines + for my $line (@{$body}) { + if ($line =~ /^\s*$/) { + if (length $paragraph) { + last; + } + $in_pseudoheaders = 0; + next; + } + # skip a paragraph if it looks like it's control or + # pseudo-headers + if ($line =~ m{^\s*(?:(?:Package|Source|Version)\:| #pseudo headers + (?:package|(?:no|)owner|severity|tag|summary| #control + reopen|close|(?:not|)(?:fixed|found)|clone| + (?:force|)merge|user(?:category|tag|) + ) + )\s+\S}x) { + if (not length $paragraph) { + print {$debug} "Found control/pseudo-headers and skiping them\n"; + $in_pseudoheaders = 1; + next; + } + } + next if $in_pseudoheaders; + $paragraph .= $line; + } + print {$debug} "Summary is going to be '$paragraph'\n"; + $summary = $paragraph; + $summary =~ s/[\n\r]//g; + if (not length $summary) { + die "Unable to find summary message to use"; + } + } + for my $data (@data) { + print {$debug} "Going to change summary"; + if (length $summary) { + if (length $data->{summary}) { + $action = "Summary replaced with message bug $param{bug} message $summary_msg"; + } + else { + $action = "Summary recorded from message bug $param{bug} message $summary_msg"; + } + } + $data->{summary} = $summary; + append_action_to_log(bug => $data->{bug_num}, + get_lock => 0, + __return_append_to_log_options( + %param, + action => $action, + ), + ) + if not exists $param{append_log} or $param{append_log}; + writebug($data->{bug_num},$data); + print {$transcript} "$action\n"; + add_recipients(data => $data, + recipients => $param{recipients}, + ); + } + if ($locks) { + for (1..$locks) { unfilelock(); } + } + +} + + + + =head1 OWNER FUNCTIONS =head2 owner diff --git a/Debbugs/Status.pm b/Debbugs/Status.pm index 3b3961f..0030a7c 100644 --- a/Debbugs/Status.pm +++ b/Debbugs/Status.pm @@ -100,6 +100,8 @@ my %fields = (originator => 'submitter', blocks => 'blocks', blockedby => 'blocked-by', unarchived => 'unarchived', + summary => 'summary', + affects => 'affects', ); # Fields which need to be RFC1522-decoded in format versions earlier than 3. diff --git a/scripts/service b/scripts/service index df289c9..da0819a 100755 --- a/scripts/service +++ b/scripts/service @@ -29,7 +29,7 @@ use Debbugs::Versions::Dpkg; use Debbugs::Status qw(splitpackages); use Debbugs::CGI qw(html_escape); -use Debbugs::Control qw(:archive :log :owner); +use Debbugs::Control qw(:all); use Debbugs::Log qw(:misc); use Debbugs::Text qw(:templates); @@ -1184,9 +1184,32 @@ END %limit_pkgs = (); print {$transcript} "Not ignoring any bugs.\n\n"; } + } elsif (m/^summary\s+\#?(-?\d+)\s*(\d+|)\s*$/i) { + $ok++; + $ref = $1; + my $summary_msg = length($2)?$2:undef; + $ref = $clonebugs{$ref} if exists $clonebugs{$ref}; + $bug_affected{$ref} = 1; + eval { + summary(bug => $ref, + transcript => $transcript, + ($dl > 0 ? (debug => $transcript):()), + requester => $header{from}, + request_addr => $controlrequestaddr, + message => \@log, + recipients => \%recipients, + summary => $summary_msg, + ); + }; + if ($@) { + $errors++; + print {$transcript} "Failed to give $ref a summary: $@"; + } + } elsif (m/^owner\s+\#?(-?\d+)\s+((?:\S.*\S)|\!)\s*$/i) { $ok++; $ref = $1; + $ref = $clonebugs{$ref} if exists $clonebugs{$ref}; my $newowner = $2; if ($newowner eq '!') { $newowner = $replyto; @@ -1203,9 +1226,14 @@ END owner => $newowner, ); }; + if ($@) { + $errors++; + print {$transcript} "Failed to mark $ref as having an owner: $@"; + } } elsif (m/^noowner\s+\#?(-?\d+)\s*$/i) { $ok++; $ref = $1; + $ref = $clonebugs{$ref} if exists $clonebugs{$ref}; $bug_affected{$ref} = 1; eval { owner(bug => $ref, @@ -1225,6 +1253,7 @@ END } elsif (m/^unarchive\s+#?(\d+)$/i) { $ok++; $ref = $1; + $ref = $clonebugs{$ref} if exists $clonebugs{$ref}; $bug_affected{$ref} = 1; eval { bug_unarchive(bug => $ref, @@ -1243,6 +1272,7 @@ END } elsif (m/^archive\s+#?(\d+)$/i) { $ok++; $ref = $1; + $ref = $clonebugs{$ref} if exists $clonebugs{$ref}; $bug_affected{$ref} = 1; eval { bug_archive(bug => $ref, diff --git a/t/06_mail_handling.t b/t/06_mail_handling.t index ccf1ee7..b188a99 100644 --- a/t/06_mail_handling.t +++ b/t/06_mail_handling.t @@ -1,7 +1,7 @@ # -*- mode: cperl;-*- # $Id: 05_mail.t,v 1.1 2005/08/17 21:46:17 don Exp $ -use Test::More tests => 66; +use Test::More tests => 72; use warnings; use strict; @@ -196,6 +196,16 @@ my @control_commands = status_key => 'owner', status_value => '', }, + summary => {command => 'summary', + value => '5', + status_key => 'summary', + status_value => 'This is a silly bug', + }, + nosummary => {command => 'summary', + value => '', + status_key => 'summary', + status_value => '', + }, close => {command => 'close', value => '', status_key => 'done', -- 2.39.2