You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@gump.apache.org by st...@apache.org on 2004/10/26 08:48:15 UTC

svn commit: rev 55582 - in gump/trunk: . python/gump python/gump/commands python/gump/core python/gump/core/run python/gump/util python/gump/util/process

Author: stefano
Date: Mon Oct 25 23:48:14 2004
New Revision: 55582

Added:
   gump/trunk/gump.log.config
   gump/trunk/python/gump/commands/
   gump/trunk/python/gump/commands/__init__.py   (contents, props changed)
   gump/trunk/python/gump/commands/build.py
   gump/trunk/python/gump/commands/check.py
   gump/trunk/python/gump/commands/env.py
   gump/trunk/python/gump/util/locks.py
Modified:
   gump/trunk/   (props changed)
   gump/trunk/gump.py
   gump/trunk/python/gump/__init__.py
   gump/trunk/python/gump/core/config.py
   gump/trunk/python/gump/core/gumpinit.py
   gump/trunk/python/gump/core/run/gumpenv.py
   gump/trunk/python/gump/util/__init__.py
   gump/trunk/python/gump/util/process/command.py
   gump/trunk/python/gump/util/process/launcher.py
Log:
started the refactoring to unify gump into a single command line entry point with different subcomands (a-la svn or cvs)


Added: gump/trunk/gump.log.config
==============================================================================
--- (empty file)
+++ gump/trunk/gump.log.config	Mon Oct 25 23:48:14 2004
@@ -0,0 +1,25 @@
+[loggers]
+keys=root
+
+[handlers]
+keys=stdout
+
+[formatters]
+keys=simple
+
+[logger_root]
+level=INFO
+handlers=stdout
+propagate=1
+qualname=gump
+
+[handler_stdout]
+class=StreamHandler
+level=NOTSET
+formatter=simple
+args=(sys.stdout,)
+
+[formatter_simple]
+format=%(message)s
+datefmt=
+

Modified: gump/trunk/gump.py
==============================================================================
--- gump/trunk/gump.py	(original)
+++ gump/trunk/gump.py	Mon Oct 25 23:48:14 2004
@@ -1,321 +1,120 @@
-#!/usr/bin/env python
-
-#
-#   Copyright 2003-2004 The Apache Software Foundation
-#
-#   Licensed under the Apache License, Version 2.0 (the "License");
-#   you may not use this file except in compliance with the License.
-#   You may obtain a copy of the License at
-#
-#       http://www.apache.org/licenses/LICENSE-2.0
-#
-#   Unless required by applicable law or agreed to in writing, software
-#   distributed under the License is distributed on an "AS IS" BASIS,
-#   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-#   See the License for the specific language governing permissions and
-#   limitations under the License.
-#
-__revision__  = "$Rev$"
-__date__      = "$Date$"
-__copyright__ = "Copyright (c) 1999-2004 Apache Software Foundation"
-__license__   = "http://www.apache.org/licenses/LICENSE-2.0"
-
-"""
-
-  This is the commandline entrypoint into Python Gump,
-  for full integrations. See cron/gump.py for the same
-  but used *primarily* by nightly cron jobs.
-  
-  It updates Gump (from soruce control) to ensure it (itself) is 
-  latest, does some environment twiddling, and runs the
-  main gump/integration.py. Bit more twiddling with 
-  outputs afterwards...
-
-"""
-
-import os.path
-import os
-import sys
-import socket
-import time
-import signal
-import smtplib
-import StringIO
-from xml.dom import minidom
-
-GUMP_VERSION='2.1'
-
-def runCommand(command,args='',dir=None,outputFile=None):
-    """ Run a command, and check the result... """
-    
-    originalCWD=None
-    if dir:     
-        originalCWD=os.getcwd()
-        cwdpath=os.path.abspath(dir)
-        try:
-            if not os.path.exists(cwdpath): os.makedirs(dir)
-            os.chdir(cwdpath)
-        except Exception, details :
-            # Log the problem and re-raise
-            sys.stdout.write('Failed to create/change CWD [' + cwdpath + ']. Details: ' + str(details) + '\n')
-            return 0
-              
-    try:              
-        fullCommand = command + ' ' + args  
-        sys.stdout.write('\nExecuting: "' + fullCommand + '"')
-        if dir:
-            sys.stdout.write(' in directory "' + dir + '"\n')
-        else:
-            sys.stdout.write('\n')
-            
-        # Execute Command & Calculate Exit Code
-        systemReturn=os.system(fullCommand)
-        
-        if not os.name == 'dos' and not os.name == 'nt':
-            waitcode=systemReturn
-        
-            #
-            # The return code (from system = from wait) is (on Unix):
-            #
-            #    a 16 bit number
-            #    top byte    =    exit status
-            #    low byte    =    signal that killed it
-            #
-            exit_code=(((waitcode & 0xFF00) >> 8) & 0xFF)
-        
-        else:
-            exit_code=systemReturn
-    
-        if exit_code:
-            sys.stdout.write('Process Exit Code : ' + `exit_code` + '\n')
-    
-    finally:
-        if originalCWD: os.chdir(originalCWD)
-      
-    return exit_code
-
-#-----------------------------------------------------------------------# 
-
-def catFile(output,file,title=None):
-    """ Cat a file to a stream... """
-    if title:
-        output.write(title + ' ------------------------ \n\n')
-        
-    input=open(file,'r')
-    line = input.readline()
-    while line:
-        output.write(line)
-        line = input.readline()
-
+#!/usr/bin/env python
+
+#
+#   Copyright 2003-2004 The Apache Software Foundation
+#
+#   Licensed under the Apache License, Version 2.0 (the "License");
+#   you may not use this file except in compliance with the License.
+#   You may obtain a copy of the License at
+#
+#       http://www.apache.org/licenses/LICENSE-2.0
+#
+#   Unless required by applicable law or agreed to in writing, software
+#   distributed under the License is distributed on an "AS IS" BASIS,
+#   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+#   See the License for the specific language governing permissions and
+#   limitations under the License.
+#
+
+__revision__  = "$Rev$"
+__date__      = "$Date$"
+__copyright__ = "Copyright (c) 1999-2004 Apache Software Foundation"
+__license__   = "http://www.apache.org/licenses/LICENSE-2.0"
+
+import os,sys
+
 #-----------------------------------------------------------------------# 
-        
-def establishLock(lockFile):
-
-    failed=0
-    info=''
-    if 'posix'==os.name:
-        import fcntl
-                
-        try:            
-            lock=open(lockFile,'a+')
-            fcntl.flock(lock.fileno(), fcntl.LOCK_EX | fcntl.LOCK_NB)
-        except:            
-            failed=1
-            info=', and is locked.'
-        
-    else:
-        if os.path.exists(lockFile):
-            failed=1
-        
-        # Write this PID into a lock file
-        lock=open(lockFile,'w')
-            
-    if failed:
-        print """The lock file [%s] exists%s. 
-Either Gump is still running, or it terminated very abnormally.    
-Please resolve this (waiting or removing the lock file) before retrying.
-        """ % (lockFile, info)
-        sys.exit(1)
-    
-    # Leave a mark...
-    lock.write(`os.getpid()`)
-    lock.flush()
-        
-    return lock
 
