use Scalar::Util qw(looks_like_number);
+use List::Util qw(first);
+
use Mail::RFC822::Address;
chdir($config{spool_dir}) or
die "Unable to create new IO::Scalar";
print {$transcript} "Processing commands for $controlrequestaddr:\n\n";
-# debug level
+
my $dl = 0;
+my %affected_packages;
+my %recipients;
+
+my @common_control_options =
+ (($dl > 0 (debug => $transcript):()),
+ transcript => $transcript,
+ requester => $header{from},
+ request_addr => $controlrequestaddr,
+ request_msgid => $header{'message-id'},
+ request_subject => $header{subject},
+ request_nn => $nn,
+ request_replyto => $replyto
+ message => \@log,
+ affected_packages => \%affected_packages,
+ recipients => \%recipients,
+ );
+
my $state= 'idle';
my $lowstate= 'idle';
my $mergelowstate= 'idle';
$bug_affected{$ref}=1;
my $version= $3;
eval {
- set_package(bug => $ref,
- transcript => $transcript,
- ($dl > 0 ? (debug => $transcript):()),
- requester => $header{from},
- request_addr => $controlrequestaddr,
- message => \@log,
- recipients => \%recipients,
+ set_package(@common_control_options,
+ bug => $ref,
package => \@new_packages,
);
# if there is a version passed, we make an internal call
# to set_found
if (defined($version) && length $version) {
- set_found(bug => $ref,
- transcript => $transcript,
- ($dl > 0 ? (debug => $transcript):()),
- requester => $header{from},
- request_addr => $controlrequestaddr,
- message => \@log,
- recipients => \%recipients,
+ set_found(@common_control_options,
+ bug => $ref,
version => $version,
);
}
$errors++;
print {$transcript} "Failed to clear fixed versions and reopen on $ref: $@";
}
- } elsif (m/^reopen\s+\#?(-?\d+)$/i ? ($noriginator='', 1) :
- m/^reopen\s+\#?(-?\d+)\s+\=$/i ? ($noriginator='', 1) :
- m/^reopen\s+\#?(-?\d+)\s+\!$/i ? ($noriginator=$replyto, 1) :
- m/^reopen\s+\#?(-?\d+)\s+(\S.*\S)$/i ? ($noriginator=$2, 1) : 0) {
+ } elsif (m/^reopen\s+\#?(-?\d+)(?:\s+([\=\!]|(?:\S.*\S)))?$/i) {
$ok++;
$ref= $1;
- $bug_affected{$ref}=1;
- if (&setbug) {
- if (@{$data->{fixed_versions}}) {
- print {$transcript} "'reopen' may be inappropriate when a bug has been closed with a version;\nyou may need to use 'found' to remove fixed versions.\n";
- }
- if (!length($data->{done})) {
- print {$transcript} "$gBug is already open, cannot reopen.\n\n";
- &nochangebug;
- } else {
- $action=
- $noriginator eq '' ? "$gBug reopened, originator not changed." :
- "$gBug reopened, originator set to $noriginator.";
- do {
- $affected_packages{$data->{package}} = 1;
- add_recipients(data => $data,
- recipients => \%recipients,
- transcript => $transcript,
- ($dl > 0 ? (debug => $transcript):()),
- );
- $data->{originator}= $noriginator eq '' ? $data->{originator} : $noriginator;
- $data->{fixed_versions}= [];
- $data->{done}= '';
- } while (&getnextbug);
- }
- }
+ $bug_affected{$ref}=1;
+ my $new_submitter = $2;
+ if (defined $new_submitter) {
+ if ($new_submitter eq '=') {
+ undef $new_submitter;
+ }
+ elsif ($new_submitter eq '!') {
+ $new_submitter = $replyto;
+ }
+ }
+ eval {
+ reopen(@common_control_options,
+ bug => $ref,
+ submitter => $new_submitter,
+ );
+ };
+ if ($@) {
+ $errors++;
+ print {$transcript} "Failed to reopen $ref: $@";
+ }
} elsif (m{^(?:(?i)found)\s+\#?(-?\d+)
(?:\s+((?:$config{package_name_re}\/)?
$config{package_version_re}
if (defined $2) {
@versions = split /\s*,\s*/,$2;
eval {
- set_found(bug => $ref,
- transcript => $transcript,
- ($dl > 0 ? (debug => $transcript):()),
- requester => $header{from},
- request_addr => $controlrequestaddr,
- message => \@log,
- affected_packages => \%affected_packages,
- recipients => \%recipients,
+ set_found(@common_control_options,
+ bug => $ref,
found => \@versions,
add => 1,
);
}
else {
eval {
- set_fixed(bug => $ref,
- transcript => $transcript,
- ($dl > 0 ? (debug => $transcript):()),
- requester => $header{from},
- request_addr => $controlrequestaddr,
- message => \@log,
- affected_packages => \%affected_packages,
- recipients => \%recipients,
+ set_fixed(@common_control_options,
+ bug => $ref,
fixed => [],
reopen => 1,
);
my @versions;
@versions = split /\s*,\s*/,$2;
eval {
- set_found(bug => $ref,
- transcript => $transcript,
- ($dl > 0 ? (debug => $transcript):()),
- requester => $header{from},
- request_addr => $controlrequestaddr,
- message => \@log,
- affected_packages => \%affected_packages,
- recipients => \%recipients,
+ set_found(@common_control_options,
+ bug => $ref,
found => \@versions,
remove => 1,
);
my @versions;
@versions = split /\s*,\s*/,$2;
eval {
- set_fixed(bug => $ref,
- transcript => $transcript,
- ($dl > 0 ? (debug => $transcript):()),
- requester => $header{from},
- request_addr => $controlrequestaddr,
- message => \@log,
- affected_packages => \%affected_packages,
- recipients => \%recipients,
+ set_fixed(@common_control_options,
+ bug => $ref,
fixed => \@versions,
add => 1,
);
my @versions;
@versions = split /\s*,\s*/,$2;
eval {
- set_fixed(bug => $ref,
- transcript => $transcript,
- ($dl > 0 ? (debug => $transcript):()),
- requester => $header{from},
- request_addr => $controlrequestaddr,
- message => \@log,
- affected_packages => \%affected_packages,
- recipients => \%recipients,
+ set_fixed(@common_control_options,
+ bug => $ref,
fixed => \@versions,
remove => 1,
);
print {$transcript} "$newsubmitter is not a valid e-mail address; not changing submitter\n";
$errors++;
}
- elsif (&getbug) {
- if (&checkpkglimit) {
- &foundbug;
- $affected_packages{$data->{package}} = 1;
- add_recipients(data => $data,
- recipients => \%recipients,
- transcript => $transcript,
- ($dl > 0 ? (debug => $transcript):()),
- );
- $oldsubmitter= $data->{originator};
- $data->{originator}= $newsubmitter;
- $action= "Changed $gBug submitter from $oldsubmitter to $newsubmitter.";
- &savebug;
- print {$transcript} "$action\n";
- if (length($data->{done})) {
- print {$transcript} "(By the way, that $gBug is currently marked as done.)\n";
- }
- print {$transcript} "\n";
- $message= <<END;
-From: $gMaintainerEmail ($gProject $gBug Tracking System)
-To: $oldsubmitter
-Subject: $gBug#$ref submitter address changed
- ($header{'subject'})
-References: $header{'message-id'} $data->{msgid}
-In-Reply-To: $data->{msgid}
-Message-ID: <handler.$ref.$nn.newsubmitter.$midix\@$gEmailDomain>
-Reply-To: $ref\@$gEmailDomain
-X-$gProject-PR-Message: submitter-changed $ref
-
-The submitter address recorded for your $gBug report
-#$ref: $data->{subject}
-has been changed.
-
-The old submitter address for this report was
-$oldsubmitter.
-The new submitter address is
-$newsubmitter.
-
-This change was made by
-$replyto.
-If it was incorrect, please contact them directly.
-
-$gMaintainer
-(administrator, $gProject $gBugs database)
-
-END
- &sendmailmessage($message,$oldsubmitter);
- } else {
- &cancelbug;
- }
- } else {
- ¬foundbug;
+ else {
+ eval {
+ set_submitter(@common_control_options,
+ bug => $ref,
+ submitter => $newsubmitter,
+ );
+ };
+ if ($@) {
+ $errors++;
+ print {$transcript} "Failed to set submitter on $ref: $@";
+ }
}
} elsif (m/^forwarded\s+\#?(-?\d+)\s+(\S.*\S)$/i) {
$ok++;
$ref = $clonebugs{$ref} if exists $clonebugs{$ref};
$bug_affected{$ref} = 1;
eval {
- set_forwarded(bug => $ref,
- transcript => $transcript,
- ($dl > 0 ? (debug => $transcript):()),
- requester => $header{from},
- request_addr => $controlrequestaddr,
- message => \@log,
- affected_packages => \%affected_packages,
- recipients => \%recipients,
- forwarded => $forward_to,
+ set_forwarded(@common_control_options,
+ bug => $ref,
+ forwarded => $forward_to,
);
};
if ($@) {
$ref = $clonebugs{$ref} if exists $clonebugs{$ref};
$bug_affected{$ref} = 1;
eval {
- set_forwarded(bug => $ref,
- transcript => $transcript,
- ($dl > 0 ? (debug => $transcript):()),
- requester => $header{from},
- request_addr => $controlrequestaddr,
- message => \@log,
- affected_packages => \%affected_packages,
- recipients => \%recipients,
- forwarded => undef,
+ set_forwarded(@common_control_options,
+ bug => $ref,
+ forwarded => undef,
);
};
if ($@) {
} elsif (m/^(?:severity|priority)\s+\#?(-?\d+)\s+([-0-9a-z]+)$/i) {
$ok++;
$ref= $1;
+ $ref = $clonebugs{$ref} if exists $clonebugs{$ref};
$bug_affected{$ref}=1;
my $newseverity= $2;
- if (!grep($_ eq $newseverity, @gSeverityList, "$gDefaultSeverity")) {
- print {$transcript} "Severity level \`$newseverity' is not known.\n".
- "Recognized are: $gShowSeverities.\n\n";
- $errors++;
- } elsif (exists $gObsoleteSeverities{$newseverity}) {
+ if (exists $gObsoleteSeverities{$newseverity}) {
print {$transcript} "Severity level \`$newseverity' is obsolete. " .
"Use $gObsoleteSeverities{$newseverity} instead.\n\n";
$errors++;
- } elsif (&setbug) {
- my $printseverity= $data->{severity};
- $printseverity= "$gDefaultSeverity" if $printseverity eq '';
- $action= "Severity set to \`$newseverity' from \`$printseverity'";
- do {
- $affected_packages{$data->{package}} = 1;
- add_recipients(data => $data,
- recipients => \%recipients,
- transcript => $transcript,
- ($dl > 0 ? (debug => $transcript):()),
- );
- if (defined $gStrongList and isstrongseverity($newseverity)) {
- addbcc("$gStrongList\@$gListDomain");
- }
- $data->{severity}= $newseverity;
- } while (&getnextbug);
- }
+ } elsif (not defined first {$_ eq $newseverity}
+ (@gSeverityList, "$gDefaultSeverity")) {
+ print {$transcript} "Severity level \`$newseverity' is not known.\n".
+ "Recognized are: $gShowSeverities.\n\n";
+ $errors++;
+ } else {
+ eval {
+ set_severity(@common_control_options,
+ bug => $ref,
+ severity => $newseverity,
+ );
+ };
+ if ($@) {
+ $errors++;
+ print {$transcript} "Failed to set severity of $config{bug} $ref to $newseverity: $@";
+ }
+ }
} elsif (m/^tags?\s+\#?(-?\d+)\s+(([=+-])\s*)?(\S.*)?$/i) {
+ ### TODO: [#505189] Consider altering this to accept tag #nnn + foo - bar - baz
$ok++;
$ref = $1;
- my $addsubcode = $3;
- my $tags = $4;
+ $ref = $clonebugs{$ref} if exists $clonebugs{$ref};
$bug_affected{$ref}=1;
- my $addsub = "add";
+ my $addsubcode = $3;
+ my @add_remove_option = ();
if (defined $addsubcode) {
- $addsub = "sub" if ($addsubcode eq "-");
- $addsub = "add" if ($addsubcode eq "+");
- $addsub = "set" if ($addsubcode eq "=");
+ if ($addsubcode eq '-') {
+ push @add_remove_option,(remove => 1);
+ }
+ elsif ($addsubcode eq '+') {
+ push @add_remove_option,(add => 1);
+ }
}
- my @okaytags = ();
- my @badtags = ();
- foreach my $t (split /[\s,]+/, $tags) {
- if (!grep($_ eq $t, @gTags)) {
+ my $tags = $4;
+ my @tags = /[\s,]+/, $tags;
+ foreach my $tag (@tags) {
+ if (not defined first {$_ eq $tag} @{$config{tags}}) {
push @badtags, $t;
- } else {
- push @okaytags, $t;
}
}
if (@badtags) {
"Recognized are: ".join(' ', @gTags).".\n\n";
$errors++;
}
- if (&setbug) {
- if ($data->{keywords} eq '') {
- print {$transcript} "There were no tags set.\n";
- } else {
- print {$transcript} "Tags were: $data->{keywords}\n";
- }
- if ($addsub eq "set") {
- $action= "Tags set to: " . join(", ", @okaytags);
- } elsif ($addsub eq "add") {
- $action= "Tags added: " . join(", ", @okaytags);
- } elsif ($addsub eq "sub") {
- $action= "Tags removed: " . join(", ", @okaytags);
- }
- do {
- $affected_packages{$data->{package}} = 1;
- add_recipients(data => $data,
- recipients => \%recipients,
- transcript => $transcript,
- ($dl > 0 ? (debug => $transcript):()),
- );
- $data->{keywords} = '' if ($addsub eq "set");
- # Allow removing obsolete tags.
- if ($addsub eq "sub") {
- foreach my $t (@badtags) {
- $data->{keywords} = join ' ', grep $_ ne $t,
- split ' ', $data->{keywords};
- }
- }
- # Now process all other additions and subtractions.
- foreach my $t (@okaytags) {
- $data->{keywords} = join ' ', grep $_ ne $t,
- split ' ', $data->{keywords};
- $data->{keywords} = "$t $data->{keywords}" unless($addsub eq "sub");
- }
- $data->{keywords} =~ s/\s*$//;
- } while (&getnextbug);
+ eval {
+ set_tags(@common_control_options,
+ bug => $ref,
+ tags => [@tags],
+ warn_on_bad_tags => 0, # don't warn on bad tags,
+ # 'cause we do that above
+ @add_remove_option,
+ );
+ };
+ if ($@) {
+ # we intentionally have two errors here if there is a bad
+ # tag and the above fails for some reason
+ $errors++;
+ print {$transcript} "Failed to alter tags of $config{bug} $ref: $@";
}
} elsif (m/^(un)?block\s+\#?(-?\d+)\s+(by|with)\s+(\S.*)?$/i) {
$ok++;
$ref = $clonebugs{$ref} if exists $clonebugs{$ref};
$bug_affected{$ref} = 1;
eval {
- affects(bug => $ref,
- transcript => $transcript,
- ($dl > 0 ? (debug => $transcript):()),
- requester => $header{from},
- request_addr => $controlrequestaddr,
- message => \@log,
- recipients => \%recipients,
+ affects(@common_control_options,
packages => [splitpackages($3)],
($add_remove eq '+'?(add => 1):()),
($add_remove eq '-'?(remove => 1):()),
$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(@common_control_options,
+ bug => $ref,
summary => $summary_msg,
);
};
}
$bug_affected{$ref} = 1;
eval {
- owner(bug => $ref,
- transcript => $transcript,
- ($dl > 0 ? (debug => $transcript):()),
- requester => $header{from},
- request_addr => $controlrequestaddr,
- message => \@log,
- recipients => \%recipients,
+ owner(@common_control_options,
+ bug => $ref,
owner => $newowner,
);
};
$ref = $clonebugs{$ref} if exists $clonebugs{$ref};
$bug_affected{$ref} = 1;
eval {
- owner(bug => $ref,
- transcript => $transcript,
- ($dl > 0 ? (debug => $transcript):()),
- requester => $header{from},
- request_addr => $controlrequestaddr,
- message => \@log,
- recipients => \%recipients,
+ owner(@common_control_options,
+ bug => $ref,
owner => undef,
);
};
$ref = $clonebugs{$ref} if exists $clonebugs{$ref};
$bug_affected{$ref} = 1;
eval {
- bug_unarchive(bug => $ref,
- transcript => $transcript,
- ($dl > 0 ? (debug => $transcript):()),
- affected_bugs => \%bug_affected,
- requester => $header{from},
- request_addr => $controlrequestaddr,
- message => \@log,
+ bug_unarchive(@common_control_options,
+ bug => $ref,
recipients => \%recipients,
);
};
$ref = $clonebugs{$ref} if exists $clonebugs{$ref};
$bug_affected{$ref} = 1;
eval {
- bug_archive(bug => $ref,
- transcript => $transcript,
- ($dl > 0 ? (debug => $transcript):()),
+ bug_archive(@common_control_options,
+ bug => $ref,
ignore_time => 1,
archive_unarchived => 0,
- affected_bugs => \%bug_affected,
- requester => $header{from},
- request_addr => $controlrequestaddr,
- message => \@log,
- recipients => \%recipients,
);
};
if ($@) {