Skip to content

Commit 75fe00f

Browse files
committed
Rework check_modules.pl.
The script now uses the settings in the course environment for external programs and to check the database driver (DBD::mysql or DBD::MariaDB). In order for that to work, first the script checks that all of the needed modules are found, load, and are at the sufficient version. That is except for the database driver module. If any are not found, then the script exits with a message stating that it is unable to continue without the required modules. If all modules are good, then the script checks the database driver module next. For this it "runtime" loads the course environment and its dependencies (as well as a runtime detection of the webwork2 root and lib directories). This is to address issue #2740. In addition the following modules are removed that are no longer needed: * Array::Utils * Email::Sender::Simple - still used but is a dependency of Email::Stuffer and doesn't need to be checked separately * HTML::Tagset * HTML::Template * IO::Socket::SSL * Net::LDAPS * Net::SMPT * Net::SSLeay * PadWalker * Path::Class * Safe - we use our local version (WWSafe.pm) and still check Opcode which it uses * Template `npm` is added to the list of required applications. Most of these things were noted in issue #1917.
1 parent 82ac1ff commit 75fe00f

File tree

1 file changed

+117
-87
lines changed

1 file changed

+117
-87
lines changed

bin/check_modules.pl

Lines changed: 117 additions & 87 deletions
Original file line numberDiff line numberDiff line change
@@ -1,53 +1,39 @@
11
#!/usr/bin/env perl
2-
#
32

43
=head1 NAME
54
6-
check_modules.pl - check to ensure that all applications and perl modules are installed.
5+
check_modules.pl - Check to ensure that applications and perl modules needed by
6+
webwork2 are installed.
77
88
=head1 SYNOPSIS
99
1010
check_modules.pl [options]
1111
1212
Options:
13-
-m|--modules Lists the perl modules needed to be installed.
14-
-p|--programs Lists the programs/applications that are needed.
15-
-A|--all checks both programs and modules (Default if -m or -p is not selected)
13+
-m|--modules Check that the perl modules needed by webwork2 can be loaded.
14+
-p|--programs Check that the programs needed by webwork2 exist.
15+
16+
Both programs and modules are checked if no options are given.
1617
1718
=head1 DESCRIPTION
1819
19-
Lists all needed applications for webwork as well as a perl modules.
20+
Checks that modules needed by webwork2 can be loaded and are at the sufficient
21+
version, and that applications needed by webwork2 exist.
2022
2123
=cut
2224

2325
use strict;
2426
use warnings;
2527
use version;
28+
use feature 'say';
29+
2630
use Getopt::Long qw(:config bundling);
2731
use Pod::Usage;
2832

29-
my @applicationsList = qw(
30-
convert
31-
curl
32-
dvisvgm
33-
mkdir
34-
mv
35-
mysql
36-
node
37-
tar
38-
git
39-
gzip
40-
latex
41-
pandoc
42-
xelatex
43-
dvipng
44-
);
45-
4633
my @modulesList = qw(
4734
Archive::Tar
4835
Archive::Zip
4936
Archive::Zip::SimpleZip
50-
Array::Utils
5137
Benchmark
5238
Carp
5339
Class::Accessor
@@ -60,12 +46,10 @@ =head1 DESCRIPTION
6046
Date::Format
6147
Date::Parse
6248
DateTime
63-
DBD::mysql
6449
DBI
6550
Digest::MD5
6651
Digest::SHA
6752
Email::Address::XS
68-
Email::Sender::Simple
6953
Email::Sender::Transport::SMTP
7054
Email::Stuffer
7155
Errno
@@ -85,11 +69,8 @@ =head1 DESCRIPTION
8569
Getopt::Long
8670
Getopt::Std
8771
HTML::Entities
88-
HTML::Tagset
89-
HTML::Template
9072
HTTP::Async
9173
IO::File
92-
IO::Socket::SSL
9374
Iterator
9475
Iterator::Util
9576
Locale::Maketext::Lexicon
@@ -104,29 +85,22 @@ =head1 DESCRIPTION
10485
Mojolicious::Plugin::NotYAMLConfig
10586
Mojolicious::Plugin::RenderFile
10687
Net::IP
107-
Net::LDAPS
10888
Net::OAuth
109-
Net::SMTP
110-
Net::SSLeay
11189
Opcode
112-
PadWalker
11390
Pandoc
114-
Path::Class
11591
Perl::Tidy
11692
PHP::Serialization
11793
Pod::Simple::Search
11894
Pod::Simple::XHTML
11995
Pod::Usage
12096
Pod::WSDL
121-
Safe
12297
Scalar::Util
12398
SOAP::Lite
12499
Socket
125100
SQL::Abstract
126101
Statistics::R::IO
127102
String::ShellQuote
128103
SVG
129-
Template
130104
Text::CSV
131105
Text::Wrap
132106
Tie::IxHash
@@ -147,90 +121,146 @@ =head1 DESCRIPTION
147121
'IO::Socket::SSL' => 2.007,
148122
'LWP::Protocol::https' => 6.06,
149123
'Mojolicious' => 9.34,
150-
'Net::SSLeay' => 1.46,
151124
'SQL::Abstract' => 2.000000
152125
);
153126

