Module::Dependency Documentation
------------------ -------------

Perl Modules
---- -------

This readme should give you an idea of what the modules actually do in this
distribution. See the README.COMMANDS file for information on the commands
supplied for your convenience, and the README file for an overview.

Module::Dependency::Indexer
---------------------------

This module takes care of creating the database file.

Module::Dependency::Grapher
---------------------------

Uses GD to plot graphical dependency information. Can also produce simple
plain text output, PostScript, SVG, or HTML fragment output.

Module::Dependency::Info
------------------------

This module is used as the interface to query the database and get 
information out.


POD DOCUMENTATION FOLLOWS
-------------------------------------------------------------------------


NAME
    Module::Dependency::Grapher - creates visual dependency charts and
    accessible text versions

SYNOPSIS
            use Module::Dependency::Grapher;
            Module::Dependency::Grapher::setIndex( '/var/tmp/dependence/unified.dat' );
            Module::Dependency::Grapher::makeImage( 'both', ['Foo::Bar', 'Foo::Baz'], '/home/www/foodep.png', {Format => 'png'} );
            Module::Dependency::Grapher::makePs( 'both', ['Foo::Bar', 'Foo::Baz'], '/home/www/foodep.eps' );
            Module::Dependency::Grapher::makeText( 'both', ['Foo::Bar', 'Foo::Baz'], '/home/www/foodep.txt', {NoLegend => 1} );
            Module::Dependency::Grapher::makeHtml( 'both', ['Foo::Bar', 'Foo::Baz'], '/home/www/foodep.ssi', {NoLegend => 1} );

DESCRIPTION
    Module::Dependency::Grapher::setIndex( $filename );
        This tells the module where the database is. It doesn't affect the
        other modules - they have their own setIndex routines. The default
        is /var/tmp/dependence/unified.dat

    Module::Dependency::Grapher::makeImage( $kind, $seeds, $filename,
    $options );
        Draws an image showing the dependency links between a set of items.
        The 'tree' of dependencies is started at the item or items named in
        the $seeds array reference. The code then links to all the parent
        and/or child dependencies of those seeds. And repeat for those
        items, etc.

        $kind is 'parent', 'child' or 'both'. This parameter tells the code
        whether to plot (respectively) things that depend upon the seed
        items, things that the seed items depend upon, or both directions.

        $seeds is a reference to an array of item names

        $filename is the file to which the output should go. Use '-' for
        STDOUT. Clobbers existing files.

        See below for the options. See README.EXAMPLES too.

    Module::Dependency::Grapher::makePs( $kind, $seeds, $filename, $options
    );
        As makeImage() but does it in PostScript or EPS. EPS is the default.
        See below for the options. See README.EXAMPLES too.

    Module::Dependency::Grapher::makeSvg( $kind, $seeds, $filename, $options
    );
        As makeImage() but does it in SVG. See below for the options. See
        README.EXAMPLES too.

    Module::Dependency::Grapher::makeText( $kind, $seeds, $filename,
    $options );
        Creates a plain-text rendition of the dependency heirarchy. As it's
        only ASCII it can't plot the individual links between items, so it
        simplifies and presents only each level of the tree as a whole.

        Parameters are as for makeImage()

        See below for options. See README.EXAMPLES too.

    Module::Dependency::Grapher::makeHtml( $kind, $seeds, $filename,
    $options );
        Creates an HTML fragment rendition of the dependency heirarchy. As
        it's only text it can't plot the individual links between items, so
        it simplifies and presents only each level of the tree. Information
        comes out in a table, and the whole fragment uses CLASS attributes
        so that you can apply CSS to it. Typical fragment is:

                <div class="MDGraph"><h2>Dependencies for all scripts</h2>
                <h4>Grapher.pm 1.7 - Fri Jan 11 00:00:56 2002</h4>
                Key:<br />Parent indicates parent dependencies<br />
                        **** indicates the item(s) from which the relationships are drawn<br />
                    Child are child dependencies<br />

                <table class="MDGraphTable">
                <tr><th>Kind</th><th>Items</th></tr>
                <tr><td class="MDGraphSeed">****</td><td class="MDGraphSeed">x.pl, y.pl</td></tr>
                <tr><td class="MDGraphChild">Child</td><td class="MDGraphChild">a, b, c</td></tr>
                </table>
                </div>

        Parameters are as for makeImage().

        See below for options - especially the ImageMap (and related)
        options, which allows this method to return an HTML client-side
        imagemap. See README.EXAMPLES too.

  OPTIONS

    Options are case-sensitive, and you pass them in as a hash reference,
    e.g.

            Module::Dependency::Grapher::makeImage( $kind, $objlist, $IMGFILE, {Title => $title, Format => 'GIF'} );

    These are the recognized options:

    Title
        Sets the title of the output to whatever string you want. Displayed
        at the top.

    Format
        The output image format - can be (case-insensitive) GIF, PNG, GD, or
        JPG - but some may not be available depending on how your local copy
        of libgd was compiled. You'll need to examine you local GD setup
        (PNG is pretty standard thesedays though) Default is PNG.

        The makePs() method recognizes only 'EPS' or 'PS' as format options.
        Default is 'EPS'.

    IncludeRegex
        A regular expression use to filter the items displayed. If this is
        '::' for example then the output will only show dependencies that
        contain those characters.

    ExcludeRegex
        A regular expression use to filter the items displayed. If this is
        '::' for example then the output will not show dependencies that
        contain those characters.

    NoLegend
        If true, don't print the 'legend' box/text

    NoVersion
        If true, don't print the version/date line.

    Colour
        Used by makePs() only - if 1 it makes a colour image, if 0 it makes
        a greyscale image. Default is 1.

    Font
        sed by makePs() only. Set the font used in the drawing. Default is
        'Helvetica'.

    ImageMap
        Used by makeHtml() only - if set to 'print' it will print a skeleton
        imagemap to the output file; if set to 'return' then the imagemap
        text is the return value of makeHtml() so that the caller can
        process the string further.

        An imagemap looks like this example, but you can change the href
        attributes using the HrefFormat option (see below) so that they
        match what your CGI program is expecting.

                <map name="dependence">
                <!-- PACK a --><area href="" shape="rect" coords="217,110,229,122" alt="Root dependency tree on a" title="Root dependency tree on a">
                <!-- PACK x.pl --><area href="" shape="rect" coords="17,110,44,122" alt="Root dependency tree on x.pl" title="Root dependency tree on x.pl">
                </map>

        If you want to totally change the format of each 'area' element see
        the ImageMapCode option below.

        Note that the href attributes are deliberately left empty, for users
        of the 'return' method to easily post-process the string. The PACK
        comment at the start of each line is provided to tell you what the
        package or scriptname is. The imagemap corresponds to the image that
        _would_ be produced by makeImage() if it were given the same
        arguments.

        See the bundled 'cgidepend.plx' CGI program to see a use for this
        imagemap.

    ImageMapCode
        Used by makeHtml() only - must be a code reference. Called once for
        each 'area' required. The first argument is the package name that
        the 'area' corresponds to, 'Foo::Bar' or 'baz.pl' for example. The
        second argument is the current HrefFormat setting, but you may
        ignore that, seeing as you're going to be writing the entire
        element. The default coderef creates the 'area' elements as shown
        above and respects the HrefFormat option.

    HrefFormat
        Used by makeHtml() and makeSvg() only - default is ''. A sprintf()
        formatting string used to format the 'href' attribute in EACH 'area'
        element of the imagemap, or the href of the anchors in SVG output.
        E.g. '?myparam=%s' would create an href of '?myparam=Foo'.

        If empty (as is the default) then you get no clickable links in the
        SVG output.

