Name

WWW::PGXN::Distribution - Distribution metadata fetched from PGXN

Synopsis

my $pgxn = WWW::PGXN->new( url => 'https://api.pgxn.org/' );
my $dist = $pgxn->get_distribution('pgTAP');
$dist->download_to('.');

Description

This module represents PGXN distribution metadata fetched from PGXN>. It is not intended to be constructed directly, but via the "get_distribution" in WWW::PGXN method of WWW::PGXN.

Interface

Instance Accessors

name

my $name = $distribution->name;
$distribution->name($name);

The name of the distribution.

version

my $version = $distribution->version;
$distribution->version($version);

The distribution version distribution. Returned as a string, but may be passed to SemVer for comparing versions.

use SemVer;
my $version = SemVer->new( $distribution->version );

This interface may be modified in the future to return a SemVer object itself.

abstract

my $abstract = $distribution->abstract;
$distribution->abstract($abstract);

The abstract for the distribution, a very brief description.

license

my $license = $distribution->license;
$distribution->license($license);

The license for the distribution, usually a simple string such as "gpl_3" or "postgresql". See the PGXN Meta spec for details.

user

my $user = $distribution->user;
$distribution->user($user);

The nickname of the user who released the distribution. Use the "get_user" in WWW::PGXN method of WWW::PGXN to get more info on the user:

my $user = $pgxn->get_user( $distribution->user );
say "Released by ", $user->name, ' <', $user->email, '>';

description

my $description = $distribution->description;
$distribution->description($description);

The distribution description, longer than the abstract.

generated_by

my $generated_by = $distribution->generated_by;
$distribution->generated_by($generated_by);

The name of the person or application that generated the metadata from which this distribution object is created.

date

my $date = $distribution->date;
$distribution->date($date);

The date the distribution was released on PGXN. Represented as a string in strict ISO-8601 format and in the UTC time zone. It may be parsed into a DateTime object like so:

use DateTime::Format::Strptime;
my $parser = DateTime::Format::Strptime->new(
    pattern   => '%FT%T',
    time_zone => 'Z'
);
my $date = $parser->parse_datetime( '2010-10-29T22:46:45Z' );

This interface may be modified in the future to return a DateTime object itself.

release_status

my $release_status = $distribution->release_status;
$distribution->release_status($release_status);

The release_status of the distribution. Should be one of:

stable
testing
unstable

sha1

my $sha1 = $distribution->sha1;
$distribution->sha1($sha1);

The SHA-1 digest for the distribution. You can validate the distribution file like so:

use Digest::SHA1;
my $file = $distribution->download_to('.');
open my $fh, '<:raw', $file or die "Cannot open $file: $!\n";
my $sha1 = Digest::SHA1->new;
$sha1->addfile($fh);
warn $distribution->name . ' ' . $distribution->version
    . ' does not validate against SHA1'
    unless $sha1->hexdigest eq $distribution->sha1;

Instance Methods

maintainers

my @maintainers = $distribution->maintainers;

Returns a list of the maintainers of the module. By the recommendation of the PGXN Meta spec, each should be formatted with a name and email address suitable for on the recipient line of an email.

special_files

my @special_files = $distribution->special_files;

Returns a list of special files in the distribution, such as Changes, README, Makefile, and META.json, among others. Available only from an API server. Returns an empty list for distributions fetched from a mirror.

docs

my $docs = $distribution->docs;

Returns a hash reference describing the documentation in the distribution. The keys are paths to documentation files, and the values are hashes with at least one key, title which contains the title, of course. A second key, abstract, is optional and contains an abstract of the document. The documentation files are stored as HTML and may be fetched via body_for_html_doc().

no_index

my $no_index = $distribution->no_index;

Returns a hash reference describing files and directories that should not be indexed by search engines or the PGXN infrastructure. The PGXN Meta spec specifies that the structure of this hash contain only these keys:

file

An array of file names.

directory

An array of directory names.

The returned has will be empty if all files may be indexed.

