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