]> git.donarmstrong.com Git - debbugs.git/blobdiff - Debbugs/Bugs.pm
merge changes from dla source tree
[debbugs.git] / Debbugs / Bugs.pm
index 5a4156e7bf6dcc9baedea185b687c4f8e2598649..bb793134b87dff9dd00f109a021689fce5d7f010 100644 (file)
@@ -1,3 +1,9 @@
+# This module is part of debbugs, and is released
+# under the terms of the GPL version 2, or any later
+# version at your option.
+# See the file README and COPYING for more information.
+#
+# Copyright 2007 by Don Armstrong <don@donarmstrong.com>.
 
 package Debbugs::Bugs;
 
@@ -40,7 +46,7 @@ BEGIN{
 
      @EXPORT = ();
      %EXPORT_TAGS = ();
-     @EXPORT_OK = (qw(get_bugs));
+     @EXPORT_OK = (qw(get_bugs count_bugs newest_bug));
      $EXPORT_TAGS{all} = [@EXPORT_OK];
 }
 
@@ -49,7 +55,7 @@ use Params::Validate qw(validate_with :types);
 use IO::File;
 use Debbugs::Status qw(splitpackages);
 use Debbugs::Packages qw(getsrcpkgs);
-use Debbugs::Common qw(getparsedaddrs getmaintainers getmaintainers_reverse);
+use Debbugs::Common qw(getparsedaddrs getmaintainers getmaintainers_reverse make_list);
 use Fcntl qw(O_RDONLY);
 use MLDBM qw(DB_File Storable);
 
@@ -98,7 +104,8 @@ searches are performed.
 =over
 
 =item archive -- whether to search archived bugs or normal bugs;
-defaults to false.
+defaults to false. As a special case, if archive is 'both', but
+archived and unarchived bugs are returned.
 
 =item usertags -- set of usertags and the bugs they are applied to
 
