]> SALOME platform Git repositories - tools/sat.git/commitdiff
Salome HOME
begin fix sat compile
authorChristian Van Wambeke <christian.van-wambeke@cea.fr>
Wed, 30 May 2018 14:47:12 +0000 (16:47 +0200)
committerChristian Van Wambeke <christian.van-wambeke@cea.fr>
Wed, 30 May 2018 14:47:12 +0000 (16:47 +0200)
commands/clean.py
commands/compile.py
commands/script.py
src/compilation.py
src/salomeTools.py
src/utilsSat.py

index 0e48f359f6de6ee275dcaa36069e3fb3aa6febe5..7dcd9d870f343bf57c5e864a47e2bd524ab08345 100644 (file)
@@ -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")
index 4eec34db56dcaee4c3d523df70f9668b7427094a..1bea3d426f2c1035b873a65df56c4749359cc8a5 100644 (file)
@@ -91,11 +91,6 @@ class Command(_BaseCommand):
   def run(self, cmd_arguments):
     """method called for command 'sat compile <options>'"""
     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, "<KO>")
             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 + "<KO> " + error_step)
-            logger.debug("\n==== <KO> 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("<KO> " + rc.getWhy())
         else:
-            logger.info("\r%s%s" % (header, " " * len_end_line))
-            logger.info("\r" + header + "<OK>")
-            logger.info(_("\nINSTALL directory = %s") % p_info.install_dir)
-            logger.debug("\n==== <OK> in compile of %s\n" % p_name)
+          logger.info("<KO> " + 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)
     
index 4d82303c630e60bf150965c06bb7dd3302f3d17e..a1a40cd886e0e22a2a55eac06a1ecdee4b371ffc 100644 (file)
@@ -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 = "<OK>"
+    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 = "<KO>"
-   
-    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 + "<KO>")
-        logger.debug("==== <KO> in script execution of %s\n" %  p_name)
-    else:
-        logger.info("\r%s%s" % (header, " " * len_end_line))
-        logger.info("\r" + header + "<OK>")
-        logger.debug("==== <OK> in script execution of %s\n" %  p_name)
-    logger.info("\n")
+    #logger.info("")
 
     return res
index f2049207e14cd54a046981e19d712c9edc847bea..b14f1af4ff8a99bcbc8026114b1ed94307265db5 100644 (file)
@@ -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)
         
index 5ad7ae5811ce0540c9d8ed8022fef21a4181ac42..6695397c2e281aded4992c877dc32c50fcc75f0f 100755 (executable)
@@ -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):
index aab6049aee4db193170b24d831c45efe27414d06..f1308fc2f6210315b00d2d3d527de39ec6e6b8cc 100644 (file)
@@ -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("<OK>\n")
+    if res.isOk():
+        logger.info("<OK>")
     else:
-        logger.info("<KO>\n")
+        logger.info("<KO>")
 
 def isSilent(output_verbose_level):
     """is silent fort self.build_environ"""