gump-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From bode...@apache.org
Subject svn commit: r749185 [3/3] - in /gump/live: ./ python/gump/actor/document/xdocs/ python/gump/core/model/ python/gump/core/update/ python/gump/test/ python/gump/util/process/
Date Mon, 02 Mar 2009 05:00:12 GMT
Modified: gump/live/python/gump/core/model/module.py
URL: http://svn.apache.org/viewvc/gump/live/python/gump/core/model/module.py?rev=749185&r1=749184&r2=749185&view=diff
==============================================================================
--- gump/live/python/gump/core/model/module.py (original)
+++ gump/live/python/gump/core/model/module.py Mon Mar  2 05:00:11 2009
@@ -18,132 +18,163 @@
 """
 
     This module contains information on <module and it's repository references.
-    
-"""
 
-from time import localtime, strftime, tzname
+"""
 
-from gump.core.model.state import *
-from gump.core.model.stats import Statable, Statistics
-from gump.core.model.project import *
-from gump.core.model.object import NamedModelObject
+from gump import log
 from gump.core.model.misc import Resultable, Positioned, AddressPair
-from gump.util import getIndent
-from gump.util.note import transferAnnotations, Annotatable
-from gump.util.domutils import *
+from gump.core.model.object import NamedModelObject, ModelObject
+from gump.core.model.project import Project, ProjectSummary
+from gump.core.model.repository import SCM_TYPE_ARTIFACTS, SCM_TYPE_CVS, \
+    SCM_TYPE_P4, SUPPORTED_SCMS
+from gump.core.model.state import REASON_CONFIG_FAILED, REASON_PACKAGE, \
+    STATE_COMPLETE, STATE_FAILED
+from gump.core.model.stats import Statable, Statistics
+from gump.util import createOrderedList, default, getIndent, \
+    getStringFromUnicode
+from gump.util.domutils import getDomAttributeValue, getDomChildValue, \
+    hasDomAttribute, transferDomInfo
+
+import os.path
+import sys
+
+def create_scm_instance(scm_type, dom, repo):
+    """
+    Factory method for matching ModuleScm subclass of given SCM
+    """
+    if scm_type == SCM_TYPE_CVS:
+        return ModuleCvs(dom, repo)
+    elif scm_type == SCM_TYPE_P4:
+        return ModuleP4(dom, repo)
+    elif scm_type == SCM_TYPE_ARTIFACTS:
+        return ModuleArtifacts(dom, repo)
+    return ModuleScm(dom, repo)
+
 
 class ModuleScm(ModelObject):
-    def __init__(self,dom,repository):
-        ModelObject.__init__(self,dom)
-        
+    """
+    Describes the common properties of a module's SCM system
+    """
+    def __init__(self, dom, repository):
+        ModelObject.__init__(self, dom)
+
         # Reference to the shared repository
-        self.repository = repository    
-            
+        self.repository = repository
+
         # Extract settings
         self.dir = self.getDomAttributeValue('dir')
-        self.type = self.element.tagName
 
     def getRootUrl(self):
         url = self.repository.getUrl()
         if url and self.hasDir():
             url += self.getDir()
         return url
-        
+
     def hasDir(self):
-        if self.dir: return True
+        if self.dir:
+            return True
         return False
-        
+
     def getDir(self):
         return self.dir
-        
+
     def getViewUrl(self):
         return self.getRootUrl()
-         
-    def getScmType(self):
-        return self.type
 
-    def getScmName(self):
-        return self.repository.getType()
+    def getScmType(self):
+        return self.repository.getScmType()
 
 class ModuleCvs(ModuleScm):
-    def __init__(self,dom,repository):
-        ModuleScm.__init__(self, dom, repository)
-        
+    """
+    Describes the properties of a module's <cvs element
+    """
+    def __init__(self, dom, repository):
+        ModuleScm.__init__(self,  dom,  repository)
+
         # Extract settings
-        self.tag                        =       self.getDomAttributeValue('tag')
-        self.module                     =       self.getDomAttributeValue('module')
-        self.hostPrefix         =   self.getDomAttributeValue('host-prefix')
-        
+        self.tag = self.getDomAttributeValue('tag')
+        self.module = self.getDomAttributeValue('module')
+        self.hostPrefix = self.getDomAttributeValue('host-prefix')
+
     def getCvsRoot(self):
         """Construct the CVS root for this set of information"""
 
         # Form the CVS root starting with the method
-        root=':' + str(self.repository.getMethod()) + ':'
+        root = ':' + str(self.repository.getMethod()) + ':'
         # Add the user (if set)
-        if self.repository.hasUser(): root+=str(self.repository.getUser())
+        if self.repository.hasUser():
+            root += str(self.repository.getUser())
         # Craft the hostname
         if self.repository.hasHostname():
-            root+='@'
-            if self.hostPrefix: root+=self.hostPrefix+'.'      
-            root+=str(self.repository.getHostname()) + ':'
-            
+            root += '@'
+            if self.hostPrefix:
+                root += self.hostPrefix + '.'
+            root += str(self.repository.getHostname()) + ':'
+
             # :TODO: Allow users to override default port
             # this is throwing off the kaffe.org cvs repository...
             #if str(self.repository.getMethod())=='pserver': 
-            #    root+='2401'
-        root+=str(self.repository.getPath())
-        
+            #    root += '2401'
+        root += str(self.repository.getPath())
+
         # If a subdirectory
-        if self.dir: root+='/'+str(self.dir)
+        if self.dir:
+            root += '/' + str(self.dir)
 
         return root
-    
+
     def hasTag(self):
-        if self.tag: return True
+        if self.tag:
+            return True
         return False
-        
+
     def getTag(self):
         return str(self.tag)
-        
+
     def hasHostPrefix(self):
-        if self.hostPrefix: return True
+        if self.hostPrefix:
+            return True
         return False
-        
+
     def getHostPrefix(self):
         return str(self.hostPrefix)
-        
+
     def hasModule(self):
-        if self.module: return True
+        if self.module:
+            return True
         return False
-        
+
     def getModule(self):
         return str(self.module)
-         
+
     def getViewUrl(self):
-        url=None
+        url = None
         if self.repository.hasCvsWeb():
             if self.dir:
-                 url=self.repostory.getCvsWeb()+'/'+str(self.dir)+'/'
+                url = self.repository.getCvsWeb() + '/' + str(self.dir) + '/'
             else:
-                 url=self.repostory.getCvsWeb()+'/'+self.module.getName()
+                url = self.repository.getCvsWeb() + '/' + self.module.getName()
         return url
-        
+
 class ModuleP4(ModuleScm):
-    def __init__(self,dom,repository):
-        ModuleScm.__init__(self, dom, repository)
+    """
+    Describes the properties of a module's <p4 element
+    """
+    def __init__(self, dom, repository):
+        ModuleScm.__init__(self,  dom,  repository)
 
         # Reference to the shared repository
-        self.hostname='perforce:1666'
+        self.hostname = 'perforce:1666'
         if repository.hasDomChild('root'):
-            root=repository.getDomChild('root')
-            self.method=getDomChildValue(root,'method')
-            self.user=getDomChildValue(root,'user')
-            self.password=getDomChildValue(root,'password')
-            self.path=getDomChildValue(root,'path')
-            self.hostname=getDomChildValue(root,'hostname')
-            self.clientspec=getDomChildValue(root,'clientspec')
+            root = repository.getDomChild('root')
+            self.method = getDomChildValue(root, 'method')
+            self.user = getDomChildValue(root, 'user')
+            self.password = getDomChildValue(root, 'password')
+            self.path = getDomChildValue(root, 'path')
+            self.hostname = getDomChildValue(root, 'hostname')
+            self.clientspec = getDomChildValue(root, 'clientspec')
 
-        self.tag=self.getDomAttributeValue('tag')
+        self.tag = self.getDomAttributeValue('tag')
 
     def getPort(self):
         return str(self.hostname)
@@ -156,172 +187,179 @@
 
     def getClientspec(self):
         return str(self.clientspec)
-    
+
     def hasTag(self):
-        if self.tag: return True
+        if self.tag:
+            return True
         return False
-        
+
     def getTag(self):
         return str(self.tag)
-        
+
 class ModuleArtifacts(ModelObject):
-    def __init__(self,dom,repository):
-        ModelObject.__init__(self,dom)
-        
+    """
+    Describes the properties of a module's <artifacts element
+    """
+    def __init__(self, dom, repository):
+        ModelObject.__init__(self, dom)
+
         # Reference to the shared repository
-        self.repository=repository
-        
+        self.repository = repository
+
         # Extract settings
         self.url = self.getDomAttributeValue('url')
-        self.group=self.getDomAttributeValue('group')
-    
+        self.group = self.getDomAttributeValue('group')
+
     def getRootUrl(self):
-        url=self.repository.getUrl()
+        url = self.repository.getUrl()
         if self.hasUrl():
-            url+=self.getUrl()
+            url += self.getUrl()
         return url
-        
+
     def hasUrl(self):
-        if self.url: return True
+        if self.url:
+            return True
         return False
-        
+
     def getUrl(self):
         return self.url
-        
+
     def getGroup(self):
         return self.group
-        
+
 class Module(NamedModelObject, Statable, Resultable, Positioned):
     """Set of Modules (which contain projects)"""
-    def __init__(self,name,dom,owner):
-        NamedModelObject.__init__(self,name,dom,owner)
-                
+    def __init__(self, name, dom, owner):
+        NamedModelObject.__init__(self, name, dom, owner)
+
         Statable.__init__(self)
         Resultable.__init__(self)
         Positioned.__init__(self)
-        
-        self.totalDepends=[]
-        self.totalDependees=[]
-    
-        self.projects={}
-        
-        self.notifys=[]
-        
-        self.repository=None
+
+        self.totalDepends = []
+        self.totalDependees = []
+
+        self.projects = {}
+
+        self.notifys = []
+
+        self.repository = None
         self.scm = None
-        
+
         self.packaged           =       False 
-        self.redistributable=   False
-        
+        self.redistributable =    False
+
         # Changes were found (when updating)
         self.modified           =       False
-        
+
         # The task of updating has occured..
         self.updated            =       False
-        
+
         self.affected           =       0
-                
+
         # Extract settings
-        self.tag=''
-                
-        self.url=None
-        self.desc=''
-        
+        self.tag = ''
+
+        self.url = None
+        self.desc = ''
+
         # 
-        self.workspace=None
-        self.workdir=None
-        
-        self.groupId=None
-           
-    def getObjectForTag(self,tag,dom,name=None):
+        self.workspace = None
+        self.workdir = None
+
+        self.groupId = None
+
+    def getObjectForTag(self, tag, dom, name = None):
         """
