You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@gump.apache.org by bo...@apache.org on 2007/05/03 12:52:39 UTC

svn commit: r534785 - in /gump/live/python/gump: actor/document/xdocs/ actor/mysql/ actor/notify/ actor/syndication/ core/ core/build/ core/model/ core/run/ core/runner/ util/ util/process/

Author: bodewig
Date: Thu May  3 03:52:35 2007
New Revision: 534785

URL: http://svn.apache.org/viewvc?view=rev&rev=534785
Log:
merge Maven2 builder from trunk

Modified:
    gump/live/python/gump/actor/document/xdocs/documenter.py
    gump/live/python/gump/actor/mysql/dynagumper.py
    gump/live/python/gump/actor/notify/notifier.py
    gump/live/python/gump/actor/syndication/syndicator.py
    gump/live/python/gump/core/build/builder.py
    gump/live/python/gump/core/build/maven.py
    gump/live/python/gump/core/config.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/project.py
    gump/live/python/gump/core/model/property.py
    gump/live/python/gump/core/model/workspace.py
    gump/live/python/gump/core/run/actor.py
    gump/live/python/gump/core/run/gumpenv.py
    gump/live/python/gump/core/runner/demand.py
    gump/live/python/gump/core/runner/runner.py
    gump/live/python/gump/util/mysql.py
    gump/live/python/gump/util/process/launcher.py

Modified: gump/live/python/gump/actor/document/xdocs/documenter.py
URL: http://svn.apache.org/viewvc/gump/live/python/gump/actor/document/xdocs/documenter.py?view=diff&rev=534785&r1=534784&r2=534785
==============================================================================
--- gump/live/python/gump/actor/document/xdocs/documenter.py (original)
+++ gump/live/python/gump/actor/document/xdocs/documenter.py Thu May  3 03:52:35 2007
@@ -82,6 +82,7 @@
         self.syncObject(module)
          
     def processProject(self,project):
+        
         verbose=self.run.getOptions().isVerbose()
         debug=self.run.getOptions().isDebug()
         self.documentProject(project,True)
@@ -809,6 +810,9 @@
         projectsTable=projectsSection.createTable(['Index','Time','Name','State','Duration\nin state','Last Modified','Notes'])
         pcount=0
         for project in self.gumpSet.getCompletedProjects():
+                        
+            # Hack for bad data.
+            if not project.inModule(): continue
                        
             #if realTime and \
             #    (project.getState()==STATE_FAILED or \
@@ -984,6 +988,9 @@
         depOrder=createOrderedList(sortedProjectList,compareProjectsByFullDependeeCount)
   
         for project in depOrder:
+            # Hack for bad data
+            if not project.inModule(): continue
+                
             if not self.gumpSet.inProjectSequence(project): continue       
             
             if not project.getState()==STATE_FAILED:
@@ -1043,6 +1050,9 @@
                     'Dependees','Project State','Duration\nin state'])
         pcount=0
         for project in sortedProjectList:
+            # Hack for bad data
+            if not project.inModule(): continue    
+            # Filter
             if not self.gumpSet.inProjectSequence(project): continue       
             
             if not project.getState()==STATE_SUCCESS or \
@@ -1089,6 +1099,9 @@
                     'Depends','Not-Built Depends','Project State','Duration\nin state'])
         pcount=0
         for project in sortedProjectList:
+            # Hack for bad data
+            if not project.inModule(): continue    
+            # Filter    
             if not self.gumpSet.inProjectSequence(project): continue       
             
             if not project.getState()==STATE_PREREQ_FAILED:
@@ -1679,6 +1692,10 @@
     #    endXDoc(x)
         
     def documentProject(self,project,realTime=False): 
+    
+        # Hack for bad data. Gump3 won't let it get this
+        # far.
+        if not project.inModule(): return
         
         spec=self.resolver.getFileSpec(project)
         document=XDocDocument('Project : ' + project.getName(),    
@@ -2549,77 +2566,80 @@
                     fileList.createEntry("Owner (Referencer): "))
             
         if fileReference.exists():
-            if fileReference.isDirectory():                
+            try:
+                if fileReference.isDirectory():                
                 
-                listingSection=fdocument.createSection('Directory Contents')
-                listingTable=listingSection.createTable(['Filename','Type','Size'])
+                    listingSection=fdocument.createSection('Directory Contents')
+                    listingTable=listingSection.createTable(['Filename','Type','Size'])
                 
-                directory=fileReference.getPath()
+                    directory=fileReference.getPath()
                 
-                # Change to os.walk once we can move to Python 2.3
-                files=os.listdir(directory)
-                files.sort()
-                for listedFile in files:
+                    # Change to os.walk once we can move to Python 2.3
+                    files=os.listdir(directory)
+                    files.sort()
+                    for listedFile in files:
                     
