From 8c376d1e3beca0aedf81e6840e5cc385e1d65d95 Mon Sep 17 00:00:00 2001 From: Alain Reguera Delgado Date: Oct 20 2013 15:42:09 +0000 Subject: Update understanding_modules.asciidoc file. - The article is rather complete by now. The relevant information that motivated the article creation has been put in place already but it needs revisions, still. --- diff --git a/Automation/Manuals/Understanding_Modules/understanding_modules.asciidoc b/Automation/Manuals/Understanding_Modules/understanding_modules.asciidoc index ffdb5ac..8dc8f20 100644 --- a/Automation/Manuals/Understanding_Modules/understanding_modules.asciidoc +++ b/Automation/Manuals/Understanding_Modules/understanding_modules.asciidoc @@ -44,7 +44,7 @@ desired result. Module environments are executed and destroyed at demand. Inside *centos-art.sh*, module environments can be either ``parent modules,'' ``child modules,'' or ``sibling modules.'' -[[module-environment-parent]] +[[parent-modules-environment]] Parent Modules ~~~~~~~~~~~~~~ @@ -99,631 +99,191 @@ action. With this information you can create your own module environment, already. However, when your module is getting too much complicated you probably want to divide it in smaller pieces that you can execute accordingly, based on the purpose you defined for it. Such -kind of division can be implemented through ``modules' related -functions.'' - -Module's related functions are stored in the same directory of your -module's initialization file and they are very useful when you are -refactoring it. Definitions of module's related functions are loaded -before the initialization file does, so it is a good practice to -create them only when you are absolutely sure they will be executed in -your module. Otherwise they may be loaded and never be used, which -make the script to waste memory unnecessarily. In these cases, when -you need to divide the logic of a module in smaller pieces where these -pieces may or may not be executed based on specific conditions, all -taking place in the same iteration, then using ``_child modules_'' is -a more suitable approach. +kind of division can be implemented as described in +<>. -Child Modules -~~~~~~~~~~~~~ +Summary +~~~~~~~ -Child modules are initiated by executing the -*tcar_setModuleEnvironment* function with the *-t child* option set on -it. Child modules have the characteristic of being nested modules. -They cannot be executed from the command-line. Normally, child modules -are executed from parent modules but they can be executed from other -child modules, too. When several child modules are executed in one -single iteration of *centos-art.sh*, they create a chain of modules. -A chain of modules is very useful in situations where you want to -divide one large task into smaller tasks and also control which of -these smaller tasks is executed based on specific conditions (e.g., -you may want to render images or documentation, but not both, in one -single iteration of *centos-art.sh* script). In a chain of modules, -lower modules in the chain (those started last) have access to -information set by modules higher in the chain (those started first), -but not the opposite. When processing information this way, modules -aren't destroyed until the last module executed in the chain has -finished its work (e.g., all the commands inside it have been -executed). At that point, child modules are destroyed in the reverse -order they were executed. +This section has covered basic concepts related to module environment +inside *centos-art.sh* script. The next section takes these concepts +and focuses on the implementation of them. Once you finish it, you +should be able of writing your own module environments from scratch +inside *centos-art.sh* script. -For example, when you execute the *hello* module with both *--debug* -and *--upper* option, *centos-art.sh* script creates a chain of three -modules to produce the greeting message. Firstly, it begins by -executing the parent module named *hello*, then it continues with the -child module named *output* which in turn executes the child module -name *lower* to finally print the expected greeting message. In this -example, the module named *lower* is the last module in the chain of -executed modules. It has access to all information defined by earlier -modules (e.g., in *hello* and *output* modules) and none of its earlier -modules will be destroyed until it has finished its work. This process -becomes more visible when you take a look at <>. +[[module-implementation]] +Module Implementation +--------------------- -[[debug-child-modules]] -.Debugging execution of child modules +The *centos-art.sh* script implements module environments inside the +``+Modules+'' directory, as described in <>. + +[[module-implementation-parent]] +Parent Modules +~~~~~~~~~~~~~~ + +For example, consider the creation of a module named *hello*. The +purpose of this module is to print a greeting message to standard +output and then exit successfully. To create such a module, we need to +create a directory named ``Hello'' inside the ``Modules'' directory +and put an initialization file named ``hello.sh'' inside it. Because +we want to execute the *hello* module from *centos-art.sh* script +command-line, we put it in the first level of directories of +Modules+ +directory. See <>. + +[[parent-module-layout]] +.Directory layout used by parent modules ====================================================================== ---------------------------------------------------------------------- -Thu 10 Oct 2013 11:52:41 PM CDT =========================> [0] | main -Thu 10 Oct 2013 11:52:41 PM CDT TCAR_MODULE_BASEDIR Automation/Modules -Thu 10 Oct 2013 11:52:41 PM CDT TCAR_MODULE_NAME [0]=hello -Thu 10 Oct 2013 11:52:41 PM CDT TCAR_MODULE_TYPE parent -Thu 10 Oct 2013 11:52:41 PM CDT TCAR_MODULE_ARGUMENT --upper --greeting=hi -Thu 10 Oct 2013 11:52:41 PM CDT TCAR_MODULE_LIST hello|help|locale|prepare|render|tuneup|vcs -Thu 10 Oct 2013 11:52:41 PM CDT TCAR_MODULE_DIR Automation/Modules/Hello -Thu 10 Oct 2013 11:52:41 PM CDT TCAR_MODULE_DIR_MODULES Automation/Modules/Hello/Modules -Thu 10 Oct 2013 11:52:41 PM CDT TCAR_MODULE_DIR_MANUALS Automation/Modules/Hello/Manuals -Thu 10 Oct 2013 11:52:41 PM CDT TCAR_MODULE_DIR_LOCALES Automation/Modules/Hello/Locales -Thu 10 Oct 2013 11:52:41 PM CDT TCAR_MODULE_DIR_CONFIGS Automation/Modules/Hello/Configs -Thu 10 Oct 2013 11:52:41 PM CDT TCAR_MODULE_INIT_FILE Automation/Modules/Hello/hello.sh -Thu 10 Oct 2013 11:52:41 PM CDT TEXTDOMAIN hello.sh -Thu 10 Oct 2013 11:52:41 PM CDT TEXTDOMAINDIR Automation/Modules/Hello/Locales -Thu 10 Oct 2013 11:52:41 PM CDT export -f hello -Thu 10 Oct 2013 11:52:41 PM CDT export -f hello_getOptions -Thu 10 Oct 2013 11:52:41 PM CDT -------------------------> hello --upper --greeting=hi -Thu 10 Oct 2013 11:52:41 PM CDT =========================> [1] | hello -Thu 10 Oct 2013 11:52:41 PM CDT TCAR_MODULE_BASEDIR Automation/Modules/Hello/Modules -Thu 10 Oct 2013 11:52:41 PM CDT TCAR_MODULE_NAME [1]=output -Thu 10 Oct 2013 11:52:41 PM CDT TCAR_MODULE_TYPE child -Thu 10 Oct 2013 11:52:41 PM CDT TCAR_MODULE_ARGUMENT -Thu 10 Oct 2013 11:52:41 PM CDT TCAR_MODULE_LIST output -Thu 10 Oct 2013 11:52:41 PM CDT TCAR_MODULE_DIR Automation/Modules/Hello/Modules/Output -Thu 10 Oct 2013 11:52:41 PM CDT TCAR_MODULE_DIR_MODULES Automation/Modules/Hello/Modules/Output/Modules -Thu 10 Oct 2013 11:52:41 PM CDT TCAR_MODULE_DIR_MANUALS Automation/Modules/Hello/Modules/Output/Manuals -Thu 10 Oct 2013 11:52:41 PM CDT TCAR_MODULE_DIR_LOCALES Automation/Modules/Hello/Modules/Output/Locales -Thu 10 Oct 2013 11:52:41 PM CDT TCAR_MODULE_DIR_CONFIGS Automation/Modules/Hello/Modules/Output/Configs -Thu 10 Oct 2013 11:52:41 PM CDT TCAR_MODULE_INIT_FILE Automation/Modules/Hello/Modules/Output/output.sh -Thu 10 Oct 2013 11:52:41 PM CDT TEXTDOMAIN output.sh -Thu 10 Oct 2013 11:52:41 PM CDT TEXTDOMAINDIR Automation/Modules/Hello/Modules/Output/Locales -Thu 10 Oct 2013 11:52:41 PM CDT export -f output -Thu 10 Oct 2013 11:52:41 PM CDT -------------------------> output -Thu 10 Oct 2013 11:52:41 PM CDT =========================> [2] | output -Thu 10 Oct 2013 11:52:41 PM CDT TCAR_MODULE_BASEDIR Automation/Modules/Hello/Modules/Output/Modules -Thu 10 Oct 2013 11:52:41 PM CDT TCAR_MODULE_NAME [2]=upper -Thu 10 Oct 2013 11:52:41 PM CDT TCAR_MODULE_TYPE child -Thu 10 Oct 2013 11:52:41 PM CDT TCAR_MODULE_ARGUMENT -Thu 10 Oct 2013 11:52:41 PM CDT TCAR_MODULE_LIST camel|lower|random|upper -Thu 10 Oct 2013 11:52:41 PM CDT TCAR_MODULE_DIR Automation/Modules/Hello/Modules/Output/Modules/Upper -Thu 10 Oct 2013 11:52:41 PM CDT TCAR_MODULE_DIR_MODULES Automation/Modules/Hello/Modules/Output/Modules/Upper/Modules -Thu 10 Oct 2013 11:52:42 PM CDT TCAR_MODULE_DIR_MANUALS Automation/Modules/Hello/Modules/Output/Modules/Upper/Manuals -Thu 10 Oct 2013 11:52:42 PM CDT TCAR_MODULE_DIR_LOCALES Automation/Modules/Hello/Modules/Output/Modules/Upper/Locales -Thu 10 Oct 2013 11:52:42 PM CDT TCAR_MODULE_DIR_CONFIGS Automation/Modules/Hello/Modules/Output/Modules/Upper/Configs -Thu 10 Oct 2013 11:52:42 PM CDT TCAR_MODULE_INIT_FILE Automation/Modules/Hello/Modules/Output/Modules/Upper/upper.sh -Thu 10 Oct 2013 11:52:42 PM CDT TEXTDOMAIN upper.sh -Thu 10 Oct 2013 11:52:42 PM CDT TEXTDOMAINDIR Automation/Modules/Hello/Modules/Output/Modules/Upper/Locales -Thu 10 Oct 2013 11:52:42 PM CDT export -f upper -Thu 10 Oct 2013 11:52:42 PM CDT -------------------------> upper -HI -Thu 10 Oct 2013 11:52:42 PM CDT <------------------------- upper -Thu 10 Oct 2013 11:52:42 PM CDT unset -f upper -Thu 10 Oct 2013 11:52:42 PM CDT <========================= [2] | output -Thu 10 Oct 2013 11:52:42 PM CDT <------------------------- output -Thu 10 Oct 2013 11:52:42 PM CDT unset -f output -Thu 10 Oct 2013 11:52:42 PM CDT <========================= [1] | hello -Thu 10 Oct 2013 11:52:42 PM CDT <------------------------- hello -Thu 10 Oct 2013 11:52:42 PM CDT unset -f hello -Thu 10 Oct 2013 11:52:42 PM CDT unset -f hello_getOptions -Thu 10 Oct 2013 11:52:42 PM CDT <========================= [0] | main +. +|-- COPYING <1> +|-- Locales/ <2> +|-- Manuals/ <3> +|-- Modules/ <4> +| `-- Hello/ <5> +| |-- hello.sh <6> +| `-- hello_getOptions.sh <7> +|-- Scripts/ <8> +|-- centos-art.conf.sh <9> +`-- centos-art.sh <10> ---------------------------------------------------------------------- + +<1> Script's copying conditions. +<2> Script's localization files. +<3> Script's documentation files. +<4> Script's modules. Here is where you store parent modules. +<5> Parent directory of module named hello. +<6> Initialization file of module named hello. +<7> Function related to module named hello. +<8> Script's global functions. +<9> Script's configuration file. +<10> Script's initialization file. ====================================================================== -The module environment described in <> shows the -child modules' ability of reducing scope as they get deeper in the -chain of executed modules. However, child modules lack the possibility -of nest modules that share the same scope. For example, in the *hello* -module described above, you cannot execute the modules *lower* or -*upper* from *camel* module, as if they were child modules of it. -That is not possible because they all have the same scope, which is, -to print the greeting message to standard output. Child modules are -conceived to reduce the module scope as new child modules are -executed. When you need to execute new module environments and, also, -retain the last scope from which the new module is executed, you need -to use ``_sibling modules_,'' instead. +<> presents a complete module layout you can use +as reference to create your own module implementations. However, it is +not complete yet. At this point, when you execute *centos-art.sh*, it +is able to find out *hello* module's initialization file and execute +it but that prints an error message because the initialization file +doesn't have a function definition inside. It is completely empty. In +order for *centos-art.sh* script to do something useful, you need to +write a function definition inside the initialization file, as +described in <>. -Sibling Modules -~~~~~~~~~~~~~~~ +[[module-init-file]] +The Initialization File +~~~~~~~~~~~~~~~~~~~~~~~ -Sibling modules are initiated by executing the -*tcar_setModuleEnvironment* function with the *-t sibling* option set -on it. Sibling modules are another type of nested modules but, in -contrast with child modules, sibling modules cannot be executed from -parent modules. Normally, sibling modules are executed from other -sibling modules but, considering the context, they can be executed -from child module too, to initiate sibling processing. When several -siblings modules are executed, they also build a chain of modules. In -contrast with the chain of child modules, the chain of sibling modules -destroys the last sibling module executed before executing the next -sibling module. This make the chain to stop its growing at sibling -module processing, unless you call a child module from a sibling -module. In this case, the chain expansion would continue as long as -the number of child modules you execute. This process becomes more -visible when you take a look at <>. +The module's initialization file contains the module's main function +definition and a comment describing what it does on top of it. This +comment includes a small description about what the function does, a +written by section, the copyright note and the legal status of the +file. The function definition is set later and must be written using +the long definition format (i.e., it must begin with the word +``+function+,'' then the function name, and finally the ``+{+'' +character). The name of the function is exactly the same of the +initialization file but without the +.sh+ extension. These conditions +are required in order for *centos-art.sh* script to execute the +function definition and destroy it when it is no longer used. See +<>. -In <>, we've executed the *hello* module with -the *--greeting=hi*, *--camel*, and *--debug* options. In this -example, *centos-art.sh* script executes the *hello* module then the -*output* module which in turn executes the *camel* module. At this -point, can appreciate how the chain of modules stop growing. Observe -that *camel* module has gained the position 2 in the chain of modules -and executes the *upper* module which takes the position 3, as -expected. Now, when *upper* module finishes its work it is destroyed -and the module's counter is reset to its previous value which is 2 -(the one set by *camel* module). Then, *camel* executes the *lower* -module which take position 3 at the chain of modules until it -finishes. When it finishes, the *camel* module finishes its work and -is destroyed, then *output*, then *hello*. +The function definition is where you write all the commands you want +the module runs, once executed. The function definition can be as +simple as just one single line of code or as complex as you can +imagine. It is the place where you express your solutions. However, +when writing initialization files, it is considered a good practice to +avoid any sort of complexity. Instead, try to write small and simple +initialization files. In case you notice the initialization file is +growing up inevitably, you can reduce its code by refactoring it. To +do this, you can use resources like module related functions and child +modules. These resources are described in <>, and +they help you to keep the initialization file in a clean state, easy +to understand, maintain and debug. -[[debug-sibling-modules]] -.Debugging execution of sibling modules +[[initialization-file]] +.Initialization file used by hello module ====================================================================== ---------------------------------------------------------------------- -Thu 10 Oct 2013 11:51:42 PM CDT =========================> [0] | main -Thu 10 Oct 2013 11:51:42 PM CDT TCAR_MODULE_BASEDIR Automation/Modules -Thu 10 Oct 2013 11:51:42 PM CDT TCAR_MODULE_NAME [0]=hello -Thu 10 Oct 2013 11:51:42 PM CDT TCAR_MODULE_TYPE parent -Thu 10 Oct 2013 11:51:42 PM CDT TCAR_MODULE_ARGUMENT --camel --greeting=hi -Thu 10 Oct 2013 11:51:42 PM CDT TCAR_MODULE_LIST hello|help|locale|prepare|render|tuneup|vcs -Thu 10 Oct 2013 11:51:42 PM CDT TCAR_MODULE_DIR Automation/Modules/Hello -Thu 10 Oct 2013 11:51:42 PM CDT TCAR_MODULE_DIR_MODULES Automation/Modules/Hello/Modules -Thu 10 Oct 2013 11:51:42 PM CDT TCAR_MODULE_DIR_MANUALS Automation/Modules/Hello/Manuals -Thu 10 Oct 2013 11:51:42 PM CDT TCAR_MODULE_DIR_LOCALES Automation/Modules/Hello/Locales -Thu 10 Oct 2013 11:51:42 PM CDT TCAR_MODULE_DIR_CONFIGS Automation/Modules/Hello/Configs -Thu 10 Oct 2013 11:51:42 PM CDT TCAR_MODULE_INIT_FILE Automation/Modules/Hello/hello.sh -Thu 10 Oct 2013 11:51:42 PM CDT TEXTDOMAIN hello.sh -Thu 10 Oct 2013 11:51:42 PM CDT TEXTDOMAINDIR Automation/Modules/Hello/Locales -Thu 10 Oct 2013 11:51:43 PM CDT export -f hello -Thu 10 Oct 2013 11:51:43 PM CDT export -f hello_getOptions -Thu 10 Oct 2013 11:51:43 PM CDT -------------------------> hello --camel --greeting=hi -Thu 10 Oct 2013 11:51:43 PM CDT =========================> [1] | hello -Thu 10 Oct 2013 11:51:43 PM CDT TCAR_MODULE_BASEDIR Automation/Modules/Hello/Modules -Thu 10 Oct 2013 11:51:43 PM CDT TCAR_MODULE_NAME [1]=output -Thu 10 Oct 2013 11:51:43 PM CDT TCAR_MODULE_TYPE child -Thu 10 Oct 2013 11:51:43 PM CDT TCAR_MODULE_ARGUMENT -Thu 10 Oct 2013 11:51:43 PM CDT TCAR_MODULE_LIST output -Thu 10 Oct 2013 11:51:43 PM CDT TCAR_MODULE_DIR Automation/Modules/Hello/Modules/Output -Thu 10 Oct 2013 11:51:43 PM CDT TCAR_MODULE_DIR_MODULES Automation/Modules/Hello/Modules/Output/Modules -Thu 10 Oct 2013 11:51:43 PM CDT TCAR_MODULE_DIR_MANUALS Automation/Modules/Hello/Modules/Output/Manuals -Thu 10 Oct 2013 11:51:43 PM CDT TCAR_MODULE_DIR_LOCALES Automation/Modules/Hello/Modules/Output/Locales -Thu 10 Oct 2013 11:51:43 PM CDT TCAR_MODULE_DIR_CONFIGS Automation/Modules/Hello/Modules/Output/Configs -Thu 10 Oct 2013 11:51:43 PM CDT TCAR_MODULE_INIT_FILE Automation/Modules/Hello/Modules/Output/output.sh -Thu 10 Oct 2013 11:51:43 PM CDT TEXTDOMAIN output.sh -Thu 10 Oct 2013 11:51:43 PM CDT TEXTDOMAINDIR Automation/Modules/Hello/Modules/Output/Locales -Thu 10 Oct 2013 11:51:43 PM CDT export -f output -Thu 10 Oct 2013 11:51:43 PM CDT -------------------------> output -Thu 10 Oct 2013 11:51:43 PM CDT =========================> [2] | output -Thu 10 Oct 2013 11:51:43 PM CDT TCAR_MODULE_BASEDIR Automation/Modules/Hello/Modules/Output/Modules -Thu 10 Oct 2013 11:51:43 PM CDT TCAR_MODULE_NAME [2]=camel -Thu 10 Oct 2013 11:51:43 PM CDT TCAR_MODULE_TYPE child -Thu 10 Oct 2013 11:51:43 PM CDT TCAR_MODULE_ARGUMENT -Thu 10 Oct 2013 11:51:43 PM CDT TCAR_MODULE_LIST camel|lower|random|upper -Thu 10 Oct 2013 11:51:43 PM CDT TCAR_MODULE_DIR Automation/Modules/Hello/Modules/Output/Modules/Camel -Thu 10 Oct 2013 11:51:43 PM CDT TCAR_MODULE_DIR_MODULES Automation/Modules/Hello/Modules/Output/Modules/Camel/Modules -Thu 10 Oct 2013 11:51:43 PM CDT TCAR_MODULE_DIR_MANUALS Automation/Modules/Hello/Modules/Output/Modules/Camel/Manuals -Thu 10 Oct 2013 11:51:43 PM CDT TCAR_MODULE_DIR_LOCALES Automation/Modules/Hello/Modules/Output/Modules/Camel/Locales -Thu 10 Oct 2013 11:51:43 PM CDT TCAR_MODULE_DIR_CONFIGS Automation/Modules/Hello/Modules/Output/Modules/Camel/Configs -Thu 10 Oct 2013 11:51:43 PM CDT TCAR_MODULE_INIT_FILE Automation/Modules/Hello/Modules/Output/Modules/Camel/camel.sh -Thu 10 Oct 2013 11:51:43 PM CDT TEXTDOMAIN camel.sh -Thu 10 Oct 2013 11:51:43 PM CDT TEXTDOMAINDIR Automation/Modules/Hello/Modules/Output/Modules/Camel/Locales -Thu 10 Oct 2013 11:51:43 PM CDT export -f camel -Thu 10 Oct 2013 11:51:43 PM CDT -------------------------> camel -Thu 10 Oct 2013 11:51:43 PM CDT =========================> [3] | camel -Thu 10 Oct 2013 11:51:43 PM CDT TCAR_MODULE_BASEDIR Automation/Modules/Hello/Modules/Output/Modules -Thu 10 Oct 2013 11:51:43 PM CDT TCAR_MODULE_NAME [3]=upper -Thu 10 Oct 2013 11:51:43 PM CDT TCAR_MODULE_TYPE sibling -Thu 10 Oct 2013 11:51:43 PM CDT TCAR_MODULE_ARGUMENT -Thu 10 Oct 2013 11:51:43 PM CDT TCAR_MODULE_LIST camel|lower|random|upper -Thu 10 Oct 2013 11:51:43 PM CDT TCAR_MODULE_DIR Automation/Modules/Hello/Modules/Output/Modules/Upper -Thu 10 Oct 2013 11:51:43 PM CDT TCAR_MODULE_DIR_MODULES Automation/Modules/Hello/Modules/Output/Modules/Upper/Modules -Thu 10 Oct 2013 11:51:43 PM CDT TCAR_MODULE_DIR_MANUALS Automation/Modules/Hello/Modules/Output/Modules/Upper/Manuals -Thu 10 Oct 2013 11:51:43 PM CDT TCAR_MODULE_DIR_LOCALES Automation/Modules/Hello/Modules/Output/Modules/Upper/Locales -Thu 10 Oct 2013 11:51:43 PM CDT TCAR_MODULE_DIR_CONFIGS Automation/Modules/Hello/Modules/Output/Modules/Upper/Configs -Thu 10 Oct 2013 11:51:43 PM CDT TCAR_MODULE_INIT_FILE Automation/Modules/Hello/Modules/Output/Modules/Upper/upper.sh -Thu 10 Oct 2013 11:51:43 PM CDT TEXTDOMAIN upper.sh -Thu 10 Oct 2013 11:51:43 PM CDT TEXTDOMAINDIR Automation/Modules/Hello/Modules/Output/Modules/Upper/Locales -Thu 10 Oct 2013 11:51:43 PM CDT export -f upper -Thu 10 Oct 2013 11:51:43 PM CDT -------------------------> upper -H -Thu 10 Oct 2013 11:51:43 PM CDT <------------------------- upper -Thu 10 Oct 2013 11:51:43 PM CDT unset -f upper -Thu 10 Oct 2013 11:51:43 PM CDT <========================= [3] | camel -Thu 10 Oct 2013 11:51:43 PM CDT =========================> [3] | camel -Thu 10 Oct 2013 11:51:43 PM CDT TCAR_MODULE_BASEDIR Automation/Modules/Hello/Modules/Output/Modules -Thu 10 Oct 2013 11:51:43 PM CDT TCAR_MODULE_NAME [3]=lower -Thu 10 Oct 2013 11:51:43 PM CDT TCAR_MODULE_TYPE sibling -Thu 10 Oct 2013 11:51:43 PM CDT TCAR_MODULE_ARGUMENT -Thu 10 Oct 2013 11:51:43 PM CDT TCAR_MODULE_LIST camel|lower|random|upper -Thu 10 Oct 2013 11:51:43 PM CDT TCAR_MODULE_DIR Automation/Modules/Hello/Modules/Output/Modules/Lower -Thu 10 Oct 2013 11:51:43 PM CDT TCAR_MODULE_DIR_MODULES Automation/Modules/Hello/Modules/Output/Modules/Lower/Modules -Thu 10 Oct 2013 11:51:44 PM CDT TCAR_MODULE_DIR_MANUALS Automation/Modules/Hello/Modules/Output/Modules/Lower/Manuals -Thu 10 Oct 2013 11:51:44 PM CDT TCAR_MODULE_DIR_LOCALES Automation/Modules/Hello/Modules/Output/Modules/Lower/Locales -Thu 10 Oct 2013 11:51:44 PM CDT TCAR_MODULE_DIR_CONFIGS Automation/Modules/Hello/Modules/Output/Modules/Lower/Configs -Thu 10 Oct 2013 11:51:44 PM CDT TCAR_MODULE_INIT_FILE Automation/Modules/Hello/Modules/Output/Modules/Lower/lower.sh -Thu 10 Oct 2013 11:51:44 PM CDT TEXTDOMAIN lower.sh -Thu 10 Oct 2013 11:51:44 PM CDT TEXTDOMAINDIR Automation/Modules/Hello/Modules/Output/Modules/Lower/Locales -Thu 10 Oct 2013 11:51:44 PM CDT export -f lower -Thu 10 Oct 2013 11:51:44 PM CDT -------------------------> lower -i -Thu 10 Oct 2013 11:51:44 PM CDT <------------------------- lower -Thu 10 Oct 2013 11:51:44 PM CDT unset -f lower -Thu 10 Oct 2013 11:51:44 PM CDT <========================= [3] | camel -Thu 10 Oct 2013 11:51:44 PM CDT <------------------------- camel -Thu 10 Oct 2013 11:51:44 PM CDT unset -f camel -Thu 10 Oct 2013 11:51:44 PM CDT <========================= [2] | output -Thu 10 Oct 2013 11:51:44 PM CDT <------------------------- output -Thu 10 Oct 2013 11:51:44 PM CDT unset -f output -Thu 10 Oct 2013 11:51:44 PM CDT <========================= [1] | hello -Thu 10 Oct 2013 11:51:44 PM CDT <------------------------- hello -Thu 10 Oct 2013 11:51:44 PM CDT unset -f hello -Thu 10 Oct 2013 11:51:44 PM CDT unset -f hello_getOptions -Thu 10 Oct 2013 11:51:44 PM CDT <========================= [0] | main ----------------------------------------------------------------------- -====================================================================== - -<> shows a single iteration of *centos-art.sh* -script executing different types of modules. Normally, one module is -executed at some point and destroyed at the same point when it has -finished its work, however, what if the next immediate module you are -about to execute is the same module you are about to destroyed? This -is, you need to execute the last module in the chain of executed -modules again, but, this time, from itself. In cases like this, the -*centos-art.sh* script doesn't destroy the last module. It cannot, -because you are certainly executing a new module from itself, so it -has to wait for this new call to finish in order to be destroyed. This -kind of processing is known as _processing modules recursively._ - -Recursive Modules -~~~~~~~~~~~~~~~~~ - -When one module environment executes itself we are in presence of a -recursive module execution. The execution of modules recursively -doesn't destroy the last module in the chain of executed modules and -doesn't increment or decrement the module counter either. The module -counter is somehow frozen until a different module environment is -executed. In this cases, the last module environment remains in memory -for the new module execution to make use of. This process becomes more visible -when you take a look at <>. +#!/bin/bash +###################################################################### +# +# hello.sh -- Print out greetings to standard output and exit +# successfully. +# +# Written by: +# * Alain Reguera Delgado , 2013 +# +# Copyright (C) 2009-2013 The CentOS Artwork SIG +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2 of the License, or (at +# your option) any later version. +# +# This program is distributed in the hope that it will be useful, but +# WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +# +###################################################################### -[CAUTION] -When you execute modules recursively, you should be very careful not -to get trapped into an endless loop. +function hello { -In <>, we've executed the *hello* module with -the *--greeting=hello*, *--random*, and *--debug* options. In this -example, *centos-art.sh* script executes a parent module named *hello* -which in turn executes a child module named *output* which in turn -executes a child module named *random*. At this point, the *random* -modules executes itself five times (the number of characters passed as -value to greeting option) to print out random letters from the -greeting message. The output may have no much sense on itself but the -related debugging information helps to understand the execution of -modules recursively. + tcar_printMessage "`gettext "Hello, World!"`" --as-stdout-line -[[debug-recursive-modules]] -.Processing execution of modules recursively -====================================================================== ----------------------------------------------------------------------- -Thu 10 Oct 2013 11:50:03 PM CDT =========================> [0] | main -Thu 10 Oct 2013 11:50:03 PM CDT TCAR_MODULE_BASEDIR Automation/Modules -Thu 10 Oct 2013 11:50:03 PM CDT TCAR_MODULE_NAME [0]=hello -Thu 10 Oct 2013 11:50:03 PM CDT TCAR_MODULE_TYPE parent -Thu 10 Oct 2013 11:50:03 PM CDT TCAR_MODULE_ARGUMENT --random --greeting=Hello -Thu 10 Oct 2013 11:50:03 PM CDT TCAR_MODULE_LIST hello|help|locale|prepare|render|tuneup|vcs -Thu 10 Oct 2013 11:50:03 PM CDT TCAR_MODULE_DIR Automation/Modules/Hello -Thu 10 Oct 2013 11:50:03 PM CDT TCAR_MODULE_DIR_MODULES Automation/Modules/Hello/Modules -Thu 10 Oct 2013 11:50:03 PM CDT TCAR_MODULE_DIR_MANUALS Automation/Modules/Hello/Manuals -Thu 10 Oct 2013 11:50:04 PM CDT TCAR_MODULE_DIR_LOCALES Automation/Modules/Hello/Locales -Thu 10 Oct 2013 11:50:04 PM CDT TCAR_MODULE_DIR_CONFIGS Automation/Modules/Hello/Configs -Thu 10 Oct 2013 11:50:04 PM CDT TCAR_MODULE_INIT_FILE Automation/Modules/Hello/hello.sh -Thu 10 Oct 2013 11:50:04 PM CDT TEXTDOMAIN hello.sh -Thu 10 Oct 2013 11:50:04 PM CDT TEXTDOMAINDIR Automation/Modules/Hello/Locales -Thu 10 Oct 2013 11:50:04 PM CDT export -f hello -Thu 10 Oct 2013 11:50:04 PM CDT export -f hello_getOptions -Thu 10 Oct 2013 11:50:04 PM CDT -------------------------> hello --random --greeting=Hello -Thu 10 Oct 2013 11:50:04 PM CDT =========================> [1] | hello -Thu 10 Oct 2013 11:50:04 PM CDT TCAR_MODULE_BASEDIR Automation/Modules/Hello/Modules -Thu 10 Oct 2013 11:50:04 PM CDT TCAR_MODULE_NAME [1]=output -Thu 10 Oct 2013 11:50:04 PM CDT TCAR_MODULE_TYPE child -Thu 10 Oct 2013 11:50:04 PM CDT TCAR_MODULE_ARGUMENT -Thu 10 Oct 2013 11:50:04 PM CDT TCAR_MODULE_LIST output -Thu 10 Oct 2013 11:50:04 PM CDT TCAR_MODULE_DIR Automation/Modules/Hello/Modules/Output -Thu 10 Oct 2013 11:50:04 PM CDT TCAR_MODULE_DIR_MODULES Automation/Modules/Hello/Modules/Output/Modules -Thu 10 Oct 2013 11:50:04 PM CDT TCAR_MODULE_DIR_MANUALS Automation/Modules/Hello/Modules/Output/Manuals -Thu 10 Oct 2013 11:50:04 PM CDT TCAR_MODULE_DIR_LOCALES Automation/Modules/Hello/Modules/Output/Locales -Thu 10 Oct 2013 11:50:04 PM CDT TCAR_MODULE_DIR_CONFIGS Automation/Modules/Hello/Modules/Output/Configs -Thu 10 Oct 2013 11:50:04 PM CDT TCAR_MODULE_INIT_FILE Automation/Modules/Hello/Modules/Output/output.sh -Thu 10 Oct 2013 11:50:04 PM CDT TEXTDOMAIN output.sh -Thu 10 Oct 2013 11:50:04 PM CDT TEXTDOMAINDIR Automation/Modules/Hello/Modules/Output/Locales -Thu 10 Oct 2013 11:50:04 PM CDT export -f output -Thu 10 Oct 2013 11:50:04 PM CDT -------------------------> output -Thu 10 Oct 2013 11:50:04 PM CDT =========================> [2] | output -Thu 10 Oct 2013 11:50:04 PM CDT TCAR_MODULE_BASEDIR Automation/Modules/Hello/Modules/Output/Modules -Thu 10 Oct 2013 11:50:04 PM CDT TCAR_MODULE_NAME [2]=random -Thu 10 Oct 2013 11:50:04 PM CDT TCAR_MODULE_TYPE child -Thu 10 Oct 2013 11:50:04 PM CDT TCAR_MODULE_ARGUMENT -Thu 10 Oct 2013 11:50:04 PM CDT TCAR_MODULE_LIST camel|lower|random|upper -Thu 10 Oct 2013 11:50:04 PM CDT TCAR_MODULE_DIR Automation/Modules/Hello/Modules/Output/Modules/Random -Thu 10 Oct 2013 11:50:04 PM CDT TCAR_MODULE_DIR_MODULES Automation/Modules/Hello/Modules/Output/Modules/Random/Modules -Thu 10 Oct 2013 11:50:04 PM CDT TCAR_MODULE_DIR_MANUALS Automation/Modules/Hello/Modules/Output/Modules/Random/Manuals -Thu 10 Oct 2013 11:50:04 PM CDT TCAR_MODULE_DIR_LOCALES Automation/Modules/Hello/Modules/Output/Modules/Random/Locales -Thu 10 Oct 2013 11:50:04 PM CDT TCAR_MODULE_DIR_CONFIGS Automation/Modules/Hello/Modules/Output/Modules/Random/Configs -Thu 10 Oct 2013 11:50:04 PM CDT TCAR_MODULE_INIT_FILE Automation/Modules/Hello/Modules/Output/Modules/Random/random.sh -Thu 10 Oct 2013 11:50:04 PM CDT TEXTDOMAIN random.sh -Thu 10 Oct 2013 11:50:04 PM CDT TEXTDOMAINDIR Automation/Modules/Hello/Modules/Output/Modules/Random/Locales -Thu 10 Oct 2013 11:50:04 PM CDT export -f random -Thu 10 Oct 2013 11:50:04 PM CDT -------------------------> random -H -Thu 10 Oct 2013 11:50:04 PM CDT ~~~~~~~~~~~~~~~~~~~~~~~~~> random -H -Thu 10 Oct 2013 11:50:04 PM CDT ~~~~~~~~~~~~~~~~~~~~~~~~~> random -l -Thu 10 Oct 2013 11:50:04 PM CDT ~~~~~~~~~~~~~~~~~~~~~~~~~> random -l -Thu 10 Oct 2013 11:50:04 PM CDT ~~~~~~~~~~~~~~~~~~~~~~~~~> random -H -Thu 10 Oct 2013 11:50:04 PM CDT <------------------------- random -Thu 10 Oct 2013 11:50:04 PM CDT unset -f random -Thu 10 Oct 2013 11:50:04 PM CDT <========================= [2] | output -Thu 10 Oct 2013 11:50:04 PM CDT <------------------------- output -Thu 10 Oct 2013 11:50:05 PM CDT unset -f output -Thu 10 Oct 2013 11:50:05 PM CDT <========================= [1] | hello -Thu 10 Oct 2013 11:50:05 PM CDT <------------------------- hello -Thu 10 Oct 2013 11:50:05 PM CDT unset -f hello -Thu 10 Oct 2013 11:50:05 PM CDT unset -f hello_getOptions -Thu 10 Oct 2013 11:50:05 PM CDT <========================= [0] | main +} ---------------------------------------------------------------------- ====================================================================== -Recursive execution of modules occurs only when the module you are -executing is considered sibling of the last module executed in the -chain of executed modules and they both have the same name. The fact -that no variable name is printed out in <> -means that they were not created. The change in the arrows shown in -the example, from +->+ to +~>+, means that module's related functions -weren't exported for the new module execution either. It also means -that the initialization script is reusing both module's related -functions variables from the last module's environment in the chain of -executed modules. In this case *random* module itself. +The function definition described in <> uses the +*tcar_printMessage* global function to print localized versions of the +string ``Hello, World!'' to standard output. Because there isn't no +other command in the function definition, when the greeting message is +printed out, *centos-art.sh* destroys the *hello* module and exit +successfully. This process is more visible when also pass the +*--debug* option. See <>. Summary ~~~~~~~ -This section has covered the module environment inside *centos-art.sh* -script, including module types and possible combinations of them. The -next section takes these concepts and focuses on the implementation of -them. Once you finish it, you should be able of writing your own -module environments from scratch inside *centos-art.sh* script. +Congratulations! You've implemented a module environment inside +*centos-art.sh* script. With the information you have so far, you are +able to create your own module environment implementations. The next +section delves into available resources you can use to simplify module +environments when the initialization file starts growing inevitably +and complexity daemons begin hammering your head. -[[module-implementation]] -Module Implementation ---------------------- +[[module-optimization]] +Module Optimization +------------------- -The *centos-art.sh* script implements module environments inside the -``+Modules+'' directory. Inside this directory, each module -environment has its own directory. Inside each module directory there -is one initialization file and, optionally, module-related stuff like -functions, locales, documentation, configuration and dependent -modules. Inside the +Modules+ directory, module directories are -written capitalized while initialization files, inside them, are -written in lower case. Even though module directories and -initialization files are written differently, they both make a single -module because they use the same single name. +The *centos-art.sh* script provides four resources you can use to +optimize your module implementations. These resources are ``related +functions,'' ``child modules,'' ``sibling modules'' and ``recursive +modules''. -[[module-implementation-parent]] -Parent Modules -~~~~~~~~~~~~~~ +[[related-functions]] +Related Functions +~~~~~~~~~~~~~~~~~ -For example, consider the creation of a module named *hello*. The -purpose of this module is to print a greeting message to standard -output and then exit successfully. To create such a module, we need to -create a directory named ``Hello'' inside the ``Modules'' directory -and put an initialization file named ``hello.sh'' inside it. Because -we want to execute the *hello* module from *centos-art.sh* script -command-line, we put it in the first level of directories of +Modules+ -directory. See <>. +Related functions are very useful when you need to simplify the +function definition of one initialization file. For example, consider +extending the *hello* module so it is able to interpret arguments +passed through the command-line. Now, inside the initialization file, +we have some variable definitions, one function call to a module +related function named *hello_getOptions*, and a decision on how the +greeting message must be printed out based on the collected actions. +See <>. -[[parent-module-layout]] -.Directory layout used by parent modules +[[initialization-file-extended]] +.Initialization file used by hello module (extended) ====================================================================== ---------------------------------------------------------------------- -. -|-- COPYING <1> -|-- Locales/ <2> -|-- Manuals/ <3> -|-- Modules/ <4> -| `-- Hello/ <5> -| |-- hello.sh <6> -| `-- hello_getOptions.sh <7> -|-- Scripts/ <8> -|-- centos-art.conf.sh <9> -`-- centos-art.sh <10> ----------------------------------------------------------------------- - -<1> Script's copying conditions. -<2> Script's localization files. -<3> Script's documentation files. -<4> Script's modules. Here is where you store parent modules. -<5> Parent directory of module named hello. -<6> Initialization file of module named hello. -<7> Function related to module named hello. -<8> Script's global functions. -<9> Script's configuration file. -<10> Script's initialization file. -====================================================================== - -<> presents a complete module layout you can use -as reference to create your own module implementations. However, it is -not complete yet. At this point, when you execute *centos-art.sh*, it -is able to find out *hello* module's initialization file and execute -it but that prints an error message because the initialization file -doesn't have a function definition inside. It is completely empty. In -order for *centos-art.sh* script to do something useful, you need to -write a function definition inside the initialization file, as -described in <>. - -[[module-init-file]] -The Initialization File -~~~~~~~~~~~~~~~~~~~~~~~ - -The module's initialization file contains the module's main function -definition and a comment describing what it does on top of it. This -comment includes a small description about what the function does, a -written by section, the copyright note and the legal status of the -file. The function definition is set later and must be written using -the long definition format (i.e., it must begin with the word -``+function+,'' then the function name, and finally the ``+{+'' -character). The name of the function is exactly the same of the -initialization file but without the +.sh+ extension. These conditions -are required in order for *centos-art.sh* script to execute the -function definition and destroy it when it is no longer used. See -<>. - -The function definition is where you write all the commands you want -the module runs, once executed. The function definition can be as -simple as just one single line of code or as complex as you can -imagine. It is the place where you express your solutions. However, -when writing initialization files, it is considered a good practice to -avoid any sort of complexity. Instead, try to write small and simple -initialization files. In case you notice the initialization file is -growing up inevitably, you can reduce its code by refactoring it. To -do this, you can use resources like module related functions and child -modules. These resources are described in -<>, and they help you to keep the -initialization file in a clean state, easy to understand, maintain and -debug. - -[[initialization-file]] -.Initialization file used by hello module -====================================================================== ----------------------------------------------------------------------- -#!/bin/bash -###################################################################### -# -# hello.sh -- Print out greetings to standard output and exit -# successfully. -# -# Written by: -# * Alain Reguera Delgado , 2013 -# -# Copyright (C) 2009-2013 The CentOS Artwork SIG -# -# This program is free software; you can redistribute it and/or modify -# it under the terms of the GNU General Public License as published by -# the Free Software Foundation; either version 2 of the License, or (at -# your option) any later version. -# -# This program is distributed in the hope that it will be useful, but -# WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -# General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this program; if not, write to the Free Software -# Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. -# -###################################################################### - -function hello { - - tcar_printMessage "`gettext "Hello, World!"`" --as-stdout-line - -} ----------------------------------------------------------------------- -====================================================================== - -The function definition described in <> uses the -*tcar_printMessage* global function to print localized versions of the -string ``Hello, World!'' to standard output. Because there isn't no -other command in the function definition, when the greeting message is -printed out, *centos-art.sh* destroys the *hello* module and exit -successfully. This process is more visible when also pass the -*--debug* option. See <>. - -Summary -~~~~~~~ - -Congratulations! You've implemented a module environment inside -*centos-art.sh* script. With the information you have so far, you are -able to create your own module environment implementations. The next -section delves into available resources you can use to simplify module -environments when the initialization file starts growing inevitably -and complexity daemons begin hammering your head. - -[[optimizing-module-implementation]] -Module Optimization -------------------- - -The *centos-art.sh* script provides four resources you can use to -optimize your module implementations. These resources are ``related -functions,'' ``child modules,'' ``sibling modules'' and ``recursive -modules''. - -[[module-related-functions]] -Related Functions -~~~~~~~~~~~~~~~~~ - -Related functions are very useful when you need to simplify the -function definition of one initialization file. Related functions are -stored in the same location of module initialization file, see -<>. Definition of related function are exported -to *centos-art.sh* execution environment before executing the function -definition set inside the initialization file, so related functions -are always available in the module environment. As naming convention, -related functions are written using the module's name as suffix, then -an underscore (``_''), then a descriptive name which identifies the -function definition inside it. The *centos-art.sh* script relays in -these conventions to export and destroy related functions when new -module environments are created and destroyed. If you create module -related functions with a different pattern from that described here, -they will not be executed nor available inside the initialization file -of the module environment being currently executed. - -For example, consider extending the *hello* module so it is able to -interpret arguments passed through the command-line. Now, inside the -initialization file, we have some variable definitions, one function -call to a module related function named *hello_getOptions*, and a -decision on how the greeting message must be printed out based on the -collected actions. See <>. - -[[initialization-file-extended]] -.Initialization file used by hello module (extended) -====================================================================== ----------------------------------------------------------------------- -#!/bin/bash -###################################################################### -# -# hello.sh -- Print greeting messages and exit successfully. -# -# Written by: -# * Alain Reguera Delgado , 2013 -# -# Copyright (C) 2009-2013 The CentOS Artwork SIG -# -# This program is free software; you can redistribute it and/or modify -# it under the terms of the GNU General Public License as published by -# the Free Software Foundation; either version 2 of the License, or (at -# your option) any later version. -# -# This program is distributed in the hope that it will be useful, but -# WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -# General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this program; if not, write to the Free Software -# Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. -# -###################################################################### - -function hello { +function hello { # Define default greeting message. local HELLO_WORLD="`gettext "Hello, World!"`" @@ -781,158 +341,506 @@ variable. .Related function definition (hello_getOptions) ====================================================================== ---------------------------------------------------------------------- -#!/bin/bash -###################################################################### -# -# hello_getOptions.sh -- Interpret module-specific options for hello. -# -# Written by: -# * Alain Reguera Delgado , 2013 -# -# Copyright (C) 2009-2013 The CentOS Artwork SIG -# -# This program is free software; you can redistribute it and/or modify -# it under the terms of the GNU General Public License as published by -# the Free Software Foundation; either version 2 of the License, or (at -# your option) any later version. -# -# This program is distributed in the hope that it will be useful, but -# WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -# General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this program; if not, write to the Free Software -# Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. -# -###################################################################### - -function hello_getOptions { - - # Define short options we want to support. - local ARGSS="h::,v,g:,l,u,c,r" - - # Define long options we want to support. - local ARGSL="help::,version,greeting:,lower,upper,camel,random" - - # Redefine arguments using getopt(1) command parser. - tcar_setModuleArguments - - # Reset positional parameters on this function, using output - # produced from (getopt) arguments parser. - eval set -- "${TCAR_MODULE_ARGUMENT}" - - # Look for options passed through command-line. - while true; do - case "${1}" in - - -h | --help ) - tcar_printHelp "${2}" - ;; - - -v | --version ) - tcar_printVersion "${TCAR_MODULE_NAME}" - ;; - - -g | --greeting ) - HELLO_WORLD="${2:-${HELLO_WORLD}}" - shift 2 - ;; - - -l | --lower ) - ACTIONS="lower ${ACTIONS}" - shift 1 - ;; +function hello_getOptions { + + # Define short options we want to support. + local ARGSS="h::,v,g:,l,u,c,r" + + # Define long options we want to support. + local ARGSL="help::,version,greeting:,lower,upper,camel,random" + + # Redefine arguments using getopt(1) command parser. + tcar_setModuleArguments + + # Reset positional parameters on this function, using output + # produced from (getopt) arguments parser. + eval set -- "${TCAR_MODULE_ARGUMENT}" + + # Look for options passed through command-line. + while true; do + case "${1}" in + + -h | --help ) + tcar_printHelp "${2}" + ;; + + -v | --version ) + tcar_printVersion "${TCAR_MODULE_NAME}" + ;; + + -g | --greeting ) + HELLO_WORLD="${2:-${HELLO_WORLD}}" + shift 2 + ;; + + -l | --lower ) + ACTIONS="lower ${ACTIONS}" + shift 1 + ;; + + -u | --upper ) + ACTIONS="upper ${ACTIONS}" + shift 1 + ;; + + -c | --camel ) + ACTIONS="camel ${ACTIONS}" + shift 1 + ;; + + -r | --random ) + ACTIONS="random ${ACTIONS}" + shift 1 + ;; + + -- ) + shift 1 + break + ;; + esac + done + + # Redefine arguments using current positional parameters. Only + # paths should remain as arguments, at this point. + TCAR_MODULE_ARGUMENT="${@}" + +} +---------------------------------------------------------------------- +====================================================================== + +[IMPORTANT] +<> presents the standard construction we +use inside *centos-art.sh* script for parsing arguments passed through +the command-line in a per-module basis. As convention, all the parent +modules you write must be able to interpret the *--help* and +*--version* options using the construction described here. + +Related functions are very useful when you are refactoring the +initialization file of a module. However, they aren't so efficient +when you need to execute them at demand (e.g., based on specific +conditions). When a module is executed, related functions are exported +to *centos-art.sh* script execution environment. They remain there, +consuming memory, until the module they belong to is destroyed. If you +create a related function and never execute it, it will consume +memory, as well. So, use related functions when you are absolutely +sure they will be executed at some point, in one single iteration of +*centos-art.sh* script. If you need to execute functions at demand, +use child modules, instead. + +[[child-modules]] +Child Modules +~~~~~~~~~~~~~ + +Child modules are initiated by executing the +*tcar_setModuleEnvironment* function with the *-t child* option set on +it. Child modules have the characteristic of being nested modules. +They cannot be executed from the command-line. Normally, child modules +are executed from parent modules but they can be executed from other +child modules, too. When several child modules are executed in one +single iteration of *centos-art.sh*, they create a chain of modules. +A chain of modules is very useful in situations where you want to +divide one large task into smaller tasks and also control which of +these smaller tasks is executed based on specific conditions (e.g., +you may want to render images or documentation, but not both, in one +single iteration of *centos-art.sh* script). In a chain of modules, +lower modules in the chain (those started last) have access to +information set by modules higher in the chain (those started first), +but not the opposite. When processing information this way, modules +aren't destroyed until the last module executed in the chain has +finished its work (e.g., all the commands inside it have been +executed). At that point, child modules are destroyed in the reverse +order they were executed. + +For example, when you execute the *hello* module with both *--debug* +and *--upper* option, *centos-art.sh* script creates a chain of three +modules to produce the greeting message. Firstly, it begins by +executing the parent module named *hello*, then it continues with the +child module named *output* which in turn executes the child module +name *lower* to finally print the expected greeting message. In this +example, the module named *lower* is the last module in the chain of +executed modules. It has access to all information defined by earlier +modules (e.g., in *hello* and *output* modules) and none of its earlier +modules will be destroyed until it has finished its work. This process +becomes more visible when you take a look at <>. + +[[debug-child-modules]] +.Debugging execution of child modules +====================================================================== +---------------------------------------------------------------------- +Thu 10 Oct 2013 11:52:41 PM CDT =========================> [0] | main +Thu 10 Oct 2013 11:52:41 PM CDT TCAR_MODULE_BASEDIR Automation/Modules +Thu 10 Oct 2013 11:52:41 PM CDT TCAR_MODULE_NAME [0]=hello +Thu 10 Oct 2013 11:52:41 PM CDT TCAR_MODULE_TYPE parent +Thu 10 Oct 2013 11:52:41 PM CDT TCAR_MODULE_ARGUMENT --upper --greeting=hi +Thu 10 Oct 2013 11:52:41 PM CDT TCAR_MODULE_LIST hello|help|locale|prepare|render|tuneup|vcs +Thu 10 Oct 2013 11:52:41 PM CDT TCAR_MODULE_DIR Automation/Modules/Hello +Thu 10 Oct 2013 11:52:41 PM CDT TCAR_MODULE_DIR_MODULES Automation/Modules/Hello/Modules +Thu 10 Oct 2013 11:52:41 PM CDT TCAR_MODULE_DIR_MANUALS Automation/Modules/Hello/Manuals +Thu 10 Oct 2013 11:52:41 PM CDT TCAR_MODULE_DIR_LOCALES Automation/Modules/Hello/Locales +Thu 10 Oct 2013 11:52:41 PM CDT TCAR_MODULE_DIR_CONFIGS Automation/Modules/Hello/Configs +Thu 10 Oct 2013 11:52:41 PM CDT TCAR_MODULE_INIT_FILE Automation/Modules/Hello/hello.sh +Thu 10 Oct 2013 11:52:41 PM CDT TEXTDOMAIN hello.sh +Thu 10 Oct 2013 11:52:41 PM CDT TEXTDOMAINDIR Automation/Modules/Hello/Locales +Thu 10 Oct 2013 11:52:41 PM CDT export -f hello +Thu 10 Oct 2013 11:52:41 PM CDT export -f hello_getOptions +Thu 10 Oct 2013 11:52:41 PM CDT -------------------------> hello --upper --greeting=hi +Thu 10 Oct 2013 11:52:41 PM CDT =========================> [1] | hello +Thu 10 Oct 2013 11:52:41 PM CDT TCAR_MODULE_BASEDIR Automation/Modules/Hello/Modules +Thu 10 Oct 2013 11:52:41 PM CDT TCAR_MODULE_NAME [1]=output +Thu 10 Oct 2013 11:52:41 PM CDT TCAR_MODULE_TYPE child +Thu 10 Oct 2013 11:52:41 PM CDT TCAR_MODULE_ARGUMENT +Thu 10 Oct 2013 11:52:41 PM CDT TCAR_MODULE_LIST output +Thu 10 Oct 2013 11:52:41 PM CDT TCAR_MODULE_DIR Automation/Modules/Hello/Modules/Output +Thu 10 Oct 2013 11:52:41 PM CDT TCAR_MODULE_DIR_MODULES Automation/Modules/Hello/Modules/Output/Modules +Thu 10 Oct 2013 11:52:41 PM CDT TCAR_MODULE_DIR_MANUALS Automation/Modules/Hello/Modules/Output/Manuals +Thu 10 Oct 2013 11:52:41 PM CDT TCAR_MODULE_DIR_LOCALES Automation/Modules/Hello/Modules/Output/Locales +Thu 10 Oct 2013 11:52:41 PM CDT TCAR_MODULE_DIR_CONFIGS Automation/Modules/Hello/Modules/Output/Configs +Thu 10 Oct 2013 11:52:41 PM CDT TCAR_MODULE_INIT_FILE Automation/Modules/Hello/Modules/Output/output.sh +Thu 10 Oct 2013 11:52:41 PM CDT TEXTDOMAIN output.sh +Thu 10 Oct 2013 11:52:41 PM CDT TEXTDOMAINDIR Automation/Modules/Hello/Modules/Output/Locales +Thu 10 Oct 2013 11:52:41 PM CDT export -f output +Thu 10 Oct 2013 11:52:41 PM CDT -------------------------> output +Thu 10 Oct 2013 11:52:41 PM CDT =========================> [2] | output +Thu 10 Oct 2013 11:52:41 PM CDT TCAR_MODULE_BASEDIR Automation/Modules/Hello/Modules/Output/Modules +Thu 10 Oct 2013 11:52:41 PM CDT TCAR_MODULE_NAME [2]=upper +Thu 10 Oct 2013 11:52:41 PM CDT TCAR_MODULE_TYPE child +Thu 10 Oct 2013 11:52:41 PM CDT TCAR_MODULE_ARGUMENT +Thu 10 Oct 2013 11:52:41 PM CDT TCAR_MODULE_LIST camel|lower|random|upper +Thu 10 Oct 2013 11:52:41 PM CDT TCAR_MODULE_DIR Automation/Modules/Hello/Modules/Output/Modules/Upper +Thu 10 Oct 2013 11:52:41 PM CDT TCAR_MODULE_DIR_MODULES Automation/Modules/Hello/Modules/Output/Modules/Upper/Modules +Thu 10 Oct 2013 11:52:42 PM CDT TCAR_MODULE_DIR_MANUALS Automation/Modules/Hello/Modules/Output/Modules/Upper/Manuals +Thu 10 Oct 2013 11:52:42 PM CDT TCAR_MODULE_DIR_LOCALES Automation/Modules/Hello/Modules/Output/Modules/Upper/Locales +Thu 10 Oct 2013 11:52:42 PM CDT TCAR_MODULE_DIR_CONFIGS Automation/Modules/Hello/Modules/Output/Modules/Upper/Configs +Thu 10 Oct 2013 11:52:42 PM CDT TCAR_MODULE_INIT_FILE Automation/Modules/Hello/Modules/Output/Modules/Upper/upper.sh +Thu 10 Oct 2013 11:52:42 PM CDT TEXTDOMAIN upper.sh +Thu 10 Oct 2013 11:52:42 PM CDT TEXTDOMAINDIR Automation/Modules/Hello/Modules/Output/Modules/Upper/Locales +Thu 10 Oct 2013 11:52:42 PM CDT export -f upper +Thu 10 Oct 2013 11:52:42 PM CDT -------------------------> upper +HI +Thu 10 Oct 2013 11:52:42 PM CDT <------------------------- upper +Thu 10 Oct 2013 11:52:42 PM CDT unset -f upper +Thu 10 Oct 2013 11:52:42 PM CDT <========================= [2] | output +Thu 10 Oct 2013 11:52:42 PM CDT <------------------------- output +Thu 10 Oct 2013 11:52:42 PM CDT unset -f output +Thu 10 Oct 2013 11:52:42 PM CDT <========================= [1] | hello +Thu 10 Oct 2013 11:52:42 PM CDT <------------------------- hello +Thu 10 Oct 2013 11:52:42 PM CDT unset -f hello +Thu 10 Oct 2013 11:52:42 PM CDT unset -f hello_getOptions +Thu 10 Oct 2013 11:52:42 PM CDT <========================= [0] | main +---------------------------------------------------------------------- +====================================================================== + +The module environment described in <> shows the +child modules' ability of reducing scope as they get deeper in the +chain of executed modules. However, child modules lack the possibility +of nest modules that share the same scope. For example, in the *hello* +module described above, you cannot execute the modules *lower* or +*upper* from *camel* module, as if they were child modules of it. +That is not possible because they all have the same scope, which is, +to print the greeting message to standard output. Child modules are +conceived to reduce the module scope as new child modules are +executed. When you need to execute new module environments and, also, +retain the last scope from which the new module is executed, you need +to use ``_sibling modules_,'' instead. + +[[sibling-modules]] +Sibling Modules +~~~~~~~~~~~~~~~ + +Sibling modules are initiated by executing the +*tcar_setModuleEnvironment* function with the *-t sibling* option set +on it. Sibling modules are another type of nested modules but, in +contrast with child modules, sibling modules cannot be executed from +parent modules. Normally, sibling modules are executed from other +sibling modules but, considering the context, they can be executed +from child module too, to initiate sibling processing. When several +siblings modules are executed, they also build a chain of modules. In +contrast with the chain of child modules, the chain of sibling modules +destroys the last sibling module executed before executing the next +sibling module. This make the chain to stop its growing at sibling +module processing, unless you call a child module from a sibling +module. In this case, the chain expansion would continue as long as +the number of child modules you execute. This process becomes more +visible when you take a look at <>. + +In <>, we've executed the *hello* module with +the *--greeting=hi*, *--camel*, and *--debug* options. In this +example, *centos-art.sh* script executes the *hello* module then the +*output* module which in turn executes the *camel* module. At this +point, can appreciate how the chain of modules stop growing. Observe +that *camel* module has gained the position 2 in the chain of modules +and executes the *upper* module which takes the position 3, as +expected. Now, when *upper* module finishes its work it is destroyed +and the module's counter is reset to its previous value which is 2 +(the one set by *camel* module). Then, *camel* executes the *lower* +module which take position 3 at the chain of modules until it +finishes. When it finishes, the *camel* module finishes its work and +is destroyed, then *output*, then *hello*. + +[[debug-sibling-modules]] +.Debugging execution of sibling modules +====================================================================== +---------------------------------------------------------------------- +Thu 10 Oct 2013 11:51:42 PM CDT =========================> [0] | main +Thu 10 Oct 2013 11:51:42 PM CDT TCAR_MODULE_BASEDIR Automation/Modules +Thu 10 Oct 2013 11:51:42 PM CDT TCAR_MODULE_NAME [0]=hello +Thu 10 Oct 2013 11:51:42 PM CDT TCAR_MODULE_TYPE parent +Thu 10 Oct 2013 11:51:42 PM CDT TCAR_MODULE_ARGUMENT --camel --greeting=hi +Thu 10 Oct 2013 11:51:42 PM CDT TCAR_MODULE_LIST hello|help|locale|prepare|render|tuneup|vcs +Thu 10 Oct 2013 11:51:42 PM CDT TCAR_MODULE_DIR Automation/Modules/Hello +Thu 10 Oct 2013 11:51:42 PM CDT TCAR_MODULE_DIR_MODULES Automation/Modules/Hello/Modules +Thu 10 Oct 2013 11:51:42 PM CDT TCAR_MODULE_DIR_MANUALS Automation/Modules/Hello/Manuals +Thu 10 Oct 2013 11:51:42 PM CDT TCAR_MODULE_DIR_LOCALES Automation/Modules/Hello/Locales +Thu 10 Oct 2013 11:51:42 PM CDT TCAR_MODULE_DIR_CONFIGS Automation/Modules/Hello/Configs +Thu 10 Oct 2013 11:51:42 PM CDT TCAR_MODULE_INIT_FILE Automation/Modules/Hello/hello.sh +Thu 10 Oct 2013 11:51:42 PM CDT TEXTDOMAIN hello.sh +Thu 10 Oct 2013 11:51:42 PM CDT TEXTDOMAINDIR Automation/Modules/Hello/Locales +Thu 10 Oct 2013 11:51:43 PM CDT export -f hello +Thu 10 Oct 2013 11:51:43 PM CDT export -f hello_getOptions +Thu 10 Oct 2013 11:51:43 PM CDT -------------------------> hello --camel --greeting=hi +Thu 10 Oct 2013 11:51:43 PM CDT =========================> [1] | hello +Thu 10 Oct 2013 11:51:43 PM CDT TCAR_MODULE_BASEDIR Automation/Modules/Hello/Modules +Thu 10 Oct 2013 11:51:43 PM CDT TCAR_MODULE_NAME [1]=output +Thu 10 Oct 2013 11:51:43 PM CDT TCAR_MODULE_TYPE child +Thu 10 Oct 2013 11:51:43 PM CDT TCAR_MODULE_ARGUMENT +Thu 10 Oct 2013 11:51:43 PM CDT TCAR_MODULE_LIST output +Thu 10 Oct 2013 11:51:43 PM CDT TCAR_MODULE_DIR Automation/Modules/Hello/Modules/Output +Thu 10 Oct 2013 11:51:43 PM CDT TCAR_MODULE_DIR_MODULES Automation/Modules/Hello/Modules/Output/Modules +Thu 10 Oct 2013 11:51:43 PM CDT TCAR_MODULE_DIR_MANUALS Automation/Modules/Hello/Modules/Output/Manuals +Thu 10 Oct 2013 11:51:43 PM CDT TCAR_MODULE_DIR_LOCALES Automation/Modules/Hello/Modules/Output/Locales +Thu 10 Oct 2013 11:51:43 PM CDT TCAR_MODULE_DIR_CONFIGS Automation/Modules/Hello/Modules/Output/Configs +Thu 10 Oct 2013 11:51:43 PM CDT TCAR_MODULE_INIT_FILE Automation/Modules/Hello/Modules/Output/output.sh +Thu 10 Oct 2013 11:51:43 PM CDT TEXTDOMAIN output.sh +Thu 10 Oct 2013 11:51:43 PM CDT TEXTDOMAINDIR Automation/Modules/Hello/Modules/Output/Locales +Thu 10 Oct 2013 11:51:43 PM CDT export -f output +Thu 10 Oct 2013 11:51:43 PM CDT -------------------------> output +Thu 10 Oct 2013 11:51:43 PM CDT =========================> [2] | output +Thu 10 Oct 2013 11:51:43 PM CDT TCAR_MODULE_BASEDIR Automation/Modules/Hello/Modules/Output/Modules +Thu 10 Oct 2013 11:51:43 PM CDT TCAR_MODULE_NAME [2]=camel +Thu 10 Oct 2013 11:51:43 PM CDT TCAR_MODULE_TYPE child +Thu 10 Oct 2013 11:51:43 PM CDT TCAR_MODULE_ARGUMENT +Thu 10 Oct 2013 11:51:43 PM CDT TCAR_MODULE_LIST camel|lower|random|upper +Thu 10 Oct 2013 11:51:43 PM CDT TCAR_MODULE_DIR Automation/Modules/Hello/Modules/Output/Modules/Camel +Thu 10 Oct 2013 11:51:43 PM CDT TCAR_MODULE_DIR_MODULES Automation/Modules/Hello/Modules/Output/Modules/Camel/Modules +Thu 10 Oct 2013 11:51:43 PM CDT TCAR_MODULE_DIR_MANUALS Automation/Modules/Hello/Modules/Output/Modules/Camel/Manuals +Thu 10 Oct 2013 11:51:43 PM CDT TCAR_MODULE_DIR_LOCALES Automation/Modules/Hello/Modules/Output/Modules/Camel/Locales +Thu 10 Oct 2013 11:51:43 PM CDT TCAR_MODULE_DIR_CONFIGS Automation/Modules/Hello/Modules/Output/Modules/Camel/Configs +Thu 10 Oct 2013 11:51:43 PM CDT TCAR_MODULE_INIT_FILE Automation/Modules/Hello/Modules/Output/Modules/Camel/camel.sh +Thu 10 Oct 2013 11:51:43 PM CDT TEXTDOMAIN camel.sh +Thu 10 Oct 2013 11:51:43 PM CDT TEXTDOMAINDIR Automation/Modules/Hello/Modules/Output/Modules/Camel/Locales +Thu 10 Oct 2013 11:51:43 PM CDT export -f camel +Thu 10 Oct 2013 11:51:43 PM CDT -------------------------> camel +Thu 10 Oct 2013 11:51:43 PM CDT =========================> [3] | camel +Thu 10 Oct 2013 11:51:43 PM CDT TCAR_MODULE_BASEDIR Automation/Modules/Hello/Modules/Output/Modules +Thu 10 Oct 2013 11:51:43 PM CDT TCAR_MODULE_NAME [3]=upper +Thu 10 Oct 2013 11:51:43 PM CDT TCAR_MODULE_TYPE sibling +Thu 10 Oct 2013 11:51:43 PM CDT TCAR_MODULE_ARGUMENT +Thu 10 Oct 2013 11:51:43 PM CDT TCAR_MODULE_LIST camel|lower|random|upper +Thu 10 Oct 2013 11:51:43 PM CDT TCAR_MODULE_DIR Automation/Modules/Hello/Modules/Output/Modules/Upper +Thu 10 Oct 2013 11:51:43 PM CDT TCAR_MODULE_DIR_MODULES Automation/Modules/Hello/Modules/Output/Modules/Upper/Modules +Thu 10 Oct 2013 11:51:43 PM CDT TCAR_MODULE_DIR_MANUALS Automation/Modules/Hello/Modules/Output/Modules/Upper/Manuals +Thu 10 Oct 2013 11:51:43 PM CDT TCAR_MODULE_DIR_LOCALES Automation/Modules/Hello/Modules/Output/Modules/Upper/Locales +Thu 10 Oct 2013 11:51:43 PM CDT TCAR_MODULE_DIR_CONFIGS Automation/Modules/Hello/Modules/Output/Modules/Upper/Configs +Thu 10 Oct 2013 11:51:43 PM CDT TCAR_MODULE_INIT_FILE Automation/Modules/Hello/Modules/Output/Modules/Upper/upper.sh +Thu 10 Oct 2013 11:51:43 PM CDT TEXTDOMAIN upper.sh +Thu 10 Oct 2013 11:51:43 PM CDT TEXTDOMAINDIR Automation/Modules/Hello/Modules/Output/Modules/Upper/Locales +Thu 10 Oct 2013 11:51:43 PM CDT export -f upper +Thu 10 Oct 2013 11:51:43 PM CDT -------------------------> upper +H +Thu 10 Oct 2013 11:51:43 PM CDT <------------------------- upper +Thu 10 Oct 2013 11:51:43 PM CDT unset -f upper +Thu 10 Oct 2013 11:51:43 PM CDT <========================= [3] | camel +Thu 10 Oct 2013 11:51:43 PM CDT =========================> [3] | camel +Thu 10 Oct 2013 11:51:43 PM CDT TCAR_MODULE_BASEDIR Automation/Modules/Hello/Modules/Output/Modules +Thu 10 Oct 2013 11:51:43 PM CDT TCAR_MODULE_NAME [3]=lower +Thu 10 Oct 2013 11:51:43 PM CDT TCAR_MODULE_TYPE sibling +Thu 10 Oct 2013 11:51:43 PM CDT TCAR_MODULE_ARGUMENT +Thu 10 Oct 2013 11:51:43 PM CDT TCAR_MODULE_LIST camel|lower|random|upper +Thu 10 Oct 2013 11:51:43 PM CDT TCAR_MODULE_DIR Automation/Modules/Hello/Modules/Output/Modules/Lower +Thu 10 Oct 2013 11:51:43 PM CDT TCAR_MODULE_DIR_MODULES Automation/Modules/Hello/Modules/Output/Modules/Lower/Modules +Thu 10 Oct 2013 11:51:44 PM CDT TCAR_MODULE_DIR_MANUALS Automation/Modules/Hello/Modules/Output/Modules/Lower/Manuals +Thu 10 Oct 2013 11:51:44 PM CDT TCAR_MODULE_DIR_LOCALES Automation/Modules/Hello/Modules/Output/Modules/Lower/Locales +Thu 10 Oct 2013 11:51:44 PM CDT TCAR_MODULE_DIR_CONFIGS Automation/Modules/Hello/Modules/Output/Modules/Lower/Configs +Thu 10 Oct 2013 11:51:44 PM CDT TCAR_MODULE_INIT_FILE Automation/Modules/Hello/Modules/Output/Modules/Lower/lower.sh +Thu 10 Oct 2013 11:51:44 PM CDT TEXTDOMAIN lower.sh +Thu 10 Oct 2013 11:51:44 PM CDT TEXTDOMAINDIR Automation/Modules/Hello/Modules/Output/Modules/Lower/Locales +Thu 10 Oct 2013 11:51:44 PM CDT export -f lower +Thu 10 Oct 2013 11:51:44 PM CDT -------------------------> lower +i +Thu 10 Oct 2013 11:51:44 PM CDT <------------------------- lower +Thu 10 Oct 2013 11:51:44 PM CDT unset -f lower +Thu 10 Oct 2013 11:51:44 PM CDT <========================= [3] | camel +Thu 10 Oct 2013 11:51:44 PM CDT <------------------------- camel +Thu 10 Oct 2013 11:51:44 PM CDT unset -f camel +Thu 10 Oct 2013 11:51:44 PM CDT <========================= [2] | output +Thu 10 Oct 2013 11:51:44 PM CDT <------------------------- output +Thu 10 Oct 2013 11:51:44 PM CDT unset -f output +Thu 10 Oct 2013 11:51:44 PM CDT <========================= [1] | hello +Thu 10 Oct 2013 11:51:44 PM CDT <------------------------- hello +Thu 10 Oct 2013 11:51:44 PM CDT unset -f hello +Thu 10 Oct 2013 11:51:44 PM CDT unset -f hello_getOptions +Thu 10 Oct 2013 11:51:44 PM CDT <========================= [0] | main +---------------------------------------------------------------------- +====================================================================== - -u | --upper ) - ACTIONS="upper ${ACTIONS}" - shift 1 - ;; +<> shows a single iteration of *centos-art.sh* +script executing different types of modules. Normally, one module is +executed at some point and destroyed at the same point when it has +finished its work, however, what if the next immediate module you are +about to execute is the same module you are about to destroyed? This +is, you need to execute the last module in the chain of executed +modules again, but, this time, from itself. In cases like this, the +*centos-art.sh* script doesn't destroy the last module. It cannot, +because you are certainly executing a new module from itself, so it +has to wait for this new call to finish in order to be destroyed. This +kind of processing is known as _processing modules recursively._ - -c | --camel ) - ACTIONS="camel ${ACTIONS}" - shift 1 - ;; +[[recursive-modules]] +Recursive Modules +~~~~~~~~~~~~~~~~~ - -r | --random ) - ACTIONS="random ${ACTIONS}" - shift 1 - ;; +When one module environment executes itself we are in presence of a +recursive module execution. The execution of modules recursively +doesn't destroy the last module in the chain of executed modules and +doesn't increment or decrement the module counter either. The module +counter is somehow frozen until a different module environment is +executed. In these cases, the last module environment remains in +memory for the new module execution to make use of. This process +becomes more visible when you take a look at +<>. - -- ) - shift 1 - break - ;; - esac - done +[CAUTION] +When you execute modules recursively, you should be very careful not +to get trapped into an endless loop. - # Redefine arguments using current positional parameters. Only - # paths should remain as arguments, at this point. - TCAR_MODULE_ARGUMENT="${@}" +In <>, we've executed the *hello* module with +the *--greeting=hello*, *--random*, and *--debug* options. In this +example, *centos-art.sh* script executes a parent module named *hello* +which in turn executes a child module named *output* which in turn +executes a child module named *random*. At this point, the *random* +modules executes itself five times (the number of characters passed as +value to greeting option) to print out random letters from the +greeting message. The output may have no much sense on itself but the +related debugging information helps to understand the execution of +modules recursively. -} +[[debug-recursive-modules]] +.Processing execution of modules recursively +====================================================================== +---------------------------------------------------------------------- +Thu 10 Oct 2013 11:50:03 PM CDT =========================> [0] | main +Thu 10 Oct 2013 11:50:03 PM CDT TCAR_MODULE_BASEDIR Automation/Modules +Thu 10 Oct 2013 11:50:03 PM CDT TCAR_MODULE_NAME [0]=hello +Thu 10 Oct 2013 11:50:03 PM CDT TCAR_MODULE_TYPE parent +Thu 10 Oct 2013 11:50:03 PM CDT TCAR_MODULE_ARGUMENT --random --greeting=Hello +Thu 10 Oct 2013 11:50:03 PM CDT TCAR_MODULE_LIST hello|help|locale|prepare|render|tuneup|vcs +Thu 10 Oct 2013 11:50:03 PM CDT TCAR_MODULE_DIR Automation/Modules/Hello +Thu 10 Oct 2013 11:50:03 PM CDT TCAR_MODULE_DIR_MODULES Automation/Modules/Hello/Modules +Thu 10 Oct 2013 11:50:03 PM CDT TCAR_MODULE_DIR_MANUALS Automation/Modules/Hello/Manuals +Thu 10 Oct 2013 11:50:04 PM CDT TCAR_MODULE_DIR_LOCALES Automation/Modules/Hello/Locales +Thu 10 Oct 2013 11:50:04 PM CDT TCAR_MODULE_DIR_CONFIGS Automation/Modules/Hello/Configs +Thu 10 Oct 2013 11:50:04 PM CDT TCAR_MODULE_INIT_FILE Automation/Modules/Hello/hello.sh +Thu 10 Oct 2013 11:50:04 PM CDT TEXTDOMAIN hello.sh +Thu 10 Oct 2013 11:50:04 PM CDT TEXTDOMAINDIR Automation/Modules/Hello/Locales +Thu 10 Oct 2013 11:50:04 PM CDT export -f hello +Thu 10 Oct 2013 11:50:04 PM CDT export -f hello_getOptions +Thu 10 Oct 2013 11:50:04 PM CDT -------------------------> hello --random --greeting=Hello +Thu 10 Oct 2013 11:50:04 PM CDT =========================> [1] | hello +Thu 10 Oct 2013 11:50:04 PM CDT TCAR_MODULE_BASEDIR Automation/Modules/Hello/Modules +Thu 10 Oct 2013 11:50:04 PM CDT TCAR_MODULE_NAME [1]=output +Thu 10 Oct 2013 11:50:04 PM CDT TCAR_MODULE_TYPE child +Thu 10 Oct 2013 11:50:04 PM CDT TCAR_MODULE_ARGUMENT +Thu 10 Oct 2013 11:50:04 PM CDT TCAR_MODULE_LIST output +Thu 10 Oct 2013 11:50:04 PM CDT TCAR_MODULE_DIR Automation/Modules/Hello/Modules/Output +Thu 10 Oct 2013 11:50:04 PM CDT TCAR_MODULE_DIR_MODULES Automation/Modules/Hello/Modules/Output/Modules +Thu 10 Oct 2013 11:50:04 PM CDT TCAR_MODULE_DIR_MANUALS Automation/Modules/Hello/Modules/Output/Manuals +Thu 10 Oct 2013 11:50:04 PM CDT TCAR_MODULE_DIR_LOCALES Automation/Modules/Hello/Modules/Output/Locales +Thu 10 Oct 2013 11:50:04 PM CDT TCAR_MODULE_DIR_CONFIGS Automation/Modules/Hello/Modules/Output/Configs +Thu 10 Oct 2013 11:50:04 PM CDT TCAR_MODULE_INIT_FILE Automation/Modules/Hello/Modules/Output/output.sh +Thu 10 Oct 2013 11:50:04 PM CDT TEXTDOMAIN output.sh +Thu 10 Oct 2013 11:50:04 PM CDT TEXTDOMAINDIR Automation/Modules/Hello/Modules/Output/Locales +Thu 10 Oct 2013 11:50:04 PM CDT export -f output +Thu 10 Oct 2013 11:50:04 PM CDT -------------------------> output +Thu 10 Oct 2013 11:50:04 PM CDT =========================> [2] | output +Thu 10 Oct 2013 11:50:04 PM CDT TCAR_MODULE_BASEDIR Automation/Modules/Hello/Modules/Output/Modules +Thu 10 Oct 2013 11:50:04 PM CDT TCAR_MODULE_NAME [2]=random +Thu 10 Oct 2013 11:50:04 PM CDT TCAR_MODULE_TYPE child +Thu 10 Oct 2013 11:50:04 PM CDT TCAR_MODULE_ARGUMENT +Thu 10 Oct 2013 11:50:04 PM CDT TCAR_MODULE_LIST camel|lower|random|upper +Thu 10 Oct 2013 11:50:04 PM CDT TCAR_MODULE_DIR Automation/Modules/Hello/Modules/Output/Modules/Random +Thu 10 Oct 2013 11:50:04 PM CDT TCAR_MODULE_DIR_MODULES Automation/Modules/Hello/Modules/Output/Modules/Random/Modules +Thu 10 Oct 2013 11:50:04 PM CDT TCAR_MODULE_DIR_MANUALS Automation/Modules/Hello/Modules/Output/Modules/Random/Manuals +Thu 10 Oct 2013 11:50:04 PM CDT TCAR_MODULE_DIR_LOCALES Automation/Modules/Hello/Modules/Output/Modules/Random/Locales +Thu 10 Oct 2013 11:50:04 PM CDT TCAR_MODULE_DIR_CONFIGS Automation/Modules/Hello/Modules/Output/Modules/Random/Configs +Thu 10 Oct 2013 11:50:04 PM CDT TCAR_MODULE_INIT_FILE Automation/Modules/Hello/Modules/Output/Modules/Random/random.sh +Thu 10 Oct 2013 11:50:04 PM CDT TEXTDOMAIN random.sh +Thu 10 Oct 2013 11:50:04 PM CDT TEXTDOMAINDIR Automation/Modules/Hello/Modules/Output/Modules/Random/Locales +Thu 10 Oct 2013 11:50:04 PM CDT export -f random +Thu 10 Oct 2013 11:50:04 PM CDT -------------------------> random +H +Thu 10 Oct 2013 11:50:04 PM CDT ~~~~~~~~~~~~~~~~~~~~~~~~~> random +H +Thu 10 Oct 2013 11:50:04 PM CDT ~~~~~~~~~~~~~~~~~~~~~~~~~> random +l +Thu 10 Oct 2013 11:50:04 PM CDT ~~~~~~~~~~~~~~~~~~~~~~~~~> random +l +Thu 10 Oct 2013 11:50:04 PM CDT ~~~~~~~~~~~~~~~~~~~~~~~~~> random +H +Thu 10 Oct 2013 11:50:04 PM CDT <------------------------- random +Thu 10 Oct 2013 11:50:04 PM CDT unset -f random +Thu 10 Oct 2013 11:50:04 PM CDT <========================= [2] | output +Thu 10 Oct 2013 11:50:04 PM CDT <------------------------- output +Thu 10 Oct 2013 11:50:05 PM CDT unset -f output +Thu 10 Oct 2013 11:50:05 PM CDT <========================= [1] | hello +Thu 10 Oct 2013 11:50:05 PM CDT <------------------------- hello +Thu 10 Oct 2013 11:50:05 PM CDT unset -f hello +Thu 10 Oct 2013 11:50:05 PM CDT unset -f hello_getOptions +Thu 10 Oct 2013 11:50:05 PM CDT <========================= [0] | main ---------------------------------------------------------------------- ====================================================================== -[IMPORTANT] -<> presents the standard construction we -use inside *centos-art.sh* script for parsing arguments passed through -the command-line in a per-module basis. As convention, all the parent -modules you write must be able to interpret the *--help* and -*--version* options using the construction described here. - -Related functions are very useful when you are refactoring the -initialization file of a module. However, they aren't so efficient -when you need to execute them at demand (e.g., based on specific -conditions). When a module is executed, related functions are exported -to *centos-art.sh* script execution environment. They remain there, -consuming memory, until the module they belong to is destroyed. If you -create a related function and never execute it, it will consume -memory, as well. So, use related functions when you are absolutely -sure they will be executed at some point, in one single iteration of -*centos-art.sh* script. If you need to execute functions at demand, -use child modules, instead. - -[[module-implementation-child]] -Child Modules -~~~~~~~~~~~~~ -... - -[[module-implementation-siblings]] -Sibling Modules -~~~~~~~~~~~~~~~ - -... - -[[module-implementation-recursive]] -Recursive Modules -~~~~~~~~~~~~~~~~~ -... +Recursive execution of modules occurs only when the module you are +executing is considered sibling of the last module executed in the +chain of executed modules and they both have the same name. The fact +that no variable name is printed out in <> +means that they were not created. The arrows change from +->+ to +~>+, +means that module's related functions weren't exported for the new +module execution either. It also means that the initialization script +is reusing both related functions and variables from the last module +environment in the chain of executed modules. In this case the +*random* module. Summary ~~~~~~~ -... + +This section covered the resources you can use to optimize module +environments inside *centos-art.sh* script. The next section +summarizes the base files and directories you might find inside one +module environment. [[module-structure]] Module Structure ---------------- -The Modules Directory -~~~~~~~~~~~~~~~~~~~~~ +The module structure takes place at the root location of +*centos-art.sh* script, specifically, in a directory named +Modules+. +The +Modules+ directory at *centos-art.sh* root location is the +highest level which you can store modules in. Modules stored in this +location are known as parent modules. Parent modules can optimize +their structure by using related functions, child modules, sibling +modules and recursive modules. Basically, all these types of modules +share the same structure. They all have function files and, +optionally, module related stuff like locales, documentation, +configuration and dependent modules. See <>. -Inside the +Modules+ directory, regardless its level, there is one -directory for each module environment. Inside each module's directory -there is one initialization file and, optionally, one or more -module-related function files. and any of the following -sub-directories: - -Organizes child modules for the current module. This directory share -the same structural restrictions of its parent (e.g., each module -stored here needs to have a module directory and a initialization file -inside it to be functional). +[IMPORTANT] +From version 0.7 on, child modules no longer have +Locales+, +Manuals+ +and +Configs+ directories inside. Only initialization files, related +functions and +Modules+ directory are supported inside child modules. +See https://centos.org.cu/bugs/view.php?id=114[Bug 114]. -[[parent-module-layout-extended]] -.Directory layout used by parent modules (extended) +[[module-directory-layout]] +.The directory structure of hello module ====================================================================== ---------------------------------------------------------------------- . @@ -940,30 +848,108 @@ inside it to be functional). |-- Locales/ |-- Manuals/ |-- Modules/ -| `-- Hello/ -| |-- Modules/ -| | `-- Output/ <1> -| | |-- Lower/ <2> -| | | `-- lower.sh <3> -| | |-- Upper/ <4> -| | | `-- upper.sh <5> -| | `-- output.sh <6> -| |-- hello.sh -| `-- hello_getOptions.sh +| `-- Hello/ <1> +| |-- Locales +| | |-- es_ES +| | | |-- LC_MESSAGES +| | | | `-- hello.sh.mo <2> +| | | `-- hello.sh.po +| | `-- hello.sh.pot +| |-- Manuals +| | |-- hello.asciidoc +| | |-- man1 +| | | `-- hello.1 <3> +| | `-- render.conf <4> +| |-- Modules +| | `-- Output <5> +| | |-- Modules +| | | |-- Camel +| | | | `-- camel.sh +| | | |-- Lower <6> +| | | | `-- lower.sh <7> +| | | |-- Random +| | | | `-- random.sh +| | | `-- Upper +| | | `-- upper.sh +| | `-- output.sh <8> +| |-- hello.sh <9> +| `-- hello_getOptions.sh <10> |-- Scripts/ |-- centos-art.conf.sh `-- centos-art.sh ---------------------------------------------------------------------- -<1> Child module of hello module. -<2> Child module of output module and sibling module of upper module. -<3> Initialization file of lower module. -<4> Child module of output module and sibling module of lower module. -<5> Initialization file of upper module. -<6> Initialization file of output module. +<1> Child module of *centos-art.sh* script and parent module of +*output* module. +<2> Spanish translated strings of *hello* module. +<3> Manpage shown when you request help of *hello* module. +<4> Configuration file used to produce the manpage of *hello* module. +<5> Child module of *hello* module and parent module of *camel,* +*lower,* *random* and *upper* modules. +<6> Child module of *output* module and sibling module of *camel,* +*random* and *upper* module. +<7> Initialization file of *lower* module. +<8> Initialization file of *output* module. +<9> Initialization file of *hello* module. +<10> Function file related to *hello* module. ====================================================================== -[[module-locales-directory]] +<> presents a complete structure for module +environments you can use as reference for writing your own modules. It +begins with a parent module directory named ``Hello'' which contains +an initialization file (``hello.sh'') and one related function file +(``hello_getOptions.sh''). These files work together with a child +module named *output* which in turn has four child modules inside +named *camel,* *lower,* *random,* and *upper.* The +Locales+ directory +contains the required information to print *hello* messages in +different languages (e.g., it only supports Spanish language in our +example, but it can be extended to other languages as needed). The ++Manuals+ directory contains all the files required to produce +documentation for the *hello* module (e.g., the information you read +when provide the *--help* option in the command-line). + +The Function Files +~~~~~~~~~~~~~~~~~~ + +The function files are used to create the initialization file of a +module and the related functions of it. As convention, both +initialization file and related function files are stored in the +module's directory, see <>. + +At execution time, the definition of related function are exported to +*centos-art.sh* execution environment before executing the function +definition set inside the initialization file, so related functions +are always available for you to use in the initialization file file +and other related functions as well. This is rather useful when you +are refactoring your initialization scripts and probably related +functions as well. + +As naming convention, related function files are written using the +module's name, then an underscore (``_''), then a descriptive name +and, finally, the ``+.sh+'' extension. The function definition inside +the function file also follows this convention but excludes the +``+.sh+'' extension from name (e.g., the function file +``+hello_getOptions.sh+'' has a function definition named +``+hello_getOptions+'' inside). The *centos-art.sh* script relays in +these conventions to export and destroy related functions when new +module environments are created and destroyed. If you create related +function files with a pattern different from that described here, they +will not be executed nor available inside the initialization file of +the module environment being currently executed. + +See also: <> and <>. + +[[module-directory-modules]] +The +Modules+ Directory +~~~~~~~~~~~~~~~~~~~~~~~ + +This directory contains nested modules (e.g., child modules) and is +used for extending the current module functionality in a modular way. +There isn't a visible limitation in the number of +Modules+ directory +you can nest inside one module to achieve certain functionality so, +you can create as many levels of +Modules+ directories as you need. + +[[module-directory-locales]] The +Locales+ Directory ~~~~~~~~~~~~~~~~~~~~~~~ @@ -977,15 +963,16 @@ language. If the translatable strings inside the module's source files change, you need to run the *locale* module again to update the PO files and repeat the localization process all over again. -[[module-manuals-directory]] +[[module-directory-manuals]] The +Manuals+ Directory ~~~~~~~~~~~~~~~~~~~~~~~ This directory contains module-specific documentation. Documentation -in this directory are written in asciidoc format and produced through -the *render* functionality of *centos-art.sh* script. +in this directory is written in asciidoc format and produced through +the *render* module of *centos-art.sh* script to different formats, +including man pages and html. -[[module-configs-directory]] +[[module-directory-configs]] The +Configs+ Directory ~~~~~~~~~~~~~~~~~~~~~~~ @@ -1000,6 +987,8 @@ absolute path of module-related configuration file. Summary ~~~~~~~ -... + +This section has covered the directories and files a module is made of +inside the *centos-art.sh* script. // vim: set syntax=asciidoc: