gump-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From aj...@apache.org
Subject svn commit: r159459 - in gump/live: ./ bin/ cron/ mysql/ python/ python/gump/actor/mysql/ python/gump/actor/stats/mysql/ python/gump/core/build/ python/gump/core/language/ python/gump/core/model/ python/gump/core/run/ python/gump/core/runner/ python/gump/core/update/ python/gump/storage/ python/gump/test/ python/gump/tool/integration/ python/gump/util/ python/gump/util/process/ python/misc/ src/documentation/ src/documentation/content/xdocs/ src/documentation/content/xdocs/metadata/ src/xdocs/
Date Wed, 30 Mar 2005 02:22:44 GMT
Author: ajack
Date: Tue Mar 29 18:22:36 2005
New Revision: 159459

URL: http://svn.apache.org/viewcvs?view=rev&rev=159459
Log:
Migrating TRUNK to LIVE. Primarily for XALAN (LATIN_1 character) support
in file synchronization.


Added:
    gump/live/freej-gump-run   (props changed)
      - copied unchanged from r159424, gump/trunk/freej-gump-run
    gump/live/python/gump.log.config
      - copied unchanged from r159424, gump/trunk/python/gump.log.config
    gump/live/python/gump/actor/mysql/dynagumper.py
      - copied unchanged from r159424, gump/trunk/python/gump/actor/mysql/dynagumper.py
    gump/live/python/gump/test/mockobjects.py
      - copied unchanged from r159424, gump/trunk/python/gump/test/mockobjects.py
    gump/live/python/gump/test/testAllPyUnitTests.py.disabled.for.now   (props changed)
      - copied unchanged from r159424, gump/trunk/python/gump/test/testAllPyUnitTests.py.disabled.for.now
    gump/live/python/gump/test/testDynagumper.py
      - copied unchanged from r159424, gump/trunk/python/gump/test/testDynagumper.py
    gump/live/python/misc/
      - copied from r159424, gump/trunk/python/misc/
    gump/live/python/misc/pgrp.py
      - copied unchanged from r159424, gump/trunk/python/misc/pgrp.py
    gump/live/src/xdocs/HowToRunYourOwnGump.html
      - copied unchanged from r159424, gump/trunk/src/xdocs/HowToRunYourOwnGump.html
    gump/live/src/xdocs/gump@fosdem.pdf   (props changed)
      - copied unchanged from r159424, gump/trunk/src/xdocs/gump@fosdem.pdf
    gump/live/src/xdocs/gump@fosdem.ppt   (props changed)
      - copied unchanged from r159424, gump/trunk/src/xdocs/gump@fosdem.ppt
Removed:
    gump/live/python/gump/core/update/artifact.py
    gump/live/python/gump/storage/
    gump/live/python/gump/test/testAllPyUnitTests.py
    gump/live/python/gump/tool/integration/depot.py
Modified:
    gump/live/   (props changed)
    gump/live/bin/integrate.py
    gump/live/cron/   (props changed)
    gump/live/gump
    gump/live/mysql/gump.sql
    gump/live/python/gump/actor/stats/mysql/   (props changed)
    gump/live/python/gump/core/build/builder.py
    gump/live/python/gump/core/build/script.py
    gump/live/python/gump/core/language/java.py
    gump/live/python/gump/core/model/builder.py
    gump/live/python/gump/core/model/depend.py
    gump/live/python/gump/core/model/module.py
    gump/live/python/gump/core/model/object.py
    gump/live/python/gump/core/run/__init__.py
    gump/live/python/gump/core/run/actor.py
    gump/live/python/gump/core/run/gumpenv.py
    gump/live/python/gump/core/run/gumprun.py
    gump/live/python/gump/core/run/options.py
    gump/live/python/gump/core/runner/__init__.py
    gump/live/python/gump/core/runner/demand.py
    gump/live/python/gump/core/runner/runner.py
    gump/live/python/gump/core/update/updater.py
    gump/live/python/gump/tool/integration/__init__.py
    gump/live/python/gump/util/domutils.py
    gump/live/python/gump/util/locks.py
    gump/live/python/gump/util/mysql.py
    gump/live/python/gump/util/process/launcher.py
    gump/live/python/gump/util/sync.py
    gump/live/python/header.txt
    gump/live/src/documentation/content/xdocs/mail.xml
    gump/live/src/documentation/content/xdocs/metadata/project.xml
    gump/live/src/documentation/content/xdocs/site.xml
    gump/live/src/documentation/skinconf.xml

Propchange: gump/live/
------------------------------------------------------------------------------
--- svn:ignore (original)
+++ svn:ignore Tue Mar 29 18:22:36 2005
@@ -3,3 +3,10 @@
 
 build
 log
+work
+cvs
+jars
+tmp
+xdocs-work
+cache
+

Modified: gump/live/bin/integrate.py
URL: http://svn.apache.org/viewcvs/gump/live/bin/integrate.py?view=diff&r1=159458&r2=159459
==============================================================================
--- gump/live/bin/integrate.py (original)
+++ gump/live/bin/integrate.py Tue Mar 29 18:22:36 2005
@@ -76,8 +76,12 @@
     options.setQuick(False)
     options.setCache(False)
     
-    # 
-    options.setObjectives(gump.core.run.options.OBJECTIVE_INTEGRATE)    
+    if not os.environ.has_key('GUMP_WORK_OFFLINE'):
+      options.setObjectives(gump.core.run.options.OBJECTIVE_INTEGRATE)
+    else:
+      options.setCache(True)
+      options.setObjectives(gump.core.run.options.OBJECTIVE_OFFLINE)
+    
     
     # The Run Details...
     run=gump.core.run.gumprun.GumpRun(workspace,ps,options)

Propchange: gump/live/cron/
------------------------------------------------------------------------------
--- svn:ignore (added)
+++ svn:ignore Tue Mar 29 18:22:36 2005
@@ -0,0 +1 @@
+local-env-*.sh

Copied: gump/live/freej-gump-run (from r159424, gump/trunk/freej-gump-run)
URL: http://svn.apache.org/viewcvs/gump/live/freej-gump-run?view=diff&rev=159459&p1=gump/trunk/freej-gump-run&r1=159424&p2=gump/live/freej-gump-run&r2=159459
==============================================================================
    (empty)

Propchange: gump/live/freej-gump-run
------------------------------------------------------------------------------
    svn:executable = *

Modified: gump/live/gump
URL: http://svn.apache.org/viewcvs/gump/live/gump?view=diff&r1=159458&r2=159459
==============================================================================
--- gump/live/gump (original)
+++ gump/live/gump Tue Mar 29 18:22:36 2005
@@ -1,6 +1,6 @@
-#!/bin/sh
+#!/bin/bash
 #
-# Copyright 2004 The Apache Software Foundation
+# Copyright 2004-2005 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.
@@ -144,6 +144,16 @@
   exit 1
 }
 
+# Load the environment variables script if it exists
+function load_env
+{
+  local host=`hostname -s`
+  local envfile="`pwd`/cron/local-env-$host.sh"
+  if [[ -f $envfile ]]; then
+    . $envfile
+  fi
+}
+
 # Print a friendly error message if some dependency is missing.
 #
 # Arguments:
@@ -161,6 +171,54 @@
   fi
 }
 
+# Print a friendly error message if an environment variable is not set.
+#
+# Arguments:
+#   - name of the variable
+#   - description of what the variable should be set to
+function check_env_var
+{
+  local host=`hostname -s`
+  local envfile="`pwd`/cron/local-env-$host.sh"
+
+  local dereferenced=${!1}
+  if [[ -z "$dereferenced" ]]; then
+    error "The variable $1 has not been set. It should be set to
+$2.
+You can either set this before invoking gump, or set it in a file
+named
+  $envfile.sh
+"
+  fi
+}
+
+# Print a friendly error message i a python library is not available.
+#
+# Arguments:
+#   - the library to import
+#   - url to download location of the library
+function check_env_pylib
+{
+  cat > pycmd.tmp.py <<ENDCOMMAND
+try:
+  import $1
+except:
+  print "error"
+ENDCOMMAND
+  local cmd=`python pycmd.tmp.py`
+  result=`$cmd`
+  rm -f pycmd.tmp.py
+
+  if [[ ! -z "$result" ]]; then
+    error "Required python library $1 is not available.
+Please download it from
+
+  $2
+
+and install it."
+  fi
+}
+
 # Figure out which action to execute.
 function delegate
 {
@@ -224,6 +282,12 @@
   check_env "python" "http://www.python.org/"
   check_env "pkill" "http://sourceforge.net/projects/proctools"
 
+  check_env_var "GUMP_HOME" "the location of the gump checkout"
+  check_env_var "JAVA_HOME" "the location of the java jdk"
+  
+  check_env_pylib "rdflib" "http://rdflib.net/"
+  check_env_pylib "MySQLdb" "http://sourceforge.net/projects/mysql-python"
+
   cd cron
   ./gump.sh $@
   cd ..
@@ -233,6 +297,7 @@
 function test
 {
   check_env "python" "http://www.python.org/"
+  check_env_var "GUMP_HOME" "the location of the gump checkout"
 
   local oldpythonpath=$PYTHONPATH
   if [[ -z $oldpythonpath ]]; then
@@ -241,12 +306,15 @@
     export PYTHONPATH=`pwd`/python:`pwd`:$PYTHONPATH
   fi
 
-  #./test/gumptest.sh
+  # Run the tests
   cd python
   python ../bin/testrunner.py -d ../python/gump/test $@
   cd ..
-
-  export PYTHONPATH=$oldpythonpath
+  
+  # Clean up (NB: tests ought to do this themselves...)
+  rm -Rf python/test python/bogus python/x.svg python/gump/test/cache \
+      python/gump/test/temp \
+      python/gump/test/test python/gump/test/work
 }
 
 # Run gumpy integration tests
@@ -350,6 +418,9 @@
 #############################################################################
 # Run the script...
 #############################################################################
+
+# Load any environment variables
+load_env
 
 # Figure out the action to take then run the appropriate function
 delegate $@

Modified: gump/live/mysql/gump.sql
URL: http://svn.apache.org/viewcvs/gump/live/mysql/gump.sql?view=diff&r1=159458&r2=159459
==============================================================================
--- gump/live/mysql/gump.sql (original)
+++ gump/live/mysql/gump.sql Tue Mar 29 18:22:36 2005
@@ -21,7 +21,7 @@
   `module_name` varchar(100) NOT NULL default '',
   `description` varchar(100) NOT NULL default '',
   PRIMARY KEY  (`module_name`)
-) ENGINE=MyISAM DEFAULT CHARSET=latin1; 
+) ENGINE=MyISAM; 
 
 # Host: localhost
 # Database: gump
