Salome HOME
architecture finalization and commentaries for main executable file
authorSerge Rehbinder <serge.rehbinder@cea.fr>
Thu, 28 Jan 2016 13:29:05 +0000 (14:29 +0100)
committerSerge Rehbinder <serge.rehbinder@cea.fr>
Thu, 28 Jan 2016 13:29:05 +0000 (14:29 +0100)
data/site.pyconf [new file with mode: 0644]
src/config.py
src/salomeTools.py
src/test_command.py [new file with mode: 0644]
test/test.py

diff --git a/data/site.pyconf b/data/site.pyconf
new file mode 100644 (file)
index 0000000..9a58fcd
--- /dev/null
@@ -0,0 +1,11 @@
+#!/usr/bin/env python
+#-*- coding:utf-8 -*-
+
+SITE :
+{   
+    config : 
+    {
+        configPath : ["/home/salome/SPN_PRIVATE/sat5dev_Applications"]
+    }
+}
+
index 954075c8cd6f94a66bc19ac4b1546e2a20152226..d62cec1f4137ceb0d9774780c750cbf6894b4c81 100644 (file)
 
 import os
 import sys
-import common
 import platform
 import datetime
 import glob
 import re
 import shutil
 
+import common
+
 # Define all possible option for config command :  sat config <options>
 parser = common.options.Options()
 parser.add_option('v', 'value', 'string', 'value', "print the value of CONFIG_VARIABLE.")
@@ -134,17 +135,18 @@ class ConfigManager:
 
     def get_command_line_overrides(self, options, sections):
         '''get all the overwrites that are in the command line
-        :param options : TO DO
-        :param sections str: The command that is called.
-        :return: The list of all the overwrites of the command line.
+        :param options : the options from salomeTools class initialization (like -l5 or --overwrite)
+        :param sections str: The config section to overwrite.
+        :return: The list of all the overwrites to apply.
         :rtype: list
         '''
         # when there are no options or not the overwrite option, return an empty list
         if options is None or options.overwrite is None:
             return []
-
+        
         over = []
         for section in sections:
+            # only overwrite the sections that correspond to the option 
             over.extend(filter(lambda l: l.startswith(section + "."), options.overwrite))
         return over
 
@@ -382,7 +384,6 @@ def description():
 
 def run(args, runner):
     (options, args) = parser.parse_args(args)
-    print('Je suis dans la commande config ! Bien jouĂ© ! COUCOU')
     if options.value:
         print_value(runner.cfg, options.value, True, level=0, show_full_path=False)
     
\ No newline at end of file
index e5d8b78b9726d0b404a89ad6b1be8050f6406730..ccfa5ebef69d05e29533d601a181dee63e69de0c 100755 (executable)
 '''This file is the main entry file to salomeTools
 '''
 
+# python imports
 import os
 import sys
 import imp
 import types
 import gettext
 
+# salomeTools imports
 import common.options
 import config
 
@@ -32,141 +34,190 @@ import config
 srcdir = os.path.dirname(os.path.realpath(__file__))
 
 # load resources for internationalization
-#gettext.install('salomeTools', os.path.join(srcdir, 'common', 'i18n'))
-
 es = gettext.translation('salomeTools', os.path.join(srcdir, 'common', 'i18n'))
 es.install()
 
-def find_command_list():
+def find_command_list(dirPath):
+    ''' Parse files in dirPath that end with .py : it gives commands list
+    :param dirPath str: The directory path where to search the commands
+    :return: cmd_list : the list containing the commands name 
+    :rtype: list
+    '''
     cmd_list = []
-    for item in os.listdir(srcdir):
+    for item in os.listdir(dirPath):
         if item.endswith('.py') and item!='salomeTools.py':
             cmd_list.append(item[:-len('.py')])
     return cmd_list
 
 # The list of valid salomeTools commands
 #lCommand = ['config', 'compile', 'prepare']
-lCommand = find_command_list()
+lCommand = find_command_list(srcdir)
 
 # Define all possible option for salomeTools command :  sat <option> <args>
 parser = common.options.Options()
-parser.add_option('h', 'help', 'boolean', 'help', _(u"shows global help or help on a specific command."))
+parser.add_option('h', 'help', 'boolean', 'help', _("shows global help or help on a specific command."))
+parser.add_option('o', 'overwrite', 'list', "overwrite", _("overwrites a configuration parameters."))
+parser.add_option('g', 'debug', 'boolean', 'debug_mode', _("run salomeTools in debug mode."))
 
 class salomeTools(object):
