]> git.donarmstrong.com Git - debbugs.git/commitdiff
[project @ 2003-08-18 01:16:14 by cjwatson]
authorcjwatson <>
Mon, 18 Aug 2003 08:16:14 +0000 (00:16 -0800)
committercjwatson <>
Mon, 18 Aug 2003 08:16:14 +0000 (00:16 -0800)
Phase 1 of version tracking: CGI scripts only.

pkgreport.cgi now takes 'version', 'dist', and 'arch' arguments. If
'version' is supplied, then bugs open against that version are displayed.
Otherwise, if 'dist' is supplied, then it's expected to be a distribution,
such as stable, testing, or unstable, and bugs open against the versions of
packages in that distribution are displayed. It defaults to unstable at the
moment. 'arch' is largely for completeness because it was easy, and narrows
this down to the version of a package on that particular architecture. It
defaults to i386.

For now, bugs that apparently don't apply to the given version at all
(because they were found in a later version or in a version on a different
branch) are displayed in a separate group of sections at the bottom, "not
applicable to this version".

This is a bit of a hack at the moment in various ways, mostly because the
version data isn't yet stored in the .status files. The new $gVersion*
configuration variables are subject to completely arbitrary change. Until
all of this settles down, the output should look unchanged unless you
supply a 'version' or 'dist' argument.

cgi/bugreport.cgi
cgi/common.pl
cgi/pkgreport.cgi
debian/control

index fe19e0a04d1956dbc65924c59ce5e5aac6405f73..dad91a0c7ebbcf94a12051c0991ebc1df7fe750e 100755 (executable)
@@ -198,7 +198,22 @@ if (@merged) {
        push @descstates, $descmerged;
 }
 
