]> SALOME platform Git repositories - tools/sat.git/blob - src/__init__.py
Salome HOME
add src/versionMinorMajorPatch.py, not used
[tools/sat.git] / src / __init__.py
1 #!/usr/bin/env python
2 #-*- coding:utf-8 -*-
3 #  Copyright (C) 2010-2013  CEA/DEN
4 #
5 #  This library is free software; you can redistribute it and/or
6 #  modify it under the terms of the GNU Lesser General Public
7 #  License as published by the Free Software Foundation; either
8 #  version 2.1 of the License.
9 #
10 #  This library is distributed in the hope that it will be useful,
11 #  but WITHOUT ANY WARRANTY; without even the implied warranty of
12 #  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
13 #  Lesser General Public License for more details.
14 #
15 #  You should have received a copy of the GNU Lesser General Public
16 #  License along with this library; if not, write to the Free Software
17 #  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
18
19
20 """\
21 initial imports and utilities methods for salomeTools
22 """
23
24 import os
25 import shutil
26 import errno
27 import stat
28
29 from . import pyconf
30 from . import architecture
31 from . import printcolors
32 from . import options
33 from . import system
34 from . import ElementTree
35 from . import logger
36 from . import product
37 from . import environment
38 from . import fileEnviron
39 from . import compilation
40 from . import test_module
41 from . import template
42
43 import platform
44 if platform.system() == "Windows" :
45     import colorama
46     colorama.init()
47
48 OK_STATUS = "OK"
49 KO_STATUS = "KO"
50 NA_STATUS = "NA"
51 KNOWNFAILURE_STATUS = "KF"
52 TIMEOUT_STATUS = "TIMEOUT"
53
54 CONFIG_FILENAME = "sat-config.pyconf"
55
56 class SatException(Exception):
57     """rename Exception Class"""
58     pass
59
60 def ensure_path_exists(p):
61     """Create a path if not existing
62     
63     :param p str: The path.
64     """
65     if not os.path.exists(p):
66         os.makedirs(p)
67         
68 def check_config_has_application( config, details = None ):
69     """check that the config has the key APPLICATION. Else raise an exception.
70     
71     :param config class 'common.pyconf.Config': The config.
72     """
73     if 'APPLICATION' not in config:
74         message = _("An APPLICATION is required. Use 'config --list' to get the list of available applications.\n")
75         if details :
76             details.append(message)
77         raise SatException( message )
78
79 def check_config_has_profile( config, details = None ):
80     """\
81     check that the config has the key APPLICATION.profile.
82     else, raise an exception.
83     
84     :param config class 'common.pyconf.Config': The config.
85     """
86     check_config_has_application(config)
87     if 'profile' not in config.APPLICATION:
88         message = _("A profile section is required in your application.\n")
89         if details :
90             details.append(message)
91         raise SatException( message )
92
93 def config_has_application( config ):
94     return 'APPLICATION' in config
95
96 def get_cfg_param(config, param_name, default):
97     """\
98     eearch for param_name value in config.
99     if param_name is not in config 
100     then return default,
101     else return the found value
102        
103     :param config class 'common.pyconf.Config': The config.
104     :param param_name str: the name of the parameter to get the value
105     :param default str: The value to return if param_name is not in config
106     :return: see initial description of the function
107     :rtype: str
108     """
109     if param_name in config:
110         return config[param_name]
111     return default
112
113 def print_info(logger, info):
114     """\
115     Prints the tuples that are in info variable in a formatted way.
116     
117     :param logger Logger: The logging instance to use for the prints.
118     :param info list: The list of tuples to display
119     """
120     # find the maximum length of the first value of the tuples in info
121     smax = max(map(lambda l: len(l[0]), info))
122     # Print each item of info with good indentation
123     for i in info:
124         sp = " " * (smax - len(i[0]))
125         printcolors.print_value(logger, sp + i[0], i[1], 2)
126     logger.write("\n", 2)
127
128 def get_base_path(config):
129     """\
130     Returns the path of the products base.
131     
132     :param config Config: The global Config instance.
133     :return: The path of the products base.
134     :rtype: str
135     """
136     if "base" not in config.LOCAL:
137         local_file_path = os.path.join(config.VARS.salometoolsway,
138                                       "data",
139                                       "local.pyconf")
140         msg = _("Please define a base path in the file %s" % local_file_path)
141         raise SatException(msg)
142         
143     base_path = os.path.abspath(config.LOCAL.base)
144     
145     return base_path
146
147 def get_launcher_name(config):
148     """\
149     Returns the name of salome launcher.
150     
151     :param config Config: The global Config instance.
152     :return: The name of salome launcher.
153     :rtype: str
154     """
155     check_config_has_application(config)
156     if 'profile' in config.APPLICATION and 'launcher_name' in config.APPLICATION.profile:
157         launcher_name = config.APPLICATION.profile.launcher_name
158     else:
159         launcher_name = 'salome'
160
161     return launcher_name
162
163 def get_log_path(config):
164     """\
165     Returns the path of the logs.
166     
167     :param config Config: The global Config instance.
168     :return: The path of the logs.
169     :rtype: str
170     """
171     if "log_dir" not in config.LOCAL:
172         local_file_path = os.path.join(config.VARS.salometoolsway,
173                                       "data",
174                                       "local.pyconf")
175         msg = _("Please define a log_dir in the file %s" % local_file_path)
176         raise SatException(msg)
177       
178     log_dir_path = os.path.abspath(config.LOCAL.log_dir)
179     
180     return log_dir_path
181
182 def get_salome_version(config):
183     import versionMinorMajorPatch as VMMP
184
185     if hasattr(config.APPLICATION, 'version_salome'):
186         version = VMMP.MinorMajorPatch(config.APPLICATION.version_salome)
187     else:
188         kernel_info = product.get_product_config(config, "KERNEL")
189         aFile = os.path.join(
190                             kernel_info.install_dir,
191                             "bin",
192                             "salome",
193                             "VERSION")
194         if not os.path.isfile(aFile):
195             return None
196         with open(aFile) as f:
197           line = f.readline()  # example: '[SALOME KERNEL] : 8.4.0'
198         version = VMMP.MinorMajorPatch(line.split(":")[1])
199
200     res = version.strCompact()
201     # print("get_salome_version %s -> %s" % (version, res))
202     return res
203
204 def read_config_from_a_file(filePath):
205         try:
206             cfg_file = pyconf.Config(filePath)
207         except pyconf.ConfigError as e:
208             raise SatException(_("Error in configuration file: %(file)s\n  %(error)s") % \
209                 { 'file': filePath, 'error': str(e) })
210         return cfg_file
211
212 def get_tmp_filename(cfg, name):
213     if not os.path.exists(cfg.VARS.tmp_root):
214         os.makedirs(cfg.VARS.tmp_root)
215
216     return os.path.join(cfg.VARS.tmp_root, name)
217
218 ##
219 # Utils class to simplify path manipulations.
220 class Path:
221     def __init__(self, path):
222         self.path = str(path)
223
224     def __add__(self, other):
225         return Path(os.path.join(self.path, str(other)))
226
227     def __abs__(self):
228         return Path(os.path.abspath(self.path))
229
230     def __str__(self):
231         return self.path
232
233     def __eq__(self, other):
234         return self.path == other.path
235
236     def exists(self):
237         return self.islink() or os.path.exists(self.path)
238
239     def islink(self):
240         return os.path.islink(self.path)
241
242     def isdir(self):
243         return os.path.isdir(self.path)
244
245     def isfile(self):
246         return os.path.isfile(self.path)
247
248     def list(self):
249         return [Path(p) for p in os.listdir(self.path)]
250
251     def dir(self):
252         return Path(os.path.dirname(self.path))
253
254     def base(self):
255         return Path(os.path.basename(self.path))
256
257     def make(self, mode=None):
258         os.makedirs(self.path)        
259         if mode:
260             os.chmod(self.path, mode)
261         
262     def chmod(self, mode):
263         os.chmod(self.path, mode)
264
265     def rm(self):    
266         if self.islink():
267             os.remove(self.path)
268         else:
269             shutil.rmtree( self.path, onerror = handleRemoveReadonly )
270
271     def copy(self, path, smart=False):
272         if not isinstance(path, Path):
273             path = Path(path)
274
275         if os.path.islink(self.path):
276             return self.copylink(path)
277         elif os.path.isdir(self.path):
278             return self.copydir(path, smart)
279         else:
280             return self.copyfile(path)
281
282     def smartcopy(self, path):
283         return self.copy(path, True)
284
285     def readlink(self):
286         if self.islink():
287             return os.readlink(self.path)
288         else:
289             return False
290
291     def symlink(self, path):
292         try:
293             os.symlink(str(path), self.path)
294             return True
295         except:
296             return False
297
298     def copylink(self, path):
299         try:
300             os.symlink(os.readlink(self.path), str(path))
301             return True
302         except:
303             return False
304
305     def copydir(self, dst, smart=False):
306         try:
307             names = self.list()
308
309             if not dst.exists():
310                 dst.make()
311
312             for name in names:
313                 if name == dst:
314                     continue
315                 if smart and (str(name) in [".git", "CVS", ".svn"]):
316                     continue
317                 srcname = self + name
318                 dstname = dst + name
319                 srcname.copy(dstname, smart)
320             return True
321         except:
322             return False
323
324     def copyfile(self, path):
325         try:
326             shutil.copy2(self.path, str(path))
327             return True
328         except:
329             return False
330
331 def find_file_in_lpath(file_name, lpath, additional_dir = ""):
332     """\
333     Find in all the directories in lpath list the file that has the same name
334     as file_name. 
335     If it is found 
336     then return the full path of the file
337     else return False.
338  
339     The additional_dir (optional) is the name of the directory to add to all 
340     paths in lpath.
341     
342     :param file_name str: The file name to search
343     :param lpath List: The list of directories where to search
344     :param additional_dir str: The name of the additional directory
345     :return: the full path of the file or False if not found
346     :rtype: str
347     """
348     for directory in lpath:
349         dir_complete = os.path.join(directory, additional_dir)
350         if not os.path.isdir(directory) or not os.path.isdir(dir_complete):
351             continue
352         l_files = os.listdir(dir_complete)
353         for file_n in l_files:
354             if file_n == file_name:
355                 return os.path.join(dir_complete, file_name)
356     return False
357
358 def handleRemoveReadonly(func, path, exc):
359     excvalue = exc[1]
360     if func in (os.rmdir, os.remove) and excvalue.errno == errno.EACCES:
361         os.chmod(path, stat.S_IRWXU| stat.S_IRWXG| stat.S_IRWXO) # 0777
362         func(path)
363     else:
364         raise
365
366 def deepcopy_list(input_list):
367     """\
368     Do a deep copy of a list
369     
370     :param input_list List: The list to copy
371     :return: The copy of the list
372     :rtype: List
373     """
374     res = []
375     for elem in input_list:
376         res.append(elem)
377     return res
378
379 def remove_item_from_list(input_list, item):
380     """\
381     Remove all occurences of item from input_list
382     
383     :param input_list List: The list to modify
384     :return: The without any item
385     :rtype: List
386     """
387     res = []
388     for elem in input_list:
389         if elem == item:
390             continue
391         res.append(elem)
392     return res
393
394 def parse_date(date):
395     """\
396     Transform YYYYMMDD_hhmmss into YYYY-MM-DD hh:mm:ss.
397     
398     :param date str: The date to transform
399     :return: The date in the new format
400     :rtype: str
401     """
402     if len(date) != 15:
403         return date
404     res = "%s-%s-%s %s:%s:%s" % (date[0:4],
405                                  date[4:6],
406                                  date[6:8],
407                                  date[9:11],
408                                  date[11:13],
409                                  date[13:])
410     return res
411
412 def merge_dicts(*dict_args):
413     """\
414     Given any number of dicts, shallow copy and merge into a new dict,
415     precedence goes to key value pairs in latter dicts.
416     """
417     result = {}
418     for dictionary in dict_args:
419         result.update(dictionary)
420     return result
421
422 def replace_in_file(filein, strin, strout):
423     """Replace <strin> by <strout> in file <filein>"""
424     shutil.move(filein, filein + "_old")
425     fileout= filein
426     filein = filein + "_old"
427     fin = open(filein, "r")
428     fout = open(fileout, "w")
429     for line in fin:
430         fout.write(line.replace(strin, strout))
431
432 def get_property_in_product_cfg(product_cfg, pprty):
433     if not "properties" in product_cfg:
434         return None
435     if not pprty in product_cfg.properties:
436         return None
437     return product_cfg.properties[pprty]
438
439 def activate_mesa_property(config):
440     """Add mesa property into application properties
441     
442     :param config Config: The global configuration. It must have an application!
443     """
444     # Verify the existence of the file
445     if not 'properties' in config.APPLICATION:
446         config.APPLICATION.addMapping( 'properties', pyconf.Mapping(), None )
447     config.APPLICATION.properties.use_mesa="yes"
448