]> git.donarmstrong.com Git - debbugs.git/blobdiff - scripts/service
support cloned blocks; handle multi-packages properly
[debbugs.git] / scripts / service
index 31f353ce2332c262432be887df60fb47f51e7d63..dce8703c948ecbcf0c22349e179ad91c4603ec86 100755 (executable)
@@ -122,10 +122,12 @@ print {$transcript} "Processing commands for $controlrequestaddr:\n\n";
 my $dl = 0;
 my %affected_packages;
 my %recipients;
+# this is the hashref which is passed to all control calls
+my %limit = ();
+
 
 my @common_control_options =
-    (($dl > 0 ? (debug => $transcript):()),
-     transcript        => $transcript,
+    (transcript        => $transcript,
      requester         => $header{from},
      request_addr      => $controlrequestaddr,
      request_msgid     => $header{'message-id'},
@@ -135,6 +137,7 @@ my @common_control_options =
      message           => \@log,
      affected_packages => \%affected_packages,
      recipients        => \%recipients,
+     limit             => \%limit,
     );
 
 my $state= 'idle';
@@ -200,12 +203,15 @@ for ($procline=0; $procline<=$#bodylines; $procline++) {
     print {$transcript} "> $_\n";
     next if m/^\s*\#/;
     $action= '';
-    if (m/^stop\s*$/i || m/^quit\s*$/i || m/^--\s*$/ || m/^thank(?:s|\s*you)?\s*$/i || m/^kthxbye\s*$/i) {
+    if (m/^(?:stop|quit|--|thank(?:s|\s*you)?|kthxbye)\.*\s*$/i) {
        print {$transcript} "Stopping processing here.\n\n";
         last;
     } elsif (m/^debug\s+(\d+)$/i && $1 >= 0 && $1 <= 1000) {
         $dl= $1+0;
-        print {$transcript} "Debug level $dl.\n\n";
+       if ($dl > 0 and not grep /debug/,@common_control_options) {
+           push @common_control_options,(debug => $transcript);
+       }
+       print {$transcript} "Debug level $dl.\n\n";
     } elsif (m/^(send|get)\s+\#?(\d{2,})$/i) {
         $ref= $2+0;
         &sendlynxdoc("bugreport.cgi?bug=$ref","logs for $gBug#$ref");
@@ -551,19 +557,20 @@ END
            # to set_found
            if (defined($version) && length $version) {
                set_found(@common_control_options,
-                         bug          => $ref,
-                         version      => $version,
+                         bug   => $ref,
+                         found => $version,
                         );
            }
        };
        if ($@) {
            $errors++;
-           print {$transcript} "Failed to clear fixed versions and reopen on $ref: $@";
+           print {$transcript} "Failed to clear fixed versions and reopen on $ref: ".cleanup_eval_fail($@,$debug)."\n";
        }
     } elsif (m/^reopen\s+\#?(-?\d+)(?:\s+([\=\!]|(?:\S.*\S)))?$/i) {
         $ok++;
         $ref= $1;
-       $bug_affected{$ref}=1; 
+       $ref = $clonebugs{$ref} if exists $clonebugs{$ref};
+       $bug_affected{$ref}=1;
        my $new_submitter = $2;
        if (defined $new_submitter) {
            if ($new_submitter eq '=') {
@@ -581,7 +588,7 @@ END
        };
        if ($@) {
            $errors++;
-           print {$transcript} "Failed to reopen $ref: $@";
+           print {$transcript} "Failed to reopen $ref: ".cleanup_eval_fail($@,$debug)."\n";
        }
     } elsif (m{^(?:(?i)found)\s+\#?(-?\d+)
               (?:\s+((?:$config{package_name_re}\/)?
@@ -605,7 +612,7 @@ END
            };
            if ($@) {
                $errors++;
-               print {$transcript} "Failed to add found on $ref: $@";
+               print {$transcript} "Failed to add found on $ref: ".cleanup_eval_fail($@,$debug)."\n";
            }
        }
        else {
@@ -618,7 +625,7 @@ END
            };
            if ($@) {
                $errors++;
-               print {$transcript} "Failed to clear fixed versions and reopen on $ref: $@";
+               print {$transcript} "Failed to clear fixed versions and reopen on $ref: ".cleanup_eval_fail($@,$debug)."\n";
            }
        }
     }
@@ -643,7 +650,7 @@ END
        };
        if ($@) {
            $errors++;
-           print {$transcript} "Failed to remove found on $ref: $@";
+           print {$transcript} "Failed to remove found on $ref: ".cleanup_eval_fail($@,$debug)."\n";
        }
     }
     elsif (m{^(?:(?i)fixed)\s+\#?(-?\d+)
@@ -667,7 +674,7 @@ END
        };
        if ($@) {
            $errors++;
-           print {$transcript} "Failed to add fixed on $ref: $@";
+           print {$transcript} "Failed to add fixed on $ref: ".cleanup_eval_fail($@,$debug)."\n";
        }
     }
     elsif (m{^(?:(?i)notfixed)\s+\#?(-?\d+)
@@ -691,7 +698,7 @@ END
        };
        if ($@) {
            $errors++;
-           print {$transcript} "Failed to remove fixed on $ref: $@";
+           print {$transcript} "Failed to remove fixed on $ref: ".cleanup_eval_fail($@,$debug)."\n";
        }
     }
     elsif (m/^submitter\s+\#?(-?\d+)\s+(\!|\S.*\S)$/i) {
@@ -713,7 +720,7 @@ END
            };
            if ($@) {
                $errors++;
-               print {$transcript} "Failed to set submitter on $ref: $@";
+               print {$transcript} "Failed to set submitter on $ref: ".cleanup_eval_fail($@,$debug)."\n";
            }
         }
     } elsif (m/^forwarded\s+\#?(-?\d+)\s+(\S.*\S)$/i) {
@@ -730,7 +737,7 @@ END
        };
        if ($@) {
            $errors++;
-           print {$transcript} "Failed to set the forwarded-to-address of $ref: $@";
+           print {$transcript} "Failed to set the forwarded-to-address of $ref: ".cleanup_eval_fail($@,$debug)."\n";
        }
     } elsif (m/^notforwarded\s+\#?(-?\d+)$/i) {
         $ok++;
@@ -745,7 +752,7 @@ END
        };
        if ($@) {
            $errors++;
-           print {$transcript} "Failed to clear the forwarded-to-address of $ref: $@";
+           print {$transcript} "Failed to clear the forwarded-to-address of $ref: ".cleanup_eval_fail($@,$debug)."\n";
        }
     } elsif (m/^(?:severity|priority)\s+\#?(-?\d+)\s+([-0-9a-z]+)$/i) {
         $ok++;
@@ -771,32 +778,53 @@ END
            };
            if ($@) {
                $errors++;
-               print {$transcript} "Failed to set severity of $config{bug} $ref to $newseverity: $@";
+               print {$transcript} "Failed to set severity of $config{bug} $ref to $newseverity: ".cleanup_eval_fail($@,$debug)."\n";
            }
        }
-    } elsif (m/^tags?\s+\#?(-?\d+)\s+(([=+-])\s*)?(\S.*)?$/i) {
-       ### TODO: [#505189] Consider altering this to accept tag #nnn + foo - bar - baz
+    } elsif (m/^tags?\s+\#?(-?\d+)\s+(\S.*)$/i) {
        $ok++;
        $ref = $1;
        $ref = $clonebugs{$ref} if exists $clonebugs{$ref};
        $bug_affected{$ref}=1;
-       my $addsubcode = $3;
-       my @add_remove_option = ();
-       if (defined $addsubcode) {
-           if ($addsubcode eq '-') {
-               push @add_remove_option,(remove => 1);
-           }
-           elsif ($addsubcode eq '+') {
-               push @add_remove_option,(add => 1);
-           }
-       }
-       my $tags = $4;
+       my $tags = $2;
        my @tags = split /[\s,]+/, $tags;
-       my @badtags = ();
-       foreach my $tag (@tags) {
+       # this is an array of hashrefs which contain two elements, the
+       # first of which is the array of tags, the second is the
+       # option to pass to set_tag (we use a hashref here to make it
+       # more obvious what is happening)
+       my @tag_operations;
+       my @badtags;
+       for my $tag (@tags) {
+           if ($tag =~ /^[=+-]$/) {
+               if ($tag eq '=') {
+                   @tag_operations = {tags => [],
+                                      option => [],
+                                     };
+               }
+               elsif ($tag eq '-') {
+                   push @tag_operations,
+                       {tags => [],
+                        option => [remove => 1],
+                       };
+               }
+               elsif ($tag eq '+') {
+                   push @tag_operations,
+                       {tags => [],
+                        option => [add => 1],
+                       };
+               }
+               next;
+           }
            if (not defined first {$_ eq $tag} @{$config{tags}}) {
                push @badtags, $tag;
+               next;
            }
+           if (not @tag_operations) {
+               @tag_operations = {tags => [],
+                                  option => [add => 1],
+                                 };
+           }
+           push @{$tag_operations[-1]{tags}},$tag;
        }
        if (@badtags) {
             print {$transcript} "Unknown tag/s: ".join(', ', @badtags).".\n".
@@ -804,25 +832,27 @@ END
            $errors++;
        }
        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,
-                   );
+           for my $operation (@tag_operations) {
+               set_tag(@common_control_options,
+                       bug => $ref,
+                       tag => [@{$operation->{tags}}],
+                       warn_on_bad_tags => 0, # don't warn on bad tags,
+                       # 'cause we do that above
+                       @{$operation->{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: $@";
+           print {$transcript} "Failed to alter tags of $config{bug} $ref: ".cleanup_eval_fail($@,$debug)."\n";
        }
     } elsif (m/^(un)?block\s+\#?(-?\d+)\s+(?:by|with)\s+(\S.*)?$/i) {
        $ok++;
         $ref= $2;
        my $add_remove = defined $1 && $1 eq 'un';
-       my @blockers = split /[\s,]+/, $3;
+       my @blockers = map {exists $clonebugs{$_}?$clonebugs{$_}:$_} split /[\s,]+/, $3;
        $ref = $clonebugs{$ref} if exists $clonebugs{$ref};
        $bug_affected{$ref} = 1;
        eval {
@@ -834,7 +864,7 @@ END
        };
        if ($@) {
            $errors++;
-           print {$transcript} "Failed to set blocking bugs of $ref: $@";
+           print {$transcript} "Failed to set blocking bugs of $ref: ".cleanup_eval_fail($@,$debug)."\n";
        }
     } elsif (m/^retitle\s+\#?(-?\d+)\s+(\S.*\S)\s*$/i) {
         $ok++;
@@ -849,7 +879,7 @@ END
        };
        if ($@) {
            $errors++;
-           print {$transcript} "Failed to set the title of $ref: $@";
+           print {$transcript} "Failed to set the title of $ref: ".cleanup_eval_fail($@,$debug)."\n";
        }
     } elsif (m/^unmerge\s+\#?(-?\d+)$/i) {
        $ok++;
@@ -1080,11 +1110,42 @@ END
        my @pkgs = split /\s+/, $1;
        if (scalar(@pkgs) > 0) {
                %limit_pkgs = map { ($_, 1) } @pkgs;
-               print {$transcript} "Ignoring bugs not assigned to: " .
-                       join(" ", keys(%limit_pkgs)) . "\n\n";
+               $limit{package} = [@pkgs];
+               print {$transcript} "Limiting to bugs with field 'package' containing at least one of ".join(', ',map {qq('$_')} @pkgs)."\n";
+               print {$transcript} "Limit currently set to ";
+               for my $limit_field (keys %limit) {
+                   print {$transcript} "  '$limit_field':".join(', ',map {qq('$_')} @{$limit{$limit_field}})."\n";
+               }
+               print {$transcript} "\n";
        } else {
-               %limit_pkgs = ();
-               print {$transcript} "Not ignoring any bugs.\n\n";
+           %limit_pkgs = ();
+           $limit{package} = [];
+           print {$transcript} "Limit cleared.\n\n";
+       }
+    } elsif (m/^limit\:?\s+(\S.*\S)\s*$/) {
+       $ok++;
+       my ($field,@options) = split /\s+/, $1;
+       $field = lc($field);
+       if ($field =~ /^(?:clear|unset|blank)$/) {
+           %limit = ();
+           print {$transcript} "Limit cleared.\n\n";
+       }
+       elsif (exists $Debbugs::Status::fields{$field} ) {
+           # %limit can actually contain regexes, but because they're
+           # not evaluated in Safe, DO NOT allow them through without
+           # fixing this.
+           $limit{$field} = [@options];
+           print {$transcript} "Limiting to bugs with field '$field' containing at least one of ".join(', ',map {qq('$_')} @options)."\n";
+           print {$transcript} "Limit currently set to ";
+           for my $limit_field (keys %limit) {
+               print {$transcript} "  '$limit_field':".join(', ',map {qq('$_')} @{$limit{$limit_field}})."\n";
+           }
+           print {$transcript} "\n";
+       }
+       else {
+           print {$transcript} "Limit key $field not understood. Stopping processing here.\n\n";
+           $errors++;
+           last;
        }
     } elsif (m/^affects?\s+\#?(-?\d+)(?:\s+((?:[=+-])?)\s*(\S.*)?)?\s*$/i) {
        $ok++;
@@ -1103,7 +1164,7 @@ END
        };
        if ($@) {
            $errors++;
-           print {$transcript} "Failed to mark $ref as affecting package(s): $@";
+           print {$transcript} "Failed to mark $ref as affecting package(s): ".cleanup_eval_fail($@,$debug)."\n";
        }
 
     } elsif (m/^summary\s+\#?(-?\d+)\s*(\d+|)\s*$/i) {
@@ -1120,7 +1181,7 @@ END
        };
        if ($@) {
            $errors++;
-           print {$transcript} "Failed to give $ref a summary: $@";
+           print {$transcript} "Failed to give $ref a summary: ".cleanup_eval_fail($@,$debug)."\n";
        }
 
     } elsif (m/^owner\s+\#?(-?\d+)\s+((?:\S.*\S)|\!)\s*$/i) {
@@ -1140,7 +1201,7 @@ END
        };
        if ($@) {
            $errors++;
-           print {$transcript} "Failed to mark $ref as having an owner: $@";
+           print {$transcript} "Failed to mark $ref as having an owner: ".cleanup_eval_fail($@,$debug)."\n";
        }
     } elsif (m/^noowner\s+\#?(-?\d+)\s*$/i) {
         $ok++;
@@ -1155,7 +1216,7 @@ END
        };
        if ($@) {
            $errors++;
-           print {$transcript} "Failed to mark $ref as not having an owner: $@";
+           print {$transcript} "Failed to mark $ref as not having an owner: ".cleanup_eval_fail($@,$debug)."\n";
        }
     } elsif (m/^unarchive\s+#?(\d+)$/i) {
         $ok++;