Salome HOME
commentaries
[tools/sat.git] / src / fileEnviron.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
21 batch_header="""@echo off
22
23 rem The following variables are used only in case of a sat package
24 set out_dir_Path=%~dp0
25 set PRODUCT_OUT_DIR=%out_dir_Path%
26 set prereq_install_Path=%out_dir_Path%\PREREQUISITES\INSTALL
27 set prereq_build_Path=%out_dir_Path%\PREREQUISITES\BUILD
28 """
29
30
31 bash_header="""#!/bin/bash
32 ##########################################################################
33 #
34 #### cleandup ###
35 # cleanup a path (first parameter) from duplicated entries;
36 # second parameter is the separator
37 cleandup() {
38 out_var=`echo $1 | awk -v sep=$2 '{                      \\
39      na = split($1,a,sep);                               \\
40      k=0;                                                \\
41      for(i=0;i<=na;i++) {                                \\
42        found=0;                                          \\
43        for(j=0;j<k;j++) {                                \\
44          if(a[i]==aa[j])                                 \\
45          {                                               \\
46            found=1;                                      \\
47            break;                                        \\
48          };                                              \\
49        };                                                \\
50        if(found==0) {                                    \\
51          aa[k++]=a[i];                                   \\
52        };                                                \\
53      };                                                  \\
54      ORS=sep;                                            \\
55      for(i=0;i<k;i++) {                                  \\
56        print aa[i];                                      \\
57      }                                                   \\
58    }' | sed -e 's|\\(.*\\)$1|\\1|g' -e 's|^[:;]||' -e 's|[:;]$||'`
59 echo $out_var
60 }
61 ### clean ###
62 clean ()
63 {
64 xenv=`printenv $1`
65 out_var=`cleandup $xenv $2`
66 export $1=$out_var
67 }
68
69 # The 3 following variables are used only in case of a sat package
70 export out_dir_Path=`dirname "${BASH_SOURCE[0]}"`
71 export PRODUCT_OUT_DIR=${out_dir_Path}
72 export PRODUCT_ROOT_DIR=${PRODUCT_OUT_DIR}
73 export prereq_install_Path=${out_dir_Path}/PREREQUISITES/INSTALL
74 export prereq_build_Path=${out_dir_Path}/PREREQUISITES/BUILD
75
76 ###########################################################################
77 """
78
79
80 Launcher_header='''# a generated SALOME Configuration file using python syntax
81 '''
82
83 def get_file_environ(output, shell, environ=None):
84     """Instantiate correct FileEnvironment sub-class.
85     
86     :param output file: the output file stream.
87     :param shell str: the type of shell syntax to use.
88     :param environ dict: a potential additional environment.
89     """
90     if shell == "bash":
91         return BashFileEnviron(output, environ)
92     if shell == "batch":
93         return BatchFileEnviron(output, environ)
94     if shell == "cfgForPy":
95         return LauncherFileEnviron(output, environ)
96     raise Exception("FileEnviron: Unknown shell = %s" % shell)
97
98 class FileEnviron:
99     """Base class for shell environment
100     """
101     def __init__(self, output, environ=None):
102         """Initialization
103         
104         :param output file: the output file stream.
105         :param environ dict: a potential additional environment.
106         """
107         self._do_init(output, environ)
108
109     def _do_init(self, output, environ=None):
110         """Initialization
111         
112         :param output file: the output file stream.
113         :param environ dict: a potential additional environment.
114         """
115         self.output = output
116         self.toclean = []
117         if environ is not None:
118             self.environ = environ
119         else:
120             self.environ = os.environ
121
122     def add_line(self, number):
123         """Add some empty lines in the shell file
124         
125         :param number int: the number of lines to add
126         """
127         self.output.write("\n" * number)
128
129     def add_comment(self, comment):
130         """Add a comment in the shell file
131         
132         :param comment str: the comment to add
133         """
134         self.output.write("# %s\n" % comment)
135
136     def add_echo(self, text):
137         """Add a "echo" in the shell file
138         
139         :param text str: the text to echo
140         """
141         self.output.write('echo %s"\n' % text)
142
143     def add_warning(self, warning):
144         """Add a warning "echo" in the shell file
145         
146         :param warning str: the text to echo
147         """
148         self.output.write('echo "WARNING %s"\n' % warning)
149
150     def append_value(self, key, value, sep=os.pathsep):
151         '''append value to key using sep
152         
153         :param key str: the environment variable to append
154         :param value str: the value to append to key
155         :param sep str: the separator string
156         '''
157         self.set(key, self.get(key) + sep + value)
158         if (key, sep) not in self.toclean:
159             self.toclean.append((key, sep))
160
161     def append(self, key, value, sep=os.pathsep):
162         '''Same as append_value but the value argument can be a list
163         
164         :param key str: the environment variable to append
165         :param value str or list: the value(s) to append to key
166         :param sep str: the separator string
167         '''
168         if isinstance(value, list):
169             self.append_value(key, sep.join(value), sep)
170         else:
171             self.append_value(key, value, sep)
172
173     def prepend_value(self, key, value, sep=os.pathsep):
174         '''prepend value to key using sep
175         
176         :param key str: the environment variable to prepend
177         :param value str: the value to prepend to key
178         :param sep str: the separator string
179         '''
180         self.set(key, value + sep + self.get(key))
181         if (key, sep) not in self.toclean:
182             self.toclean.append((key, sep))
183
184     def prepend(self, key, value, sep=os.pathsep):
185         '''Same as prepend_value but the value argument can be a list
186         
187         :param key str: the environment variable to prepend
188         :param value str or list: the value(s) to prepend to key
189         :param sep str: the separator string
190         '''
191         if isinstance(value, list):
192             self.prepend_value(key, sep.join(value), sep)
193         else:
194             self.prepend_value(key, value, sep)
195
196     def is_defined(self, key):
197         '''Check if the key exists in the environment
198         
199         :param key str: the environment variable to check
200         '''
201         return (key in self.environ)
202
203     def set(self, key, value):
204         '''Set the environment variable "key" to value "value"
205         
206         :param key str: the environment variable to set
207         :param value str: the value
208         '''
209         raise NotImplementedError("set is not implement for this shell!")
210
211     def get(self, key):
212         '''Get the value of the environment variable "key"
213         
214         :param key str: the environment variable
215         '''
216         return '${%s}' % key
217
218     def command_value(self, key, command):
219         '''Get the value given by the system command "command" 
220            and put it in the environment variable key.
221            Has to be overwritten in the derived classes
222            This can be seen as a virtual method
223         
224         :param key str: the environment variable
225         :param command str: the command to execute
226         '''
227         raise NotImplementedError("command_value is not implement "
228                                   "for this shell!")
229
230     def finish(self, required=True):
231         """Add a final instruction in the out file (in case of file generation)
232         
233         :param required bool: Do nothing if required is False
234         """
235         for (key, sep) in self.toclean:
236             if sep != ' ':
237                 self.output.write('clean %s "%s"\n' % (key, sep))
238
239 class BashFileEnviron(FileEnviron):
240     """Class for bash shell.
241     """
242     def __init__(self, output, environ=None):
243         """Initialization
244         
245         :param output file: the output file stream.
246         :param environ dict: a potential additional environment.
247         """
248         self._do_init(output, environ)
249         self.output.write(bash_header)
250
251     def set(self, key, value):
252         '''Set the environment variable "key" to value "value"
253         
254         :param key str: the environment variable to set
255         :param value str: the value
256         '''
257         self.output.write('export %s="%s"\n' % (key, value))
258         self.environ[key] = value
259
260     def command_value(self, key, command):
261         '''Get the value given by the system command "command" 
262            and put it in the environment variable key.
263            Has to be overwritten in the derived classes
264            This can be seen as a virtual method
265         
266         :param key str: the environment variable
267         :param command str: the command to execute
268         '''
269         self.output.write('export %s=$(%s)\n' % (key, command))
270
271     def finish(self, required=True):
272         """Add a final instruction in the out file (in case of file generation)
273         
274         :param required bool: Do nothing if required is False
275         """
276         if not required:
277             return
278         FileEnviron.finish(self, required)
279         
280 class BatchFileEnviron(FileEnviron):
281     """for Windows batch shell.
282     """
283     def __init__(self, output, environ=None):
284         """Initialization
285         
286         :param output file: the output file stream.
287         :param environ dict: a potential additional environment.
288         """
289         self._do_init(output, environ)
290         self.output.write(batch_header)
291
292     def add_comment(self, comment):
293         """Add a comment in the shell file
294         
295         :param comment str: the comment to add
296         """
297         self.output.write("rem %s\n" % comment)
298     
299     def get(self, key):
300         '''Get the value of the environment variable "key"
301         
302         :param key str: the environment variable
303         '''
304         return '%%%s%%' % key
305     
306     def set(self, key, value):
307         '''Set the environment variable "key" to value "value"
308         
309         :param key str: the environment variable to set
310         :param value str: the value
311         '''
312         self.output.write('set %s=%s\n' % (key, value))
313         self.environ[key] = value
314
315     def command_value(self, key, command):
316         '''Get the value given by the system command "command" 
317            and put it in the environment variable key.
318            Has to be overwritten in the derived classes
319            This can be seen as a virtual method
320         
321         :param key str: the environment variable
322         :param command str: the command to execute
323         '''
324         self.output.write('%s > tmp.txt\n' % (command))
325         self.output.write('set /p %s =< tmp.txt\n' % (key))
326
327     def finish(self, required=True):
328         """Add a final instruction in the out file (in case of file generation)
329            In the particular windows case, do nothing
330         
331         :param required bool: Do nothing if required is False
332         """
333         return
334
335 def special_path_separator(name):
336     """TCLLIBPATH, TKLIBPATH, PV_PLUGIN_PATH environments variables need
337        some exotic path separator.
338        This function gives the separator regarding the name of the variable
339        to append or prepend.
340        
341     :param name str: The name of the variable to find the separator
342     """
343     special_blanks_keys=["TCLLIBPATH", "TKLIBPATH"]
344     special_semicolon_keys=["PV_PLUGIN_PATH"]
345     res=os.pathsep
346     if name in special_blanks_keys: res=" "
347     if name in special_semicolon_keys: res=";"
348     return res
349
350 class LauncherFileEnviron:
351     """Class to generate a launcher file script 
352        (in python syntax) SalomeContext API
353     """
354     def __init__(self, output, environ=None):
355         """Initialization
356         
357         :param output file: the output file stream.
358         :param environ dict: a potential additional environment.
359         """
360         self.output = output
361         self.toclean = []
362         if environ is not None:
363             self.environ = environ
364         else:
365             self.environ = os.environ
366         # Initialize some variables
367         if not self.environ.has_key("PATH"):
368             self.environ["PATH"]=""
369         if not self.environ.has_key("LD_LIBRARY_PATH"):
370             self.environ["LD_LIBRARY_PATH"]=""
371         if not self.environ.has_key("PYTHONPATH"):
372             self.environ["PYTHONPATH"]=""
373         if not self.environ.has_key("TCLLIBPATH"):
374             self.environ["TCLLIBPATH"]=""
375         if not self.environ.has_key("TKLIBPATH"):
376             self.environ["TKLIBPATH"]=""
377
378         # four whitespaces for first indentation in a python script
379         self.indent="    "
380         self.prefix="context."
381         self.setVarEnv="setVariable"
382         
383         self.begin=self.indent+self.prefix
384         self.output.write(Launcher_header)
385         self.specialKeys={"PATH": "Path",
386                           "LD_LIBRARY_PATH": "LdLibraryPath",
387                           "PYTHONPATH": "PythonPath"}
388
389     def change_to_launcher(self, value):
390         """
391         """
392         res=value
393         return res
394
395     def add_line(self, number):
396         """Add some empty lines in the launcher file
397         
398         :param number int: the number of lines to add
399         """
400         self.output.write("\n" * number)
401
402     def add_echo(self, text):
403         """Add a comment
404         
405         :param text str: the comment to add
406         """
407         self.output.write('# %s"\n' % text)
408
409     def add_warning(self, warning):
410         """Add a warning
411         
412         :param text str: the warning to add
413         """
414         self.output.write('# "WARNING %s"\n' % warning)
415
416     def append_value(self, key, value, sep=":"):
417         '''append value to key using sep
418         
419         :param key str: the environment variable to append
420         :param value str: the value to append to key
421         :param sep str: the separator string
422         '''
423         if self.is_defined(key) :
424             self.add(key, value)
425         else :
426             self.set(key, value)
427
428     def append(self, key, value, sep=":"):
429         '''Same as append_value but the value argument can be a list
430         
431         :param key str: the environment variable to append
432         :param value str or list: the value(s) to append to key
433         :param sep str: the separator string
434         '''
435         if isinstance(value, list):
436             self.append_value(key, sep.join(value), sep)
437         else:
438             self.append_value(key, value, sep)
439
440     def prepend_value(self, key, value, sep=":"):
441         '''prepend value to key using sep
442         
443         :param key str: the environment variable to prepend
444         :param value str: the value to prepend to key
445         :param sep str: the separator string
446         '''
447         if self.is_defined(key) :
448             self.add(key, value)
449         else :
450             self.set(key, value)
451
452     def prepend(self, key, value, sep=":"):
453         '''Same as prepend_value but the value argument can be a list
454         
455         :param key str: the environment variable to prepend
456         :param value str or list: the value(s) to prepend to key
457         :param sep str: the separator string
458         '''
459         if isinstance(value, list):
460             self.prepend_value(key, sep.join(value), sep)
461         else:
462             self.prepend_value(key, value, sep)
463
464     def is_defined(self, key):
465         '''Check if the key exists in the environment
466         
467         :param key str: the environment variable to check
468         '''
469         return self.environ.has_key(key)
470
471     def get(self, key):
472         '''Get the value of the environment variable "key"
473         
474         :param key str: the environment variable
475         '''
476         return '${%s}' % key
477
478     def set(self, key, value):
479         '''Set the environment variable "key" to value "value"
480         
481         :param key str: the environment variable to set
482         :param value str: the value
483         '''
484         self.output.write(self.begin+self.setVarEnv+
485                           '(r"%s", r"%s", overwrite=True)\n' % 
486                           (key, self.change_to_launcher(value)))
487         self.environ[key] = value
488     
489     def add(self, key, value):
490         '''prepend value to key using sep
491         
492         :param key str: the environment variable to prepend
493         :param value str: the value to prepend to key
494         '''     
495         if key in self.specialKeys.keys():
496             self.output.write(self.begin+'addTo%s(r"%s")\n' % 
497                               (self.specialKeys[key],
498                                self.change_to_launcher(value)))
499             self.environ[key]+=":"+value
500             return
501         sep=special_path_separator(key)
502         self.output.write(self.indent+
503                           '#temporary solution!!! have to be defined in API a '
504                           '?dangerous? addToSpecial(r"%s", r"%s")\n' % 
505                           (key, value))
506         #pathsep not precised because do not know future os launch?
507         self.output.write(self.begin+'addToSpecial(r"%s", r"%s")\n' 
508                           % (key, self.change_to_launcher(value)))
509         self.environ[key]+=sep+value #here yes we know os for current execution
510
511     def command_value(self, key, command):
512         '''Get the value given by the system command "command" 
513            and put it in the environment variable key.
514         
515         :param key str: the environment variable
516         :param command str: the command to execute
517         '''
518         self.output.write(self.indent+'#`%s`\n' % command)
519
520         import shlex, subprocess
521         args = shlex.split(command)
522         res=subprocess.Popen(args, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
523         out, __ = res.communicate()
524         self.output.write(self.begin+
525                           self.setVarEnv+
526                           '(r"%s", r"%s", overwrite=True)\n' % (key, out))
527
528     def add_comment(self, comment):
529         # Special comment in case of the distène licence
530         if comment=="DISTENE license":
531             self.output.write(self.indent+
532                               "#"+
533                               self.prefix+
534                               self.setVarEnv+
535                               '(r"%s", r"%s", overwrite=True)\n' % 
536                               ('DISTENE_LICENSE_FILE', 
537                                self.change_to_launcher(
538                                             'Use global envvar: DLIM8VAR')))
539             self.output.write(self.indent+
540                               "#"+
541                               self.prefix+
542                               self.setVarEnv+
543                               '(r"%s", r"%s", overwrite=True)\n' % 
544                               ('DISTENE_LICENCE_FILE_FOR_MGCLEANER', 
545                                self.change_to_launcher(
546                                                 '<path to your license>')))
547             self.output.write(self.indent+
548                               "#"+
549                               self.prefix+
550                               self.setVarEnv+
551                               '(r"%s", r"%s", overwrite=True)\n' % 
552                               ('DISTENE_LICENCE_FILE_FOR_YAMS', 
553                                self.change_to_launcher(
554                                                     '<path to your license>')))
555             return
556         if "setting environ for" in comment:
557             self.output.write(self.indent+"#[%s]\n" % 
558                               comment.split("setting environ for ")[1])
559             return
560
561         self.output.write(self.indent+"# %s\n" % comment)
562
563     def finish(self, required=True):
564         """Add a final instruction in the out file (in case of file generation)
565            In the particular launcher case, do nothing
566         
567         :param required bool: Do nothing if required is False
568         """
569         return