+def main(argv):
+    """ Main program; prepare environment, parse options and go. """
+
+    # Ensure we have the right version of Python that is running us
+    (major, minor, micro, releaselevel, serial) = sys.version_info
+    if not major >=2 and minor >= 3:
+        print('Gump requires Python 2.3 or above. [' + sys.version() + ']')
+        sys.exit(-1)
+        
+    # If GUMP_HOME is set, move to the specified directory
+    gumpHome = os.getenv('GUMP_HOME')
+    if gumpHome: 
+        os.chdir(gumpHome)
+    else:
+        os.putenv('GUMP_HOME',os.getcwd())
+    
+    # Insert in the Python path the location of Gump's modules
+    # WARNING: since both this file and the package are named 'gump', 
+    #          it is critical that the Gump's module path is placed first in
+    #          the list, otherwise the modules are not found.
+    sys.path.insert(0,os.path.abspath(os.path.join(os.getcwd(),'./python')))
+    
+    # Now we can import the modules
+    from gump import log
+    from gump.util import banner
+    from gump.util import locks
+    from gump.util import getModule
+    from gump.core.gumpinit import gumpinit
+    from gump.core.run.gumpenv import GumpEnvironment
+    from gump import commands
+    
+    # Set the status result
+    result = 0
+    
+    # First of all, show who we are.
+    banner()
+    
+    # Establish a lock (program will exit here if the lock is already established)
+    lockfile = os.path.abspath('gump.lock')
+    lock = locks.establishLock(lockfile)
+    
+    # Initialize Gump
+    gumpinit()
+
+    # Process the command line
+    if (len(argv) == 1): 
+        print "Usage: python gump.py <command> [options] [arguments]"
+        print 
+        print "Available commands:"
+        for i,j in  enumerate(commands.__all__):
+            print "     " + j + " ~ " + getModule("gump.commands." + j).__description__
+        print
+        print "Type 'python gump.py help <command>' for help on a specific command."
+        print
+        print "Apache Gump is a continuous integration system."
+        print
+        print "For more information: http://gump.apache.org/"
+        print "For bug reports: http://issues.apache.org/"
+        print "For suggestions: <general@gump.apache.org/>"
+
+    elif (argv[1] == 'help'):
+        if (len(argv) > 2) and (argv[2] in commands.__all__):
+            print getModule("gump.commands." + argv[2]).__doc__
+        else:
+            print "Usage: python gump.py help <command>"
+            print
+            print "Available commands:"
+            for i,j in  enumerate(commands.__all__):
+                print "     " + j + " ~ " + getModule("gump.commands." + j).__description__
+            print
+
+    elif (argv[1] in commands.__all__):
+        options = []
+        arguments = []
+        for arg in argv:
+            if (arg[:1] == '='): 
+                options.append(arg[1:])
+            else:
+                arguments.append(arg)
+        command = getModule("gump.commands." + argv[1])
+        getattr(command, "process")(options,arguments)
+    
+    # Release the lock before terminating
+    locks.releaseLock(lock,lockfile) 
+
+    sys.exit(result)
+    
 #-----------------------------------------------------------------------# 
-        
-def releaseLock(lock,lockFile):
-      
-    if 'posix'==os.name:
-        import fcntl            
-        try:
-            fcntl.flock(lockFile.fileno(), fcntl.LOCK_UN)
-        except:
-            pass
-    
-    # Close it, so we can dispose of it
-    lock.close()    
-    
-    # Others might be blocked on this
-    try:
-        os.remove(lockFile)
-    except:
-        # Somehow another could delete this, even if locked...
-        pass
 
-#-----------------------------------------------------------------------# 
-
-def main():        
-
-    # Ensure we start in the correct directory, setting GUMP_HOME
-    gumpHome=os.path.abspath(os.getcwd())
-    os.environ['GUMP_HOME']=gumpHome     
-    os.chdir(gumpHome)
-    
-    # Allow a lock    
-    lockFile=os.path.abspath('gump.lock')
-    lock=establishLock(lockFile)        
-        
-    hostname='Unknown'
-    workspaceName='Unknown'
-
-    args = sys.argv
-    result = 0
-    svnExit = -1
-    cvsExit = -1
-    integrationExit = -1
-            
-    try:
-    
-        try:
-            
-            # Process Environment
-            hostname = socket.gethostname()
-    
-            sys.stdout.write('\n - Host       : ' + hostname + '\n')
-            sys.stdout.write(' - Time       : ' + time.strftime('%d %b %Y %H:%M:%S', time.localtime()) + '\n')
-            sys.stdout.write(' - OS         : ' + `os.name` + '\n')
-            sys.stdout.write(' - Python     : ' + sys.version + '\n[' + sys.executable + ']\n')
-            
-            #sys.stdout.write('- GUMP run in env    : \n')        
-            #for envkey in os.environ.keys():
-            #    envval=os.environ[envkey]
-            #    sys.stdout.write('      ' + envkey + ' -> [' + envval + ']\n')
-            
-            # Workspace is the hostname, unless overridden
-            workspaceName = 'metadata/' + hostname + '.xml'
-            if len(args)>2 and args[1] in ['-w','--workspace']:
-                workspaceName=args[2]
-                del args[1:3]     
-            workspacePath = os.path.abspath(workspaceName)
-                
-            projectsExpr='all'
-            if len(args)>1:
-                projectsExpr=args[1]
-                del args[1:2]      
-                
-            # Check version information
-            (major, minor, micro, releaselevel, serial) = sys.version_info
-            if not major >=2 and minor >= 3:
-                raise RuntimeError('Gump requires Python 2.3 or above. [' + sys.version() + ']')
-                
-            # Nope, can't find the workspace...
-            if not os.path.exists(workspacePath):
-                raise RuntimeError('No such workspace at ' + str(workspacePath))
-       
-            # Add Gump to Python Path...
-            pythonPath=''
-            if os.environ.has_key('PYTHONPATH'):
-                pythonPath=os.environ['PYTHONPATH']
-                pythonPath+=os.pathsep
-            pythonDir=str(os.path.abspath(os.path.join(os.getcwd(),'python')))
-            pythonPath+=pythonDir
-            sys.stdout.write(' - PYTHONPATH : ' + pythonPath + '\n')
-            os.environ['PYTHONPATH']=pythonPath
-
-            sys.stdout.write('\n')
-                        
-            # Wipe all *.pyc from the pythonPath (so we don't
-            # have old code lying around as compiled zombies)
-            for root, dirs, files in os.walk(pythonDir):
-                for name in files:
-                    if name.endswith('.pyc'):
-                        fullname=os.path.join(root, name)
-                        # sys.stdout.write('- Remove PYC : ' + fullname + '\n')    
-                        os.remove(fullname)       
-            
-            # Update Gump code from SVN
-            if not os.environ.has_key('GUMP_NO_SVN_UPDATE') and \
-                not os.environ.has_key('GUMP_NO_SCM_UPDATE'):
-                svnExit = runCommand('svn','update --non-interactive')
-            else:
-                sys.stdout.write('SVN update skipped per environment setting.\n')
-                svnExit=0
-            if svnExit:
-                result=1     
-            
-            if not result:
-                # Update Gump metadata from CVS
-                if not os.environ.has_key('GUMP_NO_CVS_UPDATE') and \
-                    not os.environ.has_key('GUMP_NO_SCM_UPDATE'):
-                    cvsroot=':pserver:anoncvs@cvs.apache.org:/home/cvspublic'
-                    os.environ['CVSROOT']=cvsroot
-                    # :TODO: ??? delete os.environ['CVS_RSH']
-                    cvsExit = runCommand('cvs','-q update -dP','metadata')
-                else:
-                    sys.stdout.write('CVS update skipped per environment setting.\n')
-                    cvsExit=0
-                if cvsExit:
-                    result=1
-                
-            # :TODO: Need to remove all *.pyc (other than this one)
-            # because a Gump refactor can leave old/stale compiled
-            # classes around.
-                
-            # :TODO: Is this a CVS thing, or a Gump historical thing?
-            if os.path.exists('.timestamp'): 
-                os.remove('.timestamp')            
-        
-            if not result:
-                # Process/build command line
-                iargs = '-w ' + workspaceName + ' ' + projectsExpr + ' ' + ' '.join(args[1:])
-                
-                # Allow a check not an integrate
-                check=0
-                if '--check' in args:
-                    check=0
-                
-                #
-                # Run the main Gump...
-                #    
-                command='bin/integrate.py'
-                if check:
-                    command='bin/check.py'
-                integrationExit = runCommand(sys.executable+ ' '+command, iargs)
-                if integrationExit:
-                    result=1
-    
-        except KeyboardInterrupt:    
-            sys.stdout.write('Terminated by user interrupt...\n')
-            result = 1
-            raise
-            
-        except:    
-            sys.stdout.write('Terminated unintentionally...\n')
-            result = 1
-            raise
-        
-    finally:
-     
-        releaseLock(lock,lockFile) 
-           
-    return result
-
-#-----------------------------------------------------------------------# 
-
 if __name__ == "__main__":