154-
my ($test_programs, $test_modules, $show_help);
155-
my $test_all = 1;
127+
my @programList = qw(
128+
convert
129+
curl
130+
mkdir
131+
mv
132+
mysql
133+
mysqldump
134+
node
135+
npm
136+
tar
137+
git
138+
gzip
139+
latex
140+
latex2pdf
141+
pandoc
142+
dvipng
143+
);
144+
145+
my ($test_modules, $test_programs, $show_help);
156146

157147
GetOptions(
158148
'm|modules' => \$test_modules,
159149
'p|programs' => \$test_programs,
160-
'A|all' => \$test_all,
161150
'h|help' => \$show_help,
162151
);
163152
pod2usage(2) if $show_help;
164153

165-
my @PATH = split(/:/, $ENV{PATH});
166-
167-
if ($test_all or $test_programs) {
168-
check_apps(@applicationsList);
169-
}
170-
171-
if ($test_all or $test_modules) {
172-
check_modules(@modulesList);
173-
}
154+
$test_modules = $test_programs = 1 unless $test_programs || $test_modules;
174155

175-
sub check_apps {
176-
my @applicationsList = @_;
177-
print "\nChecking your \$PATH for executables required by WeBWorK...\n";
178-
print "\$PATH=";
179-
print join("\n", map(" $_", @PATH)), "\n\n";
180-
181-
foreach my $app (@applicationsList) {
182-
my $found = which($app);
183-
if ($found) {
184-
print " $app found at $found\n";
185-
} else {
186-
print "** $app not found in \$PATH\n";
187-
}
188-
}
189-
190-
## Check that the node version is sufficient.
191-
my $node_version_str = qx/node -v/;
192-
my ($node_version) = $node_version_str =~ m/v(\d+)\./;
156+
my @PATH = split(/:/, $ENV{PATH});
193157

194-
print "\n\n**The version of node should be at least 16. You have version $node_version"
195-
if ($node_version < 16);
196-
}
158+
check_modules() if $test_modules;
159+
say '' if $test_modules && $test_programs;
160+
check_apps() if $test_programs;
197161

