The London Perl and Raku Workshop takes place on 26th Oct 2024. If your company depends on Perl, please consider sponsoring and/or attending.

NAME

App::CELL::Load -- find and load message files and config files

VERSION

Version 0.170

SYNOPSIS

    use App::CELL::Load;

    # Load App::CELL's internal messages and config params and then
    # attempt to load the application's messages and config params
    $status = App::CELL::Load::init();
    return $status if $status->not_ok;

    # attempt to determine the site configuration directory
    my $sitedir = App::CELL::Load::get_sitedir();

    # get a reference to a list of configuration files (full paths) of a
    # given type under a given directory
    my $metafiles = App::CELL::Load::find_files( '/etc/CELL', 'meta' );
   
    # load messages from all message file in a given directory and all its
    # subdirectories
    $status = message_files( '/etc/CELL' );

    # load meta, core, and site params from all meta, core, and site
    # configuration files in a given directory and all its subdirectories
    $status = meta_core_site_files( '/etc/CELL' );

DESCRIPTION

The purpose of the App::CELL::Load module is to provide message and config file finding and loading functionality to the App::CELL::Message and App::CELL::Config modules.

PACKAGE VARIABLES

This module provides the following package variables

$sharedir - the full path of the sharedir
$sharedir_loaded - whether it has been loaded or not
$sitedir - the full path of the site configuration directory
$sitedir_loaded - whether it has been loaded or not

MODULES

init

Re-entrant initialization function.

On first call, initializes all three site configuration hashes by performing the following actions:

1. load App::CELL's internal messages and meta, core, and site params from the distro share directory determined using File::ShareDir (i.e. the config/ directory of the distro, wherever it happens to be installed)
2. determine the "site dir" (site configuration directory) by first looking for a 'sitedir' argument to the function and, failing that, looking for a 'CELL_SITE procedure described in ...WIP...
3. if a viable site dir is found, load messages and meta, core, and site params from it.

Subsequent calls check package variables to determine status of previous calls. For example, if no sharedir is found, a critical error is raised. The application could theoretically attempt to fix this and try again. Or, it might happen that the sharedir is loaded as expected, but the sitedir is not found, in which case on the second call the initialization routine would try again to find the sitedir.

Once a directory has been loaded, there is no way to "undo" it, and App::CELL will not look at that directory again.

Upon success the routine sets the following App::CELL params:

CELL_META_SHAREDIR_LOADED - meta param (boolean)
CELL_SHAREDIR_FULLPATH - site param (scalar)
CELL_META_SITEDIR_LOADED - meta param (boolean)
CELL_SITEDIR_FULLPATH - site param (array ref)

Optionally takes a PARAMHASH. The following arguments are recognized:

appname - name of the application
sitedir - full path to the/a site dir

E.g.:

    my $status = App::CELL::Load::init( appname => 'FooBar', 
        sitedir => '/etc/FooBar' );

If no sitedir is provided (through either the argument list or the environment), return status will be 'ok' provided the sharedir was found and loaded; otherwise, an 'ERR' status is returned.

If a sitedir is provided, yet not successfully loaded, an 'ERR' status will be returned.

message_files

Loads message files from the given directory. Takes: full path to configuration directory. Returns: result hash containing 'quantfiles' (total number of files processed) and 'count' (total number of messages loaded).

meta_core_site_files

Loads meta, core, and site config files from the given directory. Takes: full path to configuration directory. Returns: result hash containing 'quantfiles' (total number of files processed) and 'count' (total number of configuration parameters loaded).

get_sitedir

Look in various places (in a pre-defined order) for the site configuration directory. Stop as soon as we come up with a viable candidate. On success, returns a string containing an absolute directory path. On failure, returns undef.

find_files

Takes two arguments: full directory path and config file type.

Always returns an array reference. On "failure", the array reference will be empty.

How it works: first, the function checks a state variable to see if the "work" of walking the configuration directory has already been done. If so, then the function simply returns the corresponding array reference from its cache (the state hash %resultlist). If this is the first invocation for this directory, the function walks the directory (and all its subdirectories) to find files matching one of the four regular expressions corresponding to the four types of configuration files('meta', 'core', 'site', 'message'). For each matching file, the full path is pushed onto the corresponding array in the cache.

Note that there is a ceiling on the number of files that will be considered while walking the directory tree. This ceiling is defined in the package variable $max_files (see below).

parse_message_file

This function is where message files are parsed. It takes a PARAMHASH consisting of:

File - filename (full path)
Dest - hash reference (where to store the message templates).

Returns: number of stanzas successfully parsed and loaded

parse_config_file

Parses a configuration file and adds the parameters found to the hashref provided. If a parameter already exists in the hashref, a warning is generated, the existing parameter is not overwritten, and processing continues.

This function doesn't care what type of configuration parameters are in the file, except that they must be scalar values. Since the configuration files are actually Perl modules, the value can even be a reference (to an array, a hash, or a subroutine, or any other complex data structure).

The technique used in the eval, derived from Request Tracker, can be described as follows: a local typeglob "set" is defined, containing a reference to an anonymous subroutine. Subsequently, a config file (Perl module) consisting of calls to this "set" subroutine is required.

Note: If even one call to set fails to compile, the entire file will be rejected and no configuration parameters from that file will be loaded.

The parse_config_file function takes a PARAMHASH consisting of:

File - filename (full path)
Dest - hash reference (where to store the config params).

Returns: number of configuration parameters parsed/loaded

(IMPORTANT NOTE: If even one call to set fails to compile, the entire file will be rejected and no configuration parameters from that file will be loaded.)

_conf_from_config

This function takes a target hashref (which points to one of the 'meta', 'core', or 'site' package hashes in App::CELL::Config), a config parameter (i.e. a string), config value, config file name, and line number.

Let's imagine that the configuration parameter is "FOO_BAR". The function first checks if a key named "FOO_BAR" already exists in the package hash (which is passed into the function as %ARGS{'Dest'}). If there isn't one, it creates that key. If there is one, it leaves it untouched and triggers a warning.

Although the arguments are passed to the function in the form of a PARAMHASH, the function converts them into ordinary private variables. This was necessary to avoid extreme notational ugliness.