-                    filePath=os.path.abspath(os.path.join(directory,listedFile))
-                    listingRow=listingTable.createRow()
+                        filePath=os.path.abspath(os.path.join(directory,listedFile))
+                        listingRow=listingTable.createRow()
                     
-                    #
-                    listingRow.createData(listedFile)    
+                        #
+                        listingRow.createData(listedFile)    
                     
-                    if os.path.isdir(filePath):
-                        listingRow.createData('Directory')
-                        listingRow.createData('N/A')
-                    else:
-                        listingRow.createData('File')    
-                        listingRow.createData(str(os.path.getsize(filePath)))                                                
-            else:    
-                    
-                #
-                # Show the content...
-                #
-                outputSection=fdocument.createSection('File Contents')
-                output=fileReference.getPath()
-                if output:
-                    try:            
-                        if os.path.getsize(output) > 100000:
-                            #
-                            # This is *big* just copy/point to it
-                            #
-                            from shutil import copyfile
-                            # Extract name, to make relative to group
-                            outputBaseName=os.path.basename(output)
-                            (outputName,outputExtn)=os.path.splitext(outputBaseName)
-                            displayedOutput=self.resolver.getFile(fileReference, outputName, outputExtn, 1)
-                        
-                            # Do the transfer..
-                            copyfile(output,displayedOutput)                        
-                            outputSection.createParagraph().createLink(outputBaseName,'Complete File')
+                        if os.path.isdir(filePath):
+                            listingRow.createData('Directory')
+                            listingRow.createData('N/A')
                         else:
-                            outputSource=outputSection.createSource()    
-                            o=None
-                            try:
-                                # Keep a length count to not exceed 32K
-                                size=0
-                                o=open(output, 'r')
-                                line=o.readline()
-                                while line:
-                                    length = len(line)
-                                    size += length
-                                    # Crude to 'ensure' that escaped
-                                    # it doesn't exceed 32K.
-                                    if size > 20000:
-                                        outputSection.createParagraph('Continuation...')
-                                        outputSource=outputSection.createSource()
-                                        size = length
-                                    outputSource.createText(line)
+                            listingRow.createData('File')    
+                            listingRow.createData(str(os.path.getsize(filePath)))                                                
+                else:    
+                    
+                    #
+                    # Show the content...
+                    #
+                    outputSection=fdocument.createSection('File Contents')
+                    output=fileReference.getPath()
+                    if output:
+                        try:            
+                            if os.path.getsize(output) > 100000:
+                                #
+                                # This is *big* just copy/point to it
+                                #
+                                from shutil import copyfile
+                                # Extract name, to make relative to group
+                                outputBaseName=os.path.basename(output)
+                                (outputName,outputExtn)=os.path.splitext(outputBaseName)
+                                displayedOutput=self.resolver.getFile(fileReference, outputName, outputExtn, 1)
+                        
+                                # Do the transfer..
+                                copyfile(output,displayedOutput)                        
+                                outputSection.createParagraph().createLink(outputBaseName,'Complete File')
+                            else:
+                                outputSource=outputSection.createSource()    
+                                o=None
+                                try:
+                                    # Keep a length count to not exceed 32K
+                                    size=0
+                                    o=open(output, 'r')
                                     line=o.readline()
-                            finally:
-                                if o: o.close()
-                    except Exception, details:
-                        outputSection.createParagraph('Failed to copy contents from :' + output + ' : ' + str(details))
-                else:
-                    outputSection.createParagraph('No contents in this file.')
+                                    while line:
+                                        length = len(line)
+                                        size += length
+                                        # Crude to 'ensure' that escaped
+                                        # it doesn't exceed 32K.
+                                        if size > 20000:
+                                            outputSection.createParagraph('Continuation...')
+                                            outputSource=outputSection.createSource()
+                                            size = length
+                                        outputSource.createText(line)
+                                        line=o.readline()
+                                finally:
+                                    if o: o.close()
+                        except Exception, details:
+                            outputSection.createParagraph('Failed to copy contents from :' + output + ' : ' + str(details))
+                    else:
+                        outputSection.createParagraph('No contents in this file.')                
+            except Exception, details:
+                fdocument.createWarning('Failed documeting file or directory. %s' % details)
         else:
             fdocument.createWarning('No such file or directory.')
            

Modified: gump/live/python/gump/actor/mysql/dynagumper.py
URL: http://svn.apache.org/viewvc/gump/live/python/gump/actor/mysql/dynagumper.py?view=diff&rev=534785&r1=534784&r2=534785
==============================================================================
--- gump/live/python/gump/actor/mysql/dynagumper.py (original)
+++ gump/live/python/gump/actor/mysql/dynagumper.py Thu May  3 03:52:35 2007
@@ -57,26 +57,30 @@
         
     def processOtherEvent(self,event):
         #TODO do the actual work right here...
