From fd230a273556d4363dd1caf8ead2d8c524b208e7 Mon Sep 17 00:00:00 2001 From: Danny Glin Date: Fri, 16 Jan 2026 16:34:10 -0700 Subject: [PATCH 1/5] Change list of perl modules from array to hash --- bin/check_modules.pl | 338 ++++++++++++++++++++++++++++++++----------- 1 file changed, 253 insertions(+), 85 deletions(-) diff --git a/bin/check_modules.pl b/bin/check_modules.pl index f257ed126f..fb1a48eadb 100755 --- a/bin/check_modules.pl +++ b/bin/check_modules.pl @@ -30,90 +30,258 @@ =head1 DESCRIPTION use Getopt::Long qw(:config bundling); use Pod::Usage; -my @modulesList = qw( - Archive::Tar - Archive::Zip - Archive::Zip::SimpleZip - Benchmark - Carp - Class::Accessor - Crypt::JWT - Crypt::PK::RSA - Data::Dump - Data::Dumper - Data::Structure::Util - Data::UUID - Date::Format - Date::Parse - DateTime - DBI - Digest::MD5 - Digest::SHA - Email::Address::XS - Email::Sender::Transport::SMTP - Email::Stuffer - Errno - Exception::Class - File::Copy - File::Copy::Recursive - File::Fetch - File::Find - File::Find::Rule - File::Path - File::Spec - File::stat - File::Temp - Future::AsyncAwait - GD - GD::Barcode::QRcode - Getopt::Long - Getopt::Std - HTML::Entities - HTTP::Async - IO::File - Iterator - Iterator::Util - Locale::Maketext::Lexicon - Locale::Maketext::Simple - LWP::Protocol::https - MIME::Base32 - MIME::Base64 - Math::Random::Secure - Minion - Minion::Backend::SQLite - Mojolicious - Mojolicious::Plugin::NotYAMLConfig - Mojolicious::Plugin::RenderFile - Net::IP - Net::OAuth - Opcode - Pandoc - Perl::Critic - Perl::Tidy - PHP::Serialization - Pod::Simple::Search - Pod::Simple::XHTML - Pod::Usage - Pod::WSDL - Scalar::Util - SOAP::Lite - Socket - SQL::Abstract - String::ShellQuote - SVG - Text::CSV - Text::Wrap - Tie::IxHash - Time::HiRes - Time::Zone - Types::Serialiser - URI::Escape - UUID::Tiny - XML::LibXML - XML::Parser - XML::Parser::EasyTree - XML::Writer - YAML::XS +my %modulesList = ( + 'Archive::Tar' => { + package => { deb => 'perl-modules', }, + }, + 'Archive::Zip' => { + package => { deb => 'libarchive-zip-perl', }, + }, + 'Archive::Zip::SimpleZip' => {}, + 'Benchmark' => { + package => { deb => 'perl-modules', }, + }, + 'Carp' => { + package => { deb => 'perl-modules', }, + }, + 'Class::Accessor' => { + package => { deb => 'libclass-accessor-perl', }, + }, + 'Crypt::JWT' => { + package => { deb => 'libcrypt-jwt-perl', }, + }, + 'Crypt::PK::RSA' => { + package => { deb => 'libcryptx-perl', }, + }, + 'Data::Dump' => { + package => { deb => 'libdata-dump-perl', }, + }, + 'Data::Dumper' => { + package => { deb => 'libperl', }, + }, + 'Data::Structure::Util' => { + package => { deb => 'libdata-structure-util-perl', }, + }, + 'Data::UUID' => { + package => { deb => 'libossp-uuid-perl', }, + }, + 'Date::Format' => { + package => { deb => 'libtimedate-perl', }, + }, + 'Date::Parse' => { + package => { deb => 'libtimedate-perl', }, + }, + 'DateTime' => { + package => { deb => 'libdatetime-perl', }, + }, + 'DBI' => { + package => { deb => 'libdbi-perl', }, + }, + 'Digest::MD5' => { + package => { deb => 'libperl', }, + }, + 'Digest::SHA' => { + package => { deb => 'libperl', }, + }, + 'Email::Address::XS' => { + package => { deb => 'libemail-address-xs-perl', }, + }, + 'Email::Sender::Transport::SMTP' => { + package => { deb => 'libemail-sender-perl', }, + }, + 'Email::Stuffer' => { + package => { deb => 'libemail-stuffer-perl', }, + }, + 'Errno' => { + package => { deb => 'libperl', }, + }, + 'Exception::Class' => { + package => { deb => 'libexception-class-perl', }, + }, + 'File::Copy' => { + package => { deb => 'perl-modules', }, + }, + 'File::Copy::Recursive' => { + package => { deb => 'libfile-copy-recursive-perl', }, + }, + 'File::Fetch' => { + package => { deb => 'perl-modules', }, + }, + 'File::Find' => { + package => { deb => 'perl-modules', }, + }, + 'File::Find::Rule' => { + package => { deb => 'libfile-find-rule-perl', }, + }, + 'File::Path' => { + package => { deb => 'perl-modules', }, + }, + 'File::Spec' => { + package => { deb => 'perl-base', }, + }, + 'File::stat' => { + package => { deb => 'perl-modules', }, + }, + 'File::Temp' => { + package => { deb => 'perl-modules', }, + }, + 'Future::AsyncAwait' => { + package => { deb => 'libfuture-asyncawait-perl', }, + minversion => 0.52, + }, + 'GD' => { + package => { deb => 'libgd-perl', }, + }, + 'GD::Barcode::QRcode' => { + package => { deb => 'libgd-barcode-perl', }, + }, + 'Getopt::Long' => { + package => { deb => 'perl-modules', }, + }, + 'Getopt::Std' => { + package => { deb => 'perl-modules', }, + }, + 'HTML::Entities' => { + package => { deb => 'libhtml-parser-perl', }, + }, + 'HTTP::Async' => { + package => { deb => 'libhttp-async-perl', }, + }, + 'IO::File' => { + package => { deb => 'perl-base', }, + }, + 'Iterator' => { + package => { deb => 'libiterator-perl', }, + }, + 'Iterator::Util' => { + package => { deb => 'libiterator-util-perl', }, + }, + 'Locale::Maketext::Lexicon' => { + package => { deb => 'liblocale-maketext-lexicon-perl', }, + }, + 'Locale::Maketext::Simple' => { + package => { deb => 'perl-modules', }, + }, + 'LWP::Protocol::https' => { + package => { deb => 'liblwp-protocol-https-perl', }, + minversion => 6.06, + }, + 'MIME::Base32' => { + package => { deb => 'libmime-base32-perl', }, + }, + 'MIME::Base64' => { + package => { deb => 'libperl', }, + }, + 'Math::Random::Secure' => { + package => { deb => 'libmath-random-secure-perl', }, + }, + 'Minion' => { + package => { deb => 'libminion-perl', }, + }, + 'Minion::Backend::SQLite' => { + package => { deb => 'libminion-backend-sqlite-perl', }, + }, + 'Mojolicious' => { + package => { deb => 'libmojolicious-perl', }, + minversion => 9.34, + }, + 'Mojolicious::Plugin::NotYAMLConfig' => { + package => { deb => 'libmojolicious-perl', }, + }, + 'Mojolicious::Plugin::RenderFile' => { + package => { deb => 'libmojolicious-plugin-renderfile-perl', }, + }, + 'Net::IP' => { + package => { deb => 'libnet-ip-perl', }, + }, + 'Net::OAuth' => { + package => { deb => 'libnet-oauth-perl', }, + }, + 'Opcode' => { + package => { deb => 'libperl', }, + }, + 'Pandoc' => { + package => { deb => 'libpandoc-wrapper-perl', }, + }, + 'Perl::Critic' => { + package => { deb => 'libperl-critic-perl', }, + }, + 'Perl::Tidy' => { + package => { deb => 'perltidy', }, + }, + 'PHP::Serialization' => { + package => { deb => 'libphp-serialization-perl', }, + }, + 'Pod::Simple::Search' => { + package => { deb => 'perl-modules', }, + }, + 'Pod::Simple::XHTML' => { + package => { deb => 'perl-modules', }, + }, + 'Pod::Usage' => { + package => { deb => 'perl-modules', }, + }, + 'Pod::WSDL' => { + package => { deb => 'libpod-wsdl-perl', }, + }, + 'Scalar::Util' => { + package => { deb => 'perl-base', }, + }, + 'SOAP::Lite' => { + package => { deb => 'libsoap-lite-perl', }, + }, + 'Socket' => { + package => { deb => 'perl-base', }, + }, + 'SQL::Abstract' => { + package => { deb => 'libsql-abstract-perl', }, + minversion => 2.000000, + }, + 'String::ShellQuote' => { + package => { deb => 'libstring-shellquote-perl', }, + }, + 'SVG' => { + package => { deb => 'libsvg-perl', }, + }, + 'Text::CSV' => { + package => { deb => 'libtext-csv-perl', }, + }, + 'Text::Wrap' => { + package => { deb => 'perl-base', }, + }, + 'Tie::IxHash' => { + package => { deb => 'libtie-ixhash-perl', }, + }, + 'Time::HiRes' => { + package => { deb => 'libperl', }, + }, + 'Time::Zone' => { + package => { deb => 'libtimedate-perl', }, + }, + 'Types::Serialiser' => { + package => { deb => 'libtypes-serialiser-perl', }, + }, + 'URI::Escape' => { + package => { deb => 'liburi-perl', }, + }, + 'UUID::Tiny' => { + package => { deb => 'libuuid-tiny-perl', }, + }, + 'XML::LibXML' => { + package => { deb => 'libxml-libxml-perl', }, + }, + 'XML::Parser' => { + package => { deb => 'libxml-parser-perl', }, + }, + 'XML::Parser::EasyTree' => { + package => { deb => 'libxml-parser-easytree-perl', }, + }, + 'XML::Writer' => { + package => { deb => 'libxml-writer-perl', }, + }, + 'YAML::XS' => { + package => { deb => 'libyaml-libyaml-perl', }, + }, ); my %moduleVersion = ( @@ -196,7 +364,7 @@ sub check_modules { use strict 'refs'; }; - for my $module (@modulesList) { + for my $module (keys(%modulesList)) { $checkModule->($module); } From 6f9ef4ff39dc287339516952520acfe56a99a964 Mon Sep 17 00:00:00 2001 From: Danny Glin Date: Fri, 16 Jan 2026 16:43:10 -0700 Subject: [PATCH 2/5] Update minversion code --- bin/check_modules.pl | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/bin/check_modules.pl b/bin/check_modules.pl index fb1a48eadb..ec6b123bb7 100755 --- a/bin/check_modules.pl +++ b/bin/check_modules.pl @@ -353,18 +353,18 @@ sub check_modules { } else { say "** $module found, but failed to load: $@"; } - } elsif (defined($moduleVersion{$module}) - && version->parse(${ $module . '::VERSION' }) < version->parse($moduleVersion{$module})) + } elsif (defined($modulesList{$module}{'minversion'}) + && version->parse(${ $module . '::VERSION' }) < version->parse($modulesList{$module}{'minversion'})) { $moduleNotFound = 1; - say "** $module found, but not version $moduleVersion{$module} or better"; + say "** $module found, but not version $modulesList{$module}{'minversion'} or better"; } else { say " $module found and loaded"; } use strict 'refs'; }; - for my $module (keys(%modulesList)) { + for my $module (sort keys(%modulesList)) { $checkModule->($module); } From cee85407e14cd70a3f606f8dcc2cdf0c777504b8 Mon Sep 17 00:00:00 2001 From: Danny Glin Date: Sat, 17 Jan 2026 00:09:31 +0000 Subject: [PATCH 3/5] perltidy --- bin/check_modules.pl | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/bin/check_modules.pl b/bin/check_modules.pl index ec6b123bb7..6b41accf3b 100755 --- a/bin/check_modules.pl +++ b/bin/check_modules.pl @@ -38,7 +38,7 @@ =head1 DESCRIPTION package => { deb => 'libarchive-zip-perl', }, }, 'Archive::Zip::SimpleZip' => {}, - 'Benchmark' => { + 'Benchmark' => { package => { deb => 'perl-modules', }, }, 'Carp' => { @@ -126,7 +126,7 @@ =head1 DESCRIPTION package => { deb => 'perl-modules', }, }, 'Future::AsyncAwait' => { - package => { deb => 'libfuture-asyncawait-perl', }, + package => { deb => 'libfuture-asyncawait-perl', }, minversion => 0.52, }, 'GD' => { @@ -163,7 +163,7 @@ =head1 DESCRIPTION package => { deb => 'perl-modules', }, }, 'LWP::Protocol::https' => { - package => { deb => 'liblwp-protocol-https-perl', }, + package => { deb => 'liblwp-protocol-https-perl', }, minversion => 6.06, }, 'MIME::Base32' => { @@ -182,7 +182,7 @@ =head1 DESCRIPTION package => { deb => 'libminion-backend-sqlite-perl', }, }, 'Mojolicious' => { - package => { deb => 'libmojolicious-perl', }, + package => { deb => 'libmojolicious-perl', }, minversion => 9.34, }, 'Mojolicious::Plugin::NotYAMLConfig' => { @@ -234,7 +234,7 @@ =head1 DESCRIPTION package => { deb => 'perl-base', }, }, 'SQL::Abstract' => { - package => { deb => 'libsql-abstract-perl', }, + package => { deb => 'libsql-abstract-perl', }, minversion => 2.000000, }, 'String::ShellQuote' => { From 1cf51551dda3638887d7be7d931c66c6e6c48197 Mon Sep 17 00:00:00 2001 From: Danny Glin Date: Mon, 19 Jan 2026 22:23:19 +0000 Subject: [PATCH 4/5] Add perl packages for rpm-based systems --- bin/check_modules.pl | 440 +++++++++++++++++++++++++++++++++---------- 1 file changed, 337 insertions(+), 103 deletions(-) diff --git a/bin/check_modules.pl b/bin/check_modules.pl index 6b41accf3b..6231026db7 100755 --- a/bin/check_modules.pl +++ b/bin/check_modules.pl @@ -32,256 +32,490 @@ =head1 DESCRIPTION my %modulesList = ( 'Archive::Tar' => { - package => { deb => 'perl-modules', }, + 'package' => { + 'deb' => 'perl-modules', + 'rpm' => 'perl-Archive-Tar' + } }, 'Archive::Zip' => { - package => { deb => 'libarchive-zip-perl', }, + 'package' => { + 'deb' => 'libarchive-zip-perl', + 'rpm' => 'perl-Archive-Zip' + } + }, + 'Archive::Zip::SimpleZip' => { + 'package' => { + 'rpm' => 'perl-Archive-Zip-SimpleZip' + } }, - 'Archive::Zip::SimpleZip' => {}, - 'Benchmark' => { - package => { deb => 'perl-modules', }, + 'Benchmark' => { + 'package' => { + 'deb' => 'perl-modules', + 'rpm' => 'perl-Benchmark' + } }, 'Carp' => { - package => { deb => 'perl-modules', }, + 'package' => { + 'deb' => 'perl-modules', + 'rpm' => 'perl-Carp' + } }, 'Class::Accessor' => { - package => { deb => 'libclass-accessor-perl', }, + 'package' => { + 'deb' => 'libclass-accessor-perl', + 'rpm' => 'perl-Class-Accessor' + } }, 'Crypt::JWT' => { - package => { deb => 'libcrypt-jwt-perl', }, + 'package' => { + 'deb' => 'libcrypt-jwt-perl', + 'rpm' => 'perl-Crypt-JWT' + } }, 'Crypt::PK::RSA' => { - package => { deb => 'libcryptx-perl', }, + 'package' => { + 'deb' => 'libcryptx-perl', + 'rpm' => 'perl-CryptX' + } + }, + 'DBI' => { + 'package' => { + 'deb' => 'libdbi-perl', + 'rpm' => 'perl-DBI' + } }, 'Data::Dump' => { - package => { deb => 'libdata-dump-perl', }, + 'package' => { + 'deb' => 'libdata-dump-perl', + 'rpm' => 'perl-Data-Dump' + } }, 'Data::Dumper' => { - package => { deb => 'libperl', }, + 'package' => { + 'deb' => 'libperl', + 'rpm' => 'perl-Data-Dumper' + } }, 'Data::Structure::Util' => { - package => { deb => 'libdata-structure-util-perl', }, + 'package' => { + 'deb' => 'libdata-structure-util-perl' + } }, 'Data::UUID' => { - package => { deb => 'libossp-uuid-perl', }, + 'package' => { + 'deb' => 'libossp-uuid-perl', + 'rpm' => 'perl-Data-UUID' + } }, 'Date::Format' => { - package => { deb => 'libtimedate-perl', }, + 'package' => { + 'deb' => 'libtimedate-perl', + 'rpm' => 'perl-TimeDate' + } }, 'Date::Parse' => { - package => { deb => 'libtimedate-perl', }, + 'package' => { + 'deb' => 'libtimedate-perl', + 'rpm' => 'perl-TimeDate' + } }, 'DateTime' => { - package => { deb => 'libdatetime-perl', }, - }, - 'DBI' => { - package => { deb => 'libdbi-perl', }, + 'package' => { + 'deb' => 'libdatetime-perl', + 'rpm' => 'perl-DateTime' + } }, 'Digest::MD5' => { - package => { deb => 'libperl', }, + 'package' => { + 'deb' => 'libperl', + 'rpm' => 'perl-Digest-MD5' + } }, 'Digest::SHA' => { - package => { deb => 'libperl', }, + 'package' => { + 'deb' => 'libperl', + 'rpm' => 'perl-Digest-SHA' + } }, 'Email::Address::XS' => { - package => { deb => 'libemail-address-xs-perl', }, + 'package' => { + 'deb' => 'libemail-address-xs-perl', + 'rpm' => 'perl-Email-Address-XS' + } }, 'Email::Sender::Transport::SMTP' => { - package => { deb => 'libemail-sender-perl', }, + 'package' => { + 'deb' => 'libemail-sender-perl', + 'rpm' => 'perl-Email-Sender' + } }, 'Email::Stuffer' => { - package => { deb => 'libemail-stuffer-perl', }, + 'package' => { + 'deb' => 'libemail-stuffer-perl' + } }, 'Errno' => { - package => { deb => 'libperl', }, + 'package' => { + 'deb' => 'libperl', + 'rpm' => 'perl-Errno' + } }, 'Exception::Class' => { - package => { deb => 'libexception-class-perl', }, + 'package' => { + 'deb' => 'libexception-class-perl', + 'rpm' => 'perl-Exception-Class' + } }, 'File::Copy' => { - package => { deb => 'perl-modules', }, + 'package' => { + 'deb' => 'perl-modules', + 'rpm' => 'perl-File-Copy' + } }, 'File::Copy::Recursive' => { - package => { deb => 'libfile-copy-recursive-perl', }, + 'package' => { + 'deb' => 'libfile-copy-recursive-perl', + 'rpm' => 'perl-File-Copy-Recursive' + } }, 'File::Fetch' => { - package => { deb => 'perl-modules', }, + 'package' => { + 'deb' => 'perl-modules', + 'rpm' => 'perl-File-Fetch' + } }, 'File::Find' => { - package => { deb => 'perl-modules', }, + 'package' => { + 'deb' => 'perl-modules', + 'rpm' => 'perl-File-Find' + } }, 'File::Find::Rule' => { - package => { deb => 'libfile-find-rule-perl', }, + 'package' => { + 'deb' => 'libfile-find-rule-perl', + 'rpm' => 'perl-File-Find-Rule' + } }, 'File::Path' => { - package => { deb => 'perl-modules', }, + 'package' => { + 'deb' => 'perl-modules', + 'rpm' => 'perl-File-Path' + } }, 'File::Spec' => { - package => { deb => 'perl-base', }, - }, - 'File::stat' => { - package => { deb => 'perl-modules', }, + 'package' => { + 'deb' => 'perl-base', + 'rpm' => 'perl-PathTools' + } }, 'File::Temp' => { - package => { deb => 'perl-modules', }, + 'package' => { + 'deb' => 'perl-modules', + 'rpm' => 'perl-File-Temp' + } + }, + 'File::stat' => { + 'package' => { + 'deb' => 'perl-modules', + 'rpm' => 'perl-File-stat' + } }, 'Future::AsyncAwait' => { - package => { deb => 'libfuture-asyncawait-perl', }, - minversion => 0.52, + 'minversion' => '0.52', + 'package' => { + 'deb' => 'libfuture-asyncawait-perl' + } }, 'GD' => { - package => { deb => 'libgd-perl', }, + 'package' => { + 'deb' => 'libgd-perl', + 'rpm' => 'perl-GD' + } }, 'GD::Barcode::QRcode' => { - package => { deb => 'libgd-barcode-perl', }, + 'package' => { + 'deb' => 'libgd-barcode-perl' + } }, 'Getopt::Long' => { - package => { deb => 'perl-modules', }, + 'package' => { + 'deb' => 'perl-modules', + 'rpm' => 'perl-Getopt-Long' + } }, 'Getopt::Std' => { - package => { deb => 'perl-modules', }, + 'package' => { + 'deb' => 'perl-modules', + 'rpm' => 'perl-Getopt-Std' + } }, 'HTML::Entities' => { - package => { deb => 'libhtml-parser-perl', }, + 'package' => { + 'deb' => 'libhtml-parser-perl', + 'rpm' => 'perl-HTML-Parser' + } }, 'HTTP::Async' => { - package => { deb => 'libhttp-async-perl', }, + 'package' => { + 'deb' => 'libhttp-async-perl' + } }, 'IO::File' => { - package => { deb => 'perl-base', }, + 'package' => { + 'deb' => 'perl-base', + 'rpm' => 'perl-IO' + } }, 'Iterator' => { - package => { deb => 'libiterator-perl', }, + 'package' => { + 'deb' => 'libiterator-perl', + } }, 'Iterator::Util' => { - package => { deb => 'libiterator-util-perl', }, + 'package' => { + 'deb' => 'libiterator-util-perl' + } + }, + 'LWP::Protocol::https' => { + 'minversion' => '6.06', + 'package' => { + 'deb' => 'liblwp-protocol-https-perl', + 'rpm' => 'perl-LWP-Protocol-https' + } }, 'Locale::Maketext::Lexicon' => { - package => { deb => 'liblocale-maketext-lexicon-perl', }, + 'package' => { + 'deb' => 'liblocale-maketext-lexicon-perl' + } }, 'Locale::Maketext::Simple' => { - package => { deb => 'perl-modules', }, - }, - 'LWP::Protocol::https' => { - package => { deb => 'liblwp-protocol-https-perl', }, - minversion => 6.06, + 'package' => { + 'deb' => 'perl-modules', + 'rpm' => 'perl-Locale-Maketext-Simple' + } }, 'MIME::Base32' => { - package => { deb => 'libmime-base32-perl', }, + 'package' => { + 'deb' => 'libmime-base32-perl' + } }, 'MIME::Base64' => { - package => { deb => 'libperl', }, + 'package' => { + 'deb' => 'libperl', + 'rpm' => 'perl-MIME-Base64' + } }, 'Math::Random::Secure' => { - package => { deb => 'libmath-random-secure-perl', }, + 'package' => { + 'deb' => 'libmath-random-secure-perl', + 'rpm' => 'perl-Math-Random-Secure' + } }, 'Minion' => { - package => { deb => 'libminion-perl', }, + 'package' => { + 'deb' => 'libminion-perl' + } }, 'Minion::Backend::SQLite' => { - package => { deb => 'libminion-backend-sqlite-perl', }, + 'package' => { + 'deb' => 'libminion-backend-sqlite-perl' + } }, 'Mojolicious' => { - package => { deb => 'libmojolicious-perl', }, - minversion => 9.34, + 'minversion' => '9.34', + 'package' => { + 'deb' => 'libmojolicious-perl', + 'rpm' => 'perl-Mojolicious' + } }, 'Mojolicious::Plugin::NotYAMLConfig' => { - package => { deb => 'libmojolicious-perl', }, + 'package' => { + 'deb' => 'libmojolicious-perl', + 'rpm' => 'perl-Mojolicious' + } }, 'Mojolicious::Plugin::RenderFile' => { - package => { deb => 'libmojolicious-plugin-renderfile-perl', }, + 'package' => { + 'deb' => 'libmojolicious-plugin-renderfile-perl' + } }, 'Net::IP' => { - package => { deb => 'libnet-ip-perl', }, + 'package' => { + 'deb' => 'libnet-ip-perl', + 'rpm' => 'perl-Net-IP' + } }, 'Net::OAuth' => { - package => { deb => 'libnet-oauth-perl', }, + 'package' => { + 'deb' => 'libnet-oauth-perl', + 'rpm' => 'perl-Net-OAuth' + } }, 'Opcode' => { - package => { deb => 'libperl', }, + 'package' => { + 'deb' => 'libperl', + 'rpm' => 'perl-Opcode' + } + }, + 'PHP::Serialization' => { + 'package' => { + 'deb' => 'libphp-serialization-perl', + 'rpm' => 'perl-PHP-Serialization' + } }, 'Pandoc' => { - package => { deb => 'libpandoc-wrapper-perl', }, + 'package' => { + 'deb' => 'libpandoc-wrapper-perl' + } }, 'Perl::Critic' => { - package => { deb => 'libperl-critic-perl', }, + 'package' => { + 'deb' => 'libperl-critic-perl', + 'rpm' => 'perl-Perl-Critic' + } }, 'Perl::Tidy' => { - package => { deb => 'perltidy', }, - }, - 'PHP::Serialization' => { - package => { deb => 'libphp-serialization-perl', }, + 'package' => { + 'deb' => 'perltidy', + 'rpm' => 'perltidy' + } }, 'Pod::Simple::Search' => { - package => { deb => 'perl-modules', }, + 'package' => { + 'deb' => 'perl-modules', + 'rpm' => 'perl-Pod-Simple' + } }, 'Pod::Simple::XHTML' => { - package => { deb => 'perl-modules', }, + 'package' => { + 'deb' => 'perl-modules', + 'rpm' => 'perl-Pod-Simple' + } }, 'Pod::Usage' => { - package => { deb => 'perl-modules', }, + 'package' => { + 'deb' => 'perl-modules', + 'rpm' => 'perl-Pod-Usage' + } }, 'Pod::WSDL' => { - package => { deb => 'libpod-wsdl-perl', }, - }, - 'Scalar::Util' => { - package => { deb => 'perl-base', }, + 'package' => { + 'deb' => 'libpod-wsdl-perl' + } }, 'SOAP::Lite' => { - package => { deb => 'libsoap-lite-perl', }, - }, - 'Socket' => { - package => { deb => 'perl-base', }, + 'package' => { + 'deb' => 'libsoap-lite-perl', + 'rpm' => 'perl-SOAP-Lite' + } }, 'SQL::Abstract' => { - package => { deb => 'libsql-abstract-perl', }, - minversion => 2.000000, - }, - 'String::ShellQuote' => { - package => { deb => 'libstring-shellquote-perl', }, + 'minversion' => '2', + 'package' => { + 'deb' => 'libsql-abstract-perl', + 'rpm' => 'perl-SQL-Abstract' + } }, 'SVG' => { - package => { deb => 'libsvg-perl', }, + 'package' => { + 'deb' => 'libsvg-perl', + } + }, + 'Scalar::Util' => { + 'package' => { + 'deb' => 'perl-base', + 'rpm' => 'perl-Scalar-List-Utils' + } + }, + 'Socket' => { + 'package' => { + 'deb' => 'perl-base', + 'rpm' => 'perl-Socket' + } + }, + 'String::ShellQuote' => { + 'package' => { + 'deb' => 'libstring-shellquote-perl', + 'rpm' => 'perl-String-ShellQuote' + } }, 'Text::CSV' => { - package => { deb => 'libtext-csv-perl', }, + 'package' => { + 'deb' => 'libtext-csv-perl', + 'rpm' => 'perl-Text-CSV' + } }, 'Text::Wrap' => { - package => { deb => 'perl-base', }, + 'package' => { + 'deb' => 'perl-base', + 'rpm' => 'perl-Text-Tabs+Wrap' + } }, 'Tie::IxHash' => { - package => { deb => 'libtie-ixhash-perl', }, + 'package' => { + 'deb' => 'libtie-ixhash-perl', + 'rpm' => 'perl-Tie-IxHash' + } }, 'Time::HiRes' => { - package => { deb => 'libperl', }, + 'package' => { + 'deb' => 'libperl', + 'rpm' => 'perl-Time-HiRes' + } }, 'Time::Zone' => { - package => { deb => 'libtimedate-perl', }, + 'package' => { + 'deb' => 'libtimedate-perl', + 'rpm' => 'perl-TimeDate' + } }, 'Types::Serialiser' => { - package => { deb => 'libtypes-serialiser-perl', }, + 'package' => { + 'deb' => 'libtypes-serialiser-perl', + 'rpm' => 'perl-Types-Serialiser' + } }, 'URI::Escape' => { - package => { deb => 'liburi-perl', }, + 'package' => { + 'deb' => 'liburi-perl', + 'rpm' => 'perl-URI' + } }, 'UUID::Tiny' => { - package => { deb => 'libuuid-tiny-perl', }, + 'package' => { + 'deb' => 'libuuid-tiny-perl', + 'rpm' => 'perl-UUID-Tiny' + } }, 'XML::LibXML' => { - package => { deb => 'libxml-libxml-perl', }, + 'package' => { + 'deb' => 'libxml-libxml-perl', + 'rpm' => 'perl-XML-LibXML' + } }, 'XML::Parser' => { - package => { deb => 'libxml-parser-perl', }, + 'package' => { + 'deb' => 'libxml-parser-perl', + 'rpm' => 'perl-XML-Parser' + } }, 'XML::Parser::EasyTree' => { - package => { deb => 'libxml-parser-easytree-perl', }, + 'package' => { + 'deb' => 'libxml-parser-easytree-perl' + } }, 'XML::Writer' => { - package => { deb => 'libxml-writer-perl', }, + 'package' => { + 'deb' => 'libxml-writer-perl', + 'rpm' => 'perl-XML-Writer' + } }, 'YAML::XS' => { - package => { deb => 'libyaml-libyaml-perl', }, - }, + 'package' => { + 'deb' => 'libyaml-libyaml-perl', + 'rpm' => 'perl-YAML-LibYAML' + } + } ); my %moduleVersion = ( From 02299daa4ab7011e76037d72664a552b78fde2be Mon Sep 17 00:00:00 2001 From: Danny Glin Date: Mon, 19 Jan 2026 16:37:22 -0700 Subject: [PATCH 5/5] Add suggested install command for missing packages --- bin/check_modules.pl | 45 ++++++++++++++++++++++++++++++++------------ 1 file changed, 33 insertions(+), 12 deletions(-) diff --git a/bin/check_modules.pl b/bin/check_modules.pl index 6231026db7..35d159567b 100755 --- a/bin/check_modules.pl +++ b/bin/check_modules.pl @@ -12,6 +12,9 @@ =head1 SYNOPSIS Options: -m|--modules Check that the perl modules needed by webwork2 can be loaded. -p|--programs Check that the programs needed by webwork2 exist. + -k|--packagetype Specify what type of packages your system uses. + For debian-based systems (e.g. Ubuntu), use 'deb' + For Red Hat-based systems (e.g. RHEL, Oracle), use 'rpm' Both programs and modules are checked if no options are given. @@ -518,14 +521,6 @@ =head1 DESCRIPTION } ); -my %moduleVersion = ( - 'Future::AsyncAwait' => 0.52, - 'IO::Socket::SSL' => 2.007, - 'LWP::Protocol::https' => 6.06, - 'Mojolicious' => 9.34, - 'SQL::Abstract' => 2.000000 -); - my @programList = qw( convert curl @@ -544,19 +539,29 @@ =head1 DESCRIPTION dvipng ); -my ($test_modules, $test_programs, $show_help); +my ($test_modules, $test_programs, $packagetype, $show_help); GetOptions( - 'm|modules' => \$test_modules, - 'p|programs' => \$test_programs, - 'h|help' => \$show_help, + 'm|modules' => \$test_modules, + 'p|programs' => \$test_programs, + 'k|packagetype=s' => \$packagetype, + 'h|help' => \$show_help, ); + pod2usage(2) if $show_help; +if ($packagetype && $packagetype ne 'rpm' && $packagetype ne 'deb') { + die 'packagetype must be one of \'deb\' or \'rpm\''; +} + +my %packagemgrcommand = ('deb' => 'sudo apt install ', 'rpm' => 'sudo dnf install '); + $test_modules = $test_programs = 1 unless $test_programs || $test_modules; my @PATH = split(/:/, $ENV{PATH}); +my (@missing_packages, @missing_modules); + check_modules() if $test_modules; say '' if $test_modules && $test_programs; check_apps() if $test_programs; @@ -584,6 +589,13 @@ sub check_modules { my $file = ($module =~ s|::|/|gr) . '.pm'; if ($@ =~ /Can't locate $file in \@INC/) { say "** $module not found in \@INC"; + if ($packagetype) { + if ($modulesList{$module}{package}{$packagetype}) { + push(@missing_packages, $modulesList{$module}{package}{$packagetype}); + } else { + push(@missing_modules, $module); + } + } } else { say "** $module found, but failed to load: $@"; } @@ -605,6 +617,15 @@ sub check_modules { if ($moduleNotFound) { say ''; say 'Some required modules were not found, could not be loaded, or were not at the sufficient version.'; + if (@missing_modules || @missing_packages) { + say 'You can try to install the missing modules with the following command(s)'; + if (@missing_modules) { + say 'sudo cpanm ' . join(' ', @missing_modules); + } + if (@missing_packages) { + say $packagemgrcommand{$packagetype} . join(' ', @missing_packages); + } + } say 'Exiting as this is required to check the database driver and programs.'; exit 0; }