NAME

CPAN::PackageDetails - Create or read 02packages.details.txt.gz

SYNOPSIS

        use CPAN::PackageDetails;

        # read an existing file #####################
        my $package_details = CPAN::PackageDetails->read( $filename );
        
        my $count      = $package_details->count;
        
        my $records    = $package_details->entries;
        
        foreach my $record ( @$records )
                {
                # See CPAN::PackageDetails::Entry too
                print join "\t", map { $record->$_() } ('package name', 'version', 'path')
                print join "\t", map { $record->$_() } $package_details->columns_as_list;
                }
                
        # not yet implemented, but would be really, really cool eh?
        my $records    = $package_details->entries(
                logic   => 'OR',  # but that could be AND, which is the default
                package => qr/^Test::/, # or a string
                author  => 'OVID',      # case insenstive
                path    =>  qr/foo/,
                );
        
        # create a new file #####################
        my $package_details = CPAN::PackageDetails->new( 
                file         => "02packages.details.txt",
                url          => "http://example.com/MyCPAN/modules/02packages.details.txt",
                description  => "Package names for my private CPAN",
                columns      => "package name, version, path",
                intended_for => "My private CPAN",
                written_by   => "$0 using CPAN::PackageDetails $CPAN::PackageDetails::VERSION",
                last_updated => CPAN::PackageDetails->format_date,
                allow_packages_only_once => 1,
                );

        $package_details->add_entry(
                package_name => $package,
                version      => $package->VERSION;
                path         => $path,
                );
                
        print "About to write ", $package_details->count, " entries\n";
        
        $package_details->write_file( $file );
        
        $package_details->write_fh( \*STDOUT )
        

DESCRIPTION

CPAN uses an index file, 02packages.details.txt.gz, to map package names to distribution files. Using this module, you can get a data structure of that file, or create your own.

There are two parts to the 02packages.details.txt.gz: a header and the index. This module uses a top-level CPAN::PackageDetails object to control everything and comprise an CPAN::PackageDetails::Header and CPAN::PackageDetails::Entries object. The CPAN::PackageDetails::Entries object is a collection of CPAN::PackageDetails::Entry objects.

For the most common uses, you don't need to worry about the insides of what class is doing what. You'll call most of the methods on the top-level CPAN::PackageDetails object and it will make sure that it gets to the right place.

Methods in CPAN::PackageDetails.

These methods are in the top-level object, and there are more methods for this class in the sections that cover the Header, Entries, and Entry objects.

new

Create a new 02packages.details.txt.gz file. The default_headers method shows you which values you can pass to new. For instance:

        my $package_details = CPAN::PackageDetails->new(
                url     => $url,
                columns => 'author, package name, version, path',
                )

If you specify the allow_packages_only_once option with a true value and you try to add that package twice, the object will die. See add_entry.

init

Sets up the object. new calls this automatically for you.

default_headers

Returns the hash of header fields and their default values:

        file            "02packages.details.txt"
        url             "http://example.com/MyCPAN/modules/02packages.details.txt"
        description     "Package names for my private CPAN"
        columns         "package name, version, path"
        intended_for    "My private CPAN"
        written_by      "$0 using CPAN::PackageDetails $CPAN::PackageDetails::VERSION"
        last_updated    format_date()

In the header, these fields show up with the underscores turned into hyphens, and the letters at the beginning or after a hyphen are uppercase.

format_date

Write the date in PAUSE format. For example:

        Thu, 23 Oct 2008 02:27:36 GMT
        
read( FILE )

Read an existing 02packages.details.txt.gz file.

While parsing, it modifies the field names to map them to Perly identifiers. The field is lowercased, and then hyphens become underscores. For instance:

        Written-By ---> written_by
        
source_file

Returns the original file path for objects created through the read method.

write_file( OUTPUT_FILE )

Formats the object as a string and writes it to the file named in OUTPUT_FILE. It gzips the output.

write_file carps and returns nothing if you pass it no arguments or it cannot open OUTPUT_FILE for writing.

write_fh( FILEHANDLE )

Formats the object as a string and writes it to FILEHANDLE

Headers

The 02packages.details.txt.gz header is a short preamble that give information about the creation of the file, its intended use, and the number of entries in the file. It looks something like:

        File:         02packages.details.txt
        URL:          http://www.perl.com/CPAN/modules/02packages.details.txt
        Description:  Package names found in directory $CPAN/authors/id/
        Columns:      package name, version, path
        Intended-For: Automated fetch routines, namespace documentation.
        Written-By:   Id: mldistwatch.pm 1063 2008-09-23 05:23:57Z k 
        Line-Count:   59754
        Last-Updated: Thu, 23 Oct 2008 02:27:36 GMT

Note that there is a Columns field. This module tries to respect the ordering of columns in there. The usual CPAN tools expect only three columns and in the order in this example, but CPAN::PackageDetails tries to handle any number of columns in any order.

