Salome HOME
sat #8560 : ajout des poignées set_env_build et set_env_launch pour mieux gérer les...
[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                 if self.forBuild and "set_env_build" in dir(pyproduct):
648                     pyproduct.set_env_build(self,
649                                             product_info.install_dir,
650                                             product_info.version)
651                 elif (not self.forBuild) and "set_env_launch" in dir(pyproduct):
652                     pyproduct.set_env_launch(self,
653                                             product_info.install_dir,
654                                             product_info.version)
655                 else:
656                     # at least this one is mandatoryi,
657                     # if set_env_build and set_env_build are not defined
658                     pyproduct.set_env(self,
659                                       product_info.install_dir,
660                                       product_info.version)
661             else:
662                 # not mandatory, if set_nativ_env not defined, we do nothing
663                 if "set_nativ_env" in dir(pyproduct):
664                     pyproduct.set_nativ_env(self)
665         except:
666             __, exceptionValue, exceptionTraceback = sys.exc_info()
667             print(exceptionValue)
668             import traceback
669             traceback.print_tb(exceptionTraceback)
670             traceback.print_exc()
671
672     def run_simple_env_script(self, script_path, logger=None):
673         """\
674         Runs an environment script. Same as run_env_script, but with a 
675         script path as parameter.
676         
677         :param script_path str: a path to an environment script
678         :param logger Logger: The logger instance to display messages
679         """
680         if not self.enable_simple_env_script:
681             return
682         # Check that the script exists
683         if not os.path.exists(script_path):
684             raise src.SatException(_("Environment script not found: %s") % 
685                                    script_path)
686
687         if not self.silent and logger is not None:
688             logger.write("  ** load %s\n" % script_path, 4)
689
690         script_basename = os.path.basename(script_path)
691         if script_basename.endswith(".py"):
692             script_basename = script_basename[:-len(".py")]
693
694         # import the script and run the set_env function
695         try:
696             import imp
697             pyproduct = imp.load_source(script_basename + "_env_script",
698                                         script_path)
699             pyproduct.load_env(self)
700         except:
701             __, exceptionValue, exceptionTraceback = sys.exc_info()
702             print(exceptionValue)
703             import traceback
704             traceback.print_tb(exceptionTraceback)
705             traceback.print_exc()
706
707     def set_products(self, logger, src_root=None):
708         """\
709         Sets the environment for all the products. 
710         
711         :param logger Logger: The logger instance to display messages
712         :param src_root src: the application working directory
713         """
714         self.add_line(1)
715         self.add_comment('setting environ for all products')
716
717         # Make sure that the python lib dirs are set after python
718         if "Python" in self.cfg.APPLICATION.products:
719             self.set_a_product("Python", logger)
720             self.set_python_libdirs()
721
722         # The loop on the products
723         for product in self.cfg.APPLICATION.products.keys():
724             if product == "Python":
725                 continue
726             self.set_a_product(product, logger)
727             self.finish(False)
728  
729     def set_full_environ(self, logger, env_info):
730         """\
731         Sets the full environment for products 
732         specified in env_info dictionary. 
733         
734         :param logger Logger: The logger instance to display messages
735         :param env_info list: the list of products
736         """
737         DBG.write("set_full_environ for", env_info)
738         # DBG.write("set_full_environ config", self.cfg.APPLICATION.environ, True)
739         # set product environ
740         self.set_application_env(logger)
741
742         self.set_python_libdirs()
743
744         # set products
745         for product in env_info:
746             self.set_a_product(product, logger)
747
748 class FileEnvWriter:
749     """\
750     Class to dump the environment to a file.
751     """
752     def __init__(self, config, logger, out_dir, src_root, env_info=None):
753         """\
754         Initialization.
755
756         :param cfg Config: the global config
757         :param logger Logger: The logger instance to display messages
758         :param out_dir str: The directory path where t put the output files
759         :param src_root str: The application working directory
760         :param env_info str: The list of products to add in the files.
761         """
762         self.config = config
763         self.logger = logger
764         self.out_dir = out_dir
765         self.src_root= src_root
766         self.silent = True
767         self.env_info = env_info
768
769     def write_env_file(self, filename, forBuild, shell, for_package = None):
770         """\
771         Create an environment file.
772         
773         :param filename str: the file path
774         :param forBuild bool: if true, the build environment
775         :param shell str: the type of file wanted (.sh, .bat)
776         :return: The path to the generated file
777         :rtype: str
778         """
779         if not self.silent:
780             self.logger.write(_("Create environment file %s\n") % 
781                               src.printcolors.printcLabel(filename), 3)
782
783         # create then env object
784         env_file = open(os.path.join(self.out_dir, filename), "w")
785         tmp = src.fileEnviron.get_file_environ(env_file,
786                                                shell,
787                                                {})
788         env = SalomeEnviron(self.config, tmp, forBuild, for_package=for_package)
789         env.silent = self.silent
790
791         # Set the environment
792         if self.env_info is not None:
793             env.set_full_environ(self.logger, self.env_info)
794         else:
795             # set env from the APPLICATION
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 cleanup and close
807         env.finish(True)
808         env_file.close()
809
810         return env_file.name
811    
812     def write_cfgForPy_file(self,
813                             filename,
814                             additional_env = {},
815                             for_package = None,
816                             with_commercial = True):
817         """\
818         Append to current opened aFile a cfgForPy 
819         environment (SALOME python launcher).
820            
821         :param filename str: the file path
822         :param additional_env dict: a dictionary of additional variables 
823                                     to add to the environment
824         :param for_package str: If not None, produce a relative environment 
825                                 designed for a package. 
826         """
827         if not self.silent:
828             self.logger.write(_("Create configuration file %s\n") % 
829                               src.printcolors.printcLabel(filename.name), 3)
830
831         # create then env object
832         tmp = src.fileEnviron.get_file_environ(filename, 
833                                                "cfgForPy", 
834                                                {})
835         # environment for launch
836         env = SalomeEnviron(self.config,
837                             tmp,
838                             forBuild=False,
839                             for_package=for_package,
840                             enable_simple_env_script = with_commercial)
841         env.silent = self.silent
842
843         if self.env_info is not None:
844             env.set_full_environ(self.logger, self.env_info)
845         else:
846             # set env from PRODUCT
847             env.set_application_env(self.logger)
848
849             # The list of products to launch
850             lProductsName = env.get_names(self.config.APPLICATION.products.keys())
851             env.set( "SALOME_MODULES",    ','.join(lProductsName))
852
853             # set the products
854             env.set_products(self.logger,
855                             src_root=self.src_root)
856
857         # Add the additional environment if it is not empty
858         if len(additional_env) != 0:
859             for variable in additional_env:
860                 env.set(variable, additional_env[variable])
861
862         # add cleanup and close
863         env.finish(True)
864
865 class Shell:
866     """\
867     Definition of a Shell.
868     """
869     def __init__(self, name, extension):
870         """\
871         Initialization.
872
873         :param name str: the shell name
874         :param extension str: the shell extension
875         """
876         self.name = name
877         self.extension = extension
878
879 def load_environment(config, build, logger):
880     """\
881     Loads the environment (used to run the tests, for example).
882     
883     :param config Config: the global config
884     :param build bool: build environement if True
885     :param logger Logger: The logger instance to display messages
886     """
887     environ = SalomeEnviron(config, Environ(os.environ), build)
888     environ.set_application_env(logger)
889     environ.set_products(logger)
890     environ.finish(True)