#!/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.1 (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 , # Harrison Page # Gervase Markham # Run me out of cron at midnight to collect Bugzilla statistics. use AnyDBM_File; use strict; use vars @::legal_product; require "globals.pl"; # tidy up after graphing module if (chdir("graphs")) { unlink <./*.gif>; unlink <./*.png>; chdir(".."); } ConnectToDatabase(1); GetVersionTable(); my @myproducts; push( @myproducts, "-All-", @::legal_product ); foreach (@myproducts) { my $dir = "data/mining"; &check_data_dir ($dir); &collect_stats ($dir, $_); } &calculate_dupes(); 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 $product_id = get_product_id($product) unless $product eq '-All-'; die "Unknown product $product" unless ($product_id or $product eq '-All-'); # NB: Need to mangle the product for the filename, but use the real # product name in the query my $file_product = $product; $file_product =~ s/\//-/gs; my $file = join '/', $dir, $file_product; my $exists = -f $file; if (open DATA, ">>$file") { push my @row, &today; foreach my $status ('NEW', 'ASSIGNED', 'REOPENED', 'UNCONFIRMED', 'RESOLVED', 'VERIFIED', 'CLOSED') { if( $product eq "-All-" ) { SendSQL("select count(bug_status) from bugs where bug_status='$status'"); } else { SendSQL("select count(bug_status) from bugs where bug_status='$status' and product_id=$product_id"); } push @row, FetchOneColumn(); } foreach my $resolution ('FIXED', 'INVALID', 'WONTFIX', 'LATER', 'REMIND', 'DUPLICATE', 'WORKSFORME', 'MOVED') { if( $product eq "-All-" ) { SendSQL("select count(resolution) from bugs where resolution='$resolution'"); } else { SendSQL("select count(resolution) from bugs where resolution='$resolution' and product_id=$product_id"); } push @row, FetchOneColumn(); } if (! $exists) { print DATA <) { unlink @files; } dbmopen(%count, "data/duplicates/dupes$today", 0644) || die "Can't open DBM dupes file: $!"; # Create a hash with key "a bug number", value "bug which that bug is a # direct dupe of" - straight from the duplicates table. while (@row = FetchSQLData()) { my $dupe_of = shift @row; my $dupe = shift @row; $dupes{$dupe} = $dupe_of; } # Total up the number of bugs which are dupes of a given bug # count will then have key = "bug number", # value = "number of immediate dupes of that bug". foreach $key (keys(%dupes)) { my $dupe_of = $dupes{$key}; if (!defined($count{$dupe_of})) { $count{$dupe_of} = 0; } $count{$dupe_of}++; } # Now we collapse the dupe tree by iterating over %count until # there is no further change. while ($changed == 1) { $changed = 0; foreach $key (keys(%count)) { # if this bug is actually itself a dupe, and has a count... if (defined($dupes{$key}) && $count{$key} > 0) { # add that count onto the bug it is a dupe of, # and zero the count; the check is to avoid # loops if ($count{$dupes{$key}} != 0) { $count{$dupes{$key}} += $count{$key}; $count{$key} = 0; $changed = 1; } } } } # Remove the values for which the count is zero foreach $key (keys(%count)) { if ($count{$key} == 0) { delete $count{$key}; } } dbmclose(%count); } sub today { my ($dom, $mon, $year) = (localtime(time))[3, 4, 5]; return sprintf "%04d%02d%02d", 1900 + $year, ++$mon, $dom; } sub today_dash { my ($dom, $mon, $year) = (localtime(time))[3, 4, 5]; return sprintf "%04d-%02d-%02d", 1900 + $year, ++$mon, $dom; }