-                Get a new (or spliced) object for this tag      
+                Get a new (or spliced) object for this tag
         """
-        
-        object=None
-      
+
+        obj = None
+
         if 'project' == tag:
-            
-            owner=self.getOwner()
+
+            owner = self.getOwner()
             if self.hasProject(name):
-                object=self.getProject(name)
-                object.splice(dom)
+                obj = self.getProject(name)
+                obj.splice(dom)
             elif owner.hasProject(name):
-                object=owner.getProject(name)
-                object.splice(dom)
+                obj = owner.getProject(name)
+                obj.splice(dom)
                 self.addProject(object)
             else:
-                from gump.core.model.project import Project    
-                object=Project(name,dom,self)
+                obj = Project(name, dom, self)
                 self.addProject(object)
 
-        return object                                          
-      
+        return obj
+
     def resolve(self):
         """
         Resolving requires creating objects (in the correct lists/maps) for
         certain high level XML elements, e.g. <project.
         """
-        
-        if self.isResolved(): return
-        
-        owner=self.getOwner()
-        
+
+        if self.isResolved():
+            return
+
+        owner = self.getOwner()
+
         for pdom in self.getDomChildIterator('project'):
-            if hasDomAttribute(pdom,'name'):
-                name=getDomAttributeValue(pdom,'name')
-                
+            if hasDomAttribute(pdom, 'name'):
+                name = getDomAttributeValue(pdom, 'name')
+
                 if owner.hasProject(name):
-                    project=owner.getProject(name)
-                            
+                    project = owner.getProject(name)
+
                     if not self.hasProject(name):
-                        if not project.inModule() or (project.getModule() == self):
+                        if not project.inModule() \
+                                or (project.getModule() == self):
                             self.addProject(project)
-                        else:
-                            pass 
-                            # Duplicate project... Hmm
-                            # :TODO:
+                    else:
+                        # Duplicate project... Hmm
+                        # :TODO:
+                        pass 
                     project.splice(pdom)
-                elif self.hasProject(name):                    
+                elif self.hasProject(name):
                     project.splice(pdom)
                 else:
-                    project=Project(name,pdom,self)
+                    project = Project(name, pdom, self)
                     self.addProject(project) 
-        
+
         self.setResolved()
-                
+
     # provide default elements when not defined in xml
-    def complete(self,workspace):
-          
+    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   
-        self.workspace=workspace
-        
+        if self.isComplete():
+            return
+
+        # :TODO: hacky
+        self.workspace = workspace
+
         # Defaults
-        self.workdir=self.getName()
-        self.groupId=self.getName()
-             
+        self.workdir = self.getName()
+        self.groupId = self.getName()
+
         # Import overrides from DOM
-        transferDomInfo( self.element, self, {'srcdir':'workdir'})
-                            
-        packaged=False
-                
+        transferDomInfo(self.element, self, {'srcdir':'workdir'})
+
+        packaged = False
+
         # Claim ownership & check for packages
         # ###################################################
         # A module which contains only packaged projects might as
         # well be considered packages, no need to update from CVS
         # since we won't be building.
-        packageCount=0
-        allPackaged=True
-                        
+        packageCount = 0
+        allPackaged = True
+
         for project in self.getProjects():
-          
+
             #
             # Check for duplications
             #
@@ -329,30 +367,33 @@
                 # Claim ownership
                 self.addProject(project)
             elif not self == project.getModule():
-                workspace.addError('Duplicate project [' + project.getName() + '] in [' \
-                        + project.getModule().getName() + '] and now [' + self.getName() + ']')
-                
+                workspace.addError('Duplicate project [' + project.getName() + \
+                                       '] in [' \
+                                       + project.getModule().getName() \
+                                       + '] and now [' + self.getName() + ']')
+
             #
             # Check for packaged
             #
             if not project.isPackaged():
-                allPackaged=False
+                allPackaged = False
             else:
                 self.addInfo('Packaged Project: ' + project.getName())
-                packageCount+=1                
-       
+                packageCount += 1
+
         # Must be one to be all
-        if not packageCount: allPackaged=False
-    
+        if not packageCount:
+            allPackaged = False
+
         log.debug('Packaged? ' + `self` + ':' + `packageCount`)
-            
+
         # Give this module a second try,  if some are packaged, and
         # check if the others have no outputs, then call them good.
         if packageCount and not allPackaged:
-            
+
             log.debug('Packaged? ' + `self` + ':' + `packageCount`)
-        
-            allPackaged=True
+
+            allPackaged = True
             for project in self.getProjects():
                 if not project.isPackaged():
                     if not project.hasOutputs():
@@ -361,87 +402,88 @@
                         # project in a module as a package, and those that do
                         # not product significant outputs (e.g. test projects)
                         # will be asssumed to be packages.
-                        #                
-                        project.setHonoraryPackage(True)            
-                        project.changeState(STATE_COMPLETE,REASON_PACKAGE)    
-                        packageCount+=1
-                    else:    
-                        allPackaged=False
+                        #
+                        project.setHonoraryPackage(True)
+                        project.changeState(STATE_COMPLETE, REASON_PACKAGE)
+                        packageCount += 1
+                    else:
+                        allPackaged = False
                         if packageCount:
-                            self.addWarning('Incomplete \'Packaged\' Module. Project: ' + \
-                                    project.getName() + ' is not packaged')  
-               
+                            self.addWarning('Incomplete \'Packaged\' Module. ' \
+                                                + 'Project: ' \
+                                                + project.getName() \
+                                                + ' is not packaged')
+
         # If packages module, accept it... 
         if allPackaged:
-            packaged=True
+            packaged = True
             self.setPackaged(True)
-            self.changeState(STATE_COMPLETE,REASON_PACKAGE)  
+            self.changeState(STATE_COMPLETE, REASON_PACKAGE)
             self.addInfo("\'Packaged\' Module. (Packaged projects: " + \
-                                    `packageCount` + '.)')                                            
+                                    `packageCount` + '.)')
 
         # Determine source directory
-        self.absWorkingDir=     \
-                os.path.abspath(
-                        os.path.join(workspace.getBaseDirectory(),      
-                                self.workdir))
-        
-        self.absSrcCtlDir=    \
-                 os.path.abspath(
-                         os.path.join(    workspace.getSourceControlStagingDirectory(), 
-                                            self.getName())) # todo allow override              
+        self.absWorkingDir = \
+            os.path.abspath(os.path.join(workspace.getBaseDirectory(),
+                                         self.workdir))
+
+        self.absSrcCtlDir = \
+            os.path.abspath(
+            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'))
-                               
+        self.absUpdateLock = \
+            os.path.abspath(
+            os.path.join(workspace.getSourceControlStagingDirectory(), 
+                         self.getName() + '.lock'))
+
         if not packaged:
             self.parseScm()
 
         # Grab all notifications
         for notifyEntry in self.getDomChildIterator('nag'):
             # Determine where to send
-            toaddr=getDomAttributeValue(notifyEntry,'to',workspace.administrator)
-            fromaddr=getDomAttributeValue(notifyEntry,'from',workspace.email)   
-            self.notifys.append(
-                    AddressPair(
-                        getStringFromUnicode(toaddr),
-                        getStringFromUnicode(fromaddr)))  
-        
+            toaddr = getDomAttributeValue(notifyEntry, 'to',
+                                          workspace.administrator)
+            fromaddr = getDomAttributeValue(notifyEntry, 'from',
+                                            workspace.email)
+            self.notifys.append(AddressPair(
+                    getStringFromUnicode(toaddr),
+                    getStringFromUnicode(fromaddr)))
+
 
         if self.hasDomChild('url'):
-            url=self.getDomChild('url')
-            self.url=getDomAttributeValue(url,'href')
-            
+            url = self.getDomChild('url')
+            self.url = getDomAttributeValue(url, 'href')
+
         if self.hasDomChild('description'):
-            self.desc=self.getDomChildValue('description')           
+            self.desc = self.getDomChildValue('description')
 
         # Existence means 'true'
-        self.redistributable=self.hasDomChild('redistributable')    
+        self.redistributable = self.hasDomChild('redistributable')
 
         # make groupId default to module's name
         if not self.groupId:
-            self.groupId = self.getName();
+            self.groupId = self.getName()
 
         # For prettiness
-        self.sortedProjects=createOrderedList(self.getProjects())
-                            
+        self.sortedProjects = createOrderedList(self.getProjects())
+
         # Copy over any XML errors/warnings
-        # :TODO:#1: transferAnnotations(self.xml, self)  
-                
-        self.setComplete(True)            
-        
+        # :TODO:#1: transferAnnotations(self.xml, self)
+
+        self.setComplete(True)
+
     def parseScm(self):
         """
         Parses the child element that holds SCM information
         """
 
-        # sorted by priority, the first matching SCM element wins
-        supportedScms = ['cvs', 'svn', 'p4', 'git', 'artifacts']
-        for s in supportedScms:
-            if self.hasDomChild(s):
-                dom = self.getDomChild(s)
+        for s in SUPPORTED_SCMS:
+            if self.hasDomChild(s.name):
+                dom = self.getDomChild(s.name)
                 repoName = getDomAttributeValue(dom, 'repository')
                 if repoName:
                     if self.workspace.hasRepository(repoName):
@@ -449,293 +491,291 @@
                         repo = self.workspace.getRepository(repoName)
                         self.repository = repo
                         repo.addModule(self)
-                        self.scm = self.createScmInstance(s, dom, repo)
+                        self.scm = create_scm_instance(s, dom, repo)
                     else:
-                        self.changeState(STATE_FAILED,REASON_CONFIG_FAILED)
-                        self.addError('No such repository ['+ str(repoName) \
-                                          +'] in workspace on [' \
-                                          + self.getName() + ']')
+                        self.changeState(STATE_FAILED, REASON_CONFIG_FAILED)
+                        self.addError('No such repository [' +  str(repoName) \
+                                           + '] in workspace on [' \
+                                           +  self.getName() + ']')
                 return
 
 
-    def createScmInstance(self, type, dom, repo):
-        """
-        Factory method for matching ModuleScm subclass of given SCM
-        """
-        if type == 'cvs':
-            return ModuleCvs(dom, repo)
-        elif type == 'p4':
-            return ModuleP4(dom, repo)
-        elif type == 'artifacts':
-            return ModuleArtifacts(dom, repo)
-        return ModuleScm(dom, repo)
-
     def hasNotifys(self):
-        if self.notifys: return True
+        if self.notifys:
+            return True
         return False
-        
+
     def getNotifys(self):
         return self.notifys
-        
+
     def getArtifactGroup(self):
         """
         What do this module's artifacts group under?
