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 TclFileEnviron(output, environ)
39 return BatFileEnviron(output, environ)
40 if shell == "cfgForPy":
41 return LauncherFileEnviron(output, environ)
43 return ContextFileEnviron(output, environ)
44 raise Exception("FileEnviron: Unknown shell = %s" % shell)
46 class FileEnviron(object):
48 Base class for shell environment
50 def __init__(self, output, environ=None):
54 :param output file: the output file stream.
55 :param environ dict: SalomeEnviron.
57 self._do_init(output, environ)
61 easy non exhaustive quick resume for debug print"""
63 "output" : self.output,
64 "environ" : self.environ,
66 return "%s(\n%s\n)" % (self.__class__.__name__, PP.pformat(res))
69 def _do_init(self, output, environ=None):
73 :param output file: the output file stream.
74 :param environ dict: a potential additional environment.
77 self.init_path=True # by default we initialise all paths, except PATH
78 if environ is not None:
79 self.environ = environ
81 self.environ = src.environment.Environ({})
83 def add_line(self, number):
85 Add some empty lines in the shell file
87 :param number int: the number of lines to add
89 self.output.write("\n" * number)
91 def add_comment(self, comment):
93 Add a comment in the shell file
95 :param comment str: the comment to add
97 self.output.write("# %s\n" % comment)
99 def add_echo(self, text):
101 Add a "echo" in the shell file
103 :param text str: the text to echo
105 self.output.write('echo %s"\n' % text)
107 def add_warning(self, warning):
109 Add a warning "echo" in the shell file
111 :param warning str: the text to echo
113 self.output.write('echo "WARNING %s"\n' % warning)
115 def append_value(self, key, value, sep=os.pathsep):
117 append value to key using sep,
118 if value contains ":" or ";" then raise error
120 :param key str: the environment variable to append
121 :param value str: the value to append to key
122 :param sep str: the separator string
124 # check that value so no contain the system separator
126 if separator in value:
127 raise Exception("FileEnviron append key '%s' value '%s' contains forbidden character '%s'" % (key, value, separator))
129 if self.environ.is_defined(key):
130 value_list = self.environ.get(key).split(sep)
131 if self.environ._expandvars(value) in value_list:
132 do_append=False # value is already in key path : we don't append it again
135 self.environ.append_value(key, value,sep)
136 self.set(key, self.get(key) + sep + value)
138 def append(self, key, value, sep=os.pathsep):
140 Same as append_value but the value argument can be a list
142 :param key str: the environment variable to append
143 :param value str or list: the value(s) to append to key
144 :param sep str: the separator string
146 if isinstance(value, list):
148 self.append_value(key, v, sep)
150 self.append_value(key, value, sep)
152 def prepend_value(self, key, value, sep=os.pathsep):
154 prepend value to key using sep,
155 if value contains ":" or ";" then raise error
157 :param key str: the environment variable to prepend
158 :param value str: the value to prepend to key
159 :param sep str: the separator string
161 # check that value so no contain the system separator
163 if separator in value:
164 raise Exception("FileEnviron append key '%s' value '%s' contains forbidden character '%s'" % (key, value, separator))
167 if self.environ.is_defined(key):
168 value_list = self.environ.get(key).split(sep)
169 exp_val=self.environ._expandvars(value)
170 if exp_val in 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
213 if src.architecture.is_windows():
214 return '%' + key + '%'
218 def get_value(self, key):
219 """Get the real value of the environment variable "key"
220 It can help env scripts
221 :param key str: the environment variable
223 return self.environ.get_value(key)
226 """Add a final instruction in the out file (in case of file generation)
228 :param required bool: Do nothing if required is False
232 def set_no_init_path(self):
233 """Set the no initialisation mode for all paths.
234 By default only PATH is not reinitialised. All others paths are
235 (LD_LIBRARY_PATH, PYTHONPATH, ...)
236 After the call to these function ALL PATHS ARE NOT REINITIALISED.
237 There initial value is inherited from the environment
241 def value_filter(self, value):
243 # on windows platform, replace / by \
244 if src.architecture.is_windows():
245 res = value.replace("/","\\")
249 class TclFileEnviron(FileEnviron):
253 def __init__(self, output, environ=None):
256 :param output file: the output file stream.
257 :param environ dict: a potential additional environment.
259 self._do_init(output, environ)
260 self.output.write(tcl_header.replace("<module_name>",
261 self.environ.get("sat_product_name")))
262 self.output.write("\nset software %s\n" % self.environ.get("sat_product_name") )
263 self.output.write("set version %s\n" % self.environ.get("sat_product_version") )
264 root=os.path.join(self.environ.get("sat_product_base_path"),
266 self.environ.get("sat_product_base_name"),
269 self.output.write("set root %s\n" % root)
270 modules_to_load=self.environ.get("sat_product_load_depend")
271 if len(modules_to_load)>0:
272 # write module load commands for product dependencies
273 self.output.write("\n")
274 for module_to_load in modules_to_load.split(";"):
275 self.output.write(module_to_load+"\n")
277 def set(self, key, value):
278 """Set the environment variable "key" to value "value"
280 :param key str: the environment variable to set
281 :param value str: the value
283 self.output.write('setenv %s "%s"\n' % (key, value))
284 self.environ.set(key, value)
288 Get the value of the environment variable "key"
290 :param key str: the environment variable
292 return self.environ.get(key)
294 def append_value(self, key, value, sep=os.pathsep):
295 """append value to key using sep
297 :param key str: the environment variable to append
298 :param value str: the value to append to key
299 :param sep str: the separator string
302 self.output.write('append-path %s %s\n' % (key, value))
304 self.output.write('append-path --delim=\%c %s %s\n' % (sep, key, value))
306 def prepend_value(self, key, value, sep=os.pathsep):
307 """prepend value to key using sep
309 :param key str: the environment variable to prepend
310 :param value str: the value to prepend to key
311 :param sep str: the separator string
314 self.output.write('prepend-path %s %s\n' % (key, value))
316 self.output.write('prepend-path --delim=\%c %s %s\n' % (sep, key, value))
319 class BashFileEnviron(FileEnviron):
321 Class for bash shell.
323 def __init__(self, output, environ=None):
326 :param output file: the output file stream.
327 :param environ dict: a potential additional environment.
329 self._do_init(output, environ)
330 self.output.write(bash_header)
332 def set(self, key, value):
333 """Set the environment variable "key" to value "value"
335 :param key str: the environment variable to set
336 :param value str: the value
338 self.output.write('export %s="%s"\n' % (key, value))
339 self.environ.set(key, value)
343 class BatFileEnviron(FileEnviron):
345 for Windows batch shell.
347 def __init__(self, output, environ=None):
350 :param output file: the output file stream.
351 :param environ dict: a potential additional environment.
353 self._do_init(output, environ)
354 self.output.write(bat_header)
356 def add_comment(self, comment):
357 """Add a comment in the shell file
359 :param comment str: the comment to add
361 self.output.write("rem %s\n" % comment)
364 """Get the value of the environment variable "key"
366 :param key str: the environment variable
368 return '%%%s%%' % key
370 def set(self, key, value):
371 """Set the environment variable "key" to value "value"
373 :param key str: the environment variable to set
374 :param value str: the value
376 self.output.write('set %s=%s\n' % (key, self.value_filter(value)))
377 self.environ.set(key, value)
380 class ContextFileEnviron(FileEnviron):
381 """Class for a salome context configuration file.
383 def __init__(self, output, environ=None):
386 :param output file: the output file stream.
387 :param environ dict: a potential additional environment.
389 self._do_init(output, environ)
390 self.output.write(cfg_header)
392 def set(self, key, value):
393 """Set the environment variable "key" to value "value"
395 :param key str: the environment variable to set
396 :param value str: the value
398 self.output.write('%s="%s"\n' % (key, value))
399 self.environ.set(key, value)
402 """Get the value of the environment variable "key"
404 :param key str: the environment variable
406 return '%({0})s'.format(key)
408 def add_echo(self, text):
411 :param text str: the comment to add
413 self.add_comment(text)
415 def add_warning(self, warning):
418 :param text str: the warning to add
420 self.add_comment("WARNING %s" % warning)
422 def prepend_value(self, key, value, sep=os.pathsep):
423 """prepend value to key using sep
425 :param key str: the environment variable to prepend
426 :param value str: the value to prepend to key
427 :param sep str: the separator string
430 if self.environ.is_defined(key):
431 value_list = self.environ.get(key).split(sep)
432 #value cannot be expanded (unlike bash/bat case) - but it doesn't matter.
433 if value in value_list:
434 do_append=False # value is already in key path : we don't append it again
437 self.environ.append_value(key, value,sep)
438 self.output.write('ADD_TO_%s: %s\n' % (key, value))
440 def append_value(self, key, value, sep=os.pathsep):
441 """append value to key using sep
443 :param key str: the environment variable to append
444 :param value str: the value to append to key
445 :param sep str: the separator string
447 self.prepend_value(key, value)
450 class LauncherFileEnviron(FileEnviron):
452 Class to generate a launcher file script
453 (in python syntax) SalomeContext API
455 def __init__(self, output, environ=None):
458 :param output file: the output file stream.
459 :param environ dict: a potential additional environment.
461 self._do_init(output, environ)
462 self.python_version=self.environ.get("sat_python_version")
463 self.bin_kernel_root_dir=self.environ.get("sat_bin_kernel_install_dir")
464 self.app_root_dir=self.environ.get("sat_app_root_dir")
466 # four whitespaces for first indentation in a python script
468 self.prefix="context."
469 self.setVarEnv="setVariable"
470 self.begin=self.indent+self.prefix
472 # write the begining of launcher file.
473 # choose the template version corresponding to python version
474 # and substitute BIN_KERNEL_INSTALL_DIR (the path to salomeContext.py)
475 if self.python_version == 2:
476 launcher_header=launcher_header2
478 launcher_header=launcher_header3
479 self.output.write(launcher_header\
480 .replace("BIN_KERNEL_INSTALL_DIR", self.bin_kernel_root_dir))
482 # for these path, we use specialired functions in salomeContext api
483 self.specialKeys={"PATH": "Path",
484 "LD_LIBRARY_PATH": "LdLibraryPath",
485 "PYTHONPATH": "PythonPath"}
487 # we do not want to reinitialise PATH.
488 # for that we make sure PATH is in self.environ
489 # and therefore we will not use setVariable for PATH
490 if not self.environ.is_defined("PATH"):
491 self.environ.set("PATH","")
494 def add_echo(self, text):
497 :param text str: the comment to add
499 self.output.write('# %s"\n' % text)
501 def add_warning(self, warning):
504 :param text str: the warning to add
506 self.output.write('# "WARNING %s"\n' % warning)
508 def append_value(self, key, value, sep=os.pathsep):
509 """append value to key using sep,
510 if value contains ":" or ";" then raise error
512 :param key str: the environment variable to prepend
513 :param value str: the value to prepend to key
514 :param sep str: the separator string
516 # check that value so no contain the system separator
518 msg="LauncherFileEnviron append key '%s' value '%s' contains forbidden character '%s'"
519 if separator in value:
520 raise Exception(msg % (key, value, separator))
522 if (self.init_path and (not self.environ.is_defined(key))):
523 # reinitialisation mode set to true (the default)
524 # for the first occurrence of key, we set it.
525 # therefore key will not be inherited from environment
529 # in all other cases we use append (except if value is already the key
531 if self.environ.is_defined(key):
532 value_list = self.environ.get(key).split(sep)
533 # rem : value cannot be expanded (unlike bash/bat case) - but it doesn't matter.
534 if value in value_list:
535 do_append=False # value is already in key path : we don't append it again
538 self.environ.append_value(key, value,sep) # register value in self.environ
539 if key in self.specialKeys.keys():
540 #for these special keys we use the specific salomeContext function
541 self.output.write(self.begin+'addTo%s(r"%s")\n' %
542 (self.specialKeys[key], self.value_filter(value)))
544 # else we use the general salomeContext addToVariable function
545 self.output.write(self.indent+'appendPath(r"%s", r"%s",separator="%s")\n'
546 % (key, self.value_filter(value), sep))
548 def append(self, key, value, sep=":"):
549 """Same as append_value but the value argument can be a list
551 :param key str: the environment variable to append
552 :param value str or list: the value(s) to append to key
553 :param sep str: the separator string
555 if isinstance(value, list):
557 self.append_value(key, v, sep)
559 self.append_value(key, value, sep)
561 def prepend_value(self, key, value, sep=os.pathsep):
562 """prepend value to key using sep,
563 if value contains ":" or ";" then raise error
565 :param key str: the environment variable to prepend
566 :param value str: the value to prepend to key
567 :param sep str: the separator string
569 # check that value so no contain the system separator
571 msg="LauncherFileEnviron append key '%s' value '%s' contains forbidden character '%s'"
572 if separator in value:
573 raise Exception(msg % (key, value, separator))
575 if (self.init_path and (not self.environ.is_defined(key))):
576 # reinitialisation mode set to true (the default)
577 # for the first occurrence of key, we set it.
578 # therefore key will not be inherited from environment
581 # in all other cases we use append (except if value is already the key
583 if self.environ.is_defined(key):
584 value_list = self.environ.get(key).split(sep)
585 # rem : value cannot be expanded (unlike bash/bat case) - but it doesn't matter.
586 if value in value_list:
587 do_append=False # value is already in key path : we don't append it again
590 self.environ.append_value(key, value,sep) # register value in self.environ
591 if key in self.specialKeys.keys():
592 #for these special keys we use the specific salomeContext function
593 self.output.write(self.begin+'addTo%s(r"%s")\n' %
594 (self.specialKeys[key], self.value_filter(value)))
596 # else we use the general salomeContext addToVariable function
597 self.output.write(self.begin+'addToVariable(r"%s", r"%s",separator="%s")\n'
598 % (key, self.value_filter(value), sep))
601 def prepend(self, key, value, sep=":"):
602 """Same as prepend_value but the value argument can be a list
604 :param key str: the environment variable to prepend
605 :param value str or list: the value(s) to prepend to key
606 :param sep str: the separator string
608 if isinstance(value, list):
610 self.prepend_value(key, v, sep)
612 self.prepend_value(key, value, sep)
615 def set(self, key, value):
616 """Set the environment variable "key" to value "value"
618 :param key str: the environment variable to set
619 :param value str: the value
621 self.output.write(self.begin+self.setVarEnv+
622 '(r"%s", r"%s", overwrite=True)\n' %
623 (key, self.value_filter(value)))
624 self.environ.set(key,value)
627 def add_comment(self, comment):
628 # Special comment in case of the distène licence
629 if comment=="DISTENE license":
630 self.output.write(self.indent+
634 '(r"%s", r"%s", overwrite=True)\n' %
635 ('DISTENE_LICENSE_FILE', 'Use global envvar: DLIM8VAR'))
636 self.output.write(self.indent+
640 '(r"%s", r"%s", overwrite=True)\n' %
641 ('DLIM8VAR', '<your licence>'))
643 if "setting environ for" in comment:
644 self.output.write(self.indent+"#[%s]\n" %
645 comment.split("setting environ for ")[1])
648 self.output.write(self.indent+"# %s\n" % comment)
652 Add a final instruction in the out file (in case of file generation)
653 In the particular launcher case, do nothing
655 :param required bool: Do nothing if required is False
657 if self.python_version == 2:
658 launcher_tail=launcher_tail_py2
660 launcher_tail=launcher_tail_py3
661 self.output.write(launcher_tail)
664 class ScreenEnviron(FileEnviron):
665 def __init__(self, output, environ=None):
666 self._do_init(output, environ)
669 def add_line(self, number):
672 def add_comment(self, comment):
675 def add_echo(self, text):
678 def add_warning(self, warning):
681 def write(self, command, name, value, sign="="):
683 self.output.write(" %s%s %s %s %s\n" % \
684 (src.printcolors.printcLabel(command),
685 " " * (12 - len(command)),
686 src.printcolors.printcInfo(name), sign, value))
688 def is_defined(self, name):
689 return name in self.defined
692 return "${%s}" % name
694 def set(self, name, value):
695 self.write("set", name, value)
696 self.defined[name] = value
698 def prepend(self, name, value, sep=":"):
699 if isinstance(value, list):
700 value = sep.join(value)
701 value = value + sep + self.get(name)
702 self.write("prepend", name, value)
704 def append(self, name, value, sep=":"):
705 if isinstance(value, list):
706 value = sep.join(value)
707 value = self.get(name) + sep + value
708 self.write("append", name, value)
710 def run_env_script(self, module, script):
711 self.write("load", script, "", sign="")
720 rem The following variables are used only in case of a sat package
721 set out_dir_Path=%~dp0
727 # <module_name> module for use with 'environment-modules' package
733 ##########################################################################
735 # This line is used only in case of a sat package
736 export out_dir_Path=$(cd $(dirname ${BASH_SOURCE[0]});pwd)
738 ###########################################################################
742 [SALOME Configuration]
745 launcher_header2="""\
746 #! /usr/bin/env python
748 ################################################################
749 # WARNING: this file is automatically generated by SalomeTools #
750 # WARNING: and so could be overwritten at any time. #
751 ################################################################
758 # Add the pwdPath to able to run the launcher after unpacking a package
759 # Used only in case of a salomeTools package
760 out_dir_Path=os.path.dirname(os.path.realpath(__file__))
762 # Preliminary work to initialize path to SALOME Python modules
765 sys.path[:0] = [ 'BIN_KERNEL_INSTALL_DIR' ] # to get salomeContext
767 # define folder to store omniorb config (initially in virtual application folder)
769 from salomeContextUtils import setOmniOrbUserPath
771 except Exception as e:
774 # End of preliminary work
776 # salome doc only works for virtual applications. Therefore we overwrite it with this function
777 def _showDoc(modules):
778 for module in modules:
779 modulePath = os.getenv(module+"_ROOT_DIR")
780 if modulePath != None:
781 baseDir = os.path.join(modulePath, "share", "doc", "salome")
782 docfile = os.path.join(baseDir, "gui", module.upper(), "index.html")
783 if not os.path.isfile(docfile):
784 docfile = os.path.join(baseDir, "tui", module.upper(), "index.html")
785 if not os.path.isfile(docfile):
786 docfile = os.path.join(baseDir, "dev", module.upper(), "index.html")
787 if os.path.isfile(docfile):
788 out, err = subprocess.Popen(["xdg-open", docfile]).communicate()
790 print ("Online documentation is not accessible for module:", module)
792 print (module+"_ROOT_DIR not found!")
795 # Identify application path then locate configuration files
798 if args == ['--help']:
799 from salomeContext import usage
804 # Create a SalomeContext which parses configFileNames to initialize environment
806 from salomeContext import SalomeContext, SalomeContextException
807 context = SalomeContext(None)
809 # Here set specific variables, if needed
810 # context.addToPath('mypath')
811 # context.addToLdLibraryPath('myldlibrarypath')
812 # context.addToPythonPath('mypythonpath')
813 # context.setVariable('myvarname', 'value')
816 context.getLogger().setLevel(40)
819 launcher_header3="""\
820 #! /usr/bin/env python3
822 ################################################################
823 # WARNING: this file is automatically generated by SalomeTools #
824 # WARNING: and so could be overwritten at any time. #
825 ################################################################
832 # Add the pwdPath to able to run the launcher after unpacking a package
833 # Used only in case of a salomeTools package
834 out_dir_Path=os.path.dirname(os.path.realpath(__file__))
836 # Preliminary work to initialize path to SALOME Python modules
839 sys.path[:0] = [ 'BIN_KERNEL_INSTALL_DIR' ]
841 # define folder to store omniorb config (initially in virtual application folder)
843 from salomeContextUtils import setOmniOrbUserPath
845 except Exception as e:
848 # End of preliminary work
850 # salome doc only works for virtual applications. Therefore we overwrite it with this function
851 def _showDoc(modules):
852 for module in modules:
853 modulePath = os.getenv(module+"_ROOT_DIR")
854 if modulePath != None:
855 baseDir = os.path.join(modulePath, "share", "doc", "salome")
856 docfile = os.path.join(baseDir, "gui", module.upper(), "index.html")
857 if not os.path.isfile(docfile):
858 docfile = os.path.join(baseDir, "tui", module.upper(), "index.html")
859 if not os.path.isfile(docfile):
860 docfile = os.path.join(baseDir, "dev", module.upper(), "index.html")
861 if os.path.isfile(docfile):
862 out, err = subprocess.Popen(["xdg-open", docfile]).communicate()
864 print("Online documentation is not accessible for module:", module)
866 print(module+"_ROOT_DIR not found!")
869 # Identify application path then locate configuration files
872 if args == ['--help']:
873 from salomeContext import usage
877 #from salomeContextUtils import getConfigFileNames
878 #configFileNames, args, unexisting = getConfigFileNames( args, checkExistence=True )
879 #if len(unexisting) > 0:
880 # print("ERROR: unexisting configuration file(s): " + ', '.join(unexisting))
883 # Create a SalomeContext which parses configFileNames to initialize environment
885 from salomeContext import SalomeContext, SalomeContextException
886 context = SalomeContext(None)
888 # Here set specific variables, if needed
889 # context.addToPath('mypath')
890 # context.addToLdLibraryPath('myldlibrarypath')
891 # context.addToPythonPath('mypythonpath')
892 # context.setVariable('myvarname', 'value')
895 context.getLogger().setLevel(40)
898 launcher_tail_py2="""\
899 if len(args) >1 and args[0]=='doc':
903 # Start SALOME, parsing command line arguments
904 out, err, status = context.runSalome(args)
907 except SalomeContextException, e:
909 logging.getLogger("salome").error(e)
912 # salomeContext only prepend variables, we use our own appendPath when required
913 def appendPath(name, value, separator=os.pathsep):
917 value = os.path.expandvars(value) # expand environment variables
918 env = os.getenv(name, None)
920 os.environ[name] = value
922 os.environ[name] = env + separator + value
925 if __name__ == "__main__":
931 launcher_tail_py3="""\
932 if len(args) >1 and args[0]=='doc':
936 # Start SALOME, parsing command line arguments
937 out, err, status = context.runSalome(args)
940 except SalomeContextException as e:
942 logging.getLogger("salome").error(e)
945 # salomeContext only prepend variables, we use our own appendPath when required
946 def appendPath(name, value, separator=os.pathsep):
950 value = os.path.expandvars(value) # expand environment variables
951 env = os.getenv(name, None)
953 os.environ[name] = value
955 os.environ[name] = env + separator + value
958 if __name__ == "__main__":