ajack       2004/05/15 11:02:31

  Modified:    python/gump/model project.py
               python/gump/utils tools.py __init__.py sync.py
               python/gump/test utils.py
               python/gump/core engine.py
  Log:
  Capture 'sync log' (what dirs/files changes)

  

  NOTE: Use this (not CVS|SVN command stdout/stderr output) to detect 'updated'.

  

  Later might add 'diff'
  
  Revision  Changes    Path
  1.82      +3 -0      gump/python/gump/model/project.py
  
  Index: project.py
  ===================================================================
  RCS file: /home/cvs/gump/python/gump/model/project.py,v
  retrieving revision 1.81
  retrieving revision 1.82
  diff -u -r1.81 -r1.82
  --- project.py        5 May 2004 17:41:33 -0000       1.81
  +++ project.py        15 May 2004 18:02:31 -0000      1.82
  @@ -338,6 +338,9 @@
       def setHonoraryPackage(self,honorary):
           self.honoraryPackage=honorary
       
  +    def isGumped(self):
  +        return (not self.isPackaged()) and self.hasBuildCommand()
  +        
       # provide elements when not defined in xml
       def complete(self,workspace):
           if self.isComplete(): return
  
  
  
  1.25      +21 -9     gump/python/gump/utils/tools.py
  
  Index: tools.py
  ===================================================================
  RCS file: /home/cvs/gump/python/gump/utils/tools.py,v
  retrieving revision 1.24
  retrieving revision 1.25
  diff -u -r1.24 -r1.25
  --- tools.py  4 May 2004 15:12:52 -0000       1.24
  +++ tools.py  15 May 2004 18:02:31 -0000      1.25
  @@ -148,21 +148,33 @@
       return reference.exists() and reference.isNotDirectory()
   
      
  -def copyDirectories(sourcedir,destdir,annotatable=None):   
  +def copyDirectories(sourcedir,destdir,annotatable=None,output=None):   
  +    """    
  +        Copy any changed files, report if work done        
  +    """
  +    changes=0
       try:
  -        copy=Copy(sourcedir,destdir)        
  -        copy.execute()    
  +        copy=Copy(sourcedir,destdir,output)        
  +        changes=copy.execute()    
       finally:
           if annotatable:
  -            transferAnnotations(copy, annotatable)        
  -    
  -def syncDirectories(sourcedir,destdir,annotatable=None):                
  +            transferAnnotations(copy, annotatable)     
  +                      
  +    return changes
  +       
  +def syncDirectories(sourcedir,destdir,annotatable=None,output=None):                
  +    """
  +        Sync two directories, report if difference
  +        [and hence changes] occured.
  +    """
  +    changes=0
       try:
  -        sync=Sync(sourcedir,destdir)        
  -        sync.execute()    
  +        sync=Sync(sourcedir,destdir,output)        
  +        changes=sync.execute()    
       finally:
           if annotatable:
  -            transferAnnotations(sync, annotatable)    
  +            transferAnnotations(sync, annotatable)                
  +    return changes
               
   def wipeDirectoryTree(dir):
       log.info('Wipe Directory [' + `dir` + ']') 
  
  
  
  1.40      +12 -4     gump/python/gump/utils/__init__.py
  
  Index: __init__.py
  ===================================================================
  RCS file: /home/cvs/gump/python/gump/utils/__init__.py,v
  retrieving revision 1.39
  retrieving revision 1.40
  diff -u -r1.39 -r1.40
  --- __init__.py       5 May 2004 17:41:33 -0000       1.39
  +++ __init__.py       15 May 2004 18:02:31 -0000      1.40
  @@ -293,16 +293,24 @@
           increment=wrapLen
           totalLen=len(line)                         
           while increment > 0:
  -            wrappedLine+=line[startPosn:endPosn]
  -            if totalLen - endPosn > wrapLen:
  +            #print `startPosn` + " : " + `endPosn` + " : (" + `totalLen` + ') : ' + 
`increment`
  +            
  +            # Add the piece
  +            wrappedLine+=line[startPosn:endPosn+1]
  +            
  +            # We have more wrappign to do
  +            if (totalLen - endPosn) > wrapLen:
                   increment=wrapLen
               else:
                   increment=(totalLen - endPosn)
  +                
  +            # We aren't at end
               if increment:
                   wrappedLine+=eol+marker
  -            startPosn+=increment
  +                
  +            startPosn=endPosn+1
               endPosn+=increment
  -            # print `startPosn` + " : " + `endPosn` + " : " + `totalLen` + ' : ' + 