Methods in CPAN::PackageDetails

header_class

Returns the class that CPAN::PackageDetails uses to create the header object.

Returns the header object.

Methods in CPAN::PackageDetails::Header

new( HASH )

Create a new Header object. Unless you want a lot of work so you get more control, just let CPAN::PackageDetails's new or read handle this for you.

In most cases, you'll want to create the Entries object first then pass a reference the the Entries object to new since the header object needs to know how to get the count of the number of entries so it can put it in the "Line-Count" header.

        CPAN::PackageDetails::Header->new(
                _entries => $entries_object,
                )
set_header

Add an entry to the collection. Call this on the CPAN::PackageDetails object and it will take care of finding the right handler.

header_exists( FIELD )

Returns true if the header has a field named FIELD, regardless of its value.

get_header( FIELD )

Returns the value for the named header FIELD. Carps and returns nothing if the named header is not in the object. This method is available from the CPAN::PackageDetails or CPAN::PackageDetails::Header object:

        $package_details->get_header( 'url' );
        
        $package_details->header->get_header( 'url' );
        

The header names in the Perl code are in a different format than they are in the file. See default_headers for an explanation of the difference.

For most headers, you can also use the header name as the method name:

        $package_details->header->url;
columns_as_list

Returns the columns name as a list (rather than a comma-joined string). The list is in the order of the columns in the output.

as_string

Return the header formatted as a string.

Entries

Entries are the collection of the items describing the package details. It comprises all of the Entry object.

Methods is CPAN::PackageDetails

entries_class

Returns the class to use for the Entries object.

To use a different Entries class, tell new which class you want to use by passing the entries_class option:

        CPAN::PackageDetails->new(
                ...,
                entries_class => $class,
                );

Note that you are responsible for loading the right class yourself.

count

Returns the number of entries.

This dispatches to the count in CPAN::PackageDetails::Entries. These are the same:

        $package_details->count;
        
        $package_details->entries->count;
entries

Returns the entries object.

Methods in CPAN::PackageDetails::Entries

new

Creates a new Entries object. This doesn't do anything fancy. To add to it, use add_entry.

        entry_class => the class to use for each entry object
        columns     => the column names, in order that you want them in the output

If you specify the allow_packages_only_once option with a true value and you try to add that package twice, the object will die. See add_entry.

entry_class

Returns the class that Entries uses to make a new Entry object.

columns
count

Returns the number of entries. This is not the same as the number of lines that would show up in the 02packages.details.txt file since this method counts duplicates as well.

entries

Returns the Entries object.

allow_packages_only_once( [ARG] )
add_entry

Add an entry to the collection. Call this on the CPAN::PackageDetails object and it will take care of finding the right handler.

If you've set allow_packages_only_once to a true value (which is the default, too), add_entry will die if you try to add another entry with the same package name even if it has a different or greater version. You can set this to a false value and add as many entries as you like then use as_unqiue_sorted_list to get just the entries with the highest versions for each package.

already_added( PACKAGE )

Returns true if there is already an entry for PACKAGE.

as_string

Returns a text version of the Entries object. This calls as_string on each Entry object, and concatenates the results for all Entry objects.

as_unique_sorted_list

In list context, this returns a list of entries sorted by package name and version. Each package exists exactly once in the list and with the largest version number seen.

In scalar context this returns the count of the number of unique entries.

Once called, it caches its result until you add more entries.

Entry

An entry is a single line from 02packages.details.txt that maps a package name to a source. It's a whitespace-separated list that has the values for the column identified in the "columns" field in the header.

By default, there are three columns: package name, version, and path.

Inside a CPAN::PackageDetails object, the actual work and manipulation of the entries are handled by delegate classes specified in entries_class and entry_class). At the moment these are immutable, so you'd have to subclass this module to change them.

Methods is CPAN::PackageDetails

entry_class

Returns the class to use for each Entry object.

To use a different Entry class, tell new which class you want to use by passing the entry_class option:

        CPAN::PackageDetails->new(
                ...,
                entry_class => $class,
                )

Note that you are responsible for loading the right class yourself.

Methods in CPAN::PackageDetails::Entry

new( FIELD1 => VALUE1 [, FIELD2 => VALUE2] )

Create a new entry

as_string( @column_names )

Formats the Entry as text. It joins with whitespace the values for the column names you pass it. You get the newline automatically.

Any values that are not defined (or the empty string) turn into the literal string 'undef' to preserve the columns in the output.

TO DO

SEE ALSO

SOURCE AVAILABILITY

This source is in Github:

        http://github.com/briandfoy/cpan-packagedetails
        

AUTHOR

brian d foy, <bdfoy@cpan.org>

COPYRIGHT AND LICENSE

Copyright (c) 2009, brian d foy, All Rights Reserved.

You may redistribute this under the same terms as Perl itself.