PREREQUISITES
    If you want to use the makePs() method you'll need PostScript::Simple
    installed. If you want to use the makeImage() method you'll need GD
    installed. If you want to use the makeSvg() method you'll need the SVG
    module. However, these modules are 'require'd as needed so you can quite
    happily use the makeText and makeHtml routines.

SEE ALSO
    Module::Dependency and the README files.

VERSION
    $Id: README.MODULES,v 1.10 2002/09/25 23:07:31 piers Exp $

NAME
    Module::Dependency::Indexer - creates the databases used by the
    dependency mapping module

SYNOPSIS
            use Module::Dependency::Indexer;
            Module::Dependency::Indexer::setIndex( '/var/tmp/dependency/unified.dat' );
            Module::Dependency::Indexer::makeIndex( $directory, [ $another, $andanother... ] );
            Module::Dependency::Indexer::setShebangCheck( 0 );

DESCRIPTION
    This module looks at all .pm, .pl and .plx files within and below a
    given directory/directories (found with File::Find), reads through them
    and extracts some information about them. If the shebang check is turned
    on then it also looks at the first line of all other files, to see if
    they're perl programs too. We extract this information:

    *   The name of the package (e.g. 'Foo::Bar') or the name of the script
        (e.g. 'chat.pl')

    *   The full filesystem location of the file.

    *   The dependencies of the file - i.e. the packages that it 'use's or
        'require's

    *   The reverse dependencies - i.e. what other scripts and modules THAT
        IT HAS INDEXED use or require the file. It can't, of course, know
        about 'use' statements in files it hasn't examined.

    When it has extracted all this information it uses Storable to write the
    data to disk in the indexfile location.

    This search is quite an expensive operation, taking around 10 seconds
    for the site_perl directory here. However once the information has been
    gathered it's extremely fast to use.

