зеркало из https://github.com/mozilla/gecko-dev.git
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:
Родитель
c90a5da673
Коммит
e9b9a129a7
|
@ -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>
|
||||||
|
|
Загрузка…
Ссылка в новой задаче