+    '''The main class that stores all the commands of salomeTools
+    '''
     def __init__(self, opt, dataDir=None):
         '''Initialization
+        :param opt str: The sat options 
+        :param: dataDir str : the directory that contain all the external data (like software pyconf and software scripts)
         '''
         # Read the salomeTools options (the list of possible options is at the beginning of this file)
         try:
-            (options, args) = parser.parse_args(opt)
+            (options, argus) = parser.parse_args(opt.split(' '))
         except Exception as exc:
             write_exception(exc)
             sys.exit(-1)
-                           
+
+        # initialization of class attributes       
         self.__dict__ = dict()
-        self.options = options
-        self.dataDir = dataDir
-        # set the commands
+        self.cfg = None # the config that will be read using config_pyconf module
+        self.options = options # the options passed to salomeTools
+        self.dataDir = dataDir # default value will be <salomeTools root>/data
+        # set the commands by calling the dedicated function
         self.__setCommands__(srcdir)
         
+        # if the help option has been called, print help and exit
         if options.help:
             try:
-                self.print_help(args)
+                self.print_help(argus)
                 sys.exit(0)
             except Exception as exc:
-                code = 1
                 write_exception(exc)
+                sys.exit(1)
 
     def __getattr__(self, name):
+        ''' overwrite of __getattr__ function in order to display a customized message in case of a wrong call
+        :param name str: The name of the attribute 
+        '''
         if name in self.__dict__:
             return self.__dict__[name]
         else:
             raise AttributeError(name + _(" is not a valid command"))
-
-    def __setattr__(self, name, value):
-        object.__setattr__(self,name,value)
-
-
+    
     def __setCommands__(self, dirPath):
+        '''set class attributes corresponding to all commands that are in the dirPath directory
+        :param dirPath str: The directory path containing the commands 
+        '''
+        # loop on the commands name
         for nameCmd in lCommand:
+            # load the module that has name nameCmd in dirPath
             (file_, pathname, description) = imp.find_module(nameCmd, [dirPath])
             module = imp.load_module(nameCmd, file_, pathname, description)
-
+            
             def run_command(args):
-                print('Je suis dans l\'initialisation de la commande ' + __name__)
+                '''The function that will load the configuration (all pyconf)
+                and return the function run of the command corresponding to module
+                :param args str: The directory path containing the commands 
+                '''
                 argv = args.split(" ")
                 
                 # first argument is the APPLICATION
                 appliToLoad = None
-                if len(argv) > 0 and argv[0][0] != "-":
+                if argv != [''] and argv[0][0] != "-":
                     appliToLoad = argv[0].rstrip('*')
                     argv = argv[1:]
                 
-                # read the configuration from all the pyconf files    
-                cfgManager = config.ConfigManager()
-                self.cfg = cfgManager.getConfig(dataDir=self.dataDir, application=appliToLoad)
+                # Read the config if it is not already done
+                if not self.cfg:
+                    # read the configuration from all the pyconf files    
+                    cfgManager = config.ConfigManager()
+                    self.cfg = cfgManager.getConfig(dataDir=self.dataDir, application=appliToLoad, options=self.options)
                 
                 return __module__.run(argv, self)
 
+            # Make sure that run_command will be redefined at each iteration of the loop
             globals_up = {}
             globals_up.update(run_command.__globals__)
             globals_up.update({'__name__': nameCmd, '__module__' : module})
             func = types.FunctionType(run_command.__code__, globals_up, run_command.__name__,run_command.__defaults__, run_command.__closure__)
 
+            # set the attribute corresponding to the command
             self.__setattr__(nameCmd, func)
 
