NAME
App::GHGen::PerlCustomizer - Customize Perl workflows based on project requirements
SYNOPSIS
use App::GHGen::PerlCustomizer qw(detect_perl_requirements);
my $requirements = detect_perl_requirements();
# Returns: { min_version => '5.036', has_cpanfile => 1, ... }
FUNCTIONS
detect_perl_requirements()
Detect Perl version requirements and dependency-file presence in the current directory.
Purpose
Inspect the current working directory for common Perl distribution files (cpanfile, Makefile.PL, dist.ini, Build.PL) and extract the minimum Perl version declared in any of them.
Arguments
None.
Returns
A hash reference with the following keys, all of which are always present:
{
min_version => Str | undef, # e.g. '5.036'; undef when undetected
has_cpanfile => Bool,
has_makefile_pl => Bool,
has_dist_ini => Bool,
has_build_pl => Bool,
}
Side Effects
Reads files from the current working directory.
Usage Example
use App::GHGen::PerlCustomizer qw(detect_perl_requirements);
my $reqs = detect_perl_requirements();
say $reqs->{min_version} // 'not specified';
API SPECIFICATION
Input
# No parameters.
Output
{
type => 'hashref',
keys => {
min_version => { type => 'scalar', optional => 1 },
has_cpanfile => { type => 'scalar' },
has_makefile_pl => { type => 'scalar' },
has_dist_ini => { type => 'scalar' },
has_build_pl => { type => 'scalar' },
},
}
FORMAL SPECIFICATION
detect_perl_requirements : → Requirements
Requirements ≔ {
min_version: ℤ* ∪ { ⊥ },
has_cpanfile: 𝔹,
has_makefile_pl: 𝔹,
has_dist_ini: 𝔹,
has_build_pl: 𝔹,
}
min_version ≔
cpanfile exists ∧ version parseable from cpanfile → version
Makefile.PL exists ∧ MIN_PERL_VERSION parseable → version
otherwise → ⊥
generate_custom_perl_workflow($options)
Generate a customized Perl CI workflow and return it as a YAML string.
Options:
perl_versions(array ref)-
Explicit list of Perl versions to include in the test matrix, e.g.
['5.40', '5.38', '5.36']. Takes precedence overmin_perl_versionandmax_perl_versionwhen supplied. min_perl_version(string, default'5.36')-
Lowest Perl version to include in the matrix when
perl_versionsis not given. Accepts both'5.036'and'5.36'notation. max_perl_version(string, default'5.42')-
Highest Perl version to include in the default matrix when
perl_versionsis not given. The built-in version table currently spans5.22through5.44; the default produces the matrix5.36, 5.38, 5.40, 5.42.To test against Perl 5.44 (opt-in, not tested by default), pass
max_perl_version => '5.44'or setperl_versionsexplicitly:generate_custom_perl_workflow({ max_perl_version => '5.44' }); # matrix: 5.36, 5.38, 5.40, 5.42, 5.44 generate_custom_perl_workflow({ perl_versions => ['5.42', '5.44'] }); # matrix: 5.42, 5.44 os(array ref)-
Operating systems for the build matrix. Default:
['ubuntu-latest', 'macos-latest', 'windows-latest']. timeout(integer, default30)-
Value written to
timeout-minuteson every matrix job. enable_linter(boolean, default1)-
When true, inserts a "Lint and syntax check" step after all dependency installation steps and before the test run. The step runs on every matrix cell (all OS and Perl version combinations) so that compile-time errors are caught across the full version range being tested.
The step uses
shell: perl {0}, which works identically on Linux, macOS, and Windows without any OS-specific branching. It searcheslib/andbin/(falling back to.when neither exists), spawnsperl -Mstrict -Mwarnings -cfor each.pmfile found, and exits non-zero if any file fails. No additional CPAN modules are required. enable_linter_unused(boolean, default1)-
When true, inserts a "Check for unused variables" step immediately after the test run and before Perl::Critic. The step installs warnings::unused from CPAN and runs
perl -Mwarnings::unused -con every.pmfile underlib/.This step is conditioned on the latest matrix Perl version and
ubuntu-latest, matching the Perl::Critic and coverage steps. It is also markedcontinue-on-error: truebecause unused-variable warnings can be legitimately noisy on some codebases. enable_critic(boolean, default1)-
When true, adds a Perl::Critic step on the latest matrix Perl version and
ubuntu-latest. enable_coverage(boolean, default1)-
When true, adds a Devel::Cover test-coverage step on the latest matrix Perl version and
ubuntu-latest. enable_perlimports(boolean, default1)-
When true, adds a "Check imports with perlimports" step on the latest matrix Perl version and
ubuntu-latest. The step installs App::perlimports from CPAN and runsperlimports --lintacross all.pmfiles underlib/. It is markedcontinue-on-error: truebecause import hygiene warnings are advisory; they should not block a CI run in established codebases.
Generated step order:
- 1.
actions/checkout - 2. Setup Perl via
shogo82148/actions-setup-perl - 3. Cache CPAN modules via
actions/cache - 4. Install cpanm and
local::lib - 5. Install project dependencies
- 6. Lint and syntax check — all matrix cells (when
enable_linteris true); the unused-variable check viaPERL5OPT=-Mwarnings::unusedis embedded at the end of this step whenenable_linter_unusedis true - 7. Run tests
- 8. Run Perl::Critic — latest Perl + Ubuntu only (when
enable_criticis true) - 9. Check imports with perlimports — latest Perl + Ubuntu only (when
enable_perlimportsis true) - 10. Test coverage — latest Perl + Ubuntu only (when
enable_coverageis true) - 11. Show cpanm build log on failure
API SPECIFICATION
Input
{
opts => {
type => 'hashref',
default => {},
keys => {
perl_versions => { type => 'arrayref', optional => 1 },
min_perl_version => { type => 'scalar', default => '5.36' },
max_perl_version => { type => 'scalar', default => '5.42' },
os => { type => 'arrayref', optional => 1 },
timeout => { type => 'scalar', default => 30 },
enable_linter => { type => 'scalar', default => 1 },
enable_linter_unused => { type => 'scalar', default => 1 },
enable_critic => { type => 'scalar', default => 1 },
enable_coverage => { type => 'scalar', default => 1 },
enable_perlimports => { type => 'scalar', default => 1 },
},
},
}
Output
{ type => 'scalar' } # multi-line YAML string starting with '---'
FORMAL SPECIFICATION
generate_custom_perl_workflow : Opts → YAML
versions ≔ opts.perl_versions ?? range(min, max)
latest ≔ versions[|versions|−1]
yaml contains "Lint and syntax check" step ↔ opts.enable_linter = 1
yaml contains "PERL5OPT=-Mwarnings::unused" ↔ opts.enable_linter_unused = 1
yaml contains "Run Perl::Critic" ↔ opts.enable_critic = 1
yaml contains "Test coverage" ↔ opts.enable_coverage = 1
yaml contains "Check imports with perlimports" ↔ opts.enable_perlimports = 1
step ordering invariant:
pos(lint) < pos(unused) < pos(tests) < pos(critic) < pos(perlimports) < pos(coverage)
AUTHOR
Nigel Horne <njh@nigelhorne.com>
LICENSE
Usage is subject to the GPL2 licence terms. If you use it, please let me know.