-    sys.exit(main())
+    main(sys.argv)
 
-#---------------------------- End of File ------------------------------# 
-    
+#---------------------------- End of File ------------------------------#
\ No newline at end of file

Modified: gump/trunk/python/gump/__init__.py
==============================================================================
--- gump/trunk/python/gump/__init__.py	(original)
+++ gump/trunk/python/gump/__init__.py	Mon Oct 25 23:48:14 2004
@@ -23,23 +23,12 @@
 # $Header: /home/stefano/cvs/gump/python/gump/__init__.py,v 1.25 2004/07/19 16:07:53 ajack Exp $
 # 
 
-"""
-
-  Gump Basic Interfaces
-  
-"""
-
 # Either python-2.3 [or http://www.red-dove.com/python_logging.html]
 import logging
+import logging.config
 
-# init logging
-logging.basicConfig()
+# configure the logger
+logging.config.fileConfig("gump.log.config")
 
 # base gump logger
-log = logging.getLogger(__name__)
-
-#set verbosity to show all messages of severity >= default.logLevel
-log.setLevel(logging.INFO) # logging.DEBUG
-
-
-# tell Python what modules make up the gump packag
\ No newline at end of file
+log = logging.getLogger("root")

Added: gump/trunk/python/gump/commands/__init__.py
==============================================================================
--- (empty file)
+++ gump/trunk/python/gump/commands/__init__.py	Mon Oct 25 23:48:14 2004
@@ -0,0 +1,24 @@
+#!/usr/bin/env python
+
+# Copyright 2003-2004 The Apache Software Foundation
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+# 
+#     http://www.apache.org/licenses/LICENSE-2.0
+# 
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+__revision__  = "$Rev: 36667 $"
+__date__      = "$Date: 2004-08-20 08:55:45 -0600 (Fri, 20 Aug 2004) $"
+__copyright__ = "Copyright (c) 1999-2004 Apache Software Foundation"
+__license__   = "http://www.apache.org/licenses/LICENSE-2.0"
+
+# tell Python what modules make up this package
+# NOTE: this is used by the command line processing routines so keep it up to date!
+__all__ = ["env","build","check"]
\ No newline at end of file

Added: gump/trunk/python/gump/commands/build.py
==============================================================================
--- (empty file)
+++ gump/trunk/python/gump/commands/build.py	Mon Oct 25 23:48:14 2004
@@ -0,0 +1,54 @@
+#!/usr/bin/python
+
+# Copyright 2003-2004 The Apache Software Foundation
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+# 
+#     http://www.apache.org/licenses/LICENSE-2.0
+# 
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+"""
+usage: build [options] [project]
+
+  Perform an integration build.
+
+Valid options:
+  [TODO]  
+"""
+
+__description__ = "Perform an integration build"
+
+__revision__  = "$Rev: 54600 $"
+__date__      = "$Date: 2004-10-11 12:50:02 -0400 (Mon, 11 Oct 2004) $"
+__copyright__ = "Copyright (c) 1999-2004 Apache Software Foundation"
+__license__   = "http://www.apache.org/licenses/LICENSE-2.0"
+
+import gump.core.run.gumprun
+import gump.core.run.options
+from gump.core.runner.runner import getRunner
+from gump.core.loader.loader import WorkspaceLoader
+
+def process(options,arguments):    
+
+    # get parsed workspace definition
+    workspace = WorkspaceLoader(options.isCache()).load(ws)    
+        
+    # Ensure we use text, not xdocs...
+    options.setText(True)
+    
+    # Set objectives
+    options.setObjectives(options.OBJECTIVE_BUILD)
+    
+    # The Run Details...
+    run = gumprun.GumpRun(workspace,ps,options)
+        
+    # Perform this integration run...
+    return getRunner(run).perform()
+    
\ No newline at end of file

Added: gump/trunk/python/gump/commands/check.py
==============================================================================
--- (empty file)
+++ gump/trunk/python/gump/commands/check.py	Mon Oct 25 23:48:14 2004
@@ -0,0 +1,52 @@
+#!/usr/bin/python
+
+# Copyright 2003-2004 The Apache Software Foundation
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+# 
+#     http://www.apache.org/licenses/LICENSE-2.0
+# 
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+"""
+usage: build [options] [project]
+
+  Perform the integration build.
+
+Valid options:
+  [TODO]  
+"""
+
+__description__ = "Check the integration"
+
+__revision__  = "$Rev: 54600 $"
+__date__      = "$Date: 2004-10-11 12:50:02 -0400 (Mon, 11 Oct 2004) $"
+__copyright__ = "Copyright (c) 1999-2004 Apache Software Foundation"
+__license__   = "http://www.apache.org/licenses/LICENSE-2.0"
+
+
+import gump.core.run.gumprun
+import gump.core.run.options
+from gump.core.runner.runner import getRunner
+from gump.core.loader.loader import WorkspaceLoader
+
+def process(options,arguments):    
+
+    # get parsed workspace definition
+    workspace = WorkspaceLoader(options.isQuick()).load(ws)    
+        
+    # Set objectives
+    options.setObjectives(options.OBJECTIVE_CHECK)
+    
+    # The Run Details...
+    run = gumprun.GumpRun(workspace,ps,options)
+        
+    # Perform this integration run...
+    return getRunner(run).perform()
+    
\ No newline at end of file

