stas        2003/01/27 22:50:59

  Modified:    lib/Apache Status.pm
  Log:
  - refactor the run-time requirement lookup and require code
  - cleanup to work under the "modperl" handler
  - die if CGI and Apache::Request aren't available
  - use CPAN search for hints to install a missing module
  
  Revision  Changes    Path
  1.3       +103 -80   modperl-2.0/lib/Apache/Status.pm
  
  Index: Status.pm
  ===================================================================
  RCS file: /home/cvs/modperl-2.0/lib/Apache/Status.pm,v
  retrieving revision 1.2
  retrieving revision 1.3
  diff -u -r1.2 -r1.3
  --- Status.pm 28 Jan 2003 04:53:15 -0000      1.2
  +++ Status.pm 28 Jan 2003 06:50:59 -0000      1.3
  @@ -21,38 +21,24 @@
   $Apache::Status::VERSION = '3.00'; # mod_perl 2.0
   
   use constant IS_WIN32 => ($^O eq "MSWin32");
  -my $Is_Win32 = ($^O eq "MSWin32");
  -
  -my %is_installed = ();
  -{
  -    local $SIG{__DIE__};
  -    %is_installed = map {
  -     $_, (eval("require $_") || 0);
  -    } qw (Data::Dumper Devel::Symdump B Apache::Request 
  -        Apache::Peek Apache::Symbol);
  -}
   
   our $newQ;
   
  -if ($is_installed{"Apache::Request"}) {
  +if (eval {require Apache::Request}) {
       $newQ ||= sub { Apache::Request->new(@_) };
   }
  -else {
  -    $is_installed{"CGI"} = eval("require CGI") || 0;
  +elsif (eval {require CGI}) {
       $newQ ||= sub { CGI->new; };
   }
  -
  -my $CPAN_base = "http://cpan.org/modules/by-module/";;
  -
  -my $install_symdump = <<EOF;
  -Please install the <a href="$CPAN_base/Devel/">Devel::Symdump</a> module.
  -EOF
  +else {
  +    die "Need CGI.pm or Apache::Request to operate";
  +}
   
   my %status = (
       script    => "PerlRequire'd Files",
       inc       => "Loaded Modules",
       rgysubs   => "Compiled Registry Scripts",
  -    'symdump' => "Symbol Table Dump",
  +    symdump   => "Symbol Table Dump",
       inh_tree  => "Inheritance Tree",
       isa_tree  => "ISA Tree", 
       env       => "Environment",
  @@ -69,6 +55,53 @@
       $status{"section_config"} = "Perl Section Configuration";
   }
   
  +my %requires = (
  +    deparse     => ["StatusDeparse",     "B::Deparse",     0.59, ],
  +    fathom      => ["StatusFathom",      "B::Fathom",      0.05, ],
  +    symdump     => ["",                  "Devel::Symdump", 2.00, ],
  +    dumper      => ["StatusDumper",      "Data::Dumper",   0,    ],
  +    b           => ["",                  "B",              0,    ],
  +    graph       => ["StatusGraph",       "B::Graph",       0.03, ],
  +    lexinfo     => ["StatusLexInfo",     "B::LexInfo",     0,    ],
  +    xref        => ["",                  "B::Xref",        0,    ],
  +    terse       => ["StatusTerse",       "B::Terse",       0,    ],
  +    tersesize   => ["StatusTerseSize",   "B::TerseSize",   0,    ],
  +    packagesize => ["StatusPackageSize", "B::TerseSize",   0,    ],
  +    peek        => ["StatusPeek",        "Apache::Peek",   0,    ], # XXX: version?
  +);
  +
  +sub has {
  +    my($r, $what) = @_;
  +
  +    return 0 unless exists $requires{$what};
  +
  +    my($opt, $module, $version) = @{ $requires{$what} };
  +
  +    (my $file = $module) =~ s|::|/|;
  +    $file .= ".pm";
  +
  +    # if !$opt we skip the testing for the option
  +    return 0 if $opt && !status_config($r, $opt);
  +    return 0 unless eval { require $file };
  +    return 0 unless $module->VERSION >= $version;
  +
  +    return 1;
  +}
  +
  +use constant CPAN_SEARCH => 'http://search.cpan.org/search?mode=module&query';
  +
  +sub install_hint {
  +    my ($module) = @_;
  +    return qq{Please install the } .
  +           qq{<a href="@{[CPAN_SEARCH]}=$module">$module</a> module.};
  +}
  +
  +sub status_config {
  +    my($r, $key) = @_;
  +    return (lc($r->dir_config($key)) eq "on") ||
  +        (lc($r->dir_config('StatusOptionsAll')) eq "on");
  +}
  +
   sub menu_item {
       my($self, $key, $val, $sub) = @_;
       $status{$key} = $val;
  @@ -124,10 +157,10 @@
   sub symdump {
       my($r, $q, $package) = @_;
   
  -    return $install_symdump unless $is_installed{"Devel::Symdump"};
  +    return install_hint("Devel::Symdump") unless has($r, "symdump");
   
  -    my $meth = "new";
  -    $meth = "rnew" if lc($r->dir_config("StatusRdump")) eq "on";
  +    my $meth = lc($r->dir_config("StatusRdump")) eq "on" 
  +        ? "rnew" : "new";
       my $sob = Devel::Symdump->$meth($package);
       return $sob->Apache::Status::as_HTML($package, $r, $q);
   }
  @@ -281,6 +314,7 @@
        (map {
         my $val = $SIG{$_} || "";
         if ($val and ref $val eq "CODE") {
  +             # XXX: 2.0 doesn't have Apache::Symbol
             if (my $cv = Apache::Symbol->can('sv_name')) {
                 $val = "\\&".  $cv->($val);
             }
  @@ -297,20 +331,22 @@
   
   
   sub status_inh_tree {
  -    return $is_installed{"Devel::Symdump"}
  +    return has(shift, "symdump")
           ? ["<pre>", Devel::Symdump->inh_tree, "</pre>"]
  -        : $install_symdump;
  +        : install_hint("Devel::Symdump");
   }
   
  -sub status_isa_tree { 
  -    return $is_installed{"Devel::Symdump"}
  +sub status_isa_tree {
  +    return has(shift, "symdump")
           ? ["<pre>", Devel::Symdump->isa_tree, "</pre>"]
  -        : $install_symdump;
  +        : install_hint("Devel::Symdump");
   }
   
  -sub status_data_dump { 
  +sub status_data_dump {
       my($r, $q) = @_;
   
  +    return install_hint('Data::Dumper') unless has($r, "dumper");
  +
       my($name, $type) = (split "/", $r->uri)[-2,-1];
   
       no strict 'refs';
  @@ -331,7 +367,7 @@
   
   sub status_cv_dump { 
       my($r, $q) = @_;
  -    return [] unless $is_installed{B};
  +    return [] unless has($r, "b");
   
       no strict 'refs';
       my($name, $type) = (split "/", $r->uri)[-2,-1];
  @@ -366,28 +402,10 @@
       \@retval;
   }
   
  -sub status_config {
  -    my($r, $key) = @_;
  -    return (lc($r->dir_config($key)) eq "on") ||
  -        (lc($r->dir_config('StatusOptionsAll')) eq "on");
  -}
  -
  -sub b_graph_link {
  -    my($r, $q, $name) = @_;
  -
  -    return unless status_config($r, "StatusGraph");
  -    return unless eval { require B::Graph };
  -
  -    B::Graph->UNIVERSAL::VERSION('0.03');
  -    my $script = $r->location;
  -    return qq(\n<a href="$script/$name?noh_b_graph">OP Tree Graph</a>\n);
  -}
  -
   sub b_lexinfo_link {
       my($r, $q, $name) = @_;
   
  -    return unless status_config($r, "StatusLexInfo");
  -    return unless eval { require B::LexInfo };
  +    return unless has($r, "lexinfo");
   
       my $script = $q->location;
       return qq(\n<a href="$script/$name?noh_b_lexinfo">Lexical Info</a>\n);
  @@ -397,6 +415,7 @@
       my $r = shift;
   
       $r->content_type("text/plain");
  +    return unless has($r, "lexinfo");
   
       no strict 'refs';
       my($name) = (split "/", $r->uri)[-1];
  @@ -411,8 +430,7 @@
   sub b_terse_link {
       my($r, $q, $name) = @_;
   
  -    return unless status_config($r, "StatusTerse");
  -    return unless eval { require B::Terse };
  +    return unless has($r, "terse");
   
       my $script = $r->location;
       my @retval;
  @@ -427,21 +445,22 @@
   sub noh_b_terse {
       my $r = shift;
   
  -    return unless eval { require B::Terse };
  -
       $r->content_type("text/plain");
  +    return unless has($r, "terse");
   
       no strict 'refs';
       my($arg, $name) = (split "/", $r->uri)[-2,-1];
       $r->print("Syntax Tree Dump ($b_terse_exp{$arg}) for $name\n\n");
  +
  +    # XXX: blead perl dumps things to STDERR, though the same version
  +    # works fine with 1.27
       B::Terse::compile($arg, $name)->();
   }
   
   sub b_terse_size_link {
       my($r, $q, $name) = @_;
   
  -    return unless status_config($r, "StatusTerseSize");
  -    return unless eval { require B::TerseSize };
  +    return unless has($r, "tersesize");
   
       my $script = $r->location;
       my @retval;
  @@ -456,9 +475,8 @@
   sub noh_b_terse_size {
       my $r = shift;
   
  -    return unless eval { require B::TerseSize };
  -
       $r->content_type("text/html");
  +    return unless has($r, "tersesize");
   
       $r->print('<pre>');
       my($arg, $name) = (split "/", $r->uri)[-2,-1];
  @@ -471,8 +489,7 @@
   sub b_package_size_link {
       my($r, $q, $name) = @_;
   
  -    return unless status_config($r, "StatusPackageSize");
  -    return unless eval { require B::TerseSize };
  +    return unless has($r, "packagesize");
   
       my $script = $r->location;
       qq(<a href="$script/$name?noh_b_package_size">Memory Usage</a>\n);
  @@ -481,9 +498,9 @@
   sub noh_b_package_size {
       my($r, $q) = @_;
   
  -    return unless eval { require B::TerseSize };
  -
       $r->content_type("text/html");
  +    return unless has($r, "packagesize");
  +
       $r->print('<pre>');
   
       no strict 'refs';
  @@ -524,9 +541,7 @@
   sub b_deparse_link {
       my($r, $q, $name) = @_;
   
  -    return unless status_config($r, "StatusDeparse");
  -    return unless eval { require B::Deparse };
  -    return unless $B::Deparse::VERSION >= 0.59;
  +    return unless has($r, "deparse");
   
       my $script = $r->location;
       return qq(\n<a href="$script/$name?noh_b_deparse">Deparse</a>\n);
  @@ -536,6 +551,7 @@
       my $r = shift;
   
       $r->content_type("text/plain");
  +    return unless has($r, "deparse");
   
       my $name = (split "/", $r->uri)[-1];
       $r->print("Deparse of $name\n\n");
  @@ -548,9 +564,7 @@
   sub b_fathom_link {
       my($r, $q, $name) = @_;
   
  -    return unless status_config($r, "StatusFathom");
  -    return unless eval { require B::Fathom };
  -    return unless $B::Fathom::VERSION >= 0.05;
  +    return unless has($r, "fathom");
   
       my $script = $r->location;
       return qq(\n<a href="$script/$name?noh_b_fathom">Fathom Score</a>\n);
  @@ -560,6 +574,7 @@
       my $r = shift;
   
       $r->content_type("text/plain");
  +    return unless has($r, "fathom");
   
       my $name = (split "/", $r->uri)[-1];
       $r->print("Fathom Score of $name\n\n");
  @@ -571,8 +586,7 @@
   sub peek_link {
       my($r, $q, $name, $type) = @_;
   
  -    return unless status_config($r, "StatusPeek");
  -    return unless $is_installed{"Apache::Peek"};
  +    return unless has($r, "peek");
   
       my $script = $r->location;
       return qq(\n<a href="$script/$name/$type?noh_peek">Peek Dump</a>\n);
  @@ -582,6 +596,7 @@
       my $r = shift;
   
       $r->content_type("text/plain");
  +    return unless has($r, "peek");
   
       no strict 'refs';
       my($name, $type) = (split "/", $r->uri)[-2,-1];
  @@ -593,7 +608,7 @@
   sub xref_link {
       my($r, $q, $name) = @_;
   
  -    return unless $is_installed{"B::Xref"};
  +    return unless has($r, "xref");
   
       my $script = $r->location;
       return qq(\n<a href="$script/$name?noh_xref">Cross Reference Report</a>\n);
  @@ -603,10 +618,10 @@
       my $r = shift;
   
       $r->content_type("text/plain");
  +    return unless has($r, "xref");
   
  -    require B::Xref;
       (my $thing = $r->path_info) =~ s:^/::;
  -    print "Xref of $thing\n";
  +    $r->print("Xref of $thing\n");
       B::Xref::compile($thing)->();
   }
   
  @@ -617,10 +632,19 @@
                          });
   }
   
  +sub b_graph_link {
  +    my($r, $q, $name) = @_;
  +
  +    return unless has($r, "graph");
  +
  +    my $script = $r->location;
  +    return qq(\n<a href="$script/$name?noh_b_graph">OP Tree Graph</a>\n);
  +}
  +
   sub noh_b_graph {
       my $r = shift;
   
  -    require B::Graph;
  +    return unless has($r, "graph");
   
       untie *STDOUT;
   
  @@ -699,7 +723,7 @@
       my $uri = $r->uri;
       my $is_main = $package eq "main";
   
  -    my $do_dump = status_config($r, "StatusDumper");
  +    my $do_dump = has($r, "dumper");
   
       my @methods = sort keys %{$self->{'AUTOLOAD'}};
   
  @@ -725,15 +749,14 @@
                push @line, qq(<a href="$uri?$_">$_</a>);
            }
            elsif ($type eq "functions") {
  -             if ($is_installed{B}) {
  +             if (has($r, "b")) {
                    push @line, qq(<a href="$uri/$_/$dtype?cv_dump">$_</a>);
                }
                else {
                    push @line, $_;
                }
            }
  -         elsif ($do_dump and $can_dump{$type} and 
  -               $is_installed{"Data::Dumper"}) {
  +         elsif ($do_dump and $can_dump{$type}) {
                next if /_</;
                push @line, qq(<a href="$uri/$_/$dtype?data_dump">$_</a>);
            }
  @@ -759,7 +782,7 @@
   =head1 SYNOPSIS
   
     <Location /perl-status>
  -      SetHandler  perl-script
  +      SetHandler modperl
         PerlResponseHandler Apache::Status
     </Location>
   
  @@ -771,7 +794,7 @@
   Configure like so:
   
     <Location /perl-status>
  -       SetHandler  perl-script
  +       SetHandler modperl
          PerlResponseHandler Apache::Status
     </Location>
   
  @@ -802,7 +825,7 @@
   
   =item StatusDumper
   
  -When browsing symbol tables, the values of arrays, hashes ans calars
  +When browsing symbol tables, the values of arrays, hashes and scalars
   can be viewed via B<Data::Dumper> if this configuration variable is set
   to On:
   
  
  
  


Reply via email to