Salome HOME
decrease verbosity of the launcher
[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=`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 == "bat":
93         return BatFileEnviron(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 BatFileEnviron(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(bat_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 "PATH" in self.environ.keys():
368             self.environ["PATH"]=""
369         if not "LD_LIBRARY_PATH" in self.environ.keys():
370             self.environ["LD_LIBRARY_PATH"]=""
371         if not "PYTHONPATH" in self.environ.keys():
372             self.environ["PYTHONPATH"]=""
373         if not "TCLLIBPATH" in self.environ.keys():
374             self.environ["TCLLIBPATH"]=""
375         if not "TKLIBPATH" in self.environ.keys():
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 key in self.environ.keys()
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
570
571 class ScreenEnviron(FileEnviron):
572     def __init__(self, output, environ=None):
573         self._do_init(output, environ)
574         self.defined = {}
575
576     def add_line(self, number):
577         pass
578
579     def add_comment(self, comment):
580         pass
581
582     def add_echo(self, text):
583         pass
584
585     def add_warning(self, warning):
586         pass
587
588     def write(self, command, name, value, sign="="):
589         import src
590         self.output.write("  %s%s %s %s %s\n" % \
591             (src.printcolors.printcLabel(command),
592              " " * (12 - len(command)),
593              src.printcolors.printcInfo(name), sign, value))
594
595     def is_defined(self, name):
596         return self.defined.has_key(name)
597
598     def get(self, name):
599         return "${%s}" % name
600
601     def set(self, name, value):
602         self.write("set", name, value)
603         self.defined[name] = value
604
605     def prepend(self, name, value, sep=":"):
606         if isinstance(value, list):
607             value = sep.join(value)
608         value = value + sep + self.get(name)
609         self.write("prepend", name, value)
610
611     def append(self, name, value, sep=":"):
612         if isinstance(value, list):
613             value = sep.join(value)
614         value = self.get(name) + sep + value
615         self.write("append", name, value)
616
617     def command_value(self, key, command):
618         pass
619
620     def run_env_script(self, module, script):
621         self.write("load", script, "", sign="")
622
623 # The SALOME launcher template 
624 withProfile =  """#! /usr/bin/env python
625
626 ################################################################
627 # WARNING: this file is automatically generated by SalomeTools #
628 # WARNING: and so could be overwritten at any time.            #
629 ################################################################
630
631 import os
632 import sys
633
634
635 # Add the pwdPath to able to run the launcher after unpacking a package
636 # Used only in case of a salomeTools package
637 out_dir_Path=os.path.abspath(os.path.dirname(__file__))
638
639 # Preliminary work to initialize path to SALOME Python modules
640 def __initialize():
641
642   sys.path[:0] = [ os.path.join( 'PROFILE_INSTALL_DIR', 'bin', 'salome' ) ]
643   os.environ['ABSOLUTE_APPLI_PATH'] = 'PROFILE_INSTALL_DIR'
644   
645   # define folder to store omniorb config (initially in virtual application folder)
646   try:
647     from salomeContextUtils import setOmniOrbUserPath
648     setOmniOrbUserPath()
649   except Exception, e:
650     print e
651     sys.exit(1)
652 # End of preliminary work
653
654 def main(args):
655   # Identify application path then locate configuration files
656   __initialize()
657
658   if args == ['--help']:
659     from salomeContext import usage
660     usage()
661     sys.exit(0)
662
663   #from salomeContextUtils import getConfigFileNames
664   #configFileNames, args, unexisting = getConfigFileNames( args, checkExistence=True )
665   #if len(unexisting) > 0:
666   #  print "ERROR: unexisting configuration file(s): " + ', '.join(unexisting)
667   #  sys.exit(1)
668
669   # Create a SalomeContext which parses configFileNames to initialize environment
670   try:
671     from salomeContext import SalomeContext, SalomeContextException
672     SalomeContext.addToSpecial=addToSpecial
673     context = SalomeContext(None)
674     
675     # Here set specific variables, if needed
676     # context.addToPath('mypath')
677     # context.addToLdLibraryPath('myldlibrarypath')
678     # context.addToPythonPath('mypythonpath')
679     # context.setVariable('myvarname', 'value')
680
681     # Logger level error
682     context.getLogger().setLevel(40)
683
684     context.setVariable(r"PRODUCT_ROOT_DIR", out_dir_Path, overwrite=True)
685     # here your local standalone environment
686
687     # Start SALOME, parsing command line arguments
688     context.runSalome(args)
689     #print 'Thank you for using SALOME!'
690
691     # Logger level info
692     context.getLogger().setLevel(20)
693
694   except SalomeContextException, e:
695     import logging
696     logging.getLogger("salome").error(e)
697     sys.exit(1)
698 #
699 def addToSpecial(self, name, value, pathSep=None):
700   "add special dangerous cases: TCLLIBPATH PV_PLUGIN_PATH etc..."
701   #http://computer-programming-forum.com/57-tcl/1dfddc136afccb94.htm
702   #TCLLIBPATH: Tcl treats the contents of that variable as a list. Be happy, for you can now use drive letters on windows.
703   if value == '':
704     return
705   
706   specialBlanksKeys=["TCLLIBPATH", "TKLIBPATH"]
707   specialSemicolonKeys=["PV_PLUGIN_PATH"]
708   res=os.pathsep
709   if name in specialBlanksKeys: res=" "
710   if name in specialSemicolonKeys: res=";"
711   
712   if pathSep==None:
713     sep=res
714   else:
715     sep=pathSep
716   value = os.path.expandvars(value) # expand environment variables
717   self.getLogger().debug("Add to %s: %s", name, value)
718   env = os.getenv(name, None)
719   if env is None:
720     os.environ[name] = value
721   else:
722     os.environ[name] = value + sep + env #explicitely or not special path separator ?whitespace, semicolon?
723
724 if __name__ == "__main__":
725   args = sys.argv[1:]
726   main(args)
727 #
728 """
729