Added: gump/trunk/python/gump/commands/env.py
==============================================================================
--- (empty file)
+++ gump/trunk/python/gump/commands/env.py	Mon Oct 25 23:48:14 2004
@@ -0,0 +1,39 @@
+#!/usr/bin/python
+
+# Copyright 2003-2004 The Apache Software Foundation
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+# 
+#     http://www.apache.org/licenses/LICENSE-2.0
+# 
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+"""
+usage: env
+
+  Checks the Gump environment for the presence of the programs
+  required for Gump to perform its operations.
+
+Valid options:
+  [none]
+"""
+
+__description__ = "Checks the Gump environment"
+
+__revision__  = "$Rev: 54600 $"
+__date__      = "$Date: 2004-10-11 12:50:02 -0400 (Mon, 11 Oct 2004) $"
+__copyright__ = "Copyright (c) 1999-2004 Apache Software Foundation"
+__license__   = "http://www.apache.org/licenses/LICENSE-2.0"
+
+from gump.core.run.gumpenv import GumpEnvironment
+
+def process(options,arguments):
+    env = GumpEnvironment()
+    env.checkEnvironment()
+    env.getJavaProperties()

Modified: gump/trunk/python/gump/core/config.py
==============================================================================
--- gump/trunk/python/gump/core/config.py	(original)
+++ gump/trunk/python/gump/core/config.py	Mon Oct 25 23:48:14 2004
@@ -36,8 +36,7 @@
 class dir:
     """Configuration of paths"""
 
-    cmdpath   = os.path.abspath(sys.argv[0])
-    base      = os.path.abspath(os.path.join(os.path.dirname(cmdpath),'..'))  
+    base      = os.path.abspath(os.getcwd())  
     
     cache     = os.path.abspath(os.path.join(base,'cache'))
     work      = os.path.abspath(os.path.join(base,'work'))
@@ -54,7 +53,7 @@
 class setting:    
     """Configuration of hardcoded settings"""
     
-    VERSION='2.1.0-alpha-0003'
+    VERSION='2.2'
     
     WS_VERSION="0.4"
     WS_MINIMUM_VERSION="0.3"
@@ -75,12 +74,12 @@
 class default:
     """Configuration of default settings"""
     
-    gumpfullhost   = socket.gethostname()   
-    gumphost   = socket.gethostname().split('.')[0]
-    gumpid	   = os.getpid()    
-    workspace  = os.path.abspath('%s/%s.xml' % (dir.base, gumphost))
-    globalws   = os.path.abspath('%s/%s' % (dir.base, 'global-workspace.xml'))
-    merge      = os.path.abspath('%s/%s' % (dir.work, 'merge.xml'))
+    gumpfullhost = socket.gethostname()   
+    gumphost     = socket.gethostname().split('.')[0]
+    gumpid       = os.getpid()    
+    workspace    = os.path.abspath('%s/%s.xml' % (dir.base, gumphost))
+    globalws     = os.path.abspath('%s/%s' % (dir.base, 'global-workspace.xml'))
+    merge        = os.path.abspath('%s/%s' % (dir.work, 'merge.xml'))
     
     # Note, these can be updated by gumpinit
     timestamp    = time.time()
@@ -88,11 +87,10 @@
     datetime_str = datetime.strftime(setting.DATETIME_FORMAT)
     date_str     = datetime.strftime(setting.DATE_FORMAT)
     
-    logLevel   = logging.INFO # logging.DEBUG
-    classpath = (os.getenv('CLASSPATH') or '').split(os.pathsep)  
+    logLevel     = logging.INFO # logging.DEBUG
+    classpath    = (os.getenv('CLASSPATH') or '').split(os.pathsep)  
     
-    logurl		=	'http://cvs.apache.org/builds/gump/nightly/'
-    bannerimage = 'http://gump.apache.org/images/gump-logo.gif'
+    bannerimage  = 'http://gump.apache.org/images/gump-logo.png'
     
     email = 'gump@' + gumpfullhost
     administrator = 'general@gump.apache.org'
@@ -102,7 +100,6 @@
     signature="\r\n--\r\nApache Gump\nhttp://gump.apache.org/ " \
         + '[Instance: ' + gumpfullhost + "]\n"
         
-        
     # Information for portability
     if not os.name == 'dos' and not os.name == 'nt':
         classpathSeparator=':'
@@ -113,12 +110,11 @@
         shellQuote='"'
         shellEscape='\\'
 
-    
 class switch:
     """Configuration of switches """   
-    optimize=False # Optimize (at risk to exact correctness) anywhere one can
-    optimizenetwork=False # Do least network traffic 
-    debugging=False # Not debugging..
+    optimize        = False # Optimize (at risk to exact correctness) anywhere one can
+    optimizenetwork = False # Do least network traffic 
+    debugging       = False # Not debugging..
     
 def basicConfig():
     if not os.path.exists(dir.cache): os.mkdir(dir.cache)

Modified: gump/trunk/python/gump/core/gumpinit.py
==============================================================================
--- gump/trunk/python/gump/core/gumpinit.py	(original)
+++ gump/trunk/python/gump/core/gumpinit.py	Mon Oct 25 23:48:14 2004
@@ -57,18 +57,19 @@
     initializeGarbageCollection()
     
     # If a .timestamp exists, use it.
-    timestamp=os.path.join(dir.base,'.timestamp')
+    timestamp = os.path.join(dir.base,'.timestamp')
     if os.path.exists(timestamp):
         default.timestamp = os.path.getmtime(timestamp)
     else:
         default.timestamp = time.time()
+
     # Import this timestamp
     default.datetime   = datetime.datetime.fromtimestamp(default.timestamp)
     default.datetime_s = default.datetime.strftime(setting.DATETIME_FORMAT)
     default.date_s     = default.datetime.strftime(setting.DATE_FORMAT)
     default.datetime_sp= default.datetime.strftime(setting.DATETIME_PRESENTATION_FORMAT)
     default.date_sp    = default.datetime.strftime(setting.DATE_PRESENTATION_FORMAT)
-    
-    
+
+
 if __name__ == '__main__':
     gumpinit()

Modified: gump/trunk/python/gump/core/run/gumpenv.py
==============================================================================
--- gump/trunk/python/gump/core/run/gumpenv.py	(original)
+++ gump/trunk/python/gump/core/run/gumpenv.py	Mon Oct 25 23:48:14 2004
@@ -16,10 +16,8 @@
 # limitations under the License.
 
 """
-
  A gump environment (i.e. what tools are available in this machine's
  environment, and so forth).
- 
 """
 
 import os.path
@@ -54,7 +52,6 @@
     	
     	What environment variables are set, what tools are 
     	available, what Java command to use, etc.