@@ -174,7 +181,7 @@ sub get_bugs{
                                          bugs      => {type => SCALAR|ARRAYREF,
                                                        optional => 1,
                                                       },
-                                         archive   => {type => BOOLEAN,
+                                         archive   => {type => BOOLEAN|SCALAR,
                                                        default => 0,
                                                       },
                                          usertags  => {type => HASHREF,
@@ -186,6 +193,13 @@ sub get_bugs{
      # Normalize options
      my %options = %param;
      my @bugs;
+     if ($options{archive} eq 'both') {
+         push @bugs, get_bugs(%options,archive=>0);
+         push @bugs, get_bugs(%options,archive=>1);
+         my %bugs;
+         @bugs{@bugs} = @bugs;
+         return keys %bugs;
+     }
      # A configuration option will set an array that we'll use here instead.
      for my $routine (qw(Debbugs::Bugs::get_bugs_by_idx Debbugs::Bugs::get_bugs_flatfile)) {
          my ($package) = $routine =~ m/^(.+)\:\:/;
@@ -214,6 +228,70 @@ sub get_bugs{
      return @bugs;
 }
 
+=head2 count_bugs
+
+     count_bugs(function => sub {...})
+
+Uses a subroutine to classify bugs into categories and return the
+number of bugs which fall into those categories
+
+=cut
+
+sub count_bugs {
+     my %param = validate_with(params => \@_,
+                              spec   => {function => {type => CODEREF,
+                                                     },
+                                         archive  => {type => BOOLEAN,
+                                                      default => 0,
+                                                     },
+                                        },
+                             );
+     my $flatfile;
+     if ($param{archive}) {
+         $flatfile = IO::File->new("$config{spool_dir}/index.archive", 'r')
+              or die "Unable to open $config{spool_dir}/index.archive for reading: $!";
+     }
+     else {
+         $flatfile = IO::File->new("$config{spool_dir}/index.db", 'r')
+              or die "Unable to open $config{spool_dir}/index.db for reading: $!";
+     }
+     my %count = ();
+     while(<$flatfile>) {
+         if (m/^(\S+)\s+(\d+)\s+(\d+)\s+(\S+)\s+\[\s*([^]]*)\s*\]\s+(\w+)\s+(.*)$/) {
+              my @x = $param{function}->(pkg       => $1,
+                                         bug       => $2,
+                                         status    => $4,
+                                         submitter => $5,
+                                         severity  => $6,
+                                         tags      => $7,
+                                        );
+              local $_;
+              $count{$_}++ foreach @x;
+         }
+     }
+     close $flatfile;
+     return %count;
+}
+
+=head2 newest_bug
+
+     my $bug = newest_bug();
+
+Returns the bug number of the newest bug, which is nextnumber-1.
+
+=cut
+
+sub newest_bug {
+     my $nn_fh = IO::File->new("$config{spool_dir}/nextnumber",'r')
+         or die "Unable to open $config{spool_dir}nextnumber for reading: $!";
+     local $/;
+     my $next_number = <$nn_fh>;
+     close $nn_fh;
+     chomp $next_number;
+     return $next_number+0;
+}
+
+
 =head2 get_bugs_by_idx
 
 This routine uses the by-$index.idx indicies to try to speed up
@@ -274,7 +352,7 @@ sub get_bugs_by_idx{
          $index = "$config{spool_dir}/by-${index}${arc}.idx";
          tie(%idx, MLDBM => $index, O_RDONLY)
               or die "Unable to open $index: $!";
-         for my $search (__make_list($param{$key})) {
+         for my $search (make_list($param{$key})) {
               next unless defined $idx{$search};
               for my $bug (keys %{$idx{$search}}) {
                    # increment the number of searches that this bug matched
@@ -351,8 +429,8 @@ sub get_bugs_flatfile{
          # This complex slice makes a hash with the bugs which have the
           # usertags passed in $param{tag} set.
          @usertag_bugs{map {@{$_}}
-                            @{$param{usertags}}{__make_list($param{tag})}
-                       } = (1) x @{$param{usertags}}{__make_list($param{tag})}
+                            @{$param{usertags}}{make_list($param{tag})}
+                       } = (1) x @{$param{usertags}}{make_list($param{tag})}
      }
      # We handle src packages, maint and maintenc by mapping to the
      # appropriate binary packages, then removing all packages which
@@ -370,15 +448,15 @@ sub get_bugs_flatfile{
      while (<$flatfile>) {
          next unless m/^(\S+)\s+(\d+)\s+(\d+)\s+(\S+)\s+\[\s*([^]]*)\s*\]\s+(\w+)\s+(.*)$/;
          my ($pkg,$bug,$time,$status,$submitter,$severity,$tags) = ($1,$2,$3,$4,$5,$6,$7);
-         next if exists $param{bugs} and not grep {$bug == $_} __make_list($param{bugs});
+         next if exists $param{bugs} and not grep {$bug == $_} make_list($param{bugs});
          if (exists $param{package}) {
               my @packages = splitpackages($pkg);
               next unless grep { my $pkg_list = $_;
-                                 grep {$pkg_list eq $_} __make_list($param{package})
+                                 grep {$pkg_list eq $_} make_list($param{package})
                             } @packages;
          }
          if (exists $param{src}) {
-              my @src_packages = map { getsrcpkgs($_)} __make_list($param{src});
+              my @src_packages = map { getsrcpkgs($_)} make_list($param{src});
               my @packages = splitpackages($pkg);
               next unless grep { my $pkg_list = $_;
                                  grep {$pkg_list eq $_} @packages
@@ -387,22 +465,22 @@ sub get_bugs_flatfile{
          if (exists $param{submitter}) {
               my @p_addrs = map {lc($_->address)}
                    map {getparsedaddrs($_)}
-                        __make_list($param{submitter});
+                        make_list($param{submitter});
               my @f_addrs = map {$_->address}
                    getparsedaddrs($submitter||'');
               next unless grep { my $f_addr = $_; 
                                  grep {$f_addr eq $_} @p_addrs
                             } @f_addrs;
          }
-         next if exists $param{severity} and not grep {$severity eq $_} __make_list($param{severity});
-         next if exists $param{status} and not grep {$status eq $_} __make_list($param{status});
+         next if exists $param{severity} and not grep {$severity eq $_} make_list($param{severity});
+         next if exists $param{status} and not grep {$status eq $_} make_list($param{status});
          if (exists $param{tag}) {
               my $bug_ok = 0;
               # either a normal tag, or a usertag must be set
               $bug_ok = 1 if exists $param{usertags} and $usertag_bugs{$bug};
               my @bug_tags = split ' ', $tags;
               $bug_ok = 1 if grep {my $bug_tag = $_;
-                                   grep {$bug_tag eq $_} __make_list($param{tag});
+                                   grep {$bug_tag eq $_} make_list($param{tag});
                               } @bug_tags;
               next unless $bug_ok;
          }
@@ -440,7 +518,8 @@ sub __handle_pkg_src_and_maint{
                               allow_extra => 1,
                              );
 
-     my @packages = __make_list($param{package});
+     my @packages;
+     @packages = make_list($param{package}) if exists $param{package};
      my $package_keys = @packages?1:0;
      my %packages;
      @packages{@packages} = (1) x @packages;
@@ -448,7 +527,7 @@ sub __handle_pkg_src_and_maint{
          # We only want to increment the number of keys if there is
          # something to match
          my $key_inc = 0;
-         for my $package ((map { getsrcpkgs($_)} __make_list($param{src})),__make_list($param{src})) {
+         for my $package ((map { getsrcpkgs($_)} make_list($param{src})),make_list($param{src})) {
               $packages{$package}++;
               $key_inc=1;
          }
@@ -458,7 +537,7 @@ sub __handle_pkg_src_and_maint{
          my $key_inc = 0;
          my $maint_rev = getmaintainers_reverse();
          for my $package (map { exists $maint_rev->{$_}?@{$maint_rev->{$_}}:()}
-                          __make_list($param{maint})) {
+                          make_list($param{maint})) {
               $packages{$package}++;
               $key_inc = 1;
          }
@@ -468,13 +547,6 @@ sub __handle_pkg_src_and_maint{
 }
 
 
-# This private subroutine takes a scalar and turns it into a list;
-# transforming arrayrefs into their contents along the way. It also
-# turns undef into the empty list.
-sub __make_list{
-     return map {defined $_?(ref($_) eq 'ARRAY'?@{$_}:$_):()} @_;
-}
-
 1;
 
 __END__