Beefy Boxes and Bandwidth Generously Provided by pair Networks
Think about Loose Coupling
 
PerlMonks  

Search @INC And Display Modules

by Vautrin (Hermit)
on Apr 06, 2004 at 12:40 UTC ( [id://342910]=sourcecode: print w/replies, xml ) Need Help??
Category: Utility Code
Author/Contact Info Daniel R. Anderson
dan@mathjunkies.com
Description:

Every once in a while I'll see somebody asking how to figure out what modules are installed on their system by default, or somebody looking to find modules they installed, or somebody looking to find whether or not a particular module is installed. So, I've created a script that will use File::Find to search all of the directories in @INC, figure out the proper module name, and display it.

I also added command line options so that you can choose whether or not you want to display modules you installed, modules that came with Perl, or both. In the spirit of Unix tools, the outputted list of modules is one per line, and completely unformatted. You can pipe the output to grep if you want to search for a module, or pipe it to sort if you want to see some semblance of order, or pipe it to wc to get a word count.

#! /usr/bin/perl
# ModuleList.plx

# Copyright (c) Daniel R. Anderson
# Distributed under the same license
# terms as Perl.

use strict;
use warnings;
use File::Find;

# these variables are used to decide
# what to print out
my $no_core = 1;
my $no_user = 0;
my @installed_modules;

foreach my $arg (@ARGV) {
  if ($arg =~ m/--no-core/i) {
    $no_core = 1;
  }
  elsif ($arg =~ m/--use-core/i) {
    $no_core = 0;
  }
  elsif ($arg =~ m/--no-user/i) {
    $no_user = 1;
  }
  elsif ($arg =~ m/--use-user/i) {
    $no_user = 0;
  }
  else {
    print "ModuleList.plx\n\n";
    print "Usage:\n";
    print "% ./ModuleList.plx [options]\n";
    print "Where options are:\n";
    print "--no-core  - Don't print core modules\n";
    print "--use-core - Print core modules\n";
    print "--no-user  - Don't print user modules\n";
    print "--use-user - Print user modules\n\n";
    print "If no options are specified --no-core and\n";
    print "--use-user are assumd.\n\n";
    print "Copyright (c) 2004 Daniel R. Anderson\n";
    print "Distributed under the same licensing terms\n";
    print "as Perl.\n\n";
    exit (0);
  }
}

# to check whether or not a module came with Perl
# I simply created a hash with all the modules
# included in 5.8.0 (perldoc perlmodlib).

# This will make lookups
# relatively fast for the 200+ modules that
# are included.  Also, I assume that Modules
# were only *added* to the core list
# So it shouldn't matter if, for instance,
# B.pm wasn't included with version 5.0.

# However, if there are any modules that were
# added and removed from previous versions, please
# message me so I can update my code.

my $came_with_perl = {
              'AnyDBM_File' => 1,
              'Attribute::Handlers' => 1,
              'AutoLoader' => 1,
              'AutoSplit' => 1,
              'B' => 1,
              'B::Asmdata' => 1,
              'B::Assembler' => 1,
              'B::Bblock' => 1,
              'B::Bytecode' => 1,
              'B::C' => 1,
              'B::CC' => 1,
              'B::Concise' => 1,
              'B::Debug' => 1,
              'B::Deparse' => 1,
              'B::Disassembler' => 1,
              'B::Lint' => 1,
              'B::Showlex' => 1,
              'B::Stackobj' => 1,
              'B::Stash' => 1,
              'B::Terse' => 1,
              'B::Xref' => 1,
              'Benchmark' => 1,
              'ByteLoader' => 1,
              'CGI' => 1,
              'CGI::Apache' => 1,
              'CGI::Carp' => 1,
              'CGI::Cookie' => 1,
              'CGI::Fast' => 1,
              'CGI::Pretty' => 1,
              'CGI::Push' => 1,
              'CGI::Switch' => 1,
              'CGI::Util' => 1,
              'CPAN' => 1,
              'CPAN::FirstTime' => 1,
              'CPAN::Nox' => 1,
              'Carp' => 1,
              'Carp::Heavy' => 1,
              'Class::ISA' => 1,
              'Class::Struct' => 1,
              'Config' => 1,
              'Cwd' => 1,
              'DB' => 1,
              'DB_File' => 1,
              'Devel::SelfStubber' => 1,
              'Digest' => 1,
              'DirHandle' => 1,
              'Dumpvalue' => 1,
              'Encode' => 1,
              'English' => 1,
              'Env' => 1,
              'Errno' => 1,
              'Exporter' => 1,
              'Exporter::Heavy' => 1,
              'ExtUtils::Command' => 1,
              'ExtUtils::Command::MM' => 1,
              'ExtUtils::Constant' => 1,
              'ExtUtils::Embed' => 1,
              'ExtUtils::Install' => 1,
              'ExtUtils::Installed' => 1,
              'ExtUtils::Liblist' => 1,
              'ExtUtils::MM' => 1,
              'ExtUtils::MM_Any' => 1,
              'ExtUtils::MM_BeOS' => 1,
              'ExtUtils::MM_Cygwin' => 1,
              'ExtUtils::MM_DOS' => 1,
              'ExtUtils::MM_MacOS' => 1,
              'ExtUtils::MM_NW5' => 1,
              'ExtUtils::MM_OS2' => 1,
              'ExtUtils::MM_UWIN' => 1,
              'ExtUtils::MM_Unix' => 1,
              'ExtUtils::MM_VMS' => 1,
              'ExtUtils::MM_Win32' => 1,
              'ExtUtils::MM_Win95' => 1,
              'ExtUtils::MY' => 1,
              'ExtUtils::MakeMaker' => 1,
              'ExtUtils::Manifest' => 1,
              'ExtUtils::Mkbootstrap' => 1,
              'ExtUtils::Mksymlists' => 1,
              'ExtUtils::Packlist' => 1,
              'ExtUtils::testlib' => 1,
              'Fatal' => 1,
              'Fcntl' => 1,
              'File::Basename' => 1,
              'File::CheckTree' => 1,
              'File::Compare' => 1,
              'File::Copy' => 1,
              'File::DosGlob' => 1,
              'File::Find' => 1,
              'File::Path' => 1,
              'File::Spec' => 1,
              'File::Spec::Cygwin' => 1,
              'File::Spec::Epoc' => 1,
              'File::Spec::Functions' => 1,
              'File::Spec::Mac' => 1,
              'File::Spec::OS2' => 1,
              'File::Spec::Unix' => 1,
              'File::Spec::VMS' => 1,
              'File::Spec::Win32' => 1,
              'File::Temp' => 1,
              'File::stat' => 1,
              'FileCache' => 1,
              'FileHandle' => 1,
              'Filter::Simple' => 1,
              'FindBin' => 1,
              'Getopt::Long' => 1,
              'Getopt::Std' => 1,
              'Hash::Util' => 1,
              'I18N::Collate' => 1,
              'I18N::LangTags' => 1,
              'I18N::LangTags::List' => 1,
              'IO' => 1,
              'IPC::Open2' => 1,
              'IPC::Open3' => 1,
              'Locale::Constants' => 1,
              'Locale::Country' => 1,
              'Locale::Currency' => 1,
              'Locale::Language' => 1,
              'Locale::Maketext' => 1,
              'Locale::Maketext::TPJ13' => 1,
              'Locale::Script' => 1,
              'Math::BigFloat' => 1,
              'Math::BigInt' => 1,
              'Math::BigInt::Calc' => 1,
              'Math::BigRat' => 1,
              'Math::Complex' => 1,
              'Math::Trig' => 1,
              'Memoize' => 1,
              'Memoize::AnyDBM_File' => 1,
              'Memoize::Expire' => 1,
              'Memoize::ExpireFile' => 1,
              'Memoize::ExpireTest' => 1,
              'Memoize::NDBM_File' => 1,
              'Memoize::SDBM_File' => 1,
              'Memoize::Storable' => 1,
              'NDBM_File' => 1,
              'NEXT' => 1,
              'Net::Cmd' => 1,
              'Net::Config' => 1,
              'Net::Domain' => 1,
              'Net::FTP' => 1,
              'Net::NNTP' => 1,
              'Net::Netrc' => 1,
              'Net::POP3' => 1,
              'Net::Ping' => 1,
              'Net::SMTP' => 1,
              'Net::Time' => 1,
              'Net::hostent' => 1,
              'Net::libnetFAQ' => 1,
              'Net::netent' => 1,
              'Net::protoent' => 1,
              'Net::servent' => 1,
              'O' => 1,
              'ODBM_File' => 1,
              'Opcode' => 1,
              'POSIX' => 1,
              'PerlIO' => 1,
              'PerlIO::via::QuotedPrint' => 1,
              'Pod::Checker' => 1,
              'Pod::Find' => 1,
              'Pod::Functions' => 1,
              'Pod::Html' => 1,
              'Pod::InputObjects' => 1,
              'Pod::LaTeX' => 1,
              'Pod::Man' => 1,
              'Pod::ParseLink' => 1,
              'Pod::ParseUtils' => 1,
              'Pod::Parser' => 1,
              'Pod::Plainer' => 1,
              'Pod::Select' => 1,
              'Pod::Text' => 1,
              'Pod::Text::Color' => 1,
              'Pod::Text::Overstrike' => 1,
              'Pod::Text::Termcap' => 1,
              'Pod::Usage' => 1,
              'SDBM_File' => 1,
              'Safe' => 1,
              'Search::Dict' => 1,
              'SelectSaver' => 1,
              'SelfLoader' => 1,
              'Shell' => 1,
              'Socket' => 1,
              'Storable' => 1,
              'Switch' => 1,
              'Symbol' => 1,
              'Term::ANSIColor' => 1,
              'Term::Cap' => 1,
              'Term::Complete' => 1,
              'Term::ReadLine' => 1,
              'Test' => 1,
              'Test::Builder' => 1,
              'Test::Harness' => 1,
              'Test::Harness::Assert' => 1,
              'Test::Harness::Iterator' => 1,
              'Test::Harness::Straps' => 1,
              'Test::More' => 1,
              'Test::Simple' => 1,
              'Test::Tutorial' => 1,
              'Text::Abbrev' => 1,
              'Text::Balanced' => 1,
              'Text::ParseWords' => 1,
              'Text::Soundex' => 1,
              'Text::Tabs' => 1,
              'Text::Wrap' => 1,
              'Thread' => 1,
              'Thread::Queue' => 1,
              'Thread::Semaphore' => 1,
              'Tie::Array' => 1,
              'Tie::File' => 1,
              'Tie::Handle' => 1,
              'Tie::Hash' => 1,
              'Tie::Memoize' => 1,
              'Tie::RefHash' => 1,
              'Tie::Scalar' => 1,
              'Tie::SubstrHash' => 1,
              'Time::Local' => 1,
              'Time::gmtime' => 1,
              'Time::localtime' => 1,
              'Time::tm' => 1,
              'UNIVERSAL' => 1,
              'Unicode::Collate' => 1,
              'Unicode::UCD' => 1,
              'User::grent' => 1,
              'User::pwent' => 1,
              'Win32' => 1,
             };

find(\&main::wanted, @INC);

sub wanted {
  my $module_name = $_;
  # check whether or not we have a module
  return unless ($module_name =~ m/\.pm$/i);
  # get rid of the extension
  $module_name =~ s[\.pm$][]si;
  # now figure out the full name
  my $module_path = $File::Find::dir;
  foreach my $dir (@INC) {
    $module_path =~ s[^$dir][]s;
  }

  my @directories = split /\//, $module_path;
  while (@directories) {
    $module_name = pop (@directories) . "::$module_name";
  }

  # check whether to include it
  if ($came_with_perl->{$module_name}) {
    push @installed_modules, $module_name unless ($no_core);
  }
  else {
    push @installed_modules, $module_name unless ($no_user);
  }
}

while (@installed_modules) {
  my $module = shift (@installed_modules);
  print "$module\n";
}
Replies are listed 'Best First'.
Re: Search @INC And Display Modules
by kvale (Monsignor) on Apr 06, 2004 at 16:52 UTC
    You can get rid of that humongous hash def and deal with different perl versions by using Module::CoreList
    use Module::CoreList; print $Module::CoreList::version{5.00503}{CPAN}; # prints 1.48 my $came_with_perl = $Module::CoreList::version{5.00503};

    -Mark

      You can get rid of that humongous hash def and deal with different perl versions by using Module::CoreList

      Actually, I tried that, and ran into a couple of problems with it:

      1. Module::CoreList is not installed by default on all systems. This would mean I would either have to include it in my code or have people download and install it -- which makes it less of the autonomous program I wanted it to be. (For instance, not everyone has the rights to install modules on their servers).
      2. Module::CoreList is incomplete. I don't know if it's because my version of Perl isn't supported or if I was using it wrong, but I got many of the Modules from perlmodlib in the output.
      3. Module::CoreList contains a big hash like the one right there, except mine worked for what was needed.
      4. I didn't need hashes of all the modules for all versions of perl. A hash of all of the modules was sufficient because if it was installed, 10 to 1 it came with Perl
      5. After playing around with it for a couple minutes, I figured it would be much quicker to create a macro in Emacs to grab the modules from perldoc perlmodlib, and it was.
      6. I also contemplated ripping modules from perldoc perlmodlib so that I would be sure of having the right modules for that particular version of Perl. I decided against it because that assumed that perldoc was installed, that the user had access rights to it, and that all perlmodlib pages were formatted a certain way (i.e. I'd have to do some debugging on different versions of Perl to be sure -- which seemed like more trouble then it was worth).

      Want to support the EFF and FSF by buying cool stuff? Click here.
        In Tk::Pod::FindPods I just use the following subroutine to determine whether a module is a non-core module:
        sub is_site_module { my $path = shift; if ($^O eq 'MSWin32') { return $path =~ m|[/\\]site[/\\]lib[/\\]|; } $path =~ /^( \Q$Config{'installsitelib'}\E | \Q$Config{'installsitearch'}\E )/x; }

Log In?
Username:
Password:

What's my password?
Create A New User
Domain Nodelet?
Node Status?
node history
Node Type: sourcecode [id://342910]
help
Chatterbox?
and the web crawler heard nothing...

How do I use this?Last hourOther CB clients
Other Users?
Others chilling in the Monastery: (8)
As of 2024-03-28 21:39 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found