Salome HOME
CMake: doing proper string comparison in IF clause
[modules/kernel.git] / bin / salomeRunner.py
index 7a884e2379a2aeb9f12f2281194ac1c814a2e38a..c80c4f3164b2ece36bd755f268562ff7c2da4a37 100644 (file)
@@ -11,14 +11,30 @@ import pickle
 import subprocess
 import platform
 
+from salomeLauncherUtils import SalomeRunnerException
+from salomeLauncherUtils import getScriptsAndArgs, formatScriptsAndArgs
 
-"""
-Define a specific exception class to manage exceptions related to SalomeRunner
-"""
-class SalomeRunnerException(Exception):
-  """Report error messages to the user interface of SalomeRunner."""
-#
+def usage():
+  #exeName = os.path.splitext(os.path.basename(__file__))[0]
 
+  msg = '''\
+Usage: salome [command] [options] [--config=file1,...,filen]
+
+Commands:
+    start         Launches SALOME virtual application [DEFAULT]
+    shell         Executes a script under SALOME application environment
+    connect       Connects a Python console to the active SALOME session
+    killall       Kill all SALOME running sessions
+    info          Display some information about SALOME
+    help          Show this message
+    coffee        Yes! SALOME can also make coffee!!"
+
+Use salome start --help or salome shell --help
+to show help on start and shell commands.
+'''
+
+  print msg
+#
 
 """
 The SalomeRunner class in an API to configure SALOME environment then
@@ -35,20 +51,25 @@ class SalomeRunner:
   to .cfg format before setting the environment.
   """
   def __init__(self, configFileNames=[]):
+    #it could be None explicitely (if user use multiples setEnviron...for standalone)
+    if configFileNames==None:
+       return
+
     if len(configFileNames) == 0:
       raise SalomeRunnerException("No configuration files given")
 
+    reserved=['PATH', 'LD_LIBRARY_PATH', 'PYTHONPATH', 'MANPATH', 'PV_PLUGIN_PATH']
     for filename in configFileNames:
       basename, extension = os.path.splitext(filename)
       if extension == ".cfg":
-        self.__setEnvironmentFromConfigFile(filename)
+        self.__setEnvironmentFromConfigFile(filename, reserved)
       elif extension == ".sh":
         #new convert procedures, temporary could be use not to be automatically deleted
-        temp = tempfile.NamedTemporaryFile(suffix='.cfg', delete=False)
-        #temp = tempfile.NamedTemporaryFile(suffix='.cfg')
+        #temp = tempfile.NamedTemporaryFile(suffix='.cfg', delete=False)
+        temp = tempfile.NamedTemporaryFile(suffix='.cfg')
         try:
-          convertEnvFileToConfigFile(filename, temp.name)
-          self.__setEnvironmentFromConfigFile(temp.name)
+          convertEnvFileToConfigFile(filename, temp.name, reserved)
+          self.__setEnvironmentFromConfigFile(temp.name, reserved)
         except ConfigParser.ParsingError, e:
           self.getLogger().warning("Invalid token found when parsing file: %s\n"%(filename))
           print e
@@ -70,28 +91,28 @@ class SalomeRunner:
 
   """Append value to PATH environment variable"""
   def addToPath(self, value):
-    self.__addToReserved('PATH', value)
+    self.addToEnviron('PATH', value)
   #
 
   """Append value to LD_LIBRARY_PATH environment variable"""
   def addToLdLibraryPath(self, value):
-    self.__addToReserved('LD_LIBRARY_PATH', value)
+    self.addToEnviron('LD_LIBRARY_PATH', value)
   #
 
   """Append value to PYTHONPATH environment variable"""
   def addToPythonPath(self, value):
-    self.__addToReserved('PYTHONPATH', value)
+    self.addToEnviron('PYTHONPATH', value)
   #
 
   """Set environment variable to value"""
   def setEnviron(self, name, value, overwrite=False):
     env = os.getenv(name, '')
     if env and not overwrite:
-      self.getLogger().warning("Environment variable already existing and not overwritten: %s", name)
+      self.getLogger().warning("Environment variable already existing (and not overwritten): %s=%s", name, value)
       return
 
     if env:
-      self.getLogger().info("Overwriting environment variable: %s", name)
+      self.getLogger().warning("Overwriting environment variable: %s=%s", name, value)
 
     value = os.path.expandvars(value) # expand environment variables
     self.getLogger().debug("Set environment variable: %s=%s", name, value)
@@ -104,30 +125,24 @@ class SalomeRunner:
       del os.environ[name]
   #
 
+  """Append value to environment variable"""
+  def addToEnviron(self, name, value, separator=os.pathsep):
+    if value == '':
+      return
+
+    value = os.path.expandvars(value) # expand environment variables
+    self.getLogger().debug("Add to %s: %s", name, value)
+    env = os.getenv(name, None)
+    if env is None:
+      os.environ[name] = value
+    else:
+      os.environ[name] = value + separator + env
+  #
+
   ###################################
   # This begins the private section #
   ###################################
 
