diff --git a/CGI.pl b/CGI.pl index 356c579e578c1be03850554d1fb2cb360be5fe26..f16640bc1a390e5d9c0b4f72d05483b38dbe5a15 100644 --- a/CGI.pl +++ b/CGI.pl @@ -224,7 +224,11 @@ sub PasswordForLogin { my ($login) = (@_); SendSQL("select cryptpassword from profiles where login_name = " . SqlQuote($login)); - return FetchOneColumn(); + my $result = FetchOneColumn(); + if (!defined $result) { + $result = ""; + } + return $result; } sub confirm_login { @@ -253,7 +257,6 @@ sub confirm_login { exit; } my $realcryptpwd = PasswordForLogin($::FORM{"Bugzilla_login"}); - my $enteredcryptpwd = crypt($enteredpwd, substr($realcryptpwd, 0, 2)); if (defined $::FORM{"PleaseMailAPassword"}) { my $realpwd; @@ -264,6 +267,7 @@ sub confirm_login { SqlQuote($enteredlogin)); $realpwd = FetchOneColumn(); } + my $urlbase = Param("urlbase"); my $template = "From: bugzilla-daemon To: %s Subject: Your bugzilla password. @@ -274,7 +278,7 @@ To use the wonders of bugzilla, you can use the following: Password: %s To change your password, go to: - [Param urlbase]changepassword.cgi + ${urlbase}changepassword.cgi (Your bugzilla and CVS password, if any, are not currently synchronized. Top hackers are working around the clock to fix this, as you read this.) @@ -294,7 +298,8 @@ To use the wonders of bugzilla, you can use the following: print "and enter your password in the form there.\n"; exit; } - + + my $enteredcryptpwd = crypt($enteredpwd, substr($realcryptpwd, 0, 2)); if ($realcryptpwd eq "" || $enteredcryptpwd ne $realcryptpwd) { print "Content-type: text/html\n\n"; print "<H1>Login failed.</H1>\n"; @@ -332,6 +337,9 @@ To use the wonders of bugzilla, you can use the following: $::COOKIE{"Bugzilla_logincookie"} . " and profiles.userid = logincookies.userid"); $loginok = FetchOneColumn(); + if (!defined $loginok) { + $loginok = 0; + } } if ($loginok ne "1") { diff --git a/CHANGES b/CHANGES index 42e2629058a2378301a8eb87484495563fbdb1f7..cba77d560da22140f94adddafefde5609cf93887 100644 --- a/CHANGES +++ b/CHANGES @@ -10,6 +10,142 @@ query the CVS tree. For example, will tell you what has been changed in the last week. +2/8/99 Added FreeBSD to the list of OS's. Feed this to MySQL: + + alter table bugs change column op_sys op_sys enum("All", "Windows 3.1", "Windows 95", "Windows 98", "Windows NT", "Mac System 7", "Mac System 7.5", "Mac System 7.6.1", "Mac System 8.0", "Mac System 8.5", "AIX", "BSDI", "HP-UX", "IRIX", "Linux", "FreeBSD", "OSF/1", "Solaris", "SunOS", "OS/2", "other") not null; + + +2/4/99 Added a new column "description" to the components table, and added +links to a new page which will use this to describe the components of a +given product. Feed this to MySQL: + + alter table components add column description mediumtext not null; + + +2/3/99 Added a new column "initialqacontact" to the components table that gives +an initial QA contact field. It may be empty if you wish the initial qa +contact to be empty. If you're not using the QA contact field, you don't need +to add this column, but you might as well be safe and add it anyway: + + alter table components add column initialqacontact tinytext not null; + + +2/2/99 Added a new column "milestoneurl" to the products table that gives a URL +which is to describe the currently defined milestones for a product. If you +don't use target milestone, you might be able to get away without adding this +column, but you might as well be safe and add it anyway: + + alter table products add column milestoneurl tinytext not null; + + +1/29/99 Whoops; had a mispelled op_sys. It was "Mac System 7.1.6"; it should +be "Mac System 7.6.1". It turns out I had no bugs with this value set, so I +could just do the below simple command. If you have bugs with this value, you +may need to do something more complicated. + + alter table bugs change column op_sys op_sys enum("All", "Windows 3.1", "Windows 95", "Windows 98", "Windows NT", "Mac System 7", "Mac System 7.5", "Mac System 7.6.1", "Mac System 8.0", "Mac System 8.5", "AIX", "BSDI", "HP-UX", "IRIX", "Linux", "OSF/1", "Solaris", "SunOS", "OS/2", "other") not null; + + + +1/20/99 Added new fields: Target Milestone, QA Contact, and Status Whiteboard. +These fields are all optional in the UI; there are parameters to turn them on. +However, whether or not you use them, the fields need to be in the DB. There +is some code that needs them, even if you don't. + +To update your DB to have these fields, send the following to MySQL: + + alter table bugs add column target_milestone varchar(20) not null, + add column qa_contact mediumint not null, + add column status_whiteboard mediumtext not null, + add index (target_milestone), add index (qa_contact); + + + +1/18/99 You can now query by CC. To make this perform reasonably, the CC table +needs some indices. The following MySQL does the necessary stuff: + + alter table cc add index (bug_id), add index (who); + + +1/15/99 The op_sys field can now be queried by (and more easily tweaked). +To make this perform reasonably, it needs an index. The following MySQL +command will create the necessary index: + + alter table bugs add index (op_sys); + + +12/2/98 The op_sys and rep_platform fields have been tweaked. op_sys +is now an enum, rather than having the legal values all hard-coded in +perl. rep_platform now no longer allows a value of "X-Windows". + +Here's how I ported to the new world. This ought to work for you too. +Actually, it's probably overkill. I had a lot of illegal values for op_sys +in my tables, from importing bugs from strange places. If you haven't done +anything funky, then much of the below will be a no-op. + +First, send the following commands to MySQL to make sure all your values for +rep_platform and op_sys are legal in the new world.. + + update bugs set rep_platform="Sun" where rep_platform="X-Windows" and op_sys like "Solaris%"; + update bugs set rep_platform="SGI" where rep_platform="X-Windows" and op_sys = "IRIX"; + update bugs set rep_platform="SGI" where rep_platform="X-Windows" and op_sys = "HP-UX"; + update bugs set rep_platform="DEC" where rep_platform="X-Windows" and op_sys = "OSF/1"; + update bugs set rep_platform="PC" where rep_platform="X-Windows" and op_sys = "Linux"; + update bugs set rep_platform="other" where rep_platform="X-Windows"; + update bugs set rep_platform="other" where rep_platform=""; + update bugs set op_sys="Mac System 7" where op_sys="System 7"; + update bugs set op_sys="Mac System 7.5" where op_sys="System 7.5"; + update bugs set op_sys="Mac System 8.0" where op_sys="8.0"; + update bugs set op_sys="OSF/1" where op_sys="Digital Unix 4.0"; + update bugs set op_sys="IRIX" where op_sys like "IRIX %"; + update bugs set op_sys="HP-UX" where op_sys like "HP-UX %"; + update bugs set op_sys="Windows NT" where op_sys like "NT %"; + update bugs set op_sys="OSF/1" where op_sys like "OSF/1 %"; + update bugs set op_sys="Solaris" where op_sys like "Solaris %"; + update bugs set op_sys="SunOS" where op_sys like "SunOS%"; + update bugs set op_sys="other" where op_sys = "Motif"; + update bugs set op_sys="other" where op_sys = "Other"; + +Next, send the following commands to make sure you now have only legal +entries in your table. If either of the queries do not come up empty, then +you have to do more stuff like the above. + + select bug_id,op_sys,rep_platform from bugs where rep_platform not regexp "^(All|DEC|HP|Macintosh|PC|SGI|Sun|X-Windows|Other)$"; + select bug_id,op_sys,rep_platform from bugs where op_sys not regexp "^(All|Windows 3.1|Windows 95|Windows 98|Windows NT|Mac System 7|Mac System 7.5|Mac System 7.1.6|Mac System 8.0|AIX|BSDI|HP-UX|IRIX|Linux|OSF/1|Solaris|SunOS|other)$"; + +Finally, once that's all clear, alter the table to make enforce the new legal +entries: + + alter table bugs change column op_sys op_sys enum("All", "Windows 3.1", "Windows 95", "Windows 98", "Windows NT", "Mac System 7", "Mac System 7.5", "Mac System 7.1.6", "Mac System 8.0", "AIX", "BSDI", "HP-UX", "IRIX", "Linux", "OSF/1", "Solaris", "SunOS", "other") not null, change column rep_platform rep_platform enum("All", "DEC", "HP", "Macintosh", "PC", "SGI", "Sun", "Other"); + + + + + +11/20/98 Added searching of CC field. To better support this, added +some indexes to the CC table. You probably want to execute the following +mysql commands: + + alter table cc add index (bug_id); + alter table cc add index (who); + + +10/27/98 security check for legal products in place. bug charts are not +available as an option if collectstats.pl has never been run. all products +get daily stats collected now. README updated: Chart::Base is listed as +a requirement, instructions for using collectstats.pl included as +an optional step. also got silly and added optional quips to bug +reports. + +10/17/98 modified README installation instructions slightly. + +10/7/98 Added a new table called "products". Right now, this is used +only to have a description for each product, and that description is +only used when initially adding a new bug. Anyway, you *must* create +the new table (which you can do by running the new makeproducttable.sh +script). If you just leave it empty, things will work much as they +did before, or you can add descriptions for some or all of your +products. 9/15/98 Everything has been ported to Perl. NO MORE TCL. This diff --git a/CVS/Entries b/CVS/Entries index ff867da71c116bd68e77646f9fe4b54084dca15a..23ffbdede0545746f1234145144b72f05d4aa053 100644 --- a/CVS/Entries +++ b/CVS/Entries @@ -1,40 +1,47 @@ -/1x1.gif/1.1/Sat Sep 19 06:08:00 1998/-kb/ -/CGI.pl/1.2/Sat Sep 19 06:08:00 1998// -/CHANGES/1.4/Sat Sep 19 06:08:00 1998// -/README/1.7/Sat Sep 19 06:08:00 1998// -/ant.jpg/1.2/Sat Sep 19 06:08:02 1998/-kb/ -/bug_form.pl/1.1/Sat Sep 19 06:08:02 1998// -/bug_status.html/1.1/Sat Sep 19 06:08:02 1998// -/buglist.cgi/1.8/Sat Sep 19 06:08:02 1998// -/changepassword.cgi/1.3/Sat Sep 19 06:08:03 1998// -/colchange.cgi/1.4/Sat Sep 19 06:08:03 1998// -/defparams.pl/1.3/Sat Sep 19 06:08:03 1998// -/doclosebug.cgi/1.1/Sat Sep 19 06:08:03 1998// -/doeditparams.cgi/1.2/Sat Sep 19 06:08:03 1998// -/edit_desc.cgi/1.1/Sat Sep 19 06:08:03 1998// -/editparams.cgi/1.4/Sat Sep 19 06:08:03 1998// -/enter_bug.cgi/1.6/Sat Sep 19 06:08:03 1998// -/globals.pl/1.6/Sat Sep 19 06:08:03 1998// -/help.html/1.1/Sat Sep 19 06:08:03 1998// -/how_to_mail.html/1.1/Sat Sep 19 06:08:03 1998// -/index.html/1.2/Sat Sep 19 06:08:03 1998// -/long_list.cgi/1.4/Sat Sep 19 06:08:04 1998// -/makeactivitytable.sh/1.1/Sat Sep 19 06:08:04 1998// -/makebugtable.sh/1.1/Sat Sep 19 06:08:04 1998// -/makecctable.sh/1.1/Sat Sep 19 06:08:04 1998// -/makecomponenttable.sh/1.9/Sat Sep 19 06:08:04 1998// -/makelogincookiestable.sh/1.1/Sat Sep 19 06:08:04 1998// -/makeprofilestable.sh/1.2/Sat Sep 19 06:08:04 1998// -/makeversiontable.sh/1.4/Sat Sep 19 06:08:04 1998// -/new_comment.cgi/1.2/Sat Sep 19 06:08:04 1998// -/newquip.html/1.2/Sat Sep 19 06:08:04 1998// -/post_bug.cgi/1.2/Sat Sep 19 06:08:04 1998// -/process_bug.cgi/1.6/Sat Sep 19 06:08:05 1998// -/processmail/1.9/Sat Sep 19 06:08:05 1998// -/query.cgi/1.8/Sat Sep 19 06:08:05 1998// -/relogin.cgi/1.3/Sat Sep 19 06:08:05 1998// -/sanitycheck.cgi/1.2/Sat Sep 19 06:08:05 1998// -/show_activity.cgi/1.2/Sat Sep 19 06:08:05 1998// -/show_bug.cgi/1.2/Sat Sep 19 06:08:05 1998// -/whineatnews.pl/1.1/Sat Sep 19 06:08:05 1998// +/1x1.gif/1.1/Wed Feb 10 22:11:47 1999/-kb/ +/CGI.pl/1.6/Wed Feb 10 22:11:47 1999// +/CHANGES/1.16/Wed Feb 10 22:11:47 1999// +/README/1.12/Wed Feb 10 22:11:47 1999// +/ant.jpg/1.2/Wed Feb 10 22:11:47 1999/-kb/ +/backdoor.cgi/1.6/Wed Feb 10 22:11:48 1999// +/bug_form.pl/1.8/Wed Feb 10 22:11:48 1999// +/bug_status.html/1.3/Wed Feb 10 22:11:48 1999// +/buglist.cgi/1.23/Wed Feb 10 22:11:48 1999// +/changepassword.cgi/1.6/Wed Feb 10 22:11:48 1999// +/colchange.cgi/1.7/Wed Feb 10 22:11:48 1999// +/collectstats.pl/1.3/Wed Feb 10 22:11:48 1999// +/defparams.pl/1.5/Wed Feb 10 22:11:48 1999// +/describecomponents.cgi/1.1/Wed Feb 10 22:11:48 1999// +/doeditowners.cgi/1.3/Wed Feb 10 22:11:48 1999// +/doeditparams.cgi/1.5/Wed Feb 10 22:11:48 1999// +/editowners.cgi/1.3/Wed Feb 10 22:11:48 1999// +/editparams.cgi/1.7/Wed Feb 10 22:11:48 1999// +/enter_bug.cgi/1.14/Wed Feb 10 22:11:48 1999// +/help.html/1.1/Wed Feb 10 22:11:48 1999// +/helpemailquery.html/1.1/Wed Feb 10 22:11:48 1999// +/how_to_mail.html/1.1/Wed Feb 10 22:11:49 1999// +/index.html/1.3/Wed Feb 10 22:11:49 1999// +/long_list.cgi/1.5/Wed Feb 10 22:11:49 1999// +/makeactivitytable.sh/1.1/Wed Feb 10 22:11:49 1999// +/makebugtable.sh/1.8/Wed Feb 10 22:11:49 1999// +/makecctable.sh/1.2/Wed Feb 10 22:11:49 1999// +/makecomponenttable.sh/1.38/Wed Feb 10 22:11:49 1999// +/makelogincookiestable.sh/1.1/Wed Feb 10 22:11:49 1999// +/makeproducttable.sh/1.8/Wed Feb 10 22:11:49 1999// +/makeprofilestable.sh/1.2/Wed Feb 10 22:11:49 1999// +/makeversiontable.sh/1.10/Wed Feb 10 22:11:49 1999// +/new_comment.cgi/1.2/Wed Feb 10 22:11:49 1999// +/newquip.html/1.2/Wed Feb 10 22:11:49 1999// +/notargetmilestone.html/1.1/Wed Feb 10 22:11:49 1999// +/post_bug.cgi/1.5/Wed Feb 10 22:11:49 1999// +/process_bug.cgi/1.13/Wed Feb 10 22:11:49 1999// +/processmail/1.11/Wed Feb 10 22:11:49 1999// +/query.cgi/1.23/Wed Feb 10 22:11:50 1999// +/relogin.cgi/1.5/Wed Feb 10 22:11:50 1999// +/reports.cgi/1.10/Wed Feb 10 22:11:50 1999// +/sanitycheck.cgi/1.4/Wed Feb 10 22:11:50 1999// +/show_activity.cgi/1.2/Wed Feb 10 22:11:50 1999// +/show_bug.cgi/1.5/Wed Feb 10 22:11:50 1999// +/whineatnews.pl/1.1/Wed Feb 10 22:11:50 1999// +/globals.pl/1.14/Wed Feb 10 22:11:51 1999// D diff --git a/README b/README index f7bc7ace564c1e9b65b1c38ec643e47d9c7a557c..c792e802fdd8ad3a2314b08a035f032165fb447e 100644 --- a/README +++ b/README @@ -24,9 +24,12 @@ this document!) First, you need some other things: 1) MySQL database server. - 2) Perl5.004 or greater, including MySQL support and the Date::Format - package from CPAN. + 2) Perl5.004 or greater, including MySQL support, and modules + Date::Format and Chart::Base available from your nearest + CPAN server. See http://www.perl.com/CPAN. ftp://ftp.cpan.org/pub/CPAN/authors/id/GBARR/TimeDate-1.08.tar.gz + ftp://ftp.cpan.org/pub/CPAN/authors/id/DBONNER/Chart-0.99.tar.gz + ftp://ftp.cpan.org/pub/CPAN/authors/id/LDS/GD-1.18.tar.gz 3) Some kind of HTTP server so you could use CGI scripts Earlier versions of Bugzilla required TCL. THIS IS NO LONGER TRUE. @@ -53,17 +56,20 @@ You have a freedom of choice here - Apache, Netscape or any other server on UNIX would do. The only thing - to make configuration easier you'd better run HTTP daemon on the same machine that you run MySQL server on. Make sure that you can access 'bugs' database with user -id you're running the daemon with. +id you're running the daemon with. +globals.pl: $::db = Mysql->Connect("localhost", "bugs", "nobody", "") -2. TWEAKING THE TOOLS +In globals.pl, the database connect call uses a mysql account +name "bugs" (third argument to Mysql->Connect) to access the +bugs database. You may have to hack the code to use "nobody" +or whatever your HTTP server is running as. - Now you should have all necessary tools to be able to run Bugzilla -and see why the wouldn't work for you right now. - First of all you have to change "#!/usr/bonsaitools" to wherever -you've installed your binaries in all executable scripts in Bugzilla -directories. +2. Tweaking the Tools + + All scripts look in /usr/bonsaitools/bin for perl. Make +the appropriate links or modify the paths in each script. Make sure the directory containing the binaries is writable by the web server. Bugzilla keeps some temporary files here. @@ -107,3 +113,31 @@ It's a good idea to set up a daily cronjob that does This causes email that gets sent to anyone who has a NEW bug that hasn't been touched for several days. For more info, see the whinedays and whinemail parameters. + + +6. Modifying your running system + +Bugzilla optimizes database lookups by storing all relatively static +information in the versioncache file, located in the data/ +subdirectory under your installation directory (we said before it +needs to be writable, right?!) + +If you make a change to the structural data in your database (the +versions table for example), or to the "constants" encoded in +defparams.pl, you will need to remove the cached content from the data +directory (by doing a "rm data/versioncache"), or your changes won't +show up! + +That file gets automatically regenerated whenever it's more than an +hour old, so Bugzilla will eventually notice your changes by itself, +but generally you want it to notice right away, so that you can test +things. + + +7. Optional: Bug Graphs + +Place collectstats.pl in your crontab once/day to take a snapshot +of the number of open, assigned and reopened bugs for every +product. The tool will create a data/mining directory and append +the count to a file named for the product. After at least two points +of data are available, you can view a graph from the Bug Reports page. diff --git a/backdoor.cgi b/backdoor.cgi new file mode 100755 index 0000000000000000000000000000000000000000..93481f21a80c664a7d8ca591c9829c92f2f90d6f --- /dev/null +++ b/backdoor.cgi @@ -0,0 +1,163 @@ +#!/usr/bonsaitools/bin/perl -w +# -*- Mode: perl; indent-tabs-mode: nil -*- +# +# The contents of this file are subject to the Mozilla Public License +# Version 1.0 (the "License"); you may not use this file except in +# compliance with the License. You may obtain a copy of the License at +# http://www.mozilla.org/MPL/ +# +# Software distributed under the License is distributed on an "AS IS" +# basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See the +# License for the specific language governing rights and limitations +# under the License. +# +# The Original Code is the Bugzilla Bug Tracking System. +# +# The Initial Developer of the Original Code is Netscape Communications +# Corporation. Portions created by Netscape are Copyright (C) 1998 +# Netscape Communications Corporation. All Rights Reserved. +# +# Contributor(s): Terry Weissman <terry@mozilla.org> + +# Provides a silly 'back-door' mechanism to let me automatically insert +# bugs from the netscape bugsystem. Other installations of Bugzilla probably +# don't need to worry about this file any. + +use diagnostics; +use strict; + +require "CGI.pl"; + +# Shut up misguided -w warnings about "used only once": + +use vars %::versions; + + +ConnectToDatabase(); + +print "Content-type: text/plain\n\n"; + +# while (my ($key,$value) = each %ENV) { +# print "$key=$value\n"; +# } + +my $host = $ENV{'REMOTE_ADDR'}; + +SendSQL("select passwd from backdoor where host = '$host'"); +my $passwd = FetchOneColumn(); +if (!defined $passwd || !defined $::FORM{'passwd'} || + $passwd ne crypt($::FORM{'passwd'}, substr($passwd, 0, 2))) { + print "Who are you?\n"; + print "Env:\n"; + while (my ($key,$value) = each %ENV) { + print "$key=$value\n"; + } + print "\nForm:\n"; + while (my ($key,$value) = each %::FORM) { + print "$key=$value\n"; + } + exit; +} + + + +my $prod = $::FORM{'product'}; +my $comp = $::FORM{'component'}; +my $version = $::FORM{'version'}; + +GetVersionTable(); + + +sub Punt { + my ($label, $value) = (@_); + my $maintainer = Param("maintainer"); + print "I don't know how to move into Bugzilla a bug with a $label of $value. +If you really do need to do this, speak to $maintainer and maybe he +can teach me."; + exit; +} + + +# Do remapping of things from BugSplat world to Bugzilla. + +if ($prod eq "Communicator") { + $prod = "Mozilla"; + $version = "other"; +} + + +# Validate fields, and whine about things that we apparently couldn't remap +# into something legal. + + +if (!defined $::components{$prod}) { + Punt("product", $prod); +} +if (lsearch($::components{$prod}, $comp) < 0) { + Punt("component", $comp); +} +if (lsearch($::versions{$prod}, $version) < 0) { + $version = "other"; + if (lsearch($::versions{$prod}, $version) < 0) { + Punt("version", $version); + } +} + + +$::FORM{'product'} = $prod; +$::FORM{'component'} = $comp; +$::FORM{'version'} = $version; + + +$::FORM{'long_desc'} = + "(This bug imported from BugSplat, Netscape's internal bugsystem. It +was known there as bug #$::FORM{'bug_id'} +http://scopus.netscape.com/bugsplat/show_bug.cgi?id=$::FORM{'bug_id'} +Imported into Bugzilla on " . time2str("%D %H:%M", time()) . ") + +" . $::FORM{'long_desc'}; + + +$::FORM{'reporter'} = + DBNameToIdAndCheck("$::FORM{'reporter'}\@netscape.com", 1); +$::FORM{'assigned_to'} = + DBNameToIdAndCheck("$::FORM{'assigned_to'}\@netscape.com", 1); +if ($::FORM{'qa_contact'} ne "") { + $::FORM{'qa_contact'} = + DBNameToIdAndCheck("$::FORM{'qa_contact'}\@netscape.com", 1); +} else { + $::FORM{'qa_contact'} = 0; +} + + +my @list = ('reporter', 'assigned_to', 'product', 'version', 'rep_platform', + 'op_sys', 'bug_status', 'bug_severity', 'priority', 'component', + 'short_desc', 'long_desc', 'creation_ts', 'delta_ts', + 'bug_file_loc', 'qa_contact'); + +my @vallist; +foreach my $i (@list) { + push @vallist, SqlQuote($::FORM{$i}); +} + +my $query = "insert into bugs (" . + join(',', @list) . + ") values (" . + join(',', @vallist) . + ")"; + + +SendSQL($query); + +SendSQL("select LAST_INSERT_ID()"); +my $zillaid = FetchOneColumn(); + +foreach my $cc (split(/,/, $::FORM{'cc'})) { + if ($cc ne "") { + my $cid = DBNameToIdAndCheck("$cc\@netscape.com", 1); + SendSQL("insert into cc (bug_id, who) values ($zillaid, $cid)"); + } +} + +print "Created bugzilla bug $zillaid\n"; +system("./processmail $zillaid < /dev/null > /dev/null 2> /dev/null &"); diff --git a/bug_form.pl b/bug_form.pl index ed6aead8a34cb26f9f15fa94d7b64f4a826cab62..d56d6b42a0be742c4040ce622bb47082b4e42cb6 100644 --- a/bug_form.pl +++ b/bug_form.pl @@ -37,6 +37,9 @@ select reporter, bug_file_loc, short_desc, + target_milestone, + qa_contact, + status_whiteboard, date_format(creation_ts,'Y-m-d') from bugs where bug_id = $::FORM{'id'}"; @@ -49,7 +52,8 @@ if (@row = FetchSQLData()) { foreach my $field ("bug_id", "product", "version", "rep_platform", "op_sys", "bug_status", "resolution", "priority", "bug_severity", "component", "assigned_to", "reporter", - "bug_file_loc", "short_desc", "creation_ts") { + "bug_file_loc", "short_desc", "target_milestone", + "qa_contact", "status_whiteboard", "creation_ts") { $bug{$field} = shift @row; if (!defined $bug{$field}) { $bug{$field} = ""; @@ -118,8 +122,10 @@ print " <TD><SELECT NAME=product>" . make_options(\@::legal_product, $bug{'product'}) . "</SELECT></TD> - <TD ALIGN=RIGHT><B>OS:</B></TD><TD>$bug{'op_sys'}</TD> - <TD ALIGN=RIGHT><B>Reporter:</B></TD><TD>$bug{'reporter'}</TD> + <TD ALIGN=RIGHT><B>OS:</B></TD> + <TD><SELECT NAME=op_sys>" . + make_options(\@::legal_opsys, $bug{'op_sys'}) . + "</SELECT><TD ALIGN=RIGHT><B>Reporter:</B></TD><TD>$bug{'reporter'}</TD> </TR><TR> <TD ALIGN=RIGHT><B><A HREF=\"bug_status.html\">Status:</A></B></TD> <TD>$bug{'bug_status'}</TD> @@ -132,13 +138,52 @@ print " <TD>$bug{'resolution'}</TD> <TD ALIGN=RIGHT><B><A HREF=\"bug_status.html#severity\">Severity:</A></B></TD> <TD><SELECT NAME=bug_severity>$sev_popup</SELECT></TD> - <TD ALIGN=RIGHT><B>Component:</B></TD> + <TD ALIGN=RIGHT><B><A HREF=\"describecomponents.cgi?product=" . + url_quote($bug{'product'}) . "\">Component:</A></B></TD> <TD><SELECT NAME=component>$component_popup</SELECT></TD> </TR><TR> <TD ALIGN=RIGHT><B><A HREF=\"bug_status.html#assigned_to\">Assigned To: </A></B></TD> - <TD>$bug{'assigned_to'}</TD> - </TR><TR> + <TD>$bug{'assigned_to'}</TD>"; + +if (Param("usetargetmilestone")) { + my $url = ""; + if (defined $::milestoneurl{$bug{'product'}}) { + $url = $::milestoneurl{$bug{'product'}}; + } + 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, + $bug{'target_milestone'}) . + "</SELECT></TD>"; +} + +print " +</TR>"; + +if (Param("useqacontact")) { + my $name = $bug{'qa_contact'} > 0 ? DBID_to_name($bug{'qa_contact'}) : ""; + print " + <TR> + <TD ALIGN=\"RIGHT\"><B>QA Contact:</B> + <TD COLSPAN=6> + <INPUT NAME=qa_contact VALUE=\"" . + value_quote($name) . + "\" SIZE=60></ + </TR>"; +} + + +print " + <TR> <TD ALIGN=\"RIGHT\">$URL <TD COLSPAN=6> <INPUT NAME=bug_file_loc VALUE=\"$bug{'bug_file_loc'}\" SIZE=60></TD> @@ -148,7 +193,21 @@ print " <INPUT NAME=short_desc VALUE=\"" . value_quote($bug{'short_desc'}) . "\" SIZE=60></TD> - </TR> + </TR>"; + +if (Param("usestatuswhiteboard")) { + print " + <TR> + <TD ALIGN=\"RIGHT\"><B>Status Whiteboard:</B> + <TD COLSPAN=6> + <INPUT NAME=status_whiteboard VALUE=\"" . + value_quote($bug{'status_whiteboard'}) . + "\" SIZE=60></ + </TR>"; +} + + +print " </TABLE> <br> <B>Additional Comments:</B> @@ -237,3 +296,5 @@ print " navigation_header(); print "</BODY>\n"; + +1; diff --git a/bug_status.html b/bug_status.html index fff5585583fc6caeda933dcfc5498c3bf3c9efaa..e351b414ad5f7dcf965e45776192d20db281f610 100755 --- a/bug_status.html +++ b/bug_status.html @@ -159,19 +159,34 @@ Most bugs should have area set to <B>CODE</B>. Legal values include: <LI> l10n <i>(localization)</i> </UL> <a name="rep_platform"><h2>Platform</h2></a> -This is the platform against which the bug was reported. Legal +This is the hardware platform against which the bug was reported. Legal platforms include: <UL> <LI> All (happens on all platform; cross-platform bug) <LI> Macintosh <LI> PC -<LI> X-Windows +<LI> Sun +<LI> HP </UL> <b>Note:</b> Selecting the option "All" does not select bugs assigned against all platforms. It merely selects bugs that <b>occur</b> on all platforms. +<a name="op_sys"><h2>Operating System</h2></a> +This is the operating system against which the bug was reported. Legal +operating systems include: + +<UL> +<LI> All (happens on all operating systems; cross-platform bug) +<LI> Windows 95 +<LI> Mac System 8.0 +<LI> Linux +</UL> + +Note that the operating system implies the platform, but not always. +For example, Linux can run on PC and Macintosh and others. + <a name="assigned_to"><h2>Assigned To</h2></a> This is the person in charge of resolving the bug. Every time this @@ -189,6 +204,6 @@ status field appropriately. <hr> <address><a href="http://home.netscape.com/people/terry/">Terry Weissman <terry@netscape.com></a></address> <!-- hhmts start --> -Last modified: Tue Aug 25 23:11:26 1998 +Last modified: Fri Jan 15 13:36:36 1999 <!-- hhmts end --> </body> </html> diff --git a/buglist.cgi b/buglist.cgi index e93fc3d8d7ff53c9fdeaecc35b0cf72c7f9d940c..0a157027392042ea9ecc6a381c0abadf753b51a5 100755 --- a/buglist.cgi +++ b/buglist.cgi @@ -22,12 +22,20 @@ use diagnostics; use strict; -print "Content-type: multipart/x-mixed-replace;boundary=ThisRandomString\n"; -print "\n"; -print "--ThisRandomString\n"; +require "CGI.pl"; +my $serverpush = 1; -require "CGI.pl"; +if ($ENV{'HTTP_USER_AGENT'} =~ /MSIE/) { + # Internet explorer doesn't seem to understand server push. What fun. + $serverpush = 0; +} + +if ($serverpush) { + print "Content-type: multipart/x-mixed-replace;boundary=thisrandomstring\n"; + print "\n"; + print "--thisrandomstring\n"; +} # Shut up misguided -w warnings about "used only once": @@ -40,7 +48,8 @@ use vars @::legal_platform, @::legal_severity, @::legal_priority, @::default_column_list, - @::legal_resolution_no_dup; + @::legal_resolution_no_dup, + @::legal_target_milestone; @@ -55,7 +64,7 @@ if (!defined $::FORM{'cmdtype'}) { CMD: for ($::FORM{'cmdtype'}) { /^runnamed$/ && do { $::buffer = $::COOKIE{"QUERY_" . $::FORM{"namedcmd"}}; - ProcessFormFields $::buffer; + ProcessFormFields($::buffer); last CMD; }; /^editnamed$/ && do { @@ -143,16 +152,20 @@ DefCol("platform", "substring(bugs.rep_platform, 1, 3)", "Plt", "bugs.rep_platform"); DefCol("owner", "assign.login_name", "Owner", "assign.login_name"); DefCol("reporter", "report.login_name", "Reporter", "report.login_name"); +DefCol("qa_contact", "qacont.login_name", "QAContact", "qacont.login_name"); DefCol("status", "substring(bugs.bug_status,1,4)", "State", "bugs.bug_status"); DefCol("resolution", "substring(bugs.resolution,1,4)", "Result", "bugs.resolution"); DefCol("summary", "substring(bugs.short_desc, 1, 60)", "Summary", "", 1); DefCol("summaryfull", "bugs.short_desc", "Summary", "", 1); +DefCol("status_whiteboard", "bugs.status_whiteboard", "StatusSummary", "", 1); DefCol("component", "substring(bugs.component, 1, 8)", "Comp", "bugs.component"); DefCol("product", "substring(bugs.product, 1, 8)", "Product", "bugs.product"); DefCol("version", "substring(bugs.version, 1, 5)", "Vers", "bugs.version"); DefCol("os", "substring(bugs.op_sys, 1, 4)", "OS", "bugs.op_sys"); +DefCol("target_milestone", "bugs.target_milestone", "TargetM", + "bugs.target_milestone"); my @collist; if (defined $::COOKIE{'COLUMNLIST'}) { @@ -187,10 +200,12 @@ bugs.product, bugs.bug_status"; } + $query .= " from bugs, profiles assign, - profiles report, + profiles report + left join profiles qacont on bugs.qa_contact = qacont.userid, versions projector where bugs.assigned_to = assign.userid and bugs.reporter = report.userid @@ -198,12 +213,22 @@ and bugs.product = projector.program and bugs.version = projector.value "; +if ((defined $::FORM{'emailcc1'} && $::FORM{'emailcc1'}) || + (defined $::FORM{'emailcc2'} && $::FORM{'emailcc2'})) { + + # We need to poke into the CC table. Do weird SQL left join stuff so that + # we can look in the CC table, but won't reject any bugs that don't have + # any CC fields. + $query =~ s/bugs,/bugs left join cc using (bug_id) left join profiles ccname on cc.who = ccname.userid,/; +} + if (defined $::FORM{'sql'}) { $query .= "and (\n$::FORM('sql')\n)" } else { my @legal_fields = ("bug_id", "product", "version", "rep_platform", "op_sys", "bug_status", "resolution", "priority", "bug_severity", - "assigned_to", "reporter", "bug_file_loc", "component"); + "assigned_to", "reporter", "component", + "target_milestone"); foreach my $field (keys %::FORM) { my $or = ""; @@ -236,6 +261,68 @@ if (defined $::FORM{'sql'}) { } } + +foreach my $id ("1", "2") { + if (!defined ($::FORM{"email$id"})) { + next; + } + my $email = trim($::FORM{"email$id"}); + if ($email eq "") { + next; + } + my $qemail = SqlQuote($email); + my $type = $::FORM{"emailtype$id"}; + my $emailid; + if ($type eq "exact") { + $emailid = DBNameToIdAndCheck($email); + } + + my $foundone = 0; + my $lead= "and (\n"; + foreach my $field ("assigned_to", "reporter", "cc", "qa_contact") { + my $doit = $::FORM{"email$field$id"}; + if (!$doit) { + next; + } + $foundone = 1; + my $table; + if ($field eq "assigned_to") { + $table = "assign"; + } elsif ($field eq "reporter") { + $table = "report"; + } elsif ($field eq "qa_contact") { + $table = "qacont"; + } else { + $table = "ccname"; + } + if ($type eq "exact") { + if ($field eq "cc") { + $query .= "\t$lead cc.who = $emailid\n"; + } else { + $query .= "\t$lead $field = $emailid\n"; + } + } elsif ($type eq "regexp") { + $query .= "\t$lead $table.login_name regexp $qemail\n"; + } elsif ($type eq "notregexp") { + $query .= "\t$lead $table.login_name not regexp $qemail\n"; + } else { + $query .= "\t$lead instr($table.login_name, $qemail)\n"; + } + $lead = " or "; + } + if (!$foundone) { + print "You must specify one or more fields in which to search for <tt>$email</tt>.\n"; + exit; + } + if ($lead eq " or ") { + $query .= ")\n"; + } +} + + + + + if (defined $::FORM{'changedin'}) { my $c = trim($::FORM{'changedin'}); if ($c ne "") { @@ -251,14 +338,16 @@ Click the <B>Back</B> button and try again."; } } -foreach my $f ("short_desc", "long_desc") { +foreach my $f ("short_desc", "long_desc", "bug_file_loc", + "status_whiteboard") { if (defined $::FORM{$f}) { - my $s = SqlQuote(trim($::FORM{$f})); + my $s = trim($::FORM{$f}); if ($s ne "") { + $s = SqlQuote($s); if ($::FORM{$f . "_type"} eq "regexp") { - $query .= "and $f regexp $s "; + $query .= "and $f regexp $s\n"; } else { - $query .= "and instr($f, $s) "; + $query .= "and instr($f, $s)\n"; } } } @@ -277,7 +366,7 @@ if (defined $::FORM{'order'} && $::FORM{'order'} ne "") { last ORDER; }; /Import/ && do { - $::FORM{'order'} = "bugs.priority"; + $::FORM{'order'} = "bugs.priority, bugs.bug_severity"; last ORDER; }; /Assign/ && do { @@ -290,9 +379,11 @@ if (defined $::FORM{'order'} && $::FORM{'order'} ne "") { $query .= $::FORM{'order'}; } -print "Please stand by ... <p>\n"; -if (defined $::FORM{'debug'}) { - print "<pre>$query</pre>\n"; +if ($serverpush) { + print "Please stand by ... <p>\n"; + if (defined $::FORM{'debug'}) { + print "<pre>$query</pre>\n"; + } } SendSQL($query); @@ -329,7 +420,7 @@ my $tablestart = "<TABLE CELLSPACING=0 CELLPADDING=2> foreach my $c (@collist) { if (exists $::needquote{$c}) { if ($::needquote{$c}) { - $tablestart .= "<TH WIDTH=100% valigh=left>"; + $tablestart .= "<TH WIDTH=100% valign=left>"; } else { $tablestart .= "<TH valign=left>"; } @@ -367,10 +458,13 @@ while (@row = FetchSQLData()) { pnl "<A HREF=\"show_bug.cgi?id=$bug_id\">"; pnl "$bug_id</A> "; foreach my $c (@collist) { + if (!exists $::needquote{$c}) { + next; + } my $value = shift @row; my $nowrap = ""; - if (exists $::needquote{$c} && $::needquote{$c}) { + if ($::needquote{$c}) { $value = html_quote($value); } else { $value = "<nobr>$value</nobr>"; @@ -391,8 +485,10 @@ while (@row = FetchSQLData()) { my $buglist = join(":", @bugarray); -print "\n"; -print "--ThisRandomString\n"; +if ($serverpush) { + print "\n"; + print "--thisrandomstring\n"; +} my $toolong = 0; @@ -500,7 +596,30 @@ document.write(\" <input type=button value=\\\"Uncheck All\\\" onclick=\\\"SetCh <TD><SELECT NAME=component>$component_popup</SELECT></TD> <TD ALIGN=RIGHT><B><A HREF=\"bug_status.html#severity\">Severity:</A></B></TD> <TD><SELECT NAME=bug_severity>$sev_popup</SELECT></TD> -</TR> +</TR>"; + + if (Param("usetargetmilestone")) { + push(@::legal_target_milestone, " "); + my $tfm_popup = make_options(\@::legal_target_milestone, + $::dontchange); + print " + <TR> + <TD ALIGN=RIGHT><B>Target milestone:</B></TD> + <TD><SELECT NAME=target_milestone>$tfm_popup</SELECT></TD> + </TR>"; + } + + if (Param("useqacontact")) { + print " +<TR> +<TD><B>QA Contact:</B></TD> +<TD COLSPAN=3><INPUT NAME=qa_contact SIZE=32 VALUE=\"" . + value_quote($::dontchange) . "\"></TD> +</TR>"; + } + + + print " </TABLE> <INPUT NAME=multiupdate value=Y TYPE=hidden> @@ -594,4 +713,6 @@ if ($count > 0) { print "<A HREF=\"buglist.cgi?$fields&tweak=1\">Make changes to several of these bugs at once.</A>\n"; } } -print "\n--ThisRandomString--\n"; +if ($serverpush) { + print "\n--thisrandomstring--\n"; +} diff --git a/changepassword.cgi b/changepassword.cgi index 8a8e5623db91ea6def2ad684078ecae3840df59f..a3a17e39a3d54b47bd5fb449f1b658950f850b18 100755 --- a/changepassword.cgi +++ b/changepassword.cgi @@ -19,9 +19,6 @@ # # Contributor(s): Terry Weissman <terry@mozilla.org> -#! /usr/bonsaitools/bin/mysqltcl -# -*- Mode: tcl; indent-tabs-mode: nil -*- - require "CGI.pl"; confirm_login(); diff --git a/colchange.cgi b/colchange.cgi index bd3b23d6f44f097b8fc09ac17f637cd0592f58f4..33d2dfe7057285361e9d9f40347858a95cf4c6d6 100755 --- a/colchange.cgi +++ b/colchange.cgi @@ -31,8 +31,20 @@ print "Content-type: text/html\n"; my @masterlist = ("opendate", "changeddate", "severity", "priority", "platform", "owner", "reporter", "status", "resolution", - "component", "product", "version", "project", "os", - "summary", "summaryfull"); + "component", "product", "version", "project", "os"); + +if (Param("usetargetmilestone")) { + push(@masterlist, "target_milestone"); +} +if (Param("useqacontact")) { + push(@masterlist, "qa_contact"); +} +if (Param("usestatuswhiteboard")) { + push(@masterlist, "status_whiteboard"); +} + + +push(@masterlist, ("summary", "summaryfull")); my @collist; diff --git a/collectstats.pl b/collectstats.pl new file mode 100755 index 0000000000000000000000000000000000000000..05e6204cb378343d371b034529bd0ca845e8ad9a --- /dev/null +++ b/collectstats.pl @@ -0,0 +1,107 @@ +#!/usr/bonsaitools/bin/perl -w +# -*- Mode: perl; indent-tabs-mode: nil -*- +# +# The contents of this file are subject to the Mozilla Public License +# Version 1.0 (the "License"); you may not use this file except in +# compliance with the License. You may obtain a copy of the License at +# http://www.mozilla.org/MPL/ +# +# Software distributed under the License is distributed on an "AS IS" +# basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See the +# License for the specific language governing rights and limitations +# under the License. +# +# The Original Code is the Bugzilla Bug Tracking System. +# +# The Initial Developer of the Original Code is Netscape Communications +# Corporation. Portions created by Netscape are Copyright (C) 1998 +# Netscape Communications Corporation. All Rights Reserved. +# +# Contributor(s): Terry Weissman <terry@mozilla.org>, +# Harrison Page <harrison@netscape.com> + +# Run me out of cron at midnight to collect Bugzilla statistics. + +use diagnostics; +use strict; +use vars @::legal_product; + +require "globals.pl"; + +ConnectToDatabase(); +GetVersionTable(); + +foreach (@::legal_product) + { + my $dir = "data/mining"; + + &check_data_dir ($dir); + &collect_stats ($dir, $_); + } + +sub check_data_dir + { + my $dir = shift; + + if (! -d) + { + mkdir $dir, 0777; + chmod 0777, $dir; + } + } + +sub collect_stats + { + my $dir = shift; + my $product = shift; + my $when = localtime (time); + + my $query = <<FIN; +select count(bug_status) from bugs where +(bug_status='NEW' or bug_status='ASSIGNED' or bug_status='REOPENED') +and product='$product' group by bug_status +FIN + $product =~ s/\//-/gs; + my $file = join '/', $dir, $product; + my $exists = -f $file; + + if (open DATA, ">>$file") + { + SendSQL ($query); + + my %count; + push my @row, &today; + + while (my @n = FetchSQLData()) + { + push @row, @n; + } + + if (! $exists) + { + print DATA <<FIN; +# Bugzilla daily bug stats +# +# do not edit me! this file is generated. +# +# fields: date|new|assigned|reopened +# product: $product +# created: $when +FIN + } + + print DATA (join '|', @row) . "\n"; + close DATA; + } + else + { + print "$0: $file, $!"; + } + } + +sub today + { + my ($dom, $mon, $year) = (localtime(time))[3, 4, 5]; + return sprintf "%04d%02d%02d", 1900 + $year, ++$mon, $dom; + } + diff --git a/defparams.pl b/defparams.pl index 807e513102c635edb56370f0457c56ef596ab3a7..cfb41fbae0144ada048f0f8724c25fec23c09dee 100644 --- a/defparams.pl +++ b/defparams.pl @@ -30,13 +30,20 @@ sub WriteParams { foreach my $i (@::param_list) { if (!defined $::param{$i}) { $::param{$i} = $::param_default{$i}; + if (!defined $::param{$i}) { + die "No default parameter ever specified for $i"; + } } } mkdir("data", 0777); chmod 0777, "data"; my $tmpname = "data/params.$$"; open(FID, ">$tmpname") || die "Can't create $tmpname"; + my $v = $::param{'version'}; + delete $::param{'version'}; # Don't write the version number out to + # the params file. print FID GenerateCode('%::param'); + $::param{'version'} = $v; print FID "1;\n"; close FID; rename $tmpname, "data/params" || die "Can't rename $tmpname to data/params"; @@ -78,6 +85,7 @@ sub check_numeric { # t -- A short text entry field (suitable for a single line) # l -- A long text field (suitable for many lines) # b -- A boolean value (either 1 or 0) +# i -- An integer. # defenum -- This param defines an enum that defines a column in one of # the database tables. The name of the parameter is of the form # "tablename.columnname". @@ -235,4 +243,30 @@ DefParam("defaultquery", "t", "bug_status=NEW&bug_status=ASSIGNED&bug_status=REOPENED&product=Mozilla&order=%22Importance%22"); +DefParam("usetargetmilestone", + "Do you wish to use the Target Milestone field?", + "b", + 0); + +DefParam("nummilestones", + "If using Target Milestone, how many milestones do you wish to + appear?", + "t", + 10, + \&check_numeric); + +DefParam("useqacontact", + "Do you wish to use the QA Contact field?", + "b", + 0); + +DefParam("usestatuswhiteboard", + "Do you wish to use the Status Whiteboard field?", + "b", + 0); + + + + 1; + diff --git a/describecomponents.cgi b/describecomponents.cgi new file mode 100755 index 0000000000000000000000000000000000000000..bce7577d24ab76940f84aa54fdfcda33f7eab3c2 --- /dev/null +++ b/describecomponents.cgi @@ -0,0 +1,96 @@ +#!/usr/bonsaitools/bin/perl -w +# -*- Mode: perl; indent-tabs-mode: nil -*- +# +# The contents of this file are subject to the Mozilla Public License +# Version 1.0 (the "License"); you may not use this file except in +# compliance with the License. You may obtain a copy of the License at +# http://www.mozilla.org/MPL/ +# +# Software distributed under the License is distributed on an "AS IS" +# basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See the +# License for the specific language governing rights and limitations +# under the License. +# +# The Original Code is the Bugzilla Bug Tracking System. +# +# The Initial Developer of the Original Code is Netscape Communications +# Corporation. Portions created by Netscape are Copyright (C) 1998 +# Netscape Communications Corporation. All Rights Reserved. +# +# Contributor(s): Terry Weissman <terry@mozilla.org> + +use vars %::FORM; + +use diagnostics; +use strict; + +require "CGI.pl"; + +ConnectToDatabase(); +GetVersionTable(); + +print "Content-type: text/html\n\n"; + +my $product = $::FORM{'product'}; +if (!defined $product || lsearch(\@::legal_product, $product) < 0) { + + PutHeader("Bugzilla component description"); + print " +<FORM> +Please specify the product whose components you want described. +<P> +Product: <SELECT NAME=product> +"; + print make_options(\@::legal_product); + print " +</SELECT> +<P> +<INPUT TYPE=\"submit\" VALUE=\"Submit\"> +</FORM> +"; + exit; +} + + +PutHeader("Bugzilla component description", "Bugzilla component description", + $product); + +print " +<TABLE> +<tr> +<th align=left>Component</th> +<th align=left>Default owner</th> +"; + +my $useqacontact = Param("useqacontact"); + +my $cols = 2; +if ($useqacontact) { + print "<th align=left>Default qa contact</th>"; + $cols++; +} + +my $colbut1 = $cols - 1; + +print "</tr>"; + +SendSQL("select value, initialowner, initialqacontact, description from components where program = " . SqlQuote($product)); + +while (MoreSQLData()) { + my @row = FetchSQLData(); + my ($component, $initialowner, $initialqacontact, $description) = (@row); + + print qq| +<tr><td colspan=$cols><hr></td></tr> +<tr><td rowspan=2>$component</td> +<td><a href="mailto:$initialowner">$initialowner</a></td> +|; + if ($useqacontact) { + print qq| +<td><a href="mailto:$initialqacontact">$initialqacontact</a></td> +|; + } + print "</tr><tr><td colspan=$colbut1>$description</td></tr>\n"; +} + +print "<tr><td colspan=$cols><hr></td></tr></table>\n"; diff --git a/doclosebug.cgi b/doclosebug.cgi deleted file mode 100755 index cfb353976ab1be1fc8885a52efc708b8e3519a12..0000000000000000000000000000000000000000 --- a/doclosebug.cgi +++ /dev/null @@ -1,53 +0,0 @@ -#! /usr/bonsaitools/bin/mysqltcl -# -*- Mode: tcl; indent-tabs-mode: nil -*- -# -# The contents of this file are subject to the Mozilla Public License -# Version 1.0 (the "License"); you may not use this file except in -# compliance with the License. You may obtain a copy of the License at -# http://www.mozilla.org/MPL/ -# -# Software distributed under the License is distributed on an "AS IS" -# basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See the -# License for the specific language governing rights and limitations -# under the License. -# -# The Original Code is the Bugzilla Bug Tracking System. -# -# The Initial Developer of the Original Code is Netscape Communications -# Corporation. Portions created by Netscape are Copyright (C) 1998 -# Netscape Communications Corporation. All Rights Reserved. -# -# Contributor(s): Terry Weissman <terry@mozilla.org> - -source "CGI.tcl" -puts "Content-type: text/plain\n" - -set query "update bugs\nset -bug_status=RESOLVED, -bug_resolution=FIXED -where bug_id = $FORM(id)" - -set newcomment "Fixed by changes in $FORM(directory):" -foreach i $FORM(fileversions) { - lassign $i file version - append newcomment "\n $file ($version)" -} - -puts "Query is $query" -puts "Comment is $newcomment" - -exit - -ConnectToDatabase - -SendSQL $query - -while {[MoreSQLData]} { - FetchSQLData - set result [MoreSQLData] -} - -AppendComment $FORM(id) $FORM(who) $newcomment - - -exec ./processmail $FORM(id) < /dev/null > /dev/null 2> /dev/null & diff --git a/doeditowners.cgi b/doeditowners.cgi new file mode 100755 index 0000000000000000000000000000000000000000..b09d7298bdb2435df74a3d370126b9a197676450 --- /dev/null +++ b/doeditowners.cgi @@ -0,0 +1,72 @@ +#!/usr/bonsaitools/bin/perl -w +# -*- Mode: perl; indent-tabs-mode: nil -*- +# +# The contents of this file are subject to the Mozilla Public License +# Version 1.0 (the "License"); you may not use this file except in +# compliance with the License. You may obtain a copy of the License at +# http://www.mozilla.org/MPL/ +# +# Software distributed under the License is distributed on an "AS IS" +# basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See the +# License for the specific language governing rights and limitations +# under the License. +# +# The Original Code is the Bugzilla Bug Tracking System. +# +# The Initial Developer of the Original Code is Netscape Communications +# Corporation. Portions created by Netscape are Copyright (C) 1998 +# Netscape Communications Corporation. All Rights Reserved. +# +# Contributor(s): Sam Ziegler <sam@ziegler.org> + +use diagnostics; +use strict; + +require "CGI.pl"; + +# Shut up misguided -w warnings about "used only once": +use vars %::COOKIE; + + +confirm_login(); + +print "Content-type: text/html\n\n"; + +if (Param("maintainer") ne $::COOKIE{'Bugzilla_login'}) { + print "<H1>Sorry, you aren't the maintainer of this system.</H1>\n"; + print "And so, you aren't allowed to edit the parameters of it.\n"; + exit; +} + + +PutHeader("Saving new owners"); + +SendSQL("select program, value, initialowner from components order by program, value"); + +my @line; + +foreach my $key (keys(%::FORM)) { + $::FORM{url_decode($key)} = $::FORM{$key}; +} + +my @updates; +my $curIndex = 0; + +while (@line = FetchSQLData()) { + my $curItem = "$line[0]_$line[1]"; + if (exists $::FORM{$curItem}) { + $::FORM{$curItem} =~ s/\r\n/\n/; + if ($::FORM{$curItem} ne $line[2]) { + print "$line[0] : $line[1] is now owned by $::FORM{$curItem}.<BR>\n"; + $updates[$curIndex++] = "update components set initialowner = '$::FORM{$curItem}' where program = '$line[0]' and value = '$line[1]'"; + } + } +} + +foreach my $update (@updates) { + SendSQL($update); +} + +print "OK, done.<p>\n"; +print "<a href=editowners.cgi>Edit the owners some more.</a><p>\n"; +print "<a href=query.cgi>Go back to the query page.</a>\n"; diff --git a/doeditparams.cgi b/doeditparams.cgi index e43fd73ce569e68235f23f28acdd1a2432f1899e..dd6214982cc098261864ec8c0520ce7275aff3a2 100755 --- a/doeditparams.cgi +++ b/doeditparams.cgi @@ -69,6 +69,8 @@ foreach my $i (@::param_list) { WriteParams(); +unlink "data/versioncache"; + print "OK, done.<p>\n"; print "<a href=editparams.cgi>Edit the params some more.</a><p>\n"; print "<a href=query.cgi>Go back to the query page.</a>\n"; diff --git a/edit_desc.cgi b/edit_desc.cgi deleted file mode 100755 index 7f386b89487249bc19afea3f7d0b09070a9f0c5b..0000000000000000000000000000000000000000 --- a/edit_desc.cgi +++ /dev/null @@ -1,112 +0,0 @@ -#! /usr/bonsaitools/bin/mysqltcl -# -*- Mode: tcl; indent-tabs-mode: nil -*- -# -# The contents of this file are subject to the Mozilla Public License -# Version 1.0 (the "License"); you may not use this file except in -# compliance with the License. You may obtain a copy of the License at -# http://www.mozilla.org/MPL/ -# -# Software distributed under the License is distributed on an "AS IS" -# basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See the -# License for the specific language governing rights and limitations -# under the License. -# -# The Original Code is the Bugzilla Bug Tracking System. -# -# The Initial Developer of the Original Code is Netscape Communications -# Corporation. Portions created by Netscape are Copyright (C) 1998 -# Netscape Communications Corporation. All Rights Reserved. -# -# Contributor(s): Terry Weissman <terry@mozilla.org> - -source "CGI.tcl" -confirm_login - -puts "Content-type: text/html\n" -ConnectToDatabase -if {[info exists FORM(commit)]} { - puts "<TITLE>Changing Long Description for bug [FormData id]</TITLE>" - set tmpfile [TmpName ldesc.[pid]] - SendSQL "select rowid from bugs where bug_id = [FormData id]" - set r [FetchSQLData] - set lfile [open $tmpfile w] - puts -nonewline $lfile [FormData long_desc] - close $lfile - orawritelong $oc [lindex $r 0] bugs long_desc $tmpfile - unlink $tmpfile - oracommit $oc - puts "<H1>Long Description Changed</H1>" - puts "<UL><LI>" - puts "<A HREF=\"show_bug.cgi?id=[FormData id]\">Show Bug #[FormData id]</A>" - puts "<LI><A HREF=\"query.cgi\">Query Page</A>" - exec ./processmail [FormData id] < /dev/null > /dev/null 2> /dev/null & - exit 0 -} - - -puts "<TITLE>Editing Long Description for bug [FormData id]</TITLE>" - -puts "<H2>Be Careful</H2>" -puts "Many people think that the ability to edit the full long description -is a bad thing and that developers should not be allowed to do this, -because information can get lost. Please do not use this feature casually. -<P><HR>" - -set generic_query { -select - bugs.bug_id, - bugs.product, - bugs.version, - bugs.rep_platform, - bugs.op_sys, - bugs.bug_status, - bugs.bug_severity, - bugs.priority, - bugs.resolution, - assign.login_name, - report.login_name, - bugs.bug_file_loc, - bugs.short_desc -from bugs,profiles assign,profiles report,priorities -where assign.userid = bugs.assigned_to and report.userid = bugs.reporter and -} - - -SendSQL "$generic_query bugs.bug_id = [FormData id]" -set result [ FetchSQLData ] -puts "<TABLE WIDTH=100%>" -puts "<TD COLSPAN=4><TR><DIV ALIGN=CENTER><B><FONT =\"+3\">[html_quote [lindex $result 13]]</B></FONT></DIV>" -puts "<TR><TD><B>Bug#:</B> [lindex $result 0]" -puts "<TD><B>Product:</B> [lindex $result 1]" -puts "<TD><B>Version:</B> [lindex $result 2]" -puts "<TD><B>Platform:</B> [lindex $result 3]" -puts "<TR><TD><B>OS/Version:</B> [lindex $result 4]" -puts "<TD><B>Status:</B> [lindex $result 5]" -puts "<TD><B>Severity:</B> [lindex $result 6]" -puts "<TD><B>Priority:</B> [lindex $result 7]" -puts "</TD><TD><B>Resolution:</B> [lindex $result 8]</TD>" -puts "<TD><B>Assigned To:</B> [lindex $result 9]" -puts "<TD><B>Reported By:</B> [lindex $result 10]" -puts "<TR><TD COLSPAN=6><B>URL:</B> [html_quote [lindex $result 11]]" -puts "<TR><TD><B>Description:</B>\n</TABLE>" - -set ldesc [GetLongDescription [FormData id]] -set lines [llength [split $ldesc "\n"]] -incr lines 10 -if {$lines > 100} { - set lines 100 -} -if {[regexp {Macintosh} $env(HTTP_USER_AGENT)]} { - set cols 160 -} else { - set cols 80 -} - -puts "<FORM METHOD=POST ACTION=\"edit_desc.cgi\"> -<INPUT TYPE=HIDDEN NAME=\"id\" VALUE=$FORM(id)> -<INPUT TYPE=HIDDEN NAME=\"commit\" VALUE=yes> -<TEXTAREA NAME=long_desc WRAP=HARD COLS=$cols ROWS=$lines> -[html_quote $ldesc] -</TEXTAREA> -<INPUT TYPE=SUBMIT VALUE=\"Change Description\"> -</FORM>" diff --git a/editowners.cgi b/editowners.cgi new file mode 100755 index 0000000000000000000000000000000000000000..1bfb6ac13606e2b63e65083b0137e91e14efd2e6 --- /dev/null +++ b/editowners.cgi @@ -0,0 +1,72 @@ +#!/usr/bonsaitools/bin/perl -w +# -*- Mode: perl; indent-tabs-mode: nil -*- +# +# The contents of this file are subject to the Mozilla Public License +# Version 1.0 (the "License"); you may not use this file except in +# compliance with the License. You may obtain a copy of the License at +# http://www.mozilla.org/MPL/ +# +# Software distributed under the License is distributed on an "AS IS" +# basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See the +# License for the specific language governing rights and limitations +# under the License. +# +# The Original Code is the Bugzilla Bug Tracking System. +# +# The Initial Developer of the Original Code is Netscape Communications +# Corporation. Portions created by Netscape are Copyright (C) 1998 +# Netscape Communications Corporation. All Rights Reserved. +# +# Contributor(s): Sam Ziegler <sam@ziegler.org> + +# Code derived from editparams.cgi + +use diagnostics; +use strict; + +require "CGI.pl"; + +# Shut up misguided -w warnings about "used only once": +use vars %::COOKIE; + +confirm_login(); + +print "Content-type: text/html\n\n"; + +if (Param("maintainer") ne $::COOKIE{Bugzilla_login}) { + print "<H1>Sorry, you aren't the maintainer of this system.</H1>\n"; + print "And so, you aren't allowed to edit the parameters of it.\n"; + exit; +} + + +PutHeader("Edit Component Owners"); + +print "This lets you edit the owners of the program components of bugzilla.\n"; + +print "<form method=post action=doeditowners.cgi><table>\n"; + +my $rowbreak = "<tr><td colspan=2><hr></td></tr>"; + +SendSQL("select program, value, initialowner from components order by program, value"); + +my @line; +my $curProgram = ""; + +while (@line = FetchSQLData()) { + if ($line[0] ne $curProgram) { + print $rowbreak; + print "<tr><th align=right valign=top>$line[0]:</th><td></td></tr>\n"; + $curProgram = $line[0]; + } + print "<tr><td valign = top>$line[1]</td><td><input size=80 "; + print "name=\"$line[0]_$line[1]\" value=\"$line[2]\"></td></tr>\n"; +} + +print "</table>\n"; + +print "<input type=submit value=\"Submit changes\">\n"; + +print "</form>\n"; + +print "<p><a href=query.cgi>Skip all this, and go back to the query page</a>\n"; diff --git a/editparams.cgi b/editparams.cgi index f926c0ae97849d874a01a89351ccee75f6865004..75c7500d78a98852e019aeeee73c865ae318bd86 100755 --- a/editparams.cgi +++ b/editparams.cgi @@ -61,7 +61,7 @@ foreach my $i (@::param_list) { SWITCH: for ($::param_type{$i}) { /^t$/ && do { print "<input size=80 name=$i value=\"" . - value_quote($value) . '">\n'; + value_quote($value) . "\">\n"; last SWITCH; }; /^l$/ && do { diff --git a/enter_bug.cgi b/enter_bug.cgi index c2196240003fc2cb918f5670efa132f6d68f9748..9b365152263f98b450d9c4ee380007b4c236547f 100755 --- a/enter_bug.cgi +++ b/enter_bug.cgi @@ -41,9 +41,15 @@ if (!defined $::FORM{'product'}) { print "<H2>First, you must pick a product on which to enter\n"; print "a bug.</H2>\n"; + print "<table>"; foreach my $p (sort (@prodlist)) { - print "<a href=\"enter_bug.cgi?product=" . url_quote($p) . "\"&$::buffer>$p</a><br>\n"; + print "<tr><th align=right valign=top><a href=\"enter_bug.cgi?product=" . url_quote($p) . "\"&$::buffer>$p</a>:</th>\n"; + if (defined $::proddesc{$p}) { + print "<td valign=top>$::proddesc{$p}</td>\n"; + } + print "</tr>"; } + print "</table>\n"; exit; } $::FORM{'product'} = $prodlist[0]; @@ -72,12 +78,17 @@ sub pickplatform { return $value; } for ($ENV{'HTTP_USER_AGENT'}) { - /Mozilla.*\(X11/ && do {return "X-Windows";}; /Mozilla.*\(Windows/ && do {return "PC";}; /Mozilla.*\(Macintosh/ && do {return "Macintosh";}; /Mozilla.*\(Win/ && do {return "PC";}; + /Mozilla.*Linux.*86/ && do {return "PC";}; + /Mozilla.*Linux.*alpha/ && do {return "DEC";}; + /Mozilla.*OSF/ && do {return "DEC";}; + /Mozilla.*HP-UX/ && do {return "HP";}; + /Mozilla.*IRIX/ && do {return "SGI";}; + /Mozilla.*(SunOS|Solaris)/ && do {return "Sun";}; # default - return "PC"; + return "Other"; } } @@ -122,13 +133,14 @@ sub pickos { /Mozilla.*\(.*;.*; IRIX.*\)/ && do {return "IRIX";}; /Mozilla.*\(.*;.*; 32bit.*\)/ && do {return "Windows 95";}; /Mozilla.*\(.*;.*; 16bit.*\)/ && do {return "Windows 3.1";}; - /Mozilla.*\(.*;.*; 68K.*\)/ && do {return "System 7.5";}; - /Mozilla.*\(.*;.*; PPC.*\)/ && do {return "System 7.5";}; + /Mozilla.*\(.*;.*; 68K.*\)/ && do {return "Mac System 8.5";}; + /Mozilla.*\(.*;.*; PPC.*\)/ && do {return "Mac System 8.5";}; /Mozilla.*\(.*;.*; OSF.*\)/ && do {return "OSF/1";}; /Mozilla.*\(.*;.*; Linux.*\)/ && do {return "Linux";}; /Mozilla.*\(.*;.*; SunOS 5.*\)/ && do {return "Solaris";}; /Mozilla.*\(.*;.*; SunOS.*\)/ && do {return "SunOS";}; /Mozilla.*\(.*;.*; SunOS.*\)/ && do {return "SunOS";}; + /Mozilla.*\(.*;.*; BSD\/OS.*\)/ && do {return "BSDI";}; /Mozilla.*\(Win16.*\)/ && do {return "Windows 3.1";}; /Mozilla.*\(Win95.*\)/ && do {return "Windows 95";}; /Mozilla.*\(WinNT.*\)/ && do {return "Windows NT";}; @@ -171,14 +183,15 @@ print " <TR> <td ALIGN=right valign=top><B>Version:</B></td> <td>" . Version_element(pickversion(), $product) . "</td> - <td align=right valign=top><b>Component:</b></td> + <td align=right valign=top><b><a href=\"describecomponents.cgi?product=" . + url_quote($product) . "\">Component:</b></td> <td>$component_popup</td> </TR> <tr><td> <td> <td> <td> <td> <td> </tr> <TR> <td align=right><b><B><A HREF=\"bug_status.html#rep_platform\">Platform:</A></B></td> <TD>$platform_popup</TD> - <TD ALIGN=RIGHT><B>OS:</B></TD> + <TD ALIGN=RIGHT><B><A HREF=\"bug_status.html#op_sys\">OS:</A></B></TD> <TD>$opsys_popup</TD> <td align=right valign=top></td> <td rowspan=3></td> diff --git a/globals.pl b/globals.pl index 306c633db172f014a45e8fb6f8c7f163c6c0e6dc..ac6b4b7cc08d7a67fe47b03c2d99192283f68894 100644 --- a/globals.pl +++ b/globals.pl @@ -25,9 +25,10 @@ use strict; use Mysql; use Date::Format; # For time2str(). +# use Carp; # for confess # Contains the version string for the current running Bugzilla. -$::param{'version'} = '2.0'; +$::param{'version'} = '2.2'; $::dontchange = "--do_not_change--"; $::chooseone = "--Choose_one:--"; @@ -71,10 +72,6 @@ sub FetchOneColumn { } -@::legal_opsys = ("Windows 3.1", "Windows 95", "Windows NT", "System 7", - "System 7.5", "7.1.6", "AIX", "BSDI", "HP-UX", "IRIX", - "Linux", "OSF/1", "Solaris", "SunOS", "other"); - @::default_column_list = ("severity", "priority", "platform", "owner", "status", "resolution", "summary"); @@ -235,6 +232,19 @@ sub GenerateVersionTable { $carray{$c} = 1; } + my $dotargetmilestone = Param("usetargetmilestone"); + + my $mpart = $dotargetmilestone ? ", milestoneurl" : ""; + SendSQL("select product, description$mpart from products"); + while (@line = FetchSQLData()) { + my ($p, $d, $u) = (@line); + $::proddesc{$p} = $d; + if ($dotargetmilestone) { + $::milestoneurl{$p} = $u; + } + } + + my $cols = LearnAboutColumns("bugs"); @::log_columns = @{$cols->{"-list-"}}; @@ -248,6 +258,7 @@ sub GenerateVersionTable { @::legal_priority = SplitEnumType($cols->{"priority,type"}); @::legal_severity = SplitEnumType($cols->{"bug_severity,type"}); @::legal_platform = SplitEnumType($cols->{"rep_platform,type"}); + @::legal_opsys = SplitEnumType($cols->{"op_sys,type"}); @::legal_bug_status = SplitEnumType($cols->{"bug_status,type"}); @::legal_resolution = SplitEnumType($cols->{"resolution,type"}); @::legal_resolution_no_dup = @::legal_resolution; @@ -276,11 +287,21 @@ sub GenerateVersionTable { print FID GenerateCode('%::components'); @::legal_components = sort {uc($a) cmp uc($b)} keys(%carray); print FID GenerateCode('@::legal_components'); - foreach my $i('product', 'priority', 'severity', 'platform', + foreach my $i('product', 'priority', 'severity', 'platform', 'opsys', 'bug_status', 'resolution', 'resolution_no_dup') { print FID GenerateCode('@::legal_' . $i); } + print FID GenerateCode('%::proddesc'); + if ($dotargetmilestone) { + my $last = Param("nummilestones"); + my $i; + for ($i=1 ; $i<=$last ; $i++) { + push(@::legal_target_milestone, "M$i"); + } + print FID GenerateCode('@::legal_target_milestone'); + print FID GenerateCode('%::milestoneurl'); + } print FID "1;\n"; close FID; rename $tmpname, "data/versioncache" || die "Can't rename $tmpname to versioncache"; @@ -447,6 +468,9 @@ sub SplitEnumType { sub SqlQuote { my ($str) = (@_); +# if (!defined $str) { +# confess("Undefined passed to SqlQuote"); +# } $str =~ s/([\\\'])/\\$1/g; $str =~ s/\0/\\0/g; return "'$str'"; @@ -461,7 +485,13 @@ sub Param { } # Um, maybe we haven't sourced in the params at all yet. if (stat("data/params")) { + # Write down and restore the version # here. That way, we get around + # anyone who maliciously tries to tweak the version number by editing + # the params file. Not to mention that in 2.0, there was a bug that + # wrote the version number out to the params file... + my $v = $::param{'version'}; require "data/params"; + $::param{'version'} = $v; } if (defined $::param{$value}) { return $::param{$value}; @@ -490,8 +520,8 @@ sub PerformSubsts { sub trim { ($_) = (@_); - s/^\s*//g; - s/\s*$//g; + s/^\s+//g; + s/\s+$//g; return $_; } diff --git a/helpemailquery.html b/helpemailquery.html new file mode 100644 index 0000000000000000000000000000000000000000..622e3aa458b888cc1c4f281cc15d088cb576aa89 --- /dev/null +++ b/helpemailquery.html @@ -0,0 +1,36 @@ +<html> <head> +<title>Help on searching by email address.</title> +</head> + +<body> +<h1>Help on searching by email address.</h1> + +This used to be simpler, but not very powerful. Now it's really +powerful and useful, but it may not be obvious how to use it... + +<p> + +To search for bugs associated with an email address: + +<ul> + <li> Type a portion of an email address into the text field. + <li> Select which fields of the bug you expect that address to be in + the bugs you're looking for. +</ul> + +<p> + +You can look for up to two different email addresses; if you specify +both, then only bugs which match both will show up. This is useful to +find bugs that were, for example, created by Ralph and assigned to +Fred. + +<p> + +You can also use the drop down menus to specify whether you want to +match addresses by doing a substring match, by using regular +expressions, or by exactly matching a fully specified email address. + + + +</body> </html> diff --git a/index.html b/index.html index d1537012a7f1bc122cbd9fc218c0b96158cdbabd..a8e36662f4d7a69ed01b7707eab623c7edd35aaa 100644 --- a/index.html +++ b/index.html @@ -68,7 +68,8 @@ bugzilla. But it all boils down to a choice of: <br> <a href="query.cgi">Go to the query page to start.</a><br> -<a href="enter_bug.cgi">Enter a new bug</a> +<a href="enter_bug.cgi">Enter a new bug</a><br> +<a href="reports.cgi">Bug reports</a> <FORM METHOD=GET ACTION=show_bug.cgi><INPUT TYPE=SUBMIT VALUE="Find"> bug # <INPUT NAME=id SIZE=6></FORM></TD> diff --git a/long_list.cgi b/long_list.cgi index 1fb019496e42a3c5861053ff44874eb8cd4e625d..18f3c0e27f4c79f8374d8499d31fb84b2e14e3e2 100755 --- a/long_list.cgi +++ b/long_list.cgi @@ -46,7 +46,10 @@ select report.login_name, bugs.component, bugs.bug_file_loc, - bugs.short_desc + bugs.short_desc, + bugs.target_milestone, + bugs.qa_contact, + bugs.status_whiteboard from bugs,profiles assign,profiles report where assign.userid = bugs.assigned_to and report.userid = bugs.reporter and "; @@ -60,7 +63,8 @@ foreach my $bug (split(/:/, $::FORM{'buglist'})) { if (@row = FetchSQLData()) { my ($id, $product, $version, $platform, $opsys, $status, $severity, $priority, $resolution, $assigned, $reporter, $component, $url, - $shortdesc) = (@row); + $shortdesc, $target_milestone, $qa_contact, + $status_whiteboard) = (@row); print "<IMG SRC=\"1x1.gif\" WIDTH=1 HEIGHT=80 ALIGN=LEFT>\n"; print "<TABLE WIDTH=100%>\n"; print "<TD COLSPAN=4><TR><DIV ALIGN=CENTER><B><FONT =\"+3\">" . @@ -77,10 +81,24 @@ foreach my $bug (split(/:/, $::FORM{'buglist'})) { print "<TR><TD><B>Resolution:</B> $resolution</TD>\n"; print "<TD><B>Assigned To:</B> $assigned\n"; print "<TD><B>Reported By:</B> $reporter\n"; + if (Param("useqacontact")) { + my $name = ""; + if ($qa_contact > 0) { + $name = DBID_to_name($qa_contact); + } + print "<TD><B>QA Contact:</B> $name\n"; + } print "<TR><TD><B>Component:</B> $component\n"; + if (Param("usetargetmilestone")) { + print "<TD><B>Target milestone:</B>$target_milestone\n"; + } print "<TR><TD COLSPAN=6><B>URL:</B> " . html_quote($url) . "\n"; - print "<TR><TD COLSPAN=6><B>Summary :</B> " . html_quote($shortdesc) . "\n"; - print "<TR><TD><B>Description :</B>\n</TABLE>\n"; + print "<TR><TD COLSPAN=6><B>Summary:</B> " . html_quote($shortdesc) . "\n"; + if (Param("usestatuswhiteboard")) { + print "<TR><TD COLSPAN=6><B>Status Whiteboard:" . + html_quote($status_whiteboard) . "\n"; + } + print "<TR><TD><B>Description:</B>\n</TABLE>\n"; print "<PRE>" . html_quote(GetLongDescription($bug)) . "</PRE>\n"; print "<HR>\n"; } diff --git a/makebugtable.sh b/makebugtable.sh index ff0cc78c17a9ef5ca788ab912bda361bb0c70160..b6ca5473dd8d500da6c470d37ae7e38f0e89f20c 100755 --- a/makebugtable.sh +++ b/makebugtable.sh @@ -37,28 +37,33 @@ creation_ts datetime, delta_ts timestamp, short_desc mediumtext, long_desc mediumtext, -op_sys tinytext, +op_sys enum("All", "Windows 3.1", "Windows 95", "Windows 98", "Windows NT", "Mac System 7", "Mac System 7.5", "Mac System 7.6.1", "Mac System 8.0", "Mac System 8.5", "AIX", "BSDI", "HP-UX", "IRIX", "Linux", "FreeBSD", "OSF/1", "Solaris", "SunOS", "OS/2", "other") not null, priority enum("P1", "P2", "P3", "P4", "P5") not null, product varchar(16) not null, -rep_platform enum("All", "DEC", "HP", "Macintosh", "PC", "SGI", "Sun", "X-Windows", "Other"), +rep_platform enum("All", "DEC", "HP", "Macintosh", "PC", "SGI", "Sun", "Other"), reporter mediumint not null, version varchar(16) not null, area enum("BUILD", "CODE", "CONTENT", "DOC", "PERFORMANCE", "TEST", "UI", "i18n", "l10n") not null, component varchar(50) not null, resolution enum("", "FIXED", "INVALID", "WONTFIX", "LATER", "REMIND", "DUPLICATE", "WORKSFORME") not null, - +target_milestone varchar(20) not null, +qa_contact mediumint not null, +status_whiteboard mediumtext not null, index (assigned_to), index (delta_ts), index (bug_severity), index (bug_status), +index (op_sys), index (priority), index (product), index (reporter), index (version), index (area), index (component), -index (resolution) +index (resolution), +index (target_milestone), +index (qa_contact) ); diff --git a/makecctable.sh b/makecctable.sh index 44c50ca925afeff00ae04ae8ef84852ae98160d3..f0bde191bcbdb967a555c48473a501aeef77f736 100755 --- a/makecctable.sh +++ b/makecctable.sh @@ -29,7 +29,10 @@ mysql << OK_ALL_DONE use bugs; create table cc ( bug_id mediumint not null, - who mediumint not null + who mediumint not null, + + index(bug_id), + index(who) ); diff --git a/makecomponenttable.sh b/makecomponenttable.sh index b2e95c2f3f48af7b9c4f50ab131205ed2112a197..5688e91c7215d6ce8940fec79d0e2c2efeca1144 100755 --- a/makecomponenttable.sh +++ b/makecomponenttable.sh @@ -30,94 +30,139 @@ use bugs; create table components ( value tinytext, program tinytext, -initialowner tinytext # Should arguably be a mediumint! +initialowner tinytext not null, # Should arguably be a mediumint! +initialqacontact tinytext not null, # Should arguably be a mediumint! +description mediumtext not null ); - -insert into components (value, program, initialowner) values ("Macintosh FE", "Mozilla", "sdagley@netscape.com"); -insert into components (value, program, initialowner) values ("Windows FE", "Mozilla", "blythe@netscape.com"); -insert into components (value, program, initialowner) values ("XFE", "Mozilla", "ramiro@netscape.com"); -insert into components (value, program, initialowner) values ("StubFE", "Mozilla", "toshok@netscape.com"); -insert into components (value, program, initialowner) values ("Aurora/RDF FE", "Mozilla", "don@netscape.com"); -insert into components (value, program, initialowner) values ("Aurora/RDF BE", "Mozilla", "guha@netscape.com"); -insert into components (value, program, initialowner) values ("Berkeley DB", "Mozilla", "montulli@netscape.com"); -insert into components (value, program, initialowner) values ("Browser Hooks", "Mozilla", "ebina@netscape.com"); -insert into components (value, program, initialowner) values ("Build Config", "Mozilla", "briano@netscape.com"); -insert into components (value, program, initialowner) values ("Composer", "Mozilla", "brade@netscape.com"); -insert into components (value, program, initialowner) values ("Compositor Library", "Mozilla", "vidur@netscape.com"); -insert into components (value, program, initialowner) values ("Dialup", "Mozilla", "selmer@netscape.com"); -insert into components (value, program, initialowner) values ("FontLib", "Mozilla", "dp@netscape.com"); -insert into components (value, program, initialowner) values ("HTML Dialogs", "Mozilla", "nisheeth@netscape.com"); -insert into components (value, program, initialowner) values ("HTML to Text/PostScript Translation", "Mozilla", "brendan@netscape.com"); -insert into components (value, program, initialowner) values ("ImageLib", "Mozilla", "pnunn@netscape.com"); -insert into components (value, program, initialowner) values ("JPEG Image Handling", "Mozilla", "tgl@sss.pgh.pa.us"); -insert into components (value, program, initialowner) values ("PNG Image Handling", "Mozilla", "png@wco.com"); -insert into components (value, program, initialowner) values ("Image Conversion Library", "Mozilla", "mjudge@netscape.com"); -insert into components (value, program, initialowner) values ("I18N Library", "Mozilla", "bobj@netscape.com"); -insert into components (value, program, initialowner) values ("Java Stubs", "Mozilla", "warren@netscape.com"); -insert into components (value, program, initialowner) values ("JavaScript", "Mozilla", "mccabe@netscape.com"); -insert into components (value, program, initialowner) values ("JavaScript Debugger", "Mozilla", "jband@netscape.com"); -insert into components (value, program, initialowner) values ("JavaScript/Java Reflection", "Mozilla", "fur@netscape.com"); -insert into components (value, program, initialowner) values ("Layout", "Mozilla", "toshok@netscape.com"); -insert into components (value, program, initialowner) values ("LibMocha", "Mozilla", "mlm@netscape.com"); -insert into components (value, program, initialowner) values ("MIMELib", "Mozilla", "terry@mozilla.org"); -insert into components (value, program, initialowner) values ("NetLib", "Mozilla", "gagan@netscape.com"); -insert into components (value, program, initialowner) values ("NSPR", "Mozilla", "wtc@netscape.com"); -insert into components (value, program, initialowner) values ("Password Cache", "Mozilla", "montulli@netscape.com"); -insert into components (value, program, initialowner) values ("PICS", "Mozilla", "montulli@netscape.com"); -insert into components (value, program, initialowner) values ("Plugins", "Mozilla", "amusil@netscape.com"); -insert into components (value, program, initialowner) values ("Preferences", "Mozilla", "aoki@netscape.com"); -insert into components (value, program, initialowner) values ("Progress Window", "Mozilla", "atotic@netscape.com"); -insert into components (value, program, initialowner) values ("Registry", "Mozilla", "dveditz@netscape.com"); -insert into components (value, program, initialowner) values ("Scheduler", "Mozilla", "aoki@netscape.com"); -insert into components (value, program, initialowner) values ("Security Stubs", "Mozilla", "jsw@netscape.com"); -insert into components (value, program, initialowner) values ("SmartUpdate", "Mozilla", "dveditz@netscape.com"); -insert into components (value, program, initialowner) values ("XML", "Mozilla", "guha@netscape.com"); -insert into components (value, program, initialowner) values ("XP-COM", "Mozilla", "scullin@netscape.com"); -insert into components (value, program, initialowner) values ("XP File Handling", "Mozilla", "atotic@netscape.com"); -insert into components (value, program, initialowner) values ("XP Miscellany", "Mozilla", "brendan@netscape.com"); -insert into components (value, program, initialowner) values ("XP Utilities", "Mozilla", "toshok@netscape.com"); -insert into components (value, program, initialowner) values ("Zlib", "Mozilla", "pnunn@netscape.com"); - - - -insert into components (value, program, initialowner) values ("Platform: Lesstif on Linux", "Mozilla", "ramiro@netscape.com"); -insert into components (value, program, initialowner) values ("Platform: OS/2", "Mozilla", "law@netscape.com"); -insert into components (value, program, initialowner) values ("Platform: MacOS/PPC", "Mozilla", "sdagley@netscape.com"); -insert into components (value, program, initialowner) values ("Platform: Rhapsody", "Mozilla", "mcafee@netscape.com"); -insert into components (value, program, initialowner) values ("Platform: MFC/Win32 on Windows", "Mozilla", "blythe@netscape.com"); - - -insert into components (value, program, initialowner) values ("UI", "Bugzilla", "terry@mozilla.org"); -insert into components (value, program, initialowner) values ("Database", "Bugzilla", "terry@mozilla.org"); - - -insert into components (value, program, initialowner) values ("ActiveX Wrapper", "NGLayout", "locka@iol.ie"); -insert into components (value, program, initialowner) values ("Content Model", "NGLayout", "kipp@netscape.com"); -insert into components (value, program, initialowner) values ("Cookies", "NGLayout", "scullin@netscape.com"); -insert into components (value, program, initialowner) values ("DOM", "NGLayout", "vidur@netscape.com"); -insert into components (value, program, initialowner) values ("DOM", "NGLayout", "vidur@netscape.com"); -insert into components (value, program, initialowner) values ("Editing Interfaces", "NGLayout", "kostello@netscape.com"); -insert into components (value, program, initialowner) values ("Embedding APIs", "NGLayout", "jevering@netscape.com"); -insert into components (value, program, initialowner) values ("Event Handling", "NGLayout", "joki@netscape.com"); -insert into components (value, program, initialowner) values ("Event Handling", "NGLayout", "joki@netscape.com"); -insert into components (value, program, initialowner) values ("Form Submission", "NGLayout", "karnaze@netscape.com"); -insert into components (value, program, initialowner) values ("HTMLFrames", "NGLayout", "karnaze@netscape.com"); -insert into components (value, program, initialowner) values ("HTMLTables", "NGLayout", "buster@netscape.com"); -insert into components (value, program, initialowner) values ("Layout", "NGLayout", "kipp@netscape.com"); -insert into components (value, program, initialowner) values ("Networking Library", "NGLayout", "valeski@netscape.com"); -insert into components (value, program, initialowner) values ("Parser", "NGLayout", "rickg@netscape.com"); -insert into components (value, program, initialowner) values ("Plug-ins", "NGLayout", "michaelp@netscape.com"); -insert into components (value, program, initialowner) values ("Rendering", "NGLayout", "michaelp@netscape.com"); -insert into components (value, program, initialowner) values ("Selection and Search", "NGLayout", "rods@netscape.com"); -insert into components (value, program, initialowner) values ("Style System", "NGLayout", "peterl@netscape.com"); -insert into components (value, program, initialowner) values ("Threading", "NGLayout", "rpotts@netscape.com"); -insert into components (value, program, initialowner) values ("Viewer App", "NGLayout", "scullin@netscape.com"); -insert into components (value, program, initialowner) values ("Widget Set", "NGLayout", "kmcclusk@netscape.com"); -insert into components (value, program, initialowner) values ("XPCOM", "NGLayout", "scullin@netscape.com"); - +insert into components (value, program, initialowner, initialqacontact) values ("XPFC", "Calendar", "spider@netscape.com", ""); +insert into components (value, program, initialowner, initialqacontact) values ("config", "Calendar", "spider@netscape.com", ""); +insert into components (value, program, initialowner, initialqacontact) values ("Core", "Calendar", "sman@netscape.com", ""); +insert into components (value, program, initialowner, initialqacontact) values ("NLS", "Calendar", "jusn@netscape.com", ""); +insert into components (value, program, initialowner, initialqacontact) values ("UI", "Calendar", "eyork@netscape.com", ""); +insert into components (value, program, initialowner, initialqacontact) values ("Test", "Calendar", "sman@netscape.com", ""); +insert into components (value, program, initialowner, initialqacontact) values ("Install", "Calendar", "sman@netscape.com", ""); + +insert into components (value, program, initialowner, initialqacontact, description) values ("CCK-Wizard", "CCK", "selmer@netscape.com", "bmartin@netscape.com", "The CCK wizard allows the user to gather data by walking through a series of screens to create a set of customizations and build a media image."); +insert into components (value, program, initialowner, initialqacontact, description) values ("CCK-Installation", "CCK", "selmer@netscape.com", "bmartin@netscape.com", "The CCK installation includes verifying the CD-layout. Other areas include the installations screens, directory structure, branding and launching the CCK Wizard."); +insert into components (value, program, initialowner, initialqacontact, description) values ("CCK-Shell", "CCK", "selmer@netscape.com", "bmartin@netscape.com", "CCK allows an ISP to customize the first screen seen by the user. The shell dialog(s) displays a background image as well as buttons and text explaining the installation options to the user."); +insert into components (value, program, initialowner, initialqacontact, description) values ("CCK-Whitebox", "CCK", "selmer@netscape.com", "bmartin@netscape.com", "This is a series of whitebox tests to test the critical functions of the CCK Wizard."); +insert into components (value, program, initialowner, initialqacontact, description) values ("Dialup-Install", "CCK", "selmer@netscape.com", "bmartin@netscape.com", "This is the Installation of a custom build which includes the Account Setup module created by CCK"); +insert into components (value, program, initialowner, initialqacontact, description) values ("Dialup-Account Setup", "CCK", "selmer@netscape.com", "bmartin@netscape.com", "The Account Setup Wizard is used by the end users who want to create or modify an existing Internet account."); +insert into components (value, program, initialowner, initialqacontact, description) values ("Dialup-Mup/Muc", "CCK", "selmer@netscape.com", "bmartin@netscape.com", "This refers to multiple user configurations which allows association of Microsoft dialup networking connectoids to Netscape user profiles."); +insert into components (value, program, initialowner, initialqacontact, description) values ("Dialup-Upgrade", "CCK", "selmer@netscape.com", "bmartin@netscape.com", "This is the upgrade path from 4.5 to the latest release where the user preferences are preserved."); +insert into components (value, program, initialowner, initialqacontact, description) values ("AS-Whitebox", "CCK", "selmer@netscape.com", "bmartin@netscape.com", "This is a series of whitebox tests to test the critical functions of the Account Setup."); + +insert into components (value, program, initialowner, initialqacontact) values ("LDAP C SDK", "Directory", "chuckb@netscape.com", ""); +insert into components (value, program, initialowner, initialqacontact) values ("LDAP Java SDK", "Directory", "chuckb@netscape.com", ""); +insert into components (value, program, initialowner, initialqacontact) values ("PerLDAP", "Directory", "leif@netscape.com", ""); +insert into components (value, program, initialowner, initialqacontact) values ("LDAP Tools", "Directory", "chuckb@netscape.com", ""); + + +insert into components (value, program, initialowner, initialqacontact, description) values ("Networking", "MailNews", "mscott@netscape.com", "lchiang@netscape.com", "Integration with libnet, protocol support for POP3, IMAP4, SMTP, NNTP and LDAP"); +insert into components (value, program, initialowner, initialqacontact, description) values ("Database", "MailNews", "davidmc@netscape.com", "lchiang@netscape.com", "Persistent storage of address books and mail/news summary files"); +insert into components (value, program, initialowner, initialqacontact, description) values ("MIME", "MailNews", "rhp@netscape.com", "lchiang@netscape.com", "Parsing the MIME structure"); +insert into components (value, program, initialowner, initialqacontact, description) values ("Security", "MailNews", "jefft@netscape.com", "lchiang@netscape.com", "SSL, S/MIME for mail"); +insert into components (value, program, initialowner, initialqacontact, description) values ("Composition", "MailNews", "ducarroz@netscape.com", "lchiang@netscape.com", "Front-end and back-end of message composition and sending"); +insert into components (value, program, initialowner, initialqacontact, description) values ("Address Book", "MailNews", "putterman@netscape.com", "lchiang@netscape.com", "Names, email addresses, phone numbers, etc."); +insert into components (value, program, initialowner, initialqacontact, description) values ("Front End", "MailNews", "phil@netscape.com", "lchiang@netscape.com", "Three pane view, sidebar contents, toolbars, dialogs, etc."); +insert into components (value, program, initialowner, initialqacontact, description) values ("Back End", "MailNews", "phil@netscape.com", "lchiang@netscape.com", "RDF data sources and application logic for local mail, news, IMAP and LDAP"); +insert into components (value, program, initialowner, initialqacontact, description) values ("Internationalization", "MailNews", "nhotta@netscape.com", "momoi@netscape.com", "Internationalization is the process of designing and developing a software product to function in multiple locales. This process involves identifying the locales that must be supported, designing features which support those locales, and writing code that functions equally well in any of the supported locales."); +insert into components (value, program, initialowner, initialqacontact, description) values ("Localization", "MailNews", "rchen@netscape.com", "momoi@netscape.com", "Localization is the process of adapting software for a specific international market; this process includes translating the user interface, resizing dialog boxes, replacing icons and other culturally sensitive graphics (if necessary), customizing features (if necessary), and testing the localized product to ensure that the program still works."); + + + +insert into components (value, program, initialowner, initialqacontact) values ("Macintosh FE", "Mozilla", "sdagley@netscape.com", ""); +insert into components (value, program, initialowner, initialqacontact) values ("Windows FE", "Mozilla", "blythe@netscape.com", ""); +insert into components (value, program, initialowner, initialqacontact) values ("XFE", "Mozilla", "ramiro@netscape.com", ""); +insert into components (value, program, initialowner, initialqacontact) values ("StubFE", "Mozilla", "rickg@netscape.com", ""); +insert into components (value, program, initialowner, initialqacontact) values ("Aurora/RDF FE", "Mozilla", "don@netscape.com", ""); +insert into components (value, program, initialowner, initialqacontact) values ("Aurora/RDF BE", "Mozilla", "guha@netscape.com", ""); +insert into components (value, program, initialowner, initialqacontact) values ("Berkeley DB", "Mozilla", "montulli@netscape.com", ""); +insert into components (value, program, initialowner, initialqacontact) values ("Browser Hooks", "Mozilla", "ebina@netscape.com", ""); +insert into components (value, program, initialowner, initialqacontact) values ("Build Config", "Mozilla", "briano@netscape.com", ""); +insert into components (value, program, initialowner, initialqacontact) values ("Composer", "Mozilla", "akkana@netscape.com", ""); +insert into components (value, program, initialowner, initialqacontact) values ("Compositor Library", "Mozilla", "vidur@netscape.com", ""); +insert into components (value, program, initialowner, initialqacontact) values ("Dialup", "Mozilla", "selmer@netscape.com", ""); +insert into components (value, program, initialowner, initialqacontact) values ("FontLib", "Mozilla", "dp@netscape.com", ""); +insert into components (value, program, initialowner, initialqacontact) values ("HTML Dialogs", "Mozilla", "nisheeth@netscape.com", ""); +insert into components (value, program, initialowner, initialqacontact) values ("HTML to Text/PostScript Translation", "Mozilla", "brendan@netscape.com", ""); +insert into components (value, program, initialowner, initialqacontact) values ("ImageLib", "Mozilla", "pnunn@netscape.com", ""); +insert into components (value, program, initialowner, initialqacontact) values ("JPEG Image Handling", "Mozilla", "tgl@sss.pgh.pa.us", ""); +insert into components (value, program, initialowner, initialqacontact) values ("PNG Image Handling", "Mozilla", "png@wco.com", ""); +insert into components (value, program, initialowner, initialqacontact) values ("Image Conversion Library", "Mozilla", "mjudge@netscape.com", ""); +insert into components (value, program, initialowner, initialqacontact) values ("I18N Library", "Mozilla", "bobj@netscape.com", ""); +insert into components (value, program, initialowner, initialqacontact) values ("Java Stubs", "Mozilla", "warren@netscape.com", ""); +insert into components (value, program, initialowner, initialqacontact) values ("JavaScript", "Mozilla", "mccabe@netscape.com", ""); +insert into components (value, program, initialowner, initialqacontact) values ("JavaScript/Java Reflection", "Mozilla", "fur@netscape.com", ""); +insert into components (value, program, initialowner, initialqacontact) values ("Layout", "Mozilla", "rickg@netscape.com", ""); +insert into components (value, program, initialowner, initialqacontact) values ("LibMocha", "Mozilla", "mlm@netscape.com", ""); +insert into components (value, program, initialowner, initialqacontact) values ("MIMELib", "Mozilla", "terry@mozilla.org", ""); +insert into components (value, program, initialowner, initialqacontact) values ("NetLib", "Mozilla", "gagan@netscape.com", ""); +insert into components (value, program, initialowner, initialqacontact) values ("NSPR", "Mozilla", "srinivas@netscape.com", ""); +insert into components (value, program, initialowner, initialqacontact) values ("Password Cache", "Mozilla", "montulli@netscape.com", ""); +insert into components (value, program, initialowner, initialqacontact) values ("PICS", "Mozilla", "montulli@netscape.com", ""); +insert into components (value, program, initialowner, initialqacontact) values ("Plugins", "Mozilla", "amusil@netscape.com", ""); +insert into components (value, program, initialowner, initialqacontact) values ("Preferences", "Mozilla", "aoki@netscape.com", ""); +insert into components (value, program, initialowner, initialqacontact) values ("Progress Window", "Mozilla", "atotic@netscape.com", ""); +insert into components (value, program, initialowner, initialqacontact) values ("Registry", "Mozilla", "dveditz@netscape.com", ""); +insert into components (value, program, initialowner, initialqacontact) values ("Scheduler", "Mozilla", "aoki@netscape.com", ""); +insert into components (value, program, initialowner, initialqacontact) values ("Security Stubs", "Mozilla", "jsw@netscape.com", ""); +insert into components (value, program, initialowner, initialqacontact) values ("SmartUpdate", "Mozilla", "dveditz@netscape.com", ""); +insert into components (value, program, initialowner, initialqacontact) values ("XML", "Mozilla", "guha@netscape.com", ""); +insert into components (value, program, initialowner, initialqacontact) values ("XP-COM", "Mozilla", "scullin@netscape.com", ""); +insert into components (value, program, initialowner, initialqacontact) values ("XP File Handling", "Mozilla", "atotic@netscape.com", ""); +insert into components (value, program, initialowner, initialqacontact) values ("XP Miscellany", "Mozilla", "brendan@netscape.com", ""); +insert into components (value, program, initialowner, initialqacontact) values ("XP Utilities", "Mozilla", "rickg@netscape.com", ""); +insert into components (value, program, initialowner, initialqacontact) values ("Zlib", "Mozilla", "pnunn@netscape.com", ""); +insert into components (value, program, initialowner, initialqacontact, description) values ("Internationalization", "Mozilla", "ftang@netscape.com", "teruko@netscape.com", "Internationalization is the process of designing and developing a software product to function in multiple locales. This process involves identifying the locales that must be supported, designing features which support those locales, and writing code that functions equally well in any of the supported locales."); +insert into components (value, program, initialowner, initialqacontact, description) values ("Localization", "Mozilla", "rchen@netscape.com", "teruko@netscape.com", "Localization is the process of adapting software for a specific international market; this process includes translating the user interface, resizing dialog boxes, replacing icons and other culturally sensitive graphics (if necessary), customizing features (if necessary), and testing the localized product to ensure that the program still works."); + + + +insert into components (value, program, initialowner, initialqacontact) values ("Platform: Lesstif on Linux", "Mozilla", "ramiro@netscape.com", ""); +insert into components (value, program, initialowner, initialqacontact) values ("Platform: OS/2", "Mozilla", "law@netscape.com", ""); +insert into components (value, program, initialowner, initialqacontact) values ("Platform: MacOS/PPC", "Mozilla", "sdagley@netscape.com", ""); +insert into components (value, program, initialowner, initialqacontact) values ("Platform: Rhapsody", "Mozilla", "mcafee@netscape.com", ""); +insert into components (value, program, initialowner, initialqacontact) values ("Platform: MFC/Win32 on Windows", "Mozilla", "blythe@netscape.com", ""); + + +insert into components (value, program, initialowner, initialqacontact) values ("ActiveX Wrapper", "NGLayout", "locka@iol.ie", ""); +insert into components (value, program, initialowner, initialqacontact) values ("Content Model", "NGLayout", "kipp@netscape.com", ""); +insert into components (value, program, initialowner, initialqacontact) values ("Cookies", "NGLayout", "scullin@netscape.com", ""); +insert into components (value, program, initialowner, initialqacontact) values ("DOM", "NGLayout", "vidur@netscape.com", ""); +insert into components (value, program, initialowner, initialqacontact) values ("DOM", "NGLayout", "vidur@netscape.com", ""); +insert into components (value, program, initialowner, initialqacontact) values ("Editor", "NGLayout", "kostello@netscape.com", ""); +insert into components (value, program, initialowner, initialqacontact) values ("Embedding APIs", "NGLayout", "jevering@netscape.com", ""); +insert into components (value, program, initialowner, initialqacontact) values ("Event Handling", "NGLayout", "joki@netscape.com", ""); +insert into components (value, program, initialowner, initialqacontact) values ("Event Handling", "NGLayout", "joki@netscape.com", ""); +insert into components (value, program, initialowner, initialqacontact) values ("Form Submission", "NGLayout", "pollmann@netscape.com", ""); +insert into components (value, program, initialowner, initialqacontact) values ("HTMLFrames", "NGLayout", "karnaze@netscape.com", ""); +insert into components (value, program, initialowner, initialqacontact) values ("HTMLTables", "NGLayout", "karnaze@netscape.com", ""); +insert into components (value, program, initialowner, initialqacontact) values ("Layout", "NGLayout", "troy@netscape.com", ""); +insert into components (value, program, initialowner, initialqacontact) values ("Networking Library", "NGLayout", "gagan@netscape.com", ""); +insert into components (value, program, initialowner, initialqacontact) values ("Parser", "NGLayout", "rickg@netscape.com", ""); +insert into components (value, program, initialowner, initialqacontact) values ("Plug-ins", "NGLayout", "amusil@netscape.com", ""); +insert into components (value, program, initialowner, initialqacontact) values ("Compositor", "NGLayout", "michaelp@netscape.com", ""); +insert into components (value, program, initialowner, initialqacontact) values ("Selection and Search", "NGLayout", "kostello@netscape.com", ""); +insert into components (value, program, initialowner, initialqacontact) values ("Style System", "NGLayout", "peterl@netscape.com", ""); +insert into components (value, program, initialowner, initialqacontact) values ("Threading", "NGLayout", "rpotts@netscape.com", ""); +insert into components (value, program, initialowner, initialqacontact) values ("Viewer App", "NGLayout", "rickg@netscape.com", ""); +insert into components (value, program, initialowner, initialqacontact) values ("Widget Set", "NGLayout", "kmcclusk@netscape.com", ""); +insert into components (value, program, initialowner, initialqacontact) values ("XPCOM", "NGLayout", "scullin@netscape.com", ""); +insert into components (value, program, initialowner, initialqacontact) values ("xpidl", "NGLayout", "shaver@netscape.com", ""); +insert into components (value, program, initialowner, initialqacontact, description) values ("Internationalization", "NGLayout", "ftang@netscape.com", "teruko@netscape.com", "Internationalization is the process of designing and developing a software product to function in multiple locales. This process involves identifying the locales that must be supported, designing features which support those locales, and writing code that functions equally well in any of the supported locales."); +insert into components (value, program, initialowner, initialqacontact, description) values ("Localization", "NGLayout", "rchen@netscape.com", "teruko@netscape.com", "Localization is the process of adapting software for a specific international market; this process includes translating the user interface, resizing dialog boxes, replacing icons and other culturally sensitive graphics (if necessary), customizing features (if necessary), and testing the localized product to ensure that the program still works."); + + +insert into components (value, program, initialowner, initialqacontact, description) values ("Bonsai", "Webtools", "terry@mozilla.org", "", 'Web based <a href="http://www.mozilla.org/bonsai.html">Tree control system</a> for watching the up-to-the-minute goings-on in a CVS repository'); +insert into components (value, program, initialowner, initialqacontact, description) values ("Bugzilla", "Webtools", "terry@mozilla.org", "", "Use this component to report bugs in the bug system itself"); +insert into components (value, program, initialowner, initialqacontact, description) values ("Despot", "Webtools", "terry@mozilla.org", "", "mozilla.org's <a href=http://cvs-mirror.mozilla.org/webtools/despot.cgi>account management</a> system"); +insert into components (value, program, initialowner, initialqacontact, description) values ("LXR", "Webtools", "endico@mozilla.org", "", 'Source code <a href="http://cvs-mirror.mozilla.org/webtools/lxr/">cross reference</a> system'); +insert into components (value, program, initialowner, initialqacontact, description) values ("Mozbot", "Webtools", "terry@mozilla.org", "", 'IRC robot that watches tinderbox and other things'); +insert into components (value, program, initialowner, initialqacontact, description) values ("Tinderbox", "Webtools", "terry@mozilla.org", "", 'Tree-watching system to monitor <a href="http://www.mozilla.org/tinderbox.html">continuous builds</a> that we run on multiple platforms.'); select * from components; diff --git a/makeproducttable.sh b/makeproducttable.sh new file mode 100755 index 0000000000000000000000000000000000000000..e9d8fc2445b85a57db9d6afb74ab1421ecde63dc --- /dev/null +++ b/makeproducttable.sh @@ -0,0 +1,44 @@ +#!/bin/sh +# +# The contents of this file are subject to the Mozilla Public License +# Version 1.0 (the "License"); you may not use this file except in +# compliance with the License. You may obtain a copy of the License at +# http://www.mozilla.org/MPL/ +# +# Software distributed under the License is distributed on an "AS IS" +# basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See the +# License for the specific language governing rights and limitations +# under the License. +# +# The Original Code is the Bugzilla Bug Tracking System. +# +# The Initial Developer of the Original Code is Netscape Communications +# Corporation. Portions created by Netscape are Copyright (C) 1998 +# Netscape Communications Corporation. All Rights Reserved. +# +# Contributor(s): Terry Weissman <terry@mozilla.org> + +mysql > /dev/null 2>/dev/null << OK_ALL_DONE + +use bugs; + +drop table products; +OK_ALL_DONE + +mysql << OK_ALL_DONE +use bugs; +create table products ( +product tinytext, +description mediumtext, +milestoneurl tinytext not null +); + + +insert into products (product, description) values ("Calendar", 'For bugs about the <a href="http://www.mozilla.org/projects/calendar">Calendar</a> project'); +insert into products (product, description) values ("CCK", 'For bugs about the <a href="http://www.mozilla.org/projects/cck">Client Customization Kit<a> project'); +insert into products (product, description) values ("Directory", 'For bugs about the <a href="http://www.mozilla.org/directory">Directory (LDAP)</a> project'); +insert into products (product, description) values ("MailNews", 'For bugs about the <a href="http://www.mozilla.org/mailnews/index.html">Mozilla Mail/News</a> project'); +insert into products (product, description) values ("Mozilla", "For bugs about the Mozilla web browser"); +insert into products (product, description, milestoneurl) values ("NGLayout", 'For bugs about the <a href="http://www.mozilla.org/newlayout/">New Layout</a> project', 'http://www.mozilla.org/projects/seamonkey/milestones'); +insert into products (product, description) values ("Webtools", 'For bugs about the web-based tools that mozilla.org uses. This include Bugzilla (problems you are having with this bug system itself), <a href="http://www.mozilla.org/bonsai.html">Bonsai</a>, and <a href="http://www.mozilla.org/tinderbox.html">Tinderbox</a>.'); + diff --git a/makeversiontable.sh b/makeversiontable.sh index 2e86547791bbb6dcaa8ef2346d6aba99385d5aae..4dd6c565fd94610931ba94f928ba91792c450fef 100755 --- a/makeversiontable.sh +++ b/makeversiontable.sh @@ -34,6 +34,10 @@ program tinytext +insert into versions (value, program) values ("other", "Calendar"); +insert into versions (value, program) values ("other", "CCK"); +insert into versions (value, program) values ("other", "Directory"); +insert into versions (value, program) values ("other", "MailNews"); insert into versions (value, program) values ("other", "Mozilla"); insert into versions (value, program) values ("1998-03-31", "Mozilla"); insert into versions (value, program) values ("1998-04-08", "Mozilla"); @@ -41,9 +45,8 @@ insert into versions (value, program) values ("1998-04-29", "Mozilla"); insert into versions (value, program) values ("1998-06-03", "Mozilla"); insert into versions (value, program) values ("1998-07-28", "Mozilla"); insert into versions (value, program) values ("1998-09-04", "Mozilla"); -insert into versions (value, program) values ("1.0", "Bugzilla"); -insert into versions (value, program) values ("other", "Bugzilla"); insert into versions (value, program) values ("other", "NGLayout"); +insert into versions (value, program) values ("other", "Webtools"); select * from versions; diff --git a/notargetmilestone.html b/notargetmilestone.html new file mode 100644 index 0000000000000000000000000000000000000000..22bbdcf9c3b2437658b215a67e90d37488fe69c4 --- /dev/null +++ b/notargetmilestone.html @@ -0,0 +1,10 @@ +<html> <head> +<title>No target milestones.</title> +</head> + +<body> +<h1>No target milestones.</h1> + +No target milestones have been defined for this product. You can set +the Target Milestone field to things, but there is not currently any +agreed definition of what the milestones are. diff --git a/post_bug.cgi b/post_bug.cgi index 3ea3b070fd6ef50b0be248d28a88ae3934eb4a4c..1cff52326971f62a05270939c220ad594598b4e1 100755 --- a/post_bug.cgi +++ b/post_bug.cgi @@ -79,6 +79,22 @@ $::FORM{'reporter'} = DBNameToIdAndCheck($::FORM{'reporter'}); my @bug_fields = ("reporter", "product", "version", "rep_platform", "bug_severity", "priority", "op_sys", "assigned_to", "bug_status", "bug_file_loc", "short_desc", "component"); + +if (Param("useqacontact")) { + SendSQL("select initialqacontact from components where program=" . + SqlQuote($::FORM{'product'}) . + " and value=" . SqlQuote($::FORM{'component'})); + my $qacontact = FetchOneColumn(); + if (defined $qacontact && $qacontact ne "") { + $::FORM{'qa_contact'} = DBNameToIdAndCheck($qacontact, 1); + push(@bug_fields, "qa_contact"); + } +} + + + + + my $query = "insert into bugs (\n" . join(",\n", @bug_fields) . ", creation_ts, long_desc ) values ( diff --git a/process_bug.cgi b/process_bug.cgi index 6755ce91cf50c231dc660f33c60da0acb75b7d5e..f68b7e186a6369e46e4dfe5f467420d0dd91e40f 100755 --- a/process_bug.cgi +++ b/process_bug.cgi @@ -122,16 +122,29 @@ sub ChangeResolution { foreach my $field ("rep_platform", "priority", "bug_severity", "url", "summary", "component", "bug_file_loc", "short_desc", - "product", "version", "component") { + "product", "version", "component", "op_sys", + "target_milestone", "status_whiteboard") { if (defined $::FORM{$field}) { if ($::FORM{$field} ne $::dontchange) { DoComma(); - $::query .= "$field = " . SqlQuote($::FORM{$field}); + $::query .= "$field = " . SqlQuote(trim($::FORM{$field})); } } } +if (defined $::FORM{'qa_contact'}) { + my $name = trim($::FORM{'qa_contact'}); + if ($name ne $::dontchange) { + my $id = 0; + if ($name ne "") { + $id = DBNameToIdAndCheck($name); + } + DoComma(); + $::query .= "qa_contact = $id"; + } +} + ConnectToDatabase(); @@ -273,6 +286,12 @@ foreach my $id (@idlist) { foreach my $col (@::log_columns) { my $old = shift @oldvalues; my $new = shift @newvalues; + if (!defined $old) { + $old = ""; + } + if (!defined $new) { + $new = ""; + } if ($old ne $new) { if (!defined $whoid) { $whoid = DBNameToIdAndCheck($::FORM{'who'}); diff --git a/processmail b/processmail index ee6b92ad1430d76eedd69c68e434985c9e3a5e94..df1001fd9dbbbbe89e4c06458ebf14e97aa7012f 100755 --- a/processmail +++ b/processmail @@ -99,7 +99,7 @@ sub DescCC { if (scalar(@$cclist) <= 0) { return ""; } - return "Cc: " . join(", ", $cclist) . "\n"; + return "Cc: " . join(", ", @$cclist) . "\n"; } @@ -110,7 +110,8 @@ sub GetBugText { my @collist = ("bug_id", "product", "version", "rep_platform", "op_sys", "bug_status", "resolution", "priority", "bug_severity", "area", "assigned_to", "reporter", "bug_file_loc", - "short_desc", "component"); + "short_desc", "component", "qa_contact", "target_milestone", + "status_whiteboard"); my $query = "select " . join(", ", @collist) . " from bugs where bug_id = $id"; @@ -130,6 +131,21 @@ sub GetBugText { $::bug{'assigned_to'} = DBID_to_name($::bug{'assigned_to'}); $::bug{'reporter'} = DBID_to_name($::bug{'reporter'}); + my $qa_contact = ""; + my $target_milestone = ""; + my $status_whiteboard = ""; + if (Param('useqacontact') && $::bug{'qa_contact'} > 0) { + $::bug{'qa_contact'} = DBID_to_name($::bug{'qa_contact'}); + $qa_contact = "QAContact: $::bug{'qa_contact'}\n"; + } else { + $::bug{'qa_contact'} = ""; + } + if (Param('usetargetmilestone') && $::bug{'target_milestone'} ne "") { + $target_milestone = "TargetMilestone: $::bug{'target_milestone'}\n"; + } + if (Param('usestatuswhiteboard') && $::bug{'status_whiteboard'} ne "") { + $status_whiteboard = "StatusWhiteboard: $::bug{'status_whiteboard'}\n"; + } $::bug{'long_desc'} = GetLongDescription($id); @@ -151,7 +167,7 @@ Component: $::bug{'component'} Area: $::bug{'area'} AssignedTo: $::bug{'assigned_to'} ReportedBy: $::bug{'reporter'} -URL: $::bug{'bug_file_loc'} +$qa_contact$target_milestone${status_whiteboard}URL: $::bug{'bug_file_loc'} " . DescCC($::bug{'cclist'}) . "Summary: $::bug{'short_desc'} $::bug{'long_desc'} @@ -166,7 +182,7 @@ sub fixaddresses { my @result; my %seen; foreach my $i (@$list) { - if (!defined $::nomail{$i} && !defined $seen{$i}) { + if ($i ne "" && !defined $::nomail{$i} && !defined $seen{$i}) { push @result, $i; $seen{$i} = 1; } @@ -237,7 +253,8 @@ foreach my $i (@ARGV) { close FID; if (Different($old, $new)) { system("diff -c $old $new > $diffs"); - my $tolist = fixaddresses([$::bug{'assigned_to'}, $::bug{'reporter'}]); + my $tolist = fixaddresses([$::bug{'assigned_to'}, $::bug{'reporter'}, + $::bug{'qa_contact'}]); my $cclist = fixaddresses($::bug{'cclist'}); my $logstr = "Bug $i changed"; if ($tolist ne "" || $cclist ne "") { diff --git a/query.cgi b/query.cgi index a8efd1fed56b9b4d0301ef8ab54c756079e896f9..f782bd5c106176a89efb7c9ebc1f56895ef92135 100755 --- a/query.cgi +++ b/query.cgi @@ -19,8 +19,6 @@ # # Contributor(s): Terry Weissman <terry@mozilla.org> -# Contains some global routines used throughout the CGI scripts of Bugzilla. - use diagnostics; use strict; @@ -33,10 +31,12 @@ use vars @::legal_resolution, @::legal_bug_status, @::legal_priority, @::legal_resolution, + @::legal_opsys, @::legal_platform, @::legal_components, @::legal_versions, @::legal_severity, + @::legal_target_milestone, %::FORM; @@ -59,7 +59,11 @@ my %type; foreach my $name ("bug_status", "resolution", "assigned_to", "rep_platform", "priority", "bug_severity", "product", "reporter", "op_sys", - "component", "version") { + "component", "version", + "email1", "emailtype1", "emailreporter1", + "emailassigned_to1", "emailcc1", "emailqa_contact1", + "email2", "emailtype2", "emailreporter2", + "emailassigned_to2", "emailcc2", "emailqa_contact2") { $default{$name} = ""; $type{$name} = 0; } @@ -101,8 +105,82 @@ print "Set-Cookie: BUGLIST= Content-type: text/html\n\n"; GetVersionTable(); -my $who = GeneratePeopleInput("assigned_to", $default{"assigned_to"}); -my $reporter = GeneratePeopleInput("reporter", $default{"reporter"}); + +sub GenerateEmailInput { + my ($id) = (@_); + my $defstr = value_quote($default{"email$id"}); + my $deftype = $default{"emailtype$id"}; + if ($deftype eq "") { + $deftype = "substring"; + } + my $assignedto = ($default{"emailassigned_to$id"} eq "1") ? "checked" : ""; + my $reporter = ($default{"emailreporter$id"} eq "1") ? "checked" : ""; + my $cc = ($default{"emailcc$id"} eq "1") ? "checked" : ""; + + if ($assignedto eq "" && $reporter eq "" && $cc eq "") { + if ($id eq "1") { + $assignedto = "checked"; + } else { + $reporter = "checked"; + } + } + + my $qapart = ""; + if (Param("useqacontact")) { + my $qacontact = + ($default{"emailqa_contact$id"} eq "1") ? "checked" : ""; + $qapart = qq| +<tr> +<td></td> +<td> +<input type="checkbox" name="emailqa_contact$id" value=1 $qacontact>QA Contact +</td> +</tr> +|; + } + + return qq| +<table border=1 cellspacing=0 cellpadding=0> +<tr><td> +<table cellspacing=0 cellpadding=0> +<tr> +<td rowspan=2 valign=top><a href="helpemailquery.html">Email:</a> +<input name="email$id" size="30" value=""> matching as +<SELECT NAME=emailtype$id> +<OPTION VALUE="regexp">regexp +<OPTION VALUE="notregexp">not regexp +<OPTION SELECTED VALUE="substring">substring +<OPTION VALUE="exact">exact +</SELECT> +</td> +<td> +<input type="checkbox" name="emailassigned_to$id" value=1 $assignedto>Assigned To +</td> +</tr> +<tr> +<td> +<input type="checkbox" name="emailreporter$id" value=1 $reporter>Reporter +</td> +</tr>$qapart +<tr> +<td align=right>(Will match any of the selected fields)</td> +<td> +<input type="checkbox" name="emailcc$id" value=1 $cc>CC +</td> +</tr> +</table> +</table> +|; +} + + + + + +my $emailinput1 = GenerateEmailInput(1); +my $emailinput2 = GenerateEmailInput(2); + + # Muck the "legal product" list so that the default one is always first (and @@ -118,6 +196,7 @@ my $reporter = GeneratePeopleInput("reporter", $default{"reporter"}); PutHeader("Bugzilla Query Page", "Query Page"); push @::legal_resolution, "---"; # Oy, what a hack. +push @::legal_target_milestone, "---"; # Oy, what a hack. print " <FORM NAME=queryForm METHOD=GET ACTION=\"buglist.cgi\"> @@ -127,6 +206,7 @@ print " <th align=left><A HREF=\"bug_status.html\">Status</a>:</th> <th align=left><A HREF=\"bug_status.html\">Resolution</a>:</th> <th align=left><A HREF=\"bug_status.html#rep_platform\">Platform</a>:</th> +<th align=left><A HREF=\"bug_status.html#op_sys\">OpSys</a>:</th> <th align=left><A HREF=\"bug_status.html#priority\">Priority</a>:</th> <th align=left><A HREF=\"bug_status.html#severity\">Severity</a>:</th> </tr> @@ -147,6 +227,11 @@ print " </SELECT> </td> <td align=left valign=top> +<SELECT NAME=\"op_sys\" MULTIPLE SIZE=7> +@{[make_options(\@::legal_opsys, $default{'op_sys'}, $type{'op_sys'})]} +</SELECT> +</td> +<td align=left valign=top> <SELECT NAME=\"priority\" MULTIPLE SIZE=7> @{[make_options(\@::legal_priority, $default{'priority'}, $type{'priority'})]} </SELECT> @@ -159,12 +244,12 @@ print " </table> <p> -<TABLE> -<TR><TD ALIGN=RIGHT><B><A HREF=\"bug_status.html#assigned_to\">Assigned To:</a></B><TD>$who +$emailinput1<p> +$emailinput2<p> + + + -<p> -<TR><TD ALIGN=RIGHT><B>Reporter:</B><TD>$reporter -</TABLE> <NOBR>Changed in the last <INPUT NAME=changedin SIZE=2> days.</NOBR> @@ -172,9 +257,16 @@ print " <table> <tr> -<TH ALIGN=LEFT>Program:</th> -<TH ALIGN=LEFT>Version:</th> -<TH ALIGN=LEFT>Component:</th> +<TH ALIGN=LEFT VALIGN=BOTTOM>Program:</th> +<TH ALIGN=LEFT VALIGN=BOTTOM>Version:</th> +<TH ALIGN=LEFT VALIGN=BOTTOM><A HREF=describecomponents.cgi>Component:<a></th> +"; + +if (Param("usetargetmilestone")) { + print "<TH ALIGN=LEFT VALIGN=BOTTOM>Target Milestone:</th>"; +} + +print " </tr> <tr> @@ -194,8 +286,18 @@ print " <SELECT NAME=\"component\" MULTIPLE SIZE=5> @{[make_options(\@::legal_components, $default{'component'}, $type{'component'})]} </SELECT> -</td> +</td>"; +if (Param("usetargetmilestone")) { + print " +<td align=left valign=top> +<SELECT NAME=\"target_milestone\" MULTIPLE SIZE=5> +@{[make_options(\@::legal_target_milestone, $default{'component'}, $type{'component'})]} +</SELECT> +</td>"; +} + +print " </tr> </table> @@ -212,6 +314,24 @@ print " <td><input type=radio name=long_desc_type value=substr checked>Substring</td> <td><input type=radio name=long_desc_type value=regexp>Regexp</td> </tr> +<tr> +<td align=right>URL:</td> +<td><input name=bug_file_loc size=30></td> +<td><input type=radio name=bug_file_loc_type value=substr checked>Substring</td> +<td><input type=radio name=bug_file_loc_type value=regexp>Regexp</td> +</tr>"; + +if (Param("usestatuswhiteboard")) { + print " +<tr> +<td align=right>Status whiteboard:</td> +<td><input name=status_whiteboard size=30></td> +<td><input type=radio name=status_whiteboard_type value=substr checked>Substring</td> +<td><input type=radio name=status_whiteboard_type value=regexp>Regexp</td> +</tr>"; +} + +print " </table> <p> @@ -247,7 +367,7 @@ print " <OPTION SELECTED>\"Importance\" <OPTION>Assignee </SELECT></NOBR> -<INPUT TYPE=\"submit\" VALUE=\"Submit\"> +<INPUT TYPE=\"submit\" VALUE=\"Submit query\"> <INPUT TYPE=\"reset\" VALUE=\"Reset back to the default query\"> <INPUT TYPE=hidden name=form_name VALUE=query> <BR>Give me a <A HREF=\"help.html\">clue</A> about how to use this form. @@ -260,11 +380,13 @@ print " if (defined $::COOKIE{"Bugzilla_login"}) { if ($::COOKIE{"Bugzilla_login"} eq Param("maintainer")) { print "<a href=editparams.cgi>Edit Bugzilla operating parameters</a><br>\n"; + print "<a href=editowners.cgi>Edit Bugzilla component owners</a><br>\n"; } print "<a href=relogin.cgi>Log in as someone besides <b>$::COOKIE{'Bugzilla_login'}</b></a><br>\n"; } print "<a href=changepassword.cgi>Change your password.</a><br>\n"; print "<a href=\"enter_bug.cgi\">Create a new bug.</a><br>\n"; +print "<a href=\"reports.cgi\">Bug reports</a><br>\n"; diff --git a/reports.cgi b/reports.cgi new file mode 100755 index 0000000000000000000000000000000000000000..f78fd643fcea5d9316e29fc0e099a9cd928cd832 --- /dev/null +++ b/reports.cgi @@ -0,0 +1,509 @@ +#!/usr/bonsaitools/bin/perl -w +# -*- Mode: perl; indent-tabs-mode: nil -*- +# +# The contents of this file are subject to the Mozilla Public License +# Version 1.0 (the "License"); you may not use this file except in +# compliance with the License. You may obtain a copy of the License at +# http://www.mozilla.org/MPL/ +# +# Software distributed under the License is distributed on an "AS IS" +# basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See the +# License for the specific language governing rights and limitations +# under the License. +# +# The Original Code is the Bugzilla Bug Tracking System. +# +# The Initial Developer of the Original Code is Netscape Communications +# Corporation. Portions created by Netscape are Copyright (C) 1998 +# Netscape Communications Corporation. All Rights Reserved. +# +# Contributor(s): Harrison Page <harrison@netscape.com>, +# Terry Weissman <terry@mozilla.org> + +use diagnostics; +use strict; +use Chart::Lines; + +require "CGI.pl"; +require "globals.pl"; + +use vars @::legal_product; + +my $dir = "data/mining"; +my $week = 60 * 60 * 24 * 7; +my @status = qw (NEW ASSIGNED REOPENED); + +# while this looks odd/redundant, it allows us to name +# functions differently than the value passed in + +my %reports = + ( + "most_doomed" => \&most_doomed, + "show_chart" => \&show_chart, + ); + +# patch from Sam Ziegler <sam@ziegler.org>: +# +# "reports.cgi currently has it's own idea of what +# the header should be. This patch sets it to the +# system wide header." + +print "Content-type: text/html\n\n"; + +if (defined $::FORM{'nobanner'}) + { +print <<FIN; +<html> +<head><title>Bug Reports</title></head> +<body bgcolor="#FFFFFF"> +FIN + } +else + { + PutHeader ("Bug Reports") unless (defined $::FORM{'nobanner'}); + } + +ConnectToDatabase(); +GetVersionTable(); + +$::FORM{'output'} = $::FORM{'output'} || "most_doomed"; # a reasonable default + +if (! defined $::FORM{'product'}) + { + &choose_product; + } +else + { + # we want to be careful about what subroutines + # can be called from outside. modify %reports + # accordingly when a new report type is added + + if (! exists $reports{$::FORM{'output'}}) + { + $::FORM{'output'} = "most_doomed"; # a reasonable default + } + + my $f = $reports{$::FORM{'output'}}; + + if (! defined $f) + { + print "start over, your form data was all messed up.<p>\n"; + foreach (keys %::FORM) + { + print "<font color=blue>$_</font> : " . + ($::FORM{$_} ? $::FORM{$_} : "undef") . "<br>\n"; + } + exit; + } + + &{$f}; + } + +print <<FIN; +<p> +</body> +</html> +FIN + +################################## +# user came in with no form data # +################################## + +sub choose_product + { + my $product_popup = make_options (\@::legal_product, $::legal_product[0]); + my $charts = (-d $dir) ? "<option value=\"show_chart\">Bug Charts" : ""; + + print <<FIN; +<center> +<h1>Welcome to the Bugzilla Query Kitchen</h1> +<form method=get action=reports.cgi> +<table border=1 cellpadding=5> +<tr> +<td align=center><b>Product:</b></td> +<td align=center> +<select name="product"> +$product_popup +</select> +</td> +</tr> +<tr> +<td align=center><b>Output:</b></td> +<td align=center> +<select name="output"> +<option value="most_doomed">Bug Counts +$charts +</select> +<tr> +<td align=center><b>Switches:</b></td> +<td align=left> +<input type=checkbox name=links value=1> Links to Bugs<br> +<input type=checkbox name=nobanner value=1> No Banner<br> +<input type=checkbox name=quip value=1> Include Quip<br> +</td> +</tr> +<tr> +<td colspan=2 align=center> +<input type=submit value=Continue> +</td> +</tr> +</table> +</form> +<p> +FIN + } + +sub most_doomed + { + my $when = localtime (time); + + print <<FIN; +<center> +<h1> +Bug Report for $::FORM{'product'} +</h1> +$when<p> +FIN + + my $query = <<FIN; +select + bugs.bug_id, bugs.assigned_to, bugs.bug_severity, + bugs.bug_status, bugs.product, + assign.login_name, + report.login_name, + unix_timestamp(date_format(bugs.creation_ts, '%Y-%m-%d %h:%m:%s')) + +from bugs, + profiles assign, + profiles report, + versions projector +where bugs.assigned_to = assign.userid +and bugs.reporter = report.userid +and bugs.product='$::FORM{'product'}' +and + ( + bugs.bug_status = 'NEW' or + bugs.bug_status = 'ASSIGNED' or + bugs.bug_status = 'REOPENED' + ) +FIN + + print "<font color=purple><tt>$query</tt></font><p>\n" + unless (! exists $::FORM{'showsql'}); + + SendSQL ($query); + + my $c = 0; + + my $quip = "Summary"; + my $bugs_count = 0; + my $bugs_new_this_week = 0; + my $bugs_reopened = 0; + my %bugs_owners; + my %bugs_summary; + my %bugs_status; + my %bugs_totals; + my %bugs_lookup; + + ############################# + # suck contents of database # + ############################# + + while (my ($bid, $a, $sev, $st, $prod, $who, $rep, $ts) = FetchSQLData()) + { + next if (exists $bugs_lookup{$bid}); + + $bugs_lookup{$bid} ++; + $bugs_owners{$who} ++; + $bugs_new_this_week ++ if (time - $ts <= $week); + $bugs_status{$st} ++; + $bugs_count ++; + + push @{$bugs_summary{$who}{$st}}, $bid; + + $bugs_totals{$who}{$st} ++; + } + + if ($::FORM{'quip'}) + { + if (open (COMMENTS, "<data/comments")) + { + my @cdata; + while (<COMMENTS>) + { + push @cdata, $_; + } + close COMMENTS; + $quip = "<i>" . $cdata[int(rand($#cdata + 1))] . "</i>"; + } + } + + ######################### + # start painting report # + ######################### + + print <<FIN; +<h1>$quip</h1> +<table border=1 cellpadding=5> +<tr> +<td align=right><b>New Bugs This Week</b></td> +<td align=center>$bugs_new_this_week</td> +</tr> + +<tr> +<td align=right><b>Bugs Marked New</b></td> +<td align=center>$bugs_status{'NEW'}</td> +</tr> + +<tr> +<td align=right><b>Bugs Marked Assigned</b></td> +<td align=center>$bugs_status{'ASSIGNED'}</td> +</tr> + +<tr> +<td align=right><b>Bugs Marked Reopened</b></td> +<td align=center>$bugs_status{'REOPENED'}</td> +</tr> + +<tr> +<td align=right><b>Total Bugs</b></td> +<td align=center>$bugs_count</td> +</tr> + +</table> +<p> +FIN + + if ($bugs_count == 0) + { + print "No bugs found!\n"; + exit; + } + + print <<FIN; +<h1>Bug Count by Engineer</h1> +<table border=3 cellpadding=5> +<tr> +<td align=center bgcolor="#DDDDDD"><b>Owner</b></td> +<td align=center bgcolor="#DDDDDD"><b>New</b></td> +<td align=center bgcolor="#DDDDDD"><b>Assigned</b></td> +<td align=center bgcolor="#DDDDDD"><b>Reopened</b></td> +<td align=center bgcolor="#DDDDDD"><b>Total</b></td> +</tr> +FIN + + foreach my $who (sort keys %bugs_summary) + { + my $bugz = 0; + print <<FIN; +<tr> +<td align=left><tt>$who</tt></td> +FIN + + foreach my $st (@status) + { + $bugs_totals{$who}{$st} += 0; + print <<FIN; +<td align=center>$bugs_totals{$who}{$st} +FIN + $bugz += $#{$bugs_summary{$who}{$st}} + 1; + } + + print <<FIN; +<td align=center>$bugz</td> +</tr> +FIN + } + + print <<FIN; +</table> +<p> +FIN + + ############################### + # individual bugs by engineer # + ############################### + + print <<FIN; +<h1>Individual Bugs by Engineer</h1> +<table border=1 cellpadding=5> +<tr> +<td align=center bgcolor="#DDDDDD"><b>Owner</b></td> +<td align=center bgcolor="#DDDDDD"><b>New</b></td> +<td align=center bgcolor="#DDDDDD"><b>Assigned</b></td> +<td align=center bgcolor="#DDDDDD"><b>Reopened</b></td> +</tr> +FIN + + foreach my $who (sort keys %bugs_summary) + { + print <<FIN; +<tr> +<td align=left><tt>$who</tt></td> +FIN + + foreach my $st (@status) + { + my @l; + + foreach (sort { $a <=> $b } @{$bugs_summary{$who}{$st}}) + { + if ($::FORM{'links'}) + { + push @l, "<a href=\"show_bug.cgi?id=$_\">$_</a>\n"; + } + else + { + push @l, $_; + } + } + + my $bugz = join ' ', @l; + $bugz = " " unless ($bugz); + + print <<FIN +<td align=left>$bugz</td> +FIN + } + + print <<FIN; +</tr> +FIN + } + + print <<FIN; +</table> +<p> +FIN + } + +sub is_legal_product + { + my $product = shift; + return grep { $_ eq $product} @::legal_product; + } + +sub header + { + print <<FIN; +<TABLE BGCOLOR="#000000" WIDTH="100%" BORDER=0 CELLPADDING=0 CELLSPACING=0> +<TR><TD><A HREF="http://www.mozilla.org/"><IMG + SRC="http://www.mozilla.org/images/mozilla-banner.gif" ALT="" + BORDER=0 WIDTH=600 HEIGHT=58></A></TD></TR></TABLE> +FIN + } + +sub show_chart + { + my $when = localtime (time); + + if (! is_legal_product ($::FORM{'product'})) + { + &die_politely ("Unknown product: $::FORM{'product'}"); + } + + print <<FIN; +<center> +FIN + + my @dates; + my @open; my @assigned; my @reopened; + + my $prodname = $::FORM{'product'}; + + $prodname =~ s/\//-/gs; + + my $file = join '/', $dir, $prodname; + my $image = "$file.gif"; + + if (! open FILE, $file) + { + &die_politely ("The tool which gathers bug counts has not been run yet."); + } + + while (<FILE>) + { + chomp; + next if ($_ =~ /^#/ or ! $_); + my ($date, $open, $assigned, $reopened) = split /\|/, $_; + my ($yy, $mm, $dd) = $date =~ /^\d{2}(\d{2})(\d{2})(\d{2})$/; + + push @dates, "$mm/$dd/$yy"; + push @open, $open; + push @assigned, $assigned; + push @reopened, $reopened; + } + + close FILE; + + if ($#dates < 1) + { + &die_politely ("We don't have enough data points to make a graph (yet)"); + } + + my $img = Chart::Lines->new (800, 600); + my @labels = qw (New Assigned Reopened); + my @when; + my $i = 0; + my @data; + + push @data, \@dates; + push @data, \@open; + push @data, \@assigned; + push @data, \@reopened; + + my $MAXTICKS = 20; # Try not to show any more x ticks than this. + my $skip = 1; + if (@dates > $MAXTICKS) { + $skip = int((@dates + $MAXTICKS - 1) / $MAXTICKS); + } + + my %settings = + ( + "title" => "Bug Charts for $::FORM{'product'}", + "x_label" => "Dates", + "y_label" => "Bug Count", + "legend_labels" => \@labels, + "skip_x_ticks" => $skip, + ); + + $img->set (%settings); + + open IMAGE, ">$image" or die "$image: $!"; + $img->gif (*IMAGE, \@data); + close IMAGE; + + print <<FIN; +<img src="$image"> +<br clear=left> +<br> +FIN + } + +sub die_politely + { + my $msg = shift; + + print <<FIN; +<p> +<table border=1 cellpadding=10> +<tr> +<td align=center> +<font color=blue>Sorry, but ...</font> +<p> +There is no graph available for <b>$::FORM{'product'}</b><p> + +<font size=-1> +$msg +<p> +</font> +</td> +</tr> +</table> +<p> +FIN + + exit; + } + + diff --git a/show_bug.cgi b/show_bug.cgi index 98829e356c741d7725e17eba7a64737250321336..75a3bb8e34ae2b95eedcd5289b6e7bdff32dd8d7 100755 --- a/show_bug.cgi +++ b/show_bug.cgi @@ -46,4 +46,5 @@ navigation_header(); print "<HR>\n"; -do "bug_form.pl"; +$! = 0; +do "bug_form.pl" || die "Error doing bug_form.pl: $!";