-        self.log.warning('dynagumper.py processOtherEvent: need to implement event processing')
-                      
+        #self.log.warning('dynagumper.py processOtherEvent: need to implement event processing')
+        pass
+              
     def processWorkspace(self):
         """
         Add information about the workspace to the database.
         """
         #TODO do the actual work right here...
         #self.ensureThisHostIsInDatabase()
-        self.log.warning('dynagumper.py processWorkspace: need to implement workspace event processing')
-    
+        #self.log.warning('dynagumper.py processWorkspace: need to implement workspace event processing')
+        pass
+
     def processModule(self,module):    
         """
         Add information about a module to the database.
         """
         #TODO do the actual work
-        self.log.warning('dynagumper.py processModule: need to implement module event processing')
-    
+        #self.log.warning('dynagumper.py processModule: need to implement module event processing')
+        pass
+
     def processProject(self,project):    
         """
         Add information about a project to the database.
         """
         #TODO do the actual work right here...
-        self.log.warning('dynagumper.py processProject: need to implement project event processing')
+        #self.log.warning('dynagumper.py processProject: need to implement project event processing')
+        pass

Modified: gump/live/python/gump/actor/notify/notifier.py
URL: http://svn.apache.org/viewvc/gump/live/python/gump/actor/notify/notifier.py?view=diff&rev=534785&r1=534784&r2=534785
==============================================================================
--- gump/live/python/gump/actor/notify/notifier.py (original)
+++ gump/live/python/gump/actor/notify/notifier.py Thu May  3 03:52:35 2007
@@ -98,7 +98,8 @@
         if self._hasUnwanted():
             log.info('We have some unwanted\'s to send to list...')
             