-  def _usage(self, unused=[]):
-    exeName = os.path.splitext(os.path.basename(__file__))[0]
-
-    msg = '''\
-Usage: %s [command] [options] [--config=file1,...,filen]
-
-Commands:
-    start         Launches SALOME virtual application [DEFAULT]
-    shell         Executes a script under SALOME application environment
-    connect       Connects a Python console to the active SALOME session
-    killall       Kill all SALOME running sessions
-    info          Display some information about SALOME
-    help          Show this message
-    coffee        Yes! SALOME can also make coffee!!"\
-
-'''%exeName
-
-    print msg
-  #
-
   def __parseArguments(self, args):
     if len(args) == 0 or args[0].startswith("-"):
       return None, args
@@ -146,9 +161,8 @@ Commands:
       }
 
     if not command in availableCommands.keys():
-      self.getLogger().error("Unrecognized command: %s.", command)
-      self._usage()
-      sys.exit(1)
+      command = "start"
+      options = args
 
     return availableCommands[command], options
   #
@@ -164,25 +178,32 @@ Commands:
 
     if command is None:
       if args and args[0] in ["-h","--help","help"]:
-        self._usage()
+        usage()
         sys.exit(0)
       # try to default to "start" command
       command = "_runAppli"
 
     try:
-      getattr(self, command)(options) # run appropriate method
-    except AttributeError:
-      self.getLogger().error("Method %s is not implemented.", command)
+      res = getattr(self, command)(options) # run appropriate method
+      return res or (None, None)
+    except SystemExit, exc:
+      if exc==0:
+        sys.exit(0) #catch sys.exit(0) happy end no warning
+      if exc==1:
+        self.getLogger().warning("SystemExit 1 in method %s.", command)
       sys.exit(1)
-    except:
+    except StandardError:
       self.getLogger().error("Unexpected error:")
       import traceback
       traceback.print_exc()
       sys.exit(1)
+    except SalomeRunnerException, e:
+      self.getLogger().error(e)
+      sys.exit(1)
   #
 
-  def __setEnvironmentFromConfigFile(self, filename):
-    unsetVars, configVars, reservedDict = parseConfigFile(filename, reserved=['PATH', 'LD_LIBRARY_PATH', 'PYTHONPATH'])
+  def __setEnvironmentFromConfigFile(self, filename, reserved=[]):
+    unsetVars, configVars, reservedDict = parseConfigFile(filename, reserved)
 
     # unset variables
     for var in unsetVars:
@@ -192,7 +213,7 @@ Commands:
     for reserved in reservedDict:
       a = filter(None, reservedDict[reserved]) # remove empty elements
       reformattedVals = ':'.join(a)
-      self.__addToReserved(reserved, reformattedVals)
+      self.addToEnviron(reserved, reformattedVals)
       pass
 
     for key,val in configVars:
@@ -202,19 +223,6 @@ Commands:
     sys.path[:0] = os.getenv('PYTHONPATH','').split(':')
   #
 
-  def __addToReserved(self, name, value):
-    if value == '':
-      return
-
-    value = os.path.expandvars(value) # expand environment variables
-    self.getLogger().debug("Add to %s: %s", name, value)
-    env = os.getenv(name, None)
-    if env is None:
-      os.environ[name] = value
-    else:
-      os.environ[name] = value + os.pathsep + env
-  #
-
   def _runAppli(self, args=[]):
     # Initialize SALOME environment
     sys.argv = ['runSalome'] + args
@@ -233,17 +241,11 @@ Commands:
     import setenv
     setenv.main(True)
 
-    if args:
-      exe = args[0]
-      # if exe does not contain any slashes (/), search in PATH
-      # if exe contains slashes:
-      #    if exe begins with a slash, use this absolute path
-      #    else build absolute path relative to current working directory
-      if (os.sep in exe) and (exe[0] is not os.sep):
-        args[0] = os.getcwd() + os.sep + exe
-
-      proc = subprocess.Popen(args, shell=False, close_fds=True)
-      proc.wait()
+    scriptArgs = getScriptsAndArgs(args)
+    command = formatScriptsAndArgs(scriptArgs)
+    if command:
+      proc = subprocess.Popen(command, shell=True, close_fds=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
+      return proc.communicate()
     else:
       absoluteAppliPath = os.getenv('ABSOLUTE_APPLI_PATH','')
       cmd = ["/bin/bash",  "--rcfile", absoluteAppliPath + "/.bashrc" ]
@@ -262,7 +264,6 @@ Commands:
   #
 
   def _killAll(self, args=[]):
-    #self._runAppli(['-k'] + args)
     from killSalome import killAllPorts
     killAllPorts()
   #
@@ -272,6 +273,10 @@ Commands:
     self._runAppli(["--version"])
   #
 
+  def _usage(self, unused=[]):
+    usage()
+  #
+
   def _makeCoffee(self, args=[]):
     print "                        ("
     print "                          )     ("
@@ -314,6 +319,7 @@ Commands:
     if not hasattr(self, '_logger'):
       self._logger = logging.getLogger(__name__)
       #self._logger.setLevel(logging.DEBUG)
+      self._logger.setLevel(logging.ERROR)
     return self._logger;
   #
 
@@ -323,7 +329,11 @@ if __name__ == "__main__":
   if len(sys.argv) == 3:
     runner = pickle.loads(sys.argv[1])
     args = pickle.loads(sys.argv[2])
-    runner._getStarted(args)
+    (out, err) = runner._getStarted(args)
+    if out:
+      sys.stdout.write(out)
+    if err:
+      sys.stderr.write(err)
   else:
-    SalomeRunner()._usage()
+    usage()
 #