`increment`
  +            #print `startPosn` + " : " + `endPosn` + " : (" + `totalLen` + ') : ' + 
`increment`
       else:
           wrappedLine=line
               
  
  
  
  1.13      +97 -60    gump/python/gump/utils/sync.py
  
  Index: sync.py
  ===================================================================
  RCS file: /home/cvs/gump/python/gump/utils/sync.py,v
  retrieving revision 1.12
  retrieving revision 1.13
  diff -u -r1.12 -r1.13
  --- sync.py   5 May 2004 17:41:33 -0000       1.12
  +++ sync.py   15 May 2004 18:02:31 -0000      1.13
  @@ -35,42 +35,78 @@
   DIFF_ACTION=3
   
   class PathWalker(Annotatable):
  -    """
  -    this class can be used to sync two directories
  -    x = Sync(sourcedir, targetdir) # construct
  -    x.execute() #run
  -    if targetdir does not exist, it will be created
  -    if sourcedir does not exist, the class will raise an IOError
  -    the class can be also used to copy from one directory to another
  -    x = Sync(sourcedir, targetdir, )
  -    """
  -    def __init__(self, sourcedir, targetdir, action = SYNC_ACTION, debug=0):
  +
  +    def __init__(self, sourcedir, targetdir, action = SYNC_ACTION, output=None, 
debug=0):
           Annotatable.__init__(self)
           self.sourcedir = sourcedir
           self.targetdir = targetdir
           self.action = action
           self.debug=debug
           
  +        # A place to 'log' actions        
  +        self.output=output
  +        self.outputStream=None
  +        
  +        # Notice that actions occured        
  +        self.actionsOccured=0
  +        
       def execute(self):
           log.debug('Starting %s from [%s]' % (self.action,self.sourcedir))
           log.debug('          target dir [' + self.targetdir + ']')
  -        if not os.path.exists(self.sourcedir):
  -            log.error('Exiting sync, source directory does not exist [' + 
self.sourcedir + ']')
  -            raise IOError, 'source directory does not exist [' + self.sourcedir + 
']'
  +        
  +        # Allow user to pass an open stream, or a filename
  +        # In later case control open/close.
  +        doClose=0
  +        if self.output:
  +            if isinstance(self.output,types.StringTypes):
  +                doClose=1
  +                self.outputStream=open(self.output,'w')
  +            else:
  +                self.outputStream=self.output
  +                
  +        try:
  +            
  +            if not os.path.exists(self.sourcedir):
  +                log.error('Exiting sync, source directory does not exist [' + 
self.sourcedir + ']')
  +                raise IOError, 'source directory does not exist [' + self.sourcedir 
+ ']'
   
  -        if not os.path.isdir(self.sourcedir):
  -            log.error('Exiting sync, source is not a directory [' + self.sourcedir 
+ ']')
  -            raise IOError, 'source is not a directory [' + self.sourcedir + ']'
  +            if not os.path.isdir(self.sourcedir):
  +                log.error('Exiting sync, source is not a directory [' + 
self.sourcedir + ']')
  +                raise IOError, 'source is not a directory [' + self.sourcedir + ']'
   
  -        if not os.path.exists(self.targetdir):
  -            try:
  -                os.makedirs(self.targetdir)
  -            except Exception, details:
  -                log.exception('failed on ' + str(details))
  -                raise IOError, 'could not create directory [' + self.targetdir + ']'
  +            if not os.path.exists(self.targetdir):
  +                try:
  +                    os.makedirs(self.targetdir)
  +                except Exception, details:
  +                    log.exception('failed on ' + str(details))
  +                    raise IOError, 'could not create directory [' + self.targetdir 