@@ -36,7 +36,7 @@
   `start` datetime NOT NULL default '0000-00-00 00:00:00',
   `end` datetime NOT NULL default '0000-00-00 00:00:00',
   PRIMARY KEY  (`module_name`,`run_id`)
-) ENGINE=MyISAM DEFAULT CHARSET=latin1; 
+) ENGINE=MyISAM; 
 
 # Host: localhost
 # Database: gump
@@ -55,7 +55,7 @@
   `sequence_in_state` int(11) NOT NULL default '0',
   `last_modified` datetime NOT NULL default '0000-00-00 00:00:00',
   PRIMARY KEY  (`module_name`)
-) ENGINE=MyISAM DEFAULT CHARSET=latin1; 
+) ENGINE=MyISAM; 
 
 # Host: localhost
 # Database: gump
@@ -66,7 +66,7 @@
   `description` varchar(100) NOT NULL default '',
   `module_name` varchar(100) NOT NULL default '',
   PRIMARY KEY  (`project_name`)
-) ENGINE=MyISAM DEFAULT CHARSET=latin1; 
+) ENGINE=MyISAM; 
 
 # Host: localhost
 # Database: gump
@@ -81,7 +81,7 @@
   `start` datetime NOT NULL default '0000-00-00 00:00:00',
   `end` datetime NOT NULL default '0000-00-00 00:00:00',
   PRIMARY KEY  (`run_id`,`project_name`)
-) ENGINE=MyISAM DEFAULT CHARSET=latin1; 
+) ENGINE=MyISAM; 
 
 # Host: localhost
 # Database: gump
@@ -99,7 +99,7 @@
   `start_of_state` datetime default '0000-00-00 00:00:00',
   `sequence_in_state` int(11) NOT NULL default '0',
   PRIMARY KEY  (`project_name`)
-) ENGINE=MyISAM DEFAULT CHARSET=latin1; 
+) ENGINE=MyISAM; 
 
 # Host: localhost
 # Database: gump
@@ -110,7 +110,7 @@
   `name` varchar(100) NOT NULL default '',
   `description` varchar(100) NOT NULL default '',
   PRIMARY KEY  (`code`)
-) ENGINE=MyISAM DEFAULT CHARSET=latin1; 
+) ENGINE=MyISAM; 
 
 # Host: localhost
 # Database: gump
@@ -128,7 +128,7 @@
   `start_of_state` datetime default '0000-00-00 00:00:00',
   `sequence_in_state` int(11) NOT NULL default '0',
   PRIMARY KEY  (`repository_name`)
-) ENGINE=MyISAM DEFAULT CHARSET=latin1; 
+) ENGINE=MyISAM; 
 
 # Host: localhost
 # Database: gump
@@ -139,7 +139,7 @@
   `start` datetime NOT NULL default '0000-00-00 00:00:00',
   `end` datetime NOT NULL default '0000-00-00 00:00:00',
   PRIMARY KEY  (`run_id`)
-) ENGINE=MyISAM DEFAULT CHARSET=latin1; 
+) ENGINE=MyISAM; 
 
 # Host: localhost
 # Database: gump
@@ -150,7 +150,7 @@
   `name` varchar(100) NOT NULL default '',
   `description` varchar(100) NOT NULL default '',
   PRIMARY KEY  (`code`)
-) ENGINE=MyISAM DEFAULT CHARSET=latin1; 
+) ENGINE=MyISAM; 
 
 # Host: localhost
 # Database: gump
@@ -168,5 +168,5 @@
   `start_of_state` datetime default '0000-00-00 00:00:00',
   `sequence_in_state` int(11) NOT NULL default '0',
   PRIMARY KEY  (`workspace_name`)
-) ENGINE=MyISAM DEFAULT CHARSET=latin1; 
+) ENGINE=MyISAM; 
 

Propchange: gump/live/python/gump/actor/stats/mysql/
------------------------------------------------------------------------------
--- svn:ignore (added)
+++ svn:ignore Tue Mar 29 18:22:36 2005
@@ -0,0 +1 @@
+*.pyc

Modified: gump/live/python/gump/core/build/builder.py
URL: http://svn.apache.org/viewcvs/gump/live/python/gump/core/build/builder.py?view=diff&r1=159458&r2=159459
==============================================================================
--- gump/live/python/gump/core/build/builder.py (original)
+++ gump/live/python/gump/core/build/builder.py Tue Mar 29 18:22:36 2005
@@ -67,8 +67,6 @@
 from gump.core.model.stats import *
 from gump.core.model.state import *
 
-import gump.tool.integration.depot
-
 
 ###############################################################################
 # Classes
@@ -427,12 +425,11 @@
         # See if we have any...
         artifacts = self.repository.extractMostRecentGroup(group)
         if not artifacts:
-            self.checkUpstreamRepositories(project)
             # Then try again...
             artifacts = self.repository.extractMostRecentGroup(group)
             
         # :TODO:
-        # If not artifacts, download using Depot?
+        # If not artifacts, download.
         
         artifactsOk=False
             
@@ -465,26 +462,6 @@
         else:                                 
             log.error(' ------ Extracted (fallback) artifacts from Repository : '+ project.getName())  
             project.addInfo('Failed to extract fallback artifacts from Gump Repository')  
-       
-    def checkUpstreamRepositories(self,project):
-        """
-        
-        See if we can download something...
-        
-        """
-        if self.run.getEnvironment().noDepot: return
-        
-        log.info(' ------ Check upstream repositories for : '+ project.getName())    
-        
-        cmd=gump.tool.integration.depot.getGroupUpdateCommand(project.getArtifactGroup(),
-                    self.repository.getRepositoryDir())
-        
-        # Execute the command ....
-        cmdResult=execute(cmd,self.run.getWorkspace().tmpdir)
-    
-        # Update context with the fact that this work was done
-        work=CommandWorkItem(WORK_TYPE_UPDATE,cmd,cmdResult)
-        project.performedWork(work)
          
     def preview(self,project,languageHelper):
         """

Modified: gump/live/python/gump/core/build/script.py
URL: http://svn.apache.org/viewcvs/gump/live/python/gump/core/build/script.py?view=diff&r1=159458&r2=159459
==============================================================================
--- gump/live/python/gump/core/build/script.py (original)
+++ gump/live/python/gump/core/build/script.py Tue Mar 29 18:22:36 2005
@@ -55,7 +55,7 @@
     args = Parameters()
     for arg in script.getProperties():
         if arg.name.startswith('--') or not arg.name.startswith('-'):
-            if arg.value:
+            if arg.value and arg.value != "*Unset*": # TODO: fix this properly. Ugly!
                 args.addNamedParameter(arg.name,arg.value,'=')
             else:
                 args.addParameter(arg.name)

Modified: gump/live/python/gump/core/language/java.py
URL: http://svn.apache.org/viewcvs/gump/live/python/gump/core/language/java.py?view=diff&r1=159458&r2=159459
==============================================================================
--- gump/live/python/gump/core/language/java.py (original)
+++ gump/live/python/gump/core/language/java.py Tue Mar 29 18:22:36 2005
@@ -8,7 +8,7 @@
 # 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.
@@ -221,12 +221,21 @@
 
         # Append sub-projects outputs, if inherited
         for subdependency in project.getDirectDependencies():        
-            #    If the dependency is set to 'all' (or 'hard') we inherit all dependencies
-            # If the dependency is set to 'runtime' we inherit all runtime dependencies
-            # If the dependent project inherited stuff, we inherit that...
-            if        (inherit==gump.core.model.depend.INHERIT_ALL or inherit==gump.core.model.depend.INHERIT_HARD) \
-                    or (inherit==gump.core.model.depend.INHERIT_RUNTIME and subdependency.isRuntime()) \
-                    or (subdependency.inherit > gump.core.model.depend.INHERIT_NONE):      
+        	#
+        	# 	For the main project we working on, we care about it's request for inheritence
+        	#	but we don't recursively inherit. (i.e. we only do this at recursion depth 1).
+        	#
+            #   If the dependency is set to 'all' (or 'hard') we inherit all dependencies.
+            # 	If the dependency is set to 'runtime' we inherit all runtime dependencies.
+            #
+            #	INHERIT_OUTPUTS (aka INHERIT_JARS) is more sticky, and we track that down (and down, ...).
+            #
+            if   (  ( ( 1 == depth ) and \
+                 	(inherit in [ gump.core.model.depend.INHERIT_ALL, gump.core.model.depend.INHERIT_HARD ]) \
+                    	or \
+                    (inherit == gump.core.model.depend.INHERIT_RUNTIME and subdependency.isRuntime()) ) \
+                   or \
+                   	( inherit in [ gump.core.model.depend.INHERIT_OUTPUTS ] ) ) :      
                 (subcp, subbcp) = self._getDependOutputList(project,subdependency,visited,depth+1,debug)
                 self._importClasspaths(classpath,bootclasspath,subcp,subbcp)   
             elif debug:

Modified: gump/live/python/gump/core/model/builder.py
URL: http://svn.apache.org/viewcvs/gump/live/python/gump/core/model/builder.py?view=diff&r1=159458&r2=159459
==============================================================================
--- gump/live/python/gump/core/model/builder.py (original)
+++ gump/live/python/gump/core/model/builder.py Tue Mar 29 18:22:36 2005
@@ -154,7 +154,7 @@
         ids=getDomAttributeValue(pdom,'id','')
 
         # Runtime?
-        runtime=hasDomAttribute(pdom,'runtime')
+        runtime=domAttributeIsTrue(pdom,'runtime')
 
         if workspace.hasProject(projectName): 
                         

Modified: gump/live/python/gump/core/model/depend.py
URL: http://svn.apache.org/viewcvs/gump/live/python/gump/core/model/depend.py?view=diff&r1=159458&r2=159459
==============================================================================
--- gump/live/python/gump/core/model/depend.py (original)
+++ gump/live/python/gump/core/model/depend.py Tue Mar 29 18:22:36 2005
@@ -66,11 +66,6 @@
     
     annotation = None # 'Expressed Dependency'
     
-    # :TODO: I hate this line of code!!!!
-    # :TODO:#2: I really hate this code, we ought not be trying
-    # to acess the delegate. We do so to check for existence
-    # but w/o value. Not good. Really gotta re-write that XML
-    # loading/merging stuff.
     noclasspath=hasDomChild(ddom,'noclasspath')    
         
     # Construct the dependency

Modified: gump/live/python/gump/core/model/module.py
URL: http://svn.apache.org/viewcvs/gump/live/python/gump/core/model/module.py?view=diff&r1=159458&r2=159459
==============================================================================
--- gump/live/python/gump/core/model/module.py (original)
+++ gump/live/python/gump/core/model/module.py Tue Mar 29 18:22:36 2005
@@ -57,8 +57,9 @@
             root+=str(self.repository.getHostname()) + ':'
             
             # :TODO: Allow users to override default port
-            if str(self.repository.getMethod())=='pserver': 
-                root+='2401'
+            # this is throwing off the kaffe.org cvs repository...
+            #if str(self.repository.getMethod())=='pserver': 
+            #    root+='2401'
         root+=str(self.repository.getPath())
         
         # If a subdirectory
@@ -402,10 +403,16 @@
                         os.path.join(workspace.getBaseDirectory(),	
                                 self.workdir))
         
-        self.absSrcCtlDir=	\
+        self.absSrcCtlDir=    \
                  os.path.abspath(
-                         os.path.join(	workspace.getSourceControlStagingDirectory(), 
+                         os.path.join(    workspace.getSourceControlStagingDirectory(), 
                                             self.getName())) # todo allow override              
+
+        # For when multiple gump runs share (on posix)
+        self.absUpdateLock=    \
+                 os.path.abspath(
+                         os.path.join(    workspace.getSourceControlStagingDirectory(), 
+                                            self.getName() + '.lock'))
                                
         # :TODO: Consolidate this code, less cut-n-paste but also
         # check the 'type' of the repository is appropriate for the
@@ -673,6 +680,9 @@
         
     def getSourceControlStagingDirectory(self):
         return self.absSrcCtlDir
+        
+    def getUpdateLockFile(self):
+        return self.absUpdateLock
         
     def getWorkingDirectory(self):
         return self.absWorkingDir

Modified: gump/live/python/gump/core/model/object.py
URL: http://svn.apache.org/viewcvs/gump/live/python/gump/core/model/object.py?view=diff&r1=159458&r2=159459
==============================================================================
--- gump/live/python/gump/core/model/object.py (original)
+++ gump/live/python/gump/core/model/object.py Tue Mar 29 18:22:36 2005
@@ -156,6 +156,9 @@
         Annotatable.dump(self,indent,output)
     
     # Helper methods
+    def domAttributeIsTrue(self,name):
+        return domAttributeIsTrue(self.element,name)
+        
     def hasDomAttribute(self,name):
         return hasDomAttribute(self.element,name)
     

Modified: gump/live/python/gump/core/run/__init__.py
URL: http://svn.apache.org/viewcvs/gump/live/python/gump/core/run/__init__.py?view=diff&r1=159458&r2=159459
==============================================================================
--- gump/live/python/gump/core/run/__init__.py (original)
+++ gump/live/python/gump/core/run/__init__.py Tue Mar 29 18:22:36 2005
@@ -19,10 +19,25 @@
 # 
 
 """
