Bug 112373 you should be able to enter bug dependencies/blockers when you enter a bug.

patch by jhedlund
r,2xr=joel
This commit is contained in:
bugreport%peshkin.net 2002-10-17 04:31:56 +00:00
Родитель c90a5da673
Коммит e9b9a129a7
6 изменённых файлов: 186 добавлений и 43 удалений

Просмотреть файл

@ -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 { sub GetBugActivity {
my ($id, $starttime) = (@_); my ($id, $starttime) = (@_);

Просмотреть файл

@ -1836,8 +1836,8 @@ AddFDef("reporter", "ReportedBy", 1);
AddFDef("votes", "Votes", 0); AddFDef("votes", "Votes", 0);
AddFDef("qa_contact", "QAContact", 1); AddFDef("qa_contact", "QAContact", 1);
AddFDef("cc", "CC", 1); AddFDef("cc", "CC", 1);
AddFDef("dependson", "BugsThisDependsOn", 0); AddFDef("dependson", "BugsThisDependsOn", 1);
AddFDef("blocked", "OtherBugsDependingOnThis", 0); AddFDef("blocked", "OtherBugsDependingOnThis", 1);
AddFDef("attachments.description", "Attachment description", 0); AddFDef("attachments.description", "Attachment description", 0);
AddFDef("attachments.thedata", "Attachment data", 0); AddFDef("attachments.thedata", "Attachment data", 0);
AddFDef("attachments.filename", "Attachment filename", 0); AddFDef("attachments.filename", "Attachment filename", 0);

Просмотреть файл

@ -49,7 +49,7 @@ sub sillyness {
use vars qw($vars $template); use vars qw($vars $template);
ConnectToDatabase(); ConnectToDatabase();
confirm_login(); my $whoid = confirm_login();
# The format of the initial comment can be structured by adding fields to the # 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. # Build up SQL string to add bug.
my $sql = "INSERT INTO bugs " . my $sql = "INSERT INTO bugs " .
"(" . join(",", @used_fields) . ", reporter, creation_ts, " . "(" . 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. # Add the bug report to the DB.
SendSQL($sql); SendSQL($sql);
SendSQL("select now()");
my $timestamp = FetchOneColumn();
# Get the bug ID back. # Get the bug ID back.
SendSQL("select LAST_INSERT_ID()"); SendSQL("select LAST_INSERT_ID()");
my $id = FetchOneColumn(); my $id = FetchOneColumn();
@ -319,11 +393,28 @@ foreach my $ccid (keys(%ccids)) {
SendSQL("INSERT INTO cc (bug_id, who) VALUES ($id, $ccid)"); SendSQL("INSERT INTO cc (bug_id, who) VALUES ($id, $ccid)");
} }
my @all_deps;
if (UserInGroup("editbugs")) { if (UserInGroup("editbugs")) {
foreach my $keyword (@keywordlist) { foreach my $keyword (@keywordlist) {
SendSQL("INSERT INTO keywords (bug_id, keywordid) SendSQL("INSERT INTO keywords (bug_id, keywordid)
VALUES ($id, $keyword)"); 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"); 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) $template->process("bug/create/created.html.tmpl", $vars)
|| ThrowTemplateError($template->error()); || 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; $::FORM{'id'} = $id;
show_bug("header is already done"); show_bug("header is already done");

Просмотреть файл

@ -1013,49 +1013,16 @@ sub FindWrapPoint {
return $wrappoint; 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 { sub LogDependencyActivity {
my ($i, $oldstr, $target, $me) = (@_); my ($i, $oldstr, $target, $me) = (@_);
my $newstr = SnapShotDeps($i, $target, $me); my $newstr = SnapShotDeps($i, $target, $me);
if ($oldstr ne $newstr) { if ($oldstr ne $newstr) {
# Figure out what's really different... # Figure out what's really different...
my ($removed, $added) = DiffStrings($oldstr, $newstr); 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 # update timestamp on target bug so midairs will be triggered
SendSQL("UPDATE bugs SET delta_ts=NOW() WHERE bug_id=$i"); SendSQL("UPDATE bugs SET delta_ts=NOW() WHERE bug_id=$i");
$bug_changed = 1;
return 1; return 1;
} }
return 0; return 0;
@ -1210,7 +1177,9 @@ foreach my $id (@idlist) {
AppendComment($id, $::COOKIE{'Bugzilla_login'}, $::FORM{'comment'}, AppendComment($id, $::COOKIE{'Bugzilla_login'}, $::FORM{'comment'},
$::FORM{'commentprivacy'}, $timestamp, $::FORM{'work_time'}); $::FORM{'commentprivacy'}, $timestamp, $::FORM{'work_time'});
if ($::FORM{'work_time'} != 0) { 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 $groupDelNames = join(',', @groupDelNames);
my $groupAddNames = join(',', @groupAddNames); my $groupAddNames = join(',', @groupAddNames);
LogActivityEntry($id, "bug_group", $groupDelNames, $groupAddNames); LogActivityEntry($id, "bug_group", $groupDelNames, $groupAddNames,
$whoid, $timestamp);
$bug_changed = 1;
my $removedCcString = ""; my $removedCcString = "";
if (defined $::FORM{newcc} || defined $::FORM{removecc} || defined $::FORM{masscc}) { if (defined $::FORM{newcc} || defined $::FORM{removecc} || defined $::FORM{masscc}) {
@ -1313,7 +1284,8 @@ foreach my $id (@idlist) {
if (scalar(@removed) || scalar(@added)) { if (scalar(@removed) || scalar(@added)) {
my $removed = join(", ", @removed); my $removed = join(", ", @removed);
my $added = join(", ", @added); 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, RemoveVotes($id, 0,
"This bug has been moved to a different product"); "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. # Set and update flags.
@ -1553,7 +1526,8 @@ foreach my $id (@idlist) {
unless ($isreporter || $isoncc || ! $::FORM{'confirm_add_duplicate'}) { unless ($isreporter || $isoncc || ! $::FORM{'confirm_add_duplicate'}) {
# The reporter is oblivious to the existence of the new bug and is permitted access # The reporter is oblivious to the existence of the new bug and is permitted access
# ... add 'em to the cc (and record activity) # ... 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) . ")"); SendSQL("INSERT INTO cc (who, bug_id) VALUES ($reporter, " . SqlQuote($duplicate) . ")");
} }
# Bug 171639 - Duplicate notifications do not need to be private. # Bug 171639 - Duplicate notifications do not need to be private.

Просмотреть файл

@ -131,6 +131,22 @@ sub ProcessOneBug {
} }
$values{'estimated_time'} = FormatTimeUnit($values{'estimated_time'}); $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; my @diffs;

Просмотреть файл

@ -203,6 +203,22 @@
<input name="keywords" size="60" value=""> (optional) <input name="keywords" size="60" value=""> (optional)
</td> </td>
</tr> </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 %] [% END %]
<tr> <tr>