Salome HOME
ensure that fix_permissions.sh is not called on Windows
[tools/sat.git] / src / __init__.py
index dd6d6464f989c8de181a382bf2b5b53d7eaca958..9f3e8d1e7a2fc26019dbee57d82f3ecee2954470 100644 (file)
@@ -55,20 +55,25 @@ KNOWNFAILURE_STATUS = "KF"
 TIMEOUT_STATUS = "TIMEOUT"
 
 class SatException(Exception):
-    """rename Exception Class"""
-    pass
+    """sat exception class"""
+    def message(self, arg):
+        if sys.version_info[0] >= 3:
+            # message method is not available for python 3.8+
+            return super().msg(arg)
+        else:
+            return super(SatException,self).message(arg)
 
 def ensure_path_exists(p):
     """Create a path if not existing
-    
+
     :param p str: The path.
     """
     if not os.path.exists(p):
         os.makedirs(p)
-        
+
 def check_config_has_application( config, details = None ):
     """check that the config has the key APPLICATION. Else raise an exception.
-    
+
     :param config class 'common.pyconf.Config': The config.
     """
     if 'APPLICATION' not in config:
@@ -77,11 +82,22 @@ def check_config_has_application( config, details = None ):
             details.append(message)
         raise SatException( message )
 
+def check_platform_is_supported( config, logger ):
+    """check that the platform is supported, write warning if not.
+
+    :param config class 'common.pyconf.Config': The config.
+    """
+    if 'platform' in config.APPLICATION and config.VARS.dist not in config.APPLICATION.platform:
+        msg = "WARNING: Your application configuration is not supported on this platform (%s)\n"\
+              "         Please consider using the native application!" % config.VARS.dist
+        logger.write("\n%s\n\n" % printcolors.printcWarning(msg), 1)
+    return
+
 def check_config_has_profile( config, details = None ):
     """\
     check that the config has the key APPLICATION.profile.
     else, raise an exception.
-    
+
     :param config class 'common.pyconf.Config': The config.
     """
     check_config_has_application(config)
@@ -91,16 +107,37 @@ def check_config_has_profile( config, details = None ):
             details.append(message)
         raise SatException( message )
 
+def appli_test_property(config,property_name, property_value):
+    """Generic function to test if an application has a property set to a value
+    :param config class 'common.pyconf.Config': The config.
+    :param property_name : The name of the property to check
+    :param property_value : The value of the property to test
+    :return: True if the application has the property set to property_value
+    :rtype: boolean
+    """
+    # first check if application has property_value
+    if not ("APPLICATION"  in config and
+            "properties"   in config.APPLICATION and
+            property_name  in config.APPLICATION.properties):
+        return False
+
+    # then check to the property is set to property_value
+    eval_expression = 'config.APPLICATION.properties.%s == "%s"' %\
+                      (property_name,property_value)
+    result = eval(eval_expression)
+    return result
+
+
 def config_has_application( config ):
     return 'APPLICATION' in config
 
 def get_cfg_param(config, param_name, default):
     """\
     eearch for param_name value in config.
-    if param_name is not in config 
+    if param_name is not in config
     then return default,
     else return the found value
-       
+
     :param config class 'common.pyconf.Config': The config.
     :param param_name str: the name of the parameter to get the value
     :param default str: The value to return if param_name is not in config
@@ -147,7 +184,7 @@ def getProductNames(cfg, wildcards, logger):
         if len(filtered) > 0:
           res.append(prod)
           ok = True
-          break
+          continue
       if not ok:
         notFound[wild] = None
     if len(res) == 0:
@@ -162,7 +199,7 @@ def getProductNames(cfg, wildcards, logger):
 def print_info(logger, info):
     """\
     Prints the tuples that are in info variable in a formatted way.
-    
+
     :param logger Logger: The logging instance to use for the prints.
     :param info list: The list of tuples to display
     """
@@ -177,7 +214,7 @@ def print_info(logger, info):
 def get_base_path(config):
     """\
     Returns the path of the products base.
-    
+
     :param config Config: The global Config instance.
     :return: The path of the products base.
     :rtype: str
@@ -188,15 +225,15 @@ def get_base_path(config):
                                       "local.pyconf")
         msg = _("Please define a base path in the file %s" % local_file_path)
         raise SatException(msg)
-        
+
     base_path = os.path.abspath(config.LOCAL.base)
-    
+
     return base_path
 
 def get_launcher_name(config):
     """\
     Returns the name of salome launcher.
-    
+
     :param config Config: The global Config instance.
     :return: The name of salome launcher.
     :rtype: str
@@ -209,10 +246,27 @@ def get_launcher_name(config):
 
     return launcher_name
 
+def get_launcher_exe(config):
+    """\
+    Returns the name of exe defined in profile section.
+
+    :param config Config: The global Config instance.
+    :return: The name of the exe to use in launcher.
+    :rtype: str
+    """
+    check_config_has_application(config)
+    if 'profile' in config.APPLICATION and 'exe' in config.APPLICATION.profile:
+        exe_name = config.APPLICATION.profile.exe
+    else:
+        exe_name = None
+
+    return exe_name
+
+
 def get_log_path(config):
     """\
     Returns the path of the logs.
-    
+
     :param config Config: The global Config instance.
     :return: The path of the logs.
     :rtype: str
@@ -223,11 +277,20 @@ def get_log_path(config):
                                       "local.pyconf")
         msg = _("Please define a log_dir in the file %s" % local_file_path)
         raise SatException(msg)