prereqs

my $prereqs = $distribution->prereqs;

Returns a hash reference describing the prerequisites of the extension. The PGXN Meta spec dictates That the top level keys of this hash may be any of:

configure
build
test
runtime
develop

The value for each of these keys must be a hash reference describing the prerequisites for that part of the extension lifecycle. The keys in this secondary hash may be any of:

requires
recommends
suggests

Each of these in turn points to another hash reference, the keys of which are the names of the prerequisite extensions and the values are their minimum required version numbers. See the Prereq Spec for further explication of these phases and relationships. Here's an example of what a typical prereqs hash might look like:

{
  prereqs => {
    runtime => {
      requires => {
        PostgreSQL => '8.0.0',
        PostGIS    => '1.5.0'
      },
      recommends => {
        PostgreSQL => '8.4.0'
      },
      suggests => {
        semver => 0
      },
    },
    build => {
      requires => {
        prefix => 0
      },
    },
    test => {
      recommends => {
        pgTAP   => 0
      },
    }
  }
}

provides

my $provides = $distribution->provides;

Returns a hash reference describing the resources provided by the distribution. The keys are the names of the resources (generally extension names) and their values are hash references describing them. The keys available in these hashes include:

file

The name of the file in which the resource is defined.

version

The semantic version of the resource.

abstract

A brief description of the resource.

docfile

A path to the documentation file for the resource, if any.

docpath

A path to the documentation for the resource, usually the same as docfile but without the file name extension. So if docfile is docs/pair.txt, docpath would be docs/pair. Provided only by the API server. May be present even if docfile is not, since the API might have found the documentation even if the release manager didn't specify it in the META.json.

Here's an example of the structure for a simple distribution that provides a single extension:

{
   pair => {
      abstract => 'A key/value pair data type',
      file     => 'sql/pair.sql',
      version  => '0.1.1',
      docfile  => 'doc/pair.md',
      docpath  => 'doc/pair',
   }
}

See the <spec|https://pgxn.org/meta/spec.html#provides> for more information.

releases

my $releases = $distribution->releases;

Returns a hash reference providing version and date information for all releases of the distribution. The hash reference must have one or more of the following keys:

stable
testing
unstable

An array reference containing hashes of versions and release dates of all releases of the distribution with the named release status, ordered from most to least recent.

Here's an example of the releases data structure:

{
    stable => [
        { version => '0.1.1', date => '2010-10-22T16:32:52Z' },
        { version => '0.1.0', date => '2010-10-19T03:59:54Z' }
    ],
    testing => [
        { version => '0.0.1', date => '2010-09-23T14:23:52Z' }
    ]
}

resources

my $resources = $distribution->resources;

Returns a hash reference describing the resources for the distribution. These include source code repository information, bug reporting addresses, and the like. Example:

{
   bugtracker => {
      web => 'https://github.com/theory/kv-pair/issues/'
   },
   repository => {
      type => 'git',
      url  => 'git://github.com/theory/kv-pair.git',
      web  => 'https://github.com/theory/kv-pair/'
   },
}

Read the Resources section of the meta spec for all the details.

tags

my @tags = $distribution->tags;

Returns a list of the tags associated with the distribution. Each may be used to look up further information about the tag via WWW::PGXN::Tag objects like so:

for my $tag ( map { $pgxn->get_tag($_) } $distribution->tags ) {
    say $tag->name;
}

download_url

my $url = $distribution->download_url;

The absolute URL for the distribution archive file on the mirror or API sever, such as

https://api.pgxn.org/dist/pair/pair-0.1.1.zip

Or, for a file system URL:

file:/path/to/mirror/dist/pair/pair-0.1.1.zip

download_path

my $uri = $distribution->path;

The path to the distribution archive file. That is, the path relative to any PGXN mirror root. So rather than the full URL you'd get from the url method, you just get the path as derived from the distribution URI template, for example:

/dist/pair/pair-0.1.1.zip

source_url

my $source_url = $distribution->source_url;

