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->get_hash;

        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,
                disallow_alpha_versions  => 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 );

         # OR ...

        $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

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 in CPAN::PackageDetails::Entries.

If you specify the disallow_alpha_versions option with a true value and you try to add that package twice, the object will die. See add_entry in CPAN::PackageDetails::Entries.

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.

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 a temporary file and gzips the output. When everything is complete, it renames the temporary file to its final name.

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

write_fh( FILEHANDLE )

Formats the object as a string and writes it to FILEHANDLE

check_file( FILE, CPAN_PATH )

This method takes an existing 02packages.details.txt.gz named in FILE and the CPAN root at CPAN_PATH (to append to the relative paths in the index), then checks the file for several things:

        1. That there are entries in the file
        2. The number of entries matches those declared in the Line-Count header
        3. All paths listed in the file exist under CPAN_PATH
        4. All distributions under CPAN_PATH have an entry (not counting older versions)

If any of these checks fail, check_file croaks with a hash reference with these keys:

        # present in every error object
        filename                the FILE you passed in
        cpan_path               the CPAN_PATH you passed in
        cwd                     the current working directory
        error_count

        # if FILE is missing
        missing_file          exists and true if FILE doesn't exist

        # if the entry count in the file is wrong
        # that is, the actual line count and header disagree
        entry_count_mismatch    true
        line_count              the line count declared in the header
        entry_count             the actual count

        # if some distros in CPAN_HOME are missing in FILE
        missing_in_file         anonymous array of missing paths

        # if some entries in FILE are missing the file in CPAN_HOME
        missing_in_repo         anonymous array of missing paths
check_for_missing_dists_in_repo( CPAN_PATH )

Given an object and a CPAN_PATH, return an anonymous array of the distributions in the object that are not in CPAN_PATH. That is, complain when the object has extra distributions.

check_file calls this for you and adds the result to its error output.

check_for_missing_dists_in_file( CPAN_PATH )

Given an object and a CPAN_PATH, return an anonymous array of the distributions in CPAN_PATH that do not show up in the object. That is, complain when the object doesn't have all the dists.

check_file calls this for you and adds the result to its error output.

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

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.

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.

TO DO

SEE ALSO

SOURCE AVAILABILITY

This source is in Github:

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

AUTHOR

brian d foy, <briandfoy@pobox.com>

COPYRIGHT AND LICENSE

Copyright © 2009-2024, brian d foy <briandfoy@pobox.com>. All rights reserved.

You may redistribute this under the terms of the Artistic License 2.0.