-      
+
     log_dir_path = os.path.abspath(config.LOCAL.log_dir)
-    
+
     return log_dir_path
 
+def get_salometool_version(config):
+   """Return the salomeTool version.
+
+   :param config Config: The global Config instance.
+   :return: the description of this version of sat in terms of tag and commit
+   """
+   return config.LOCAL.tag
+
+
 def get_salome_version(config):
     import versionMinorMajorPatch as VMMP
 
@@ -246,9 +309,8 @@ def get_salome_version(config):
           line = f.readline()  # example: '[SALOME KERNEL] : 8.4.0'
         version = VMMP.MinorMajorPatch(line.split(":")[1])
 
-    res = version.strCompact()
-    # print("get_salome_version %s -> %s" % (version, res))
-    return int(res) # TODO may be future avoid test(s) on integer, use MajorMinorPatch
+    # from nov. 2023 and SALOME 9.10.0 forbid test(s) on integer, use MajorMinorPatch class tests
+    return version
 
 def read_config_from_a_file(filePath):
         try:
@@ -304,14 +366,14 @@ class Path:
         return Path(os.path.basename(self.path))
 
     def make(self, mode=None):
-        os.makedirs(self.path)        
+        os.makedirs(self.path)
         if mode:
             os.chmod(self.path, mode)
-        
+
     def chmod(self, mode):
         os.chmod(self.path, mode)
 
-    def rm(self):    
+    def rm(self):
         if self.islink():
             os.remove(self.path)
         else:
@@ -380,14 +442,14 @@ class Path:
 def find_file_in_lpath(file_name, lpath, additional_dir = ""):
     """\
     Find in all the directories in lpath list the file that has the same name
-    as file_name. 
-    If it is found 
+    as file_name.
+    If it is found
     then return the full path of the file
     else return False.
-    The additional_dir (optional) is the name of the directory to add to all 
+
+    The additional_dir (optional) is the name of the directory to add to all
     paths in lpath.
-    
+
     :param file_name str: The file name to search
     :param lpath List: The list of directories where to search
     :param additional_dir str: The name of the additional directory
@@ -404,13 +466,13 @@ def find_file_in_lpath(file_name, lpath, additional_dir = ""):
                 return os.path.join(dir_complete, file_name)
     return False
 
-def find_file_in_ftppath(file_name, ftppath, installation_dir, logger):
+def find_file_in_ftppath(file_name, ftppath, installation_dir, logger, additional_dir = ""):
     """\
     Find in all ftp servers in ftppath the file called file_name
     If it is found then return the destination path of the file
     (the place where the file was downloaded"
     else return False.
-    
+
     :param file_name str: The file name to search
     :param ftppath, List: The list of ftp servers where to search
     :param installation_dir str: The name of the installation directory
@@ -431,7 +493,7 @@ def find_file_in_ftppath(file_name, ftppath, installation_dir, logger):
     for ipath in ftppath:
         splpath=ipath.split(":")
         bigftppath+=splpath
-        
+
     for ftp_archive in bigftppath:
        try:
            # ftp_archive has the form ftp.xxx.yyy/dir1/dir2/...
@@ -443,8 +505,20 @@ def find_file_in_ftppath(file_name, ftppath, installation_dir, logger):
            for directory in ftp_archive_split[1:]:
                logger.write("   Change directory to %s\n" % directory, 3)
                ftp.cwd(directory)
+           if additional_dir:
+               ftp.cwd(additional_dir)
        except:
            logger.error("while connecting to ftp server %s\n" % ftp_server)
+           continue
+
+       try:  # get md5 file if it exists
+           file_name_md5=file_name + ".md5"
+           destination_md5=destination + ".md5"
+           if ftp.size(file_name_md5) > 0:
+               with open(destination_md5,'wb') as dest_file_md5:
+                   ftp.retrbinary("RETR "+file_name_md5, dest_file_md5.write)
+       except:
+           pass
 
        try:
            if ftp.size(file_name) > 0:
@@ -455,7 +529,6 @@ def find_file_in_ftppath(file_name, ftppath, installation_dir, logger):
                return destination
        except:
            logger.error("File not found in ftp_archive %s\n" % ftp_server)
-           pass
 
     return False
 
@@ -470,7 +543,7 @@ def handleRemoveReadonly(func, path, exc):
 def deepcopy_list(input_list):
     """\
     Do a deep copy of a list
-    
+
     :param input_list List: The list to copy
     :return: The copy of the list
     :rtype: List
@@ -483,7 +556,7 @@ def deepcopy_list(input_list):
 def remove_item_from_list(input_list, item):
     """\
     Remove all occurences of item from input_list
-    
+
     :param input_list List: The list to modify
     :return: The without any item
     :rtype: List
@@ -498,7 +571,7 @@ def remove_item_from_list(input_list, item):
 def parse_date(date):
     """\
     Transform YYYYMMDD_hhmmss into YYYY-MM-DD hh:mm:ss.
-    
+
     :param date str: The date to transform
     :return: The date in the new format
     :rtype: str
@@ -542,11 +615,10 @@ def get_property_in_product_cfg(product_cfg, pprty):
 
 def activate_mesa_property(config):
     """Add mesa property into application properties
-    
+
     :param config Config: The global configuration. It must have an application!
     """
     # Verify the existence of the file
     if not 'properties' in config.APPLICATION:
         config.APPLICATION.addMapping( 'properties', pyconf.Mapping(), None )
     config.APPLICATION.properties.use_mesa="yes"
-