+Gump works in a batch mode. Doing one iteration of cvs and svn updates
+and then building all the different projects is called a single "gump
+run". Such a run is modelled by gump.core.run.gumprun.GumpRun.
 
-  Gump Run Components.
-  
+A run is split into several stages:
+
+    1) setup work (parsing commands, merging xml files, etc)
+    2) general build work (initializing and setting up helpers,
+       performing per-run tasks)
+    3) per-module and per-project work (ie updates and builds
+       and whatever different "actors" do on a per-module or
+       per-project basis)
+    3) post-build work (cleaning up, sending out e-mail, etc)
+
+Each of these stages is handled by the gump.core.runner package. The
+gump.core.run package defines what should happen during any such run,
+and is the place where the runner and actors keep track of what is
+going on.
 """
 
-# tell Python what modules make up the gump.core package
+# tell Python what modules make up the gump.run package
 __all__ = ["actor","gumpenv","gumprun","options", "gumpset"]

Modified: gump/live/python/gump/core/run/actor.py
URL: http://svn.apache.org/viewcvs/gump/live/python/gump/core/run/actor.py?view=diff&r1=159458&r2=159459
==============================================================================
--- gump/live/python/gump/core/run/actor.py (original)
+++ gump/live/python/gump/core/run/actor.py Tue Mar 29 18:22:36 2005
@@ -16,7 +16,6 @@
 # limitations under the License.
 
 """
-
 	An actor works upon the context tree. Events (and in the future,
 	perhaps Requests) are passed to the Actor, and the Actor performs
 	it's work.
@@ -33,12 +32,10 @@
 import sys
 from fnmatch import fnmatch
 
-from gump import log
 from gump.core.config import dir, default, basicConfig
 from gump.core.run.gumpenv import GumpEnvironment
 from gump.core.run.gumprun import *
 
-
 from gump.util.work import *
 from gump.util import dump, display, getIndent
 from gump.util.note import Annotatable
@@ -49,28 +46,23 @@
 from gump.core.model.depend import  ProjectDependency
 from gump.core.model.state import *
 
-
-    
-###############################################################################
-# Functions
-###############################################################################
-
-###############################################################################
-# Classes
-###############################################################################
-
-
-        
 class  RunActor(RunSpecific):     
     """
-    
-        An actor acts upon the run result events.
-        
+        Abstract base class for all actors. The gump runner fires off different
+        kinds of "events" (really just bits of the context trees that the gump
+        runner has just updated then built) to the actor.
+        
+        This base class sets up some class properties that are often used in
+        subclasses, and defines a base _processEvent that fires off processEvent
+        on subclasses only if that method exists on the subclass.
     """
     
-    def __init__(self, run):
+    def __init__(self, run, log = None):
         RunSpecific.__init__(self,run)
         
+        if not log: from gump import log
+        self.log = log
+        
         # Oft used references..
         self.workspace=run.getWorkspace()
         self.options=run.getOptions()
@@ -89,13 +81,34 @@
         #log.debug('Process event [' + `event` + '] using [' + `self` + ']')        
         self.processEvent(event)
 
-class AbstractRunActor(RunActor):    
+class AbstractRunActor(RunActor):
+    """
+    Abstract base class for nearly all actors. It acts as a basic event filter,
+    sending different types of events to different methods in the subclass if
+    those are defined. The supported methods are:
     
-    def __init__(self, run):
-        RunActor.__init__(self,run)
-        
+        processRun() -- for events of the GumpRun type. Use this one for doing
+                start-of-run setup work.
+        processWorkspace() -- fed the Workspace for this run after it is fully
+                set up. Use this one for customizing the actor's behaviour
+                based on the workspace and performing any late initialization.
+        processModule() -- fed the Module instance for each and every module that
+                has been processed by the main runner (ie, has been updated).
+        processProject() -- fed the Project instance for each and every project
+                that has been built by the main runnner (whether successful or
+                not).
+        processOtherEvent() -- fed all the other events (ie the ones that
+                AbstractRunActor doesn't know about).
+    """
+    
+    def __init__(self, run, log=None):
+        RunActor.__init__(self, run, log)
         
     def processEvent(self,event):
+        """
+        Event handler that redirects to each of the _processXXXEvent methods,
+        which in turn delegate to processXXXEvent methods on subclasses.
+        """
         
         if isinstance(event,EntityRunEvent):
             entity=event.getEntity()
@@ -112,58 +125,54 @@
         else:
             self._processOtherEvent(event)
             
-            
-    #
-    # Call a method called 'processRun(Run)', if it
-    # is available on the sub-class (i.e. if needed)
-    #
     def _processRun(self):
+        """
+        Call a method called 'processRun(Run)', if it
+        is available on the sub-class (i.e. if needed)
+        """
         if not hasattr(self,'processRun'): return        
         if not callable(self.processRun):  return        
-        log.debug('Process Run using [' + `self` + ']')        
+        self.log.debug('Process Run using [' + `self` + ']')        
         self.processRun()
         
             
-    #
-    # Call a method called 'processWorkspace(workspace)', if it
-    # is available on the sub-class (i.e. if needed)
-    #
     def _processWorkspace(self,workspace):
+        """
+        Call a method called 'processWorkspace(workspace)', if it
+        is available on the sub-class (i.e. if needed)
+        """
         if not hasattr(self,'processWorkspace'): return        
         if not callable(self.processWorkspace):  return        
-        log.debug('Process Workspace [' + `workspace` + '] using [' + `self` + ']')        
+        self.log.debug('Process Workspace [' + `workspace` + '] using [' + `self` + ']')        
         self.processWorkspace()
         
-    #
-    # Call a method called 'processModule(module)', if it
-    # is available on the sub-class (i.e. if needed)
-    #
     def _processModule(self,module):
+        """
+        Call a method called 'processModule(module)', if it
+        is available on the sub-class (i.e. if needed)
+        """
         if not hasattr(self,'processModule'): return        
         if not callable(self.processModule):  return        
-        log.debug('Process Module [' + `module` + '] using [' + `self` + ']')        
+        self.log.debug('Process Module [' + `module` + '] using [' + `self` + ']')        
         self.processModule(module)
         
             
-    #
-    # Call a method called 'processProject(Project)', if it
-    # is available on the sub-class (i.e. if needed)
-    #
     def _processProject(self,project):
+        """
+        Call a method called 'processProject(Project)', if it
+        is available on the sub-class (i.e. if needed)
+        """
         if not hasattr(self,'processProject'): return        
         if not callable(self.processProject):  return        
-        log.debug('Process Project [' + `project` + '] using [' + `self` + ']')        
+        self.log.debug('Process Project [' + `project` + '] using [' + `self` + ']')        
         self.processProject(project)
