Commit 6b2eec91 authored by terry%mozilla.org's avatar terry%mozilla.org

Patch by "Matt Masson" <matthew@zeroknowledge.com> -- allow definition

of different target milestones by product.
parent c7ae4f65
......@@ -38,6 +38,7 @@ sub bug_form_pl_sillyness {
$zz = @::legal_priority;
$zz = @::legal_resolution_no_dup;
$zz = @::legal_severity;
$zz = %::target_milestone;
}
my $loginok = quietly_check_login();
......@@ -207,14 +208,11 @@ if (Param("usetargetmilestone")) {
if ($url eq "") {
$url = "notargetmilestone.html";
}
if ($bug{'target_milestone'} eq "") {
$bug{'target_milestone'} = " ";
}
push(@::legal_target_milestone, " ");
print "
<TD ALIGN=RIGHT><A href=\"$url\"><B>Target Milestone:</B></A></TD>
<TD><SELECT NAME=target_milestone>" .
make_options(\@::legal_target_milestone,
make_options($::target_milestone{$bug{'product'}},
$bug{'target_milestone'}) .
"</SELECT></TD>";
}
......
......@@ -45,6 +45,7 @@ sub sillyness {
$zz = @::legal_severity;
$zz = @::legal_target_milestone;
$zz = @::versions;
$zz = @::target_milestone;
};
my $serverpush = 0;
......@@ -1232,9 +1233,11 @@ document.write(\" <input type=button value=\\\"Uncheck All\\\" onclick=\\\"SetCh
</TR>";
if (Param("usetargetmilestone")) {
push(@::legal_target_milestone, " ");
my $tfm_popup = make_options(\@::legal_target_milestone,
$::dontchange);
my @legal_milestone;
if(1 == @prod_list) {
@legal_milestone = @{$::target_milestone{$prod_list[0]}};
}
my $tfm_popup = make_options(\@legal_milestone, $::dontchange);
print "
<TR>
<TD ALIGN=RIGHT><B>Target milestone:</B></TD>
......
......@@ -752,6 +752,12 @@ $table{keyworddefs} =
unique(name)';
$table{milestones} =
'value varchar(190) not null,
product varchar(64) not null,
sortkey smallint not null,
unique (product, value)';
$table{shadowlog} =
'id int not null auto_increment primary key,
ts timestamp,
......@@ -1493,6 +1499,44 @@ AddField('products', 'votestoconfirm', 'smallint not null');
AddField('profiles', 'blessgroupset', 'bigint not null');
# 2000-03-21 Adding a table for target milestones to
# database - matthew@zeroknowledge.com
$sth = $dbh->prepare("SELECT count(*) from milestones");
$sth->execute();
if (!($sth->fetchrow_arrayref()->[0])) {
print "Replacing blank milestones...\n";
$dbh->do("UPDATE bugs SET target_milestone = '---', delta_ts=delta_ts WHERE target_milestone = ' '");
# Populate milestone table with all exisiting values in database
$sth = $dbh->prepare("SELECT DISTINCT target_milestone, product FROM bugs");
$sth->execute();
print "Populating milestones table...\n";
my $value;
my $product;
while(($value, $product) = $sth->fetchrow_array())
{
# check if the value already exists
my $sortkey = substr($value, 1);
if ($sortkey !~ /^\d+$/) {
$sortkey = 0;
} else {
$sortkey *= 10;
}
$value = $dbh->quote($value);
$product = $dbh->quote($product);
my $s2 = $dbh->prepare("SELECT value FROM milestones WHERE value = $value AND product = $product");
$s2->execute();
if(!$s2->fetchrow_array())
{
$dbh->do("INSERT INTO milestones(value, product, sortkey) VALUES($value, $product, $sortkey)");
}
}
}
#
# If you had to change the --TABLE-- definition in any way, then add your
# differential change code *** A B O V E *** this comment.
......
......@@ -485,6 +485,29 @@ if ($action eq 'del') {
print "<FONT COLOR=\"red\">missing</FONT>";
}
#
# Adding listing for associated target milestones - matthew@zeroknowledge.com
#
if (Param('usetargetmilestone')) {
print "</TD>\n</TR><TR>\n";
print " <TH ALIGN=\"right\" VALIGN=\"top\"><A HREF=\"editmilestones.cgi?product=", url_quote($product), "\">Edit milestones:</A></TH>\n";
print " <TD>";
SendSQL("SELECT value
FROM milestones
WHERE product=" . SqlQuote($product) . "
ORDER BY sortkey,value");
if(MoreSQLData()) {
my $br = 0;
while ( MoreSQLData() ) {
my ($milestone) = FetchSQLData();
print "<BR>" if $br;
print $milestone;
$br = 1;
}
} else {
print "<FONT COLOR=\"red\">missing</FONT>";
}
}
print "</TD>\n</TR><TR>\n";
print " <TD VALIGN=\"top\">Bugs:</TD>\n";
......@@ -548,7 +571,8 @@ if ($action eq 'delete') {
versions WRITE,
products WRITE,
groups WRITE,
profiles WRITE");
profiles WRITE,
milestones WRITE");
# According to MySQL doc I cannot do a DELETE x.* FROM x JOIN Y,
# so I have to iterate over bugs and delete all the indivial entries
......@@ -589,6 +613,11 @@ if ($action eq 'delete') {
WHERE program=" . SqlQuote($product));
print "Versions deleted.<P>\n";
# deleting associated target milestones - matthew@zeroknowledge.com
SendSQL("DELETE FROM milestones
WHERE product=" . SqlQuote($product));
print "Milestones deleted.<BR>\n";
SendSQL("DELETE FROM products
WHERE product=" . SqlQuote($product));
print "Product '$product' deleted.<BR>\n";
......@@ -700,6 +729,29 @@ if ($action eq 'edit') {
print "<FONT COLOR=\"red\">missing</FONT>";
}
#
# Adding listing for associated target milestones - matthew@zeroknowledge.com
#
if (Param('usetargetmilestone')) {
print "</TD>\n</TR><TR>\n";
print " <TH ALIGN=\"right\" VALIGN=\"top\"><A HREF=\"editmilestones.cgi?product=", url_quote($product), "\">Edit milestones:</A></TH>\n";
print " <TD>";
SendSQL("SELECT value
FROM milestones
WHERE product=" . SqlQuote($product) . "
ORDER BY sortkey,value");
if(MoreSQLData()) {
my $br = 0;
while ( MoreSQLData() ) {
my ($milestone) = FetchSQLData();
print "<BR>" if $br;
print $milestone;
$br = 1;
}
} else {
print "<FONT COLOR=\"red\">missing</FONT>";
}
}
print "</TD>\n</TR><TR>\n";
print " <TH ALIGN=\"right\">Bugs:</TH>\n";
......@@ -782,7 +834,8 @@ if ($action eq 'update') {
products WRITE,
versions WRITE,
groups WRITE,
profiles WRITE");
profiles WRITE,
milestones WRITE");
if ($disallownew ne $disallownewold) {
$disallownew ||= 0;
......@@ -923,6 +976,7 @@ if ($action eq 'update') {
SendSQL("UPDATE components SET program=$qp WHERE program=$qpold");
SendSQL("UPDATE products SET product=$qp WHERE product=$qpold");
SendSQL("UPDATE versions SET program=$qp WHERE program=$qpold");
SendSQL("UPDATE milestones SET product=$qp WHERE product=$qpold");
# Need to do an update to groups as well. If there is a corresponding
# bug group, whether usebuggroups is currently set or not, we want to
# update it so it will match in the future. If there is no group, this
......
......@@ -260,7 +260,23 @@ sub Version_element {
return make_popup("version", $versionlist, $defversion, 1, $onchange);
}
sub Milestone_element {
my ($tm, $prod, $onchange) = (@_);
my $tmlist;
if (!defined $::target_milestone{$prod}) {
$tmlist = [];
} else {
$tmlist = $::target_milestone{$prod};
}
my $deftm = $tmlist->[0];
if (lsearch($tmlist, $tm) >= 0) {
$deftm = $tm;
}
return make_popup("target_milestone", $tmlist, $deftm, 1, $onchange);
}
# Generate a string which, when later interpreted by the Perl compiler, will
# be the same as the given string.
......@@ -427,11 +443,24 @@ sub GenerateVersionTable {
print FID GenerateCode('$::anyvotesallowed');
if ($dotargetmilestone) {
my $last = Param("nummilestones");
my $i;
for ($i=1 ; $i<=$last ; $i++) {
push(@::legal_target_milestone, "M$i");
# reading target milestones in from the database - matthew@zeroknowledge.com
SendSQL("SELECT value, product FROM milestones ORDER BY sortkey, value");
my @line;
my %tmarray;
@::legal_target_milestone = ();
while(@line = FetchSQLData()) {
my ($tm, $pr) = (@line);
if (!defined $::target_milestone{$pr}) {
$::target_milestone{$pr} = [];
}
push @{$::target_milestone{$pr}}, $tm;
if (!exists $tmarray{$tm}) {
$tmarray{$tm} = 1;
push(@::legal_target_milestone, $tm);
}
}
print FID GenerateCode('%::target_milestone');
print FID GenerateCode('@::legal_target_milestone');
print FID GenerateCode('%::milestoneurl');
}
......
......@@ -39,6 +39,7 @@ use vars %::versions,
%::legal_opsys,
%::legal_platform,
%::legal_priority,
%::target_milestone,
%::legal_severity;
my $whoid = confirm_login();
......@@ -53,6 +54,11 @@ if ( Param("strictvaluechecks") ) {
CheckFormFieldDefined(\%::FORM, 'product');
CheckFormFieldDefined(\%::FORM, 'version');
CheckFormFieldDefined(\%::FORM, 'component');
# check if target milestone is defined - matthew@zeroknowledge.com
if ( Param("usetargetmilestone") ) {
CheckFormFieldDefined(\%::FORM, 'target_milestone');
}
}
if ($::FORM{'product'} ne $::dontchange) {
......@@ -71,12 +77,18 @@ if ($::FORM{'product'} ne $::dontchange) {
#
my $vok = lsearch($::versions{$prod}, $::FORM{'version'}) >= 0;
my $cok = lsearch($::components{$prod}, $::FORM{'component'}) >= 0;
if (!$vok || !$cok) {
print "<H1>Changing product means changing version and component.</H1>\n";
print "You have chosen a new product, and now the version and/or\n";
my $mok = 1; # so it won't affect the 'if' statement if milestones aren't used
if ( Param("usetargetmilestone") ) {
$mok = lsearch($::target_milestone{$prod}, $::FORM{'target_milestone'}) >= 0;
}
if (!$vok || !$cok || !$mok) {
print "<H1>Changing product means changing version, target milestone and component.</H1>\n";
print "You have chosen a new product, and now the version, target milestone and/or\n";
print "component fields are not correct. (Or, possibly, the bug did\n";
print "not have a valid component or version field in the first place.)\n";
print "Anyway, please set the version and component now.<p>\n";
print "not have a valid target milestone, component or version field in the first place.)\n";
print "Anyway, please set the version, target milestone and component now.<p>\n";
print "<form>\n";
print "<table>\n";
print "<tr>\n";
......@@ -86,12 +98,19 @@ if ($::FORM{'product'} ne $::dontchange) {
print "<td align=right><b>Version:</b></td>\n";
print "<td>" . Version_element($::FORM{'version'}, $prod) . "</td>\n";
print "</tr><tr>\n";
if ( Param("usetargetmilestone") ) {
print "<td align=right><b>Target Milestone:</b></td>\n";
print "<td>" . Milestone_element($::FORM{'target_milestone'}, $prod) . "</td>\n";
print "</tr><tr>\n";
}
print "<td align=right><b>Component:</b></td>\n";
print "<td>" . Component_element($::FORM{'component'}, $prod) . "</td>\n";
print "</tr>\n";
print "</table>\n";
foreach my $i (keys %::FORM) {
if ($i ne 'version' && $i ne 'component') {
if ($i ne 'version' && $i ne 'component' && $i ne 'target_milestone') {
print "<input type=hidden name=$i value=\"" .
value_quote($::FORM{$i}) . "\">\n";
}
......
......@@ -282,12 +282,14 @@ my $jscript = << 'ENDSCRIPT';
<!--
var cpts = new Array();
var vers = new Array();
var tms = new Array();
ENDSCRIPT
my $p;
my $v;
my $c;
my $m;
my $i = 0;
my $j = 0;
......@@ -299,6 +301,10 @@ foreach $v (@::legal_versions) {
$jscript .= "vers['$v'] = new Array();\n";
}
my $tm;
foreach $tm (@::legal_target_milestone) {
$jscript .= "tms['$tm'] = new Array();\n";
}
for $p (@::legal_product) {
if ($::components{$p}) {
......@@ -312,6 +318,12 @@ for $p (@::legal_product) {
$jscript .= "vers['$v'][vers['$v'].length] = '$p';\n";
}
}
if ($::target_milestone{$p}) {
foreach $m (@{$::target_milestone{$p}}) {
$jscript .= "tms['$m'][tms['$m'].length] = '$p';\n";
}
}
}
$i = 0;
......@@ -404,8 +416,39 @@ function selectProduct(f) {
}
}
var tmsel = new Array();
for (i=0 ; i<f.target_milestone.length ; i++) {
if (f.target_milestone[i].selected) {
tmsel[f.target_milestone[i].value] = 1;
}
}
f.target_milestone.options.length = 0;
for (tm in tms) {
if (typeof(tms[v]) == 'function') continue;
var doit = doall;
for (i=0 ; !doit && i<f.product.length ; i++) {
if (f.product[i].selected) {
var p = f.product[i].value;
for (j in tms[tm]) {
if (typeof(tms[tm][j]) == 'function') continue;
var p2 = tms[tm][j];
if (p2 == p) {
doit = true;
break;
}
}
}
}
if (doit) {
var l = f.target_milestone.length;
f.target_milestone[l] = new Option(tm, tm);
if (tmsel[tm]) {
f.target_milestone[l].selected = true;
}
}
}
}
// -->
......@@ -431,7 +474,6 @@ PutHeader("Bugzilla Query Page", "Query",
0, $jscript);
push @::legal_resolution, "---"; # Oy, what a hack.
push @::legal_target_milestone, "---"; # Oy, what a hack.
my @logfields = ("[Bug creation]", @::log_columns);
......
......@@ -194,6 +194,25 @@ foreach my $ref (@checklist) {
}
}
# Adding check for Target Milestones / products - matthew@zeroknowledge.com
Status("Checking milestone/products");
@checklist = ();
SendSQL("select distinct product, target_milestone from bugs");
while (@row = FetchSQLData()) {
my @copy = @row;
push(@checklist, \@copy);
}
foreach my $ref (@checklist) {
my ($product, $milestone) = (@$ref);
SendSQL("SELECT count(*) FROM milestones WHERE product = '$product' AND value = '$milestone'");
if(FetchOneColumn() != 1) {
Alert("Bug(s) found with invalud product/milestone: $product/$milestone");
}
}
Status("Checking components/products");
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment