diff --git a/Automation/Manuals/Understanding_Modules/understanding_modules.asciidoc b/Automation/Manuals/Understanding_Modules/understanding_modules.asciidoc index f58cbf6..ffdb5ac 100644 --- a/Automation/Manuals/Understanding_Modules/understanding_modules.asciidoc +++ b/Automation/Manuals/Understanding_Modules/understanding_modules.asciidoc @@ -44,6 +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 ~~~~~~~~~~~~~~ @@ -113,7 +114,6 @@ 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. -[[child-modules]] Child Modules ~~~~~~~~~~~~~ @@ -517,6 +517,10 @@ 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. +[[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 @@ -531,15 +535,16 @@ directory. See <>. ====================================================================== ---------------------------------------------------------------------- . -|-- COPYING <1> -|-- Locales/ <2> -|-- Manuals/ <3> -|-- Modules/ <4> -| `-- Hello/ <5> -| `-- hello.sh <6> -|-- Scripts/ <7> -|-- centos-art.conf.sh <8> -`-- centos-art.sh <9> +|-- 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. @@ -548,9 +553,10 @@ directory. See <>. <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> Script's global functions. -<8> Script's configuration file. -<9> Script's initialization file. +<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 @@ -590,7 +596,7 @@ 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 +<>, and they help you to keep the initialization file in a clean state, easy to understand, maintain and debug. @@ -647,207 +653,132 @@ 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 optimize module +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-directory-structure]] -Module Directory Structure --------------------------- +[[optimizing-module-implementation]] +Module Optimization +------------------- -Child modules and sibling modules are nested modules. They are stored -inside other modules. Frequently we first write parent modules and -extend them through child modules. This, when function related files -cannot fix the problem efficiently. Module related function files are -stored at the same level of initialization file inside the module's -directory. +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''. -[[child-module-layout]] -.The directory structure of child and sibling modules -====================================================================== ----------------------------------------------------------------------- -. -|-- COPYING -|-- 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 -|-- Scripts/ -|-- centos-art.conf.sh -`-- centos-art.sh ----------------------------------------------------------------------- +[[module-related-functions]] +Related Functions +~~~~~~~~~~~~~~~~~ -<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. +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. +# +###################################################################### -The +Modules+ Directory -~~~~~~~~~~~~~~~~~~~~~~~ - -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: - -+Modules/+:: - 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). To know more - about this directory, see <>. - -+Locales/+:: - Organizes localization files for the current module. This - directory contains POT, PO and MO files, the *centos-art.sh* - script needs to print localized messages. Must of these files are - automatically created by *locale* module. To know more about this - directory, see <>. - -+Manuals/+:: - Organizes documentation files for the current module. This - directory contains asciidoc files used to produce documentation in - html and manpage format. The manpage format is used by - centos-art.sh script to print module's documentation when the - *--help* option is passed to the command-line. To know more about - this directory, see <>. - -+Configs/+:: - Organizes configuration files for the current module. This - directory contains non-sh files the current module depends on to - complete the task it was created for (e.g., sed scripts, gawk - scripts, etc.). To know more about this directory, see - <>. - -Module directories and module initialization files must have the same -name. Module directories are written capitalized and initialization -files in lowercase. Module related functions are written in camel-case -and use the module name as suffix. More about module-related functions -and child modules, later, in <>. - -... describes the root location of *centos-art.sh* -script and <> how it looks like after adding the -*hello* module to it. In this last example, the directory named -``Hello'' contains the files related to *hello* module environment -(e.g., the initialization file). Other components like module related -functions were intentionally omitted for simplicity sake. They are -covered later, in <>. - -[[module-locales-directory]] -The +Locales+ Directory -~~~~~~~~~~~~~~~~~~~~~~~ - -Module localization ... - -[[module-manuals-directory]] -The +Manuals+ Directory -~~~~~~~~~~~~~~~~~~~~~~~ +function hello { -Module documentation ... + # Define default greeting message. + local HELLO_WORLD="`gettext "Hello, World!"`" -[[module-configs-directory]] -Module +Configs+ Directory -~~~~~~~~~~~~~~~~~~~~~~~~~~ + # Define actions variable. Here is where actions related to + # module-specific options are stored in for further processing. + local ACTIONS='' -Module configuration ... + # Interpret module-specific options and store related actions. + hello_getOptions -Summary -~~~~~~~ + # 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 -This section described how you can create a functional module -environment from scratch. However, it doesn't explain how you can -extend the module environment using related functions or child -modules. The next section introduces the concept of module functions -and explain how you can use them to extend the functionality of an -existing module environment. - -[[extended-module-implementation]] -Extended Module Implementation ------------------------------- - -Module-specific functions are stored in the same location you store -module's initialization file. Definitions of module-specific functions -are made available in the execution environment before executing the -module's initialization file. This way, module-specific functions are -always available inside the module's initialization file. -Module-specific functions are very useful when you are refactoring the -module's initialization file. - -For example, consider extending the *hello* module, to vary the -``Hello, World!'' greeting message to something else based on a -*--greeting* option passed through the command-line. For this, we can -write everything in the module's initialization file or create a -module-specific function to take care of all related actions and then -execute it from module's initialization file. Because we want to keep -the module's initialization file small and clean, we decided to create -a module-specific function named *hello_getOptions*. This function is -stored in a file named +hello_getOptions.sh+, at the same location of -+hello.sh+ module's initialization file. See <>. - -[[script-main-layout-2]] -.The module directory structure with related function -====================================================================== ----------------------------------------------------------------------- -. -|-- COPYING -|-- Locales/ -|-- Manuals/ -|-- Modules/ -| `-- Hello/ -| |-- hello.sh -| `-- hello_getOptions.sh <-- module-related function. -|-- Scripts/ -|-- centos-art.conf.sh -`-- centos-art.sh +} ---------------------------------------------------------------------- ====================================================================== -As name convention, module-specific functions must be written using -the module's name as suffix, then an underscore, then a descriptive -name to identify the function. This convention is important in order -for *centos-art.sh* script to execute and destroy modules as expected. -If you create module-specific functions with a different pattern they -will not be executed nor available inside your module's initialization -file. - -The name of the module-specific function +hello_getOptions+ is result -of another name convention we are using inside *centos-art.sh* script. -This is, when you need to provide argument parsing for a parent -module, create a module-specific function with +_getOptions+ as prefix -on its file name, then put all the code related to argument parsing -inside it. Using a different function name here doesn't affect the -execution of your module (as long as you retain the module's name as -suffix). However, using this name convention, helps to keep a -consistent directory structure inside the script. - -The content of the module-specific function named +hello_getOptions+ -is also considered even another convention, a procedural convention at -this time. It provides the standard construction you should use -whenever you want to make parent modules able to process arguments -passed through the command-line. Through this construction, you can -define which are the short and long options the module you are writing -accepts and the possible values assigned to them, when passed. -Basically, this construction transform the option arguments passed in -the command-line in a way they can be parsed predictably, then parses -them leaving non-option arguments, only.footnote:[To know more about -option parsing inside *centos-art.sh* script, read the article named -``_Understanding Option Parsing._''] See <>. - -[[processing-args-from-cmd]] -.Processing arguments from the command-line +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. + +<> 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) ====================================================================== ---------------------------------------------------------------------- #!/bin/bash @@ -879,10 +810,10 @@ option parsing inside *centos-art.sh* script, read the article named function hello_getOptions { # Define short options we want to support. - local ARGSS="h::,v,g:" + local ARGSS="h::,v,g:,l,u,c,r" # Define long options we want to support. - local ARGSL="help::,version,greeting:" + local ARGSL="help::,version,greeting:,lower,upper,camel,random" # Redefine arguments using getopt(1) command parser. tcar_setModuleArguments @@ -908,6 +839,26 @@ function hello_getOptions { 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 @@ -923,78 +874,132 @@ function hello_getOptions { ---------------------------------------------------------------------- ====================================================================== +[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 ~~~~~~~~~~~~~~~~~ ... Summary ~~~~~~~ +... + +[[module-structure]] +Module Structure +---------------- + +The Modules Directory +~~~~~~~~~~~~~~~~~~~~~ + +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). -This section has covered ... - -Conventions ------------ - -When you write modules to *centos-art.sh* script, consider the -following common conventions: - -* Module directories are written capitalized (e.g., `Hello') while - module initialization file (e.g., `hello.sh') are written in - lower-case. - -* When you write related functions, use underscore (``_'') to separate - the module's name from the function's descriptive name. In these - cases, the function's descriptive name is always written in - camel-case (e.g., `hello_getOptions.sh'). - -* Module directories and files inside them use the module's name as - suffix in their file names to get identified. This is convention - should be followed in order for *centos-art.sh* script to execute - and destroy modules as expected. - -* The directory structure of a module is made of an initialization - file, module-specific functions and module-specific directories. - From all these components, only the initialization file is required - in order to have a functional module. The module-specific functions - are useful for refactoring the initialization file. The - module-specific directories are optional but, if use, must have the - following names and meaning: -+ -+Modules/+:: - This directory contains module-specific child modules. The purpose - of Modules/ directory is extending the functionality of higher - module environments. -+Manuals/+:: - 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. -+Configs/+:: - 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. -+Locales/+:: - 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. +[[parent-module-layout-extended]] +.Directory layout used by parent modules (extended) +====================================================================== +---------------------------------------------------------------------- +. +|-- COPYING +|-- 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 +|-- 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. +====================================================================== + +[[module-locales-directory]] +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-manuals-directory]] +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. + +[[module-configs-directory]] +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 +~~~~~~~ +... // vim: set syntax=asciidoc: