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