-        
-            
-    #
-    # Call a method called 'processOtherEvent(event)', if it
-    # is available on the sub-class (i.e. if needed)
-    #
+               
     def _processOtherEvent(self,event):
+        """
+        Call a method called 'processOtherEvent(event)', if it
+        is available on the sub-class (i.e. if needed)
+        """
         if not hasattr(self,'processOtherEvent'): return        
         if not callable(self.processOtherEvent):  return        
-        log.debug('Process (Other) Event [' + `event` + '] using [' + `self` + ']')        
+        self.log.debug('Process (Other) Event [' + `event` + '] using [' + `self` + ']')        
         self.processOtherEvent(event)
-        
-            

Modified: gump/live/python/gump/core/run/gumpenv.py
URL: http://svn.apache.org/viewcvs/gump/live/python/gump/core/run/gumpenv.py?view=diff&r1=159458&r2=159459
==============================================================================
--- gump/live/python/gump/core/run/gumpenv.py (original)
+++ gump/live/python/gump/core/run/gumpenv.py Tue Mar 29 18:22:36 2005
@@ -1,6 +1,5 @@
 #!/usr/bin/python
-
-
+#
 # Copyright 2003-2004 The Apache Software Foundation
 #
 # Licensed under the Apache License, Version 2.0 (the "License");
@@ -16,8 +15,15 @@
 # limitations under the License.
 
 """
- A gump environment (i.e. what tools are available in this machine's
- environment, and so forth).
+    A gump environment (i.e. what tools are available in this machine's
+    environment, and so forth).
+    
+    TODO: a lot of this stuff needs to be available in other environments
+    as well, for example when we run dynagump or the unit tests we also
+    want to know about our environment. Either this class is refactored so
+    as to be much more decoupled from the rest of gump or we simply move
+    this functionality out into the shell script code so we can get rid of
+    it here.
 """
 
 import os.path
@@ -25,8 +31,6 @@
 from types import NoneType
 from fnmatch import fnmatch
 
-from gump import log
-
 from gump.core.config import *
 
 from gump.util.note import Annotatable
@@ -40,33 +44,35 @@
 from gump.core.model.state import *
 from gump.core.model.propagation import *
 
-from gump.tool.integration.depot import *
-    
-###############################################################################
-# Classes
-###############################################################################
 
+#TODO: any reason checkEnvironment can't simply be called once (on __init__)
+#      and after that simply used? It'd certainly simplify the code a bit..
 class GumpEnvironment(Annotatable,Workable,Propogatable):
     """
-    	Represents the environment that Gump is running within.
-    	
-    	What environment variables are set, what tools are 
-    	available, what Java command to use, etc.
+    Represents the environment that Gump is running within.
+    
+    What environment variables are set, what tools are 
+    available, what Java command to use, etc.
+    
+    If some required bit of environment is missing, this class will actually
+    short-circuit gump and call sys.exit.
     """
 
-    def __init__(self):
+    def __init__(self, log = None):
         Annotatable.__init__(self)
         Workable.__init__(self)
         Propogatable.__init__(self)
-        Stateful.__init__(self)
+        #Stateful.__init__(self) -- redundant, already called from Propogatable.__init__
+        
+        if not log: from gump import log
+        self.log = log
         
         self.checked = False
         self.set = False
     	
         self.noMono = False
         self.noNAnt = False    
-        self.noMaven = False    	 
-        self.noDepot = False    	
+        self.noMaven = False    	
         self.noSvn = False    	
         self.noCvs = False   
         self.noP4 = False   
@@ -84,16 +90,13 @@
         self.javaCommand = 'java'
         self.javacCommand = 'javac'
         
-        # DEPOT_HOME
-        self.depotHome = None
-        
         # Timezone and offset from UTC
         self.timezone = time.tzname
         self.timezoneOffset = time.timezone
         
     def checkEnvironment(self,exitOnError=False):
         """ 
-        Check things that are required/optional 
+        Take a look at the environment and populate this object's properties based on that.
         """
         
         if self.checked: return
@@ -123,12 +126,6 @@
             self.noMaven=True
             self.addWarning('MAVEN_HOME environmental variable not found, no maven builds.')
             
-        if not self.noDepot and not self._checkEnvVariable('DEPOT_HOME',False): 
-            self.noDepot=True
-            self.addWarning('DEPOT_HOME environmental variable not found, no depot downloads.')
-        
-        self.depotHome = getDepotHome(False)
-            
         # Check for executables
         
         self._checkExecutable('env','',False)
@@ -155,11 +152,6 @@
             self.noP4=True
             self.addWarning('"p4" command not found, no Perforce repository updates')
           
-        if not self.noDepot and \
-            not self._checkExecutable(getDepotUpdateCmd(),'-version',False,False,'check_depot_update'): 
-            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'): 
             self.noMaven=True
@@ -186,7 +178,7 @@
         
     def setEnvironment(self):
         """ 
-        Set things that are required 
+        Customize the actual environment to reflect the way gump needs things to be.
         """
         
         if self.set: return
@@ -219,7 +211,7 @@
         self.checkEnvironment()
         
         if self.noJavac: 
-            log.error("Can't obtain Java properties since Java Environment was not found")
+            self.log.error("Can't obtain Java properties since Java Environment was not found")
             return {}
 
         import commands, re
@@ -252,11 +244,14 @@
         if os.path.exists(JAVA_CLASS): os.unlink(JAVA_CLASS)
 
         for (name,value) in self.javaProperties.items():
-            log.debug("Java Property: " + name + " => " + value)
+            self.log.debug("Java Property: " + name + " => " + value)
 
         return self.javaProperties
 
     def _checkExecutable(self,command,options,mandatory,logOutput=False,name=None):
+        """
+        Determine whether a particular command is or is not available.
+        """
         ok = False
         try:
             if not name: name = 'check_'+command
@@ -264,12 +259,12 @@
             result = execute(cmd)
             ok = result.isOk()
             if ok:
-                log.warning('Detected [' + command + ' ' + options + ']')   
+                self.log.warning('Detected [' + command + ' ' + options + ']')   
             else:
-                log.warning('Failed to detect [' + command + ' ' + options + ']')   
+                self.log.warning('Failed to detect [' + command + ' ' + options + ']')   
         except Exception, details:
             ok = False
-            log.error('Failed to detect [' + command + ' ' + options + '] : ' + str(details))
+            self.log.error('Failed to detect [' + command + ' ' + options + '] : ' + str(details))
             result = None
        
         # Update 
@@ -290,15 +285,18 @@
         return ok
     
     def _checkEnvVariable(self,env,mandatory=True):
+        """
+        Determine whether a particular environment variable is set.
+        """
         ok = False
         try:
             ok = os.environ.has_key(env)
             if not ok:
-                log.info('Failed to find environment variable [' + env + ']')
+                self.log.info('Failed to find environment variable [' + env + ']')
         
         except Exception, details:
             ok = False
-            log.error('Failed to find environment variable [' + env + '] : ' + str(details))
+            self.log.error('Failed to find environment variable [' + env + '] : ' + str(details))
     
         if not ok and mandatory:
             print

Modified: gump/live/python/gump/core/run/gumprun.py
URL: http://svn.apache.org/viewcvs/gump/live/python/gump/core/run/gumprun.py?view=diff&r1=159458&r2=159459
==============================================================================
--- gump/live/python/gump/core/run/gumprun.py (original)
+++ gump/live/python/gump/core/run/gumprun.py Tue Mar 29 18:22:36 2005
@@ -24,7 +24,6 @@
  It contains the gumpset (the list of projects/modules to work upon)
  It contains the workspace (metadata)
  It contains the tree of context (run information upon metadata items)
-  
  
 """
 
@@ -33,7 +32,6 @@
 import sys
 import fnmatch
 
-from gump import log
 from gump.core.config import dir, default, basicConfig
 from gump.core.run.gumpenv import GumpEnvironment
 
@@ -50,26 +48,32 @@
 from gump.core.model.depend import  ProjectDependency
 from gump.core.model.state import *
     
-###############################################################################
-# Init
-###############################################################################
-
-###############################################################################
-# Classes
-###############################################################################
-
-
 class GumpRun(gump.util.timing.Timeable,gump.util.work.Workable,gump.util.note.Annotatable,Stateful):
     """
-    The container for all information for this run
+    The container for all information for this run.
+    
+    A GumpRun is "passive", it doesn't really do much of itself. (TODO: refactor
+    so that it does absolutely *nothing*). That is what the gump.core.runner
+    package is for.
+    
+    The GumpRun is pretty central to all the stuff going on during a gump run,
+    obviously. It serves as the main communication point between the runner, its
+    helpers, and all the different actors.
+    
+    TODO: evaluate making this class less central and splitting its various
+          responsibilities into multiple smaller classes. Making this class so
+          central to everything is what promotes most of the "monolithic" feel
+          of the gump architecture right now.
     """
-    def __init__(self,workspace,expr=None,options=None,env=None):
-        
+    def __init__(self,workspace,expr=None,options=None,env=None,log=None):
         gump.util.work.Workable.__init__(self)
         gump.util.note.Annotatable.__init__(self)
         Stateful.__init__(self)
         gump.util.timing.Timeable.__init__(self, workspace.getName())
         
+        if not log: from gump import log
+        self.log = log
+        
         # The workspace being worked upon
         self.workspace=workspace
         
@@ -99,7 +103,7 @@
         self.guid = socket.getfqdn()  + ':' + workspace.getName() + ':' + default.datetime_s
         m.update(self.guid)
         self.hexguid=m.hexdigest().upper()     
-        log.info('Run GUID [' + `self.guid` + '] using [' + `self.hexguid` + ']')    
+        self.log.info('Run GUID [' + `self.guid` + '] using [' + `self.hexguid` + ']')    
         
         # Actor Queue
         self.actors=list()
@@ -162,22 +166,22 @@
         self.gumpSet.dump(indent+1,output)
        
     def registerActor(self,actor):
-        log.debug('Register Actor : ' + `actor`)
+        self.log.debug('Register Actor : ' + `actor`)
         self.actors.append(actor)
         
     def logActors(self):
-        log.debug('There are %s registered actors : ' % len(self.actors))       
+        self.log.debug('There are %s registered actors : ' % len(self.actors))       
         for actor in self.actors:
-            log.debug('Registered Actor : ' + `actor`)    
+            self.log.debug('Registered Actor : ' + `actor`)    
             
         
     def _dispatchEvent(self,event):    	
     	"""
     		Perform the dispatch
     	"""
-        log.debug('Dispatch Event : ' + `event`)        
+        self.log.debug('Dispatch Event : ' + `event`)        
         for actor in self.actors:
-            #log.debug('Dispatch Event : ' + `event` + ' to ' + `actor`)     
+            #self.log.debug('Dispatch Event : ' + `event` + ' to ' + `actor`)     
             actor._processEvent(event)
         gump.util.inspectGarbageCollection(`event`)
             
@@ -185,9 +189,9 @@
     	"""
     		Perform the dispatch
     	"""
-        log.debug('Dispatch Request : ' + `request`)    
+        self.log.debug('Dispatch Request : ' + `request`)    
         for actor in self.actors:
-            #log.debug('Dispatch Request : ' + `request` + ' to ' + `actor`)       
+            #self.log.debug('Dispatch Request : ' + `request` + ' to ' + `actor`)       
             actor._processRequest(request)
         gump.util.inspectGarbageCollection(`request`)
             
@@ -212,16 +216,27 @@
         the basis for everything, so many things are specific
         to a single run (for conveinience).
         
+        TODO: this is used both as a "marker interface" and as a
+        general way to get at the global "context" represented by
+        the GumpRun instance. If we can remove it from as many
+        classes as possible that'll promote a *lot* of seperation
+        of concerns and establishment of control barriers.
     """
     def __init__(self, run):
