From 2c7d7cd43020f31cb5b9aac6e153df7912d779ae Mon Sep 17 00:00:00 2001 From: cjwatson <> Date: Mon, 18 Aug 2003 00:16:14 -0800 Subject: [PATCH] [project @ 2003-08-18 01:16:14 by cjwatson] 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 | 17 +++++- cgi/common.pl | 143 ++++++++++++++++++++++++++++++++++++++++------ cgi/pkgreport.cgi | 26 +++++++++ debian/control | 2 +- 4 files changed, 170 insertions(+), 18 deletions(-) diff --git a/cgi/bugreport.cgi b/cgi/bugreport.cgi index fe19e0a..dad91a0 100755 --- a/cgi/bugreport.cgi +++ b/cgi/bugreport.cgi @@ -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 = 'Fixed 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, "Done: ".htmlsanit($status{done}); } elsif (length($status{forwarded})) { push @descstates, "Forwarded to ".maybelink($status{forwarded}); diff --git a/cgi/common.pl b/cgi/common.pl index 5886cf2..0e100b6 100644 --- a/cgi/common.pl +++ b/cgi/common.pl @@ -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 .= ";\nfixed 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 .= ";\nDone: " . htmlsanit($status{done}); - } else { + } + + unless (length($status{done})) { if (length($status{forwarded})) { $result .= ";\nForwarded 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 "

No reports found!

\n"; @@ -430,7 +465,7 @@ sub htmlizebugs { if ($common_raw_sort) { $result .= "\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 () { + 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; diff --git a/cgi/pkgreport.cgi b/cgi/pkgreport.cgi index b439e03..5362a0f 100755 --- a/cgi/pkgreport.cgi +++ b/cgi/pkgreport.cgi @@ -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"}; diff --git a/debian/control b/debian/control index b3749ea..c86341d 100644 --- a/debian/control +++ b/debian/control @@ -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 -- 2.39.2