-            self.sendEmail(wsTo or self.workspace.administrator,wsFrom or self.workspace.email,
+            self.sendEmail( wsTo or self.workspace.administrator,
+                            wsFrom or self.workspace.email,
                         'BATCH: All dressed up, with nowhere to go...',
                         self._getUnwantedContent())
                         
@@ -113,7 +114,8 @@
         # Belt and braces (notify to us if not notify to them)
         if self._hasUnsent():
             log.info('We have some unsented\'s to send to list...')    
-            self.sendEmail(wsTo or self.workspace.administrator,wsFrom or self.workspace.email,
+            self.sendEmail(wsTo or self.workspace.administrator,
+                        wsFrom or self.workspace.email,
                         'BATCH: Unable to send...',
                          self._getUnsentContent())
                         

Modified: gump/live/python/gump/actor/syndication/syndicator.py
URL: http://svn.apache.org/viewvc/gump/live/python/gump/actor/syndication/syndicator.py?view=diff&rev=534785&r1=534784&r2=534785
==============================================================================
--- gump/live/python/gump/actor/syndication/syndicator.py (original)
+++ gump/live/python/gump/actor/syndication/syndicator.py Thu May  3 03:52:35 2007
@@ -64,7 +64,7 @@
     def processProject(self,project):    
         """
         Syndicate information about the project (if it needs it)
-        """
+        """                
         self.rss.syndicateProject(project)
         self.atom.syndicateProject(project)
            

Modified: gump/live/python/gump/core/build/builder.py
URL: http://svn.apache.org/viewvc/gump/live/python/gump/core/build/builder.py?view=diff&rev=534785&r1=534784&r2=534785
==============================================================================
--- gump/live/python/gump/core/build/builder.py (original)
+++ gump/live/python/gump/core/build/builder.py Thu May  3 03:52:35 2007
@@ -50,6 +50,7 @@
 from gump.core.build.ant import AntBuilder
 from gump.core.build.nant import NAntBuilder
 from gump.core.build.maven import MavenBuilder
+from gump.core.build.mvn import Maven2Builder
 from gump.core.build.configure import ConfigureBuilder
 from gump.core.build.make import MakeBuilder
 
@@ -81,6 +82,7 @@
         self.ant=AntBuilder(run)
         self.nant=NAntBuilder(run)
         self.maven=MavenBuilder(run)
+        self.mvn=Maven2Builder(run)
         self.script=ScriptBuilder(run)
         self.configure = ConfigureBuilder(run)
         self.make = MakeBuilder(run);
@@ -140,6 +142,8 @@
                     self.nant.buildProject(project, languageHelper, stats)
                 elif project.hasMaven():
                     self.maven.buildProject(project, languageHelper, stats)
+                elif project.hasMvn():
+                    self.mvn.buildProject(project, languageHelper, stats)
                 elif project.hasConfigure():
                     self.configure.buildProject(project, languageHelper, stats)
                 elif project.hasMake():
@@ -322,7 +326,7 @@
                         project.addError("See Directory Listing Work for Missing Outputs")
             else:
                 project.changeState(STATE_SUCCESS)
-        else:
+        elif project.inModule():
             # List source directory (when failed) in case it helps debugging...
             listDirectoryToFileHolder(project,project.getModule().getWorkingDirectory(), 
                                         FILE_TYPE_SOURCE, 'list_source_'+project.getName())           
@@ -486,5 +490,7 @@
             self.nant.preview(project,  languageHelper, stats)
         elif project.hasMaven():
             self.maven.preview(project,  languageHelper, stats)
+        elif project.hasMvn():
+            self.mvn.preview(project, languageHelper, stats);
         else:
             print 'No builder for project: ' + project.getName()

Modified: gump/live/python/gump/core/build/maven.py
URL: http://svn.apache.org/viewvc/gump/live/python/gump/core/build/maven.py?view=diff&rev=534785&r1=534784&r2=534785
==============================================================================
--- gump/live/python/gump/core/build/maven.py (original)
+++ gump/live/python/gump/core/build/maven.py Thu May  3 03:52:35 2007
@@ -188,9 +188,11 @@
                         os.path.basename(propertiesFile))
                 except:
                     log.error('Display Properties [ ' + propertiesFile + '] Failed', exc_info=1)   
-                
-            except:
-                log.error('Generate Maven Properties Failed', exc_info=1)    
+               
+            except Exception, details:
+                message='Generate Maven Properties Failed:' + str(details)
+                log.error(message, exc_info=1)
+                project.addError(message)    
                 project.changeState(STATE_FAILED,REASON_PREBUILD_FAILED)
  
     # The propertiesFile parameter is primarily for testing.
@@ -205,6 +207,12 @@
         basedir = project.maven.getBaseDirectory() or project.getBaseDirectory()
         if not propertiesFile: 
             propertiesFile=os.path.abspath(os.path.join(basedir,'build.properties'))
+            
+        # Ensure containing directory exists, or make it.
+        propsdir=os.path.dirname(propertiesFile)
+        if not os.path.exists(propsdir):
+            project.addInfo('Making directory for Maven properties: ['+propsdir+']')
+            os.makedirs(propsdir)
         
         if os.path.exists(propertiesFile):
             project.addWarning('Overriding Maven properties: ['+propertiesFile+']')
@@ -231,7 +239,7 @@
         for property in project.getWorkspace().getProperties()+project.getMaven().getProperties():
             # build.sysclasspath makes Maven sick.
             if not 'build.sysclasspath' == property.name:
-                props.write(('%s=%s\n') % (property.name,property.value))            
+                props.write(('%s=%s\n') % (property.name,property.value.replace('\\','/')))            
         
         #
         # Output classpath properties
@@ -255,7 +263,7 @@
                 props.write(('# Contributor: %s\nmaven.jar.%s=%s\n') % \
                     (	annotatedPath.getContributor(),	
                         annotatedPath.getId(),	
-                        annotatedPath.getPath()))
+                        annotatedPath.getPath().replace('\\','/')))
 
         return propertiesFile
       

Modified: gump/live/python/gump/core/config.py
URL: http://svn.apache.org/viewvc/gump/live/python/gump/core/config.py?view=diff&rev=534785&r1=534784&r2=534785
==============================================================================
--- gump/live/python/gump/core/config.py (original)
+++ gump/live/python/gump/core/config.py Thu May  3 03:52:35 2007
@@ -55,7 +55,7 @@
 class setting:    
     """Configuration of hardcoded settings"""
     
-    VERSION='2.2'
+    VERSION='2.3'
     
     WS_VERSION="0.4"
     WS_MINIMUM_VERSION="0.3"

Modified: gump/live/python/gump/core/model/builder.py
URL: http://svn.apache.org/viewvc/gump/live/python/gump/core/model/builder.py?view=diff&rev=534785&r1=534784&r2=534785
==============================================================================
--- gump/live/python/gump/core/model/builder.py (original)
+++ gump/live/python/gump/core/model/builder.py Thu May  3 03:52:35 2007
@@ -203,7 +203,7 @@
         # Check for debugging properties
         self.setDebug(self.domAttributeIsTrue('debug'))
         self.setVerbose(self.domAttributeIsTrue('verbose'))
-                        
+        
         self.setComplete(True)
                     
     def dump(self, indent=0, output=sys.stdout):
@@ -268,6 +268,24 @@
     	
         # Import the goal
         self.goal=self.getDomAttributeValue('goal','jar')
+            	    
+    def getGoal(self):
+        return self.goal
+    	
+    def dump(self, indent=0, output=sys.stdout):
+        """ Display the contents of this object """
+        Builder.dump(self,indent,output)
+        i=getIndent(indent+1)
+        output.write(i+'Goal: ' + self.getGoal() + '\n')
+
+# represents an <mvn/> element
+class Maven2(Builder):
+    """ A Maven command (within a project)"""
+    def __init__(self,dom,project):
+    	Builder.__init__(self,dom,project)
+    	
+        # Import the goal
+        self.goal=self.getDomAttributeValue('goal','package')
             	    
     def getGoal(self):
         return self.goal

Modified: gump/live/python/gump/core/model/depend.py
URL: http://svn.apache.org/viewvc/gump/live/python/gump/core/model/depend.py?view=diff&rev=534785&r1=534784&r2=534785
==============================================================================
--- gump/live/python/gump/core/model/depend.py (original)
+++ gump/live/python/gump/core/model/depend.py Thu May  3 03:52:35 2007
@@ -94,6 +94,7 @@
         self.optional=optional
         self.ids=ids
         self.noclasspath=noclasspath
+        self.valid=True
         if annotation:	self.addInfo(annotation)
         
     def __del__(self):
@@ -223,6 +224,12 @@
         # Which direction (to or from?)
         self.dependees=dependees
         
+    def removeDepend(self, depend):
+        # :TODO: Ought remove more (or never delete,
+        # but never let 'bad' (i.e. circular) get in
+        # here in the first place.
+        self.depends.remove(depend)
+        
     def addDepend(self, depend):
         
         #
@@ -311,6 +318,9 @@
     # 
     def addDependency(self,depend):
         self.directDependencies.addDepend(depend)
+        
+    def removeDependency(self,depend):
+        self.directDependencies.removeDepend(depend)
             
     def getDirectDependencies(self):
         return self.directDependencies.getDepends()
@@ -452,14 +462,6 @@
             if dependency.getProject().getName()==name	\
                 and not dependency.isNoClasspath() :
                 return True            
-        return False
-
-    def uponFuzzy(self):
-        """
-        At least one of these dependencies is Fuzzy...
-        """
-        for dependency in self.getFullDependencies():
-            if dependency.getProject().isFuzzy(): return True
         return False
 
     # determine if this project is a prereq of any project on the todo list

Modified: gump/live/python/gump/core/model/module.py
URL: http://svn.apache.org/viewvc/gump/live/python/gump/core/model/module.py?view=diff&rev=534785&r1=534784&r2=534785
==============================================================================
--- gump/live/python/gump/core/model/module.py (original)
+++ gump/live/python/gump/core/model/module.py Thu May  3 03:52:35 2007
@@ -317,7 +317,12 @@
                 
     # provide default elements when not defined in xml
     def complete(self,workspace):
-     
+          
+        # Give some indication when spinning on
+        # circular dependencies, 'cos even though we
+        # have code in to not spin, never assume never...
+        log.debug('Complete: %s' % self)
+        
         if self.isComplete(): return
 
         # :TODO: hacky   

Modified: gump/live/python/gump/core/model/project.py
URL: http://svn.apache.org/viewvc/gump/live/python/gump/core/model/project.py?view=diff&rev=534785&r1=534784&r2=534785
==============================================================================
--- gump/live/python/gump/core/model/project.py (original)
+++ gump/live/python/gump/core/model/project.py Thu May  3 03:52:35 2007
@@ -31,7 +31,7 @@
                             AddressPair
 from gump.core.model.stats import Statable, Statistics
 from gump.core.model.property import Property
-from gump.core.model.builder import Ant,NAnt,Maven,Script,Configure,Make
+from gump.core.model.builder import Ant,NAnt,Maven,Maven2,Script,Configure,Make
 from gump.util import getIndent
 from gump.util.file import *
 from gump.core.model.depend import *
@@ -79,8 +79,9 @@
     	#
     	self.ant=None
         self.nant=None
-    	self.maven=None
-    	self.script=None
+        self.maven=None
+        self.mvn= None
+        self.script=None
         self.configure = None
         self.make = None
         self.builder = []
@@ -159,6 +160,10 @@
         if self.maven: return True
         return False
         
+    def hasMvn(self):
+        if self.mvn: return True
+        return False
+        
     def hasScript(self):
         if self.script: return True
         return False
@@ -180,6 +185,9 @@
     def getMaven(self):
         return self.maven
         
+    def getMvn(self):
+        return self.mvn
+        
     def getScript(self):
         return self.script
     
@@ -343,11 +351,23 @@
         return (not self.isPackaged()) and self.hasBuilder()
         
     # provide elements when not defined in xml
-    def complete(self,workspace): 
+    def complete(self,workspace,visited=None): 
+    
+        # Give some indication when spinning on
+        # circular dependencies, 'cos even though we
+        # have code in to not spin, never assume never...
+        log.debug('Complete: %s, Path: %s' % (self, visited))
+        
         if self.isComplete(): return
-
+        
+        # Create a copy, for recursion, and
+        # detection of circular paths.
+        new_visited = [self]
+        if visited: new_visited += visited
+                            
         if not self.inModule():
-            self.addWarning("Not in a module")
+            self.changeState(STATE_FAILED,REASON_CONFIG_FAILED)
+            self.addError("Not in a module")
             return
          
         # :TODO: hacky   
@@ -387,6 +407,14 @@
             # Copy over any XML errors/warnings
             # :TODO:#1: transferAnnotations(self.xml.maven, self)
             
+        # Import any <mvn part [if not packaged]
+        if self.hasDomChild('mvn') and not packaged:
+            self.mvn = Maven2(self.getDomChild('mvn'),self)
+            self.builder.append(self.mvn)
+            
+            # Copy over any XML errors/warnings
+            # :TODO:#1: transferAnnotations(self.xml.maven, self)
+            
         # Import any <script part [if not packaged]
         if self.hasDomChild('script') and not packaged:
             self.script = Script(self.getDomChild('script'),self)
@@ -563,12 +591,32 @@
         [b.expand(self, workspace) for b in self.builder]
 
         if not packaged:
+            removes = []
+            
             # Complete dependencies so properties can reference the,
             # completed metadata within a dependent project
             for dependency in self.getDirectDependencies():
                 depProject=dependency.getProject()
-                if not depProject.isComplete():
-                    depProject.complete(workspace)
+                if depProject in new_visited:
+                    for circProject in new_visited:
+                        circProject.changeState(STATE_FAILED,REASON_CONFIG_FAILED)
+                        circProject.addError("Circular Dependency. Path: %s -> %s." % \
+                                                (new_visited, depProject.getName()))
+                                                
+                    self.addError("Dependency broken, removing dependency on %s from %s." % \
+                                                (depProject.getName(), self.getName()))
+                
+                    removes.append(dependency)
+                else:
+                    # Don't redo what is done.
+                    if not depProject.isComplete():
+                        # Recurse, knowing which project
+                        # is in this list.
+                        depProject.complete(workspace, new_visited)
+                        
+            # Remove circulars...
+            for dependency in removes:
+                self.removeDependency(dependency)
 
             self.buildDependenciesMap(workspace)                        
         
@@ -585,6 +633,9 @@
         if self.maven:
             self.addJVMArgs(self.getDomChild("maven"))
 
+        if self.mvn:
+            self.addJVMArgs(self.getDomChild("mvn"))
+
         #
         # complete properties
         #
@@ -595,14 +646,16 @@
             # TODO -- move these back?
             #
             if badDepends or badOptions: 
-                for xmldepend in badDepends:
+                for badDep in badDepends:
+                    (xmldepend,reason) = badDep
                     self.changeState(STATE_FAILED,REASON_CONFIG_FAILED)
-                    self.addError("Bad Dependency. Project: " \
-                            + getDomAttributeValue(xmldepend,'project') + " unknown to *this* workspace")
+                    self.addError("Bad Dependency. Project: %s : %s " \
+                            % (getDomAttributeValue(xmldepend,'project'),reason))
 
-                for xmloption in badOptions:                
-                    self.addWarning("Bad *Optional* Dependency. Project: " \
-                            + getDomAttributeValue(xmloption,'project') + " unknown to *this* workspace")
+                for badOpt in badOptions:
+                    (xmloption,reason) = badOpt   
+                    self.addWarning("Bad *Optional* Dependency. Project: %s : %s" \
+                            % (getDomAttributeValue(xmloption,'project') , reason))
         else:
             self.addInfo("This is a packaged project, location: " + self.home)        
                                     
@@ -626,10 +679,10 @@
                     
         # Close down the DOM...
         self.shutdownDom()       
-        
-        # Done, don't redo
+    
+        # Done so don't redo
         self.setComplete(True)
-
+    
     # turn the <jvmarg> children of domchild into jvmargs
     def addJVMArgs(self,domChild):        
         for jvmarg in getDomChildIterator(domChild,'jvmarg'):
@@ -652,7 +705,7 @@
                 # Add a dependency
                 self.addDependency(dependency)
             else:
-                badDepends.append(ddom)    
+                badDepends.append((ddom,"unknown to *this* workspace"))    
                 
         # Walk the XML parts converting
         badOptions=[]
@@ -667,7 +720,7 @@
                 # Add a dependency
                 self.addDependency(dependency)                    
             else:
-                badOptions.append(odom)
+                badOptions.append((odom,"unknown to *this* workspace"))
 
         return (badDepends, badOptions)
         

Modified: gump/live/python/gump/core/model/property.py
URL: http://svn.apache.org/viewvc/gump/live/python/gump/core/model/property.py?view=diff&rev=534785&r1=534784&r2=534785
==============================================================================
--- gump/live/python/gump/core/model/property.py (original)
+++ gump/live/python/gump/core/model/property.py Thu May  3 03:52:35 2007
@@ -47,6 +47,9 @@
     # provide default elements when not defined in xml
     def complete(self,parent,workspace):
         if self.isComplete(): return
+        
+        # Don't normally allow blank properties
+        blankOk=False
     
         if self.hasDomAttribute('value'):
             self.value=self.getDomAttributeValue('value','')
@@ -145,11 +148,14 @@
             else:
                 responsibleParty.addError( \
                     'Can\'t have path on property on workspace: ' + self.getName())
+        else:
+            # Nothing set, allow blank
+            blankOk = True
         
         #
         # Do we have a value yet?
         #
-        if isinstance(self.value,NoneType):
+        if not blankOk and isinstance(self.value,NoneType):
             responsibleParty.addError('Unhandled Property: ' + self.getName() + ' on: ' + str(parent))
             self.value='*Unset*'
                 

Modified: gump/live/python/gump/core/model/workspace.py
URL: http://svn.apache.org/viewvc/gump/live/python/gump/core/model/workspace.py?view=diff&rev=534785&r1=534784&r2=534785
==============================================================================
--- gump/live/python/gump/core/model/workspace.py (original)
+++ gump/live/python/gump/core/model/workspace.py Thu May  3 03:52:35 2007
@@ -474,13 +474,13 @@
     def hasNotifyFromOverride(self):
         if not self.isNotify(): return False
         nag=self.getDomChild('nag')
-        return hasDomAttribute(nag,'from')
+        return hasDomAttribute(nag,'from')        
         
     def getNotifyFromOverride(self):
         if self.isNotify():
             nag=self.getDomChild('nag')
-            return getDomAttributeValue(nag,'from')
-        
+            return getDomAttributeValue(nag,'from')    
+            
     def getNotifyOverrides(self):
         
         # Nag Overrides
@@ -493,7 +493,7 @@
         if self.hasNotifyFromOverride():
             wsNotifyFromOverrideAddr=self.getNotifyFromOverride()
         
-        return ( wsNotifyToOverrideAddr, wsNotifyFromOverrideAddr)
+        return ( wsNotifyToOverrideAddr, wsNotifyFromOverrideAddr )
              
     def getVersion(self):
         if self.hasDomAttribute('version'):

Modified: gump/live/python/gump/core/run/actor.py
URL: http://svn.apache.org/viewvc/gump/live/python/gump/core/run/actor.py?view=diff&rev=534785&r1=534784&r2=534785
==============================================================================
--- gump/live/python/gump/core/run/actor.py (original)
+++ gump/live/python/gump/core/run/actor.py Thu May  3 03:52:35 2007
@@ -164,10 +164,15 @@
         is available on the sub-class (i.e. if needed)
         """
         if not hasattr(self,'processProject'): return        
-        if not callable(self.processProject):  return        
-        self.log.debug('Process Project [' + `project` + '] using [' + `self` + ']')        
-        self.processProject(project)
-               
+        if not callable(self.processProject):  return     
+        
+        # Hack for bad data.
+        if project.inModule():   
+        	self.log.debug('Process Project [' + `project` + '] using [' + `self` + ']')        
+        	self.processProject(project)
+     	else:
+            self.log.debug('Skip Project (not in module) [' + `project` + '] for [' + `self` + ']')        
+        	   
     def _processOtherEvent(self,event):
         """
         Call a method called 'processOtherEvent(event)', if it

Modified: gump/live/python/gump/core/run/gumpenv.py
URL: http://svn.apache.org/viewvc/gump/live/python/gump/core/run/gumpenv.py?view=diff&rev=534785&r1=534784&r2=534785
==============================================================================
--- gump/live/python/gump/core/run/gumpenv.py (original)
+++ gump/live/python/gump/core/run/gumpenv.py Thu May  3 03:52:35 2007
@@ -74,6 +74,7 @@
         self.noMono = False
         self.noNAnt = False    
         self.noMaven = False    	
+        self.noMaven2 = False
         self.noSvn = False    	
         self.noCvs = False   
         self.noP4 = False   
@@ -90,7 +91,7 @@
         self.javaHome = None
         self.javaCommand = 'java'
         self.javacCommand = 'javac'
-        
+                
         # Timezone and offset from UTC
         self.timezone = time.tzname
         self.timezoneOffset = time.timezone
@@ -115,8 +116,13 @@
         # 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.addInfo('javaCommand environmental variable setting javac command to ' + self.javacCommand )      
+        else:
+            # Default to $JAVA_HOME/bin/java, can be overridden with $JAVA_CMD.
+            if os.environ.has_key('JAVA_HOME'):        
+                self.javaCommand  = os.path.join(os.environ['JAVA_HOME'],'bin',self.javaCommand)
+                self.addInfo('javaCommand set to $JAVA_HOME/bin/java = ' + self.javaCommand )             
+        
         self._checkEnvVariable('JAVA_HOME')
                 
         if os.environ.has_key('JAVA_HOME'):        
@@ -127,6 +133,10 @@
             self.noMaven=True
             self.addWarning('MAVEN_HOME environmental variable not found, no maven builds.')
             
+        if not self.noMaven2 and not self._checkEnvVariable('M2_HOME',False): 
+            self.noMaven=True
+            self.addWarning('M2_HOME environmental variable not found, no mvn builds.')
+            
         # Check for executables
         
         self._checkExecutable('env','',False)
@@ -157,6 +167,11 @@
             not self._checkExecutable('maven','--version',False,False,'check_maven'): 
             self.noMaven=True
             self.addWarning('"maven" command not found, no Maven builds')
+       
+        if not self.noMaven2 and \
+            not self._checkExecutable('mvn','--version',False,False,'check_maven2'): 
+            self.noMaven=True
+            self.addWarning('"mvn" command not found, no Maven2 builds')
        
         if not self.noNAnt and \
             not self._checkExecutable('NAnt','-help',False,False,'check_NAnt'): 

Modified: gump/live/python/gump/core/runner/demand.py
URL: http://svn.apache.org/viewvc/gump/live/python/gump/core/runner/demand.py?view=diff&rev=534785&r1=534784&r2=534785
==============================================================================
--- gump/live/python/gump/core/runner/demand.py (original)
+++ gump/live/python/gump/core/runner/demand.py Thu May  3 03:52:35 2007
@@ -71,7 +71,9 @@
         """
         Wait for all workers to complete.
         """
-        self.group.waitForAll()
+        if self.group:
+            if hasattr(self.group, "waitForAll"):
+                self.group.waitForAll()
         
     def performUpdate(self,module):
         """
@@ -179,16 +181,18 @@
         # In project order...
         for project in sequence:
 
-            # Process the module, upon demand
-            module=project.getModule()
-            
             # If we want to be updating...
             if gumpOptions.isUpdate():
-                # W/ multiple project in one module, it may be done
-                if not module.isUpdated():
-                    self.log.debug('Update module *inlined* (not in background thread) ' + `module` + '.')     
-                    inlined+=1
-                    self.performUpdate(module)
+                
+                if project.inModule():
+                    # Process the module, upon demand
+                    module=project.getModule()
+            
+                    # W/ multiple project in one module, it may be done
+                    if not module.isUpdated():
+                        self.log.debug('Update module *inlined* (not in background thread) ' + `module` + '.')     
+                        inlined+=1
+                        self.performUpdate(module)
 
             # If we want to be building...
             if gumpOptions.isBuild():

Modified: gump/live/python/gump/core/runner/runner.py
URL: http://svn.apache.org/viewvc/gump/live/python/gump/core/runner/runner.py?view=diff&rev=534785&r1=534784&r2=534785
==============================================================================
--- gump/live/python/gump/core/runner/runner.py (original)
+++ gump/live/python/gump/core/runner/runner.py Thu May  3 03:52:35 2007
@@ -217,7 +217,11 @@
         
         # Notify last
         if self.run.getOptions().isNotify() and self.run.getWorkspace().isNotify():
-            self.run.registerActor(Notifier(self.run))         
+            self.run.registerActor(Notifier(self.run))    
+        else:
+            self.log.info('Not doing notifications [%s,%s]' \
+                % (self.run.getOptions().isNotify(), \
+                    self.run.getWorkspace().isNotify() ) )
                     
                     
         # See what we have...            

Modified: gump/live/python/gump/util/mysql.py
URL: http://svn.apache.org/viewvc/gump/live/python/gump/util/mysql.py?view=diff&rev=534785&r1=534784&r2=534785
==============================================================================
--- gump/live/python/gump/util/mysql.py (original)
+++ gump/live/python/gump/util/mysql.py Thu May  3 03:52:35 2007
@@ -145,13 +145,14 @@
                 affected=cursor.execute(statement)
                 log.debug('SQL affected: ' + `affected`)
             
-                row = cursor.fetchall()[0] # Ought be only one...
+                if affected > 0: # might be nothing in db yet
+                    row = cursor.fetchall()[0] # Ought be only one...
           
-                # Extract values
-                for column in columns:
-                    if row.has_key(column) and row[column]:
-                        settings[column]=row[column]
-                        #print 'Extracted %s -> %s' % ( column, row[column])
+                    # Extract values
+                    for column in columns:
+                        if row.has_key(column) and row[column]:
+                            settings[column]=row[column]
+                            #print 'Extracted %s -> %s' % ( column, row[column])
                               
             except Exception, details:
                 if cursor: self.logWarnings(cursor)

Modified: gump/live/python/gump/util/process/launcher.py
URL: http://svn.apache.org/viewvc/gump/live/python/gump/util/process/launcher.py?view=diff&rev=534785&r1=534784&r2=534785
==============================================================================
--- gump/live/python/gump/util/process/launcher.py (original)
+++ gump/live/python/gump/util/process/launcher.py Thu May  3 03:52:35 2007
@@ -205,6 +205,9 @@
         log.warn('Kill process group %s (i.e. anything launched by PID %s) [from %s, for %s]' \
                     % (pgrpID, pid, os.getpid(), default.gumpid))  
         if -1 != pgrpID:
+            # Give cores time to be produced, then just get serious...
+            os.killpg(pgrpID,signal.SIGABRT)
+            time.sleep(10)
             os.killpg(pgrpID,signal.SIGKILL)
         else:
             log.warn('No such PID' + str(pid) + '.')