3 # Copyright (C) 2010-2013 CEA/DEN
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.
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.
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
21 import src.debug as DBG
22 import src.architecture
23 import src.environment
25 def get_file_environ(output, shell, environ=None):
26 """Instantiate correct FileEnvironment sub-class.
28 :param output file: the output file stream.
29 :param shell str: the type of shell syntax to use.
30 :param environ dict: a potential additional environment.
33 environ=src.environment.Environ({})
35 return BashFileEnviron(output, environ)
37 return BatFileEnviron(output, environ)
38 if shell == "cfgForPy":
39 return LauncherFileEnviron(output, environ)
41 return ContextFileEnviron(output, environ)
42 raise Exception("FileEnviron: Unknown shell = %s" % shell)
44 class FileEnviron(object):
46 Base class for shell environment
48 def __init__(self, output, environ=None):
52 :param output file: the output file stream.
53 :param environ dict: SalomeEnviron.
55 self._do_init(output, environ)
59 easy non exhaustive quick resume for debug print"""
61 "output" : self.output,
62 "environ" : self.environ,
64 return "%s(\n%s\n)" % (self.__class__.__name__, PP.pformat(res))
67 def _do_init(self, output, environ=None):
71 :param output file: the output file stream.
72 :param environ dict: a potential additional environment.
75 self.init_path=True # by default we initialise all paths, except PATH
76 if environ is not None:
77 self.environ = environ
79 self.environ = src.environment.Environ({})
81 def add_line(self, number):
83 Add some empty lines in the shell file
85 :param number int: the number of lines to add
87 self.output.write("\n" * number)
89 def add_comment(self, comment):
91 Add a comment in the shell file
93 :param comment str: the comment to add
95 self.output.write("# %s\n" % comment)
97 def add_echo(self, text):
99 Add a "echo" in the shell file
101 :param text str: the text to echo
103 self.output.write('echo %s"\n' % text)
105 def add_warning(self, warning):
107 Add a warning "echo" in the shell file
109 :param warning str: the text to echo
111 self.output.write('echo "WARNING %s"\n' % warning)
113 def append_value(self, key, value, sep=os.pathsep):
115 append value to key using sep,
116 if value contains ":" or ";" then raise error
118 :param key str: the environment variable to append
119 :param value str: the value to append to key
120 :param sep str: the separator string
122 # check that value so no contain the system separator
124 if separator in value:
125 raise Exception("FileEnviron append key '%s' value '%s' contains forbidden character '%s'" % (key, value, separator))
127 if self.environ.is_defined(key):
128 value_list = self.environ.get(key).split(sep)
129 if self.environ._expandvars(value) in value_list:
130 do_append=False # value is already in key path : we don't append it again
131 #print "\nCNC append_value value is already set!! key=%s, val=%s value_list=%s\n" % (key,self.environ._expandvars(value), value_list)
134 self.environ.append_value(key, value,sep)
135 self.set(key, self.get(key) + sep + value)
137 def append(self, key, value, sep=os.pathsep):
139 Same as append_value but the value argument can be a list
141 :param key str: the environment variable to append
142 :param value str or list: the value(s) to append to key
143 :param sep str: the separator string
145 if isinstance(value, list):
147 self.append_value(key, v, sep)
149 self.append_value(key, value, sep)
151 def prepend_value(self, key, value, sep=os.pathsep):
153 prepend value to key using sep,
154 if value contains ":" or ";" then raise error
156 :param key str: the environment variable to prepend
157 :param value str: the value to prepend to key
158 :param sep str: the separator string
160 # check that value so no contain the system separator
162 if separator in value:
163 raise Exception("FileEnviron append key '%s' value '%s' contains forbidden character '%s'" % (key, value, separator))
166 if self.environ.is_defined(key):
167 value_list = self.environ.get(key).split(sep)
168 exp_val=self.environ._expandvars(value)
169 if exp_val in value_list:
171 #print "\nCNC prepend_value value is already set!! key=%s, val=%s value_list=%s\n" % (key,exp_val, value_list)
172 if not do_not_prepend:
173 self.environ.prepend_value(key, value,sep)
174 self.set(key, value + sep + self.get(key))
176 def prepend(self, key, value, sep=os.pathsep):
178 Same as prepend_value but the value argument can be a list
180 :param key str: the environment variable to prepend
181 :param value str or list: the value(s) to prepend to key
182 :param sep str: the separator string
184 if isinstance(value, list):
185 for v in reversed(value): # prepend list, first item at last to stay first
186 self.prepend_value(key, v, sep)
188 self.prepend_value(key, value, sep)
190 def is_defined(self, key):
192 Check if the key exists in the environment
194 :param key str: the environment variable to check
196 return self.environ.is_defined(key)
198 def set(self, key, value):
200 Set the environment variable 'key' to value 'value'
202 :param key str: the environment variable to set
203 :param value str: the value
205 raise NotImplementedError("set is not implement for this shell!")
209 Get the value of the environment variable "key"
211 :param key str: the environment variable
215 def get_value(self, key):
216 """Get the real value of the environment variable "key"
217 It can help env scripts
218 :param key str: the environment variable
220 return self.environ.get_value(key)
223 """Add a final instruction in the out file (in case of file generation)
225 :param required bool: Do nothing if required is False
229 def set_no_init_path(self):
230 """Set the no initialisation mode for all paths.
231 By default only PATH is not reinitialised. All others paths are
232 (LD_LIBRARY_PATH, PYTHONPATH, ...)
233 After the call to these function ALL PATHS ARE NOT REINITIALISED.
234 There initial value is inherited from the environment
238 def value_filter(self, value):
240 # on windows platform, replace / by \
241 if src.architecture.is_windows():
242 res = value.replace("/","\\")
246 class BashFileEnviron(FileEnviron):
248 Class for bash shell.
250 def __init__(self, output, environ=None):
253 :param output file: the output file stream.
254 :param environ dict: a potential additional environment.
256 self._do_init(output, environ)
257 self.output.write(bash_header)
259 def set(self, key, value):
260 """Set the environment variable "key" to value "value"
262 :param key str: the environment variable to set
263 :param value str: the value
265 self.output.write('export %s="%s"\n' % (key, value))
266 self.environ.set(key, value)
270 class BatFileEnviron(FileEnviron):
272 for Windows batch shell.
274 def __init__(self, output, environ=None):
277 :param output file: the output file stream.
278 :param environ dict: a potential additional environment.
280 self._do_init(output, environ)
281 self.output.write(bat_header)
283 def add_comment(self, comment):
284 """Add a comment in the shell file
286 :param comment str: the comment to add
288 self.output.write("rem %s\n" % comment)
291 """Get the value of the environment variable "key"
293 :param key str: the environment variable
295 return '%%%s%%' % key
297 def set(self, key, value):
298 """Set the environment variable "key" to value "value"
300 :param key str: the environment variable to set
301 :param value str: the value
303 self.output.write('set %s=%s\n' % (key, self.value_filter(value)))
304 self.environ.set(key, value)
307 class ContextFileEnviron(FileEnviron):
308 """Class for a salome context configuration file.
310 def __init__(self, output, environ=None):
313 :param output file: the output file stream.
314 :param environ dict: a potential additional environment.
316 self._do_init(output, environ)
317 self.output.write(cfg_header)
319 def set(self, key, value):
320 """Set the environment variable "key" to value "value"
322 :param key str: the environment variable to set
323 :param value str: the value
325 self.output.write('%s="%s"\n' % (key, value))
326 self.environ.set(key, value)
329 """Get the value of the environment variable "key"
331 :param key str: the environment variable
333 return '%({0})s'.format(key)
335 def add_echo(self, text):
338 :param text str: the comment to add
340 self.add_comment(text)
342 def add_warning(self, warning):
345 :param text str: the warning to add
347 self.add_comment("WARNING %s" % warning)
349 def prepend_value(self, key, value, sep=os.pathsep):
350 """prepend value to key using sep
352 :param key str: the environment variable to prepend
353 :param value str: the value to prepend to key
354 :param sep str: the separator string
357 if self.environ.is_defined(key):
358 value_list = self.environ.get(key).split(sep)
359 #value cannot be expanded (unlike bash/bat case) - but it doesn't matter.
360 if value in value_list:
361 do_append=False # value is already in key path : we don't append it again
364 self.environ.append_value(key, value,sep)
365 self.output.write('ADD_TO_%s: %s\n' % (key, value))
367 def append_value(self, key, value, sep=os.pathsep):
368 """append value to key using sep
370 :param key str: the environment variable to append
371 :param value str: the value to append to key
372 :param sep str: the separator string
374 self.prepend_value(key, value)
377 class LauncherFileEnviron(FileEnviron):
379 Class to generate a launcher file script
380 (in python syntax) SalomeContext API
382 def __init__(self, output, environ=None):
385 :param output file: the output file stream.
386 :param environ dict: a potential additional environment.
388 self._do_init(output, environ)
389 self.python_version=self.environ.get("sat_python_version")
390 self.bin_kernel_root_dir=self.environ.get("sat_bin_kernel_install_dir")
391 self.app_root_dir=self.environ.get("sat_app_root_dir")
393 # four whitespaces for first indentation in a python script
395 self.prefix="context."
396 self.setVarEnv="setVariable"
397 self.begin=self.indent+self.prefix
399 # write the begining of launcher file.
400 # choose the template version corresponding to python version
401 # and substitute BIN_KERNEL_INSTALL_DIR (the path to salomeContext.py)
402 if self.python_version == 2:
403 launcher_header=launcher_header2
405 launcher_header=launcher_header3
406 self.output.write(launcher_header\
407 .replace("BIN_KERNEL_INSTALL_DIR", self.bin_kernel_root_dir))
409 # for these path, we use specialired functions in salomeContext api
410 self.specialKeys={"PATH": "Path",
411 "LD_LIBRARY_PATH": "LdLibraryPath",
412 "PYTHONPATH": "PythonPath"}
414 # we do not want to reinitialise PATH.
415 # for that we make sure PATH is in self.environ
416 # and therefore we will not use setVariable for PATH
417 if not self.environ.is_defined("PATH"):
418 self.environ.set("PATH","")
421 def add_echo(self, text):
424 :param text str: the comment to add
426 self.output.write('# %s"\n' % text)
428 def add_warning(self, warning):
431 :param text str: the warning to add
433 self.output.write('# "WARNING %s"\n' % warning)
435 def append_value(self, key, value, sep=":"):
436 """append value to key using sep,
437 if value contains ":" or ";" then raise error
439 :param key str: the environment variable to append
440 :param value str: the value to append to key
441 :param sep str: the separator string
443 # append is not defined in context api
444 self.prepend_value(key, value)
446 def append(self, key, value, sep=":"):
447 """Same as append_value but the value argument can be a list
449 :param key str: the environment variable to append
450 :param value str or list: the value(s) to append to key
451 :param sep str: the separator string
453 if isinstance(value, list):
455 self.append_value(key, v, sep)
457 self.append_value(key, value, sep)
459 def prepend_value(self, key, value, sep=os.pathsep):
460 """prepend value to key using sep,
461 if value contains ":" or ";" then raise error
463 :param key str: the environment variable to prepend
464 :param value str: the value to prepend to key
465 :param sep str: the separator string
467 # check that value so no contain the system separator
469 msg="LauncherFileEnviron append key '%s' value '%s' contains forbidden character '%s'"
470 if separator in value:
471 raise Exception(msg % (key, value, separator))
473 if (self.init_path and (not self.environ.is_defined(key))):
474 # reinitialisation mode set to true (the default)
475 # for the first occurrence of key, we set it.
476 # therefore key will not be inherited from environment
479 # in all other cases we use append (except if value is already the key
481 if self.environ.is_defined(key):
482 value_list = self.environ.get(key).split(sep)
483 # rem : value cannot be expanded (unlike bash/bat case) - but it doesn't matter.
484 if value in value_list:
485 do_append=False # value is already in key path : we don't append it again
488 self.environ.append_value(key, value,sep) # register value in self.environ
489 if key in self.specialKeys.keys():
490 #for these special keys we use the specific salomeContext function
491 self.output.write(self.begin+'addTo%s(r"%s")\n' %
492 (self.specialKeys[key], self.value_filter(value)))
494 # else we use the general salomeContext addToVariable function
495 self.output.write(self.begin+'addToVariable(r"%s", r"%s",separator="%s")\n'
496 % (key, self.value_filter(value), sep))
499 def prepend(self, key, value, sep=":"):
500 """Same as prepend_value but the value argument can be a list
502 :param key str: the environment variable to prepend
503 :param value str or list: the value(s) to prepend to key
504 :param sep str: the separator string
506 if isinstance(value, list):
508 self.prepend_value(key, v, sep)
510 self.prepend_value(key, value, sep)
513 def set(self, key, value):
514 """Set the environment variable "key" to value "value"
516 :param key str: the environment variable to set
517 :param value str: the value
519 self.output.write(self.begin+self.setVarEnv+
520 '(r"%s", r"%s", overwrite=True)\n' %
521 (key, self.value_filter(value)))
522 self.environ.set(key,value)
525 def add_comment(self, comment):
526 # Special comment in case of the distène licence
527 if comment=="DISTENE license":
528 self.output.write(self.indent+
532 '(r"%s", r"%s", overwrite=True)\n' %
533 ('DISTENE_LICENSE_FILE', 'Use global envvar: DLIM8VAR'))
534 self.output.write(self.indent+
538 '(r"%s", r"%s", overwrite=True)\n' %
539 ('DLIM8VAR', '<your licence>'))
541 if "setting environ for" in comment:
542 self.output.write(self.indent+"#[%s]\n" %
543 comment.split("setting environ for ")[1])
546 self.output.write(self.indent+"# %s\n" % comment)
550 Add a final instruction in the out file (in case of file generation)
551 In the particular launcher case, do nothing
553 :param required bool: Do nothing if required is False
555 if self.python_version == 2:
556 launcher_tail=launcher_tail_py2
558 launcher_tail=launcher_tail_py3
559 self.output.write(launcher_tail)
562 class ScreenEnviron(FileEnviron):
563 def __init__(self, output, environ=None):
564 self._do_init(output, environ)
567 def add_line(self, number):
570 def add_comment(self, comment):
573 def add_echo(self, text):
576 def add_warning(self, warning):
579 def write(self, command, name, value, sign="="):
581 self.output.write(" %s%s %s %s %s\n" % \
582 (src.printcolors.printcLabel(command),
583 " " * (12 - len(command)),
584 src.printcolors.printcInfo(name), sign, value))
586 def is_defined(self, name):
587 return name in self.defined
590 return "${%s}" % name
592 def set(self, name, value):
593 self.write("set", name, value)
594 self.defined[name] = value
596 def prepend(self, name, value, sep=":"):
597 if isinstance(value, list):
598 value = sep.join(value)
599 value = value + sep + self.get(name)
600 self.write("prepend", name, value)
602 def append(self, name, value, sep=":"):
603 if isinstance(value, list):
604 value = sep.join(value)
605 value = self.get(name) + sep + value
606 self.write("append", name, value)
608 def run_env_script(self, module, script):
609 self.write("load", script, "", sign="")
618 rem The following variables are used only in case of a sat package
619 set out_dir_Path=%~dp0
625 ##########################################################################
627 # This line is used only in case of a sat package
628 export out_dir_Path=$(cd $(dirname ${BASH_SOURCE[0]});pwd)
630 ###########################################################################
634 [SALOME Configuration]
637 launcher_header2="""\
638 #! /usr/bin/env python
640 ################################################################
641 # WARNING: this file is automatically generated by SalomeTools #
642 # WARNING: and so could be overwritten at any time. #
643 ################################################################
650 # Add the pwdPath to able to run the launcher after unpacking a package
651 # Used only in case of a salomeTools package
652 out_dir_Path=os.path.dirname(os.path.realpath(__file__))
654 # Preliminary work to initialize path to SALOME Python modules
657 sys.path[:0] = [ 'BIN_KERNEL_INSTALL_DIR' ] # to get salomeContext
659 # define folder to store omniorb config (initially in virtual application folder)
661 from salomeContextUtils import setOmniOrbUserPath
663 except Exception as e:
666 # End of preliminary work
668 # salome doc only works for virtual applications. Therefore we overwrite it with this function
669 def _showDoc(modules):
670 for module in modules:
671 modulePath = os.getenv(module+"_ROOT_DIR")
672 if modulePath != None:
673 baseDir = os.path.join(modulePath, "share", "doc", "salome")
674 docfile = os.path.join(baseDir, "gui", module.upper(), "index.html")
675 if not os.path.isfile(docfile):
676 docfile = os.path.join(baseDir, "tui", module.upper(), "index.html")
677 if not os.path.isfile(docfile):
678 docfile = os.path.join(baseDir, "dev", module.upper(), "index.html")
679 if os.path.isfile(docfile):
680 out, err = subprocess.Popen(["xdg-open", docfile]).communicate()
682 print "Online documentation is not accessible for module:", module
684 print module+"_ROOT_DIR not found!"
687 # Identify application path then locate configuration files
690 if args == ['--help']:
691 from salomeContext import usage
695 #from salomeContextUtils import getConfigFileNames
696 #configFileNames, args, unexisting = getConfigFileNames( args, checkExistence=True )
697 #if len(unexisting) > 0:
698 # print "ERROR: unexisting configuration file(s): " + ', '.join(unexisting)
701 # Create a SalomeContext which parses configFileNames to initialize environment
703 from salomeContext import SalomeContext, SalomeContextException
704 context = SalomeContext(None)
706 # Here set specific variables, if needed
707 # context.addToPath('mypath')
708 # context.addToLdLibraryPath('myldlibrarypath')
709 # context.addToPythonPath('mypythonpath')
710 # context.setVariable('myvarname', 'value')
713 context.getLogger().setLevel(40)
716 launcher_header3="""\
717 #! /usr/bin/env python3
719 ################################################################
720 # WARNING: this file is automatically generated by SalomeTools #
721 # WARNING: and so could be overwritten at any time. #
722 ################################################################
729 # Add the pwdPath to able to run the launcher after unpacking a package
730 # Used only in case of a salomeTools package
731 out_dir_Path=os.path.dirname(os.path.realpath(__file__))
733 # Preliminary work to initialize path to SALOME Python modules
736 sys.path[:0] = [ 'BIN_KERNEL_INSTALL_DIR' ]
738 # define folder to store omniorb config (initially in virtual application folder)
740 from salomeContextUtils import setOmniOrbUserPath
742 except Exception as e:
745 # End of preliminary work
747 # salome doc only works for virtual applications. Therefore we overwrite it with this function
748 def _showDoc(modules):
749 for module in modules:
750 modulePath = os.getenv(module+"_ROOT_DIR")
751 if modulePath != None:
752 baseDir = os.path.join(modulePath, "share", "doc", "salome")
753 docfile = os.path.join(baseDir, "gui", module.upper(), "index.html")
754 if not os.path.isfile(docfile):
755 docfile = os.path.join(baseDir, "tui", module.upper(), "index.html")
756 if not os.path.isfile(docfile):
757 docfile = os.path.join(baseDir, "dev", module.upper(), "index.html")
758 if os.path.isfile(docfile):
759 out, err = subprocess.Popen(["xdg-open", docfile]).communicate()
761 print("Online documentation is not accessible for module:", module)
763 print(module+"_ROOT_DIR not found!")
766 # Identify application path then locate configuration files
769 if args == ['--help']:
770 from salomeContext import usage
774 #from salomeContextUtils import getConfigFileNames
775 #configFileNames, args, unexisting = getConfigFileNames( args, checkExistence=True )
776 #if len(unexisting) > 0:
777 # print("ERROR: unexisting configuration file(s): " + ', '.join(unexisting))
780 # Create a SalomeContext which parses configFileNames to initialize environment
782 from salomeContext import SalomeContext, SalomeContextException
783 context = SalomeContext(None)
785 # Here set specific variables, if needed
786 # context.addToPath('mypath')
787 # context.addToLdLibraryPath('myldlibrarypath')
788 # context.addToPythonPath('mypythonpath')
789 # context.setVariable('myvarname', 'value')
792 context.getLogger().setLevel(40)
795 launcher_tail_py2="""\
796 if len(args) >1 and args[0]=='doc':
800 # Start SALOME, parsing command line arguments
801 out, err, status = context.runSalome(args)
804 except SalomeContextException, e:
806 logging.getLogger("salome").error(e)
810 if __name__ == "__main__":
816 launcher_tail_py3="""\
817 if len(args) >1 and args[0]=='doc':
821 # Start SALOME, parsing command line arguments
822 out, err, status = context.runSalome(args)
825 except SalomeContextException as e:
827 logging.getLogger("salome").error(e)
831 if __name__ == "__main__":