FUNCTIONS
    setIndex( $filename )
        This function tells the module where to write out the datafile. You
        can set this, make an index of some directory of perl stuff, set it
        to something else, index a different folder, etc., in order to build
        up many indices. This only affects this module - you need to tell
        ...::Info where to look for datafiles independently of this module.

        Default is /var/tmp/dependence/unified.dat

    makeIndex( $directory, [ $another, $andanother... ] )
        Builds, and stores to the current data file, a SINGLE database for
        all the files found under all of the supplied directories. To create
        multiple indexes, run this method many times with a setIndex
        inbetween each so that you don't clobber the previous run's
        datafile.

    setShebangCheck( BOOLEAN )
        Turns on or off the checking of #! lines for all files that are not
        .pl, .plx or .pm filenames. By default we do check the #! lines.

NOTE ABOUT WHAT IS INDEXED
    A database entry is made for each file scanned. This makes the generally
    good assumption that a .pl file is a script that is not use/required by
    anything else, and a .pm file is a package file which may be
    use/required by many other files. Database entries ARE NOT made just
    because a file is use/required - hence the database will not contain an
    entry for 'strict' or 'File::Find' (for example) unless you explicitly
    index your perl's lib/ folder.

    E.g., if 'Local::Foo.pm' uses strict and File::Find and we index it, its
    entry in the database will show that it depends on strict and
    File::Find, as you'd expect. It's just that we won't create an entry for
    'strict' on that basis alone.

    In practice this behaviour is what you want - you want to see how the
    mass of perl in your cgi-bin and site_perl folders fits together (for
    example), or maybe just a single project in CVS. You may of course
    include your perl lib directory in the database should you want to see
    the dependencies involving the standard modules, but generally that's
    not relevant.

USE OF THE DATA
    Now you've got a datafile which links all the scripts and modules in a
    set of directories. Use ...::Info to get at the data. Note that the data
    is stored using Storable's nstore method which _should_ make these
    indexes portable across platforms. Not tested though.

ADVICE, GETTING AT DATA
    As Storable is so fast, you may want to make one big index of all
    folders where perl things are. Then you can load this datafile back up,
    extract the entry for, say, Local::Foo and examine its dependencies (and
    reverse dependencies). Based on what you find, you can get the entries
    for Local::Foo::Bar and Local::Foo::Baz (things used by Local::Foo) or
    perhaps Local::Stuff (which uses Local::Foo). Then you can examine those
    records, etc. This is how ...::Grapher builds the tree of dependencies,
    basically.

    You use Module::Dependency::Info to get at these records using a nice
    simple API. If you're feeling keen you can just grab the entire object -
    but that's in the ...::Info module.

    Here we have a single index for all our local perl code, and that lives
    in /var/tmp/dependence/unified.dat - the default location. Other
    applications just use that file.

DEBUGGING
    There is a TRACE stub function, and the module uses TRACE() to log
    activity. Override our TRACE with your own routine, e.g. one that prints
    to STDERR, to see these messages.

SEE ALSO
    Module::Dependency and the README files.

VERSION
    $Id: README.MODULES,v 1.10 2002/09/25 23:07:31 piers Exp $

NAME
    Module::Dependency::Info - retrieve dependency information for scripts
    and modules

SYNOPSIS
            use Module::Dependency::Info;
            Module::Dependency::Info::setIndex( '/var/tmp/dependence/unified.dat' );
        
            # load the index (actually it's loaded automatically if needed so this is optional)
            Module::Dependency::Info::retrieveIndex();
            # or
            $refToEntireDatabase = Module::Dependency::Info::retrieveIndex();
        
            $listref = Module::Dependency::Info::allItems();
            $listref = Module::Dependency::Info::allScripts();
        
            # note the syntax here - the name of perl scripts, but the package name of modules.
            $dependencyInfo = Module::Dependency::Info::getItem( 'Foo::Bar' [, $forceReload ] );
            # and
            $dependencyInfo = Module::Dependency::Info::getItem( 'blahblah.pl' [, $forceReload ] );
        
            $filename = Module::Dependency::Info::getFilename( 'Foo::Bar' [, $forceReload ] );
            $listref = Module::Dependency::Info::getChildren( $node [, $forceReload ] );
            $listref = Module::Dependency::Info::getParents( $node [, $forceReload ] );
        
            $value = Module::Dependency::Info::relationship( 'Foo::Bar', 'strict' );
        
            Module::Dependency::Info::dropIndex();

DESCRIPTION
    This module is used to access the data structures created by
    Module::Dependency::Indexer OR a third-party application that creates
    databases of the correct format. Although you can get at the database
    structure itself you should use the accessor methods.