-    def print_help(self, argv):
-        '''Prints help for a command
+    def print_help(self, opt):
+        '''Prints help for a command. Function called when "sat -h <command>"
+        :param argv str: the options passed (to get the command name)
         '''
-        command = argv[0]
+        # if no command as argument (sat -h)
+        if len(opt)==0:
+            print_help()
+            return
+        # get command name
+        command = opt[0]
         # read the configuration from all the pyconf files    
         cfgManager = config.ConfigManager()
         self.cfg = cfgManager.getConfig(dataDir=self.dataDir)
 
+        # Check if this command exists
         if not hasattr(self, command):
             raise common.SatException(_("Command '%s' does not exist") % command)
-
+        
+        # Print salomeTools version
         print_version()
         
+        # load the module
         module = self.get_module(command)
 
+        # print the description of the command that is done in the command file
         if hasattr( module, "description" ) :
             print(common.printcolors.printcHeader( _("Description:") ))
             print(module.description() + '\n')
 
+        # print the description of the command options
         if hasattr( module, "parser" ) :
             module.parser.print_help()
 
     def get_module(self, module):
+        '''Loads a command. Function called only by print_help
+        :param module str: the command to load
+        '''
+        # Check if this command exists
         if not hasattr(self, module):
             raise common.SatException(_("Command '%s' does not exist") % module)
 
-        # reduce variables substitution and so on
+        # load the module
         (file_, pathname, description) = imp.find_module(module, [srcdir])
         module = imp.load_module(module, file_, pathname, description)
         return module
  
 def print_version():
+    '''prints salomeTools version (in src/common/internal_config/salomeTools.pyconf)
+    '''
+    # read the config 
     cfgManager = config.ConfigManager()
     cfg = cfgManager.getConfig()
+    # print the key corresponding to salomeTools version
     print(common.printcolors.printcHeader( _("Version: ") ) + cfg.INTERNAL.sat_version + '\n')
 
 
-def print_help(options):
+def print_help():
+    '''prints salomeTools general help
+    :param options str: the options
+    '''
     print_version()
     
     print(common.printcolors.printcHeader( _("Usage: ") ) + "sat [sat_options] <command> [product] [command_options]\n")
 
     parser.print_help()
 
-    # parse the src directory to list the available commands.
+    # display all the available commands.
     print(common.printcolors.printcHeader(_("Available commands are:\n")))
     for command in lCommand:
         print(" - %s" % (command))
-
-    print(common.printcolors.printcHeader(_(u"\nGetting the help for a specific command: ")) + "sat --help <command>\n")
+        
+    # Explain how to get the help for a specific command
+    print(common.printcolors.printcHeader(_("\nGetting the help for a specific command: ")) + "sat --help <command>\n")
 
 def write_exception(exc):
+    '''write exception in case of error in a command
+    :param exc exception: the exception to print
+    '''
     sys.stderr.write("\n***** ")
     sys.stderr.write(common.printcolors.printcError("salomeTools ERROR:"))
     sys.stderr.write("\n" + str(exc) + "\n")
@@ -179,21 +230,26 @@ if __name__ == "__main__":
     cmd_line = " ".join(sys.argv)
     # Initialize the code that will be returned by the terminal command 
     code = 0
-
     (options, args) = parser.parse_args(sys.argv[1:])
-    
-    if len(args) == 0:
-        # no options => show help
-        print_help(options)
-    else:
-        sat = salomeTools(sys.argv[1:])
-        command = args[0]
-        fun_command = sat.__getattr__(command)
-        if len(args[1:]) == 0:
-            print(common.printcolors.printcWarning(_("No arguments")))
-            sys.exit(0)
-        fun_command(' '.join(args[1:]))
 
+    # instantiate the salomeTools class with correct options
+    sat = salomeTools(' '.join(sys.argv[1:]))
+    # the command called
+    command = args[0]
+    # get dynamically the command function to call
+    fun_command = sat.__getattr__(command)
+    if options.debug_mode:
+        # call classically the command and if it fails, show exception and stack (usual python mode)
+        code = fun_command(' '.join(args[1:]))
+    else:
+        # catch exception in order to show less verbose but elegant message
+        try:
+            code = fun_command(' '.join(args[1:]))
+        except Exception as exc:
+            code = 1
+            write_exception(exc)
     
-
-
+    # exit salomeTools with the right code (0 if no errors, else 1)
+    if code is None: code = 0
+    sys.exit(code)
+        
\ No newline at end of file
diff --git a/src/test_command.py b/src/test_command.py
new file mode 100644 (file)
index 0000000..cac7729
--- /dev/null
@@ -0,0 +1,21 @@
+#!/usr/bin/env python
+#-*- coding:utf-8 -*-
+
+import common
+
+# Define all possible option for config command :  sat config <options>
+parser = common.options.Options()
+parser.add_option('u', 'unique', 'boolean', 'unique', "TEST d'option.")
+parser.add_option('v', 'value', 'string', 'value', "Appelle la commande config avec l'option value.")
+
+def description():
+    return _("Test d'une commande supplĂ©mentaire.")
+    
+
+def run(args, runner):
+    (options, args) = parser.parse_args(args)
+    if options.unique:
+        print('unique')
+    elif options.value:
+        runner.cfg.VARS.user = 'TEST'
+        runner.config('-v ' + options.value)
index 39673e7ebc2b93c61cae27e8ea8fceaaccf91235..842475a4641868e9181b69ee4f4340fc2324427e 100644 (file)
@@ -24,5 +24,8 @@ sys.path.append(os.path.join(testdir, '..', 'src'))
 
 from salomeTools import salomeTools
 
-sat = salomeTools('--help')
+sat = salomeTools('')
 sat.config('appli-test -v APPLICATION')
+
+sat2 = salomeTools("-oINTERNAL.sat_version='coucou'")
+sat2.config('appli-test -v INTERNAL.sat_version')