summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorbugreport%peshkin.net <>2002-10-17 13:31:49 +0200
committerbugreport%peshkin.net <>2002-10-17 13:31:49 +0200
commitdc892b1118b931cb2b616a7c5158995f97960d22 (patch)
treeaaf3b348692d622fb638048dc0756679ffdaadb0
parentd69b9a45e9b7031fc569ca1970abd012a84fede1 (diff)
downloadbugzilla-dc892b1118b931cb2b616a7c5158995f97960d22.tar.gz
bugzilla-dc892b1118b931cb2b616a7c5158995f97960d22.tar.xz
Bug 112373 you should be able to enter bug dependencies/blockers when you enter a bug.
patch by jhedlund r,2xr=joel
-rw-r--r--CGI.pl31
-rwxr-xr-xchecksetup.pl4
-rwxr-xr-xpost_bug.cgi108
-rwxr-xr-xprocess_bug.cgi54
-rwxr-xr-xprocessmail16
-rw-r--r--template/en/default/bug/create/create.html.tmpl16
6 files changed, 186 insertions, 43 deletions
diff --git a/CGI.pl b/CGI.pl
index 24c006c03..6ca5f2588 100644
--- a/CGI.pl
+++ b/CGI.pl
@@ -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>