METHODS
    setIndex( $filename );
        This tells the module where the database is. It doesn't affect the
        ...::Indexer module - that has its own setIndex routine. The default
        is /var/tmp/dependence/unified.dat

    retrieveIndex();
        Loads the database into memory. You only have to do this once -
        after that it's there in RAM ready for use. This routine is called
        automatically if needed anyway. Incidentally it returns a reference
        to the entire data structure, but don't use it directly, use this...

    $listref = Module::Dependency::Info::allItems();
        Returns a reference to an array of all the items in the currently
        loaded datafile. The order is whatever keys() gives us. The entries
        in the array are things like 'foo.pl' and 'Bar::Baz'.

    $listref = Module::Dependency::Info::allScripts();
        Returns a reference ot an array of all the scripts in the currently
        loaded datafile. The order is whatever it is in the datafile.

    $record = Module::Dependency::Info::getItem( $name [, $forceReload ] );
        Returns entire record for the thing you name, or undef if no such
        entry can be found (remember modules are referred to like 'Foo::Bar'
        whereas scripts like 'foo.pl'). Implicity loads the datafile from
        disk, using the current setting of the data location, if it isn't
        loaded. Pass in a 1 as the second argument if you want to force a
        reload - this may be relevant in long-lived perl processes like
        mod_perl, but only do it when you need to, like every 10 minutes or
        whatever makes sense for your application.

    $filename = Module::Dependency::Info::getFilename( $node [, $forceReload
    ] );
        Gets the full filename for the package/script named, or undef if no
        record could be found.

    $listref = Module::Dependency::Info::getChildren( $node [, $forceReload
    ] );
        Gets a list of all dependencies, i.e. packages that this item
        depends on, for the package/script named, or undef if no record
        could be found.

    $listref = Module::Dependency::Info::getParents( $node [, $forceReload ]
    );
        Gets a list of all reverse dependencies, i.e. packages that depend
        upon this item, for the package/script named, or undef if no record
        could be found.

    $value = Module::Dependency::Info::relationship( $itemName, $otherItem
    );
        Tells you whether, according to the current database, $itemName is
        related to $otherItem. $itemName is a module or script in the
        database (i.e. it's a file that has been indexed). Return values
        are:

        undef if $itemName is not in the database

        'NONE' if no link can be found (may be a false negative if links
        between the 2 items are not in the index)

        'PARENT' if the $otherItem depends upon $itemName

        'CHILD' if $itemName depends upon $otherItem

        'CIRCULAR' if $otherItem is both 'PARENT' and 'CHILD'.

    dropIndex
        drops the current database - you generally have no need to do this
        unless you're trying to save memory. Usually all you need to do is
        setIndex followed by a retrieveIndex, get* or all* function.

DATA RECORDS
    The database contains a list of all scripts (.pl and .plx files)
    encountered. We treat these as special because they form the 'top' of
    the dependency tree - they 'use' things, but they are not 'use'd
    themselves. It's just an array of all their nodenames (the filename,
    excluding the path to the file, e.g. 'foo.pl').

    The main bit is a hash. The keys of the hash are one of two things: a)
    keys to module records are the name of the package, e.g. 'Foo::Bar'; b)
    keys to script records are the nodename of the file, e.g. 'foo.pl'.

    A data records looks like the right-hand half of these:

            # lots of Data::Dumper output snipped
            'IFL::Beasts::Evol::RendererUtils' => {
                    'filename' => '/home/system/cgi-bin/lib/IFL/Beasts/Evol/RendererUtils.pm',
                    'package' => 'IFL::Beasts::Evol::RendererUtils',
                    'depended_upon_by' => [
                            'IFL::Beasts::Evol::TextSkin',
                            'IFL::Beasts::Evol::HTMLSkin'
                    ],
                    'depends_on' => [
                            'lib',
                            'Exporter',
                            'Carp',
                            'IFL::Beasts::Evol::LanguageUtils',
                            'IFL::Beasts::Evol::MathUtils',
                            'EDUtemplate'
                    ]
            },
            # lots of Data::Dumper output snipped

    Or like this, for a script file:

            # lots of Data::Dumper output snipped
            'csv_validator.pl' => {
                    'filename' => '/home/system/cgi-bin/education/user_reg/csv_validator.pl',
                    'package' => 'csv_validator.pl',
                    'depends_on' => [
                            'CGI',
                            'EDUprofile',
                            'LWP::Simple',
                            'File::Find'
                    ]
            },
            # lots of Data::Dumper output snipped

    But of course you should use the accessor methods to get at the
    information.

DEBUGGING
    There is a TRACE stub function, and the module uses TRACE() to log
    activity. Override our TRACE with your own routine, e.g. one that prints
    to STDERR, to see these messages.

SEE ALSO
    Module::Dependency and the README files.

VERSION
    $Id: README.MODULES,v 1.10 2002/09/25 23:07:31 piers Exp $

