Salome HOME
imp #12887 create sat-config.pyconf and sat-product.pyconf sprint_181015
authorChristian Van Wambeke <christian.van-wambeke@cea.fr>
Tue, 6 Nov 2018 10:05:32 +0000 (11:05 +0100)
committerChristian Van Wambeke <christian.van-wambeke@cea.fr>
Tue, 6 Nov 2018 10:05:32 +0000 (11:05 +0100)
commands/compile.py
src/__init__.py
src/product.py
src/pyconf.py

index 67209bb53a27173698db382bfbc76885ebfc4fc8..4cb7586218756eedde4fa3f3cc84faa56f28fc66 100644 (file)
@@ -282,7 +282,9 @@ def compile_all_products(sat, config, options, products_infos, logger):
                       batch=True,
                       verbose=0,
                       logger_add_link = logger)
-        
+
+        # DBG.write("Only for test of check_config_exists", src.product.check_config_exists(config, "/volatile/wambeke/SAT5/MATIX_V24_S840/INSTALL/PACKAGESPY", p_info, verbose=True), True)
+
         # Clean the the install directory 
         # if the corresponding option was called
         if options.clean_install and not options.clean_all:
@@ -463,7 +465,7 @@ def compile_product(sat, p_name_info, config, options, logger, header, len_end):
     # product that have been successfully compiled
     if res==0:       
         logger.write(_("Add the config file in installation directory\n"), 5)
-        add_compile_config_file(p_info, config)
+        src.product.add_compile_config_file(p_info, config)
         
         if options.check:
             # Do the unit tests (call the check command)
