diff options
-rw-r--r-- | CGI.pl | 31 | ||||
-rwxr-xr-x | checksetup.pl | 4 | ||||
-rwxr-xr-x | post_bug.cgi | 108 | ||||
-rwxr-xr-x | process_bug.cgi | 54 | ||||
-rwxr-xr-x | processmail | 16 | ||||
-rw-r--r-- | template/en/default/bug/create/create.html.tmpl | 16 |
6 files changed, 186 insertions, 43 deletions
@@ -894,6 +894,37 @@ sub CheckIfVotedConfirmed { } } +sub LogActivityEntry { + my ($i,$col,$removed,$added,$whoid,$timestamp) = @_; + # in the case of CCs, deps, and keywords, there's a possibility that someone # might try to add or remove a lot of them at once, which might take more + # space than the activity table allows. We'll solve this by splitting it + # into multiple entries if it's too long. + while ($removed || $added) { + my ($removestr, $addstr) = ($removed, $added); + if (length($removestr) > 254) { + my $commaposition = FindWrapPoint($removed, 254); + $removestr = substr($removed,0,$commaposition); + $removed = substr($removed,$commaposition); + $removed =~ s/^[,\s]+//; # remove any comma or space + } else { + $removed = ""; # no more entries + } + if (length($addstr) > 254) { + my $commaposition = FindWrapPoint($added, 254); + $addstr = substr($added,0,$commaposition); + $added = substr($added,$commaposition); + $added =~ s/^[,\s]+//; # remove any comma or space + } else { + $added = ""; # no more entries + } + $addstr = SqlQuote($addstr); + $removestr = SqlQuote($removestr); + my $fieldid = GetFieldID($col); + SendSQL("INSERT INTO bugs_activity " . + "(bug_id,who,bug_when,fieldid,removed,added) VALUES " . + "($i,$whoid," . SqlQuote($timestamp) . ",$fieldid,$removestr,$addstr)"); + } +} sub GetBugActivity { my ($id, $starttime) = (@_); diff --git a/checksetup.pl b/checksetup.pl index c44c03235..5f7ca5326 100755 --- a/checksetup.pl +++ b/checksetup.pl @@ -1836,8 +1836,8 @@ AddFDef("reporter", "ReportedBy", 1); AddFDef("votes", "Votes", 0); AddFDef("qa_contact", "QAContact", 1); AddFDef("cc", "CC", 1); -AddFDef("dependson", "BugsThisDependsOn", 0); -AddFDef("blocked", "OtherBugsDependingOnThis", 0); +AddFDef("dependson", "BugsThisDependsOn", 1); +AddFDef("blocked", "OtherBugsDependingOnThis", 1); AddFDef("attachments.description", "Attachment description", 0); AddFDef("attachments.thedata", "Attachment data", 0); AddFDef("attachments.filename", "Attachment filename", 0); diff --git a/post_bug.cgi b/post_bug.cgi index d519a484c..882bd3dd9 100755 --- a/post_bug.cgi +++ b/post_bug.cgi @@ -49,7 +49,7 @@ sub sillyness { use vars qw($vars $template); ConnectToDatabase(); -confirm_login(); +my $whoid = confirm_login(); # The format of the initial comment can be structured by adding fields to the @@ -231,6 +231,77 @@ if ($::FORM{'keywords'} && UserInGroup("editbugs")) { } } +# Check for valid dependency info. +foreach my $field ("dependson", "blocked") { + if (UserInGroup("editbugs") && defined($::FORM{$field}) && + $::FORM{$field} ne "") { + my @validvalues; + foreach my $id (split(/[\s,]+/, $::FORM{$field})) { + next unless $id; + ValidateBugID($id, 1); + push(@validvalues, $id); + } + $::FORM{$field} = join(",", @validvalues); + } +} +# Gather the dependecy list, and make sure there are no circular refs +my %deps; +if (UserInGroup("editbugs") && defined($::FORM{'dependson'})) { + my $me = "blocked"; + my $target = "dependson"; + my %deptree; + for (1..2) { + $deptree{$target} = []; + my %seen; + foreach my $i (split('[\s,]+', $::FORM{$target})) { + if (!exists $seen{$i}) { + push(@{$deptree{$target}}, $i); + $seen{$i} = 1; + } + } + # populate $deps{$target} as first-level deps only. + # and find remainder of dependency tree in $deptree{$target} + @{$deps{$target}} = @{$deptree{$target}}; + my @stack = @{$deps{$target}}; + while (@stack) { + my $i = shift @stack; + SendSQL("select $target from dependencies where $me = " . + SqlQuote($i)); + while (MoreSQLData()) { + my $t = FetchOneColumn(); + if (!exists $seen{$t}) { + push(@{$deptree{$target}}, $t); + push @stack, $t; + $seen{$t} = 1; + } + } + } + + if ($me eq 'dependson') { + my @deps = @{$deptree{'dependson'}}; + my @blocks = @{$deptree{'blocked'}}; + my @union = (); + my @isect = (); + my %union = (); + my %isect = (); + foreach my $b (@deps, @blocks) { $union{$b}++ && $isect{$b}++ } + @union = keys %union; + @isect = keys %isect; + if (@isect > 0) { + my $both; + foreach my $i (@isect) { + $both = $both . GetBugLink($i, "#" . $i) . " "; + } + $vars->{'both'} = $both; + ThrowUserError("dependency_loop_multi", undef, "abort"); + } + } + my $tmp = $me; + $me = $target; + $target = $tmp; + } +} + # Build up SQL string to add bug. my $sql = "INSERT INTO bugs " . "(" . join(",", @used_fields) . ", reporter, creation_ts, " . @@ -300,6 +371,9 @@ SendSQL("LOCK TABLES bugs WRITE, bug_group_map WRITE, longdescs WRITE, cc WRITE, # Add the bug report to the DB. SendSQL($sql); +SendSQL("select now()"); +my $timestamp = FetchOneColumn(); + # Get the bug ID back. SendSQL("select LAST_INSERT_ID()"); my $id = FetchOneColumn(); @@ -319,11 +393,28 @@ foreach my $ccid (keys(%ccids)) { SendSQL("INSERT INTO cc (bug_id, who) VALUES ($id, $ccid)"); } +my @all_deps; if (UserInGroup("editbugs")) { foreach my $keyword (@keywordlist) { SendSQL("INSERT INTO keywords (bug_id, keywordid) VALUES ($id, $keyword)"); } + if (defined $::FORM{'dependson'}) { + my $me = "blocked"; + my $target = "dependson"; + for (1..2) { + foreach my $i (@{$deps{$target}}) { + SendSQL("INSERT INTO dependencies ($me, $target) values " . + "($id, $i)"); + push(@all_deps, $i); # list for mailing dependent bugs + # Log the activity for the other bug: + LogActivityEntry($i, $me, "", $id, $whoid, $timestamp); + } + my $tmp = $me; + $me = $target; + $target = $tmp; + } + } } SendSQL("UNLOCK TABLES") if Param("shadowdb"); @@ -360,6 +451,21 @@ print "Content-type: text/html\n\n"; $template->process("bug/create/created.html.tmpl", $vars) || ThrowTemplateError($template->error()); +foreach my $i (@all_deps) { + $vars->{'mail'} = ""; + open(PMAIL, "-|") or exec('./processmail', $i, $::COOKIE{'Bugzilla_login'}); $vars->{'mail'} .= $_ while <PMAIL>; + close(PMAIL); + + $vars->{'id'} = $i; + $vars->{'type'} = "dep"; + + # Let the user know we checked to see if we should email notice + # of this new bug to users with a relationship to the depenedant + # bug and who did and didn't receive email about it + $template->process("bug/process/results.html.tmpl", $vars) + || ThrowTemplateError($template->error()); +} + $::FORM{'id'} = $id; show_bug("header is already done"); diff --git a/process_bug.cgi b/process_bug.cgi index 43895ced3..427e622c4 100755 --- a/process_bug.cgi +++ b/process_bug.cgi @@ -1013,49 +1013,16 @@ sub FindWrapPoint { return $wrappoint; } -sub LogActivityEntry { - my ($i,$col,$removed,$added) = @_; - # in the case of CCs, deps, and keywords, there's a possibility that someone - # might try to add or remove a lot of them at once, which might take more - # space than the activity table allows. We'll solve this by splitting it - # into multiple entries if it's too long. - while ($removed || $added) { - my ($removestr, $addstr) = ($removed, $added); - if (length($removestr) > 254) { - my $commaposition = FindWrapPoint($removed, 254); - $removestr = substr($removed,0,$commaposition); - $removed = substr($removed,$commaposition); - $removed =~ s/^[,\s]+//; # remove any comma or space - } else { - $removed = ""; # no more entries - } - if (length($addstr) > 254) { - my $commaposition = FindWrapPoint($added, 254); - $addstr = substr($added,0,$commaposition); - $added = substr($added,$commaposition); - $added =~ s/^[,\s]+//; # remove any comma or space - } else { - $added = ""; # no more entries - } - $addstr = SqlQuote($addstr); - $removestr = SqlQuote($removestr); - my $fieldid = GetFieldID($col); - SendSQL("INSERT INTO bugs_activity " . - "(bug_id,who,bug_when,fieldid,removed,added) VALUES " . - "($i,$whoid," . SqlQuote($timestamp) . ",$fieldid,$removestr,$addstr)"); - $bug_changed = 1; - } -} - sub LogDependencyActivity { my ($i, $oldstr, $target, $me) = (@_); my $newstr = SnapShotDeps($i, $target, $me); if ($oldstr ne $newstr) { # Figure out what's really different... my ($removed, $added) = DiffStrings($oldstr, $newstr); - LogActivityEntry($i,$target,$removed,$added); + LogActivityEntry($i,$target,$removed,$added,$whoid,$timestamp); # update timestamp on target bug so midairs will be triggered SendSQL("UPDATE bugs SET delta_ts=NOW() WHERE bug_id=$i"); + $bug_changed = 1; return 1; } return 0; @@ -1210,7 +1177,9 @@ foreach my $id (@idlist) { AppendComment($id, $::COOKIE{'Bugzilla_login'}, $::FORM{'comment'}, $::FORM{'commentprivacy'}, $timestamp, $::FORM{'work_time'}); if ($::FORM{'work_time'} != 0) { - LogActivityEntry($id, "work_time", "", $::FORM{'work_time'}); + LogActivityEntry($id, "work_time", "", $::FORM{'work_time'}, + $whoid, $timestamp); + $bug_changed = 1; } } } @@ -1278,7 +1247,9 @@ foreach my $id (@idlist) { my $groupDelNames = join(',', @groupDelNames); my $groupAddNames = join(',', @groupAddNames); - LogActivityEntry($id, "bug_group", $groupDelNames, $groupAddNames); + LogActivityEntry($id, "bug_group", $groupDelNames, $groupAddNames, + $whoid, $timestamp); + $bug_changed = 1; my $removedCcString = ""; if (defined $::FORM{newcc} || defined $::FORM{removecc} || defined $::FORM{masscc}) { @@ -1313,7 +1284,8 @@ foreach my $id (@idlist) { if (scalar(@removed) || scalar(@added)) { my $removed = join(", ", @removed); my $added = join(", ", @added); - LogActivityEntry($id,"cc",$removed,$added); + LogActivityEntry($id,"cc",$removed,$added,$whoid,$timestamp); + $bug_changed = 1; } } @@ -1499,7 +1471,8 @@ foreach my $id (@idlist) { RemoveVotes($id, 0, "This bug has been moved to a different product"); } - LogActivityEntry($id,$col,$old,$new); + LogActivityEntry($id,$col,$old,$new,$whoid,$timestamp); + $bug_changed = 1; } } # Set and update flags. @@ -1553,7 +1526,8 @@ foreach my $id (@idlist) { unless ($isreporter || $isoncc || ! $::FORM{'confirm_add_duplicate'}) { # The reporter is oblivious to the existence of the new bug and is permitted access # ... add 'em to the cc (and record activity) - LogActivityEntry($duplicate,"cc","",DBID_to_name($reporter)); + LogActivityEntry($duplicate,"cc","",DBID_to_name($reporter), + $whoid,$timestamp); SendSQL("INSERT INTO cc (who, bug_id) VALUES ($reporter, " . SqlQuote($duplicate) . ")"); } # Bug 171639 - Duplicate notifications do not need to be private. diff --git a/processmail b/processmail index 3b421e922..fd1f50b62 100755 --- a/processmail +++ b/processmail @@ -131,6 +131,22 @@ sub ProcessOneBug { } $values{'estimated_time'} = FormatTimeUnit($values{'estimated_time'}); + my @dependslist; + SendSQL("SELECT dependson FROM dependencies WHERE + blocked = $id ORDER BY dependson"); + while (MoreSQLData()) { + push(@dependslist, FetchOneColumn()); + } + $values{'dependson'} = join(",", @dependslist); + + my @blockedlist; + SendSQL("SELECT blocked FROM dependencies WHERE + dependson = $id ORDER BY blocked"); + while (MoreSQLData()) { + push(@blockedlist, FetchOneColumn()); + } + $values{'blocked'} = join(",", @blockedlist); + my @diffs; diff --git a/template/en/default/bug/create/create.html.tmpl b/template/en/default/bug/create/create.html.tmpl index 354dd990c..6bc3e5441 100644 --- a/template/en/default/bug/create/create.html.tmpl +++ b/template/en/default/bug/create/create.html.tmpl @@ -203,6 +203,22 @@ <input name="keywords" size="60" value=""> (optional) </td> </tr> + <tr> + <td align="right"> + <strong>Depends on:</strong> + </td> + <td> + <input name="dependson" accesskey="d"> + </td> + </tr> + <tr> + <td align="right"> + <strong>Blocks:</strong> + </td> + <td> + <input name="blocked" accesskey="b"> + </td> + </tr> [% END %] <tr> |