NAME
Test::CPAN::Health::Check::SemVer - Check that a distribution version follows semantic versioning
SYNOPSIS
use Test::CPAN::Health::Check::SemVer;
my $check = Test::CPAN::Health::Check::SemVer->new;
my $result = $check->run($dist);
printf "%s: %s\n", $result->status, $result->summary;
DESCRIPTION
Examines the version string declared in the distribution's META.json (or META.yml) and scores it against the Semantic Versioning 2.0.0 specification (https://semver.org).
Score matrix:
100 -- strict semver (X.Y.Z or vX.Y.Z, optionally with pre-release and/or build metadata).
60 -- Perl-style decimal (X.YYY), accepted with a warning because it is ubiquitous on CPAN but not interoperable with semver tooling.
0 -- anything else (missing version, empty string, epoch-only, etc.).
LIMITATIONS
Version 0.x.y is legal semver and scores 100; it is not penalised here because many mature distributions use 0.x to signal API instability.
This check does not compare the declared version against the version embedded in the main
.pmfile. That comparison belongs toMinPerlor a dedicatedVersionSynccheck.
run
PURPOSE
Extract the version string from the distribution's META file and score it.
API SPECIFICATION
INPUT
dist Test::CPAN::Health::Distribution required
context Hashref optional prior check results
OUTPUT
Test::CPAN::Health::Result with:
check_id 'sem_ver'
status 'pass' | 'warn' | 'fail' | 'skip'
score 0 | 60 | 100
summary human-readable verdict
details arrayref of diagnostic strings (non-empty on warn/fail)
MESSAGES
Code | Severity | Message | Resolution
------+----------+------------------------------------+---------------------
SV001 | SKIP | No META file found | Add META.json or META.yml
SV002 | FAIL | Version is missing or empty | Declare a version in META
SV003 | WARN | Decimal-style version {v} | Migrate to X.Y.Z semver
SV004 | FAIL | Version {v} does not match semver | Use X.Y.Z format
SV005 | PASS | Version {v} follows semver 2.0 |
FORMAL SPECIFICATION
-- Z schema (placeholder) --
SemVerOp
dist : Distribution
version : String | undefined
score : {0, 60, 100}
status : {pass, warn, fail, skip}
-------------------------------------------------------
version = undefined => status = skip
version = "" => status = fail /\ score = 0
version matches SEMVER_RE => status = pass /\ score = 100
version matches DECIMAL_RE => status = warn /\ score = 60
otherwise => status = fail /\ score = 0
SIDE EFFECTS
None. All information comes from the already-parsed META object.
USAGE EXAMPLE
my $result = Test::CPAN::Health::Check::SemVer->new->run($dist);
print $result->summary;
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.