-        
+
         Return String
         """
         return self.groupId
-        
-    def addProject(self,project):
+
+    def addProject(self, project):
         """
                 Associate this module with this project, and vice verse.
         """
-        name=project.getName()
-        
+        name = project.getName()
+
         if self.hasProject(name):
             raise RuntimeError, 'Attempt to add duplicate project: ' + name
-            
+
         # Reference this module as owner
         project.setModule(self)
-        
+
         # Stash project
-        self.projects[name]=project
-        
+        self.projects[name] = project
+
         # Teach workspace about this also...
         if not self.getOwner().hasProject(name):
             self.getOwner().addProject(project)
         else:
-            otherProject=self.getOwner().getProject(name)
-            
+            otherProject = self.getOwner().getProject(name)
+
             if not project is otherProject:
-                raise RuntimeError, 'Attempt to add duplicate project (in module): ' + name    
-                     
-    def hasProject(self,name):
+                raise RuntimeError, \
+                    'Attempt to add duplicate project (in module): ' + name
+
+    def hasProject(self, name):
         return self.projects.has_key(name)
-        
-    def getProject(self,name):
+
+    def getProject(self, name):
         return self.projects[name]
-        
+
     def getProjects(self):
         return self.projects.values()
-        
+
     def getSortedProjects(self):
-        return self.sortedProjects        
-  
+        return self.sortedProjects
+
     def getChildren(self):
-        return self.getProjects()        
-        
+        return self.getProjects()
+
     def isPackaged(self):
         return self.packaged
-                
-    def setPackaged(self,packaged):
-        self.packaged=packaged
-        
+
+    def setPackaged(self, packaged):
+        self.packaged = packaged
+
     def isRedistributable(self):
         # Existence means 'true'
         return self.redistributable or \
             (self.repository and self.repository.isRedistributable())
-        
+
     #
     # Get a full list of all the projects that depend
     # upon projects in this module 
     #
-    def getFullDependees(self):   
+    def getFullDependees(self):
         # Calculated once only...
-        if self.totalDependees: return self.totalDependees
-                
+        if self.totalDependees:
+            return self.totalDependees
+
         for project in self.getProjects():
             if not project in self.totalDependees:
                 self.totalDependees.append(project)
                 for dependee in project.getFullDependees():
-                    dependeeProject=dependee.getOwnerProject()
+                    dependeeProject = dependee.getOwnerProject()
                     if not dependeeProject in self.totalDependees:
-                        self.totalDependees.append(dependeeProject)   
-                        
-        # Sort for prettiness...                     
+                        self.totalDependees.append(dependeeProject)
+
+        # Sort for prettiness...
         self.totalDependees.sort()
         return self.totalDependees
-            
-    def getFullDependeeCount(self):         
-        return len(self.getFullDependees())   
-            
-    def getFullDepends(self):   
-        if self.totalDepends: return self.totalDepends
-                
+
+    def getFullDependeeCount(self):
+        return len(self.getFullDependees())
+
+    def getFullDepends(self):
+        if self.totalDepends:
+            return self.totalDepends
+
         for project in self.getProjects():
             if not project in self.totalDepends:
                 self.totalDepends.append(project)
                 for depend in project.getFullDependencies():
-                    dependProject=depend.getProject()
+                    dependProject = depend.getProject()
                     if not dependProject in self.totalDepends:
-                        self.totalDepends.append(dependProject)                        
+                        self.totalDepends.append(dependProject)
         self.totalDepends.sort()
         return self.totalDepends
-            
-    def getFullDependencyCount(self):         
-        return len(self.getFullDepends())   
-        
+
+    def getFullDependencyCount(self):
+        return len(self.getFullDepends())
+
     def getFOGFactor(self):
-        fogFactor=0
-        fogFactors=0
+        fogFactor = 0
+        fogFactors = 0
         for project in self.getProjects():
             projectFOGFactor = project.getFOGFactor()
             fogFactor += projectFOGFactor
             fogFactors += 1
-                
+
         if not fogFactors:
-            fogFactors=1 # 0/1 is better than 0/0
-            
+            fogFactors = 1 # 0/1 is better than 0/0
+
         return float(fogFactor)/float(fogFactors)
-        
+
     def getHistoricalOddsOfSuccess(self):
-        historicalOdds=0
-        historicalOddses=0
+        historicalOdds = 0
+        historicalOddses = 0
         for project in self.getProjects():
-                projectHistoricalOddsOfSuccess = project.getHistoricalOddsOfSuccess()
-                historicalOdds += projectHistoricalOddsOfSuccess
-                historicalOddses += 1
-                
+            projectHistoricalOddsOfSuccess = \
+                project.getHistoricalOddsOfSuccess()
+            historicalOdds += projectHistoricalOddsOfSuccess
+            historicalOddses += 1
+
         if not historicalOddses:
-            historicalOddses=1 # 0/1 is better than 0/0
-            
+            historicalOddses = 1 # 0/1 is better than 0/0
+
         return float(historicalOdds)/float(historicalOddses)
-        
+
     def hasLastModified(self):
-        return self.getStats().hasLastModified()                
-    
+        return self.getStats().hasLastModified()
+
     def getLastModified(self):
-        return self.getStats().getLastModified()                
-    
+        return self.getStats().getLastModified()
+
     # Get a summary of states for each project
-    def getProjectSummary(self,summary=None):  
-    
+    def getProjectSummary(self, summary = None):
+
         # Fails 'cos count into other's summary
-        # if hasattr(self,'summary'): return self.summary
-        
+        # if hasattr(self, 'summary'): return self.summary
+
         if not summary: 
-            summary=ProjectSummary()
-        
+            summary = ProjectSummary()
+
         #
         # Subordinates are projects, so get their summary
         #
         for project in self.getProjects():
             summary.addState(project.getStatePair())
-        
+
         # Fails, see above.
         # Store for later...
         # self.summary = summary
-        
+
         return summary
-    def dump(self, indent=0, output=sys.stdout):
-        output.write(getIndent(indent)+'Module : ' + self.name + '\n')
-        NamedModelObject.dump(self, indent+1, output)
+    def dump(self,  indent = 0,  output = sys.stdout):
+        output.write(getIndent(indent) + 'Module : '  +  self.name  +  '\n')
+        NamedModelObject.dump(self, indent + 1, output)
         if self.isPackaged():
-            output.write(getIndent(indent+1)+'Packaged Module\n')
-        
+            output.write(getIndent(indent + 1) + 'Packaged Module\n')
+
     def hasTag(self):
-        if self.tag: return True
+        if self.tag:
+            return True
         return False
-        
+
     def getTag(self):
         return str(self.tag)
-        
+
     def getSourceControlStagingDirectory(self):
         return self.absSrcCtlDir
-        
+
     def getUpdateLockFile(self):
         return self.absUpdateLock
-        
+
     def getWorkingDirectory(self):
         return self.absWorkingDir
-        
+
     def getModuleDirName(self):
         return self.workdir
-        
+
     def hasUrl(self):
-        if self.url: return True
+        if self.url:
+            return True
         return False
-        
+
     def getUrl(self):
         return self.url
-        
+
     def hasDescription(self):
-        if self.desc: return True
+        if self.desc:
+            return True
         return False
-        
+
     def getDescription(self):
-        return self.desc     
-        
+        return self.desc
+
     def getWorkspace(self):
         return self.workspace
-    
+
     def getMetadataLocation(self):
-        return self.metadata            
-        
+        return self.metadata
+
     def getMetadataViewUrl(self):
-        location=self.getMetadataLocation()
+        location = self.getMetadataLocation()
         if location:
-            if location.startswith('http'): return location
+            if location.startswith('http'):
+                return location
             # :TODO: Make configurable
             return 'http://svn.apache.org/repos/asf/gump/metadata/' + location
-        
+
     def isUpdatable(self):
-        if self.scm: return True
+        if self.scm:
+            return True
         return False
-                
+
     # Where the contents (at the repository) Modified?
     def isModified(self):
         return self.modified
-        
-    def setModified(self,modified):
-        self.modified=modified
-    
+
+    def setModified(self, modified):
+        self.modified = modified
+
     # Where the contents (at the repository) Updated?
     def isUpdated(self):
         return self.updated
-        
-    def setUpdated(self,updated):
-        self.updated=updated
-    
+
+    def setUpdated(self, updated):
+        self.updated = updated
+
     def hasRepository(self):
         return self.repository
-        
+
     def getRepository(self):
         return self.repository
-    
-    def getViewUrl(self):
-        scm = getScm(self);
-        if scm:
-            return scm.getViewUrl()
 
     def getScm(self):
         return self.scm
 
+    def getViewUrl(self):
+        if self.scm:
+            return self.scm.getViewUrl()
+
 class ModuleStatistics(Statistics):
     """ 
         Module Statistics Holder
     """
-    def __init__(self,moduleName):
-        Statistics.__init__(self,moduleName)    
-        self.lastModified=None
-        
+    def __init__(self, moduleName):
+        Statistics.__init__(self, moduleName)
+        self.lastModified = None
+
     def hasLastModified(self):
-        if self.lastModified: return True
+        if self.lastModified:
+            return True
         return False
-        
+
     def getLastModified(self):
         return self.lastModified
-        
+
     def getKeyBase(self):
-        return 'module:'+ self.name
-        
+        return 'module:' +  self.name
+
     def lastModifiedKey(self):
         return self.getKeyBase() + '-last-updated'
-        
-    def update(self,module):      
-        Statistics.update(self,module)
+
+    def update(self, module):
+        Statistics.update(self, module)
 
         #
         # Track code updates/changes
         # 
         if module.isModified():
-            self.lastModified=default.datetime
+            self.lastModified = default.datetime

Modified: gump/live/python/gump/core/model/repository.py
URL: http://svn.apache.org/viewvc/gump/live/python/gump/core/model/repository.py?rev=749185&r1=749184&r2=749185&view=diff
==============================================================================
--- gump/live/python/gump/core/model/repository.py (original)
+++ gump/live/python/gump/core/model/repository.py Mon Mar  2 05:00:11 2009
@@ -15,166 +15,200 @@
 # See the License for the specific language governing permissions and
 # limitations under the License.
 
-"""
-    This module contains information on
-"""
-
-from gump.core.model.state import *
-from gump.core.model.stats import *
+import sys
 
 from gump.core.model.object import NamedModelObject
-
+from gump.core.model.stats import Statable, Statistics
 from gump.util import getIndent
-from gump.util.domutils import *
+from gump.util.domutils import getDomChildValue
+
+class ScmType:
+    """
+    enum-like class describing all supported SCMs
+    """
+
+    def __init__(self, name, displayName):
+        self.name = name
+        self.displayName = displayName
+
+SCM_TYPE_CVS = ScmType('cvs', 'CVS')
+SCM_TYPE_SVN = ScmType('svn', 'Subversion')
+SCM_TYPE_ARTIFACTS = ScmType('artifacts', 'Artfifacts')
+SCM_TYPE_P4 = ScmType('p4', 'Perforce')
+SCM_TYPE_GIT = ScmType('git', 'Git')
+
+# sorted by priority, the first matching SCM element inside a module wins
+SUPPORTED_SCMS = [SCM_TYPE_CVS, SCM_TYPE_SVN, SCM_TYPE_P4,
+                  SCM_TYPE_GIT,
+                  SCM_TYPE_ARTIFACTS]
+
+def scm_type_for_name(name):
+    """
+    looks up a supported SCM by its name
+    """
+    for s in SUPPORTED_SCMS:
+        if s.name == name:
+            return s
+    return None
 
 class Repository(NamedModelObject, Statable):
     """ 