-        self.run    =    run
+        self.run = run
         
     def getRun(self):
         return self.run
 
 class RunEvent(RunSpecific):
     """
-        An event to actors (e.g. a project built, a module updated)
+        An event to actors (e.g. a project built, a module updated).
+        
+        Note that not all events currently passed around are really
+        "events", for example, we pass around actual Workspace and
+        Project model elements as if they were "events", by encapsulating
+        them into an EntityRunEvent. It is up to the actors to make sense
+        of why the entity is an event.
     """
             
     def __init__(self, run):
@@ -244,9 +259,8 @@
         
 class EntityRunEvent(RunEvent):
     """
-    
-        An event to actors (e.g. a project built, a module updated)
-        
+        An event to actors (e.g. a project built, a module updated) that is
+        associated with a particular piece of the gump model.
     """
             
     def __init__(self, run, entity, realtime=0):
@@ -261,15 +275,13 @@
     def getEntity(self):
         return self.entity 
         
-    def isRealtime(self):
+    def isRealtime(self): #TODO: what is "realtime"?
         return self.realtime    
         
                 
 class RunRequest(RunEvent):
     """
-    
         A request for some work (not used yet)
-
     """            
     def __init__(self, run, type):
         RunEvent.__init__(self,run)
@@ -284,10 +296,8 @@
         
 class EntityRunRequest(RunEvent):
     """
-    
         An request regarding a known entity (e.g. Workspace/Module/Project).
         (not used yet)
-        
     """
     def __init__(self, run, type, entity):
         RunEvent.__init__(self, run, type)

Modified: gump/live/python/gump/core/run/options.py
URL: http://svn.apache.org/viewcvs/gump/live/python/gump/core/run/options.py?view=diff&r1=159458&r2=159459
==============================================================================
--- gump/live/python/gump/core/run/options.py (original)
+++ gump/live/python/gump/core/run/options.py Tue Mar 29 18:22:36 2005
@@ -54,6 +54,7 @@
 OBJECTIVE_REDO=OBJECTIVE_UPDATE | OBJECTIVE_BUILD
 OBJECTIVE_INTEGRATE=OBJECTIVE_UPDATE | OBJECTIVE_BUILD | \
                         OBJECTIVE_DOCUMENT
+OBJECTIVE_OFFLINE=OBJECTIVE_BUILD | OBJECTIVE_DOCUMENT
 
 # Features            
 FEATURE_UNSET=0

Modified: gump/live/python/gump/core/runner/__init__.py
URL: http://svn.apache.org/viewcvs/gump/live/python/gump/core/runner/__init__.py?view=diff&r1=159458&r2=159459
==============================================================================
--- gump/live/python/gump/core/runner/__init__.py (original)
+++ gump/live/python/gump/core/runner/__init__.py Tue Mar 29 18:22:36 2005
@@ -1,6 +1,5 @@
 #!/usr/bin/env python
-
-#!/usr/bin/env python
+#
 # Copyright 2003-2004 The Apache Software Foundation
 #
 # Licensed under the Apache License, Version 2.0 (the "License");
@@ -15,7 +14,15 @@
 # See the License for the specific language governing permissions and
 # limitations under the License.
 
-# tell Python what modules make up the gump.test package
-__all__ = ["runner","demand","tasks"]
+# tell Python what modules make up the gump.runner package
+__all__ = ["runner","demand"]
+
+"""
+The gump.runner module contains the "main application loop" for a gump run.
+This is the place where threads are spawned, the project build list is
+iterated over, etcetera. Responsibility is split between the abstract
+GumpRunner class (which does basic setup) and subclasses that customize
+behaviour like multithreading and/or which actors are run.
 
-    
+Which runner to use is determined using the gump.runner.getRunner() method.
+"""
\ No newline at end of file

Modified: gump/live/python/gump/core/runner/demand.py
URL: http://svn.apache.org/viewcvs/gump/live/python/gump/core/runner/demand.py?view=diff&r1=159458&r2=159459
==============================================================================
--- gump/live/python/gump/core/runner/demand.py (original)
+++ gump/live/python/gump/core/runner/demand.py Tue Mar 29 18:22:36 2005
@@ -15,17 +15,9 @@
 # See the License for the specific language governing permissions and
 # limitations under the License.
 
-"""
-
-	The OnDemand runner performs a run, but does work on
-	modules as the needs of projects demands it.
-
-"""
-
 import os.path
 import sys
 
-from gump import log
 from gump.core.run.gumprun import *
 from gump.core.runner.runner import *
 from gump.core.config import dir, default, basicConfig
@@ -45,34 +37,23 @@
 from gump.core.model.state import *
 
 from gump.util.threads.tools import *
+from gump.util.locks import *
 
-
-###############################################################################
-# Classes
-###############################################################################
-  
-class UpdateWork:
-    def __init__(self,runner,module):
-        self.runner=runner
-        self.module=module
-        
-    def __str__(self):
-        return 'UpdateWork:'+`self.module`
-        
-class UpdateWorker(WorkerThread):
-    def performWork(self,work):
-        # Do the work...
-        work.runner.performUpdate(work.module)
-        
 class OnDemandRunner(GumpRunner):
+    """
+	The OnDemand runner updates modules just-in-time before a project is built.
+	
+	However, if gump is configured for multithreading, it also spawns several updater
+	threads in the background which do module updates. This is an effort to maximize
+	network and disk I/O.
+    """
 
-    def __init__(self,run):
-        GumpRunner.__init__(self,run)
+    def __init__(self, run, log=None):
+        GumpRunner.__init__(self,run,log)
 
-    ###########################################
     def spawnUpdateThreads(self, updaters=1):
         """
-        Fork off a bunch of threads.
+        Fork off a bunch of threads for running module updates.
         """
         
         self.workList=ThreadWorkList('Updates')
@@ -93,36 +74,51 @@
         
     def performUpdate(self,module):
         """
-        
-        	Perform a module update (locking whilst doing it)	
+        	Perform the (cvs,svn) update of a single module.
         	
+        	The module is locked during the update. Most of the actual work
+        	is delegated to the updater that's provided by the parent GumpRunner
+        	class.
         """
-        
-        # Lock the module, while we work on it...
-        lock=module.getLock()
-        
+        flock=None
         try:
-            lock.acquire()
+            # Only on POSIX can we block on a file lock,
+            # so only here do we support shared update
+            # staging areas.
+            if 'posix'==os.name:
+                flock = acquireLock(module.getUpdateLockFile())
+              
+            # Normal thread locking...
+            lock=module.getLock()
+            try:
+                lock.acquire()
         
-            if not module.isUpdated():
+                if not module.isUpdated():
                 
-                # Perform Update
-                self.updater.updateModule(module)         
+                    # Perform Update
+                    self.updater.updateModule(module)         
         
-                # Fire event
-                self.run.generateEvent(module)
+                    # Fire event
+                    self.run.generateEvent(module)
         
-                # Mark as done in set
-                self.run.gumpSet.setCompletedModule(module)
+                    # Mark as done in set
+                    self.run.gumpSet.setCompletedModule(module)
                 
-                # Mark Updated
-                module.setUpdated(True)
+                    # Mark Updated
+                    module.setUpdated(True)
+            finally:
+                lock.release()
         finally:
-            lock.release()
+            if flock:
+                releaseLock(flock,module.getUpdateLockFile())
+            
             
     def performBuild(self,project):
         """
-            Perform a project build
+            Perform the actual (ant,maven,make) build of a single project.
+            
+            Most of the actual work is delegated to the builder that's
+            provided by the parent GumpRunner class.
         """
             
         # Perform the build action
@@ -134,11 +130,8 @@
         # Mark completed
         self.run.getGumpSet().setCompletedProject(project)
         
-    ###########################################
-
     def performRun(self):
         """
-        
         	Perform a run, building projects (and updating modules)
         	as needed.
         	
@@ -149,6 +142,9 @@
         	Fire events (1) before everything (2) for each entity
         	[module or project] and (3) after everything.
         	
+        	You may think of this method as performing "all the real beef" for
+        	a gump run, delegating to lots of different helpers and actors in
+        	the process.
         """
         # Initialize to run
         self.initialize(True)
@@ -189,7 +185,7 @@
             if gumpOptions.isUpdate():
                 # W/ multiple project in one module, it may be done
                 if not module.isUpdated():
-                    log.debug('Update module *inlined* (not in background thread) ' + `module` + '.')     
+                    self.log.debug('Update module *inlined* (not in background thread) ' + `module` + '.')     
                     inlined+=1
                     self.performUpdate(module)
 
@@ -223,3 +219,24 @@
             result = EXIT_CODE_FAILED
             
         return result  
