From 3454a7dfce9e6612035213b9cc67e233e7b0f61a Mon Sep 17 00:00:00 2001 From: "gerv%gerv.net" <> Date: Fri, 12 Oct 2001 06:01:44 +0000 Subject: Bug 83058 - need a way to hide resolved bugs in dependency tree view. Patch by kiko; r=gerv, afranke. --- showdependencytree.cgi | 358 +++++++++++++++++++++++++++++++++++++++++++------ 1 file changed, 318 insertions(+), 40 deletions(-) (limited to 'showdependencytree.cgi') diff --git a/showdependencytree.cgi b/showdependencytree.cgi index bab36da61..14d504567 100755 --- a/showdependencytree.cgi +++ b/showdependencytree.cgi @@ -1,4 +1,4 @@ -#!/usr/bonsaitools/bin/perl -w +#!/usr/bonsaitools/bin/perl -wT # -*- Mode: perl; indent-tabs-mode: nil -*- # # The contents of this file are subject to the Mozilla Public @@ -19,10 +19,13 @@ # Rights Reserved. # # Contributor(s): Terry Weissman +# Andreas Franke +# Christian Reis use diagnostics; use strict; +use lib qw(.); require "CGI.pl"; # Shut up misguided -w warnings about "used only once": @@ -40,34 +43,85 @@ $::usergroupset = $::usergroupset; # More warning suppression silliness. ###################################################################### # Make sure the bug ID is a positive integer representing an existing -# bug that the user is authorized to access. +# bug that the user is authorized to access ValidateBugID($::FORM{'id'}); +my $id = $::FORM{'id'}; +my $hide_resolved = $::FORM{'hide_resolved'} || 0; +my $maxdepth = $::FORM{'maxdepth'} || 0; + +if ($maxdepth !~ /^\d+$/) { $maxdepth = 0 }; +if ($hide_resolved !~ /^\d+$/ || $hide_resolved != 1) { $hide_resolved = 0 }; + ###################################################################### # End Data/Security Validation ###################################################################### -my $id = $::FORM{'id'}; -my $linkedid = qq{$id}; - -print "Content-type: text/html\n\n"; -PutHeader("Dependency tree", "Dependency tree", "Bug $linkedid"); +# +# Globals +# A hash to count visited bugs, and also to avoid processing repeated bugs my %seen; +# HTML output generated in the parse of the dependency tree. This is a +# global only to avoid excessive complication in the recursion invocation +my $html; + +# Saves the largest of the two actual depths of the trees +my $realdepth = 0; + +# The scriptname for use as FORM ACTION. +my $scriptname = $::ENV{'SCRIPT_NAME'}; # showdependencytree.cgi + +# +# Functions + +# DumpKids recurses through the bug hierarchy starting at bug i, and +# appends the bug information found to the html global variable. The +# parameters are not straightforward, so look at the examples. +# +# DumpKids(i, target [, depth]) +# +# Params +# i: The bug id to analyze +# target: The type we are looking for; either "blocked" or "dependson" +# Optional +# depth: The current dependency depth we are analyzing, used during +# recursion +# Globals Modified +# html: Bug descriptions are appended here +# realdepth: We set the maximum depth of recursion reached +# seen: We store the bugs analyzed so far +# Globals Referenced +# maxdepth +# hide_resolved +# +# Examples: +# DumpKids(163, "blocked"); +# will look for bugs that depend on bug 163 +# DumpKids(163, "dependson"); +# will look for bugs on which bug 163 depends + sub DumpKids { - my ($i, $me, $target) = (@_); - if (exists $seen{$i}) { - return; - } + my ($i, $target, $depth) = (@_); + my $bgcolor = "#d9d9d9"; + my $fgcolor = "#000000"; + my $me; + if (! defined $depth) { $depth = 1; } + if (exists $seen{$i}) { return; } $seen{$i} = 1; - SendSQL("select $target from dependencies where $me = $i order by $target"); + if ($target eq "blocked") { + $me = "dependson"; + } else { + $me = "blocked"; + } + SendSQL("select $target from dependencies where $me=$i order by $target"); my @list; while (MoreSQLData()) { push(@list, FetchOneColumn()); } if (@list) { - print "
    \n"; + my $list_started = 0; foreach my $kid (@list) { my ($bugid, $stat, $milestone) = ("", "", ""); my ($userid, $short_desc) = ("", ""); @@ -79,36 +133,260 @@ sub DumpKids { ($bugid, $stat, $userid, $short_desc) = (FetchSQLData()); } - if (!defined $bugid) { - next; - } - my $opened = ($stat eq "NEW" || $stat eq "ASSIGNED" || - $stat eq "REOPENED"); - print "
  • "; - if (!$opened) { - print ""; - } - $short_desc = html_quote($short_desc); - SendSQL("select login_name from profiles where userid = $userid"); - my ($owner) = (FetchSQLData()); - if ( (Param('usetargetmilestone')) && ($milestone) ) { - print qq{$kid [$milestone, $owner] - $short_desc}; - } else { - print qq{$kid [$owner] - $short_desc}; - } - if (!$opened) { - print ""; - } - DumpKids($kid, $me, $target); + if (! defined $bugid) { next; } + my $opened = IsOpenedState($stat); + if ($hide_resolved && ! $opened) { next; } + + # If we specify a maximum depth, we hide the output when + # that depth has occured, but continue recursing so we know + # the real maximum depth of the tree. + if (! $maxdepth || $depth <= $maxdepth) { + if (! $list_started) { $html .= "
      "; $list_started = 1 } + $html .= "
    • "; + if (! $opened) { + $html .= qq| + |; + } + $short_desc = html_quote($short_desc); + SendSQL("select login_name from profiles where userid = $userid"); + my ($owner) = (FetchSQLData()); + if ((Param('usetargetmilestone')) && ($milestone)) { + $html .= qq| + $kid [$milestone, $owner] + - $short_desc. + |; + } else { + $html .= qq| + $kid [$owner] - + $short_desc.\n|; + } + if (! $opened) { $html .= ""; } + } # End hideable output + + # Store the maximum depth so far + $realdepth = $realdepth < $depth ? $depth : $realdepth; + DumpKids($kid, $target, $depth + 1); } - print "
    \n"; + if ($list_started) { $html .= "