-    	
     """
 
     def __init__(self):
@@ -63,35 +60,35 @@
         Propogatable.__init__(self)
         Stateful.__init__(self)
         
-        self.checked=False
-        self.set=False
+        self.checked = False
+        self.set = False
     	
-        self.noMono=False
-        self.noNAnt=False    
-        self.noMaven=False    	 
-    	self.noDepot=False    	
-    	self.noUpdate=False    
-    	self.noSvn=False    	
-    	self.noCvs=False   
-    	self.noP4=False   
-        self.noJava=False
-        self.noJavac=False
+        self.noMono = False
+        self.noNAnt = False    
+        self.noMaven = False    	 
+        self.noDepot = False    	
+        self.noSvn = False    	
+        self.noCvs = False   
+        self.noP4 = False   
+        self.noJava = False
+        self.noJavac = False
         
-        self.javaProperties=None
+        self.javaProperties = None
     
         # GUMP_HOME
         self.gumpHome = None
         
-    	# JAVACMD can override this, see checkEnvironment
-    	self.javaHome = None
+        # JAVACMD can override this, see checkEnvironment
+        self.javaHome = None
         self.javaCommand = 'java'
+        self.javacCommand = 'javac'
         
         # DEPOT_HOME
         self.depotHome = None
         
         # Timezone and offset from UTC
-        self.timezone=time.tzname
-        self.timezoneOffset=time.timezone
+        self.timezone = time.tzname
+        self.timezoneOffset = time.timezone
         
     def checkEnvironment(self,exitOnError=False):
         """ 
@@ -100,35 +97,26 @@
         
         if self.checked: return
     
-        #
-        # :TODO: Complete this, it ought be an important early warning...
-        #
-    
-    
-        #:TODO: Take more from runAnt.py on:
-        # - ANT_OPTS?
-        # - How to ensure lib/tools.jar is in classpath
-        # - Others?
-    
-        #
-        #    Directories...
-     
-    
+        # Check for directories
+        
         self._checkEnvVariable('GUMP_HOME')                
-        self.gumpHome  = os.environ['GUMP_HOME']
+        self.gumpHome = os.environ['GUMP_HOME']
             
-        # JAVACMD can be set (perhaps for JRE verse JDK)
-        if os.environ.has_key('JAVACMD'):        
-            self.javaCommand  = os.environ['JAVACMD']
-            self.addInfo('JAVACMD environmental variable setting java command to ' \
-                + self.javaCommand )      
+        # JAVA_CMD can be set (perhaps for JRE verse JDK)
+        if os.environ.has_key('JAVA_CMD'):        
+            self.javaCommand  = os.environ['JAVA_CMD']
+            self.addInfo('JAVA_CMD environmental variable setting java command to ' + self.javaCommand )      
+
+        # JAVAC_CMD can be set (perhaps for JRE verse JDK)
+        if os.environ.has_key('JAVAC_CMD'):        
+            self.javacCommand  = os.environ['JAVAC_CMD']
+            self.addInfo('JAVAC_CMD environmental variable setting javac command to ' + self.javacCommand )      
     
         self._checkEnvVariable('JAVA_HOME')
                 
         if os.environ.has_key('JAVA_HOME'):        
             self.javaHome  = os.environ['JAVA_HOME']
-            self.addInfo('JAVA_HOME environmental variable setting java home to ' \
-                + self.javaHome )      
+            self.addInfo('JAVA_HOME environmental variable setting java home to ' + self.javaHome )      
                 
         if not self.noMaven and not self._checkEnvVariable('MAVEN_HOME',False): 
             self.noMaven=True
@@ -138,16 +126,10 @@
             self.noDepot=True
             self.addWarning('DEPOT_HOME environmental variable not found, no depot downloads.')
         
-        self.depotHome  = getDepotHome(False)
+        self.depotHome = getDepotHome(False)
             
-        #
-        # Check for executables:
-        #
-        #    java
-        #    javac (for bootstrap ant & beyond)
-        #    cvs
-        #    svn
-        #
+        # Check for executables
+        
         self._checkExecutable('env','',False)
 
         if not self.noJava and not self._checkExecutable(self.javaCommand,'-version',exitOnError,1):
@@ -172,10 +154,10 @@
             self.noP4=True
             self.addWarning('"p4" command not found, no Perforce repository updates')
           
-        if not self.noUpdate and \
+        if not self.noDepot and \
             not self._checkExecutable(getDepotUpdateCmd(),'-version',False,False,'check_depot_update'): 
-            self.noUpdate=True
-            self.addWarning('"update.py" command not found, no package downloads')
+            self.noDepot=True
+            self.addWarning('"depot update" command not found, no package downloads')
         
         if not self.noMaven and \
             not self._checkExecutable('maven','--version',False,False,'check_maven'): 
@@ -192,7 +174,7 @@
             self.noMono=True
             self.addWarning('"Mono" command not found, no Mono runtime')
        
-        self.checked=True
+        self.checked = True
         
         self.changeState(STATE_SUCCESS)
         
@@ -204,7 +186,7 @@
         if self.set: return
         
         # Blank the CLASSPATH
-        os.environ['CLASSPATH']=''
+        os.environ['CLASSPATH'] = ''
   
         self.set=True
         