+
+class UpdateWork:
+    """
+    Simple internal helper class which defines a unit of module updating work that can be
+    handled by one of the update workers.
+    """
+    def __init__(self,runner,module):
+        self.runner=runner
+        self.module=module
+        
+    def __str__(self):
+        return 'UpdateWork:'+`self.module`
+        
+class UpdateWorker(WorkerThread):
+    """
+    Simple internal worker thread which performs one unit of module updating work (one
+    UpdateWork) each time it is fired up.
+    """
+    def performWork(self,work):
+        # Do the work...
+        work.runner.performUpdate(work.module)

Modified: gump/live/python/gump/core/runner/runner.py
URL: http://svn.apache.org/viewcvs/gump/live/python/gump/core/runner/runner.py?view=diff&r1=159458&r2=159459
==============================================================================
--- gump/live/python/gump/core/runner/runner.py (original)
+++ gump/live/python/gump/core/runner/runner.py Tue Mar 29 18:22:36 2005
@@ -15,15 +15,9 @@
 # See the License for the specific language governing permissions and
 # limitations under the License.
 
-"""
-
-"""
-
 import os.path
 import sys
 
-from gump import log
-
 from gump.core.update.updater import *
 from gump.core.build.builder import *
 
@@ -41,43 +35,57 @@
 from gump.actor.results.resulter import Resulter
 from gump.actor.syndication.syndicator import Syndicator
 
-###############################################################################
-# Classes
-###############################################################################
-
-
 class GumpRunner(RunSpecific):
+    """
+    Base class for other runners that initializes several helper objects.
+    
+    the lifecycle for this class is as follows:
+    
+        runner.initialize() # set up environment
+        runner.perform()    # delegates to subclass to perform actual work
+        runner.finalize()   # do some cleanup work
+    """
 
-    def __init__(self, run):
-        
-        #
+    def __init__(self, run, log=None):
         RunSpecific.__init__(self, run)
         
-        # Main players (soon we ought make
-        # them into actors, like the others).         
-        self.updater=GumpUpdater(run)
-        self.builder=GumpBuilder(run)
+        if not log: from gump import log
+        self.log = log
         
+        # Main players (soon we ought make them into actors, like the others).         
+        self.updater = GumpUpdater(run)
+        self.builder = GumpBuilder(run)
         
         # A helper per language/type
-        self.java=gump.core.language.java.JavaHelper(run)
-        self.csharp=gump.core.language.csharp.CSharpHelper(run)
+        self.java = gump.core.language.java.JavaHelper(run)
+        self.csharp = gump.core.language.csharp.CSharpHelper(run)
         
         # Stash them for reference...
         run.setUpdater(self.updater)
-        run.setBuilder(self.builder)    
+        run.setBuilder(self.builder)
             
         run.addLanguageHelper(Project.JAVA_LANGUAGE,self.java)  
         run.addLanguageHelper(Project.CSHARP_LANGUAGE,self.csharp)
         
     def initialize(self,exitOnError=True):
+        """
+        Set up all of the neccessary resources for the subclass implementation to use.
+        Besides modifying the properties of this class, we also modify bits of the
+        workspace and bits of the GumpRun instance.
+        
+        TODO: currently this method must be called from the performRun() method of the
+        subclass. Call it from perform() instead.
+        
+        TODO: clean this up and have a clear responsibility split between the various
+        parts we're modifying here...
+        """
         
         logResourceUtilization('Before initialize')
         
         # Perform start-up logic 
         workspace = self.run.getWorkspace()
                 
-        #Check out environment
+        # Check out environment
         if not self.run.getOptions().isQuick():
             logResourceUtilization('Before check environment')            
             self.run.getEnvironment().checkEnvironment(exitOnError)
@@ -94,13 +102,12 @@
         if not workspace.getVersion() >= setting.WS_VERSION:
             message='Workspace version ['+str(workspace.getVersion())+'] below preferred [' + setting.WS_VERSION + ']'
             workspace.addWarning(message)
-            log.warn(message)   
-            
-        # Check the workspace
+            self.log.warn(message)   
+
         if not workspace.getVersion() >= setting.WS_MINIMUM_VERSION:
             message='Workspace version ['+str(workspace.getVersion())+'] below minimum [' + setting.WS_MINIMUM_VERSION + ']'
             workspace.addError(message)
-            log.error(message)   
+            self.log.error(message)   
             
         # Write workspace to a 'merge' file        
         if not self.run.getOptions().isQuick():
@@ -118,7 +125,13 @@
     
     def initializeActors(self):
         """
-        Install the appropriate actors..
+        Populate the GumpRun instance with the various actors.
+        
+        The actors handle all the "optional" behaviour like writing HTML or sending e-mail. One
+        way to think of this method is where we configure the "glue" between all the different
+        bits and pieces of the application.
+        
+        TODO:
         """
         
         # Stamp times
@@ -141,10 +154,10 @@
                 import gump.actor.mysql.databaser
                 self.run.registerActor(gump.actor.mysql.databaser.Databaser(self.run))
             except Exception, details:
