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 .pm file. That comparison belongs to MinPerl or a dedicated VersionSync check.

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.