showdependencytree.cgi 5.14 KB
Newer Older
1
#!/usr/bin/perl -wT
2 3
# -*- Mode: perl; indent-tabs-mode: nil -*-
#
4 5 6 7 8 9 10 11 12 13
# 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.
#
14
# The Original Code is the Bugzilla Bug Tracking System.
15
#
16
# The Initial Developer of the Original Code is Netscape Communications
17 18 19 20
# Corporation. Portions created by Netscape are
# Copyright (C) 1998 Netscape Communications Corporation. All
# Rights Reserved.
#
21
# Contributor(s): Terry Weissman <terry@mozilla.org>
22 23
#                 Andreas Franke <afranke@mathweb.org>
#                 Christian Reis <kiko@async.com.br>
24
#                 Myk Melez <myk@mozilla.org>
25
#                 Frédéric Buclin <LpSolit@gmail.com>
26 27 28

use strict;

29
use lib qw(.);
30
require "globals.pl";
31
use Bugzilla;
32
use Bugzilla::Bug;
33

34
my $user = Bugzilla->login();
35

36
my $cgi = Bugzilla->cgi;
37 38
my $template = Bugzilla->template;
my $vars = {};
39 40
# Connect to the shadow database if this installation is using one to improve
# performance.
41
my $dbh = Bugzilla->switch_to_shadow_db();
42

43 44 45
################################################################################
# Data/Security Validation                                                     #
################################################################################
46 47

# Make sure the bug ID is a positive integer representing an existing
48
# bug that the user is authorized to access.
49 50
my $id = $cgi->param('id');
ValidateBugID($id);
51
my $current_bug = new Bugzilla::Bug($id, $user->id);
52

53
my $hide_resolved = $cgi->param('hide_resolved') ? 1 : 0;
54

55
my $maxdepth = $cgi->param('maxdepth') || 0;
56
if ($maxdepth !~ /^\d+$/) { $maxdepth = 0 };
57

58 59 60
################################################################################
# Main Section                                                                 #
################################################################################
61

62
# Stores the greatest depth to which either tree goes.
63 64
my $realdepth = 0;

65 66
# Generate the tree of bugs that this bug depends on and a list of IDs
# appearing in the tree.
67
my $dependson_tree = { $id => $current_bug };
68 69 70 71 72 73 74
my $dependson_ids = {};
GenerateTree($id, "dependson", 1, $dependson_tree, $dependson_ids);
$vars->{'dependson_tree'} = $dependson_tree;
$vars->{'dependson_ids'} = [keys(%$dependson_ids)];

# Generate the tree of bugs that this bug blocks and a list of IDs
# appearing in the tree.
75
my $blocked_tree = { $id => $current_bug };
76 77 78 79 80 81 82 83 84 85 86
my $blocked_ids = {};
GenerateTree($id, "blocked", 1, $blocked_tree, $blocked_ids);
$vars->{'blocked_tree'} = $blocked_tree;
$vars->{'blocked_ids'} = [keys(%$blocked_ids)];

$vars->{'realdepth'}      = $realdepth;

$vars->{'bugid'}          = $id;
$vars->{'maxdepth'}       = $maxdepth;
$vars->{'hide_resolved'}  = $hide_resolved;

87
print $cgi->header();
88 89
$template->process("bug/dependency-tree.html.tmpl", $vars)
  || ThrowTemplateError($template->error());
90 91 92 93 94 95 96 97 98

################################################################################
# Recursive Tree Generation Function                                           #
################################################################################

sub GenerateTree {
    # Generates a dependency tree for a given bug.  Calls itself recursively
    # to generate sub-trees for the bug's dependencies.
    my ($bug_id, $relationship, $depth, $bugs, $ids) = @_;
99 100 101 102 103 104 105 106 107

    my @dependencies;
    if ($relationship eq 'dependson') {
        @dependencies = @{$bugs->{$bug_id}->dependson};
    }
    else {
        @dependencies = @{$bugs->{$bug_id}->blocked};
    }

108 109
    # Don't do anything if this bug doesn't have any dependencies.
    return unless scalar(@dependencies);
110

111 112 113 114 115 116 117 118 119
    # Record this depth in the global $realdepth variable if it's farther 
    # than we've gone before.
    $realdepth = max($realdepth, $depth);

    foreach my $dep_id (@dependencies) {
        # Get this dependency's record from the database and generate
        # its sub-tree if we haven't already done so (which happens
        # when bugs appear in dependency trees multiple times).
        if (!$bugs->{$dep_id}) {
120
            $bugs->{$dep_id} = new Bugzilla::Bug($dep_id, $user->id);
121 122
            GenerateTree($dep_id, $relationship, $depth+1, $bugs, $ids);
        }
123

124 125 126 127
        # Add this dependency to the list of this bug's dependencies 
        # if it exists, if we haven't exceeded the maximum depth the user 
        # wants the tree to go, and if the dependency isn't resolved 
        # (if we're ignoring resolved dependencies).
128
        if (!$bugs->{$dep_id}->{'error'}
129
            && (!$maxdepth || $depth <= $maxdepth) 
130
            && ($bugs->{$dep_id}->{'isopened'} || !$hide_resolved))
131
        {
132 133 134
            # Due to AUTOLOAD in Bug.pm, we cannot add 'dependencies'
            # as a bug object attribute from here.
            push(@{$bugs->{'dependencies'}->{$bug_id}}, $dep_id);
135
            $ids->{$dep_id} = 1;
136 137 138
        }
    }
}