@@ -591,27 +593,6 @@ def compile_product_script(sat,
               
     return res, len_end_line, error_step 
 
-def add_compile_config_file(p_info, config):
-    '''Execute the proper configuration command(s) 
-       in the product build directory.
-    
-    :param p_info Config: The specific config of the product
-    :param config Config: The global configuration
-    '''
-    # Create the compile config
-    compile_cfg = src.pyconf.Config()
-    for prod_name in p_info.depend:
-        if prod_name not in compile_cfg:
-            compile_cfg.addMapping(prod_name,
-                                   src.pyconf.Mapping(compile_cfg),
-                                   "")
-        prod_dep_info = src.product.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, src.CONFIG_FILENAME)
-    f = open(compile_cfg_path, 'w')
-    compile_cfg.__save__(f)
-    f.close()
     
 def description():
     '''method that is called when salomeTools is called with --help option.
index f2ad0ecdcf9ac5a023ac259c96e94149aae42baa..789e23030a3ec1979d049cdbac79588c15a5e781 100644 (file)
@@ -52,8 +52,6 @@ NA_STATUS = "NA"
 KNOWNFAILURE_STATUS = "KF"
 TIMEOUT_STATUS = "TIMEOUT"
 
-CONFIG_FILENAME = "sat-config.pyconf"
-
 class SatException(Exception):
     """rename Exception Class"""
     pass
index f139b7c264b7ac8d57784a26b182f1ca97f4af69..f1fa34be852d349016ef7dd4e63a907164fe7433 100644 (file)
@@ -30,8 +30,10 @@ import src.debug as DBG
 import src.versionMinorMajorPatch as VMMP
 
 AVAILABLE_VCS = ['git', 'svn', 'cvs']
+
+CONFIG_FILENAME = "sat-config.pyconf" # trace product depends version(s)
+PRODUCT_FILENAME = "sat-product.pyconf" # trace product compile config
 config_expression = "^config-\d+$"
-VERSION_DELIMITER = "_to_"
 
 def get_product_config(config, product_name, with_install_dir=True):
     """Get the specific configuration of a product from the global configuration
@@ -44,7 +46,7 @@ def get_product_config(config, product_name, with_install_dir=True):
     :return: the specific configuration of the product
     :rtype: Config
     """
-    
+
     # Get the version of the product from the application definition
     version = config.APPLICATION.products[product_name]
     # if no version, then take the default one defined in the application
@@ -92,7 +94,7 @@ def get_product_config(config, product_name, with_install_dir=True):
     # in config.PRODUCTS. This is done because the pyconf tool does not handle
     # the . and - characters 
     for c in ".-": vv = vv.replace(c, "_")
-    
+
     prod_info = None
     if product_name in config.PRODUCTS:
         # Search for the product description in the configuration
@@ -173,7 +175,7 @@ Please add a section in it.""") % {"1" : vv, "2" : prod_pyconf_path}
     prod_info.verbose = verbose
     prod_info.dev = dev
     prod_info.version = version
-    
+
     # Set the archive_info if the product is get in archive mode
     if prod_info.get_source == "archive":
         if not "archive_info" in prod_info:
@@ -453,11 +455,43 @@ def get_base_install_dir(config, prod_info, version):
             
     return install_dir
 
-def check_config_exists(config, prod_dir, prod_info):
+def add_compile_config_file(p_info, config):
+    '''Execute the proper configuration command(s)
+       in the product build directory.
+
+    :param p_info Config: The specific config of the product
+    :param config Config: The global configuration
+    '''
+    # Create the compile config
+    # DBG.write("add_compile_config_file", p_info, True)
+    res = src.pyconf.Config()
+    res.addMapping(p_info.name, src.pyconf.Mapping(res), "")
+    res[p_info.name]= p_info.version
+
+    for prod_name in p_info.depend:
+      if prod_name not in res:
+        res.addMapping(prod_name, src.pyconf.Mapping(res), "")
+      prod_dep_info = src.product.get_product_config(config, prod_name, False)
+      res[prod_name] = prod_dep_info.version
+    # Write it in the install directory of the product
+    # This file is for automatic reading/checking
+    # see check_config_exists method
+    aFile = os.path.join(p_info.install_dir, CONFIG_FILENAME)
+    with open(aFile, 'w') as f:
+      res.__save__(f)
+
+    # this file is for human eye reading
+    aFile = os.path.join(p_info.install_dir, PRODUCT_FILENAME)
+    with open(aFile, 'w') as f:
+      # f.write(DBG.getStrConfigDbg(p_info)) # debug mode
+      p_info.__save__(f, evaluated=True) # evaluated expressions mode
+
+
+def check_config_exists(config, prod_dir, prod_info, verbose=False):
     """\
-    Verify that the installation directory of a product in a base exists
-    Check all the config-<i> directory and verify the sat-config.pyconf file
-    that is in it 
+    Verify that the installation directory of a product in a base exists.
+    Check all the config-<i>/sat-config.py files found for correspondence
+    with current config and prod_info depend-version-tags
     
     :param config Config: The global configuration
     :param prod_dir str: The product installation directory path 
@@ -467,18 +501,27 @@ def check_config_exists(config, prod_dir, prod_info):
     :return: True or false is the installation is found or not 
              and if it is found, the path of the found installation
     :rtype: (boolean, str)
-    """   
-    # check if the directories or files of the directory corresponds to the 
+    """
+    # check if the directories or files of the directory corresponds to the
     # directory installation of the product
-    l_dir_and_files = os.listdir(prod_dir)
+    if os.path.isdir(prod_dir):
+      l_dir_and_files = os.listdir(prod_dir)
+    else:
+      raise Exception("Inexisting directory '%s'" % prod_dir)
+
+    DBG.write("check_config_exists 000",  (prod_dir, l_dir_and_files), verbose)
+    DBG.write("check_config_exists 111",  prod_info, verbose)
+
     for dir_or_file in l_dir_and_files:
         oExpr = re.compile(config_expression)
         if not(oExpr.search(dir_or_file)):
-            # not config-<i>, not interesting
+            # in mode BASE, not config-<i>, not interesting
+            # DBG.write("not interesting", dir_or_file, True)
             continue
         # check if there is the file sat-config.pyconf file in the installation
         # directory    
-        config_file = os.path.join(prod_dir, dir_or_file, src.CONFIG_FILENAME)
+        config_file = os.path.join(prod_dir, dir_or_file, CONFIG_FILENAME)
+        DBG.write("check_config_exists 222", config_file, verbose)
         if not os.path.exists(config_file):
             continue
         
@@ -488,7 +531,7 @@ def check_config_exists(config, prod_dir, prod_info):
             if len(compile_cfg) == 0:
                 return True, os.path.join(prod_dir, dir_or_file)
             continue
-        
+
         # check if there is the config described in the file corresponds the 
         # dependencies of the product
         config_corresponds = True    
@@ -506,15 +549,29 @@ def check_config_exists(config, prod_dir, prod_info):
                 if prod_dep_info.version != compile_cfg[prod_dep]:
                     config_corresponds = False
                     break
-        
-        for prod_name in compile_cfg:
-            if prod_name not in prod_info.depend:
+
+        if config_corresponds:
+          for prod_name in compile_cfg:
+            # assume new compatibility with prod_name in sat-config.pyconf files
+            if prod_name == prod_info.name:
+              if prod_info.version == compile_cfg[prod_name]:
+                DBG.write("check_config_exists OK 333", compile_cfg, verbose)
+                pass
+              else: # no correspondence with newer with prod_name sat-config.pyconf files
+                config_corresponds = False
+                break
+            else:
+              # as old compatibility without prod_name sat-config.pyconf files
+              if prod_name not in prod_info.depend:
+                # here there is an unexpected depend in an old compilation
                 config_corresponds = False
                 break
         
-        if config_corresponds:
+        if config_corresponds: # returns (and stops) at first correspondence found
+            DBG.write("check_config_exists OK 444", dir_or_file, verbose)
             return True, os.path.join(prod_dir, dir_or_file)
-    
+
+    # no correspondence found
     return False, None
             
             
index 68b917448421d22298572978fd2b4fc7c44b2255..7f2838f2b8aefe9c6b9a2d2162d0bc7c2cbab96a 100644 (file)
@@ -416,7 +416,7 @@ class Container(object):
             item = item.evaluate(self)
         return item
 
-    def writeToStream(self, stream, indent, container):
+    def writeToStream(self, stream, indent, container, evaluated=False):
         """
         Write this instance to a stream at the specified indentation level.
 
@@ -432,13 +432,16 @@ class Container(object):
         """
         raise NotImplementedError
 
-    def writeValue(self, value, stream, indent):
+    def writeValue(self, value, stream, indent, evaluated=False):
         if isinstance(self, Mapping):
             indstr = ' '
         else:
             indstr = indent * '  '
         if isinstance(value, Reference) or isinstance(value, Expression):
-            stream.write('%s%r%s' % (indstr, value, NEWLINE))
+            if not evaluated:
+                stream.write('%s%r%s' % (indstr, value, NEWLINE))
+            else:
+                stream.write('%s%r%s' % (indstr, self.evaluate(value), NEWLINE))
         else:
             if isinstance(value, str): # and not isWord(value):
                 value = repr(value)
@@ -573,7 +576,7 @@ class Mapping(Container):
         order = object.__getattribute__(self, 'order')
         return order.__iter__()
 
-    def writeToStream(self, stream, indent, container):
+    def writeToStream(self, stream, indent, container, evaluated=False):
         """
         Write this instance to a stream at the specified indentation level.
 
@@ -593,10 +596,10 @@ class Mapping(Container):
             if isinstance(container, Mapping):
                 stream.write(NEWLINE)
             stream.write('%s{%s' % (indstr, NEWLINE))
-            self.__save__(stream, indent + 1)
+            self.__save__(stream, indent + 1, evaluated=evaluated)
             stream.write('%s}%s' % (indstr, NEWLINE))
 
-    def __save__(self, stream, indent=0):
+    def __save__(self, stream, indent=0, evaluated=False):
         """
         Save this configuration to the specified stream.
         @param stream: A stream to which the configuration is written.
@@ -621,9 +624,9 @@ class Mapping(Container):
             stream.write('%s%-*s :' % (indstr, maxlen, skey))
             value = data[key]
             if isinstance(value, Container):
-                value.writeToStream(stream, indent, self)
+                value.writeToStream(stream, indent, self, evaluated=evaluated)
             else:
-                self.writeValue(value, stream, indent)
+                self.writeValue(value, stream, indent, evaluated=evaluated)
 
 class Config(Mapping):
     """
@@ -724,7 +727,7 @@ class Config(Mapping):
         else:
             delattr(namespaces[0], name)
 
-    def __save__(self, stream, indent=0, no_close=False):
+    def __save__(self, stream, indent=0, no_close=False, evaluated=False):
         """
         Save this configuration to the specified stream. The stream is
         closed if this is the top-level configuration in the hierarchy.
@@ -734,7 +737,7 @@ class Config(Mapping):
         @param indent: The indentation level for the output.
         @type indent: int
         """
-        Mapping.__save__(self, stream, indent)
+        Mapping.__save__(self, stream, indent, evaluated=evaluated)
         if indent == 0 and not no_close:
             stream.close()
 
@@ -837,7 +840,7 @@ class Sequence(Container):
     def __len__(self):
         return len(object.__getattribute__(self, 'data'))
 
-    def writeToStream(self, stream, indent, container):
+    def writeToStream(self, stream, indent, container, evaluated=False):
         """
         Write this instance to a stream at the specified indentation level.
 
@@ -857,10 +860,10 @@ class Sequence(Container):
             if isinstance(container, Mapping):
                 stream.write(NEWLINE)
             stream.write('%s[%s' % (indstr, NEWLINE))
-            self.__save__(stream, indent + 1)
+            self.__save__(stream, indent + 1, evaluated=evaluated)
             stream.write('%s]%s' % (indstr, NEWLINE))
 
-    def __save__(self, stream, indent):
+    def __save__(self, stream, indent, evaluated=False):
         """
         Save this instance to the specified stream.
         @param stream: A stream to which the configuration is written.
@@ -879,9 +882,9 @@ class Sequence(Container):
             if comment:
                 stream.write('%s#%s' % (indstr, comment))
             if isinstance(value, Container):
-                value.writeToStream(stream, indent, self)
+                value.writeToStream(stream, indent, self, evaluated=evaluated)
             else:
-                self.writeValue(value, stream, indent)
+                self.writeValue(value, stream, indent, evaluated=evaluated)
 
 class Reference(object):
     """