-if (length($status{done})) {
+if (@{$status{found_versions}}) {
+    my $foundtext = 'Found in ';
+    $foundtext .= (@{$status{found_versions}} == 1) ? 'version ' : 'versions ';
+    $foundtext .= join ', ', map htmlsanit($_), @{$status{found_versions}};
+    push @descstates, $foundtext;
+}
+
+if (@{$status{fixed_versions}}) {
+    my $fixedtext = '<strong>Fixed</strong> in ';
+    $fixedtext .= (@{$status{fixed_versions}} == 1) ? 'version ' : 'versions ';
+    $fixedtext .= join ', ', map htmlsanit($_), @{$status{fixed_versions}};
+    if (length($status{done})) {
+       $fixedtext .= ' by ' . htmlsanit($status{done});
+    }
+    push @descstates, $fixedtext;
+} elsif (length($status{done})) {
        push @descstates, "<strong>Done:</strong> ".htmlsanit($status{done});
 } elsif (length($status{forwarded})) {
        push @descstates, "<strong>Forwarded</strong> to ".maybelink($status{forwarded});
index 5886cf2c4069b2ec65ec9e42715232ed1ac062c5..0e100b6575ed21a28d335b42bc458c0afb5a69c4 100644 (file)
@@ -3,10 +3,16 @@
 use DB_File;
 use Fcntl qw/O_RDONLY/;
 use Mail::Address;
+use MLDBM qw/DB_File/;
+
 $config_path = '/etc/debbugs';
 $lib_path = '/usr/lib/debbugs';
 require "$lib_path/errorlib";
 
+use Debbugs::Versions;
+
+$MLDBM::RemoveTaint = 1;
+
 my $common_archive = 0;
 my $common_repeatmerged = 1;
 my %common_include = ();
@@ -21,6 +27,10 @@ my @common_pending_exclude = ();
 my @common_severity_include = ();
 my @common_severity_exclude = ();
 
+my $common_version;
+my $common_dist;
+my $common_arch;
+
 my $debug = 0;
 
 sub set_option {
@@ -77,6 +87,9 @@ sub set_option {
        @vals = @{$val} if (ref($val) eq "ARRAY" );
        @common_severity_include = @vals if (@vals);
     }
+    if ($opt eq "version") { $common_version = $val; }
+    if ($opt eq "dist") { $common_dist = $val; }
+    if ($opt eq "arch") { $common_arch = $val; }
 }
 
 sub readparse {
@@ -219,9 +232,26 @@ sub htmlindexentrystatus {
         $mseparator= ", ";
     }
 
-    if (length($status{done})) {
+    if (@{$status{found_versions}}) {
+        $result .= ";\nfound in ";
+        $result .= (@{$status{found_versions}} == 1) ? 'version '
+                                                     : 'versions ';
+        $result .= join ', ', map htmlsanit($_), @{$status{found_versions}};
+    }
+
+    if (@{$status{fixed_versions}}) {
+        $result .= ";\n<strong>fixed</strong> in ";
+        $result .= (@{$status{fixed_versions}} == 1) ? 'version '
+                                                     : 'versions ';
+        $result .= join ', ', map htmlsanit($_), @{$status{fixed_versions}};
+        if (length($status{done})) {
+            $result .= ' by ' . htmlsanit($status{done});
+        }
+    } elsif (length($status{done})) {
         $result .= ";\n<strong>Done:</strong> " . htmlsanit($status{done});
-    } else {
+    }
+
+    unless (length($status{done})) {
         if (length($status{forwarded})) {
             $result .= ";\n<strong>Forwarded</strong> to "
                        . maybelink($status{forwarded});
@@ -254,44 +284,48 @@ sub htmlindexentrystatus {
     return $result;
 }
 
+sub urlargs {
+    my $args = '';
+    $args .= "&archive=yes" if $common_archive;
+    $args .= "&repeatmerged=no" unless $common_repeatmerged;
+    $args .= "&version=$common_version" if defined $common_version;
+    $args .= "&dist=$common_dist" if defined $common_dist;
+    $args .= "&arch=$common_arch" if defined $common_arch;
+    return $args;
+}
+
 sub submitterurl {
     my $ref = shift || "";
     my $params = "submitter=" . emailfromrfc822($ref);
-    $params .= "&archive=yes" if ($common_archive);
-    $params .= "&repeatmerged=no" unless ($common_repeatmerged);
+    $params .= urlargs();
     return urlsanit("pkgreport.cgi" . "?" . $params);
 }
 
 sub mainturl {
     my $ref = shift || "";
     my $params = "maint=" . emailfromrfc822($ref);
-    $params .= "&archive=yes" if ($common_archive);
-    $params .= "&repeatmerged=no" unless ($common_repeatmerged);
+    $params .= urlargs();
     return urlsanit("pkgreport.cgi" . "?" . $params);
 }
 
 sub pkgurl {
     my $ref = shift;
     my $params = "pkg=$ref";
-    $params .= "&archive=yes" if ($common_archive);
-    $params .= "&repeatmerged=no" unless ($common_repeatmerged);
-    
+    $params .= urlargs();
     return urlsanit("pkgreport.cgi" . "?" . "$params");
 }
 
 sub srcurl {
     my $ref = shift;
     my $params = "src=$ref";
-    $params .= "&archive=yes" if ($common_archive);
-    $params .= "&repeatmerged=no" unless ($common_repeatmerged);
+    $params .= urlargs();
     return urlsanit("pkgreport.cgi" . "?" . "$params");
 }
 
 sub tagurl {
     my $ref = shift;
     my $params = "tag=$ref";
-    $params .= "&archive=yes" if ($common_archive);
-    $params .= "&repeatmerged=no" unless ($common_repeatmerged);
+    $params .= urlargs();
     return urlsanit("pkgreport.cgi" . "?" . "$params");
 }
 
@@ -368,7 +402,8 @@ sub htmlizebugs {
                              "pending-fixed", "pending upload",
                              "fixed", "fixed in NMU",
                               "done", "resolved",
-                              "forwarded", "forwarded to upstream software authors");
+                              "forwarded", "forwarded to upstream software authors",
+                              "absent", "not applicable to this version");
 
     if (@bugs == 0) {
         return "<HR><H2>No reports found!</H2></HR>\n";
@@ -430,7 +465,7 @@ sub htmlizebugs {
     if ($common_raw_sort) {
        $result .= "<UL>\n" . join("", @rawsort ) . "</UL>\n";
     } else {
-       my @pendingList = qw(pending forwarded pending-fixed fixed done);
+       my @pendingList = qw(pending forwarded pending-fixed fixed done absent);
        @pendingList = reverse @pendingList if $common_pending_reverse;
 #print STDERR join(",",@pendingList)."\n";
 #print STDERR join(",",@common_pending_include).":$#common_pending_include\n";
@@ -630,6 +665,24 @@ sub getbugstatus {
     return {} if ( !$location );
     %status = %{ readbug( $bugnum, $location ) };
 
+    $status{found_versions} = [];
+    $status{fixed_versions} = [];
+    if (defined $gVersionBugsDir and
+            (defined $common_version or defined $common_dist)) {
+        my $bughash = get_hashname($bugnum);
+        if (open BUGVER, "< $gVersionBugsDir/$bughash/$bugnum.versions") {
+            local $_;
+            while (<BUGVER>) {
+                if (/^Found-in: (.*)/i) {
+                    $status{found_versions} = [split ' ', $1];
+                } elsif (/^Fixed-in: (.*)/i) {
+                    $status{fixed_versions} = [split ' ', $1];
+                }
+            }
+            close BUGVER;
+        }
+    }
+
     $status{tags} = $status{keywords};
 
     $status{"package"} =~ s/\s*$//;
@@ -640,7 +693,27 @@ sub getbugstatus {
     $status{"pending"} = 'forwarded'       if (length($status{"forwarded"}));
     $status{"pending"} = 'pending-fixed'    if ($status{"tags"} =~ /\bpending\b/);
     $status{"pending"} = 'fixed'           if ($status{"tags"} =~ /\bfixed\b/);
-    $status{"pending"} = 'done'                    if (length($status{"done"}));
+
+    my $version;
+    if (defined $common_version) {
+        $version = $common_version;
+    } elsif (defined $common_dist) {
+        $version = getversion($status{package}, $common_dist, $common_arch);
+    }
+
+    if (defined $version) {
+        my $buggy = buggyversion($bugnum, $version, \%status);
+        if ($buggy eq 'absent') {
+            $status{"pending"} = 'absent';
+        } elsif ($buggy eq 'fixed') {
+            $status{"pending"} = 'done';
+        }
+    }
+    
+    if (length($status{done}) and
+            (not defined $version or not @{$status{fixed_versions}})) {
+        $status{"pending"} = 'done';
+    }
 
     return \%status;
 }
@@ -662,4 +735,42 @@ sub buglog {
     return getbugcomponent($bugnum, 'log', $location);
 }
 
+my %_versionobj;
+sub buggyversion {
+    my ($bug, $ver, $status) = @_;
+    return '' unless defined $gVersionPackagesDir;
+    my $src = getpkgsrc()->{$status->{package}};
+    $src = $status->{package} unless defined $src;
+
+    my $tree;
+    if (exists $_versionobj{$src}) {
+        $tree = $_versionobj{$src};
+    } else {
+        $tree = Debbugs::Versions->new(\&DpkgVer::vercmp);
+        if (open VERFILE, "< $gVersionPackagesDir/$src") {
+            $tree->load(\*VERFILE);
+            close VERFILE;
+        }
+        $_versionobj{$src} = $tree;
+    }
+
+    return $tree->buggy($ver, $status->{found_versions},
+                        $status->{fixed_versions});
+}
+
+my %_versions;
+sub getversion {
+    my ($pkg, $dist, $arch) = @_;
+    return undef unless defined $gVersionIndex;
+    $dist = 'unstable' unless defined $dist;
+    $arch = 'i386' unless defined $arch;
+
+    unless (tied %_versions) {
+        tie %_versions, 'MLDBM', $gVersionIndex, O_RDONLY
+            or die "can't open versions index: $!";
+    }
+
+    return $_versions{$pkg}{$dist}{$arch};
+}
+
 1;
index b439e036e74119a81bbf2ca0d1482a0fcf84e89c..5362a0f8a4c43d03bfa7384405634af9a5156efa 100755 (executable)
@@ -34,6 +34,9 @@ my $pend_exc = $param{'&pend-exc'} || $param{'pend-exc'} || "";
 my $pend_inc = $param{'&pend-inc'} || $param{'pend-inc'} || "";
 my $sev_exc = $param{'&sev-exc'} || $param{'sev-exc'} || "";
 my $sev_inc = $param{'&sev-inc'} || $param{'sev-inc'} || "";
+my $version = $param{'version'} || undef;
+my $dist = $param{'dist'} || undef;
+my $arch = $param{'arch'} || undef;
 
 my ($pkg, $src, $maint, $maintenc, $submitter, $severity, $status, $tag);
 
@@ -105,11 +108,21 @@ set_option("pend-exc", $pend_exc);
 set_option("pend-inc", $pend_inc);
 set_option("sev-exc", $sev_exc);
 set_option("sev-inc", $sev_inc);
+set_option("version", $version);
+set_option("dist", $dist);
+set_option("arch", $arch);
 
 my $title;
 my @bugs;
 if (defined $pkg) {
   $title = "package $pkg";
+  if (defined $version) {
+    $title .= " (version $version)";
+  } elsif (defined $dist) {
+    $title .= " in $dist";
+    my $distver = getversion($pkg, $dist, $arch);
+    $title .= " (version $distver)" if defined $distver;
+  }
   my @pkgs = split /,/, $pkg;
   @bugs = @{getbugs(sub {my %d=@_;
                          foreach my $try (splitpackages($d{"pkg"})) {
@@ -119,6 +132,13 @@ if (defined $pkg) {
                         }, 'package', @pkgs)};
 } elsif (defined $src) {
   $title = "source $src";
+  if (defined $version) {
+    $title .= " (version $version)";
+  } elsif (defined $dist) {
+    $title .= " in $dist";
+    my $distver = getversion($src, $dist, 'source');
+    $title .= " (version $distver)" if defined $distver;
+  }
   my @pkgs = ();
   my @srcs = split /,/, $src;
   foreach my $try (@srcs) {
@@ -134,6 +154,7 @@ if (defined $pkg) {
 } elsif (defined $maint) {
   my %maintainers = %{getmaintainers()};
   $title = "maintainer $maint";
+  $title .= " in $dist" if defined $dist;
   if ($maint eq "") {
     @bugs = @{getbugs(sub {my %d=@_;
                            foreach my $try (splitpackages($d{"pkg"})) {
@@ -161,6 +182,7 @@ if (defined $pkg) {
 } elsif (defined $maintenc) {
   my %maintainers = %{getmaintainers()};
   $title = "encoded maintainer $maintenc";
+  $title .= " in $dist" if defined $dist;
   @bugs = @{getbugs(sub {my %d=@_; 
                          foreach my $try (splitpackages($d{"pkg"})) {
                            my @me = getparsedaddrs($maintainers{$try});
@@ -172,6 +194,7 @@ if (defined $pkg) {
                         })};
 } elsif (defined $submitter) {
   $title = "submitter $submitter";
+  $title .= " in $dist" if defined $dist;
   my @submitters = split /,/, $submitter;
   @bugs = @{getbugs(sub {my %d=@_; my $se; 
                       ($se = $d{"submitter"} || "") =~ s/\s*\(.*\)\s*//;
@@ -180,6 +203,7 @@ if (defined $pkg) {
                     }, 'submitter-email', @submitters)};
 } elsif (defined($severity) && defined($status)) {
   $title = "$status $severity bugs";
+  $title .= " in $dist" if defined $dist;
   my @severities = split /,/, $severity;
   my @statuses = split /,/, $status;
   @bugs = @{getbugs(sub {my %d=@_;
@@ -188,12 +212,14 @@ if (defined $pkg) {
                     })};
 } elsif (defined($severity)) {
   $title = "$severity bugs";
+  $title .= " in $dist" if defined $dist;
   my @severities = split /,/, $severity;
   @bugs = @{getbugs(sub {my %d=@_;
                       return (grep($d{"severity"} eq $_, @severities));
                     }, 'severity', @severities)};
 } elsif (defined($tag)) {
   $title = "bugs tagged $tag";
+  $title .= " in $dist" if defined $dist;
   my @tags = split /,/, $tag;
   @bugs = @{getbugs(sub {my %d = @_;
                          my %tags = map { $_ => 1 } split ' ', $d{"tags"};
index b3749eac74124ba6bb6da4a8e8699e9e635e62b3..c86341d89c682c92f6e93bbd861d73f9b5beb962 100644 (file)
@@ -8,7 +8,7 @@ Build-Depends-Indep: debhelper
 
 Package: debbugs
 Architecture: all
-Depends: perl5 | perl, exim | mail-transport-agent, libmailtools-perl, ed, libmime-perl, libio-stringy-perl
+Depends: perl5 | perl, exim | mail-transport-agent, libmailtools-perl, ed, libmime-perl, libio-stringy-perl, libmldbm-perl
 Recommends: httpd, links | lynx
 Description: The bug tracking system based on the active Debian BTS
  Debian has a bug tracking system which files details of bugs reported by