@@ -223,43 +205,45 @@
         Ask the JAVA instance what it's system properties are, 
         primarily so we can log/display them (for user review).
         """
-        if not isinstance(self.javaProperties,NoneType): 
+        
+        if not isinstance(self.javaProperties,NoneType):
             return self.javaProperties
 
         # Ensure we've determined the Java Compiler to use
         self.checkEnvironment()
         
-        if self.noJavac: return {}
+        if self.noJavac: 
+            log.error("Can't obtain Java properties since Java Environment was not found")
+            return {}
 
         import commands, re
 
         JAVA_SOURCE = dir.tmp + '/sysprop.java'
 
-        source=open(JAVA_SOURCE,'w')
+        source = open(JAVA_SOURCE,'w')
         source.write("""
           import java.util.Enumeration;
           public class sysprop {
             public static void main(String [] args) {
-              Enumeration e=System.getProperties().propertyNames();
+              Enumeration e = System.getProperties().propertyNames();
               while (e.hasMoreElements()) {
-                String name = (String)e.nextElement();
-                System.out.print(name + ": ");
-                System.out.println(System.getProperty(name));
+                String name = (String) e.nextElement();
+                System.out.println(name + ": " + System.getProperty(name));
               }
             }
           }
         """)
         source.close()
     
-        os.system('javac ' + JAVA_SOURCE)
+        cmd = self.javacCommand + " " + JAVA_SOURCE
+        os.system(cmd)
         os.unlink(JAVA_SOURCE)
     
-        cmd=self.javaCommand + ' -cp ' + dir.tmp + ' sysprop'
-        self.javaProperties = \
-	        dict(re.findall('(.*?): (.*)', commands.getoutput(cmd)))
-        JAVA_CLASS=JAVA_SOURCE.replace('.java','.class')
-        if os.path.exists(JAVA_CLASS):
-            os.unlink(JAVA_CLASS)
+        cmd = self.javaCommand + ' -cp ' + dir.tmp + ' sysprop'
+        result = commands.getoutput(cmd)
+        self.javaProperties = dict(re.findall('(.*?): (.*)', result))
+        JAVA_CLASS = JAVA_SOURCE.replace('.java','.class')
+        if os.path.exists(JAVA_CLASS): os.unlink(JAVA_CLASS)
 
         for (name,value) in self.javaProperties.items():
             log.debug("Java Property: " + name + " => " + value)
@@ -267,55 +251,55 @@
         return self.javaProperties
 
     def _checkExecutable(self,command,options,mandatory,logOutput=False,name=None):
-        ok=False
+        ok = False
         try:
-            if not name: name='check_'+command
-            cmd=gump.util.process.command.getCmdFromString(command+" "+options,name)
-            result=execute(cmd)
-            ok=result.isOk()
-            if not ok:
-                log.info('Failed to detect [' + command + ']')   
+            if not name: name = 'check_'+command
+            cmd = gump.util.process.command.getCmdFromString(command+" "+options,name)
+            result = execute(cmd)
+            ok = result.isOk()
+            if ok:
+                log.warning('Detected [' + command + ' ' + options + ']')   
+            else:
+                log.warning('Failed to detect [' + command + ' ' + options + ']')   
         except Exception, details:
-            ok=False
-            log.error('Failed to detect [' + command + '] : ' + str(details))
-            result=None
+            ok = False
+            log.error('Failed to detect [' + command + ' ' + options + '] : ' + str(details))
+            result = None
        
         # Update 
         self.performedWork(CommandWorkItem(WORK_TYPE_CHECK,cmd,result))
         
         if not ok and mandatory:
-            banner()
             print
-            print " Unable to detect/test mandatory [" + command+ "] in path (see next)."
+            print "Unable to detect/test mandatory [" + command+ "] in path:"
             for p in sys.path:
                 print "  " + str(os.path.abspath(p))
             sys.exit(EXIT_CODE_MISSING_UTILITY)
         
         # Store the output
         if logOutput and result.output:
-            out=tailFileToString(result.output,10)
+            out = tailFileToString(result.output,10)
             self.addInfo(name + ' produced: \n' + out)
             
         return ok
     
     def _checkEnvVariable(self,env,mandatory=True):
-        ok=False
+        ok = False
         try:
-            ok=os.environ.has_key(env)
+            ok = os.environ.has_key(env)
             if not ok:
                 log.info('Failed to find environment variable [' + env + ']')
         
         except Exception, details:
-            ok=False
+            ok = False
             log.error('Failed to find environment variable [' + env + '] : ' + str(details))
     
         if not ok and mandatory:
-            banner()
             print
-            print " Unable to find mandatory [" + env + "] in environment (see next)."
+            print "Unable to find mandatory [" + env + "] in environment:"
             for e in os.environ.keys():
                 try:
-                    v=os.environ[e]
+                    v = os.environ[e]
                     print "  " + e + " = " + v
                 except:
                     print "  " + e 
@@ -333,6 +317,6 @@
         return self.timezoneOffset
         
 if __name__ == '__main__':
-  env = GumpEnvironment()
-  env.checkEnvironment()
-  env.getJavaProperties()
+    env = GumpEnvironment()
+    env.checkEnvironment()
+    env.getJavaProperties()

Modified: gump/trunk/python/gump/util/__init__.py
==============================================================================
--- gump/trunk/python/gump/util/__init__.py	(original)
+++ gump/trunk/python/gump/util/__init__.py	Mon Oct 25 23:48:14 2004
@@ -30,15 +30,29 @@
 from gump import log
 from gump.core.config import default, setting
 
+def banner():
+    print "      _____"
+    print "     |   __|_ Apache_ ___"
+    print "     |  |  | | |     | . |"
+    print "     |_____|___|_|_|_|  _|"
+    print "                     |_|     ~ v. " + setting.VERSION + " ~"
+    print
 
 def gumpSafeName(name):
   """returns a file system safe name"""  
-  #
   return urllib.quote_plus(name)
 
-###############################################################################
-# Dump an object (as best possible generically)
-###############################################################################
+def getModule(modulePath):
+    try:
+        aMod = sys.modules[modulePath]
+        if not isinstance(aMod, types.ModuleType):
+            raise KeyError
+    except KeyError:
+        # The last [''] is very important!
+        aMod = __import__(modulePath, globals(), locals(), [''])
+        sys.modules[modulePath] = aMod
+    return aMod
+    
 def dump(obj,indent="",visited=None):
     
     print indent+"Object: ["+str(obj.__class__)+"] "+str(obj)
@@ -139,15 +153,6 @@
         sorted.sort()        
     # Return it sorted
     return sorted   
-
-def banner():
-    print
-    print "      _____"
-    print "     |   __|_ Apache_ ___"
-    print "     |  |  | | |     | . |"
-    print "     |_____|___|_|_|_|  _|"
-    print "                     |_|     ~ v. " + setting.VERSION + " ~"
-    print
     
 def printSeparator(indent=''):
     printSeparatorToFile(None,indent)

Added: gump/trunk/python/gump/util/locks.py
==============================================================================
--- (empty file)
+++ gump/trunk/python/gump/util/locks.py	Mon Oct 25 23:48:14 2004
@@ -0,0 +1,78 @@
+#!/usr/bin/env python
+
+# Copyright 2003-2004 The Apache Software Foundation
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+# 
+#     http://www.apache.org/licenses/LICENSE-2.0
+# 
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+"""
+    Simple Lock Utilities (for Gump)
+"""
+
+import os,sys
+
+#-----------------------------------------------------------------------# 
+        
+def establishLock(lockFile):
+
+    failed=0
+    info=''
+    if 'posix'==os.name:
+        import fcntl
+                
+        try:            
+            lock=open(lockFile,'a+')
+            fcntl.flock(lock.fileno(), fcntl.LOCK_EX | fcntl.LOCK_NB)
+        except:            
+            failed=1
+            info=', and is locked.'
+        
+    else:
+        if os.path.exists(lockFile):
+            failed=1
+        
+        # Write this PID into a lock file
+        lock=open(lockFile,'w')
+            
+    if failed:
+        print """The lock file [%s] exists%s. 
+Either Gump is still running, or it terminated very abnormally.    
+Please resolve this (waiting or removing the lock file) before retrying.
+        """ % (lockFile, info)
+        sys.exit(1)
+    
+    # Leave a mark...
+    lock.write(`os.getpid()`)
+    lock.flush()
+        
+    return lock
+
+#-----------------------------------------------------------------------# 
+        
+def releaseLock(lock,lockFile):
+      
+    if 'posix'==os.name:
+        import fcntl            
+        try:
+            fcntl.flock(lockFile.fileno(), fcntl.LOCK_UN)
+        except:
+            pass
+    
+    # Close it, so we can dispose of it
+    lock.close()    
+    
+    # Others might be blocked on this
+    try:
+        os.remove(lockFile)
+    except:
+        # Somehow another could delete this, even if locked...
+        pass

Modified: gump/trunk/python/gump/util/process/command.py
==============================================================================
--- gump/trunk/python/gump/util/process/command.py	(original)
+++ gump/trunk/python/gump/util/process/command.py	Mon Oct 25 23:48:14 2004
@@ -128,7 +128,7 @@
         requiresQuoting=param.isRequiresQuoting()
         
         if requiresQuoting:
-            line+=default.shellQuote
+            line += default.shellQuote
         
         if param.prefix: 
           line += param.prefix
@@ -142,7 +142,7 @@
             line += self.getEscapedEntry(val)        
             
         if requiresQuoting:
-            line+=default.shellQuote            
+            line += default.shellQuote
         line += ' '
         
       return line
@@ -159,20 +159,20 @@
       
     def dump(self,indent=''):
       for param in self.list:
-        print indent+'  '+param.name+' '+str(param.value)+' ('+str(param.prefix)+')'
+        print indent + '  ' + param.name + ' ' + str(param.value) + ' (' + str(param.prefix) + ')'
       
 class Cmd:
     """Command Line (executable plus parameters)"""
     def __init__(self,command,name=None,cwd=None,env=None,timeout=setting.TIMEOUT):
-        self.cmdpath=command
-        self.name=name
+        self.cmdpath = command
+        self.name = name
         if not self.name:
-            self.name=command
-        self.params=Parameters()
-        self.env=env
-        if not env: self.env={}
-        self.cwd=cwd
-        self.timeout=timeout
+            self.name = command
+        self.params = Parameters()
+        self.env = env
+        if not env: self.env = {}
+        self.cwd = cwd
+        self.timeout = timeout
 
     def addParameter(self,name,val=None,separator=' '):
         self.params.addParameter(name,val,separator)
@@ -209,12 +209,12 @@
         return line
             
     def overview(self,indent=''):
-        overview=indent+'Command Line: ' + self.formatCommandLine()+'\n'
+        overview = indent + 'Command Line: ' + self.formatCommandLine() + '\n'
         if self.cwd:
-            overview += indent+'[Working Directory: ' + self.cwd + ']\n'
+            overview += indent + '[Working Directory: ' + self.cwd + ']\n'
         if self.env:
             for envKey in self.env.keys():
-                overview += indent+envKey+' : '+self.env[envKey]+ '\n'
+                overview += indent + envKey + ': ' + self.env[envKey] + '\n'
         return overview
         
     def dump(self,indent=''):
@@ -222,10 +222,10 @@
         
 def getCmdFromString(strcmd,name=None):
     """Extract a Cmd Object from a String"""
-    parts=split(strcmd,' ')
-    cmdcmd=parts[0]
-    if not name: name=cmdcmd
-    cmd=Cmd(cmdcmd,name)
+    parts = split(strcmd,' ')
+    cmdcmd = parts[0]
+    if not name: name = cmdcmd
+    cmd = Cmd(cmdcmd,name)
     for i in range(1,len(parts)):
         if parts[i]:
             cmd.addParameterObject(getParameterFromString(parts[i]))
@@ -234,27 +234,27 @@
 class CmdResult:
     """Result of execution -- state/outputs"""
     def __init__(self,cmd):
-        self.cmd=cmd
-        self.state=CMD_STATE_NOT_YET_RUN
-        self.output=None
-        self.signal=0
-        self.exit_code=-1
+        self.cmd = cmd
+        self.state = CMD_STATE_NOT_YET_RUN
+        self.output = None
+        self.signal = 0
+        self.exit_code = -1
         
         # To calculate elapsed
-        self.start=None
-        self.end=None
+        self.start = None
+        self.end = None
         
-    def overview(self,indent):
-        overview = indent+"State: " + states[self.state]
+    def overview(self,indent=''):
+        overview = indent + "State: " + states[self.state] + "\n"
         overview += self.cmd.overview(indent)
         if self.output:
-          overview += indent+"Output: " + self.output
+          overview += indent + "Output: " + self.output + "\n"
         if self.hasTimes():
-          overview += indent+"Elapsed: " + secsToElapsedTimeString(self.getElapsedSecs())
+          overview += indent + "Elapsed: " + secsToElapsedTimeString(self.getElapsedSecs()) + "\n"
         if self.signal:
-          overview += indent+"Termination Signal: " + str(self.signal)
+          overview += indent + "Termination Signal: " + str(self.signal) + "\n"
         if self.exit_code:
-          overview += indent+"ExitCode: " + str(self.exit_code)
+          overview += indent + "ExitCode: " + str(self.exit_code) + "\n"
         
         return overview
         
@@ -268,7 +268,7 @@
         return tail
         
     def isOk(self):
-        return (self.state==CMD_STATE_SUCCESS)
+        return (self.state == CMD_STATE_SUCCESS)
     
     def hasOutput(self):
         if self.output: return 1

Modified: gump/trunk/python/gump/util/process/launcher.py
==============================================================================
--- gump/trunk/python/gump/util/process/launcher.py	(original)
+++ gump/trunk/python/gump/util/process/launcher.py	Mon Oct 25 23:48:14 2004
@@ -15,9 +15,7 @@
 # limitations under the License.
 
 """