198162
sub which {
199-
my $app = shift;
200-
foreach my $path (@PATH) {
201-
return "$path/$app" if -e "$path/$app";
163+
my $program = shift;
164+
for my $path (@PATH) {
165+
return "$path/$program" if -e "$path/$program";
202166
}
167+
return;
203168
}
204169

205170
sub check_modules {
206-
my @modulesList = @_;
171+
say "Checking for modules required by WeBWorK...";
207172

208-
print "\nChecking your \@INC for modules required by WeBWorK...\n";
209-
my @inc = @INC;
210-
print "\@INC=";
211-
print join("\n", map(" $_", @inc)), "\n\n";
173+
my $moduleNotFound = 0;
212174

213-
no strict 'refs';
175+
my $checkModule = sub {
176+
my $module = shift;
214177

215-
foreach my $module (@modulesList) {
178+
no strict 'refs';
216179
eval "use $module";
217180
if ($@) {
218-
my $file = $module;
219-
$file =~ s|::|/|g;
220-
$file .= ".pm";
181+
$moduleNotFound = 1;
182+
my $file = ($module =~ s|::|/|gr) . '.pm';
221183
if ($@ =~ /Can't locate $file in \@INC/) {
222-
print "** $module not found in \@INC\n";
184+
say "** $module not found in \@INC";
223185
} else {
224-
print "** $module found, but failed to load: $@";
186+
say "** $module found, but failed to load: $@";
225187
}
226188
} elsif (defined($moduleVersion{$module})
227189
&& version->parse(${ $module . '::VERSION' }) < version->parse($moduleVersion{$module}))
228190
{
229-
print "** $module found, but not version $moduleVersion{$module} or better\n";
191+
$moduleNotFound = 1;
192+
say "** $module found, but not version $moduleVersion{$module} or better";
193+
} else {
194+
say " $module found and loaded";
195+
}
196+
use strict 'refs';
197+
};
198+
199+
for my $module (@modulesList) {
200+
$checkModule->($module);
201+
}
202+
203+
if ($moduleNotFound) {
204+
say '';
205+
say 'Some requred modules were not found, could not be loaded, or were not at the sufficient version.';
206+
say 'Exiting as this is required to check the database driver and programs.';
207+
exit 0;
208+
}
209+
210+
say '';
211+
say 'Checking for the database driver required by WeBWorK...';
212+
my $ce = loadCourseEnvironment();
213+
my $driver = $ce->{database_driver} =~ /^mysql$/i ? 'DBD::mysql' : 'DBD::MariaDB';
214+
say "Configured to use $driver in site.conf";
215+
$checkModule->($driver);
216+
217+
return;
218+
}
219+
220+
sub check_apps {
221+
my $ce = loadCourseEnvironment();
222+
223+
say 'Checking external programs required by WeBWorK...';
224+
225+
push(@programList, $ce->{pg}{specialPGEnvironmentVars}{latexImageSVGMethod});
226+
227+
for my $program (@programList) {
228+
if ($ce->{externalPrograms}{$program}) {
229+
# Remove command line arguments (for latex and latex2pdf).
230+
my $executable = $ce->{externalPrograms}{$program} =~ s/ .*$//gr;
231+
if (-e $executable) {
232+
say " $executable found for $program";
233+
} else {
234+
say "** $executable not found for $program";
235+
}
230236
} else {
231-
print " $module found and loaded\n";
237+
my $found = which($program);
238+
if ($found) {
239+
say " $found found for $program";
240+
} else {
241+
say "** $program not found in \$PATH";
242+
}
232243
}
233244
}
245+
246+
# Check that the node version is sufficient.
247+
my $node_version_str = qx/node -v/;
248+
my ($node_version) = $node_version_str =~ m/v(\d+)\./;
249+
250+
say "\n**The version of node should be at least 18. You have version $node_version."
251+
if $node_version < 18;
252+
253+
return;
254+
}
255+
256+
sub loadCourseEnvironment {
257+
eval 'require Mojo::File';
258+
die "Unable to load Mojo::File: $@" if $@;
259+
my $webworkRoot = Mojo::File->curfile->dirname->dirname;
260+
push @INC, "$webworkRoot/lib";
261+
eval 'require WeBWorK::CourseEnvironment';
262+
die "Unable to load WeBWorK::CourseEnvironment: $@" if $@;
263+
return WeBWorK::CourseEnvironment->new({ webwork_dir => $webworkRoot });
234264
}
235265

236266
1;

0 commit comments

Comments
 (0)