-    
+
     A named repository (CVS|SVN|Perforce|Artifacts|GIT) 
-    
+
     """
-    def __init__(self,name,dom,workspace):
-    	NamedModelObject.__init__(self,name,dom,workspace)
-            
-        self.url=None
-        
-        typeToLabel = {'cvs':'CVS', 'svn':'Subversion', 'artifact':'Artifact',
-                       'p4':'Perforce', 'git':'Git'}
-
-        type=self.getDomAttributeValue('type')
-        
-        try:
-            self.type = typeToLabel[type]
-        except:
-            raise RuntimeError, 'Invalid Repository Type:' + str(xml.type)
-
-        if 'cvs'==type:
-            self.web=self.getDomChildValue('cvsweb') or \
-                        self.getDomChildValue('web')
+    def __init__(self, name, dom, workspace):
+        NamedModelObject.__init__(self, name, dom, workspace)
+        Statable.__init__(self)
+
+        self.url = None
+
+        typeAttribute = self.getDomAttributeValue('type')
+        self.scmType = scm_type_for_name(typeAttribute)
+        if not self.scmType:
+            raise RuntimeError, 'Invalid Repository Type:' + str(typeAttribute)
+
+        if SCM_TYPE_CVS == self.scmType:
+            self.web = self.getDomChildValue('web') or \
+                self.getDomChildValue('cvsweb')
             if self.hasDomChild('root'):
-                root=self.getDomChild('root')
-                self.method=getDomChildValue(root,'method')  
-                self.user=getDomChildValue(root,'user')
-                self.password=getDomChildValue(root,'password')
-                self.path=getDomChildValue(root,'path')
-                self.hostname=getDomChildValue(root,'hostname')
+                root = self.getDomChild('root')
+                self.method = getDomChildValue(root, 'method')
+                self.user = getDomChildValue(root, 'user')
+                self.password = getDomChildValue(root, 'password')
+                self.path = getDomChildValue(root, 'path')
+                self.hostname = getDomChildValue(root, 'hostname')
             else:
                 raise RuntimeError, 'No XML <root on repository: ' \
                     + self.getName()
-        elif 'p4'==type:
+        elif SCM_TYPE_P4 == self.scmType:
             if self.hasDomChild('root'):
-                root=self.getDomChild('root')
-                self.p4port=getDomChildValue(root,'hostname')
+                root = self.getDomChild('root')
+                self.p4port = getDomChildValue(root, 'hostname')
             else:
                 raise RuntimeError, 'No Perforce server on P4 repository: ' \
                     + self.getName()
-            self.web=self.getDomChildValue('web')
+            self.web = self.getDomChildValue('web')
         else:
             if self.hasDomChild('url'):
-                self.url=self.getDomChildValue('url')
+                self.url = self.getDomChildValue('url')
             else:
-                raise RuntimeError, 'No URL on ' + self.type + ' repository: ' \
-                    + self.getName()
-            self.web=self.getDomChildValue('web')
-            self.user=self.getDomChildValue('user')            
-            self.password=self.getDomChildValue('password')
-            
+                raise RuntimeError, 'No URL on ' + self.scmType.displayName + \
+                    ' repository: ' + self.getName()
+            self.web = self.getDomChildValue('web')
+            self.user = self.getDomChildValue('user')
+            self.password = self.getDomChildValue('password')
+
         # Modules referencing this repository
-        self.modules=[]
-            
-    def complete(self,workspace):
+        self.modules = []
+
+    def complete(self, workspace):
         pass
-                     
-    def check(self,workspace):
+
+    def check(self, workspace):
         if not self.hasModules():
             self.addWarning('Unused Repository (not referenced by modules)')
-    
+
     def hasModules(self):
-        if self.modules: return True
+        if self.modules:
+            return True
+        return False
+
+    def hasScmType(self):
+        if self.scmType:
+            return True
         return False
-    
-    def hasType(self):
-        if self.type: return True
-        return False
-           
-    def getType(self):
-        return self.type
-            
+
+    def getScmType(self):
+        return self.scmType
+
     def getModules(self):
         return self.modules
-    
-    def dump(self, indent=0, output=sys.stdout):
-        output.write(getIndent(indent)+'Repository : ' + self.name + '\n')   
-        NamedModelObject.dump(self,indent+1,output)
-        
+
+    def dump(self, indent = 0, output = sys.stdout):
+        output.write(getIndent(indent) + 'Repository : ' + self.name + '\n')
+        NamedModelObject.dump(self, indent + 1, output)
+
     def hasTitle(self): 
         return self.hasDomAttribute('title')
-        
+
     def hasHomePage(self): 
         return self.hasDomAttribute('home-page')
-        
+
     def hasWeb(self): 
         return self.web
 
     def isRedistributable(self):
         # Existence means 'true'
         return self.hasDomChild('redistributable')
-        
+
     def hasUser(self): 
-        if hasattr(self,'user'):
-            if self.user: return True            
+        if hasattr(self, 'user'):
+            if self.user:
+                return True
         return False
-    def hasPassword(self):        
-        if hasattr(self,'password'):
-            if self.password: return True            
+
+    def hasPassword(self):
+        if hasattr(self, 'password'):
+            if self.password:
+                return True
         return False
-        
+
     def hasPath(self): 
-        if hasattr(self,'path'):
-            if self.path: return True            
+        if hasattr(self, 'path'):
+            if self.path:
+                return True
         return False
-        
+
     def hasMethod(self):
-        if hasattr(self,'method'):
-            if self.method: return True            
+        if hasattr(self, 'method'):
+            if self.method:
+                return True
         return False
-        
+
     def hasHostname(self): 
-        if hasattr(self,'hostname'):
-            if self.hostname: return True            
+        if hasattr(self, 'hostname'):
+            if self.hostname:
+                return True
         return False
-    
-    def getTitle(self): return self.getDomAttributeValue('title')
-    def getHomePage(self): return self.getDomAttributeValue('home-page')
-    def getWeb(self): return self.web
-    
-    def getUser(self): return self.user
-    def getPassword(self): return self.password
-    def getPath(self): return self.path
-    def getMethod(self): return self.method
-    def getHostname(self): return self.hostname
-    
+
+    def getTitle(self):
+        return self.getDomAttributeValue('title')
+    def getHomePage(self):
+        return self.getDomAttributeValue('home-page')
+    def getWeb(self):
+        return self.web
+
+    def getUser(self):
+        return self.user
+    def getPassword(self):
+        return self.password
+    def getPath(self):
+        return self.path
+    def getMethod(self):
+        return self.method
+    def getHostname(self):
+        return self.hostname
+
     def hasUrl(self): 
-        if self.url: return True
+        if self.url:
+            return True
         return False
-        
+
     def getUrl(self): 
         return self.url
-    
-    def addModule(self,module):
+
+    def addModule(self, module):
         self.modules.append(module)
-        
-    def getModules(self): 
-        return self.modules    
-        
+
 class RepositoryStatistics(Statistics):
     """