-
     Executing processes (CVS, ant, etc.) and capturing results
-    
 """
 
 import os
@@ -31,68 +29,54 @@
 from gump.core.config import dir
 from gump.util import *
 from gump.util.timing import *
-
-import gump.util.process.command
-
-LAUNCHER=os.path.join(os.path.join(os.path.join(os.path.join('python','gump'),'util'),'process'),'launcher.py')
+from gump.util.process import command
+    
+LAUNCHER = os.path.join(os.path.join(os.path.join(os.path.join('python','gump'),'util'),'process'),'launcher.py')
 
 def execute(cmd,tmp=dir.tmp):
-    res=gump.util.process.command.CmdResult(cmd)
+    res = command.CmdResult(cmd)
     return executeIntoResult(cmd,res,tmp)
 	
 def executeIntoResult(cmd,result,tmp=dir.tmp):
     """
-    
     	Execute a command and capture the result
-   
-   	"""	
-    
-    outputFile=None
-    start=getLocalNow()
+   	"""
+    outputFile = None
+    start = getLocalNow()
     try:
       try:          
  
         # The command line
-        execString=cmd.formatCommandLine()        
+        execString = cmd.formatCommandLine()        
         
         # Exec File
-        execFile=os.path.abspath(os.path.join(tmp,gumpSafeName(cmd.name)+'.exec'))
+        execFile = os.path.abspath(os.path.join(tmp,gumpSafeName(cmd.name)+'.exec'))
         if os.path.exists(execFile): os.remove(execFile)
         
         # Output
-        outputFile=os.path.abspath(os.path.join(tmp,gumpSafeName(cmd.name)+'.txt'))
+        outputFile = os.path.abspath(os.path.join(tmp,gumpSafeName(cmd.name)+'.txt'))
         if os.path.exists(outputFile): os.remove(outputFile)
     
         try:            
-            f=open(execFile, 'w')
-            
+            f = open(execFile, 'w')
             # The CMD
             f.write( 'CMD: %s\n' % (execString))
-                
             # Dump the TMP
-            if tmp:
-                f.write( 'TMP: %s\n' % (tmp))
-                
+            if tmp: f.write( 'TMP: %s\n' % (tmp))
             # Dump the cwd (if specified)
-            if cmd.cwd:
-                f.write( 'CWD: %s\n' % (cmd.cwd))
-                     
+            if cmd.cwd: f.write( 'CWD: %s\n' % (cmd.cwd))
             # Write the TIMEOUT
-            if cmd.timeout:
-                f.write( 'TIMEOUT: %s\n' % (cmd.timeout))    
-                
+            if cmd.timeout: f.write( 'TIMEOUT: %s\n' % (cmd.timeout))    
             # Write ENV over-writes...
-            for envKey in cmd.env.iterkeys():
-                f.write('%s: %s\n' % (envKey, cmd.env[envKey]))    
- 
+            for envKey in cmd.env.iterkeys(): f.write('%s: %s\n' % (envKey, cmd.env[envKey]))    
         finally:
             # Since we may exit via an exception, close explicitly.
             if f: f.close()    
+        
+        # make sure that the python path includes the gump modules
+        os.environ['PYTHONPATH'] = os.path.abspath(os.path.join(os.getcwd(),'./python'))
             
-        #############################################################          
-           
-        fullExec = sys.executable + ' ' + LAUNCHER + ' ' + execFile + \
-                                    ' >>' + str(outputFile) + ' 2>&1'
+        fullExec = sys.executable + ' ' + LAUNCHER + ' ' + execFile + ' >>' + str(outputFile) + ' 2>&1'
                                     
         #log.debug('Executing: ' + execString)
         #log.debug('     Exec: ' + str(execFile))
@@ -100,59 +84,51 @@
         #log.debug('Full Exec: ' + fullExec)
         
         # Execute Command & Wait
-        systemReturn=os.system(fullExec)
+        systemReturn = os.system(fullExec)
         
         if not os.name == 'dos' and not os.name == 'nt':
-            waitcode=systemReturn
-        
-            #
+            waitcode = systemReturn
             # The return code (from system = from wait) is (on Unix):
-            #
             #	a 16 bit number
             #	top byte	=	exit status
             #	low byte	=	signal that killed it
-            #
-            result.signal=(waitcode & 0xFF)
-            result.exit_code=(((waitcode & 0xFF00) >> 8) & 0xFF)
-        
+            result.signal = (waitcode & 0xFF)
+            result.exit_code = (((waitcode & 0xFF00) >> 8) & 0xFF)
         else:
-            
-            result.signal=0
-            result.exit_code=systemReturn
+            result.signal = 0
+            result.exit_code = systemReturn
             
         #log.debug('Command returned [' + str(systemReturn)+ '] [Sig:' + str(result.signal) + ' / Exit:' + str(result.exit_code) + '].')
         
-        #
         # Assume timed out if signal terminated
-        #
         if result.signal > 0:
-            result.state=gump.util.process.command.CMD_STATE_TIMED_OUT
-            log.warn('Command timed out. [' + execString + '] [' + str(timeout) + '] seconds.')
+            result.state = command.CMD_STATE_TIMED_OUT
+            #log.warn('Command timed out. [' + execString + '] [' + str(timeout) + '] seconds.')
         # Process Outputs (exit_code and stderr/stdout)
         elif result.exit_code > 0:    
-            result.state=gump.util.process.command.CMD_STATE_FAILED
-            log.warn('Command failed. [' + execString + ']. ExitCode: ' + str(result.exit_code))
+            result.state = command.CMD_STATE_FAILED
+            #log.warn('Command failed. [' + execString + ']. ExitCode: ' + str(result.exit_code))
         else:
-            result.state=gump.util.process.command.CMD_STATE_SUCCESS                
+            result.state = command.CMD_STATE_SUCCESS                
      
       except Exception, details :
         log.error('Failed to launch command. Details: ' + str(details))
         
-        result.exit_code=-1
-        result.state=gump.util.process.command.CMD_STATE_FAILED
+        result.exit_code = -1
+        result.state = command.CMD_STATE_FAILED
         
     finally:
       # Clean Up Empty Output Files
       if outputFile and os.path.exists(outputFile):
           if os.path.getsize(outputFile) > 0:
-              result.output=outputFile
+              result.output = outputFile
           else:
               os.remove(outputFile)
         
       # Keep time information
-      end=getLocalNow()
-      result.start=start
-      result.end=end 
+      end = getLocalNow()
+      result.start = start
+      result.end = end 
 	  
     return result
     
@@ -160,7 +136,7 @@
     """
     Kill this (and all child processes).
     """
-    gumpid=default.gumpid
+    gumpid = default.gumpid
     log.warn('Kill all child processed (anything launched by PID' + str(gumpid) + ')')    
     try:
         os.kill(gumpid,signal.SIGKILL)
@@ -170,45 +146,43 @@
           
 def runProcess(execFilename):
     """
-    
     Read an 'exec file' (formatted by Gump) to detect what to run,
     and how to run it.
-    
     """
-    execFile=None
+    execFile = None
     try:
-        execFile=file(execFilename,'r')
+        execFile = file(execFilename,'r')
     
         # Split into a dict of NAME: VALUE (from file)
-        execInfo=dict(re.findall('(.*?): (.*)', execFile.read()))
+        execInfo = dict(re.findall('(.*?): (.*)', execFile.read()))
         
         #print execInfo
         #for key in execInfo.iterkeys():
         #    print 'KEY : ' + key  + ' -> ' + execInfo[key]
         
-        cmd=execInfo['CMD']
-        cwd=None
-        if execInfo.has_key('CWD'):cwd=execInfo['CWD']
-        tmp=execInfo['TMP']
-        timeout=0
-        if execInfo.has_key('TIMEOUT'):timeout=int(execInfo['TIMEOUT'])
+        cmd = execInfo['CMD']
+        cwd = None
+        if execInfo.has_key('CWD'): cwd = execInfo['CWD']
+        tmp = execInfo['TMP']
+        timeout = 0
+        if execInfo.has_key('TIMEOUT'): timeout = int(execInfo['TIMEOUT'])
        
         # Make the TMP if needed
         if not os.path.exists(tmp): os.makedirs(tmp)
        
         # Make the CWD if needed
         if cwd: 
-          cwdpath=os.path.abspath(cwd)
+          cwdpath = os.path.abspath(cwd)
           if not os.path.exists(cwdpath): os.makedirs(cwdpath)
           os.chdir(cwdpath)
        
         # Write ENV over-writes...
         for envKey in execInfo.iterkeys():
             if not envKey in ['CMD','TMP','CWD']:
-                os.environ[envKey]=execInfo[envKey]
+                os.environ[envKey] = execInfo[envKey]
                
         # Timeout support
-        timer=None
+        timer = None
         if timeout:
             import threading
             timer = threading.Timer(timeout, shutdownProcesses)
@@ -216,44 +190,36 @@
             timer.start()
             
         # Run the command
-        systemReturn=os.system(cmd)
+        systemReturn = os.system(cmd)
                   
         # Stop timer (if still running)
         if timer: timer.cancel() 
         
         if not os.name in ['dos','nt']:
-            waitcode=systemReturn
-        
-            #
+            waitcode = systemReturn
             # The return code (from system = from wait) is (on Unix):
-            #
             #    a 16 bit number
             #    top byte    =    exit status
             #    low byte    =    signal that killed it
-            #
-            signal=(waitcode & 0xFF)
-            exit_code=(((waitcode & 0xFF00) >> 8) & 0xFF)
-        
+            signal = (waitcode & 0xFF)
+            exit_code = (((waitcode & 0xFF00) >> 8) & 0xFF)
         else:
-            signal=0
-            exit_code=systemReturn
+            signal = 0
+            exit_code = systemReturn
             
     finally:
         if execFile: execFile.close()
         
     return exit_code
-           
+
 if __name__=='__main__':
     import re
     
-    exit_code=0
-    execFilename=sys.argv[1]
+    exit_code = 0
+    execFilename = sys.argv[1]
     
     # Run the information within this file...
-    exit_code=runProcess(execFilename)
+    exit_code = runProcess(execFilename)
         
     # print 'Exit: ' + `exit_code`
     sys.exit(exit_code)
-        
-  
-