From 4bff5f8a5cb5fae810ef9ace67b7f130f39084d8 Mon Sep 17 00:00:00 2001 From: Christian Van Wambeke Date: Wed, 30 May 2018 16:47:12 +0200 Subject: [PATCH] begin fix sat compile --- commands/clean.py | 7 +- commands/compile.py | 567 +++++++++++++++++++++----------------------- commands/script.py | 76 +++--- src/compilation.py | 75 +++--- src/salomeTools.py | 18 +- src/utilsSat.py | 25 +- 6 files changed, 380 insertions(+), 388 deletions(-) diff --git a/commands/clean.py b/commands/clean.py index 0e48f35..7dcd9d8 100644 --- a/commands/clean.py +++ b/commands/clean.py @@ -129,9 +129,10 @@ The '--properties' options must have the following syntax: options.sources_without_dev) if len(l_dir_to_suppress) == 0: - msg = _("Specify what you want to suppress in clean command.") - logger.error(msg + "\n(see: 'sat -h clean')") - return RCO.ReturnCode("KO", "to suppress in clean command") + msg = _("Specify what to suppress in clean command") + msg += "\noption(s) source/build/install/all (see: 'sat -h clean')" + logger.error(msg) + return RCO.ReturnCode("KO", "missing option (source/build/install/all) in clean command") # Check with the user if he really wants to suppress the directories msg = _("Remove the following directories:\n") diff --git a/commands/compile.py b/commands/compile.py index 4eec34d..1bea3d4 100644 --- a/commands/compile.py +++ b/commands/compile.py @@ -91,11 +91,6 @@ class Command(_BaseCommand): def run(self, cmd_arguments): """method called for command 'sat compile '""" argList = self.assumeAsList(cmd_arguments) - - # print general help and returns - if len(argList) == 0: - self.print_help() - return RCO.ReturnCode("OK", "No arguments, as 'sat %s --help'" % self.name) self._options, remaindersArgs = self.parseArguments(argList) @@ -150,7 +145,7 @@ class Command(_BaseCommand): # Call the function that will loop over all the products and execute # the right command(s) - res = compile_all_products(runner, config, options, products_infos, logger) + res = self.compile_all_products(products_infos) # Print the final state nb_products = len(products_infos) @@ -158,177 +153,12 @@ class Command(_BaseCommand): logger.info(_("\nCompilation: <%(0)s> (%(1)d/%(2)d)\n") % \ { '0': res.getStatus(), - '1': nb_products - nb_ok, + '1': nb_ok, '2': nb_products } ) - return res -def get_children(config, p_name_p_info): - l_res = [] - p_name, __ = p_name_p_info - # Get all products of the application - products = config.APPLICATION.products - products_infos = PROD.get_products_infos(products, config) - for p_name_potential_child, p_info_potential_child in products_infos: - if ("depend" in p_info_potential_child and \ - p_name in p_info_potential_child.depend): - l_res.append(p_name_potential_child) - return l_res - -def get_recursive_children(config, p_name_p_info, without_native_fixed=False): - """ - Get the recursive list of the product that depend on - the product defined by prod_info - - :param config: (Config) The global configuration - :param prod_info: (Config) The specific config of the product - :param without_native_fixed: (bool) - If true, do not include the fixed or native products in the result - :return: (list) The list of product_informations. - """ - p_name, __ = p_name_p_info - # Initialization of the resulting list - l_children = [] - - # Get the direct children (not recursive) - l_direct_children = get_children(config, p_name_p_info) - # Minimal case : no child - if l_direct_children == []: - return [] - # Add the children and call the function to get the children of the - # children - for child_name in l_direct_children: - l_children_name = [pn_pi[0] for pn_pi in l_children] - if child_name not in l_children_name: - if child_name not in config.APPLICATION.products: - msg = _("""\ -The product %(child_name)s that is in %(product_name)s children -is not present in application %(appli_name)s.""" % - {"child_name" : child_name, - "product_name" : p_name.name, - "appli_name" : config.VARS.application} ) - raise Exception(msg) - prod_info_child = PROD.get_product_config(config, child_name) - pname_pinfo_child = (prod_info_child.name, prod_info_child) - # Do not append the child if it is native or fixed and - # the corresponding parameter is called - if without_native_fixed: - if not(PROD.product_is_native(prod_info_child) or \ - PROD.product_is_fixed(prod_info_child)): - l_children.append(pname_pinfo_child) - else: - l_children.append(pname_pinfo_child) - # Get the children of the children - l_grand_children = get_recursive_children(config, - pname_pinfo_child, - without_native_fixed = without_native_fixed) - l_children += l_grand_children - return l_children -def get_recursive_fathers(config, p_name_p_info, without_native_fixed=False): - """ - Get the recursive list of the dependencies of the product defined - by prod_info - - :param config: (Config) The global configuration - :param prod_info: (Config) The specific config of the product - :param without_native_fixed: (bool) - If true, do not include the fixed or native products in the result - :return: (list) The list of product_informations. - """ - p_name, p_info = p_name_p_info - # Initialization of the resulting list - l_fathers = [] - # Minimal case : no dependencies - if "depend" not in p_info or p_info.depend == []: - return [] - # Add the dependencies and call the function to get the dependencies of the - # dependencies - for father_name in p_info.depend: - l_fathers_name = [pn_pi[0] for pn_pi in l_fathers] - if father_name not in l_fathers_name: - if father_name not in config.APPLICATION.products: - msg = _("The product %(father_name)s that is in %(product_nam" - "e)s dependencies is not present in application %(appli_name)s" % \ - {"father_name" : father_name, - "product_name" : p_name, - "appli_name" : config.VARS.application}) - raise Exception(msg) - prod_info_father = PROD.get_product_config(config, father_name) - pname_pinfo_father = (prod_info_father.name, prod_info_father) - # Do not append the father if it is native or fixed and - # the corresponding parameter is called - if without_native_fixed: - if not(PROD.product_is_native(prod_info_father) or \ - PROD.product_is_fixed(prod_info_father)): - l_fathers.append(pname_pinfo_father) - else: - l_fathers.append(pname_pinfo_father) - # Get the dependencies of the dependency - l_grand_fathers = get_recursive_fathers(config, - pname_pinfo_father, - without_native_fixed = without_native_fixed) - for item in l_grand_fathers: - if item not in l_fathers: - l_fathers.append(item) - return l_fathers - -def sort_products(config, p_infos): - """Sort the p_infos regarding the dependencies between the products - - :param config: (Config) The global configuration - :param p_infos: (list) - List of (str, Config) => (product_name, product_info) - """ - l_prod_sorted = UTS.deepcopy_list(p_infos) - for prod in p_infos: - l_fathers = get_recursive_fathers(config, - prod, - without_native_fixed=True) - l_fathers = [father for father in l_fathers if father in p_infos] - if l_fathers == []: - continue - for p_sorted in l_prod_sorted: - if p_sorted in l_fathers: - l_fathers.remove(p_sorted) - if l_fathers==[]: - l_prod_sorted.remove(prod) - l_prod_sorted.insert(l_prod_sorted.index(p_sorted)+1, prod) - break - - return l_prod_sorted - -def extend_with_fathers(config, p_infos): - p_infos_res = UTS.deepcopy_list(p_infos) - for p_name_p_info in p_infos: - fathers = get_recursive_fathers(config, - p_name_p_info, - without_native_fixed=True) - for p_name_p_info_father in fathers: - if p_name_p_info_father not in p_infos_res: - p_infos_res.append(p_name_p_info_father) - return p_infos_res - -def extend_with_children(config, p_infos): - p_infos_res = UTS.deepcopy_list(p_infos) - for p_name_p_info in p_infos: - children = get_recursive_children(config, - p_name_p_info, - without_native_fixed=True) - for p_name_p_info_child in children: - if p_name_p_info_child not in p_infos_res: - p_infos_res.append(p_name_p_info_child) - return p_infos_res - -def check_dependencies(config, p_name_p_info): - l_depends_not_installed = [] - fathers = get_recursive_fathers(config, p_name_p_info, without_native_fixed=True) - for p_name_father, p_info_father in fathers: - if not(PROD.check_installation(p_info_father)): - l_depends_not_installed.append(p_name_father) - return l_depends_not_installed - -def compile_all_products(sat, config, options, products_infos, logger): + def compile_all_products(self, products_infos): #sat, config, options, products_infos, logger): """ Execute the proper configuration commands in each product build directory. @@ -340,15 +170,21 @@ def compile_all_products(sat, config, options, products_infos, logger): The logger instance to use for the display and logging :return: (RCO.ReturnCode) with value as the number of failing commands. """ - res = 0 + # shortcuts + config = self.getConfig() + options = self.getOptions() + logger = self.getLogger() + nameAppli = config.VARS.application + + res = [] # list of results for each products + DBG.write("compile", [p for p, tmp in products_infos]) for p_name_info in products_infos: p_name, p_info = p_name_info # Logging len_end_line = 30 - header = _("Compilation of %s") % UTS.label(p_name) - header += " %s \n" % ("." * (len_end_line - len(p_name))) + header = _("Compilation of %s ...") % UTS.label(p_name) logger.info(header) # Do nothing if the product is not compilable @@ -356,34 +192,34 @@ def compile_all_products(sat, config, options, products_infos, logger): "compilation" in p_info.properties and \ p_info.properties.compilation == "no"): UTS.log_step(logger, header, "ignored") + res.append(RCO.ReturnCode("OK", "compile %s ignored" % p_name)) continue # Do nothing if the product is native if PROD.product_is_native(p_info): UTS.log_step(logger, header, "native") + res.append(RCO.ReturnCode("OK", "no compile %s as native" % p_name)) continue # Clean the build and the install directories # if the corresponding options was called if options.clean_all: UTS.log_step(logger, header, "CLEAN BUILD AND INSTALL") - sat.clean(config.VARS.application + - " --products " + p_name + - " --build --install", - batch=True, - verbose=0, - logger_add_link = logger) + cmd_args = "--products %s --build --install" % p_name + rc = self.executeMicroCommand("clean", nameAppli, cmd_args) + if not rc.isOk(): + res.append(rc) + continue # Clean the the install directory # if the corresponding option was called if options.clean_install and not options.clean_all: UTS.log_step(logger, header, "CLEAN INSTALL") - sat.clean(config.VARS.application + - " --products " + p_name + - " --install", - batch=True, - verbose=0, - logger_add_link = logger) + cmd_args = "--products %s --install" % p_name + rc = self.executeMicroCommand("clean", nameAppli, cmd_args) + if not rc.isOk(): + res.append(rc) + continue # Recompute the product information to get the right install_dir # (it could change if there is a clean of the install directory) @@ -392,78 +228,65 @@ def compile_all_products(sat, config, options, products_infos, logger): # Check if it was already successfully installed if PROD.check_installation(p_info): logger.info(_("Already installed")) + res.append(RCO.ReturnCode("OK", "no compile %s as already installed" % p_name)) continue # If the show option was called, do not launch the compilation if options.no_compile: - logger.info(_("Not installed")) + logger.info(_("No compile and install as show option")) + res.append(RCO.ReturnCode("OK", "no compile %s as show option" % p_name)) continue # Check if the dependencies are installed l_depends_not_installed = check_dependencies(config, p_name_info) if len(l_depends_not_installed) > 0: - UTS.log_step(logger, header, "") + UTS.log_step(logger, header, "") msg = _("the following products are mandatory:\n") - for prod_name in l_depends_not_installed: + for prod_name in sorted(l_depends_not_installed): msg += "%s\n" % prod_name logger.error(msg) + res.append(RCO.ReturnCode("KO", "no compile %s as missing mandatory product(s)" % p_name)) continue # Call the function to compile the product - res_prod, len_end_line, error_step = compile_product(sat, - p_name_info, - config, - options, - logger, - header, - len_end_line) + #res_prod, len_end_line, error_step = self.compile_product(p_name_info) + #sat, p_name_info, config, options, logger, header, len_end_line) + rc = self.compile_product(p_name_info) + error_step, nameprod, install_dir = rc.getValue() + res.append(rc) - if res_prod != 0: - res += 1 - - if error_step != "CHECK": - # Clean the install directory if there is any - logger.debug(_("Cleaning the install directory if there is any\n")) - sat.clean(config.VARS.application + - " --products " + p_name + - " --install", - batch=True, - verbose=0, - logger_add_link = logger) - else: - # Clean the build directory if the compilation and tests succeed - if options.clean_build_after: - UTS.log_step(logger, header, "CLEAN BUILD") - sat.clean(config.VARS.application + - " --products " + p_name + - " --build", - batch=True, - verbose=0, - logger_add_link = logger) + if not rc.isOk(): + # problem + if error_step != "CHECK": + # Clean the install directory if there is any + logger.debug(_("Cleaning the install directory if there is any")) + cmd_args = "--products %s --install" % p_name + rc0 = self.executeMicroCommand("clean", nameAppli, cmd_args) + else: + # Ok Clean the build directory if the compilation and tests succeed + if options.clean_build_after: + UTS.log_step(logger, header, "CLEAN BUILD") + cmd_args = "--products %s --build" % p_name + rc0 = self.executeMicroCommand("clean", nameAppli, cmd_args) # Log the result - if res_prod > 0: - logger.info("\r%s%s" % (header, " " * len_end_line)) - logger.info("\r" + header + " " + error_step) - logger.debug("\n==== in compile of %s\n" % p_name) - if error_step == "CHECK": - logger.info(_("\nINSTALL directory = %s") % p_info.install_dir) + if rc.isOk(): + logger.info(" " + rc.getWhy()) else: - logger.info("\r%s%s" % (header, " " * len_end_line)) - logger.info("\r" + header + "") - logger.info(_("\nINSTALL directory = %s") % p_info.install_dir) - logger.debug("\n==== in compile of %s\n" % p_name) + logger.info(" " + rc.getWhy()) - - if res_prod != 0 and options.stop_first_fail: - break - - if res == 0: # no failing commands - return RCO.ReturnCode("OK", "no failing compile commands", res) + if not rc.isOk() and options.stop_first_fail: + break # stop at first problem + + resAll = RCO.ReturnCodeFromList(res) + nbOk = len([r for r in res if r.isOk()]) + nbKo = len([r for r in res if not r.isOk()]) + if resAll.isOk(): # no failing commands + return RCO.ReturnCode("OK", "No failing compile commands", nbOk) else: - return RCO.ReturnCode("KO", "existing %i failing compile commands" % res, res) + return RCO.ReturnCode("KO", "Existing %s failing compile product(s)" % nbKo, nbOk) -def compile_product(sat, p_name_info, config, options, logger, header, len_end): + def compile_product(self, p_name_info): #sat, p_name_info, config, options, logger, header, len_end): """ Execute the proper configuration command(s) in the product build directory. @@ -476,7 +299,12 @@ def compile_product(sat, p_name_info, config, options, logger, header, len_end): :param len_end: (int) the length of the the end of line (used in display) :return: (RCO.ReturnCode) KO if it fails. """ + config = self.getConfig() + options = self.getOptions() + logger = self.getLogger() + header = "yyyy" # TODO + nameAppli = config.VARS.application p_name, p_info = p_name_info # Get the build procedure from the product configuration. @@ -484,58 +312,41 @@ def compile_product(sat, p_name_info, config, options, logger, header, len_end): # build_sources : autotools -> build_configure, configure, make, make install # build_sources : cmake -> cmake, make, make install # build_sources : script -> script executions - res = 0 if (PROD.product_is_autotools(p_info) or PROD.product_is_cmake(p_info)): - res, len_end_line, error_step = compile_product_cmake_autotools(sat, - p_name_info, - config, - options, - logger, - header, - len_end) + rc = self.compile_product_cmake_autotools(p_name_info) + # sat, p_name_info, config, options, logger, header, len_end) if PROD.product_has_script(p_info): - res, len_end_line, error_step = compile_product_script(sat, - p_name_info, - config, - options, - logger, - header, - len_end) + rc = self.compile_product_script(p_name_info) + # sat, p_name_info, config, options, logger, header, len_end) # Check that the install directory exists - if res==0 and not(os.path.exists(p_info.install_dir)): + if rc.isOk() and not(os.path.exists(p_info.install_dir)): error_step = "NO INSTALL DIR" msg = _("All steps ended successfully, but install directory not found") logger.error(msg) - return RCO.ReturnCode("KO", "Install directory not found", (error_step, p_name, p_info.install_dir)) + return RCO.ReturnCode("KO", "Install directory for %s not found" % p_name, (error_step, p_name, p_info.install_dir)) # Add the config file corresponding to the dependencies/versions of the # product that have been successfully compiled - if res==0: - logger.debug(_("Add the config file in installation directory\n")) + if rc.isOk(): + logger.debug(_("Add the config file in installation directory")) add_compile_config_file(p_info, config) if options.check: # Do the unit tests (call the check command) UTS.log_step(logger, header, "CHECK") - res_check = sat.check( - config.VARS.application + " --products " + p_name, - verbose = 0, - logger_add_link = logger) - if res_check != 0: + cmd_args = "--products %s" % p_name + rc0 = self.executeMicroCommand("check", nameAppli, cmd_args) + if not rc0.isOk(): error_step = "CHECK" - - res += res_check + msg = _("compile steps ended successfully, but check problem") + logger.error(msg) + return RCO.ReturnCode("KO", "check of compile for %s problem" % p_name, (error_step, p_name, p_info.install_dir)) - return res, len_end_line, error_step - -def compile_product_cmake_autotools(sat, - p_name_info, - config, - options, - logger, - header, - len_end): + rc.setValue( ("COMPILE", p_name, p_info.install_dir) ) + return rc + + def compile_product_cmake_autotools(self, p_name_info): #sat, p_name_info, config, options, logger, header, len_end): """ Execute the proper build procedure for autotools or cmake in the product build directory. @@ -549,6 +360,10 @@ def compile_product_cmake_autotools(sat, :param len_end: (int) the length of the the end of line (used in display) :return: (int) 1 if it fails, else 0. """ + config = self.getConfig() + options = self.getOptions() + logger = self.getLogger() + p_name, p_info = p_name_info # Execute "sat configure", "sat make" and "sat install" @@ -608,13 +423,7 @@ def compile_product_cmake_autotools(sat, return res, len_end_line, error_step -def compile_product_script(sat, - p_name_info, - config, - options, - logger, - header, - len_end): + def compile_product_script(self, p_name_info): # sat, p_name_info, config, options, logger, header, len_end): """Execute the script build procedure in the product build directory. :param p_name_info: (tuple) @@ -626,21 +435,194 @@ def compile_product_script(sat, :param len_end: (int) the length of the the end of line (used in display) :return: (int) 1 if it fails, else 0. """ + config = self.getConfig() + options = self.getOptions() + logger = self.getLogger() + nameAppli = config.VARS.application + + header = "xxxx" # TODO + p_name, p_info = p_name_info # Execute "sat configure", "sat make" and "sat install" error_step = "" # Logging and sat command call for the script step - scrit_path_display = UTS.label(p_info.compil_script) - UTS.log_step(logger, header, "SCRIPT " + scrit_path_display) - len_end_line = len_end + len(scrit_path_display) - res = sat.script(config.VARS.application + " --products " + p_name, - verbose = 0, - logger_add_link = logger) + script_path_display = UTS.label(p_info.compil_script) + UTS.log_step(logger, header, "SCRIPT %s ..." % script_path_display) + + # res = sat.script(config.VARS.application + " --products " + p_name, verbose = 0, logger_add_link = logger) + cmd_args = "--products %s" % p_name + res = self.executeMicroCommand("script", nameAppli, cmd_args) UTS.log_res_step(logger, res) - - return res, len_end_line, error_step + return res + + +def get_children(config, p_name_p_info): + l_res = [] + p_name, __ = p_name_p_info + # Get all products of the application + products = config.APPLICATION.products + products_infos = PROD.get_products_infos(products, config) + for p_name_potential_child, p_info_potential_child in products_infos: + if ("depend" in p_info_potential_child and \ + p_name in p_info_potential_child.depend): + l_res.append(p_name_potential_child) + return l_res + +def get_recursive_children(config, p_name_p_info, without_native_fixed=False): + """ + Get the recursive list of the product that depend on + the product defined by prod_info + + :param config: (Config) The global configuration + :param prod_info: (Config) The specific config of the product + :param without_native_fixed: (bool) + If true, do not include the fixed or native products in the result + :return: (list) The list of product_informations. + """ + p_name, __ = p_name_p_info + # Initialization of the resulting list + l_children = [] + + # Get the direct children (not recursive) + l_direct_children = get_children(config, p_name_p_info) + # Minimal case : no child + if l_direct_children == []: + return [] + # Add the children and call the function to get the children of the + # children + for child_name in l_direct_children: + l_children_name = [pn_pi[0] for pn_pi in l_children] + if child_name not in l_children_name: + if child_name not in config.APPLICATION.products: + msg = _("""\ +The product %(child_name)s that is in %(product_name)s children +is not present in application %(appli_name)s.""" % + {"child_name" : child_name, + "product_name" : p_name.name, + "appli_name" : config.VARS.application} ) + raise Exception(msg) + prod_info_child = PROD.get_product_config(config, child_name) + pname_pinfo_child = (prod_info_child.name, prod_info_child) + # Do not append the child if it is native or fixed and + # the corresponding parameter is called + if without_native_fixed: + if not(PROD.product_is_native(prod_info_child) or \ + PROD.product_is_fixed(prod_info_child)): + l_children.append(pname_pinfo_child) + else: + l_children.append(pname_pinfo_child) + # Get the children of the children + l_grand_children = get_recursive_children(config, + pname_pinfo_child, + without_native_fixed = without_native_fixed) + l_children += l_grand_children + return l_children + +def get_recursive_fathers(config, p_name_p_info, without_native_fixed=False): + """ + Get the recursive list of the dependencies of the product defined + by prod_info + + :param config: (Config) The global configuration + :param prod_info: (Config) The specific config of the product + :param without_native_fixed: (bool) + If true, do not include the fixed or native products in the result + :return: (list) The list of product_informations. + """ + p_name, p_info = p_name_p_info + # Initialization of the resulting list + l_fathers = [] + # Minimal case : no dependencies + if "depend" not in p_info or p_info.depend == []: + return [] + # Add the dependencies and call the function to get the dependencies of the + # dependencies + for father_name in p_info.depend: + l_fathers_name = [pn_pi[0] for pn_pi in l_fathers] + if father_name not in l_fathers_name: + if father_name not in config.APPLICATION.products: + msg = _("The product %(father_name)s that is in %(product_nam" + "e)s dependencies is not present in application %(appli_name)s" % \ + {"father_name" : father_name, + "product_name" : p_name, + "appli_name" : config.VARS.application}) + raise Exception(msg) + prod_info_father = PROD.get_product_config(config, father_name) + pname_pinfo_father = (prod_info_father.name, prod_info_father) + # Do not append the father if it is native or fixed and + # the corresponding parameter is called + if without_native_fixed: + if not(PROD.product_is_native(prod_info_father) or \ + PROD.product_is_fixed(prod_info_father)): + l_fathers.append(pname_pinfo_father) + else: + l_fathers.append(pname_pinfo_father) + # Get the dependencies of the dependency + l_grand_fathers = get_recursive_fathers(config, + pname_pinfo_father, + without_native_fixed = without_native_fixed) + for item in l_grand_fathers: + if item not in l_fathers: + l_fathers.append(item) + return l_fathers + +def sort_products(config, p_infos): + """Sort the p_infos regarding the dependencies between the products + + :param config: (Config) The global configuration + :param p_infos: (list) + List of (str, Config) => (product_name, product_info) + """ + l_prod_sorted = UTS.deepcopy_list(p_infos) + for prod in p_infos: + l_fathers = get_recursive_fathers(config, + prod, + without_native_fixed=True) + l_fathers = [father for father in l_fathers if father in p_infos] + if l_fathers == []: + continue + for p_sorted in l_prod_sorted: + if p_sorted in l_fathers: + l_fathers.remove(p_sorted) + if l_fathers==[]: + l_prod_sorted.remove(prod) + l_prod_sorted.insert(l_prod_sorted.index(p_sorted)+1, prod) + break + + return l_prod_sorted + +def extend_with_fathers(config, p_infos): + p_infos_res = UTS.deepcopy_list(p_infos) + for p_name_p_info in p_infos: + fathers = get_recursive_fathers(config, + p_name_p_info, + without_native_fixed=True) + for p_name_p_info_father in fathers: + if p_name_p_info_father not in p_infos_res: + p_infos_res.append(p_name_p_info_father) + return p_infos_res + +def extend_with_children(config, p_infos): + p_infos_res = UTS.deepcopy_list(p_infos) + for p_name_p_info in p_infos: + children = get_recursive_children(config, + p_name_p_info, + without_native_fixed=True) + for p_name_p_info_child in children: + if p_name_p_info_child not in p_infos_res: + p_infos_res.append(p_name_p_info_child) + return p_infos_res + +def check_dependencies(config, p_name_p_info): + l_depends_not_installed = [] + fathers = get_recursive_fathers(config, p_name_p_info, without_native_fixed=True) + for p_name_father, p_info_father in fathers: + if not(PROD.check_installation(p_info_father)): + l_depends_not_installed.append(p_name_father) + return l_depends_not_installed + def add_compile_config_file(p_info, config): """ @@ -654,14 +636,11 @@ def add_compile_config_file(p_info, config): compile_cfg = PYCONF.Config() for prod_name in p_info.depend: if prod_name not in compile_cfg: - compile_cfg.addMapping(prod_name, - PYCONF.Mapping(compile_cfg), - "") + compile_cfg.addMapping(prod_name, PYCONF.Mapping(compile_cfg), "") prod_dep_info = PROD.get_product_config(config, prod_name, False) compile_cfg[prod_name] = prod_dep_info.version # Write it in the install directory of the product compile_cfg_path = os.path.join(p_info.install_dir, UTS.get_CONFIG_FILENAME()) - f = open(compile_cfg_path, 'w') - compile_cfg.__save__(f) - f.close() + with open(compile_cfg_path, 'w') as f: + compile_cfg.__save__(f) diff --git a/commands/script.py b/commands/script.py index 4d82303..a1a40cd 100644 --- a/commands/script.py +++ b/commands/script.py @@ -17,6 +17,7 @@ # License along with this library; if not, write to the Free Software # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +import os import src.debug as DBG import src.returnCode as RCO @@ -81,7 +82,7 @@ class Command(_BaseCommand): products_infos = self.get_products_list(options, config) # Print some informations - msg = ('Executing the script in the build directories of the application %s\n') % \ + msg = ('Executing the script in the build directories of the application %s') % \ UTS.label(config.VARS.application) logger.info(msg) @@ -92,22 +93,21 @@ class Command(_BaseCommand): # the right command(s) if options.nb_proc is None: options.nb_proc = 0 - res = run_script_all_products(config, - products_infos, - options.nb_proc, - logger) + good_result, results = run_script_all_products(config, products_infos, options.nb_proc, logger) # Print the final state - nb_products = len(products_infos) - if res == 0: - final_status = "" + nbExpected = len(products_infos) + msgCount = "(%d/%d)" % (good_result, nbExpected) + if good_result == nbExpected: + status = "OK" + msg = _("Execute script") + logger.info("\n%s %s: <%s>.\n" % (msg, msgCount, status)) else: - final_status = "" - - logger.info( _("\nScript: %(s (%d/%d)\n") % \ - (final_status, nb_products - res, nb_products) ) - - return res + status = "KO" + msg = _("Problem executing script") + logger.info("\n%s %s: <%s>.\n" % (msg, msgCount, status)) + + return RCO.ReturnCode(status, "%s %s" % (msg, msgCount)) def run_script_all_products(config, products_infos, nb_proc, logger): """Execute the script in each product build directory. @@ -120,15 +120,19 @@ def run_script_all_products(config, products_infos, nb_proc, logger): The logger instance to use for the display and logging :return: (int) The number of failing commands. """ - res = 0 + # Initialize the variables that will count the fails and success + results = dict() + good_result = 0 + DBG.write("run_script_all_products", [p for p, tmp in products_infos]) for p_name_info in products_infos: - res_prod = run_script_of_product(p_name_info, - nb_proc, - config, - logger) - if res_prod != 0: - res += 1 - return res + retcode = run_script_of_product(p_name_info, nb_proc, config, logger) + # show results + p_name, p_info = p_name_info + results[p_name] = retcode + if retcode.isOk(): + good_result += 1 + + return good_result, results def run_script_of_product(p_name_info, nb_proc, config, logger): """ @@ -143,13 +147,12 @@ def run_script_of_product(p_name_info, nb_proc, config, logger): The logger instance to use for the display and logging :return: (int) 1 if it fails, else 0. """ - p_name, p_info = p_name_info + header = "zzzz" # TODO # Logging - header = _("Running script of %s") % UTS.label(p_name) - header += " %s " % ("." * (20 - len(p_name))) - logger.info("\n" + header) + msg = _("Running script of %s ...") % UTS.label(p_name) + logger.info(msg) # Do nothing if he product is not compilable or has no compilation script test1 = "properties" in p_info and \ @@ -157,35 +160,24 @@ def run_script_of_product(p_name_info, nb_proc, config, logger): p_info.properties.compilation == "no" if ( test1 or (not PROD.product_has_script(p_info)) ): UTS.log_step(logger, header, "ignored") - logger.info("\n") - return 0 + return res.append(RCO.ReturnCode("OK", "run script %s ignored" % p_name)) + # Instantiate the class that manages all the construction commands # like cmake, make, make install, make test, environment management, etc... builder = COMP.Builder(config, logger, p_info) # Prepare the environment - UTS.log_step(logger, header, "PREPARE ENV") + UTS.log_step(logger, header, "PREPARE ENV ...") res_prepare = builder.prepare() UTS.log_res_step(logger, res_prepare) # Execute the script - len_end_line = 20 script_path_display = UTS.label(p_info.compil_script) UTS.log_step(logger, header, "SCRIPT " + script_path_display) - len_end_line += len(script_path_display) res = builder.do_script_build(p_info.compil_script, number_of_proc=nb_proc) UTS.log_res_step(logger, res) - - # Log the result - if res > 0: - logger.info("\r%s%s" % (header, " " * len_end_line)) - logger.info("\r" + header + "") - logger.debug("==== in script execution of %s\n" % p_name) - else: - logger.info("\r%s%s" % (header, " " * len_end_line)) - logger.info("\r" + header + "") - logger.debug("==== in script execution of %s\n" % p_name) - logger.info("\n") + + #logger.info("") return res diff --git a/src/compilation.py b/src/compilation.py index f204920..b14f1af 100644 --- a/src/compilation.py +++ b/src/compilation.py @@ -26,7 +26,6 @@ Utilities to build and compile import os import sys import shutil -import subprocess as SP from src.options import OptResult import returnCode as RCO @@ -65,42 +64,49 @@ class Builder: Prepares the environment. Build two environment: one for building and one for testing (launch). """ + # shortcuts + logger = self.logger + config = self.config + if not self.build_dir.exists(): # create build dir self.build_dir.make() - self.log(' build_dir = %s\n' % str(self.build_dir), 4) - self.log(' install_dir = %s\n' % str(self.install_dir), 4) - self.log('\n', 4) + msg = """ +build_dir = %s +install_dir = %s +""" % (str(self.build_dir), str(self.install_dir)) + logger.trace(msg) # add products in depend and opt_depend list recursively - environ_info = PROD.get_product_dependencies(self.config, self.product_info) + environ_info = PROD.get_product_dependencies(config, self.product_info) #environ_info.append(self.product_info.name) # create build environment - self.build_environ = ENVI.SalomeEnviron(self.config, ENVI.Environ(dict(os.environ)), True) - self.build_environ.silent = UTS.isSilent(self.config.USER.output_verbose_level) - self.build_environ.set_full_environ(self.logger, environ_info) + self.build_environ = ENVI.SalomeEnviron(config, ENVI.Environ(dict(os.environ)), True) + self.build_environ.silent = UTS.isSilent(config.USER.output_verbose_level) + self.build_environ.set_full_environ(logger, environ_info) # create runtime environment - self.launch_environ = ENVI.SalomeEnviron(self.config, ENVI.Environ(dict(os.environ)), False) + self.launch_environ = ENVI.SalomeEnviron(config, ENVI.Environ(dict(os.environ)), False) self.launch_environ.silent = True # no need to show here - self.launch_environ.set_full_environ(self.logger, environ_info) + self.launch_environ.set_full_environ(logger, environ_info) + msg = "build environment:\n" for ee in C_COMPILE_ENV_LIST: - vv = self.build_environ.get(ee) - if len(vv) > 0: - self.log(" %s = %s\n" % (ee, vv), 4, False) - - return 0 + vv = self.build_environ.get(ee) + if len(vv) > 0: + msg += " %s = %s\n" % (ee, vv) + + logger.trace(msg) + return RCO.ReturnCode("OK", "prepare done") def cmake(self, options=""): """Runs cmake with the given options.""" cmake_option = options # cmake_option +=' -DCMAKE_VERBOSE_MAKEFILE=ON -DSALOME_CMAKE_DEBUG=ON' if 'cmake_options' in self.product_info: - cmake_option += " %s " % " ".join( - self.product_info.cmake_options.split()) + cmake_option += " %s " % " ".join(self.product_info.cmake_options.split()) # add debug option if self.debug_mode: @@ -110,9 +116,9 @@ class Builder: # In case CMAKE_GENERATOR is defined in environment, # use it in spite of automatically detect it - if 'cmake_generator' in self.config.APPLICATION: - cmake_option += " -DCMAKE_GENERATOR=%s" \ - % self.config.APPLICATION.cmake_generator + if 'cmake_genepreparerator' in self.config.APPLICATION: + cmake_option += " -DCMAKE_GENERATOR=%s" % \ + self.config.APPLICATION.cmake_generator cmd = """ # CMAKE @@ -213,7 +219,7 @@ make -j %s %s """ % (nb_proc, make_opt) env = self.build_environ.environ.environ - res = SP.call(cmd, cwd=str(self.build_dir), env=env) + res = UTS.Popen(cmd, cwd=str(self.build_dir), env=env, logger=self.logger) return res @@ -231,7 +237,7 @@ make -j %s %s cmd += cmd + " ALL_BUILD.vcxproj" env = self.build_environ.environ.environ - res = SP.Popen(command, cwd=str(self.build_dir), env=env) + res = UTS.Popen(command, cwd=str(self.build_dir), env=env, logger=self.logger) return res @@ -247,7 +253,7 @@ make -j %s %s cmd = 'make install' env = self.build_environ.environ.environ - res = SP.Popen(command, cwd=str(self.build_dir), env=env) + res = UTS.Popen(command, cwd=str(self.build_dir), env=env, logger=self.logger) return res def check(self, command=""): @@ -264,7 +270,7 @@ make -j %s %s cmd = command env = self.build_environ.environ.environ - res = SP.Popen(command, cwd=str(self.build_dir), env=env) + res = UTS.Popen(command, cwd=str(self.build_dir), env=env , logger=self.logger) return res @@ -299,14 +305,11 @@ make -j %s %s if use_autotools: cmd = "(autotools)" if use_ctest: cmd = "(ctest)" - self.log("\n", 4, False) - self.log("%(module)s: Run default compilation method %(cmd)s\n" % \ - { "module": self.module, "cmd": cmd }, 4) + self.info("%s: Run default compilation method %s" % (self.module, cmd)) if use_autotools: if not self.prepare(): return self.get_result() - if not self.build_configure( - build_conf_options): return self.get_result() + if not self.build_configure(build_conf_options): return self.get_result() if not self.configure(configure_options): return self.get_result() if not self.make(): return self.get_result() if not self.install(): return self.get_result() @@ -330,18 +333,19 @@ make -j %s %s def do_python_script_build(self, script, nb_proc): """Performs a build with a script.""" + logger = self.logger # script found - self.logger.info(_("Compile %s using script %s\n") % \ + logger.info(_("Compile %s using script %s\n") % \ (self.product_info.name, UTS.label(script)) ) try: import imp product = self.product_info.name pymodule = imp.load_source(product + "_compile_script", script) self.nb_proc = nb_proc - retcode = pymodule.compil(self.config, self, self.logger) + retcode = pymodule.compil(self.config, self, logger) except: __, exceptionValue, exceptionTraceback = sys.exc_info() - self.logger.error(str(exceptionValue)) + logger.error(str(exceptionValue)) import traceback traceback.print_tb(exceptionTraceback) traceback.print_exc() @@ -372,7 +376,7 @@ make -j %s %s else : make_options = "-j%s" % nb_proc - self.logger.info(_("Run build script '%s'") % script) + self.logger.trace(_("Run build script '%s'") % script) self.complete_environment(make_options) # linux or win compatible, have to be chmod +x ? @@ -380,10 +384,9 @@ make -j %s %s # Run build script %s """ % script - env = self.build_environ.environ.environ - res = SP.Popen(cmd, cwd=str(self.build_dir), env=env) + res = UTS.Popen(cmd, cwd=str(self.build_dir), env=env) return res def do_script_build(self, script, number_of_proc=0): @@ -402,5 +405,5 @@ make -j %s %s return self.do_python_script_build(script, nb_proc) msg = _("The script %s must have extension as .sh, .bat or .py.") % script - raise Exception(msg) + return RCO.ReturnCode("KO", msg) diff --git a/src/salomeTools.py b/src/salomeTools.py index 5ad7ae5..6695397 100755 --- a/src/salomeTools.py +++ b/src/salomeTools.py @@ -249,7 +249,7 @@ class _BaseCommand(object): return cmdInstance def runMicroCommand(self, cmdInstance, cmd_arguments): - """create instance of a micro command and launch on arguments""" + """launch a micro command on arguments""" logger = self.getLogger() commandArguments = self.assumeAsList(cmd_arguments) # Run the micro command using the remainders command arguments @@ -268,6 +268,20 @@ class _BaseCommand(object): return returnCode + def executeMicroCommand(self, nameCmd, nameAppli, cmd_arguments): + """create instance of a micro command and launch on arguments""" + # create/get dynamically the command instance to call its 'run' method + cmdInstance = self.getMicroCommand(nameCmd, nameAppli) + + # some initialisation stuff + # cmdInstance.initFullName() # as micro command + # cmdInstance.setConfig(config) + + # logger = self.getLogger() + # logger.setFileHandlerForCommand(self, cmdInstance) + + returnCode = self.runMicroCommand(cmdInstance, cmd_arguments) + return returnCode def run(self, cmd_arguments): """ @@ -348,6 +362,7 @@ class _BaseCommand(object): return CFGMGR.get_products_list(options, config) def assumeAsList(self, strOrList): + # DBG.write("command %s assumeAsList" % self.getFullNameStr(), strOrList) return assumeAsList(strOrList) def getParser(self): @@ -480,6 +495,7 @@ class Sat(object): return self.options def assumeAsList(self, strOrList): + # DBG.write("Sat assumeAsList", strOrList, True) return assumeAsList(strOrList) def _getParser(self): diff --git a/src/utilsSat.py b/src/utilsSat.py index aab6049..f1308fc 100644 --- a/src/utilsSat.py +++ b/src/utilsSat.py @@ -249,15 +249,15 @@ def check_has_key(inConfig, key): :param key: (str) The key to check presence in in-Config node :return: (RCO.ReturnCode) 'OK' if presence """ - debug = True + # debug = True if key not in inConfig: msg = _("check_has_key '%s' not found" % key) - DBG.write("check_has_key", msg, debug) - return RCO.ReturnCode("KO", msg) + # DBG.write("check_has_key", msg, debug) + return RCO.ReturnCode("KO", msg, None) else: msg = _("check_has_key '%s' found" % key) - DBG.write("check_has_key", msg, debug) - return RCO.ReturnCode("OK", msg) + # DBG.write("check_has_key", msg, debug) + return RCO.ReturnCode("OK", msg, inConfig[key]) def check_config_has_application(config): """ @@ -303,8 +303,9 @@ def get_config_key(inConfig, key, default): :param default: (str) The value to return if key is not in-Config :return: (if supposedly leaf (str),else (in-Config Node) """ - if check_has_key(inConfig, key).isOk(): - return inConfig[key] + rc = check_has_key(inConfig, key) + if rc.isOk(): + return rc.getValue() else: return default @@ -436,14 +437,14 @@ def logger_info_tuples(logger, tuples): logger.info(msg) def log_step(logger, header, step): - logger.info("\r%s%s" % (header, " " * 20)) - logger.info("\r%s%s" % (header, step)) + #logger.info("\r%s%s" % (header, step)) + logger.info("%s" % step) def log_res_step(logger, res): - if res == 0: - logger.info("\n") + if res.isOk(): + logger.info("") else: - logger.info("\n") + logger.info("") def isSilent(output_verbose_level): """is silent fort self.build_environ""" -- 2.39.2