"; } } } -print "

Bugs that bug $linkedid depends on

"; -DumpKids($id, "blocked", "dependson"); -print "

Bugs that depend on bug $linkedid

"; -undef %seen; -DumpKids($id, "dependson", "blocked"); +# makeTreeHTML calls DumpKids and generates the HTML output for a +# dependency/blocker section. +# +# makeTreeHTML(i, linked_id, target); +# +# Params +# i: Bug id +# linked_id: Linkified bug_id used to linkify the bug +# target: The type we are looking for; either "blocked" or "dependson" +# Globals modified +# html [Also modified in our call to DumpKids] +# Globals referenced +# seen [Also modified by DumpKids] +# maxdepth +# realdepth +# +# Example: +# $depend_html = makeTreeHTML(83058, 83058, "dependson"); +# Will generate HTML for bugs that depend on bug 83058 + +sub makeTreeHTML { + my ($i, $linked_id, $target) = @_; + + # Clean up globals for this run + $html = ""; + %seen = (); + + DumpKids($i, $target); + my $tmphtml = $html; + + # Output correct heading + $html = "

Bugs that bug $linked_id ".($target eq "blocked" ? + "blocks" : "depends on"); + + # Provide feedback for omitted bugs + if ($maxdepth || $hide_resolved) { + $html .= " (Only "; + if ($hide_resolved) { $html .= "open "; } + $html .= "bugs "; + if ($maxdepth) { $html .= "whose depth is less than $maxdepth "; } + $html .= "will be shown)"; + } + + $html .= "

"; + $html .= $tmphtml; + # If no bugs were found, say so + if ((scalar keys %seen) < 2) { + $html .= "    None

\n"; + } + + return $html; +} + +# Draw the actual form controls that make up the hide/show resolved and +# depth control toolbar. +# +# drawDepForm() +# +# Params +# none +# Globals modified +# none +# Globals referenced +# hide_resolved +# maxdepth +# realdepth + +sub drawDepForm { + my $bgcolor = "#d0d0d0"; + my ($hide_msg, $hide_input); + + # Set the text and action for the hide resolved button. + if ($hide_resolved) { + $hide_input = ''; + $hide_msg = "Show Resolved"; + } else { + $hide_input = ''; + $hide_msg = "Hide Resolved"; + } + + print qq| + + + + + + + + + + + + +
+
+ + | . ( $maxdepth ? + qq|| + : "" ) . qq| + $hide_input + + +
+
+ + + Depth: + + +
+ + + + + + +
+
+ + Limit to: + + +
+ + + + + + + +
+
+
+ + + + + + + +
+
+
+ + + + | . ( $maxdepth ? qq| + | : "" ) + . qq| + + = $realdepth ? + "disabled" : "" ) . qq|> + +
+
+
+ + + + + + +
+
+ |; +} + +###################################################################### +# Main Section +###################################################################### + +my $linked_id = qq|$id|; + +# Start the tree walk and save results. The tree walk generates HTML but +# needs to be called before the page output starts so we have the +# realdepth, which is necessary for generating the control toolbar. + +# Get bugs we depend on +my $depend_html = makeTreeHTML($id, $linked_id, "dependson"); + +my $tmpdepth = $realdepth; +$realdepth = 0; + +# Get bugs we block +my $block_html = makeTreeHTML($id, $linked_id, "blocked"); + +# Select maximum depth found for use in the toolbar +$realdepth = $realdepth < $tmpdepth ? $tmpdepth : $realdepth; + +# +# Actual page output happens here + +print "Content-type: text/html\n\n"; +PutHeader("Dependency tree for Bug $id", "Dependency tree for Bug $linked_id"); +drawDepForm(); +print $depend_html; +print $block_html; +drawDepForm(); PutFooter(); -- cgit v1.2.3-24-g4f1b