+ ']'
  +                
  +            self.copytree(self.sourcedir, self.targetdir, 1)   
  +             
  +        finally:
  +            if doClose and self.outputStream:
  +                #
  +                # We opened it, we close it...
  +                #
  +                self.outputStream.close()
                   
  -        self.copytree(self.sourcedir, self.targetdir, 1)    
  +                #
  +                # Clean Up Empty Output Files
  +                #
  +                if os.path.exists(self.output):
  +                    if not os.path.getsize(self.output) > 0:
  +                        try:
  +                            os.remove(self.output)
  +                        except: pass
  +                
  +        return self.actionsOccured
           
  +    def outputAction(self,type,file,reason=''):
  +        self.actionsOccured=1
  +        if self.outputStream:
  +            reasonSep=''
  +            if reason: reasonSep=' - '
  +            self.outputStream.write('%s : %s%s%s\n' % ( type , str(file), 
reasonSep, reasonString ))
           
       def isCopy(self): return (COPY_ACTION == self.action)
       def isSync(self): return (SYNC_ACTION == self.action)
  @@ -101,6 +137,7 @@
           # handle case where destinationStat exists but is not a directory    
           #
           if destinationStat and not S_ISDIR(destinationStat[ST_MODE]):
  +            self.outputAction(' -F ', dst, 'Need a directory here, not a file.')    
    
               os.remove(dst)
               destinationStat = None
            
  @@ -108,7 +145,8 @@
           # Generate the target location (even if it means making
           # a path of directories.)
           #   
  -        if not destinationStat:    
  +        if not destinationStat:     
  +            self.outputAction(' +D ', dst)    
               os.makedirs(dst)
               
           if destinationStat:
  @@ -158,21 +196,23 @@
                   destinationStat = os.stat(tobedeleted)
                   if S_ISDIR(destinationStat[ST_MODE]):
                       if self.isDebug(): log.debug('Attempting to remove directory 
[%s]' % (`tobedeleted`))
  +                    self.outputAction(' -D ', tobedeleted)    
                       shutil.rmtree(tobedeleted)
                   else:    
  -                    if self.isDebug(): log.debug('Attempting to remove file [%s]' % 
(`tobedeleted`))
  +                    if self.isDebug(): log.debug('Attempting to remove file [%s]' % 
(`tobedeleted`))   
  +                    self.outputAction(' -F ', tobedeleted)    
                       os.remove(tobedeleted)
                       
       def removenonmatching(self, sourcedir, destdir, acceptablefiles, existingfiles):
           """
  -        this routine will remove from destination
  -        the entries which are files at destination and directory at source
  -        the entries which are directory at destination and files at source
  -        leaves untouched entries which exist both at source and at destination
  -        sourcedir = directory from which the copy is taking place
  -        destdir = directory where the epuration is to take place 
  -        acceptablefiles = array of filenames of files which are accepted at 
destination
  -        existingfiles = array of filenames which exist at destination               
                      
  +            this routine will remove from destination
  +            the entries which are files at destination and directory at source
  +            the entries which are directory at destination and files at source
  +            leaves untouched entries which exist both at source and at destination
  +            sourcedir = directory from which the copy is taking place
  +            destdir = directory where the epuration is to take place 
  +            acceptablefiles = array of filenames of files which are accepted at 
destination
  +            existingfiles = array of filenames which exist at destination           
                          
           """
           removed = []
           for afile in existingfiles:
  @@ -187,11 +227,13 @@
                           log.debug('Removing file [%s] to be replaced by directory' 
                                   %(`fulldestfile`))
                       os.remove(fulldestfile)
  +                    self.outputAction(' -F ', fulldestfile, 'Need a directory.')
                       removed.append(afile)
                   elif os.path.isfile(fullsourcefile) and 
os.path.isdir(fulldestfile):              
                       if self.isDebug(): 
                           log.debug('Removing directory [%s] to be replaced by file' 
                                   %(`fulldestfile`))
  +                    self.outputAction(' -D ', fulldestfile, 'Need a file.')
                       shutil.rmtree(fulldestfile)
                       removed.append(afile)
                       
  @@ -201,10 +243,10 @@
                   
       def maybecopy(self, srcname, dstname):
           """
  -        copy a file from srcname to dstname if 
  -        dstname does not exist
  -        or srcname and dstname have different dates
  -        or srcname and dstname have different sizes
  +            copy a file from srcname to dstname if 
  +            dstname does not exist
  +            or srcname and dstname have different dates
  +            or srcname and dstname have different sizes
           """
           sourceStat = os.stat(srcname)
           try:
  @@ -212,54 +254,49 @@
           except:
               destinationStat = None
               
  +        reason=''
           # Determine if copy is appropriate.
           performCopy = 0
           if not destinationStat:
               performCopy = 1
  +            reason='Did not exist.'
           elif S_ISDIR(destinationStat[ST_MODE]):
  +            self.outputAction(' -D ', dstname, 'Need a file.')    
               shutil.rmtree(dstname)
               performCopy = 1
           elif sourceStat[ST_SIZE] != destinationStat[ST_SIZE]:
               performCopy = 1
  +            reason='Size difference.'
           elif sourceStat[ST_MTIME] != destinationStat[ST_MTIME]:
               performCopy = 1
  +            reason='Stat difference.'
               
           if performCopy:
               if self.isDebug(): log.debug("Attempting copy from [%s] to [%s]" 
%(`srcname`, `dstname`))    
  +            self.outputAction(' U> ', dstname, reason)    
               shutil.copy2(srcname, dstname)    
           #else:
           #    log.debug("Do not copy from [%s:%s] to [%s:%s]" \
           #                %(`srcname`, `sourceStat`, `dstname`,`destinationStat`))
           #        
   
  -
  -
   class Copy(PathWalker):
       """
       A Sync without the epurate
       """
  -    def __init__(self, sourcedir, targetdir):
  -        PathWalker.__init__(self, sourcedir, targetdir, COPY_ACTION)
  -                    
  +    def __init__(self, sourcedir, targetdir, output=None, debug=0):
  +        PathWalker.__init__(self, sourcedir, targetdir, COPY_ACTION, output, debug)
                       
   class Sync(PathWalker):
       """
  -    A Sync
  +        This class can be used to sync two directories
  +            x = Sync(sourcedir, targetdir) # construct
  +            x.execute() #run
  +            if targetdir does not exist, it will be created
  +            if sourcedir does not exist, the class will raise an IOError
  +            the class can be also used to copy from one directory to another
  +        x = Sync(sourcedir, targetdir, )
       """
  -    def __init__(self, sourcedir, targetdir):
  -        PathWalker.__init__(self, sourcedir, targetdir, SYNC_ACTION)
  -                    
  -                    
  -#class Diff(Sync,FileHolder):
  -#    """
  -#    A difference analysis tool
  -#    
  -#     :TODO: Write it...
  -#     
  -#    """
  -#    def __init__(self, sourcedir, targetdir):
  -#        PathWalker.__init__(self, sourcedir, targetdir, DIFF_ACTION)
  -#        FileHolder.__init__(self)
  -#     
  -#        raise IOError, 'this does not work yet ...'
  -                
  \ No newline at end of file
  +    def __init__(self, sourcedir, targetdir, output=None, debug=0):
  +        PathWalker.__init__(self, sourcedir, targetdir, SYNC_ACTION, output, debug)
  +        
  \ No newline at end of file
  
  
  
  1.10      +24 -3     gump/python/gump/test/utils.py
  
  Index: utils.py
  ===================================================================
  RCS file: /home/cvs/gump/python/gump/test/utils.py,v
  retrieving revision 1.9
  retrieving revision 1.10
  diff -u -r1.9 -r1.10
  --- utils.py  5 May 2004 12:59:38 -0000       1.9
  +++ utils.py  15 May 2004 18:02:31 -0000      1.10
  @@ -95,10 +95,31 @@
           #print params.formatCommandLine()
           
       def testWrap(self):
  -        
line='xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx'
  -        #print wrapLine(line)
  +        
  +        eol='\n'
  +        wrapper='[WRAPPED]'
  +        
  +        totalWrapperLen=len(eol)+len(wrapper)
  +        
  +        line='xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx'
  +        wrapped=wrapLine(line,100,eol,wrapper)
  +        #print wrapped
  +        self.assertNotSubstring('Ought NOT be wrapped', wrapper, wrapped)
  +        self.assertEqual('Ought be wrapped once', len(line), len(wrapped))
  +        
  +        
  +        
line='xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx'
  +        wrapped=wrapLine(line,100,eol,wrapper)
  +        #print wrapped
  +        self.assertInString('Ought be wrapped', wrapper, wrapped)
  +        self.assertEqual('Ought be wrapped once', len(line)+totalWrapperLen, 
len(wrapped))
  +        
  +        
           
line='1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890'
  -        #print wrapLine(line)
  +        wrapped=wrapLine(line,100,eol,wrapper)
  +        #print wrapped
  +        self.assertInString('Ought be wrapped', wrapper, wrapped)
  +        self.assertEqual('Ought be wrapped twice', len(line)+(2*totalWrapperLen), 
len(wrapped))
           
       def testBeanAttributes(self):
           attrs=getBeanAttributes(TestBean())
  
  
  
  1.15      +31 -19    gump/python/gump/core/engine.py
  
  Index: engine.py
  ===================================================================
  RCS file: /home/cvs/gump/python/gump/core/engine.py,v
  retrieving revision 1.14
  retrieving revision 1.15
  diff -u -r1.14 -r1.15
  --- engine.py 12 May 2004 21:22:58 -0000      1.14
  +++ engine.py 15 May 2004 18:02:31 -0000      1.15
  @@ -263,8 +263,14 @@
         
                   work=CommandWorkItem(WORK_TYPE_UPDATE,cmd,cmdResult)
       
  +                #
                   # Update Contexts                  
  +                #
                   module.performedWork(work)  
  +                
  +                #
  +                # Might as well keep context here also.
  +                #
                   repository.performedWork(work.clone())
         
                   # Update Context w/ Results  
  @@ -283,13 +289,7 @@
                           # Kinda bogus, but better than nowt (for now)
                           module.changeState(STATE_SUCCESS,REASON_UPDATE_FAILED)
                   else:
  -                    module.changeState(STATE_SUCCESS)
  -                    
  -                    if cmdResult.hasOutput():                    
  -                        # Were the contents of the repository modified?             
                           
  -                        module.setUpdated(1)                        
  -                        log.info('Update(s) received via CVS/SVN/Jars on #[' + 
`moduleNo` + \
  -                                '] of [' + `moduleCount` + ']: ' + module.getName())
  +                    module.changeState(STATE_SUCCESS)                               
                            
       
           
               #
  @@ -304,8 +304,26 @@
                   
                   # Perform the sync...
                   try:
  -                    syncDirectories(sourcedir,destdir,module)
  +                    # Store changes next to updates log
  +                    changesFile = os.path.abspath(   \
  +                                    os.path.join(    \
  +                                        workspace.tmpdir,    \
  +                                        
'changes_to_'+gumpSafeName(module.getName())+'.txt'))
  +                    
  +                    modified=syncDirectories(sourcedir,destdir,module)
  +                    
  +                    # We are good to go...
                       module.changeState(STATE_SUCCESS)
  +                    
  +                    # Were the contents of the repository modified?                 
                       
  +                    if modified:
  +                        module.setUpdated(1)                        
  +                        log.info('Update(s) received via CVS/SVN/Jars on #[' + 
`moduleNo` + \
  +                                '] of [' + `moduleCount` + ']: ' + module.getName())
  +                                
  +                        # Log of changes...
  +                        if os.path.exists(changesFile):                             
  
  +                            catFileToFileHolder(module, changesFile, FILE_TYPE_LOG) 
                   except:
                       module.changeState(STATE_FAILED,REASON_SYNC_FAILED)
                       
  @@ -676,30 +694,24 @@
               for report in project.getReports():
                   reportDir=report.getResolvedPath() 
                   project.addInfo('Project Reports in: ' + reportDir)
  -                catDirectoryContentsToFileHolder(project,reportDir,FILE_TYPE_OUTPUT)
  +                catDirectoryContentsToFileHolder(project, reportDir, 
FILE_TYPE_OUTPUT)
       
           # Maven generates a maven.log...
           if project.hasMaven() and not project.isPackaged():
               pomFile=project.locateMavenProjectFile() 
               if os.path.exists(pomFile):                               
                   project.addDebug('Maven POM in: ' + pomFile) 
  -                catFileToFileHolder(project,pomFile, \
  -                        FILE_TYPE_CONFIG,    \
  -                        os.path.basename(pomFile)) 
  +                catFileToFileHolder(project, pomFile, FILE_TYPE_CONFIG) 
                       
               projpFile=project.locateMavenProjectPropertiesFile() 
               if os.path.exists(projpFile):                                           
     
                   project.addDebug('Maven project properties in: ' + projpFile)       
         
  -                catFileToFileHolder(project,pomFile, \
  -                        FILE_TYPE_CONFIG,    \
  -                        os.path.basename(projpFile)) 
  +                catFileToFileHolder(project, pomFile, FILE_TYPE_CONFIG) 
               
               logFile=project.locateMavenLog()                                
               if os.path.exists(logFile):
                   project.addDebug('Maven Log in: ' + logFile)                
  -                catFileToFileHolder(project,logFile, \
  -                        FILE_TYPE_LOG,       \
  -                        os.path.basename(logFile))
  +                catFileToFileHolder(project, logFile, FILE_TYPE_LOG)
               
                           
       def performProjectPackageProcessing(self, run, project, stats):
  @@ -813,7 +825,7 @@
       
           ******************************************************************
           
  -            THE DOCUMENATION INTERFACE
  +            THE DOCUMENTATION INTERFACE
           
           ******************************************************************
       
  
  
  

---------------------------------------------------------------------
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]

Reply via email to