-    	Statistics Holder
+        Statistics Holder
     """
-    def __init__(self,repositoryName):
-        Statistics.__init__(self,repositoryName)
+    def __init__(self, repositoryName):
+        Statistics.__init__(self, repositoryName)
 
     def getKeyBase(self):
-        return 'repository:'+ self.name        
-        
-    
+        return 'repository:'+ self.name
+
+

Modified: gump/live/python/gump/core/update/cvs.py
URL: http://svn.apache.org/viewvc/gump/live/python/gump/core/update/cvs.py?rev=749185&r1=749184&r2=749185&view=diff
==============================================================================
--- gump/live/python/gump/core/update/cvs.py (original)
+++ gump/live/python/gump/core/update/cvs.py Mon Mar  2 05:00:11 2009
@@ -15,9 +15,12 @@
 # See the License for the specific language governing permissions and
 # limitations under the License.
 
+import os.path
+
 from gump.core.model.workspace import Cmd
-from gump.core.update.scmupdater import ScmUpdater
+from gump.core.update.scmupdater import ScmUpdater, should_be_quiet
 from gump.tool.integration.cvs import readLogins, loginToRepositoryOnDemand
+from gump.util.tools import tailFileToString
 
 def maybe_add_tag(module, cmd):
     # Determine if a tag is set, on <cvs or on <module
@@ -29,6 +32,28 @@
     if tag:
         cmd.addParameter('-r', tag, ' ')
 
+def setup_common_parameters(module, cmd):
+    if should_be_quiet(module):    
+        cmd.addParameter('-q')
+    elif module.isDebug():
+        cmd.addParameter('-t')
+    # Request compression
+    cmd.addParameter('-z3')
+          
+    # Set the CVS root
+    cmd.addParameter('-d', module.getScm().getCvsRoot())    
+
+def error_unless_file_content_matches(cvsdir, filename, expected_content,
+                                      prop):
+    f = os.path.join(cvsdir, filename)
+    if not os.path.exists(f):
+        return (False, 'workspace doesn\'t contain a ' + filename + ' file')
+    actual = tailFileToString(f, 1).rstrip()
+    if actual != expected_content:
+        return (False, 'expected ' + prop + ' to be \'' + \
+                        expected_content + '\' but is \'' + actual + '\'')
+    return None
+
 ###############################################################################
 # Classes
 ###############################################################################
@@ -54,7 +79,7 @@
     
         cmd = Cmd('cvs', 'update_' + module.getName(),
                   module.getWorkspace().getSourceControlStagingDirectory())
-        self.setupCommonParameters(module, cmd)
+        setup_common_parameters(module, cmd)
           
         # do a cvs checkout
         cmd.addParameter('checkout')
@@ -81,7 +106,7 @@
     
         cmd = Cmd('cvs', 'update_' + module.getName(),
                   module.getSourceControlStagingDirectory())
-        self.setupCommonParameters(module, cmd)
+        setup_common_parameters(module, cmd)
           
         # Do a cvs update
         cmd.addParameter('update')
@@ -91,16 +116,48 @@
 
         return cmd
     
-    def setupCommonParameters(self, module, cmd):
-        if self.shouldBeQuiet(module):    
-            cmd.addParameter('-q')
-        elif module.isDebug():
-            cmd.addParameter('-t')
-        # Request compression
-        cmd.addParameter('-z3')
-          
-        # Set the CVS root
-        cmd.addParameter('-d', module.getScm().getCvsRoot())    
+    def workspaceMatchesModule(self, module):
+        """
+        look for a CVS directory and the files contained therein, try to match
+        the contents of said files
+        """
+        cvsdir = os.path.join(module.getSourceControlStagingDirectory(),
+                               'CVS')
+        if not os.path.exists(cvsdir):
+            return (False, 'workspace doesn\'t contain a CVS directory')
+
+        root = error_unless_file_content_matches(cvsdir, 'Root',
+                                                 module.getScm().getCvsRoot(),
+                                                 'CVSROOT')
+        if root:
+            return root
+
+        expected_module = module.getName()
+        if module.getScm().hasModule():
+            expected_module = module.getScm().getModule()
+        rep = error_unless_file_content_matches(cvsdir, 'Repository',
+                                                expected_module, 'Module')
+        if rep:
+            return rep
+
+        if module.getScm().hasTag() or module.hasTag():
+            expected_tag = 'T'
+            if module.getScm().hasTag():
+                expected_tag += module.getScm().getTag()
+            elif module.hasTag():
+                expected_tag += module.getTag()
+            tag = error_unless_file_content_matches(cvsdir, 'Tag',
+                                                    expected_tag, 'Tag')
+            if tag:
+                return tag
+
+        elif os.path.exists(os.path.join(cvsdir, 'Tag')):
+            return (False, 'workspace is tagged with \'' + \
+                        tailFileToString(os.path.join(cvsdir, 'Tag'),
+                                         1).rstrip() + \
+                        '\' but shouldn\'t have a tag at all.')
+
+        return (True, '')
 
     def maybeLogin(self, module):
         repository = module.repository

Modified: gump/live/python/gump/core/update/git.py
URL: http://svn.apache.org/viewvc/gump/live/python/gump/core/update/git.py?rev=749185&r1=749184&r2=749185&view=diff
==============================================================================
--- gump/live/python/gump/core/update/git.py (original)
+++ gump/live/python/gump/core/update/git.py Mon Mar  2 05:00:11 2009
@@ -17,8 +17,10 @@
 # limitations under the License.
 
 from gump import log
-from gump.core.model.workspace import Cmd
-from gump.core.update.scmupdater import ScmUpdater
+from gump.core.update.scmupdater import match_workspace_template, ScmUpdater, \
+    should_be_quiet
+from gump.util.process.command import Cmd
+from gump.util.tools import tailFileToString
 
 def log_repository_and_url(module):
     repository = module.repository
@@ -27,6 +29,10 @@
                   repository.getName())
 
                   
+def maybe_make_quiet(module, cmd):
+    if should_be_quiet(module):    
+        cmd.addParameter('--quiet')
+
 ###############################################################################
 # Classes
 ###############################################################################
@@ -47,7 +53,7 @@
         log_repository_and_url(module)
         cmd = Cmd('git-clone', 'update_' + module.getName(), 
                   module.getWorkspace().getSourceControlStagingDirectory())
-        self.maybeMakeQuiet(module, cmd)
+        maybe_make_quiet(module, cmd)
         cmd.addParameter(module.getScm().getRootUrl())
         cmd.addParameter(module.getName())
         return cmd
@@ -59,9 +65,14 @@
         log_repository_and_url(module)
         cmd = Cmd('git-pull', 'update_' + module.getName(), 
                   module.getSourceControlStagingDirectory())
-        self.maybeMakeQuiet(module, cmd)
+        maybe_make_quiet(module, cmd)
         return cmd
 
-    def maybeMakeQuiet(self, module, cmd):
-        if self.shouldBeQuiet(module):    
-            cmd.addParameter('--quiet')
+    def workspaceMatchesModule(self, module):
+        """
+            Run git config remote.origin.url to see whether the URL matches
+        """
+        return match_workspace_template(module, 'git config remote.origin.url',
+                                        lambda result:
+                                            tailFileToString(result.getOutput(),
+                                                             1).rstrip())

Modified: gump/live/python/gump/core/update/scmupdater.py
URL: http://svn.apache.org/viewvc/gump/live/python/gump/core/update/scmupdater.py?rev=749185&r1=749184&r2=749185&view=diff
==============================================================================
--- gump/live/python/gump/core/update/scmupdater.py (original)
+++ gump/live/python/gump/core/update/scmupdater.py Mon Mar  2 05:00:11 2009
@@ -7,9 +7,9 @@
 # The ASF licenses this file to You under the Apache License, Version 2.0
 # (the "License"); you may not use this file except in compliance with
 # the License.  You may obtain a copy of the License at
-# 
+#
 #     http://www.apache.org/licenses/LICENSE-2.0
-# 
+#
 # Unless required by applicable law or agreed to in writing, software
 # distributed under the License is distributed on an "AS IS" BASIS,
 # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
@@ -20,9 +20,46 @@
 
 from gump import log
 
-from gump.core.model.workspace import CommandWorkItem, execute, \
+from gump.core.model.workspace import CommandWorkItem, \
     REASON_UPDATE_FAILED, STATE_FAILED, STATE_SUCCESS, WORK_TYPE_UPDATE
 from gump.core.run.gumprun import RunSpecific
+from gump.util.process.launcher import execute
+from gump.util.tools import wipeDirectoryTree
+from gump.util.process.command import getCmdFromString
+
+def should_be_quiet(module):
+    """
+    Whether the configuration asks for a quiet update
+    (it does so by default)
+    """
+    return not module.isDebug() \
+        and not module.isVerbose() \
+        and not module.getScm().isDebug() \
+        and not module.getScm().isVerbose()
+
+def match_workspace_template(module, cmd_string, extract_url,
+                             expectedURL = None):
+    """
+    Template for the common run-a-command-and-extract-URL-from-output logic
+    for workspaceMatchesModule Method of ScmUpdater
+    """
+    if not expectedURL:
+        expectedURL = module.getScm().getRootUrl()
+
+    cmd = getCmdFromString(cmd_string, 'check_workspace_' + module.getName(), 
+                           module.getSourceControlStagingDirectory())
+
+    result = execute(cmd)
+
+    if not result.isOk():
+        return (False, cmd_string + ' returned ' + str(result.exit_code))
+
+    elif not result.hasOutput():
+        return (False, cmd_string + ' didn\'t return any output.')
+
+    actualURL = extract_url(result)
+    return (expectedURL == actualURL, 'Expected URL \'' + expectedURL + \
+                '\' but working copy was \'' + actualURL + '\'')
 
 ###############################################################################
 # Classes
@@ -30,10 +67,10 @@
 class ScmUpdater(RunSpecific):
     """
     Base class for a SCM specific updaters.