The absolute URL to the unzipped source on the API server, suitable for browsing. For example:

https://api.pgxn.org/src/pair/pair-0.1.1/

Or, for a file system URL:

file:/path/to/mirror/src/pair/pair-0.1.1/

If connected to a mirror, rather than an API server, undef will be returned.

source_path

my $source_path = $distribution->source_path;

The path to the unzipped, browsable distribution. That is, the path relative to any PGXN mirror root. So rather than the full URL you'd get from the source_url method, you just get the path as derived from the distribution URI template, for example:

/src/pair/pair-0.1.1/

download_to

my file = $distribution->download_to('.');
$distribution->download_to('myfile.zip');

Downloads the distribution. Pass the name of the file to save to, or the name of a directory. If a directory is specified, the file will be written with the same name as it has on PGXN, such as pgtap-0.24.0.zip. Either way, the name of the file written will be returned. Regardless of the file's name, it will always be a zip archive.

version_for

my $version = $distribution->version_for('testing');

Returns the most recent version for a release status, if any exists. The supported release statuses are:

stable
testing
unstable

These version numbers can be used to fetch information specific to a version:

my $test_dist = $pgxn->get_distribution(
    $distribution->name,
    $distribution->version_for('testing'),
);

date_for

my $date = $distribution->date_for('unstable');

Like version_for(), but returns the release date of the most recent version for the given release status. The supported release statuses are:

stable
testing
unstable

versions_for

my @versions = $distributions->versions_for('stable');

Returns a list of the versions for a particular release status, if any. The are returned in order from most to least recent.

url_for_html_doc

# returns https://api.pgxn.org/dist/pair/pair-0.1.1/doc/pair.html
my $doc_url = $distribution->url_for_html_doc('doc/pair');

The absolute URL to an HTML documentation file. Pass a document path to get its URL. The keys in the docs hash reference represent all known document paths. If connected to a mirror, rather than an API server, undef will be returned. Otherwise, if not document exists at that path, an exception will be thrown.

path_for_html_doc

# returns /dist/pair/pair-0.1.1/doc/pair.html
my $doc_url = $distribution->path_for_html_doc('doc/pair');

The path to an HTML documentation file. Pass a document path to get its URL. The keys in the docs hash reference represent all known document paths. If connected to a mirror, rather than an API server, undef will be returned. Otherwise, if not document exists at that path, an exception will be thrown.

body_for_html_doc

my $body = $distribution->body_for_html_doc('README');

Returns the body of an HTML document. Pass in the path to the doc (minus a suffix) to retrieve its contents. They keys in the hash returned by docs provide the paths for all docs included in a distribution.

Note that docs are formatted as HTML fragments with no <head> or <body> element, though they may be assumed to constitute the contents of a <body> element. They are also always encoded as UTF-8.

The contents are all contained within a single <div> element with the ID pgxndoc, and include a table of contents. Here's a simple example of the body of a document:

<div id="pgxndoc">
  <div id="pgxntoc">
    <h3>Contents</h3>
    <ul class="pgxntocroot">
      <li><a href="#Title">Title</a></li>
    </ul>
  </div>
  <div id="pgxnbod">
    <h1 id="Title"><a href="/">Title</a></h1>
    <p>Blah blah blah</p>
    <p>Body</p>
  </div>
</div>

The IDs used for contents are generated from h1, h2, and h3 elements; all other IDs and classes begin with "pgxn" as seen in this example.

See Also

  • WWW::PGXN

    The main class to communicate with a PGXN mirror or API server.

Support

This module is stored in an open GitHub repository. Feel free to fork and contribute!

Please file bug reports via GitHub Issues or by sending mail to bug-WWW-PGXN@rt.cpan.org.

Author

David E. Wheeler <david@justatheory.com>

Copyright and License

Copyright (c) 2011-2024 David E. Wheeler. Some Rights Reserved.

This module is free software; you can redistribute it and/or modify it under the same terms as Perl itself.