Salome HOME
remove extra )
[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 bat_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=$(cd $(dirname ${BASH_SOURCE[0]});pwd)
71 export PRODUCT_OUT_DIR=${out_dir_Path}
72 export PRODUCT_ROOT_DIR=${PRODUCT_OUT_DIR}
73
74 ###########################################################################
75 """
76
77
78 Launcher_header='''# a generated SALOME Configuration file using python syntax
79 '''
80
81 def get_file_environ(output, shell, environ=None):
82     """Instantiate correct FileEnvironment sub-class.
83     
84     :param output file: the output file stream.
85     :param shell str: the type of shell syntax to use.
86     :param environ dict: a potential additional environment.
87     """
88     if shell == "bash":
89         return BashFileEnviron(output, environ)
90     if shell == "bat":
91         return BatFileEnviron(output, environ)
92     if shell == "cfgForPy":
93         return LauncherFileEnviron(output, environ)
94     raise Exception("FileEnviron: Unknown shell = %s" % shell)
95
96 class FileEnviron:
97     """Base class for shell environment
98     """
99     def __init__(self, output, environ=None):
100         """Initialization
101         
102         :param output file: the output file stream.
103         :param environ dict: a potential additional environment.
104         """
105         self._do_init(output, environ)
106
107     def _do_init(self, output, environ=None):
108         """Initialization
109         
110         :param output file: the output file stream.
111         :param environ dict: a potential additional environment.
112         """
113         self.output = output
114         self.toclean = []
115         if environ is not None:
116             self.environ = environ
117         else:
118             self.environ = os.environ
119
120     def add_line(self, number):
121         """Add some empty lines in the shell file
122         
123         :param number int: the number of lines to add
124         """
125         self.output.write("\n" * number)
126
127     def add_comment(self, comment):
128         """Add a comment in the shell file
129         
130         :param comment str: the comment to add
131         """
132         self.output.write("# %s\n" % comment)
133
134     def add_echo(self, text):
135         """Add a "echo" in the shell file
136         
137         :param text str: the text to echo
138         """
139         self.output.write('echo %s"\n' % text)
140
141     def add_warning(self, warning):
142         """Add a warning "echo" in the shell file
143         
144         :param warning str: the text to echo
145         """
146         self.output.write('echo "WARNING %s"\n' % warning)
147
148     def append_value(self, key, value, sep=os.pathsep):
149         '''append value to key using sep
150         
151         :param key str: the environment variable to append
152         :param value str: the value to append to key
153         :param sep str: the separator string
154         '''
155         self.set(key, self.get(key) + sep + value)
156         if (key, sep) not in self.toclean:
157             self.toclean.append((key, sep))
158
159     def append(self, key, value, sep=os.pathsep):
160         '''Same as append_value but the value argument can be a list
161         
162         :param key str: the environment variable to append
163         :param value str or list: the value(s) to append to key
164         :param sep str: the separator string
165         '''
166         if isinstance(value, list):
167             self.append_value(key, sep.join(value), sep)
168         else:
169             self.append_value(key, value, sep)
170
171     def prepend_value(self, key, value, sep=os.pathsep):
172         '''prepend value to key using sep
173         
174         :param key str: the environment variable to prepend
175         :param value str: the value to prepend to key
176         :param sep str: the separator string
177         '''
178         self.set(key, value + sep + self.get(key))
179         if (key, sep) not in self.toclean:
180             self.toclean.append((key, sep))
181
182     def prepend(self, key, value, sep=os.pathsep):
183         '''Same as prepend_value but the value argument can be a list
184         
185         :param key str: the environment variable to prepend
186         :param value str or list: the value(s) to prepend to key
187         :param sep str: the separator string
188         '''
189         if isinstance(value, list):
190             self.prepend_value(key, sep.join(value), sep)
191         else:
192             self.prepend_value(key, value, sep)
193
194     def is_defined(self, key):
195         '''Check if the key exists in the environment
196         
197         :param key str: the environment variable to check
198         '''
199         return (key in self.environ)
200
201     def set(self, key, value):
202         '''Set the environment variable "key" to value "value"
203         
204         :param key str: the environment variable to set
205         :param value str: the value
206         '''
207         raise NotImplementedError("set is not implement for this shell!")
208
209     def get(self, key):
210         '''Get the value of the environment variable "key"
211         
212         :param key str: the environment variable
213         '''
214         return '${%s}' % key
215
216     def command_value(self, key, command):
217         '''Get the value given by the system command "command" 
218            and put it in the environment variable key.
219            Has to be overwritten in the derived classes
220            This can be seen as a virtual method
221         
222         :param key str: the environment variable
223         :param command str: the command to execute
224         '''
225         raise NotImplementedError("command_value is not implement "
226                                   "for this shell!")
227
228     def finish(self, required=True):
229         """Add a final instruction in the out file (in case of file generation)
230         
231         :param required bool: Do nothing if required is False
232         """
233         for (key, sep) in self.toclean:
234             if sep != ' ':
235                 self.output.write('clean %s "%s"\n' % (key, sep))
236
237 class BashFileEnviron(FileEnviron):
238     """Class for bash shell.
239     """
240     def __init__(self, output, environ=None):
241         """Initialization
242         
243         :param output file: the output file stream.
244         :param environ dict: a potential additional environment.
245         """
246         self._do_init(output, environ)
247         self.output.write(bash_header)
248
249     def set(self, key, value):
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         self.output.write('export %s="%s"\n' % (key, value))
256         self.environ[key] = value
257
258     def command_value(self, key, command):
259         '''Get the value given by the system command "command" 
260            and put it in the environment variable key.
261            Has to be overwritten in the derived classes
262            This can be seen as a virtual method
263         
264         :param key str: the environment variable
265         :param command str: the command to execute
266         '''
267         self.output.write('export %s=$(%s)\n' % (key, command))
268
269     def finish(self, required=True):
270         """Add a final instruction in the out file (in case of file generation)
271         
272         :param required bool: Do nothing if required is False
273         """
274         if not required:
275             return
276         FileEnviron.finish(self, required)
277         
278 class BatFileEnviron(FileEnviron):
279     """for Windows batch shell.
280     """
281     def __init__(self, output, environ=None):
282         """Initialization
283         
284         :param output file: the output file stream.
285         :param environ dict: a potential additional environment.
286         """
287         self._do_init(output, environ)
288         self.output.write(bat_header)
289
290     def add_comment(self, comment):
291         """Add a comment in the shell file
292         
293         :param comment str: the comment to add
294         """
295         self.output.write("rem %s\n" % comment)
296     
297     def get(self, key):
298         '''Get the value of the environment variable "key"
299         
300         :param key str: the environment variable
301         '''
302         return '%%%s%%' % key
303     
304     def set(self, key, value):
305         '''Set the environment variable "key" to value "value"
306         
307         :param key str: the environment variable to set
308         :param value str: the value
309         '''
310         self.output.write('set %s=%s\n' % (key, value))
311         self.environ[key] = value
312
313     def command_value(self, key, command):
314         '''Get the value given by the system command "command" 
315            and put it in the environment variable key.
316            Has to be overwritten in the derived classes
317            This can be seen as a virtual method
318         
319         :param key str: the environment variable
320         :param command str: the command to execute
321         '''
322         self.output.write('%s > tmp.txt\n' % (command))
323         self.output.write('set /p %s =< tmp.txt\n' % (key))
324
325     def finish(self, required=True):
326         """Add a final instruction in the out file (in case of file generation)
327            In the particular windows case, do nothing
328         
329         :param required bool: Do nothing if required is False
330         """
331         return
332
333 def special_path_separator(name):
334     """TCLLIBPATH, TKLIBPATH, PV_PLUGIN_PATH environments variables need
335        some exotic path separator.
336        This function gives the separator regarding the name of the variable
337        to append or prepend.
338        
339     :param name str: The name of the variable to find the separator
340     """
341     special_blanks_keys=["TCLLIBPATH", "TKLIBPATH"]
342     special_semicolon_keys=["PV_PLUGIN_PATH"]
343     res=os.pathsep
344     if name in special_blanks_keys: res=" "
345     if name in special_semicolon_keys: res=";"
346     return res
347
348 class LauncherFileEnviron:
349     """Class to generate a launcher file script 
350        (in python syntax) SalomeContext API
351     """
352     def __init__(self, output, environ=None):
353         """Initialization
354         
355         :param output file: the output file stream.
356         :param environ dict: a potential additional environment.
357         """
358         self.output = output
359         self.toclean = []
360         if environ is not None:
361             self.environ = environ
362         else:
363             self.environ = os.environ
364         # Initialize some variables
365         if not "PATH" in self.environ.keys():
366             self.environ["PATH"]=""
367         if not "LD_LIBRARY_PATH" in self.environ.keys():
368             self.environ["LD_LIBRARY_PATH"]=""
369         if not "PYTHONPATH" in self.environ.keys():
370             self.environ["PYTHONPATH"]=""
371         if not "TCLLIBPATH" in self.environ.keys():
372             self.environ["TCLLIBPATH"]=""
373         if not "TKLIBPATH" in self.environ.keys():
374             self.environ["TKLIBPATH"]=""
375
376         # four whitespaces for first indentation in a python script
377         self.indent="    "
378         self.prefix="context."
379         self.setVarEnv="setVariable"
380         
381         self.begin=self.indent+self.prefix
382         self.output.write(Launcher_header)
383         self.specialKeys={"PATH": "Path",
384                           "LD_LIBRARY_PATH": "LdLibraryPath",
385                           "PYTHONPATH": "PythonPath"}
386
387     def change_to_launcher(self, value):
388         """
389         """
390         res=value
391         return res
392
393     def add_line(self, number):
394         """Add some empty lines in the launcher file
395         
396         :param number int: the number of lines to add
397         """
398         self.output.write("\n" * number)
399
400     def add_echo(self, text):
401         """Add a comment
402         
403         :param text str: the comment to add
404         """
405         self.output.write('# %s"\n' % text)
406
407     def add_warning(self, warning):
408         """Add a warning
409         
410         :param text str: the warning to add
411         """
412         self.output.write('# "WARNING %s"\n' % warning)
413
414     def append_value(self, key, value, sep=":"):
415         '''append value to key using sep
416         
417         :param key str: the environment variable to append
418         :param value str: the value to append to key
419         :param sep str: the separator string
420         '''
421         if self.is_defined(key) :
422             self.add(key, value)
423         else :
424             self.set(key, value)
425
426     def append(self, key, value, sep=":"):
427         '''Same as append_value but the value argument can be a list
428         
429         :param key str: the environment variable to append
430         :param value str or list: the value(s) to append to key
431         :param sep str: the separator string
432         '''
433         if isinstance(value, list):
434             self.append_value(key, sep.join(value), sep)
435         else:
436             self.append_value(key, value, sep)
437
438     def prepend_value(self, key, value, sep=":"):
439         '''prepend value to key using sep
440         
441         :param key str: the environment variable to prepend
442         :param value str: the value to prepend to key
443         :param sep str: the separator string
444         '''
445         if self.is_defined(key) :
446             self.add(key, value)
447         else :
448             self.set(key, value)
449
450     def prepend(self, key, value, sep=":"):
451         '''Same as prepend_value but the value argument can be a list
452         
453         :param key str: the environment variable to prepend
454         :param value str or list: the value(s) to prepend to key
455         :param sep str: the separator string
456         '''
457         if isinstance(value, list):
458             self.prepend_value(key, sep.join(value), sep)
459         else:
460             self.prepend_value(key, value, sep)
461
462     def is_defined(self, key):
463         '''Check if the key exists in the environment
464         
465         :param key str: the environment variable to check
466         '''
467         return key in self.environ.keys()
468
469     def get(self, key):
470         '''Get the value of the environment variable "key"
471         
472         :param key str: the environment variable
473         '''
474         return '${%s}' % key
475
476     def set(self, key, value):
477         '''Set the environment variable "key" to value "value"
478         
479         :param key str: the environment variable to set
480         :param value str: the value
481         '''
482         self.output.write(self.begin+self.setVarEnv+
483                           '(r"%s", r"%s", overwrite=True)\n' % 
484                           (key, self.change_to_launcher(value)))
485         self.environ[key] = value
486     
487     def add(self, key, value):
488         '''prepend value to key using sep
489         
490         :param key str: the environment variable to prepend
491         :param value str: the value to prepend to key
492         '''     
493         if key in self.specialKeys.keys():
494             self.output.write(self.begin+'addTo%s(r"%s")\n' % 
495                               (self.specialKeys[key],
496                                self.change_to_launcher(value)))
497             self.environ[key]+=":"+value
498             return
499         sep=special_path_separator(key)
500         self.output.write(self.indent+
501                           '#temporary solution!!! have to be defined in API a '
502                           '?dangerous? addToSpecial(r"%s", r"%s")\n' % 
503                           (key, value))
504         #pathsep not precised because do not know future os launch?
505         self.output.write(self.begin+'addToSpecial(r"%s", r"%s")\n' 
506                           % (key, self.change_to_launcher(value)))
507         self.environ[key]+=sep+value #here yes we know os for current execution
508
509     def command_value(self, key, command):
510         '''Get the value given by the system command "command" 
511            and put it in the environment variable key.
512         
513         :param key str: the environment variable
514         :param command str: the command to execute
515         '''
516         self.output.write(self.indent+'#`%s`\n' % command)
517
518         import shlex, subprocess
519         args = shlex.split(command)
520         res=subprocess.Popen(args, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
521         out, __ = res.communicate()
522         self.output.write(self.begin+
523                           self.setVarEnv+
524                           '(r"%s", r"%s", overwrite=True)\n' % (key, out))
525
526     def add_comment(self, comment):
527         # Special comment in case of the distène licence
528         if comment=="DISTENE license":
529             self.output.write(self.indent+
530                               "#"+
531                               self.prefix+
532                               self.setVarEnv+
533                               '(r"%s", r"%s", overwrite=True)\n' % 
534                               ('DISTENE_LICENSE_FILE', 
535                                self.change_to_launcher(
536                                             'Use global envvar: DLIM8VAR')))
537             self.output.write(self.indent+
538                               "#"+
539                               self.prefix+
540                               self.setVarEnv+
541                               '(r"%s", r"%s", overwrite=True)\n' % 
542                               ('DLIM8VAR', 
543                                self.change_to_launcher(
544                                                 '<your licence>')))
545             return
546         if "setting environ for" in comment:
547             self.output.write(self.indent+"#[%s]\n" % 
548                               comment.split("setting environ for ")[1])
549             return
550
551         self.output.write(self.indent+"# %s\n" % comment)
552
553     def finish(self, required=True):
554         """Add a final instruction in the out file (in case of file generation)
555            In the particular launcher case, do nothing
556         
557         :param required bool: Do nothing if required is False
558         """
559         return
560
561 class ScreenEnviron(FileEnviron):
562     def __init__(self, output, environ=None):
563         self._do_init(output, environ)
564         self.defined = {}
565
566     def add_line(self, number):
567         pass
568
569     def add_comment(self, comment):
570         pass
571
572     def add_echo(self, text):
573         pass
574
575     def add_warning(self, warning):
576         pass
577
578     def write(self, command, name, value, sign="="):
579         import src
580         self.output.write("  %s%s %s %s %s\n" % \
581             (src.printcolors.printcLabel(command),
582              " " * (12 - len(command)),
583              src.printcolors.printcInfo(name), sign, value))
584
585     def is_defined(self, name):
586         return self.defined.has_key(name)
587
588     def get(self, name):
589         return "${%s}" % name
590
591     def set(self, name, value):
592         self.write("set", name, value)
593         self.defined[name] = value
594
595     def prepend(self, name, value, sep=":"):
596         if isinstance(value, list):
597             value = sep.join(value)
598         value = value + sep + self.get(name)
599         self.write("prepend", name, value)
600
601     def append(self, name, value, sep=":"):
602         if isinstance(value, list):
603             value = sep.join(value)
604         value = self.get(name) + sep + value
605         self.write("append", name, value)
606
607     def command_value(self, key, command):
608         pass
609
610     def run_env_script(self, module, script):
611         self.write("load", script, "", sign="")
612
613 # The SALOME launcher template 
614 withProfile =  """#! /usr/bin/env python
615
616 ################################################################
617 # WARNING: this file is automatically generated by SalomeTools #
618 # WARNING: and so could be overwritten at any time.            #
619 ################################################################
620
621 import os
622 import sys
623
624
625 # Add the pwdPath to able to run the launcher after unpacking a package
626 # Used only in case of a salomeTools package
627 out_dir_Path=os.path.abspath(os.path.dirname(__file__))
628
629 # Preliminary work to initialize path to SALOME Python modules
630 def __initialize():
631
632   sys.path[:0] = [ os.path.join( 'PROFILE_INSTALL_DIR', 'bin', 'salome' ) ]
633   os.environ['ABSOLUTE_APPLI_PATH'] = 'PROFILE_INSTALL_DIR'
634   
635   # define folder to store omniorb config (initially in virtual application folder)
636   try:
637     from salomeContextUtils import setOmniOrbUserPath
638     setOmniOrbUserPath()
639   except Exception, e:
640     print e
641     sys.exit(1)
642 # End of preliminary work
643
644 def main(args):
645   # Identify application path then locate configuration files
646   __initialize()
647
648   if args == ['--help']:
649     from salomeContext import usage
650     usage()
651     sys.exit(0)
652
653   #from salomeContextUtils import getConfigFileNames
654   #configFileNames, args, unexisting = getConfigFileNames( args, checkExistence=True )
655   #if len(unexisting) > 0:
656   #  print "ERROR: unexisting configuration file(s): " + ', '.join(unexisting)
657   #  sys.exit(1)
658
659   # Create a SalomeContext which parses configFileNames to initialize environment
660   try:
661     from salomeContext import SalomeContext, SalomeContextException
662     SalomeContext.addToSpecial=addToSpecial
663     context = SalomeContext(None)
664     
665     # Here set specific variables, if needed
666     # context.addToPath('mypath')
667     # context.addToLdLibraryPath('myldlibrarypath')
668     # context.addToPythonPath('mypythonpath')
669     # context.setVariable('myvarname', 'value')
670
671     # Logger level error
672     context.getLogger().setLevel(40)
673
674     context.setVariable(r"PRODUCT_ROOT_DIR", out_dir_Path, overwrite=True)
675     # here your local standalone environment
676
677     # Start SALOME, parsing command line arguments
678     context.runSalome(args)
679     #print 'Thank you for using SALOME!'
680
681     # Logger level info
682     context.getLogger().setLevel(20)
683
684   except SalomeContextException, e:
685     import logging
686     logging.getLogger("salome").error(e)
687     sys.exit(1)
688 #
689 def addToSpecial(self, name, value, pathSep=None):
690   "add special dangerous cases: TCLLIBPATH PV_PLUGIN_PATH etc..."
691   #http://computer-programming-forum.com/57-tcl/1dfddc136afccb94.htm
692   #TCLLIBPATH: Tcl treats the contents of that variable as a list. Be happy, for you can now use drive letters on windows.
693   if value == '':
694     return
695   
696   specialBlanksKeys=["TCLLIBPATH", "TKLIBPATH"]
697   specialSemicolonKeys=["PV_PLUGIN_PATH"]
698   res=os.pathsep
699   if name in specialBlanksKeys: res=" "
700   if name in specialSemicolonKeys: res=";"
701   
702   if pathSep==None:
703     sep=res
704   else:
705     sep=pathSep
706   value = os.path.expandvars(value) # expand environment variables
707   self.getLogger().debug("Add to %s: %s", name, value)
708   env = os.getenv(name, None)
709   if env is None:
710     os.environ[name] = value
711   else:
712     os.environ[name] = value + sep + env #explicitely or not special path separator ?whitespace, semicolon?
713
714 if __name__ == "__main__":
715   args = sys.argv[1:]
716   main(args)
717 #
718 """
719