NAME
Test::CPAN::Health - Analyse a CPAN distribution and produce a comprehensive health report
VERSION
Version 0.1.0
SYNOPSIS
Command-line (the usual entry point):
# Analyse the current directory
cpan-health .
# Analyse by CPAN dist name (downloads and unpacks automatically)
cpan-health LWP-UserAgent
# Analyse by module name
cpan-health LWP::UserAgent
# JSON output -- useful for editor or CI integration
cpan-health --format=json My-Dist
# Fail the build if the health score falls below 80
cpan-health --min-score=80 --no-cover My-Dist
# Skip slow or network-dependent checks
cpan-health --no-network --no-cover .
# Run only the security and versioning checks
cpan-health --check=security_advisories,sem_ver My-Dist
# Skip specific checks by id
cpan-health --skip=cpan_testers,kwalitee .
# TAP output -- pipe into any test harness
cpan-health --format=tap My-Dist | prove --stdin
# Write the report to a file
cpan-health --format=json --output=report.json LWP-UserAgent
# Show all available options
cpan-health --help
Perl API (for programmatic use):
use Test::CPAN::Health;
# Analyse a local unpacked distribution
my $health = Test::CPAN::Health->new(path => '/path/to/My-Dist-1.00');
my $report = $health->analyse;
$health->report_to($report);
# Analyse a distribution by CPAN dist name
my $health = Test::CPAN::Health->new(
dist => 'LWP-UserAgent',
format => 'json',
min_score => 80,
);
my $report = $health->analyse;
exit 1 if $report->overall_score < 80;
# Analyse by module name, skipping network-dependent checks
my $health = Test::CPAN::Health->new(
module => 'LWP::UserAgent',
no_network => 1,
skip => ['Test::CPAN::Health::Check::CPANTesters'],
);
DESCRIPTION
Test::CPAN::Health is a comprehensive distribution health checker for CPAN modules -- analogous to cargo audit + npm audit + go vet + perlcritic + cpants, all unified into a single scored report.
It accepts a distribution as a local path, a CPAN distribution name, or a module name. It runs a configurable battery of checks (POD coverage, CPAN Testers pass rate, kwalitee, CI configuration, META validity, SPDX license, stale and abandoned dependencies, known CVEs, reverse dependency count, documentation quality, examples, benchmarks, semantic versioning, perlcritic violations, code complexity, duplicate code, test coverage, minimum Perl version, and deprecation warnings) and returns a weighted score out of 100.
The report can be rendered as coloured terminal output, JSON, HTML, or TAP (allowing cpan-health to run inside a standard test harness).
LIMITATIONS
The
TestCoveragecheck requiresDevel::Coverand must run the distribution's own test suite, which is slow and may have side effects.Network-dependent checks (CPANTesters, StaleDeps, AbandonedDeps, SecurityAdvisories, ReverseDeps) require internet access and are subject to upstream API availability and rate limits.
The
DuplicateCodecheck uses a token-fingerprint algorithm viaPPIand may produce false positives on generated or data-heavy code.
analyse
Runs all configured checks against the distribution and returns a Report.
All components (Distribution, Cache, Runner, Reporter) are initialised lazily on the first call so that construction is always cheap.
API SPECIFICATION
INPUT
No arguments. Configuration comes from the constructor.
OUTPUT
Returns a Test::CPAN::Health::Report object.
MESSAGES
Code | Severity | Message | Resolution
------+----------+------------------------------------+---------------------
| | |
FORMAL SPECIFICATION
-- Z schema (placeholder) --
AnalyseOp
Test::CPAN::Health
Report'
-------------------------------------------------------
distribution /= undefined
Report' = Runner.run(distribution)
overall_score(Report') in 0..100
SIDE EFFECTS
May download the distribution from CPAN, run its test suite (if TestCoverage is enabled), and write to the local HTTP cache.
USAGE EXAMPLE
my $report = $health->analyse;
print 'Score: ', $report->overall_score, "\n";
list_checks
PURPOSE
Return a list of all default check metadata (id, name, weight, category, description) without running any check. Suitable for --list-checks output.
API SPECIFICATION
INPUT
None (class method).
OUTPUT
Arrayref of hashrefs; each has keys id, name, weight, category, description. Ordered as they would execute.
MESSAGES
Code | Severity | Message | Resolution
------+----------+-------------------------------------+---------------------
| | |
FORMAL SPECIFICATION
Post: result is an arrayref of length = #DEFAULT_CHECKS (skipping unloadable)
SIDE EFFECTS
Requires each check class (lazy load).
USAGE EXAMPLE
my @checks = @{ Test::CPAN::Health->list_checks };
printf "%-20s %s\n", $_->{id}, $_->{name} for @checks;
report_to
Render a Report to the configured output format and return the result as a string. Printing to STDOUT (for terminal/TAP formats) is the responsibility of the caller or the CLI script.
API SPECIFICATION
INPUT
report Test::CPAN::Health::Report required
OUTPUT
Scalar string containing the rendered report.
MESSAGES
Code | Severity | Message | Resolution
------+----------+------------------------------------+---------------------
| | |
FORMAL SPECIFICATION
-- Z schema (placeholder) --
RenderOp
reporter : Reporter
report : Report
output : String
-------------------------------------------------------
output = reporter.render(report)
SIDE EFFECTS
None beyond invoking the reporter.
USAGE EXAMPLE
my $text = $health->report_to($report);
print $text;
AUTHOR
Nigel Horne, <njh at nigelhorne.com>
LICENSE AND COPYRIGHT
Copyright (C) 2026 Nigel Horne.
Usage is subject to the GPL2 licence terms. If you use it, please let me know.