Name

Require — require existence of a capability

SYNOPSIS

type type-specific_value ...

DESCRIPTION

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

DIRECTIVE TYPE AND DEFAULT VALUE

Global directive,
Catalog directive

EXAMPLES

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 existence of old-style Perl modules

Require module /path/to/module.pl

Example: Requiring features

Require module    Archive::Zip
Require usertag   table_editor
Require globalsub file_info

Example: Loading module with expanded search path

Require module Vend::Swish /usr/lib/swish-e/perl

NOTES

AVAILABILITY

Require is available in Interchange versions:

4.6.0-5.9.0 (git-head)

SOURCE

Interchange 5.9.0:

Source: lib/Vend/Config.pm
Line 401

['Require',       'require',       ''],

Source: lib/Vend/Config.pm
Line 549

['Require',       'require',       ''],

Source: lib/Vend/Config.pm
Line 2685 (context shows lines 2685-2856)

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);
      }
      eval "require $module$oldtype;";
      my $error = $@;
      if ($pathinfo) {
        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 '';  
}

AUTHORS

Interchange Development Group

SEE ALSO

Capability(7ic), Suggest(7ic)

DocBook! Interchange!