Salome HOME
merge master
[tools/sat.git] / src / environment.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 import os
20 import subprocess
21 import string
22 import sys
23
24 import src
25 import src.debug as DBG
26 import pprint as PP
27
28 class Environ:
29     '''Class to manage the environment context
30     '''
31     def __init__(self, environ=None):
32         '''Initialization. If the environ argument is passed, the environment
33            will be add to it, else it is the external environment.
34            
35         :param environ dict:  
36         '''
37         if environ is not None:
38             self.environ = environ
39         else:
40             self.environ = os.environ
41
42     def __repr__(self):
43         """easy non exhaustive quick resume for debug print
44         """
45         return "%s(\n%s\n)" % (self.__class__.__name__, PP.pformat(self.environ))
46
47     def _expandvars(self, value):
48         '''replace some $VARIABLE into its actual value in the environment
49         
50         :param value str: the string to be replaced
51         :return: the replaced variable
52         :rtype: str
53         '''
54         if "$" in value:
55             # The string.Template class is a string class 
56             # for supporting $-substitutions
57             zt = string.Template(value)
58             try:
59                 value = zt.substitute(self.environ)
60             except KeyError as exc:
61                 raise src.SatException(_("Missing definition "
62                                          "in environment: %s") % str(exc))
63         return value
64
65     def append_value(self, key, value, sep=os.pathsep):
66         '''append value to key using sep
67         
68         :param key str: the environment variable to append
69         :param value str: the value to append to key
70         :param sep str: the separator string
71         '''
72         # check if the key is already in the environment
73         if key in self.environ:
74             value_list = self.environ[key].split(sep)
75             # Check if the value is already in the key value or not
76             if not value in value_list:
77                 value_list.append(value)
78             else:
79                 value_list.append(value_list.pop(value_list.index(value)))
80             self.set(key, sep.join(value_list))
81         else:
82             self.set(key, value)
83
84     def append(self, key, value, sep=os.pathsep):
85         '''Same as append_value but the value argument can be a list
86         
87         :param key str: the environment variable to append
88         :param value str or list: the value(s) to append to key
89         :param sep str: the separator string
90         '''
91         if isinstance(value, list):
92             for v in value:
93                 self.append_value(key, v, sep)
94         else:
95             self.append_value(key, value, sep)
96
97     def prepend_value(self, key, value, sep=os.pathsep):
98         '''prepend value to key using sep
99         
100         :param key str: the environment variable to prepend
101         :param value str: the value to prepend to key
102         :param sep str: the separator string
103         '''
104         if key in self.environ:
105             value_list = self.environ[key].split(sep)
106             if not value in value_list:
107                 value_list.insert(0, value)
108             else:
109                 value_list.insert(0, value_list.pop(value_list.index(value)))
110             self.set(key, sep.join(value_list))
111         else:
112             self.set(key, value)
113
114     def prepend(self, key, value, sep=os.pathsep):
115         '''Same as prepend_value but the value argument can be a list
116         
117         :param key str: the environment variable to prepend
118         :param value str or list: the value(s) to prepend to key
119         :param sep str: the separator string
120         '''
121         if isinstance(value, list):
122             for v in value:
123                 self.prepend_value(key, v, sep)
124         else:
125             self.prepend_value(key, value, sep)
126
127     def is_defined(self, key):
128         '''Check if the key exists in the environment
129         
130         :param key str: the environment variable to check
131         '''
132         return key in self.environ.keys()
133
134     def set(self, key, value):
135         '''Set the environment variable "key" to value "value"
136         
137         :param key str: the environment variable to set
138         :param value str: the value
139         '''
140         self.environ[key] = self._expandvars(value)
141
142     def get(self, key):
143         '''Get the value of the environment variable "key"
144         
145         :param key str: the environment variable
146         '''
147         if key in self.environ:
148             return self.environ[key]
149         else:
150             return ""
151
152     def command_value(self, key, command):
153         '''Get the value given by the system command "command" 
154            and put it in the environment variable key
155         
156         :param key str: the environment variable
157         :param command str: the command to execute
158         '''
159         value = subprocess.Popen(command,
160                                  shell=True,
161                                  stdout=subprocess.PIPE,
162                                  env=self.environ).communicate()[0]
163         self.environ[key] = value
164
165
166 class SalomeEnviron:
167     """Class to manage the environment of SALOME.
168     """
169
170     def __init__(self,
171                  cfg,
172                  environ,
173                  forBuild=False,
174                  for_package=None,
175                  enable_simple_env_script = True):
176         '''Initialization.
177
178         :param cfg Config: the global config
179         :param environ Environ: the Environ instance where 
180                                 to store the environment variables
181         :param forBuild bool: If true, it is a launch environment, 
182                               else a build one
183         :param for_package str: If not None, produce a relative environment 
184                                 designed for a package. 
185         '''
186         self.environ = environ
187         self.cfg = cfg
188         self.forBuild = forBuild
189         self.for_package = for_package
190         self.enable_simple_env_script = enable_simple_env_script
191         self.silent = False
192
193     def __repr__(self):
194         """easy almost exhaustive quick resume for debug print"""
195         res = {
196           "environ" : self.environ,
197           "forBuild" : self.forBuild,
198           "for_package" : self.for_package,
199         }
200         return "%s(\n%s\n)" % (self.__class__.__name__, PP.pformat(res))
201
202     def append(self, key, value, sep=os.pathsep):
203         '''append value to key using sep
204         
205         :param key str: the environment variable to append
206         :param value str: the value to append to key
207         :param sep str: the separator string
208         '''
209         return self.environ.append(key, value, sep)
210
211     def prepend(self, key, value, sep=os.pathsep):
212         '''prepend value to key using sep
213         
214         :param key str: the environment variable to prepend
215         :param value str: the value to prepend to key
216         :param sep str: the separator string
217         '''
218         return self.environ.prepend(key, value, sep)
219
220     def is_defined(self, key):
221         '''Check if the key exists in the environment
222         
223         :param key str: the environment variable to check
224         '''
225         return self.environ.is_defined(key)
226
227     def get(self, key):
228         '''Get the value of the environment variable "key"
229         
230         :param key str: the environment variable
231         '''
232         return self.environ.get(key)
233
234     def set(self, key, value):
235         '''Set the environment variable "key" to value "value"
236         
237         :param key str: the environment variable to set
238         :param value str: the value
239         '''
240         # check if value needs to be evaluated
241         if value is not None and value.startswith("`") and value.endswith("`"):
242             res = subprocess.Popen("echo %s" % value,
243                                    shell=True,
244                                    stdout=subprocess.PIPE).communicate()
245             value = res[0].strip()
246
247         return self.environ.set(key, value)
248
249     def dump(self, out):
250         """Write the environment to out
251         
252         :param out file: the stream where to write the environment
253         """
254         for k in self.environ.environ.keys():
255             try:
256                 value = self.get(k)
257             except:
258                 value = "?"
259             out.write("%s=%s\n" % (k, value))
260
261     def add_line(self, nb_line):
262         """Add empty lines to the out stream (in case of file generation)
263         
264         :param nb_line int: the number of empty lines to add
265         """
266         if 'add_line' in dir(self.environ):
267             self.environ.add_line(nb_line)
268
269     def add_comment(self, comment):
270         """Add a commentary to the out stream (in case of file generation)
271         
272         :param comment str: the commentary to add
273         """
274         if 'add_comment' in dir(self.environ):
275             self.environ.add_comment(comment)
276
277     def add_warning(self, warning):
278         """Add a warning to the out stream (in case of file generation)
279         
280         :param warning str: the warning to add
281         """
282         if 'add_warning' in dir(self.environ):
283             self.environ.add_warning(warning)
284
285     def finish(self, required):
286         """Add a final instruction in the out file (in case of file generation)
287         
288         :param required bool: Do nothing if required is False
289         """
290         if 'finish' in dir(self.environ):
291             self.environ.add_line(1)
292             self.environ.add_comment("clean all the path")
293             self.environ.finish(required)
294
295     def set_python_libdirs(self):
296         """Set some generic variables for python library paths
297         """
298         ver = self.get('PYTHON_VERSION')
299         self.set('PYTHON_LIBDIR0', os.path.join('lib',
300                                                 'python' + ver,
301                                                 'site-packages'))
302         self.set('PYTHON_LIBDIR1', os.path.join('lib64',
303                                                 'python' + ver,
304                                                 'site-packages'))
305           
306         self.python_lib0 = self.get('PYTHON_LIBDIR0')
307         self.python_lib1 = self.get('PYTHON_LIBDIR1')
308
309     def get_names(self, lProducts):
310         """Get the products name to add in SALOME_MODULES environment variable
311            It is the name of the product, except in the case where the is a 
312            component name. And it has to be in SALOME_MODULES variable only 
313            if the product has the property has_salome_hui = "yes"
314         
315         :param lProducts list: List of products to potentially add
316         """
317         lProdHasGui = [p for p in lProducts if 'properties' in 
318             src.product.get_product_config(self.cfg, p) and
319             'has_salome_gui' in 
320             src.product.get_product_config(self.cfg, p).properties and
321             src.product.get_product_config(self.cfg,
322                                            p).properties.has_salome_gui=='yes']
323         lProdName = []
324         for ProdName in lProdHasGui:
325             pi = src.product.get_product_config(self.cfg, ProdName)
326             if 'component_name' in pi:
327                 lProdName.append(pi.component_name)
328             else:
329                 lProdName.append(ProdName)
330         return lProdName
331
332     def set_application_env(self, logger):
333         """Sets the environment defined in the APPLICATION file.
334         
335         :param logger Logger: The logger instance to display messages
336         """
337         
338         # add variable PRODUCT_ROOT_DIR as $workdir in APPLICATION.environ section if not present
339         try: 
340           tmp = self.cfg.APPLICATION.environ.PRODUCT_ROOT_DIR
341         except:
342           self.cfg.APPLICATION.environ.PRODUCT_ROOT_DIR = src.pyconf.Reference(self.cfg, src.pyconf.DOLLAR, "workdir")
343           DBG.write("set_application_env add default Config.APPLICATION.environ.PRODUCT_ROOT_DIR", self.cfg.APPLICATION.environ)
344           
345         # Set the variables defined in the "environ" section
346         if 'environ' in self.cfg.APPLICATION:
347             # we write PRODUCT environment it in order to conform to 
348             # parseConfigFile.py
349             self.add_comment("PRODUCT environment") 
350             self.load_cfg_environment(self.cfg.APPLICATION.environ)
351             if self.forBuild and "build" in self.cfg.APPLICATION.environ:
352                 self.load_cfg_environment(self.cfg.APPLICATION.environ.build)
353             if not self.forBuild and "launch" in self.cfg.APPLICATION.environ:
354                 self.load_cfg_environment(self.cfg.APPLICATION.environ.launch)
355             self.add_line(1)
356
357         # If there is an "environ_script" section, load the scripts
358         if 'environ_script' in self.cfg.APPLICATION:
359             for pscript in self.cfg.APPLICATION.environ_script:
360                 self.add_comment("script %s" % pscript)
361                 sname = pscript.replace(" ", "_")
362                 self.run_env_script("APPLICATION_%s" % sname,
363                                 self.cfg.APPLICATION.environ_script[pscript],
364                                 logger)
365                 self.add_line(1)       
366
367     def set_salome_minimal_product_env(self, product_info, logger):
368         """Sets the minimal environment for a SALOME product.
369            xxx_ROOT_DIR and xxx_SRC_DIR
370         
371         :param product_info Config: The product description
372         :param logger Logger: The logger instance to display messages        
373         """
374         # set root dir
375         DBG.write("set_salome_minimal_product_env", product_info)
376         root_dir = product_info.name + "_ROOT_DIR"
377         if not self.is_defined(root_dir):
378             if 'install_dir' in product_info and product_info.install_dir:
379                 self.set(root_dir, product_info.install_dir)
380             elif not self.silent:
381                 logger.write("  " + _("No install_dir for product %s\n") %
382                               product_info.name, 5)
383         
384         source_in_package = src.get_property_in_product_cfg(product_info,
385                                                            "sources_in_package")
386         if not self.for_package or source_in_package == "yes":
387             # set source dir, unless no source dir
388             if not src.product.product_is_fixed(product_info):
389                 src_dir = product_info.name + "_SRC_DIR"
390                 if not self.is_defined(src_dir):
391                     if not self.for_package:
392                         self.set(src_dir, product_info.source_dir)
393                     else:
394                         self.set(src_dir, os.path.join("out_dir_Path",
395                                                        "SOURCES",
396                                                        product_info.name))
397
398     def set_salome_generic_product_env(self, pi):
399         """Sets the generic environment for a SALOME product.
400         
401         :param pi Config: The product description
402         """
403         # Construct XXX_ROOT_DIR
404         env_root_dir = self.get(pi.name + "_ROOT_DIR")
405         l_binpath_libpath = []
406
407         # create additional ROOT_DIR for CPP components
408         if 'component_name' in pi:
409             compo_name = pi.component_name
410             if compo_name + "CPP" == pi.name:
411                 compo_root_dir = compo_name + "_ROOT_DIR"
412                 envcompo_root_dir = os.path.join(
413                             self.cfg.TOOLS.common.install_root, compo_name )
414                 self.set(compo_root_dir ,  envcompo_root_dir)
415                 bin_path = os.path.join(envcompo_root_dir, 'bin', 'salome')
416                 lib_path = os.path.join(envcompo_root_dir, 'lib', 'salome')
417                 l_binpath_libpath.append( (bin_path, lib_path) )
418
419         if src.get_property_in_product_cfg(pi, "fhs"):
420             lib_path = os.path.join(env_root_dir, 'lib')
421             pylib1_path = os.path.join(env_root_dir, self.python_lib0)
422             pylib2_path = os.path.join(env_root_dir, self.python_lib1)
423             bin_path = os.path.join(env_root_dir, 'bin')
424         else:
425             lib_path = os.path.join(env_root_dir, 'lib', 'salome')
426             pylib1_path = os.path.join(env_root_dir, self.python_lib0, 'salome')
427             pylib2_path = os.path.join(env_root_dir, self.python_lib1, 'salome')
428             bin_path = os.path.join(env_root_dir, 'bin', 'salome')
429
430         # Construct the paths to prepend to PATH and LD_LIBRARY_PATH and 
431         # PYTHONPATH
432         l_binpath_libpath.append( (bin_path, lib_path) )
433
434         for bin_path, lib_path in l_binpath_libpath:
435             if not self.forBuild:
436                 self.prepend('PATH', bin_path)
437                 if src.architecture.is_windows():
438                     self.prepend('PATH', lib_path)
439                 else :
440                     self.prepend('LD_LIBRARY_PATH', lib_path)
441
442             l = [ bin_path, lib_path, pylib1_path, pylib2_path ]
443             self.prepend('PYTHONPATH', l)
444
445     def set_cpp_env(self, product_info):
446         """Sets the generic environment for a SALOME cpp product.
447         
448         :param product_info Config: The product description
449         """
450         # Construct XXX_ROOT_DIR
451         env_root_dir = self.get(product_info.name + "_ROOT_DIR")
452         l_binpath_libpath = []
453
454         # Construct the paths to prepend to PATH and LD_LIBRARY_PATH and 
455         # PYTHONPATH
456         bin_path = os.path.join(env_root_dir, 'bin')
457         lib_path = os.path.join(env_root_dir, 'lib')
458         l_binpath_libpath.append( (bin_path, lib_path) )
459
460         for bin_path, lib_path in l_binpath_libpath:
461             if not self.forBuild:
462                 self.prepend('PATH', bin_path)
463                 if src.architecture.is_windows():
464                     self.prepend('PATH', lib_path)
465                 else :
466                     self.prepend('LD_LIBRARY_PATH', lib_path)
467
468             l = [ bin_path, lib_path,
469                   os.path.join(env_root_dir, self.python_lib0),
470                   os.path.join(env_root_dir, self.python_lib1)
471                 ]
472             self.prepend('PYTHONPATH', l)
473
474     def load_cfg_environment(self, cfg_env):
475         """Loads environment defined in cfg_env 
476         
477         :param cfg_env Config: A config containing an environment    
478         """
479         # Loop on cfg_env values
480         for env_def in cfg_env:
481             val = cfg_env[env_def]
482             
483             # if it is env_script, do not do anything (reserved keyword)
484             if env_def == "env_script":
485                 continue
486             
487             # if it is a dict, do not do anything
488             if isinstance(val, src.pyconf.Mapping):
489                 continue
490
491             # if it is a list, loop on its values
492             if isinstance(val, src.pyconf.Sequence):
493                 # transform into list of strings
494                 l_val = []
495                 for item in val:
496                     l_val.append(item)
497                 val = l_val
498
499             # "_" means that the value must be prepended
500             if env_def.startswith("_"):
501                 # separator exception for PV_PLUGIN_PATH
502                 if env_def[1:] == 'PV_PLUGIN_PATH':
503                     self.prepend(env_def[1:], val, ';')
504                 else:
505                     self.prepend(env_def[1:], val)
506             elif env_def.endswith("_"):
507                 # separator exception for PV_PLUGIN_PATH
508                 if env_def[:-1] == 'PV_PLUGIN_PATH':
509                     self.append(env_def[:-1], val, ';')
510                 else:
511                     self.append(env_def[:-1], val)
512             else:
513                 self.set(env_def, val)
514
515     def set_a_product(self, product, logger):
516         """Sets the environment of a product. 
517         
518         :param product str: The product name
519         :param logger Logger: The logger instance to display messages
520         """
521
522         # Get the informations corresponding to the product
523         pi = src.product.get_product_config(self.cfg, product)
524         
525         if self.for_package:
526             pi.install_dir = os.path.join("out_dir_Path",
527                                           self.for_package,
528                                           pi.name)
529
530         if not self.silent:
531             logger.write(_("Setting environment for %s\n") % product, 4)
532
533         self.add_line(1)
534         self.add_comment('setting environ for ' + product)
535             
536         # Do not define environment if the product is native
537         if src.product.product_is_native(pi):
538             if src.product.product_has_env_script(pi):
539                 self.run_env_script(pi, native=True)
540             return
541                
542         # Set an additional environment for SALOME products
543         if src.product.product_is_salome(pi):
544             # set environment using definition of the product
545             self.set_salome_minimal_product_env(pi, logger)
546             self.set_salome_generic_product_env(pi)
547         
548         if src.product.product_is_cpp(pi):
549             # set a specific environment for cpp modules
550             self.set_salome_minimal_product_env(pi, logger)
551             self.set_cpp_env(pi)
552             
553             if src.product.product_is_generated(pi):
554                 if "component_name" in pi:
555                     # hack the source and install directories in order to point  
556                     # on the generated product source install directories
557                     install_dir_save = pi.install_dir
558                     source_dir_save = pi.source_dir
559                     name_save = pi.name
560                     pi.install_dir = os.path.join(self.cfg.APPLICATION.workdir,
561                                                   "INSTALL",
562                                                   pi.component_name)
563                     if self.for_package:
564                         pi.install_dir = os.path.join("out_dir_Path",
565                                                       self.for_package,
566                                                       pi.component_name)
567                     pi.source_dir = os.path.join(self.cfg.APPLICATION.workdir,
568                                                   "GENERATED",
569                                                   pi.component_name)
570                     pi.name = pi.component_name
571                     self.set_salome_minimal_product_env(pi, logger)
572                     self.set_salome_generic_product_env(pi)
573                     
574                     # Put original values
575                     pi.install_dir = install_dir_save
576                     pi.source_dir = source_dir_save
577                     pi.name = name_save
578         
579         # Put the environment define in the configuration of the product
580         if "environ" in pi:
581             self.load_cfg_environment(pi.environ)
582             if self.forBuild and "build" in pi.environ:
583                 self.load_cfg_environment(pi.environ.build)
584             if not self.forBuild and "launch" in pi.environ:
585                 self.load_cfg_environment(pi.environ.launch)
586             # if product_info defines a env_scripts, load it
587             if 'env_script' in pi.environ:
588                 self.run_env_script(pi, logger)
589
590         
591             
592
593     def run_env_script(self, product_info, logger=None, native=False):
594         """Runs an environment script. 
595         
596         :param product_info Config: The product description
597         :param logger Logger: The logger instance to display messages
598         :param native Boolean: if True load set_native_env instead of set_env
599         """
600         env_script = product_info.environ.env_script
601         # Check that the script exists
602         if not os.path.exists(env_script):
603             raise src.SatException(_("Environment script not found: %s") % 
604                                    env_script)
605
606         if not self.silent and logger is not None:
607             logger.write("  ** load %s\n" % env_script, 4)
608
609         # import the script and run the set_env function
610         try:
611             import imp
612             pyproduct = imp.load_source(product_info.name + "_env_script",
613                                         env_script)
614             if not native:
615                 pyproduct.set_env(self,
616                                   product_info.install_dir,
617                                   product_info.version)
618             else:
619                 if "set_nativ_env" in dir(pyproduct):
620                     pyproduct.set_nativ_env(self)
621         except:
622             __, exceptionValue, exceptionTraceback = sys.exc_info()
623             print(exceptionValue)
624             import traceback
625             traceback.print_tb(exceptionTraceback)
626             traceback.print_exc()
627
628     def run_simple_env_script(self, script_path, logger=None):
629         """Runs an environment script. Same as run_env_script, but with a 
630            script path as parameter.
631         
632         :param script_path str: a path to an environment script
633         :param logger Logger: The logger instance to display messages
634         """
635         if not self.enable_simple_env_script:
636             return
637         # Check that the script exists
638         if not os.path.exists(script_path):
639             raise src.SatException(_("Environment script not found: %s") % 
640                                    script_path)
641
642         if not self.silent and logger is not None:
643             logger.write("  ** load %s\n" % script_path, 4)
644
645         script_basename = os.path.basename(script_path)
646         if script_basename.endswith(".py"):
647             script_basename = script_basename[:-len(".py")]
648
649         # import the script and run the set_env function
650         try:
651             import imp
652             pyproduct = imp.load_source(script_basename + "_env_script",
653                                         script_path)
654             pyproduct.load_env(self)
655         except:
656             __, exceptionValue, exceptionTraceback = sys.exc_info()
657             print(exceptionValue)
658             import traceback
659             traceback.print_tb(exceptionTraceback)
660             traceback.print_exc()
661
662     def set_products(self, logger, src_root=None):
663         """Sets the environment for all the products. 
664         
665         :param logger Logger: The logger instance to display messages
666         :param src_root src: the application working directory
667         """
668         self.add_line(1)
669         self.add_comment('setting environ for all products')
670
671         # Make sure that the python lib dirs are set after python
672         if "Python" in self.cfg.APPLICATION.products:
673             self.set_a_product("Python", logger)
674             self.set_python_libdirs()
675
676         # The loop on the products
677         for product in self.cfg.APPLICATION.products.keys():
678             if product == "Python":
679                 continue
680             self.set_a_product(product, logger)
681             self.finish(False)
682  
683     def set_full_environ(self, logger, env_info):
684         """Sets the full environment for products 
685            specified in env_info dictionary. 
686         
687         :param logger Logger: The logger instance to display messages
688         :param env_info list: the list of products
689         """
690         DBG.write("set_full_environ for", env_info)
691         # DBG.write("set_full_environ config", self.cfg.APPLICATION.environ, True)
692         # set product environ
693         self.set_application_env(logger)
694
695         self.set_python_libdirs()
696
697         # set products
698         for product in env_info:
699             self.set_a_product(product, logger)
700
701 class FileEnvWriter:
702     """Class to dump the environment to a file.
703     """
704     def __init__(self, config, logger, out_dir, src_root, env_info=None):
705         '''Initialization.
706
707         :param cfg Config: the global config
708         :param logger Logger: The logger instance to display messages
709         :param out_dir str: The directory path where t put the output files
710         :param src_root str: The application working directory
711         :param env_info str: The list of products to add in the files.
712         '''
713         self.config = config
714         self.logger = logger
715         self.out_dir = out_dir
716         self.src_root= src_root
717         self.silent = True
718         self.env_info = env_info
719
720     def write_env_file(self, filename, forBuild, shell, for_package = None):
721         """Create an environment file.
722         
723         :param filename str: the file path
724         :param forBuild bool: if true, the build environment
725         :param shell str: the type of file wanted (.sh, .bat)
726         :return: The path to the generated file
727         :rtype: str
728         """
729         if not self.silent:
730             self.logger.write(_("Create environment file %s\n") % 
731                               src.printcolors.printcLabel(filename), 3)
732
733         # create then env object
734         env_file = open(os.path.join(self.out_dir, filename), "w")
735         tmp = src.fileEnviron.get_file_environ(env_file,
736                                                shell,
737                                                {})
738         env = SalomeEnviron(self.config, tmp, forBuild, for_package=for_package)
739         env.silent = self.silent
740
741         # Set the environment
742         if self.env_info is not None:
743             env.set_full_environ(self.logger, self.env_info)
744         else:
745             # set env from the APPLICATION
746             env.set_application_env(self.logger)
747             
748             # The list of products to launch
749             lProductsName = env.get_names(self.config.APPLICATION.products.keys())
750             env.set( "SALOME_MODULES",    ','.join(lProductsName))
751             
752             # set the products
753             env.set_products(self.logger,
754                             src_root=self.src_root)
755
756         # add cleanup and close
757         env.finish(True)
758         env_file.close()
759
760         return env_file.name
761    
762     def write_cfgForPy_file(self,
763                             filename,
764                             additional_env = {},
765                             for_package = None,
766                             with_commercial = True):
767         """Append to current opened aFile a cfgForPy 
768            environment (SALOME python launcher).
769            
770         :param filename str: the file path
771         :param additional_env dict: a dictionary of additional variables 
772                                     to add to the environment
773         :param for_package str: If not None, produce a relative environment 
774                                 designed for a package. 
775         """
776         if not self.silent:
777             self.logger.write(_("Create configuration file %s\n") % 
778                               src.printcolors.printcLabel(filename.name), 3)
779
780         # create then env object
781         tmp = src.fileEnviron.get_file_environ(filename, 
782                                                "cfgForPy", 
783                                                {})
784         # environment for launch
785         env = SalomeEnviron(self.config,
786                             tmp,
787                             forBuild=False,
788                             for_package=for_package,
789                             enable_simple_env_script = with_commercial)
790         env.silent = self.silent
791
792         if self.env_info is not None:
793             env.set_full_environ(self.logger, self.env_info)
794         else:
795             # set env from PRODUCT
796             env.set_application_env(self.logger)
797
798             # The list of products to launch
799             lProductsName = env.get_names(self.config.APPLICATION.products.keys())
800             env.set( "SALOME_MODULES",    ','.join(lProductsName))
801
802             # set the products
803             env.set_products(self.logger,
804                             src_root=self.src_root)
805
806         # Add the additional environment if it is not empty
807         if len(additional_env) != 0:
808             for variable in additional_env:
809                 env.set(variable, additional_env[variable])
810
811         # add cleanup and close
812         env.finish(True)
813
814 class Shell:
815     """Definition of a Shell.
816     """
817     def __init__(self, name, extension):
818         '''Initialization.
819
820         :param name str: the shell name
821         :param extension str: the shell extension
822         '''
823         self.name = name
824         self.extension = extension
825
826 def load_environment(config, build, logger):
827     """Loads the environment (used to run the tests, for example).
828     
829     :param config Config: the global config
830     :param build bool: build environement if True
831     :param logger Logger: The logger instance to display messages
832     """
833     environ = SalomeEnviron(config, Environ(os.environ), build)
834     environ.set_application_env(logger)
835     environ.set_products(logger)
836     environ.finish(True)