import re
import src
+import src.debug as DBG
+import src.returnCode as RCO
+from src.salomeTools import _BaseCommand
# Compatibility python 2/3 for input function
# input stays input for python 3 and input = raw_input for python 2
PROPERTY_EXPRESSION = "^.+:.+$"
-# Define all possible option for the clean command : sat clean <options>
-parser = src.options.Options()
-parser.add_option('p', 'products', 'list2', 'products',
- _('Optional: Products to clean. This option can be'
- ' passed several time to clean several products.'))
-parser.add_option('', 'properties', 'string', 'properties',
- _('Optional: Filter the products by their properties.\n'
- '\tSyntax: --properties <property>:<value>'))
-parser.add_option('s', 'sources', 'boolean', 'sources',
- _("Optional: Clean the product source directories."))
-parser.add_option('b', 'build', 'boolean', 'build',
- _("Optional: Clean the product build directories."))
-parser.add_option('i', 'install', 'boolean', 'install',
- _("Optional: Clean the product install directories."))
-parser.add_option('a', 'all', 'boolean', 'all',
- _("Optional: Clean the product source, build and install directories."))
-parser.add_option('', 'sources_without_dev', 'boolean', 'sources_without_dev',
- _("Optional: do not clean the products in development mode."))
-
-def get_products_list(options, cfg, logger):
- '''method that gives the product list with their informations from
- configuration regarding the passed options.
-
- :param options Options: The Options instance that stores the commands
- arguments
- :param config Config: The global configuration
- :param logger Logger: The logger instance to use for the display and logging
- :return: The list of (product name, product_informations).
- :rtype: List
- '''
- # Get the products to be prepared, regarding the options
- if options.products is None:
- # No options, get all products sources
- products = cfg.APPLICATION.products
- else:
- # if option --products, check that all products of the command line
- # are present in the application.
- products = options.products
- for p in products:
- if p not in cfg.APPLICATION.products:
- raise src.SatException(
- _("Product %(product)s not defined in application %(application)s") % \
- {'product': p, 'application': cfg.VARS.application} )
-
- # Construct the list of tuple containing
- # the products name and their definition
- products_infos = src.product.get_products_infos(products, cfg)
-
- # if the property option was passed, filter the list
- if options.properties:
- [prop, value] = options.properties.split(":")
- products_infos = [(p_name, p_info) for
- (p_name, p_info) in products_infos
- if "properties" in p_info and
- prop in p_info.properties and
- p_info.properties[prop] == value]
-
- return products_infos
def get_source_directories(products_infos, without_dev):
'''Returns the list of directory source paths corresponding to the list of
path.rm()
logger.write('%s\n' % src.printcolors.printc(src.OK_STATUS), 3)
-def description():
- '''method that is called when salomeTools is called with --help option.
-
- :return: The text to display for the clean command description.
- :rtype: str
- '''
- return _("""\
-The clean command suppress the source, build, or install directories
-of the application products.
-Use the options to define what directories you want to suppress and
-to reduce the list of products
-
-example:
->> sat clean SALOME-master --build --install --properties is_salome_module:yes""")
+
+########################################################################
+# Command class for command 'sat config etc.'
+########################################################################
+class Command(_BaseCommand):
-def run(args, runner, logger):
- '''method that is called when salomeTools is called with clean parameter.
- '''
-
- # Parse the options
- (options, args) = parser.parse_args(args)
-
- # check that the command has been called with an application
- src.check_config_has_application( runner.cfg )
-
- # Verify the --properties option
- if options.properties:
- oExpr = re.compile(PROPERTY_EXPRESSION)
- if not oExpr.search(options.properties):
- msg = _('WARNING: the "--properties" options must have the '
- 'following syntax:\n--properties <property>:<value>')
- logger.write(src.printcolors.printcWarning(msg), 1)
- logger.write("\n", 1)
- options.properties = None
-
-
- # Get the list of products to threat
- products_infos = get_products_list(options, runner.cfg, logger)
-
- # Construct the list of directories to suppress
- l_dir_to_suppress = []
- if options.all:
- l_dir_to_suppress += (get_source_directories(products_infos,
- options.sources_without_dev) +
- get_build_directories(products_infos) +
- get_install_directories(products_infos))
- else:
- if options.install:
- l_dir_to_suppress += get_install_directories(products_infos)
-
- if options.build:
- l_dir_to_suppress += get_build_directories(products_infos)
-
- if options.sources or options.sources_without_dev:
- l_dir_to_suppress += get_source_directories(products_infos,
- options.sources_without_dev)
-
- if len(l_dir_to_suppress) == 0:
- logger.write(src.printcolors.printcWarning(_("Nothing to suppress\n")))
- sat_command = (runner.cfg.VARS.salometoolsway +
- runner.cfg.VARS.sep +
- "sat -h clean")
- logger.write(_("Please specify what you want to suppress: tap '%s'\n") % sat_command)
- return
-
- # Check with the user if he really wants to suppress the directories
- if not runner.options.batch:
- logger.write(_("Remove the following directories ?\n"), 1)
- for directory in l_dir_to_suppress:
- logger.write(" %s\n" % directory, 1)
- rep = input(_("Are you sure you want to continue? [Yes/No] "))
- if rep.upper() != _("YES"):
- return 0
-
- # Suppress the list of paths
- suppress_directories(l_dir_to_suppress, logger)
-
- return 0
+ def getParser(self):
+ # Define all possible option for the clean command : sat clean <options>
+ parser = src.options.Options()
+ parser.add_option('p', 'products', 'list2', 'products',
+ _('Optional: Products to clean. This option can be'
+ ' passed several time to clean several products.'))
+ parser.add_option('', 'properties', 'string', 'properties',
+ _('Optional: Filter the products by their properties.\n'
+ '\tSyntax: --properties <property>:<value>'))
+ parser.add_option('s', 'sources', 'boolean', 'sources',
+ _("Optional: Clean the product source directories."))
+ parser.add_option('b', 'build', 'boolean', 'build',
+ _("Optional: Clean the product build directories."))
+ parser.add_option('i', 'install', 'boolean', 'install',
+ _("Optional: Clean the product install directories."))
+ parser.add_option('a', 'all', 'boolean', 'all',
+ _("Optional: Clean the product source, build and install directories."))
+ parser.add_option('', 'sources_without_dev', 'boolean', 'sources_without_dev',
+ _("Optional: do not clean the products in development mode."))
+ return parser
+
+ def description(self):
+ '''method that is called when salomeTools is called with --help option.
+
+ :return: The text to display for the clean command description.
+ :rtype: str
+ '''
+ return _("""\
+ The clean command suppress the source, build, or install directories
+ of the application products.
+ Use the options to define what directories you want to suppress and
+ to reduce the list of products
+
+ example:
+ >> sat clean SALOME-master --build --install --properties is_salome_module:yes""")
+
+ def run(self, args):
+ '''method that is called when salomeTools is called with clean parameter.
+ '''
+ runner = self.getRunner()
+ config = self.getConfig()
+ logger = self.getLogger()
+
+ # Parse the options
+ (options, argsc) = self.parse_args(args)
+
+ # check that the command has been called with an application
+ src.check_config_has_application( config )
+
+ # Verify the --properties option
+ if options.properties:
+ oExpr = re.compile(PROPERTY_EXPRESSION)
+ if not oExpr.search(options.properties):
+ msg = _('WARNING: the "--properties" options must have the '
+ 'following syntax:\n--properties <property>:<value>')
+ logger.write(src.printcolors.printcWarning(msg), 1)
+ logger.write("\n", 1)
+ options.properties = None
+
+
+ # Get the list of products to threat
+ products_infos = self.get_products_list(options, config, logger)
+
+ # Construct the list of directories to suppress
+ l_dir_to_suppress = []
+ if options.all:
+ l_dir_to_suppress += (get_source_directories(products_infos,
+ options.sources_without_dev) +
+ get_build_directories(products_infos) +
+ get_install_directories(products_infos))
+ else:
+ if options.install:
+ l_dir_to_suppress += get_install_directories(products_infos)
+
+ if options.build:
+ l_dir_to_suppress += get_build_directories(products_infos)
+
+ if options.sources or options.sources_without_dev:
+ l_dir_to_suppress += get_source_directories(products_infos,
+ options.sources_without_dev)
+
+ if len(l_dir_to_suppress) == 0:
+ logger.write(src.printcolors.printcWarning(_("Nothing to suppress\n")))
+ sat_command = (config.VARS.salometoolsway +
+ config.VARS.sep +
+ "sat -h clean")
+ logger.write(_("Please specify what you want to suppress: tap '%s'\n") % sat_command)
+ return RCO.ReturnCode("KO", "specify what you want to suppress")
+
+ # Check with the user if he really wants to suppress the directories
+ if not runner.options.batch:
+ logger.write(_("Remove the following directories ?\n"), 1)
+ for directory in l_dir_to_suppress:
+ logger.write(" %s\n" % directory, 1)
+ rep = input(_("Are you sure you want to continue? [Yes/No] "))
+ if rep.upper() != _("YES"):
+ return RCO.ReturnCode("OK", "user do not want to continue")
+
+ # Suppress the list of paths
+ suppress_directories(l_dir_to_suppress, logger)
+
+ return RCO.ReturnCode("OK", "clean done")
import src
import src.debug as DBG
+import src.returnCode as RCO
from src.salomeTools import _BaseCommand
'''get the config from all the configuration files.
:param application str: The application for which salomeTools is called.
- :param options class Options: The general salomeToos
- options (--overwrite or -l5, for example)
+ :param options class Options: The general salomeTools
+ options (--overwrite or -v5, for example)
:param command str: The command that is called.
:param datadir str: The repository that contain
external data for salomeTools.
logger.write("%s\n" % val)
def print_debug(config, aPath, show_label, logger, level=0, show_full_path=False):
+ """
+ logger output for debugging a config/pyconf
+ lines contains:
+ path : expression --> 'evaluation'
+ example:
+ .PROJECTS.projects.salome.project_path : $PWD --> '/volatile/wambeke/SAT5/SAT5_S840_MATIX24/SAT_SALOME'
+ """
path = str(aPath)
if path == "." :
val = config
res = outStream.value
logger.write(res)
return
-
def get_config_children(config, args):
'''Gets the names of the children of the given parameter.
'''method that is called when salomeTools is called with config parameter.
'''
runner = self.getRunner()
- logger = self.getLogger()
- parser = self.getParser()
config = self.getConfig()
- # Parse the options
- (options, args) = parser.parse_args(args)
+ logger = self.getLogger()
+ # Parse the options
+ (options, argsc) = self.parse_args(args)
+
# Only useful for completion mechanism : print the keys of the config
if options.schema:
get_config_children(config, args)
- return
+ return RCO.ReturnCode("OK", "completion mechanism")
# case : print a value of the config
if options.value:
else:
print_value(config, options.value, not options.no_label, logger,
level=0, show_full_path=False)
-
+
if options.debug:
print_debug(config, str(options.debug), not options.no_label, logger,
level=0, show_full_path=False)
src.check_config_has_application(config)
if options.info in config.APPLICATION.products:
show_product_info(config, options.info, logger)
- return
+ return RCO.ReturnCode("OK", "options.info")
raise src.SatException(
_("%(product_name)s is not a product of %(application_name)s.") % \
{'product_name' : options.info, 'application_name' : config.VARS.application} )
logger.write("%s\n" % appliname)
logger.write("\n")
+
# case : give a synthetic view of all patches used in the application
elif options.show_patchs:
src.check_config_has_application(config)
for product_name in config.APPLICATION.products.keys():
logger.write("%s\n" % product_name)
-
+ return RCO.ReturnCode("OK")
logger.write("\n", 2, False)
# Get the products list with products informations regarding the options
- products_infos = prepare.get_products_list(options, runner.cfg, logger)
+ products_infos = commands.prepare.get_products_list(options, runner.cfg, logger)
# Get the maximum name length in order to format the terminal display
max_product_name_len = 1
import os
import src
+import src.debug as DBG
+import src.returnCode as RCO
+from src.salomeTools import _BaseCommand
-# Define all possible option for prepare command : sat prepare <options>
-parser = src.options.Options()
-parser.add_option(
- 'p', 'products', 'list2', 'products',
- _('Optional: products to prepare. This option can be'
- ' passed several time to prepare several products.'))
-parser.add_option(
- 'f', 'force', 'boolean', 'force',
- _("Optional: force to prepare the products in development mode."))
-parser.add_option(
- '', 'force_patch', 'boolean', 'force_patch',
- _("Optional: force to apply patch to the products in development mode."))
-
-def get_products_list(options, cfg, logger):
- '''method that gives the product list with their informations from
- configuration regarding the passed options.
-
- :param options Options: The Options instance that stores the commands
- arguments
- :param config Config: The global configuration
- :param logger Logger: The logger instance to use for the display and logging
- :return: The list of (product name, product_informations).
- :rtype: List
- '''
- # Get the products to be prepared, regarding the options
- if options.products is None:
- # No options, get all products sources
- products = cfg.APPLICATION.products
- else:
- # if option --products, check that all products of the command line
- # are present in the application.
- products = options.products
- for p in products:
- if p not in cfg.APPLICATION.products:
- raise src.SatException(
- _("Product %(product)s not defined in application %(application)s") %
- { 'product': p, 'application': cfg.VARS.application} )
-
- # Construct the list of tuple containing
- # the products name and their definition
- products_infos = src.product.get_products_infos(products, cfg)
-
- return products_infos
def remove_products(arguments, l_products_info, logger):
'''function that removes the products in l_products_info from arguments list.
l_res.append(p_name_p_cfg)
return l_res
-def description():
+########################################################################
+# Command class for command 'sat config etc.'
+########################################################################
+class Command(_BaseCommand):
+
+ def getParser(self):
+ # Define all possible option for prepare command : sat prepare <options>
+ parser = src.options.Options()
+ parser.add_option(
+ 'p', 'products', 'list2', 'products',
+ _('Optional: products to prepare. This option can be'
+ ' passed several time to prepare several products.'))
+ parser.add_option(
+ 'f', 'force', 'boolean', 'force',
+ _("Optional: force to prepare the products in development mode."))
+ parser.add_option(
+ '', 'force_patch', 'boolean', 'force_patch',
+ _("Optional: force to apply patch to the products in development mode."))
+ return parser
+
+ def description(self):
'''method that is called when salomeTools is called with --help option.
- :return: The text to display for the prepare command description.
+ :return: The text to display for the config command description.
:rtype: str
'''
return _("""\
example:
>> sat prepare SALOME-master --products KERNEL,GUI""")
+
+
+ def run(self, args):
+ '''method that is called when salomeTools is called with prepare parameter.
+ '''
+
+ # Parse the options
+ parser = self.getParser()
+ runner = self.getRunner()
+ config = self.getConfig()
+ logger = self.getLogger()
+
+ (options, args) = parser.parse_args(args)
+ DBG.tofix("options %s" % self.name, options, True)
+
+ # check that the command has been called with an application
+ src.check_config_has_application( config )
+
+ products_infos = self.get_products_list(options, config, logger)
+
+ # Construct the arguments to pass to the clean, source and patch commands
+ args_appli = config.VARS.application + ' '
+ args_product_opt = '--products '
+ if options.products:
+ for p_name in options.products:
+ args_product_opt += ',' + p_name
+ else:
+ for p_name, __ in products_infos:
+ args_product_opt += ',' + p_name
+
+ ldev_products = [p for p in products_infos if src.product.product_is_dev(p[1])]
+ args_product_opt_clean = args_product_opt
+ if not options.force and len(ldev_products) > 0:
+ l_products_not_getted = find_products_already_getted(ldev_products)
+ if len(l_products_not_getted) > 0:
+ msg = _("Do not get the source of the following products in development mode\n"
+ " Use the --force option to overwrite it.\n")
+ logger.write(src.printcolors.printcWarning(msg), 1)
+ args_product_opt_clean = remove_products(args_product_opt_clean,
+ l_products_not_getted,
+ logger)
+ logger.write("\n", 1)
+
+
+ args_product_opt_patch = args_product_opt
+ if not options.force_patch and len(ldev_products) > 0:
+ l_products_with_patchs = find_products_with_patchs(ldev_products)
+ if len(l_products_with_patchs) > 0:
+ msg = _("do not patch the following products in development mode\n"
+ " Use the --force_patch option to overwrite it.\n")
+ logger.write(src.printcolors.printcWarning(msg), 1)
+ args_product_opt_patch = remove_products(args_product_opt_patch,
+ l_products_with_patchs,
+ logger)
+ logger.write("\n", 1)
+
+ # Construct the final commands arguments
+ args_clean = args_appli + args_product_opt_clean + " --sources"
+ args_source = args_appli + args_product_opt
+ args_patch = args_appli + args_product_opt_patch
+
+ # If there is no more any product in the command arguments,
+ # do not call the concerned command
+ oExpr = re.compile("^--products *$")
+ do_clean = not(oExpr.search(args_product_opt_clean))
+ do_source = not(oExpr.search(args_product_opt))
+ do_patch = not(oExpr.search(args_product_opt_patch))
+
+
+ # Initialize the results to Ok but nothing done status
+ res_clean = RCO.ReturnCode("OK", "nothing done")
+ res_source = RCO.ReturnCode("OK", "nothing done")
+ res_patch = RCO.ReturnCode("OK", "nothing done")
+
+ # return res_clean + res_source + res_patch
-def run(args, runner, logger):
- '''method that is called when salomeTools is called with prepare parameter.
- '''
-
- # Parse the options
- (options, args) = parser.parse_args(args)
-
- # check that the command has been called with an application
- src.check_config_has_application( runner.cfg )
-
- products_infos = get_products_list(options, runner.cfg, logger)
-
- # Construct the arguments to pass to the clean, source and patch commands
- args_appli = runner.cfg.VARS.application + ' '
- args_product_opt = '--products '
- if options.products:
- for p_name in options.products:
- args_product_opt += ',' + p_name
- else:
- for p_name, __ in products_infos:
- args_product_opt += ',' + p_name
-
- ldev_products = [p for p in products_infos if src.product.product_is_dev(p[1])]
- args_product_opt_clean = args_product_opt
- if not options.force and len(ldev_products) > 0:
- l_products_not_getted = find_products_already_getted(ldev_products)
- if len(l_products_not_getted) > 0:
- msg = _("Do not get the source of the following products in development mode\n"
- " Use the --force option to overwrite it.\n")
- logger.write(src.printcolors.printcWarning(msg), 1)
- args_product_opt_clean = remove_products(args_product_opt_clean,
- l_products_not_getted,
- logger)
- logger.write("\n", 1)
-
-
- args_product_opt_patch = args_product_opt
- if not options.force_patch and len(ldev_products) > 0:
- l_products_with_patchs = find_products_with_patchs(ldev_products)
- if len(l_products_with_patchs) > 0:
- msg = _("do not patch the following products in development mode\n"
- " Use the --force_patch option to overwrite it.\n")
- logger.write(src.printcolors.printcWarning(msg), 1)
- args_product_opt_patch = remove_products(args_product_opt_patch,
- l_products_with_patchs,
- logger)
- logger.write("\n", 1)
-
- # Construct the final commands arguments
- args_clean = args_appli + args_product_opt_clean + " --sources"
- args_source = args_appli + args_product_opt
- args_patch = args_appli + args_product_opt_patch
-
- # If there is no more any product in the command arguments,
- # do not call the concerned command
- oExpr = re.compile("^--products *$")
- do_clean = not(oExpr.search(args_product_opt_clean))
- do_source = not(oExpr.search(args_product_opt))
- do_patch = not(oExpr.search(args_product_opt_patch))
-
-
- # Initialize the results to a failing status
- res_clean = 1
- res_source = 1
- res_patch = 1
-
- # Call the commands using the API
- if do_clean:
- msg = _("Clean the source directories ...")
- logger.write(msg, 3)
- logger.flush()
- res_clean = runner.clean(args_clean, batch=True, verbose = 0,
- logger_add_link = logger)
- if res_clean == 0:
- logger.write('%s\n' % src.printcolors.printc(src.OK_STATUS), 3)
- else:
- logger.write('%s\n' % src.printcolors.printc(src.KO_STATUS), 3)
- if do_source:
- msg = _("Get the sources of the products ...")
- logger.write(msg, 5)
- res_source = runner.source(args_source,
- logger_add_link = logger)
- if res_source == 0:
- logger.write('%s\n' % src.printcolors.printc(src.OK_STATUS), 5)
- else:
- logger.write('%s\n' % src.printcolors.printc(src.KO_STATUS), 5)
- if do_patch:
- msg = _("Patch the product sources (if any) ...")
- logger.write(msg, 5)
- res_patch = runner.patch(args_patch,
- logger_add_link = logger)
- if res_patch == 0:
- logger.write('%s\n' % src.printcolors.printc(src.OK_STATUS), 5)
- else:
- logger.write('%s\n' % src.printcolors.printc(src.KO_STATUS), 5)
-
- return res_clean + res_source + res_patch
+ # Call the commands using the API
+ if do_clean:
+ msg = _("Clean the source directories ...")
+ logger.write(msg, 3)
+ logger.flush()
+ DBG.tofix("args_clean and TODO remove returns", args_clean, True)
+ res_clean = runner.getCommand("clean").run(args_clean)
+ return res_clean + res_source + res_patch
+ if do_source:
+ msg = _("Get the sources of the products ...")
+ logger.write(msg, 5)
+ res_source = runner.getCommand("source").run(args_source)
+ if do_patch:
+ msg = _("Patch the product sources (if any) ...")
+ logger.write(msg, 5)
+ res_patch = runner.getCommand("patch").run(args_patch)
+
+ return res_clean + res_source + res_patch
import shutil
import src
-import commands.prepare
-
-# Define all possible option for patch command : sat patch <options>
-parser = src.options.Options()
-parser.add_option('p', 'products', 'list2', 'products',
- _('Optional: products from which to get the sources. This option can be'
- ' passed several time to get the sources of several products.'))
+import src.debug as DBG
+import src.returnCode as RCO
+from src.salomeTools import _BaseCommand
def get_source_for_dev(config, product_info, source_dir, logger, pad):
'''The method called if the product is in development mode
if product_info.get_source == "native":
# skip
- logger.write('%s ' % src.printcolors.printc(src.OK_STATUS),
+ logger.write('%s ' % src.printcolors.printc(RCO.OK_STATUS),
3,
False)
msg = _("INFORMATION : do nothing because the product is of type 'native'.\n")
if product_info.get_source == "fixed":
# skip
- logger.write('%s ' % src.printcolors.printc(src.OK_STATUS),
+ logger.write('%s ' % src.printcolors.printc(RCO.OK_STATUS),
3,
False)
msg = _("INFORMATION : do nothing because the product is of type 'fixed'.\n")
# the product is not in development mode
is_dev = src.product.product_is_dev(product_info)
if source_dir.exists():
- logger.write('%s ' % src.printcolors.printc(src.OK_STATUS),
+ logger.write('%s ' % src.printcolors.printc(RCO.OK_STATUS),
3,
False)
msg = _("INFORMATION : Not doing anything because the source"
results[product_name] = retcode
if retcode:
# The case where it succeed
- res = src.OK_STATUS
+ res = RCO.OK_STATUS
good_result = good_result + 1
else:
# The case where it failed
- res = src.KO_STATUS
+ res = RCO.KO_STATUS
# print the result
if not(src.product.product_is_fixed(product_info) or
logger.write(src.printcolors.printcSuccess(" OK\n"), 5)
return True, ""
-def description():
- '''method that is called when salomeTools is called with --help option.
-
- :return: The text to display for the source command description.
- :rtype: str
- '''
- return _("The source command gets the sources of the application products "
- "from cvs, git or an archive.\n\nexample:"
- "\nsat source SALOME-master --products KERNEL,GUI")
+########################################################################
+# Command class for command 'sat config etc.'
+########################################################################
+class Command(_BaseCommand):
-def run(args, runner, logger):
- '''method that is called when salomeTools is called with source parameter.
- '''
- # Parse the options
- (options, args) = parser.parse_args(args)
+ def getParser(self):
+ # Define all possible option for patch command : sat patch <options>
+ parser = src.options.Options()
+ parser.add_option('p', 'products', 'list2', 'products',
+ _('Optional: products from which to get the sources. This option can be'
+ ' passed several time to get the sources of several products.'))
+ return parser
+
+ def description(self):
+ '''method that is called when salomeTools is called with --help option.
+
+ :return: The text to display for the source command description.
+ :rtype: str
+ '''
+ return _("The source command gets the sources of the application products "
+ "from cvs, git or an archive.\n\nexample:"
+ "\nsat source SALOME-master --products KERNEL,GUI")
- # check that the command has been called with an application
- src.check_config_has_application( runner.cfg )
-
- # Print some informations
- logger.write(_('Getting sources of the application %s\n') % \
- src.printcolors.printcLabel(runner.cfg.VARS.application), 1)
- src.printcolors.print_value(logger, 'workdir',
- runner.cfg.APPLICATION.workdir, 2)
- logger.write("\n", 2, False)
-
- # Get the products list with products informations regarding the options
- products_infos = commands.prepare.get_products_list(options, runner.cfg, logger)
-
- # Call to the function that gets all the sources
- good_result, results = get_all_product_sources(runner.cfg,
- products_infos,
- logger)
-
- # Display the results (how much passed, how much failed, etc...)
- status = src.OK_STATUS
- details = []
-
- logger.write("\n", 2, False)
- if good_result == len(products_infos):
- res_count = "%d / %d" % (good_result, good_result)
- else:
- status = src.KO_STATUS
- res_count = "%d / %d" % (good_result, len(products_infos))
-
- for product in results:
- if results[product] == 0 or results[product] is None:
- details.append(product)
-
- result = len(products_infos) - good_result
-
- # write results
- logger.write(_("Getting sources of the application:"), 1)
- logger.write(" " + src.printcolors.printc(status), 1, False)
- logger.write(" (%s)\n" % res_count, 1, False)
-
- if len(details) > 0:
- logger.write(_("Following sources haven't been get:\n"), 2)
- logger.write(" ".join(details), 2)
- logger.write("\n", 2, False)
-
- return result
+ def run(self, args):
+ '''method that is called when salomeTools is called with source parameter.
+ '''
+ runner = self.getRunner()
+ config = self.getConfig()
+ logger = self.getLogger()
+
+ # Parse the options
+ (options, argsc) = self.parse_args(args)
+
+ # check that the command has been called with an application
+ src.check_config_has_application( config )
+
+ # Print some informations
+ logger.write(_('Getting sources of the application %s\n') % \
+ src.printcolors.printcLabel(config.VARS.application), 1)
+ src.printcolors.print_value(logger, 'workdir',
+ config.APPLICATION.workdir, 2)
+ logger.write("\n", 2, False)
+
+ # Get the products list with products informations regarding the options
+ products_infos = self.get_products_list(options, config, logger)
+
+ # Call to the function that gets all the sources
+ good_result, results = get_all_product_sources(config,
+ products_infos,
+ logger)
+
+ # Display the results (how much passed, how much failed, etc...)
+ details = []
+
+ logger.write("\n", 2, False)
+ if good_result == len(products_infos):
+ res_count = "%d / %d" % (good_result, good_result)
+ returnCode = RCO.ReturnCode("OK", "source "+res_count)
+ else:
+ res_count = "%d / %d" % (good_result, len(products_infos))
+ returnCode = RCO.ReturnCode("KO", "source "+res_count)
+ for product in results:
+ if results[product] == 0 or results[product] is None:
+ details.append(product)
+
+ result = len(products_infos) - good_result
+
+ # write results
+ logger.write(_("Getting sources of the application:"), 1)
+ logger.write(" " + src.printcolors.printc(status), 1, False)
+ logger.write(" (%s)\n" % res_count, 1, False)
+
+ if len(details) > 0:
+ logger.write(_("Following sources haven't been get:\n"), 2)
+ logger.write(" ".join(details), 2)
+ logger.write("\n", 2, False)
+
+ return returnCode
# instantiate the salomeTools class with correct options
sat = Sat(sys.argv[1:])
# or sat = Sat("config -l") for example
- exitCode = sat.execute_command()
- DBG.write("sat exit code", src.okToStr(exitCode))
+ returnCode = sat.execute_command()
+ DBG.write("sat exit code", returnCode)
- sys.exit(exitCode)
+ sys.exit(returnCode.toSys())
import colorama
colorama.init()
-OK_STATUS = "OK"
-KO_STATUS = "KO"
-NA_STATUS = "NA"
-KNOWNFAILURE_STATUS = "KF"
-TIMEOUT_STATUS = "TIMEOUT"
CONFIG_FILENAME = "sat-config.pyconf"
-OKSYS = 0 # OKSYS and KOSYS seems equal on linux or windows
-KOSYS = 1
-OKMESS = {0: "OK", 1: "KO"} # etc... if useful
-
-def okToStr(ok):
- try:
- return OKMESS[ok]
- except:
- return "UnknownExitCode"
class SatException(Exception):
'''rename Exception Class
"""
This file assume DEBUG functionalities use
-- get debug representation from instances of SAT classes
- print debug messages in sys.stderr for salomeTools
+- show pretty print debug representation from instances of SAT classes
+ (pretty print src.pyconf.Config)
-WARNING: supposed only use in SAT development phase
+WARNING: supposedly show messages in SAT development phase, not production
+
+usage:
+>> import debug as DBG
+>> DBG.write("aTitle", aVariable) # not shown in production
+>> DBG.write("aTitle", aVariable, True) # unconditionaly shown
"""
import os
_debug = [False] #support push/pop for temporary activate debug outputs
def indent(text, amount=2, ch=' '):
+ """indent multi lines message"""
padding = amount * ch
return ''.join(padding + line for line in text.splitlines(True))
-def write(title, var="", force=None):
+def write(title, var="", force=None, fmt="\n#### DEBUG: %s:\n%s\n"):
"""write sys.stderr a message if _debug[-1]==True or optionaly force=True"""
- fmt = "\n#### DEBUG: %s:\n%s\n"
if _debug[-1] or force:
if 'src.pyconf.Config' in str(type(var)):
sys.stderr.write(fmt % (title, indent(getStrConfigDbg(var))))
sys.stderr.write(fmt % (title, indent(var)))
return
+def tofix(title, var="", force=None):
+ """
+ write sys.stderr a message if _debug[-1]==True or optionaly force=True
+ use this only if no logger accessible for classic logger.warning(message)
+ """
+ fmt = "\n#### TOFIX: %s:\n%s\n"
+ write(title, var, force, fmt)
+
def push_debug(aBool):
"""set debug outputs activated, or not"""
_debug.append(aBool)
return outStream.value
def saveConfigDbg(config, aStream, indent=0, path=""):
- """returns multilines (path expression evaluation) for debug"""
+ """pyconf returns multilines (path expression evaluation) for debug"""
_saveConfigRecursiveDbg(config, aStream, indent, path)
aStream.close() # as config.__save__()
def _saveConfigRecursiveDbg(config, aStream, indent, path):
- """inspired from Mapping.__save__"""
+ """pyconf inspired from Mapping.__save__"""
debug = False
if indent <= 0:
indentp = 0
except IOError:
pass
+_DefaultLogger = [] # o,nly one default logger as common logger on one config
+
+def getDefaultLogger(config):
+ if len(_DefaultLogger) == 1:
+ if config != _DefaultLogger[0].config:
+ raise Exception("config is not unique, unexpected, have to fix that")
+ return _DefaultLogger[0]
+ if config == None:
+ raise Exception("config have to be set for default logger, not None")
+ _DefaultLogger.append(Logger(config))
+ return _DefaultLogger[0]
+
def date_to_datetime(date):
'''Little method that gets year, mon, day, hour ,
minutes and seconds from a str in format YYYYMMDD_HHMMSS
if name in self.__dict__:
return self.__dict__[name]
else:
- raise AttributeError(name + _(u" is not a valid option"))
+ raise AttributeError("--" + name + _(u" is not a valid option"))
def __setattr__(self, name, value):
'''Overwrite of the __setattr__ function
is the full raw list of passed options
:rtype: (class 'common.options.OptResult',list)
'''
+ # see https://pymotw.com/2/getopt/
if argList is None:
argList = sys.argv[1:]
--- /dev/null
+#!/usr/bin/env python
+#-*- coding:utf-8 -*-
+
+# Copyright (C) 2018-20xx CEA/DEN
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2.1 of the License.
+#
+# This library 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
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+
+"""
+This file contains ReturnCode class
+usage:
+>> import returnCode as RCO
+"""
+
+import os
+import sys
+
+# OKSYS and KOSYS seems equal on linux or windows
+OKSYS = 0 # OK
+KOSYS = 1 # KO
+OK_STATUS = "OK"
+KO_STATUS = "KO"
+
+#####################################################
+class ReturnCode(object):
+
+ """
+ assume simple return code for methods, with explanation as 'why'
+ obviously why it is not OK, but also why it is OK (if you want)
+ usage:
+ >> import returnCode as RCO
+ >> return RCO.ReturnCode("KO", "there is no problem here")
+ >> return RCO.ReturnCode("KO", "there is a problem here because etc")
+ >> return RCO.ReturnCode("TIMEOUT_STATUS", "too long here because etc")
+ >> return RCO.ReturnCode("NA", "not applicable here because etc")
+ """
+
+ OK_STATUS = "OK"
+ KO_STATUS = "KO"
+ NA_STATUS = "NA" # not applicable
+ UNKNOWN_STATUS = "ND" # not defined
+ KNOWNFAILURE_STATUS = "KF"
+ TIMEOUT_STATUS = "TIMEOUT"
+
+ # integer for sys.exit(anInt)
+ # OKSYS and KOSYS seems equal on linux or windows
+ OKSYS = 0 # OK
+ KOSYS = 1 # KO
+ NASYS = 2 # KO not applicable return code
+ NDSYS = 3 # KO not defined return code
+ KFSYS = 4 # KO known failure return code
+ TOSYS = 5 # KO time out
+
+ _TOSYS = {
+ OK_STATUS: OKSYS,
+ KO_STATUS: KOSYS,
+ NA_STATUS: NASYS,
+ UNKNOWN_STATUS: NDSYS,
+ KNOWNFAILURE_STATUS: KFSYS,
+ TIMEOUT_STATUS: TOSYS,
+ }
+ _DEFAULT_WHY = "No given explanation"
+
+ def __init__(self, status=None, why=None):
+ if status is None:
+ aStatus = self.UNKNOWN_STATUS
+ self._why = self._DEFAULT_WHY
+ else:
+ self.setStatus(status, why)
+
+ def __repr__(self):
+ res = "%s: '%s'" % (self._status, self.indent(self._why))
+ return res
+
+ def indent(self, text, amount=5, ch=' '):
+ """indent multi lines message"""
+ padding = amount * ch
+ res = ''.join(padding + line for line in text.splitlines(True))
+ return res[amount:]
+
+ def __add__(self, value):
+ """allows expression 'returnCode1 + returnCode2 + ...' """
+ isOk = self.isOk() and value.isOk()
+ if isOk:
+ return ReturnCode("OK", "%s\n%s" % (self.getWhy(), value.getWhy()) )
+ else:
+ return ReturnCode("KO", "%s\n%s" % (self.getWhy(), value.getWhy()) )
+
+ def toSys(self):
+ try:
+ return self._TOSYS[self._status]
+ except:
+ return self._TOSYS[self.NA_STATUS]
+
+ def getWhy(self):
+ return self._why
+
+ def getWhy(self):
+ return self._why
+
+ def setWhy(self, why):
+ self._why = why
+
+ def setStatus(self, status, why=None):
+ if why is None:
+ aWhy = self._DEFAULT_WHY
+ else:
+ aWhy = why
+ if status in self._TOSYS.keys():
+ self._status = status
+ self._why = aWhy
+ else:
+ self._status = self.NA_STATUS
+ self._why = "Error status '%s' for '%s'" % (status, aWhy)
+
+ def isOk(self):
+ return (self._status == self.OK_STATUS)
+
+
+
import src.debug as DBG # Easy print stderr (for DEBUG only)
+import src.returnCode as RCO # Easy (ok/ko, why) return methods code
import src
# get path to src
def __init__(self, name):
self.name = name
self.runner = None # runner (as caller) usually as Sat instance
+ # self.config = None # config pyconf usually loaded with _getConfig method
self.logger = None # logger (from caller) usually as Sat instance logger
- self.config = None # config usually loaded with _getConfig method
def getClassName(self):
"""
tmp = PP.pformat(self.__dict__)
res = "%s(\n %s)\n" % (self.getClassName(), tmp[1:-1])
return res
-
+
+ def run(self, args):
+ return RCO.ReturnCode("KO", "_BaseCommand.run() have to be inherited")
+
def setRunner(self, runner):
"""set who owns me, and use me whith method run()"""
self.runner = runner
def setLogger(self, logger):
"""set logger for run command"""
- self.logger = logger
+ self.logger = logger
def getLogger(self):
- if self.logger is None: # could use owner Sat instance logger
+ if self.logger is None: # could use runner Sat instance logger
return self.runner.getLogger()
else: # could use local logger
return self.logger
def getParser(self):
raise Exception("_BaseCmd class have not to be instancied, only for inheritage")
+
+ def parse_args(self, args):
+ """smart parse command arguments skipping first argument name appli to load if present"""
+ parser = self.getParser()
+ if type(args) is list:
+ argList = args
+ else:
+ argList = args.split(' ')
+ DBG.write("%s args" % self.name, args, True)
+ # or if args[0][0] == "-": #as argument name appli without "--"
+ if self.runner.nameAppliLoaded is None:
+ (options, argsc) = parser.parse_args(args)
+ else:
+ (options, argsc) = parser.parse_args(args[1:]) # skip name appli
+ DBG.write("%s options" % self.name, options)
+ DBG.write("%s remainders args" % self.name, argsc)
+ if argsc != []:
+ self.getLogger().error("\n\ncommand '%s' remainders args %s\n\n" % (self.name, argsc))
+ return (options, argsc)
def description(self):
'''method that is called when salomeTools is called with --help option.
'''
raise Exception("_BaseCmd class have not to be instancied, only for inheritage")
-
def getConfig(self):
- if self.config is None:
- self.config = self._getConfig()
- return self.config
-
+ if self.runner.config is None:
+ self.runner.config = self._getConfig()
+ #DBG.write("_baseCommand runner", self.runner)
+ DBG.write("_baseCommand runner.config", self.runner.config)
+ return self.runner.config
def _getConfig(self):
'''The function that will load the configuration (all pyconf)
- and return the config from files .pyconf
+ and returns the config from files .pyconf
'''
- if self.config is not None:
- raise Exception("config existing yet in 's' instance" % self.getClassName())
+ if self.runner.config is not None:
+ raise Exception("config existing yet in 's' instance" % self.runner.getClassName())
# Get the arguments in a list and remove the empty elements
- print "command.runner.arguments", self.runner.arguments
+ # DBG.write("%s.runner.arguments" % self.name, self.runner.arguments)
self.parser = self.getParser()
try:
options, args = self.parser.parse_args(self.runner.arguments[1:])
- DBG.write("%s args", args)
- DBG.write("%s options", options)
+ DBG.write("%s args" % self.name, args)
+ DBG.write("%s options" % self.name, options)
except Exception as exc:
write_exception(exc)
- sys.exit(src.KOSYS)
+ sys.exit(RCO.KOSYS)
self.arguments = args # args are postfixes options: args[0] is the 'commands' command
self.options = options # the options passed to salomeTools
-
- print "command.arguments", self.arguments
- print "command.options", self.options
-
+
if type(args) == type(''):
# split by spaces without considering spaces in quotes
argv_0 = re.findall(r'(?:"[^"]*"|[^\s"])+', args)
self.options = options
# read the configuration from all the pyconf files
- cfgManager = commands.config.ConfigManager()
- config = cfgManager.get_config(datadir=self.datadir,
- application=appliToLoad,
- options=self.options,
- command=__nameCmd__)
+ cfgManager = getConfigManager() # commands.config.ConfigManager()
+ DBG.write("appli to load", appliToLoad, True)
+ config = cfgManager.get_config(datadir=self.runner.datadir,
+ application=appliToLoad,
+ options=self.runner.options,
+ command=self.name) # command=__nameCmd__)
+ self.runner.nameAppliLoaded = appliToLoad
+ # DBG.write("appli loaded", config, True)
# Set the verbose mode if called
+ DBG.tofix("verbose/batch/logger_add_link -1/False/None", True)
+ verbose = -1
+ batch = False
+ logger_add_link = None
if verbose > -1:
verbose_save = self.options.output_verbose_level
self.options.__setattr__("output_verbose_level", verbose)
self.options.__setattr__("batch", True)
# set output level
- if self.options.output_verbose_level is not None:
- config.USER.output_verbose_level = self.options.output_verbose_level
+ if self.runner.options.output_verbose_level is not None:
+ config.USER.output_verbose_level = self.runner.options.output_verbose_level
if config.USER.output_verbose_level < 1:
config.USER.output_verbose_level = 0
silent = (config.USER.output_verbose_level == 0)
micro_command = True
logger_command = src.logger.Logger(config,
silent_sysstd=silent,
- all_in_terminal=self.options.all_in_terminal,
+ all_in_terminal=self.runner.options.all_in_terminal,
micro_command=micro_command)
# Check that the path given by the logs_paths_in_file option
# is a file path that can be written
- if self.options.logs_paths_in_file and not micro_command:
+ if self.runner.options.logs_paths_in_file and not micro_command:
try:
self.options.logs_paths_in_file = os.path.abspath(
self.options.logs_paths_in_file)
return config
+ def get_products_list(self, options, cfg, logger):
+ '''method that gives the product list with their informations from
+ configuration regarding the passed options.
+
+ :param options Options: The Options instance that stores the commands
+ arguments
+ :param config Config: The global configuration
+ :param logger Logger: The logger instance to use for the display and logging
+ :return: The list of (product name, product_informations).
+ :rtype: List
+ '''
+ # Get the products to be prepared, regarding the options
+ if options.products is None:
+ # No options, get all products sources
+ products = cfg.APPLICATION.products
+ else:
+ # if option --products, check that all products of the command line
+ # are present in the application.
+ products = options.products
+ for p in products:
+ if p not in cfg.APPLICATION.products:
+ raise src.SatException(_("Product %(product)s "
+ "not defined in application %(application)s") %
+ { 'product': p, 'application': cfg.VARS.application} )
+
+ # Construct the list of tuple containing
+ # the products name and their definition
+ products_infos = src.product.get_products_infos(products, cfg)
+
+ return products_infos
+
+
########################################################################
# Sat class
########################################################################
# Read the salomeTools prefixes options before the 'commands' tag
# sat <options> <args>
# (the list of possible options is at the beginning of this file)
- DBG.push_debug(True)
+
+ # DBG.push_debug(True)
+
self.parser = self._getParser()
try:
if type(opt) is not list: # as string 'sat --help' for example'
else:
opts = opt
options, args = self.parser.parse_args(opts)
- DBG.write("Sat args", args)
- DBG.write("Sat options", options)
+ DBG.write("Sat options", options)
+ DBG.write("Sat remainders args", args)
+
except Exception as exc:
write_exception(exc)
- sys.exit(src.KOSYS)
+ sys.exit(RCO.KOSYS)
- self.logger = None # the logger that will be use
self.config = None # the config that will be read using pyconf module
+ self.logger = None # the logger that will be use
self.arguments = args # args are postfixes options: args[0] is the 'commands' command
self.options = options # the options passed to salomeTools
self.datadir = datadir # default value will be <salomeTools root>/data
# contains commands classes needed (think micro commands)
# if useful 'a la demande'
self.commands = {}
-
+ self.nameAppliLoaded = None
def __repr__(self):
aDict = {
def getLogger(self):
- return self.logger
+ if self.logger is None: # could use owner Sat instance logger
+ import src.logger as LOG
+ self.logger=LOG.getDefaultLogger(self.config)
+ return self.logger
+ else: # could use local logger
+ return self.logger
def _getParser(self):
_("put the command result and paths to log files."))
return parser
-
+
def _getCommand(self, name):
"""
create and add Command 'name' as instance of class in dict self.commands
raise AttributeError(_("command existing yet: '%s', use getCommand") % name)
file_, pathname, description = imp.find_module(name, [cmdsdir])
module = imp.load_module(name, file_, pathname, description)
- cmdInstance = module.Command(name)
+ try:
+ cmdInstance = module.Command(name)
+ except:
+ DBG.tofix("no Command() class in %s" % pathname, dir(module), True)
+ raise Exception("no Command() class in %s" % pathname)
+
cmdInstance.setRunner(self) # self is runner, owns cmdInstance
- DBG.write("new command", cmdInstance)
+ DBG.write("Sat load new command", cmdInstance)
return cmdInstance
def getCommand(self, name):
if not existing as self.commands[name], create it.
example:
- returns Commamd() from commamd.config
+ returns Command() from command.config
"""
if name not in self.commands.keys():
self.commands[name] = self._getCommand(name)
# print general help and returns
if len(args) == 0:
print_help()
- return src.OKSYS
+ return RCO.ReturnCode("OK", "No arguments as --help")
# if the help option has been called, print command help and returns
if self.options.help:
self.print_help(self.arguments)
- return src.OKSYS
+ return RCO.ReturnCode("OK", "Option --help")
# the command called
cmdName = args[0]
# create/get dynamically the command instance to call its 'run' method
cmdInstance = self.getCommand(cmdName)
# Run the command using the arguments
- exitCode = cmdInstance.run(args[1:])
- return exitCode
+ returnCode = cmdInstance.run(args[1:])
+ return returnCode
def print_help(self, opt):
'''Prints help for a command. Function called when "sat -h <command>"
return
# get command name
- command = opt[0]
+ cmdName = opt[0]
# read the configuration from all the pyconf files
- cfgManager = commands.config.ConfigManager()
+ cfgManager = getConfigManager()
self.cfg = cfgManager.get_config(datadir=self.datadir)
- # Check if this command exists
- if not hasattr(self, command):
- raise src.SatException(_("Command '%s' does not exist") % command)
-
- msg = self.get_command_help(module)
+ cmdInstance = self.getCommand(cmdName)
+
+ msg = self.get_command_help(cmdInstance)
if isStdoutPipe():
# clean color if the terminal is redirected by user
msg = get_version() + "\n\n"
# print the description of the command that is done in the command file
- if hasattr( module, "description" ):
+ try:
msg += src.printcolors.printcHeader( _("Description:") ) + "\n"
msg += module.description() + "\n\n"
+ except:
+ DBG.tofix("no description() for", module.name, True)
# print the description of the command options
- if hasattr( module, "parser" ) :
- msg += module.parser.get_help() + "\n"
+ try:
+ msg += module.getParser().get_help() + "\n"
+ except:
+ DBG.tofix("no getParser() for", module.name, True)
return msg
###################################################################
+def getConfigManager():
+ import commands.config
+ return commands.config.ConfigManager()
+
def get_text_from_options(options):
text_options = ""
for attr in dir(options):
def get_version():
"""get version colored string
"""
- cfgManager = commands.config.ConfigManager()
+ cfgManager = getConfigManager()
cfg = cfgManager.get_config()
# print the key corresponding to salomeTools version
msg = src.printcolors.printcHeader( _("Version: ") ) + \
# read the config
msg = get_version() + "\n\n"
msg += src.printcolors.printcHeader(_("Usage: ")) + \
- "sat [sat_options] <command> [product] [command_options]\n\n"
- msg += parser.get_help() + "\n"
+ "sat [generic_options] <command> [product] [command_options]\n\n"
+ msg += Sat()._getParser().get_help() + "\n"
msg += src.printcolors.printcHeader(_("Available commands are:")) + "\n\n"
- for command in lCommand:
+ for command in _COMMANDS_NAMES:
msg += " - %s\n" % (command)
msg += "\n"
# Explain how to get the help for a specific command
def test_010(self):
cmd = "sat --help"
stdout, stderr = SAT.launchSat(cmd)
+ print stdout, stderr
self.assertEqual(stderr, "")
self.assertTrue(" - config" in stdout)
- def test_011(self):
+ def xtest_011(self):
cmd = "--help"
s = SAT.Sat(cmd)
exitCode = s.execute_command()
self.assertEqual(src.okToStr(exitCode), "OK")
- def test_030(self):
+ def xtest_030(self):
cmd = "sat --help config"
stdout, stderr = SAT.launchSat(cmd)
self.assertEqual(stderr, "")
self.assertTrue("--value" in stdout)
- def test_031(self):
+ def xtest_031(self):
cmd = "--help config"
s = SAT.Sat(cmd)
exitCode = s.execute_command()
self.assertEqual(src.okToStr(exitCode), "OK")
- def test_012(self):
+ def xtest_032(self):
cmd = "config -l"
s = SAT.Sat(cmd)
exitCode = s.execute_command()
self.assertEqual(src.okToStr(exitCode), "OK")
- def test_040(self):
+ def xtest_040(self):
cmds = SAT.getCommandsList()
for c in cmds:
cmd = "sat --help %s" % c