NAME
Test::CPAN::Health::Distribution - Represents a CPAN distribution under analysis
SYNOPSIS
use Test::CPAN::Health::Distribution;
# From a local unpacked path
my $dist = Test::CPAN::Health::Distribution->new(path => '/tmp/LWP-UserAgent-6.77');
# From a CPAN distribution name (downloads and unpacks)
my $dist = Test::CPAN::Health::Distribution->from_cpan('LWP-UserAgent');
# From a module name (resolves dist via MetaCPAN, then downloads)
my $dist = Test::CPAN::Health::Distribution->from_module('LWP::UserAgent');
printf "%s %s by %s\n", $dist->name, $dist->version, $dist->author;
my @pm_files = @{ $dist->pm_files };
DESCRIPTION
Abstracts the distribution being analysed. All checks receive a Distribution object, which provides uniform access to the filesystem, metadata, and derived file lists regardless of whether the distribution came from a local path or was downloaded from CPAN.
All file-list methods return absolute paths.
LIMITATIONS
from_cpanandfrom_modulerequire network access andArchive::Tarto unpack tarballs. The download is cached in a temporary directory that is cleaned up at object destruction.metasearches in order: META.json, META.yml, MYMETA.json, MYMETA.yml. MYMETA files are generated byperl Makefile.PLand serve as a fallback for local checkouts. Canonical META files are produced bymake distdir(MakeMaker) ordzil build(Dist::Zilla) and must be committed separately. Returnsundefonly when none of these files are present.file_pathdoes not sanitise@partsfor path-traversal sequences (e.g.../). It is the caller's responsibility to supply trusted path components. Do not pass user-supplied strings tofile_pathwithout prior validation.all_source_filesreturns the union ofpm_filesandpl_filesat the time of the first call; the result is cached. Files added to the distribution tree afterwards are not visible.
from_cpan
PURPOSE
Factory method: resolve a CPAN distribution name to the latest release, download the tarball via MetaCPAN, unpack it to a temp directory, and return a Distribution instance pointing at the unpacked tree.
API SPECIFICATION
INPUT
dist_name Scalar required e.g. 'LWP-UserAgent'
OUTPUT
Test::CPAN::Health::Distribution object.
MESSAGES
Code | Severity | Message | Resolution
------+----------+------------------------------------+---------------------
DST01 | FATAL | Cannot resolve dist from MetaCPAN | Check dist name and network
DST02 | FATAL | Download failed | Check CPAN mirror availability
DST03 | FATAL | Unpack failed | Check Archive::Tar installation
FORMAL SPECIFICATION
-- Z schema (placeholder) --
FromCpanOp
dist_name? : String
dist! : Distribution
-------------------------------------------------------
dist_name? /= ""
dist!.name = resolve(dist_name?)
exists(dist!.path) /\ is_dir(dist!.path)
SIDE EFFECTS
Downloads a tarball from CPAN. Creates and owns a temporary directory that is removed when the returned object is destroyed.
USAGE EXAMPLE
my $dist = Test::CPAN::Health::Distribution->from_cpan('LWP-UserAgent');
from_module
PURPOSE
Factory method: resolve a module name (Foo::Bar) to its containing distribution via MetaCPAN, then delegate to from_cpan.
API SPECIFICATION
INPUT
module_name Scalar required e.g. 'LWP::UserAgent'
OUTPUT
Test::CPAN::Health::Distribution object.
MESSAGES
Code | Severity | Message | Resolution
------+----------+------------------------------------+---------------------
DST04 | FATAL | Cannot resolve module from MetaCPAN | Check module name and network
FORMAL SPECIFICATION
-- Z schema (placeholder) --
FromModuleOp
module_name? : String
dist_name! : String
-------------------------------------------------------
dist_name! = metacpan_resolve(module_name?)
SIDE EFFECTS
As from_cpan.
USAGE EXAMPLE
my $dist = Test::CPAN::Health::Distribution->from_module('LWP::UserAgent');
path
PURPOSE
Returns the absolute filesystem path to the root of the unpacked distribution.
API SPECIFICATION
INPUT
None.
OUTPUT
Absolute scalar path string.
MESSAGES
Code | Severity | Message | Resolution
------+----------+------------------------------------+---------------------
| | |
FORMAL SPECIFICATION
-- Z schema (placeholder) --
path : String
-------------------------------------------------------
is_absolute(path) /\ is_dir(path)
SIDE EFFECTS
None.
USAGE EXAMPLE
print $dist->path;
meta
PURPOSE
Returns a CPAN::Meta object parsed from the best available META file. The search order is: META.json, META.yml, MYMETA.json, MYMETA.yml. META files are authoritative (shipped with the dist); MYMETA files are generated by perl Makefile.PL and used as a fallback for local checkouts where perl Makefile.PL has been run but no canonical META file has been committed. Returns undef if no META file of any kind is found.
API SPECIFICATION
INPUT
None.
OUTPUT
CPAN::Meta object or undef.
MESSAGES
Code | Severity | Message | Resolution
------+----------+--------------------------------------+---------------------
DST05 | WARNING | Cannot parse <file>: <reason> | Fix or regenerate the META file
FORMAL SPECIFICATION
-- Z schema (placeholder) --
meta : CPAN::Meta | undefined
SIDE EFFECTS
None (reads META file on first call, caches result).
USAGE EXAMPLE
my $meta = $dist->meta or warn "No META file";
print $meta->name;
name
Returns the distribution name from META (e.g. LWP-UserAgent), or a best-guess derived from the path basename if META is absent.
version
Returns the distribution version string from META, or undef if not determinable. The result is cached after the first call; a dist whose META lacks a version field always returns undef without re-parsing.
author
Returns the first author string from META, or undef. Cached after the first call.
pm_files
Returns an arrayref of absolute paths to all .pm files under lib/.
t_files
Returns an arrayref of absolute paths to all .t files under t/.
pl_files
Returns an arrayref of absolute paths to all .pl files and files under bin/ or script/.
all_source_files
Convenience: returns the union of pm_files and pl_files as a single arrayref. The result is cached after the first call.
has_dir
Returns true if the given subdirectory exists within the distribution root. Accepts a single directory name or a list of alternatives.
file_path
Returns the absolute path to a named file within the distribution root, or undef if it does not exist.
AUTHOR
Nigel Horne, <njh at nigelhorne.com>
LICENSE AND COPYRIGHT
Copyright (C) 2025-2026 Nigel Horne.
This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version.