Require — require existence of a capability
Just like Capability
or Suggest
, this directive checks for
a feature or capability. When the tested feature is missing, a
catalog is not configured and not included in global configuration.
This is useful to ensure that needed facilities are present, especially if you run the catalog on different locations.
"Capabilities" you can require are:
globalsub
— existence of a GlobalSub
sub
— existence of a Sub
taggroup
— existence of a TagGroup
usertag
— existence of a UserTag
module (or perlmodule)
— existence of a Perl module. Optional additional argument is the custom Perl module path.
include (or perlinclude)
— prepend specified path to Perl's @INC
include path (makes most sense with Require
, not with Suggest
or Capability
even though it can be called that way for equivalent effect)
file
— existence of a readable file
executable
— existence of an executable file
Example: Requiring existence of all supported items
Require globalsub my_global_sub Require sub my_sub Require taggroup :group1,:group2 :group3 Require usertag my_global_usertag Require usertag my_catalog_usertag Require module Archive::Zip Require module Set::Crontab /usr/local/perl/modules/ Require file /etc/syslog.conf Require file relative-dir/file Require executable /usr/local/bin/gfont Require executable bin/gfont
Example: Requiring features
Require module Archive::Zip Require usertag table_editor Require globalsub file_info
Interchange 5.9.0:
Source: lib/Vend/Config.pm
Line 2690 (context shows lines 2690-2863)
sub parse_require { my($var, $val, $warn, $cap) = @_; return if $Vend::ExternalProgram; return if $Vend::ControllingInterchange; my $carptype; my $error_message; my $pathinfo; if($val =~ s/\s+"(.*)"//s) { $error_message = "\a\n\n$1\n"; } if($val =~ s%\s+((/[\w.-]+)+)%%) { $pathinfo = $1; } if($cap) { $carptype = sub { return; }; } elsif($warn) { $carptype = sub { return parse_message('', @_) }; $error_message = "\a\n\nSuggest %s %s for proper catalog operation. \ Not all functions will work!\n" unless $error_message; } else { $carptype = \&config_error; $error_message ||= 'Required %s %s not present. Aborting ' . ($C ? 'catalog' : 'Interchange daemon') . '.'; } my $nostrict; my $perlglobal = 1; if($C) { $nostrict = $Global::PerlNoStrict->{$C->{CatalogName}}; $perlglobal = $Global::AllowGlobal->{$C->{CatalogName}}; } my $vref = $C ? $C->{Variable} : $Global::Variable; my $require; my $testsub = sub { 0 }; my $name; if($val =~ s/^globalsub\s+//i) { $require = $Global::GlobalSub; $name = 'GlobalSub'; } elsif($val =~ s/^sub\s+//i) { $require = $C->{Sub}; $name = 'Sub'; } elsif($val =~ s/^taggroup\s+//i) { $require = $Global::UserTag->{Routine}; my @groups = grep /\S/, split /[\s,]+/, $val; my @needed; my $ref; for (@groups) { if($ref = $Global::TagGroup->{$_}) { push @needed, @$ref; } else { push @needed, $_; } } $name = "TagGroup $val member"; $val = join " ", @needed; } elsif($val =~ s/^usertag\s+//i) { $require = {}; $name = 'UserTag'; $testsub = sub { my $name = shift; my @tries = ($Global::UserTag->{Routine}); push(@tries,$C->{UserTag}->{Routine}) if $C; foreach (@tries) { return 1 if defined $_->{$name}; } return 0; }; } elsif($val =~ s/^(?:perl)?module\s+//i) { $require = {}; $name = 'Perl module'; $testsub = sub { my $module = shift; my $oldtype = ''; if($module =~ s/\.pl$//) { $oldtype = '.pl'; } $module =~ /[^\w:]/ and return undef; if($perlglobal) { if ($pathinfo) { unshift(@INC, $pathinfo); unshift(@INC, "$pathinfo/$Config{archname}"); } eval "require $module$oldtype;"; my $error = $@; if ($pathinfo) { shift(@INC); shift(@INC); } ::logGlobal("while eval'ing module %s got [%s]\n", $module, $error) if $error; return ! $error; } else { # Since we aren't safe to actually require, we will # just look for a readable module file $module =~ s!::!/!g; $oldtype = '.pm' if ! $oldtype; my $found; for(@INC) { next unless -f "$_/$module$oldtype" and -r _; $found = 1; } return $found; } }; } elsif ($val =~ s/^(?:perl)?include\s+//i) { my $path = Vend::File::make_absolute_file($val, 1); $require = {}; $name = 'Perl include path'; $testsub = sub { if (-d $path) { unshift @INC, $path; return 1; } return 0; }; } elsif ($val =~ s/^file\s*//i) { $require = {}; $name = 'Readable file'; $val = $pathinfo unless $val; $testsub = sub { my $path = Vend::File::make_absolute_file(shift, $C ? 0 : 1); if ($C && $path =~ s:^/+::) { $path = "$C->{VendRoot}/$path"; } return -r $path; }; } elsif ($val =~ s/^executable\s*//i) { $require = {}; $name = 'Executable file'; $val = $pathinfo unless $val; $testsub = sub { my $path = Vend::File::make_absolute_file(shift, $C ? 0 : 1); if ($C && $path =~ s:^/+::) { $path = "$C->{VendRoot}/$path"; } return -x $path; }; } my @requires = grep /\S/, split /\s+/, $val; my $uname = uc $name; $uname =~ s/.*\s+//; for(@requires) { $vref->{"MV_REQUIRE_${uname}_$_"} = 1; next if defined $require->{$_}; next if $testsub->($_); delete $vref->{"MV_REQUIRE_${uname}_$_"}; $carptype->( $error_message, $name, $_ ); } return ''; }