| Understanding Modules |
| ===================== |
| Alain Reguera Delgado <al@centos.org.cu> |
| v0.1, Oct 2013 |
| |
| Overview |
| -------- |
| |
| From version 0.5, *centos-art.sh* script implements the idea of |
| modules to its base design. Modules are a collection of functions |
| written in Bash that can call themselves one another to create |
| individual execution environments. They may be nested to achieve high |
| levels of maintainability and extensibility. This make possible for |
| modules writers to divide complicated tasks into smaller tasks that |
| can be easier to debug, maintain and share with other modules |
| efficiently (e.g., instead of loading modules all at once, they are |
| only loaded at demand and unset once they conclude their execution). |
| |
| This article describes the modular design of *centos-art.sh* script. |
| It is a good place for you to start if you are planning to contribute |
| new module environments to *centos-art.sh* script or want to know more |
| about how they work. The next section delves into what a module |
| environment is, the three module types you can find in it and the |
| correct way of execute each one of them. |
| |
| [[module-environment]] |
| Module Environment |
| ------------------ |
| |
| When you execute the *centos-art.sh* script you create an execution |
| environment in which variables and functions are defined. This |
| execution environment is the higher environment inside *centos-art.sh* |
| script. It is considered to have a ``global'' scope, so variables and |
| functions defined inside it are always available for any function |
| execution made from it. You can control the execution environment of |
| *centos-art.sh* script through +centos-art.sh+ and |
| +centos-art.conf.sh+ files. These files don't provide too much |
| functionality so specific module environments are executed from |
| +centos-art.sh+ at demand, to extend its functionality. |
| |
| Module environments are made of small functions that perform small |
| tasks and can be further executed in a specific order to produce a |
| 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.'' |
| |
| [[parent-modules-environment]] |
| Parent Modules |
| ~~~~~~~~~~~~~~ |
| |
| Parent modules are initiated by executing the |
| *tcar_setModuleEnvironment* function with the *-t parent* option set |
| on it. Parent modules are very simple in design and you can use them |
| to implement simple solutions quickly. Normally, when you execute a |
| parent module, you initiate the highest module environment possible |
| inside *centos-art.sh* script. Because of such high scope, parent |
| modules are frequently used to define module's global variables, |
| interpret module-specific options passed through the command-line and |
| execute the appropriate actions based on them. |
| |
| In <<debug-parent-modules>>, we have executed the *hello* module with |
| the *--greeting=hi* and *--debug* options through the command-line. In |
| this example, *centos-art.sh* script executes a parent module named |
| *hello*, processes the module-specific options passed through the |
| command-line, prints a greeting message to standard output and exits |
| successfully. |
| |
| [[debug-parent-modules]] |
| .Debugging execution of parent modules |
| ====================================================================== |
| ---------------------------------------------------------------------- |
| Thu 10 Oct 2013 11:53:28 PM CDT =========================> [0] | main |
| Thu 10 Oct 2013 11:53:28 PM CDT TCAR_MODULE_BASEDIR Automation/Modules |
| Thu 10 Oct 2013 11:53:28 PM CDT TCAR_MODULE_NAME [0]=hello |
| Thu 10 Oct 2013 11:53:28 PM CDT TCAR_MODULE_TYPE parent |
| Thu 10 Oct 2013 11:53:28 PM CDT TCAR_MODULE_ARGUMENT --greeting=hi |
| Thu 10 Oct 2013 11:53:28 PM CDT TCAR_MODULE_LIST hello|help|locale|prepare|render|tuneup|vcs |
| Thu 10 Oct 2013 11:53:28 PM CDT TCAR_MODULE_DIR Automation/Modules/Hello |
| Thu 10 Oct 2013 11:53:28 PM CDT TCAR_MODULE_DIR_MODULES Automation/Modules/Hello/Modules |
| Thu 10 Oct 2013 11:53:28 PM CDT TCAR_MODULE_DIR_MANUALS Automation/Modules/Hello/Manuals |
| Thu 10 Oct 2013 11:53:28 PM CDT TCAR_MODULE_DIR_LOCALES Automation/Modules/Hello/Locales |
| Thu 10 Oct 2013 11:53:28 PM CDT TCAR_MODULE_DIR_CONFIGS Automation/Modules/Hello/Configs |
| Thu 10 Oct 2013 11:53:28 PM CDT TCAR_MODULE_INIT_FILE Automation/Modules/Hello/hello.sh |
| Thu 10 Oct 2013 11:53:28 PM CDT TEXTDOMAIN hello.sh |
| Thu 10 Oct 2013 11:53:28 PM CDT TEXTDOMAINDIR Automation/Modules/Hello/Locales |
| Thu 10 Oct 2013 11:53:28 PM CDT export -f hello |
| Thu 10 Oct 2013 11:53:28 PM CDT export -f hello_getOptions |
| Thu 10 Oct 2013 11:53:28 PM CDT -------------------------> hello --greeting=hi |
| hi |
| Thu 10 Oct 2013 11:53:28 PM CDT <------------------------- hello |
| Thu 10 Oct 2013 11:53:28 PM CDT unset -f hello |
| Thu 10 Oct 2013 11:53:28 PM CDT unset -f hello_getOptions |
| Thu 10 Oct 2013 11:53:28 PM CDT <========================= [0] | main |
| ---------------------------------------------------------------------- |
| ====================================================================== |
| |
| <<debug-parent-modules>> describes an entire module environment in |
| 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 as described in |
| <<module-optimization>>. |
| |
| Summary |
| ~~~~~~~ |
| |
| 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. |
| |
| [[module-implementation]] |
| Module Implementation |
| --------------------- |
| |
| The *centos-art.sh* script implements module environments inside the |
| ``+Modules+'' directory, as described in <<module-structure>>. |
| |
| [[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>>. |
| |
| [[parent-module-layout]] |
| .Directory layout used by parent modules |
| ====================================================================== |
| ---------------------------------------------------------------------- |
| . |
| |-- 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. |
| ====================================================================== |
| |
| <<parent-module-layout>> 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>>. |
| |
| [[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 |
| <<initialization-file>>. |
| |
| 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 <<module-optimization>>, 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 <al@centos.org.cu>, 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 <<initialization-file>> 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 <<debug-parent-modules>>. |
| |
| 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. |
| |
| [[module-optimization]] |
| 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''. |
| |
| [[related-functions]] |
| Related Functions |
| ~~~~~~~~~~~~~~~~~ |
| |
| 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 <<initialization-file-extended>>. |
| |
| [[initialization-file-extended]] |
| .Initialization file used by hello module (extended) |
| ====================================================================== |
| ---------------------------------------------------------------------- |
| function hello { |
| |
| # Define default greeting message. |
| local HELLO_WORLD="`gettext "Hello, World!"`" |
| |
| # Define actions variable. Here is where actions related to |
| # module-specific options are stored in for further processing. |
| local ACTIONS='' |
| |
| # Interpret module-specific options and store related actions. |
| hello_getOptions |
| |
| # Print greeting message |
| if [[ -z ${ACTIONS} ]];then |
| # Using parent module. |
| tcar_printMessage "${HELLO_WORLD}" --as-stdout-line |
| else |
| # Using child module. |
| tcar_setModuleEnvironment -m 'output' -t 'child' |
| fi |
| |
| } |
| ---------------------------------------------------------------------- |
| ====================================================================== |
| |
| When you execute the command *centos-art.sh hello* with the |
| *--greeting=hi* argument, *centos-art.sh* stores module-specific |
| arguments inside the +TCAR_MODULE_ARGUMENT+ variable, creates a list |
| of all function definitions inside the module directory and exports |
| them. This includes the function definition of the initialization |
| file itself. Then *centos-art.sh* executes the function definition |
| set inside the initialization file and leaves all other function |
| definitions, already in memory, waiting for further execution. At this |
| point, the *hello* initialization function sets some default values |
| and execute the *hello_getOptions* function to parse all the arguments |
| passed through the command-line and redefines the +ACTIONS+ variable |
| based on them. Using the +ACTIONS+ variables it decides whether to |
| print the greeting message immediately or execute the child modules |
| named *output* so it decides what to do with the information collected |
| so far. |
| |
| <<hello_getOptions-definition>> defines the options you can pass to |
| *hello* module and the associated actions they must perform for each |
| of them. Actions aren't immediately executed here. Instead, they are |
| stored in the +ACTIONS+ variable for further processing (e.g., we |
| store the names of the modules we want to execute later). The |
| +ACTIONS+ variable was defined in the initialization file so it has a |
| global scope inside the module environment and is reachable from any |
| related function executed inside it. Storing the actions this way |
| lets the *hello* module to collect information about different actions |
| and execute them all in just one command. When all options have been |
| parsed, only non-option arguments remain in the +TCAR_MODULE_ARGUMENT+ |
| variable. |
| |
| [[hello_getOptions-definition]] |
| .Related function definition (hello_getOptions) |
| ====================================================================== |
| ---------------------------------------------------------------------- |
| 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] |
| <<hello_getOptions-definition>> 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>>. |
| |
| [[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 <<debug-child-modules>> 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 <<debug-sibling-modules>>. |
| |
| In <<debug-sibling-modules>>, 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 |
| ---------------------------------------------------------------------- |
| ====================================================================== |
| |
| <<debug-sibling-modules>> 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]] |
| 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 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 |
| <<debug-recursive-modules>>. |
| |
| [CAUTION] |
| When you execute modules recursively, you should be very careful not |
| to get trapped into an endless loop. |
| |
| In <<debug-recursive-modules>>, 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 |
| ---------------------------------------------------------------------- |
| ====================================================================== |
| |
| 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 <<debug-recursive-modules>> |
| 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 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 <<module-directory-layout>>. |
| |
| [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]. |
| |
| [[module-directory-layout]] |
| .The directory structure of hello module |
| ====================================================================== |
| ---------------------------------------------------------------------- |
| . |
| |-- COPYING |
| |-- Locales/ |
| |-- Manuals/ |
| |-- Modules/ |
| | `-- 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 *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-directory-layout>> 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 <<module-directory-layout>>. |
| |
| 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: <<module-init-file>> and <<related-functions>>. |
| |
| [[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 |
| ~~~~~~~~~~~~~~~~~~~~~~~ |
| |
| This directory contains module-specific localization files. The |
| content of this directory is automatically generated by *locale* |
| module of *centos-art.sh* script, when you execute it using the |
| initialization file as source and the *--update --sibling* options. |
| Once the localization files have been created, you need to edit PO |
| files to translate the strings from English to your preferred |
| 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-directory-manuals]] |
| The +Manuals+ Directory |
| ~~~~~~~~~~~~~~~~~~~~~~~ |
| |
| This directory contains module-specific documentation. Documentation |
| 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-directory-configs]] |
| The +Configs+ Directory |
| ~~~~~~~~~~~~~~~~~~~~~~~ |
| |
| This directory contains module-specific configuration. Some modules |
| (e.g., ``tuneup'') need to store auxiliary files required to achieve |
| its main goal (e.g., the ``tuneup'' module uses sed files to transform |
| the top-comment of scripts each time it is executed, the sed file |
| itself is stored in this directory). Whenever you need to make |
| reference to a file inside this directory, use the |
| ``TCAR_MODULE_DIR_CONFIGS'' variable. This variable provides the |
| 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. |
| |
| |