-                log.warning('Unable to register Database Actor :  %s ' % details,
+                self.log.warning('Unable to register Database Actor :  %s ' % details,
                             exc_info=1)
         
-        # Add Historical Database storer
+        # Add Historical Database storer -- ??? no such thing...
         if self.run.getOptions().isOfficial() and \
             self.run.getWorkspace().hasDatabaseInformation() and \
             self.run.getOptions().isHistorical():       
@@ -152,8 +165,19 @@
                 import gump.actor.history.historical
                 self.run.registerActor(gump.actor.history.historical.Historical(self.run))
             except Exception, details:
-                log.warning('Unable to register Historical Database Actor :  %s ' % details,
+                self.log.warning('Unable to register Historical Database Actor :  %s ' % details,
                             exc_info=1)
+
+        # Add Dynagump database populator
+        if self.run.getWorkspace().hasDatabaseInformation():
+            # create the database helper
+            dbInfo = self.run.getWorkspace().getDatabaseInformation()
+            from gump.util.mysql import Database
+            database = Database(dbInfo)
+
+            # now create the Dynagumper using that database
+            import gump.actor.mysql.dynagumper
+            self.run.registerActor(gump.actor.mysql.dynagumper.Dynagumper(self.run,database))
         
         # Document..
         # Use XDOCS if not overridden...
@@ -179,7 +203,7 @@
                 import gump.actor.rdf.describer
                 self.run.registerActor(gump.actor.rdf.describer.RDFDescriber(self.run))   
             except Exception, details:
-                log.warning('Unable to register RDF Describer :  %s ' % details,
+                self.log.warning('Unable to register RDF Describer :  %s ' % details,
                             exc_info=1)
             
         # Publish artifacts
@@ -208,10 +232,10 @@
     def getBuilder(self):
         return self.builder
    
-    #
-    # Call a method called 'documentRun(run)'
-    #
     def perform(self):
+        """
+        Does the actual gump work by delegating to the performRun(run) method of a subclass.
+        """
         if not hasattr(self,'performRun'):
             raise RuntimeError, \
                     'Class [' + `self.__class__` + '] needs a performRun(self,run)'
@@ -220,10 +244,13 @@
             raise RuntimeError, \
                     'Class [' + `self.__class__` + '] needs a callable performRun(self,run)'
         
-        log.debug('Perform run using [' + `self` + ']')
+        self.log.debug('Perform run using [' + `self` + ']')
         
         return self.performRun()
 
 def getRunner(run):
+    """
+    Factory method that provides the default GumpRunner subclass to use.
+    """
     from gump.core.runner.demand import OnDemandRunner
     return OnDemandRunner(run)

Modified: gump/live/python/gump/core/update/updater.py
URL: http://svn.apache.org/viewcvs/gump/live/python/gump/core/update/updater.py?view=diff&r1=159458&r2=159459
==============================================================================
--- gump/live/python/gump/core/update/updater.py (original)
+++ gump/live/python/gump/core/update/updater.py Tue Mar 29 18:22:36 2005
@@ -30,7 +30,6 @@
 from gump.core.update.cvs import CvsUpdater
 from gump.core.update.svn import SvnUpdater
 from gump.core.update.p4 import P4Updater
-from gump.core.update.artifact import ArtifactUpdater
 
 from gump.util import dump, display, getIndent, logResourceUtilization, \
                             invokeGarbageCollection
@@ -59,7 +58,6 @@
         self.cvs=CvsUpdater(run)
         self.svn=SvnUpdater(run)
         self.p4=P4Updater(run)
-        self.artifact=ArtifactUpdater(run)
 
     """
     
@@ -101,7 +99,7 @@
     
         workspace = self.run.getWorkspace()
         
-        log.debug("Workspace CVS|SVN|P4|artifacts Directory: " + workspace.getSourceControlStagingDirectory())
+        log.debug("Workspace CVS|SVN|P4 Directory: " + workspace.getSourceControlStagingDirectory())
 
         # Update all the modules that have CVS repositories
         for module in list: 
@@ -129,8 +127,6 @@
                 ok=self.svn.updateModule(module)
             if module.hasP4():
                 ok=self.p4.updateModule(module)
-            elif module.hasArtifacts():
-                ok=self.artifact.updateModule(module)        
             else:
                 # :TODO: Now what?
                 pass
@@ -205,7 +201,5 @@
             ok=self.svn.preview(module)
         elif module.hasP4():
             ok=self.p4.preview(module)
-        elif module.hasArtifacts():
-            ok=self.artifact.preview(module)        
         else:
             print 'No updater for module: ' + module.getName()            

Copied: gump/live/python/gump/test/testAllPyUnitTests.py.disabled.for.now (from r159424, gump/trunk/python/gump/test/testAllPyUnitTests.py.disabled.for.now)
URL: http://svn.apache.org/viewcvs/gump/live/python/gump/test/testAllPyUnitTests.py.disabled.for.now?view=diff&rev=159459&p1=gump/trunk/python/gump/test/testAllPyUnitTests.py.disabled.for.now&r1=159424&p2=gump/live/python/gump/test/testAllPyUnitTests.py.disabled.for.now&r2=159459
==============================================================================
    (empty)

Propchange: gump/live/python/gump/test/testAllPyUnitTests.py.disabled.for.now
------------------------------------------------------------------------------
    svn:eol-style = native

Modified: gump/live/python/gump/tool/integration/__init__.py
URL: http://svn.apache.org/viewcvs/gump/live/python/gump/tool/integration/__init__.py?view=diff&r1=159458&r2=159459
==============================================================================
--- gump/live/python/gump/tool/integration/__init__.py (original)
+++ gump/live/python/gump/tool/integration/__init__.py Tue Mar 29 18:22:36 2005
@@ -23,5 +23,5 @@
 ###############################################################################
 
 # tell Python what modules make up the gump.net package
-__all__ = ["cvs","depot"]
+__all__ = ["cvs"]
 

Modified: gump/live/python/gump/util/domutils.py
URL: http://svn.apache.org/viewcvs/gump/live/python/gump/util/domutils.py?view=diff&r1=159458&r2=159459
==============================================================================
--- gump/live/python/gump/util/domutils.py (original)
+++ gump/live/python/gump/util/domutils.py Tue Mar 29 18:22:36 2005
@@ -165,6 +165,11 @@
     if element.hasAttributes():
         return element.hasAttribute(name)
     return False
+    
+def domAttributeIsTrue(element,name):
+    return hasDomAttribute(element,name) and \
+               getDomAttributeValue(element,name) in ['true','True']
+     
 
 def getDomAttributeValue(element,name,default=None):
     return element.getAttribute(name) or default

Modified: gump/live/python/gump/util/locks.py
URL: http://svn.apache.org/viewcvs/gump/live/python/gump/util/locks.py?view=diff&r1=159458&r2=159459
==============================================================================
--- gump/live/python/gump/util/locks.py (original)
+++ gump/live/python/gump/util/locks.py Tue Mar 29 18:22:36 2005
@@ -22,35 +22,27 @@
 
 #-----------------------------------------------------------------------# 
         
-def establishLock(lockFile):
-
+def acquireLock(lockFile):
+    """ Block to ge an exclusive lock on a file. """
     failed=0
-    info=''
     if 'posix'==os.name:
         import fcntl
                 
         try:            
             lock=open(lockFile,'a+')
-            fcntl.flock(lock.fileno(), fcntl.LOCK_EX | fcntl.LOCK_NB)
+            fcntl.flock(lock.fileno(), fcntl.LOCK_EX)
         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)
+        raise RuntimeError, \
+            """The lock file [%s] could not be established.""" % lockFile
     
-    # Leave a mark...
+    # Write this PID into a lock file
     lock.write(`os.getpid()`)
     lock.flush()
         
@@ -75,4 +67,5 @@
         os.remove(lockFile)
     except:
         # Somehow another could delete this, even if locked...
+        # Or, could be in the process of locking it.
         pass

Modified: gump/live/python/gump/util/mysql.py
URL: http://svn.apache.org/viewcvs/gump/live/python/gump/util/mysql.py?view=diff&r1=159458&r2=159459
==============================================================================
--- gump/live/python/gump/util/mysql.py (original)
+++ gump/live/python/gump/util/mysql.py Tue Mar 29 18:22:36 2005
@@ -24,10 +24,82 @@
 import MySQLdb.cursors
 
 from gump import log
-  
+
+class Database:
+    """
+    Very simple database abstraction layer, basically adding some utilities
+    around MySQLdb and ability to parse the gump DatabaseInformation object.
+    
+    See http://www.python.org/peps/pep-0249.html for more on python and databases.
+    This class adheres to the PEP 249 Connection interface.
+    """
+    def __init__(self,dbInfo):
+        self._dbInfo=dbInfo
+        self._conn=None
+        
+    def __del__(self):
+        self.close()
+    
+    def commit(self):
+        """
+        See PEP 249.
+        """
+        pass
+    
+    def rollback(self):
+        """
+        See PEP 249.
+        """
+        pass
+    
+    def cursor(self):
+        """
+        See PEP 249.
+        """
+        return self._connection().cursor()
+
+    def close(self):
+        """
+        See PEP 249.
+        """
+        if self._conn:
+            self._conn.close()
+            self._conn=None
+
+    def execute(self, statement):
+        """
+        Simple helper method to execute SQL statements that isolates its users
+        from cursor handling.
+        
+        Pass in any SQL command. Retrieve back the results of having a cursor
+        execute that command (normally the number of affected rows).
+        """
+        cursor = None
+        try:
+            cursor = self._connection().cursor()
+            result = cursor.execute(cmd)
+            return result
+        finally:
+            if cursor: cursor.close()
+    
+    def _connection(self):
+        """
+        Get a connection to the actual database, setting one up if neccessary.
+        """
+        if not self._conn:
+            self._conn = MySQLdb.Connect(
+                    host=self._dbInfo.getHost(), 
+                    user=self._dbInfo.getUser(),
+                    passwd=self._dbInfo.getPasswd(), 
+                    db=self._dbInfo.getDatabase(),
+                    compress=1,
+                    cursorclass=MySQLdb.cursors.DictCursor)
+        
+        return self._conn
+
 class DbHelper:
     """
-    	MySQL Statistics Database Interface
+    	MySQL Statistics Database Helper
     """
 
     def __init__(self,conn,database='gump'):

Modified: gump/live/python/gump/util/process/launcher.py
URL: http://svn.apache.org/viewcvs/gump/live/python/gump/util/process/launcher.py?view=diff&r1=159458&r2=159459
==============================================================================
--- gump/live/python/gump/util/process/launcher.py (original)
+++ gump/live/python/gump/util/process/launcher.py Tue Mar 29 18:22:36 2005
@@ -22,6 +22,7 @@
 import sys
 import logging
 import signal
+import re
 
 from string import split
 
@@ -31,7 +32,8 @@
 from gump.util.timing import *
 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')
+# A separate launcher script/process is used on Windows, on Unix we fork/exec.
+LAUNCHER = os.path.join('python','gump','util','process','launcher.py')
 
 def execute(cmd,tmp=dir.tmp):
     res = command.CmdResult(cmd)
@@ -49,24 +51,29 @@
         # The command line
         execString = cmd.formatCommandLine()        
         
-        # Exec File
-        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'))
         if os.path.exists(outputFile): os.remove(outputFile)
-    
+
+        # Exec File
+        execFile = os.path.abspath(os.path.join(tmp,gumpSafeName(cmd.name)+'.exec'))
+        if os.path.exists(execFile): os.remove(execFile)
+            
         try:            
             f = open(execFile, 'w')
             # The CMD
             f.write( 'CMD: %s\n' % (execString))
+            # The OUTPUT
+            f.write( 'OUTPUT: %s\n' % (outputFile))
             # Dump the TMP
             if tmp: f.write( 'TMP: %s\n' % (tmp))
             # Dump the cwd (if specified)
             if cmd.cwd: f.write( 'CWD: %s\n' % (cmd.cwd))
-            # Write the TIMEOUT
-            if cmd.timeout: f.write( 'TIMEOUT: %s\n' % (cmd.timeout))    
+            
+            if 'posix' != os.name :
+                # Write the 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]))    
         finally:
@@ -75,47 +82,99 @@
         
         # 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'
-                                    
-        #log.debug('Executing: ' + execString)
-        #log.debug('     Exec: ' + str(execFile))
-        #log.debug('   Output: ' + str(outputFile))
-        #log.debug('Full Exec: ' + fullExec)
         
-        # Execute Command & Wait
-        systemReturn = os.system(fullExec)
+        if 'posix' == os.name :
+            
+            # Fork to get a child 'cos we are going to crap into
+            # it's ENV, and we don't want to mess in our own.
+            forkPID = os.fork();
+            
+            # Child gets PID = 0
+            if 0 == forkPID:
+                # Run the information within this file...
+                os._exit(runProcess(execFile))
+            
+            # Parent gets real PID
+            else:
+                # Timeout support
+                timer = None
+                if cmd.timeout:
+                    import threading
+                    timer = threading.Timer(cmd.timeout, \
+		    		shutdownProcessAndProcessGroup, [forkPID])
+                    timer.start()
+            
+                # Run the command
+                (childPID, waitcode) = os.waitpid(forkPID,0)
+                
+                # Stop timer (if still running)
+                if timer and timer.isAlive(): 
+                    timer.cancel()      
+                
+                # 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)
+            
+                #log.debug('Command returned [' + str(systemReturn)+ '] [Sig:' + str(result.signal) + ' / Exit:' + str(result.exit_code) + '].')
         
-        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
-            result.signal = (waitcode & 0xFF)
-            result.exit_code = (((waitcode & 0xFF00) >> 8) & 0xFF)
+                # Assume timed out if signal terminated
+                if result.signal > 0:
+                    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 = command.CMD_STATE_FAILED
+                    #log.warn('Command failed. [' + execString + ']. ExitCode: ' + str(result.exit_code))
+                else:
+                    result.state = command.CMD_STATE_SUCCESS         
+                  
         else:
-            result.signal = 0
-            result.exit_code = systemReturn
             
-        #log.debug('Command returned [' + str(systemReturn)+ '] [Sig:' + str(result.signal) + ' / Exit:' + str(result.exit_code) + '].')
+            # Run another python process (to crap into it's ENV not the main, multi-threaded, one.)
+            fullExec = sys.executable + ' ' + LAUNCHER + ' ' + execFile
+                                    
+            #log.debug('Executing: ' + execString)
+            #log.debug('     Exec: ' + str(execFile))
+            #log.debug('   Output: ' + str(outputFile))
+            #log.debug('Full Exec: ' + fullExec)
+        
+            # Execute Command & Wait
+            systemReturn = os.system(fullExec)
+        
+            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
+                result.signal = (waitcode & 0xFF)
+                result.exit_code = (((waitcode & 0xFF00) >> 8) & 0xFF)
+            else:
+                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 = 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 = command.CMD_STATE_FAILED
-            #log.warn('Command failed. [' + execString + ']. ExitCode: ' + str(result.exit_code))
-        else:
-            result.state = command.CMD_STATE_SUCCESS                
+            # Assume timed out if signal terminated
+            if result.signal > 0:
+                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 = command.CMD_STATE_FAILED
+                #log.warn('Command failed. [' + execString + ']. ExitCode: ' + str(result.exit_code))
+            else:
+                result.state = command.CMD_STATE_SUCCESS                
      
       except Exception, details :
-        log.error('Failed to launch command. Details: ' + str(details))
-        
-        result.exit_code = -1
-        result.state = command.CMD_STATE_FAILED
+          log.error('Failed to launch command. Details: ' + str(details), exc_info=1) 
+          result.exit_code = -1
+          result.state = command.CMD_STATE_FAILED
         
     finally:
       # Clean Up Empty Output Files
@@ -132,6 +191,21 @@
 	  
     return result
     
+def shutdownProcessAndProcessGroup(pid):
+    """
+    Kill this (and all child processes).
+    """
+    log.warn('Kill process group (anything launched by PID' + str(pid) + ')')    
+    try:
+        pgrpID=os.getpgid(pid)
+        if -1 != pgrpID:
+            os.killpg(pgrpID,signal.SIGKILL)
+        else:
+            log.warn('No such PID' + str(pid) + '.')    
+    except Exception, details:
+        log.error('Failed to dispatch signal ' + str(details), exc_info=1)
+        
+        
 def shutdownProcesses():
     """
     Kill this (and all child processes).
@@ -143,7 +217,7 @@
         gumpid
     except Exception, details:
         log.error('Failed to dispatch signal ' + str(details), exc_info=1)
-          
+         
 def runProcess(execFilename):
     """
     Read an 'exec file' (formatted by Gump) to detect what to run,
@@ -161,6 +235,7 @@
         #    print 'KEY : ' + key  + ' -> ' + execInfo[key]
         
         cmd = execInfo['CMD']
+        outputFile = execInfo['OUTPUT']
         cwd = None
         if execInfo.has_key('CWD'): cwd = execInfo['CWD']
         tmp = execInfo['TMP']
@@ -189,6 +264,9 @@
             timer.setDaemon(1)
             timer.start()
             
+        # Allow redirect
+        cmd += ' >>' + str(outputFile) + ' 2>&1'
+        
         # Run the command
         systemReturn = os.system(cmd)
                   
@@ -213,7 +291,6 @@
     return exit_code
 
 if __name__=='__main__':
-    import re
     
     exit_code = 0
     execFilename = sys.argv[1]

Modified: gump/live/python/gump/util/sync.py
URL: http://svn.apache.org/viewcvs/gump/live/python/gump/util/sync.py?view=diff&r1=159458&r2=159459
==============================================================================
--- gump/live/python/gump/util/sync.py (original)
+++ gump/live/python/gump/util/sync.py Tue Mar 29 18:22:36 2005
@@ -25,6 +25,7 @@
 import shutil
 
 from gump import log
+from gump.util import getStringFromUnicode
 from gump.util.work import *
 from gump.util.file import *
 from gump.util.note import *
@@ -36,8 +37,8 @@
 
     def __init__(self, sourcedir, targetdir, action = SYNC_ACTION, output=None, debug=0):
         Annotatable.__init__(self)
-        self.sourcedir = sourcedir
-        self.targetdir = targetdir
+        self.sourcedir = getStringFromUnicode(sourcedir)
+        self.targetdir = getStringFromUnicode(targetdir)
         self.action = action
         
         if SYNC_ACTION==action:
@@ -176,6 +177,7 @@
         #
         #
         for name in names:
+            
             try:    
                 srcname = os.path.join(src, name)
                 dstname = os.path.join(dst, name)
@@ -216,6 +218,7 @@
         None
         """
         for afile in existingfiles:
+            
             fullsourcefile = os.path.join(sourcedir, afile)
             fulldestfile = os.path.join(destdir, afile)
             if not afile in acceptablefiles:

Modified: gump/live/python/header.txt
URL: http://svn.apache.org/viewcvs/gump/live/python/header.txt?view=diff&r1=159458&r2=159459
==============================================================================
--- gump/live/python/header.txt (original)
+++ gump/live/python/header.txt Tue Mar 29 18:22:36 2005
@@ -14,8 +14,6 @@
 # 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"
+__copyright__ = "Copyright (c) 2004 The Apache Software Foundation"
 __license__   = "http://www.apache.org/licenses/LICENSE-2.0"
 

Modified: gump/live/src/documentation/content/xdocs/mail.xml
URL: http://svn.apache.org/viewcvs/gump/live/src/documentation/content/xdocs/mail.xml?view=diff&r1=159458&r2=159459
==============================================================================
--- gump/live/src/documentation/content/xdocs/mail.xml (original)
+++ gump/live/src/documentation/content/xdocs/mail.xml Tue Mar 29 18:22:36 2005
@@ -1,6 +1,6 @@
 <?xml version="1.0" encoding="ISO-8859-1"?>
 <!--
-  Copyright 2004 The Apache Software Foundation
+  Copyright 2004-2005 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.
@@ -62,7 +62,7 @@
           <strong>Low Traffic</strong>
           <link href="mailto:commits-subscribe@gump.apache.org">Subscribe</link>
           <link href="mailto:commits-unsubscribe@gump.apache.org">Unsubscribe</link>
-          <link href="http://nagoya.apache.org/eyebrowse/SummarizeList?listId=279">Archive</link>
+          <link href="http://mail-archives.apache.org/eyebrowse/SummarizeList?listId=279">Archive</link>
          </p>
 
         <p>This is the list where software and metadata commit messages (from CVS and SVN)

Modified: gump/live/src/documentation/content/xdocs/metadata/project.xml
URL: http://svn.apache.org/viewcvs/gump/live/src/documentation/content/xdocs/metadata/project.xml?view=diff&r1=159458&r2=159459
==============================================================================
--- gump/live/src/documentation/content/xdocs/metadata/project.xml (original)
+++ gump/live/src/documentation/content/xdocs/metadata/project.xml Tue Mar 29 18:22:36 2005
@@ -1,6 +1,6 @@
 <?xml version="1.0" encoding="ISO-8859-1"?>
 <!--
-  Copyright 2003-2004 The Apache Software Foundation
+  Copyright 2003-2005 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.
@@ -538,7 +538,7 @@
 
     <section><title>nag</title>
       <p>If this element is present, an entry for this project will be
-      created in the file naglist.  This enables email reports of
+      created in the file naglist.  This enables <link href="site:nagged">email reports</link> of
       build failures.</p>
 
       <table>

Modified: gump/live/src/documentation/content/xdocs/site.xml
URL: http://svn.apache.org/viewcvs/gump/live/src/documentation/content/xdocs/site.xml?view=diff&r1=159458&r2=159459
==============================================================================
--- gump/live/src/documentation/content/xdocs/site.xml (original)
+++ gump/live/src/documentation/content/xdocs/site.xml Tue Mar 29 18:22:36 2005
@@ -1,6 +1,6 @@
 <?xml version="1.0" encoding="ISO-8859-1"?>
 <!--
-  Copyright 2003-2004 The Apache Software Foundation
+  Copyright 2003-2005 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.
@@ -28,11 +28,11 @@
 	    <gettingstarted href="gettingstarted.html" label="Getting Started"/>
 	    <todo href="todo.html" label="Help Wanted"/>
             <license href="http://www.apache.org/licenses/LICENSE-2.0.txt" label="License"/>
+            <nagged href="nagged.html"/>
 	</gump>
 	<results label="Results">
 	    <nightly href="http://brutus.apache.org/gump/public/" label="Nightly"/>
 	    <jars href="http://brutus.apache.org/gump/public-jars/" label="Jars"/>
-	<!--     <index href="http://nagoya.apache.org/~rubys/gump/javadoc.html" label="Javadoc"/> -->
 	</results>
 	<!--
 	<menu label="Cross Reference">
@@ -47,7 +47,7 @@
             <mail href="mail.html" label="Mailing Lists"/>
             <source href="index.html#Where+is+Gump%3F" label="Source"/>
 	    <wiki href="http://wiki.apache.org/gump" label="Wiki"/>
-	    <issues href="http://nagoya.apache.org/jira/secure/BrowseProject.jspa?id=10457" label="Issues"/>
+	    <issues href="http://issues.apache.org/jira/secure/BrowseProject.jspa?id=10457" label="Issues"/>
             <howtocontribute href="http://jakarta.apache.org/site/getinvolved.html" label="Get Involved"/>
             <whoweare href="whoweare.html" label="Who We Are"/>
             <bylaws href="bylaws.html" label="Project Bylaws"/>

Modified: gump/live/src/documentation/skinconf.xml
URL: http://svn.apache.org/viewcvs/gump/live/src/documentation/skinconf.xml?view=diff&r1=159458&r2=159459
==============================================================================
--- gump/live/src/documentation/skinconf.xml (original)
+++ gump/live/src/documentation/skinconf.xml Tue Mar 29 18:22:36 2005
@@ -1,6 +1,6 @@
 <?xml version="1.0"?>
 <!--
-  Copyright 2002-2004 The Apache Software Foundation
+  Copyright 2002-2005 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.
@@ -90,7 +90,7 @@
   <favicon-url>favicon.ico</favicon-url>
 
   <!-- The following are used to construct a copyright statement -->
-  <year>2003-2004</year>
+  <year>2003-2005</year>
   <vendor>The Apache Software Foundation.</vendor>
   <!-- The optional copyright-link URL will be used as a link in the
     copyright statement -->

Copied: gump/live/src/xdocs/gump@fosdem.pdf (from r159424, gump/trunk/src/xdocs/gump@fosdem.pdf)
URL: http://svn.apache.org/viewcvs/gump/live/src/xdocs/gump%40fosdem.pdf?view=diff&rev=159459&p1=gump/trunk/src/xdocs/gump%40fosdem.pdf&r1=159424&p2=gump/live/src/xdocs/gump%40fosdem.pdf&r2=159459
==============================================================================
Binary files - no diff available.

Propchange: gump/live/src/xdocs/gump@fosdem.pdf
------------------------------------------------------------------------------
    svn:mime-type = application/octet-stream

Copied: gump/live/src/xdocs/gump@fosdem.ppt (from r159424, gump/trunk/src/xdocs/gump@fosdem.ppt)
URL: http://svn.apache.org/viewcvs/gump/live/src/xdocs/gump%40fosdem.ppt?view=diff&rev=159459&p1=gump/trunk/src/xdocs/gump%40fosdem.ppt&r1=159424&p2=gump/live/src/xdocs/gump%40fosdem.ppt&r2=159459
==============================================================================
Binary files - no diff available.

Propchange: gump/live/src/xdocs/gump@fosdem.ppt
------------------------------------------------------------------------------
    svn:mime-type = application/octet-stream



Mime
View raw message