-    
+
     Provides helpers and template method implementations.
     """
-    
+
     def __init__(self, run):
         RunSpecific.__init__(self, run)
 
@@ -57,34 +94,35 @@
         Performs a fresh check-out or an update of an existing wrokspace.
         """
 
-        log.info('Perform ' + module.getScm().getScmName() + \
+        log.info('Perform ' + module.getScm().getScmType().displayName + \
                      ' Checkout/Update on #[' + `module.getPosition()` + \
                      '] : ' + module.getName())
-    
+
         (cmd, isUpdate) = self.getCommandAndType(module)
 
         if cmd:
             if isUpdate:
-                log.debug(module.getScm().getScmName() + " Module Update : " + \
+                log.debug(module.getScm().getScmType().displayName + \
+                              " Module Update : " + \
                               module.getName() + ", Repository Name: " + \
                               module.repository.getName())
             else:
-                log.debug(module.getScm().getScmName() + \
+                log.debug(module.getScm().getScmType().displayName + \
                               " Module Checkout : " + module.getName() + \
                               ", Repository Name: " + \
                               module.repository.getName())
 
-            # Execute the command and capture results        
+            # Execute the command and capture results
             cmdResult = execute(cmd, module.getWorkspace().tmpdir)
-      
+
             # Store this as work, on both the module and (cloned) on the repo
             work = CommandWorkItem(WORK_TYPE_UPDATE, cmd, cmdResult)
             module.performedWork(work)
             module.repository.performedWork(work.clone())
-      
-            # Update Context w/ Results  
-            if not cmdResult.isOk():              
-                log.error('Failed to checkout/update module: ' + module.name)   
+
+            # Update Context w/ Results
+            if not cmdResult.isOk():
+                log.error('Failed to checkout/update module: ' + module.name)
 
                 #
                 # Here the live branch differs from trunk: while live
@@ -108,12 +146,12 @@
                     module.changeState(STATE_SUCCESS, REASON_UPDATE_FAILED)
 
             else:
-                module.changeState(STATE_SUCCESS)       
+                module.changeState(STATE_SUCCESS)
 
             return module.okToPerformWork()
 
         log.error("Don't know how to to checkout/update module: " + \
-                      module.name)   
+                      module.name)
         module.changeState(STATE_FAILED, REASON_UPDATE_FAILED)
         return False
 
@@ -121,26 +159,28 @@
     # helpers
     #
 
-    def shouldBeQuiet(self, module):
-        """
-        Whether the configuration asks for a quiet update
-        (it does so by default)
-        """
-        return not module.isDebug() \
-            and not module.isVerbose() \
-            and not module.getScm().isDebug() \
-            and not module.getScm().isVerbose()
-
-
     def getCommandAndType(self, module):
         """
         Checks whether an update or a fresh checkout is needed and
         returns a command to perform the required action.
-        
+
         Returns a tuple (command, isUpdate)
         """
         exists = os.path.exists(module.getSourceControlStagingDirectory())
 
+        if exists:
+            (matches, reason) = self.workspaceMatchesModule(module)
+            if not matches:
+                msg = 'The working copy \'' + \
+                    module.getSourceControlStagingDirectory() + \
+                    '\' doesn\'t match the module definition, reason: \'' + \
+                    reason + '\'. Removing it.'
+                log.warn(msg)
+                module.addWarning(msg)
+                wipeDirectoryTree(module.getSourceControlStagingDirectory(),
+                                  False)
+                exists = False
+
         cmd = None
         if exists:
             cmd = self.getUpdateCommand(module)
@@ -165,3 +205,17 @@
         """
         return None
 
+
+    def workspaceMatchesModule(self, module):
+        """
+        Whether the working copy matches what the updater expects it to
+        be - like being a working copy of the module's svn URL or
+        CVS Root etc.
+
+        Must return a tuple (matches, reason) with a bool indicating
+        whether the workspace matches the module defintion and a reason
+        string if it doesn't.
+
+        This base implementation returns (True, '')
+        """
+        return (True, '')

Modified: gump/live/python/gump/core/update/svn.py
URL: http://svn.apache.org/viewvc/gump/live/python/gump/core/update/svn.py?rev=749185&r1=749184&r2=749185&view=diff
==============================================================================
--- gump/live/python/gump/core/update/svn.py (original)
+++ gump/live/python/gump/core/update/svn.py Mon Mar  2 05:00:11 2009
@@ -16,9 +16,77 @@
 # See the License for the specific language governing permissions and
 # limitations under the License.
 
+import re
+import StringIO
+
 from gump import log
-from gump.core.model.workspace import Cmd
-from gump.core.update.scmupdater import ScmUpdater
+from gump.core.update.scmupdater import match_workspace_template, ScmUpdater, \
+    should_be_quiet
+from gump.util.process.command import Cmd
+from gump.util.tools import catFile
+
+def getCommand(module, forUpdate):
+    """
+    Build the appropriate SVN command for checkout or update
+    """
+    repository = module.repository
+    url = module.getScm().getRootUrl()
+      
+    log.debug("SVN URL: [" + url + "] on Repository: "\
+                  + repository.getName())
+     
+    #
+    # Prepare SVN checkout/update command...
+    # 
+    cmd = Cmd('svn', 'update_'+module.getName(), 
+              module.getWorkspace().getSourceControlStagingDirectory())
+       
+    #
+    # Be 'quiet' (but not silent) unless requested otherwise.
+    #
+    if should_be_quiet(module):    
+        cmd.addParameter('--quiet')
+                  
+    if forUpdate:
+        cmd.addParameter('update')
+    else:
+        cmd.addParameter('checkout', url)
+       
+    #
+    # Request non-interactive
+    #
+    cmd.addParameter('--non-interactive')
+
+    # Optional username/password
+    if repository.hasUser():
+        cmd.addParameter('--username', repository.getUser())    
+    if repository.hasPassword():
+        cmd.addParameter('--password', repository.getPassword())
+            
+    #
+    # If module name != SVN directory, tell SVN to put it into
+    # a directory named after our module
+    #
+    if not module.getScm().hasDir() or \
+            not module.getScm().getDir() == module.getName():
+        cmd.addParameter(module.getName())
+        
+    return cmd
+
+URL_REGEX = re.compile('^URL:\s+(.*)\s*$', re.MULTILINE | re.UNICODE)
+
+def extract_URL(result):
+    """
+    Extracs the URL from 'svn info' output
+    """
+    stream = StringIO.StringIO()
+    catFile(stream, result.getOutput())
+    output = stream.getvalue()
+    stream.close()
+    match = URL_REGEX.search(output)
+    if not match:
+        return 'Couldn\'t find URL in svn info output ' + output
+    return match.group(1)
 
 ###############################################################################
 # Classes
@@ -37,58 +105,18 @@
         """
             Build the appropriate SVN command for checkout
         """
-        return self.getCommand(module, False)
+        return getCommand(module, False)
 
     def getUpdateCommand(self, module):
         """
             Build the appropriate SVN command for update
         """
-        return self.getCommand(module, True)
+        return getCommand(module, True)
 
-    def getCommand(self, module, forUpdate):
+    def workspaceMatchesModule(self, module):
         """
-            Build the appropriate SVN command for checkout or update
+            Run svn info to see whether the URL matches
         """
-        repository = module.repository
-        url = module.getScm().getRootUrl()
-      
-        log.debug("SVN URL: [" + url + "] on Repository: "\
-                      + repository.getName())
-     
-        #
-        # Prepare SVN checkout/update command...
-        # 
-        cmd = Cmd('svn', 'update_'+module.getName(), 
-                  module.getWorkspace().getSourceControlStagingDirectory())
-       
-        #
-        # Be 'quiet' (but not silent) unless requested otherwise.
-        #
-        if self.shouldBeQuiet(module):    
-            cmd.addParameter('--quiet')
-                  
-        if forUpdate:
-            cmd.addParameter('update')
-        else:
-            cmd.addParameter('checkout', url)
-       
-        #
-        # Request non-interactive
-        #
-        cmd.addParameter('--non-interactive')
-
-        # Optional username/password
-        if repository.hasUser():
-            cmd.addParameter('--username', repository.getUser())    
-        if repository.hasPassword():
-            cmd.addParameter('--password', repository.getPassword())
-            
-        #
-        # If module name != SVN directory, tell SVN to put it into
-        # a directory named after our module
-        #
-        if not module.getScm().hasDir() or \
-           not module.getScm().getDir() == module.getName():
-                cmd.addParameter(module.getName())
-        
-        return cmd
+        return match_workspace_template(module, 'svn info', extract_URL,
+                                        module.getScm().getRootUrl() \
+                                            .rstrip('/'))

Modified: gump/live/python/gump/core/update/updater.py
URL: http://svn.apache.org/viewvc/gump/live/python/gump/core/update/updater.py?rev=749185&r1=749184&r2=749185&view=diff
==============================================================================
--- gump/live/python/gump/core/update/updater.py (original)
+++ gump/live/python/gump/core/update/updater.py Mon Mar  2 05:00:11 2009
@@ -23,6 +23,8 @@
 import os.path
 
 from gump import log
+from gump.core.model.repository import SCM_TYPE_CVS, SCM_TYPE_GIT, \
+    SCM_TYPE_SVN, SCM_TYPE_P4
 from gump.core.model.workspace import catFileToFileHolder, \
     EXIT_CODE_FAILED, EXIT_CODE_SUCCESS, FILE_TYPE_LOG, \
     gumpSafeName, logResourceUtilization, \
@@ -95,8 +97,12 @@
     def __init__(self, run):
         RunSpecific.__init__(self, run)
         
-        self.updaters = {'cvs' : CvsUpdater(run), 'svn' : SvnUpdater(run),
-                         'p4' : P4Updater(run), 'git' : GitUpdater(run)}
+        self.updaters = {
+            SCM_TYPE_CVS : CvsUpdater(run),
+            SCM_TYPE_SVN : SvnUpdater(run),
+            SCM_TYPE_P4 : P4Updater(run),
+            SCM_TYPE_GIT : GitUpdater(run)
+            }
 
 
     #    ******************************************************************

Modified: gump/live/python/gump/test/model.py
URL: http://svn.apache.org/viewvc/gump/live/python/gump/test/model.py?rev=749185&r1=749184&r2=749185&view=diff
==============================================================================
--- gump/live/python/gump/test/model.py (original)
+++ gump/live/python/gump/test/model.py Mon Mar  2 05:00:11 2009
@@ -27,6 +27,7 @@
 
 from gump import log
 import gump.core.config
+from gump.core.model.repository import SCM_TYPE_CVS, SCM_TYPE_SVN
 from gump.core.model.state import *
 from gump.util import *
 from gump.test import getWorkedTestRun
@@ -167,7 +168,7 @@
         module2=self.module2
         
         self.assertTrue('Module has CVS',
-                        module1.getScm().getScmType() == 'cvs')
+                        module1.getScm().getScmType() == SCM_TYPE_CVS)
         self.assertNonZeroString('CVSROOT',module1.cvs.getCvsRoot())
         self.assertNonZeroString('Has Tag',module1.cvs.getTag())
         self.assertNonZeroString('Has Tag',module2.getTag())
@@ -176,7 +177,7 @@
         svnmodule1= self.workspace.getModule('svn_module1')
         
         self.assertTrue('Module has SVN',
-                        module1.getScm().getScmType() == 'svn')
+                        module1.getScm().getScmType() == SCM_TYPE_SVN)
         self.assertNonZeroString('SVN URL',svnmodule1.svn.getRootUrl())
         self.assertTrue('SVN Dir',svnmodule1.svn.hasDir())
     

Modified: gump/live/python/gump/util/process/command.py
URL: http://svn.apache.org/viewvc/gump/live/python/gump/util/process/command.py?rev=749185&r1=749184&r2=749185&view=diff
==============================================================================
--- gump/live/python/gump/util/process/command.py (original)
+++ gump/live/python/gump/util/process/command.py Mon Mar  2 05:00:11 2009
@@ -221,12 +221,12 @@
     def dump(self,indent=''):
         print self.overview(indent)
         
-def getCmdFromString(strcmd,name=None):
+def getCmdFromString(strcmd, name = None, cwd = None):
     """Extract a Cmd Object from a String"""
     parts = split(strcmd,' ')
     cmdcmd = parts[0]
     if not name: name = cmdcmd
-    cmd = Cmd(cmdcmd,name)
+    cmd = Cmd(cmdcmd, name, cwd)
     for i in range(1,len(parts)):
         if parts[i]:
             cmd.addParameterObject(getParameterFromString(parts[i]))



Mime
View raw message