Changeset 344


Ignore:
Timestamp:
22-05-08 21:48:59 (5 years ago)
Author:
thomas
Message:
  • moap/vcs/vcs.py: Add getPropertyChanges() to get paths that have changed properties.
  • moap/test/test_vcs_svn.py:
  • moap/vcs/svn.py: Implement it for svn.
  • moap/command/cl.py: Use it in moap cl prep so that we allow commenting on property changes. Fixes #286.
Location:
trunk
Files:
5 edited

Legend:

Unmodified
Added
Removed
  • trunk/ChangeLog

    r343 r344  
     12008-05-22  Thomas Vander Stichele  <thomas at apestaart dot org> 
     2 
     3        * moap/vcs/vcs.py: 
     4          Add getPropertyChanges() to get paths that have changed properties. 
     5        * moap/test/test_vcs_svn.py: 
     6        * moap/vcs/svn.py: 
     7          Implement it for svn. 
     8        * moap/command/cl.py: 
     9          Use it in moap cl prep so that we allow commenting on property 
     10          changes. 
     11          Fixes #286. 
     12 
    1132008-05-22  Thomas Vander Stichele  <thomas at apestaart dot org> 
    214 
  • trunk/moap/command/cl.py

    r320 r344  
    433433 
    434434    def do(self, args): 
     435        def filePathRelative(vcsPath, filePath): 
     436            # the paths are absolute because we asked for an absolute path 
     437            # diff strip them to be relative 
     438            if filePath.startswith(vcsPath): 
     439                filePath = filePath[len(vcsPath) + 1:] 
     440            return filePath 
     441 
     442        def writeLine(about): 
     443            line = "\t* %s:\n" % about 
     444            # wrap to maximum 72 characters, and keep tabs 
     445            lines = textwrap.wrap(line, 72, expand_tabs=False, 
     446                replace_whitespace=False, 
     447                subsequent_indent="\t  ") 
     448            os.write(fd, "\n".join(lines) + '\n') 
     449 
     450 
    435451        clPath = self.parentCommand.clPath 
    436452        if args: 
     
    454470        self.stdout.write('Finding changes.\n') 
    455471        changes = v.getChanges(vcsPath) 
     472        propertyChanges = v.getPropertyChanges(vcsPath) 
    456473 
    457474        # filter out the ChangeLog we're preparing 
     
    459476            del changes[os.path.abspath(clPath)] 
    460477 
    461         if not changes: 
     478        if not (changes or propertyChanges): 
    462479            self.stdout.write('No changes detected.\n') 
    463480            return 0 
    464481 
    465         files = changes.keys() 
    466         files.sort() 
    467  
    468         ct = ctags.CTags() 
    469         if self.options.ctags: 
    470             # run ctags only on files that aren't deleted 
    471             ctagsFiles = files[:] 
    472             for f in files: 
    473                 if not os.path.exists(f): 
    474                     ctagsFiles.remove(f) 
    475  
    476             # get the tags for all the files we're looking at 
    477             binary = None 
    478             for candidate in ["ctags", "exuberant-ctags", "ctags-exuberant"]: 
    479                 self.debug('Checking for existence of %s' % candidate) 
    480                 if os.system('which %s > /dev/null 2>&1' % candidate) == 0: 
    481                     self.debug('Checking for exuberance of %s' % candidate) 
    482                     output = commands.getoutput("%s --version" % candidate) 
    483                     if output.startswith("Exuberant"): 
    484                         binary = candidate 
    485                         break 
    486  
    487             if not binary: 
    488                 self.stderr.write('Warning: no exuberant ctags found.\n') 
    489                 from moap.util import deps 
    490                 deps.handleMissingDependency(deps.ctags()) 
    491                 self.stderr.write('\n') 
    492             else: 
    493                 self.stdout.write('Extracting affected tags from source.\n') 
    494                 command = "%s -u --fields=+nlS -f - %s" % ( 
    495                     binary, " ".join(ctagsFiles)) 
    496                 self.debug('Running command %s' % command) 
    497                 output = commands.getoutput(command) 
    498                 ct.addString(output) 
     482        if changes: 
     483            files = changes.keys() 
     484            files.sort() 
     485 
     486            ct = ctags.CTags() 
     487            if self.options.ctags: 
     488                # run ctags only on files that aren't deleted 
     489                ctagsFiles = files[:] 
     490                for f in files: 
     491                    if not os.path.exists(f): 
     492                        ctagsFiles.remove(f) 
     493 
     494                # get the tags for all the files we're looking at 
     495                binary = None 
     496                for candidate in ["ctags", "exuberant-ctags", "ctags-exuberant"]: 
     497                    self.debug('Checking for existence of %s' % candidate) 
     498                    if os.system('which %s > /dev/null 2>&1' % candidate) == 0: 
     499                        self.debug('Checking for exuberance of %s' % candidate) 
     500                        output = commands.getoutput("%s --version" % candidate) 
     501                        if output.startswith("Exuberant"): 
     502                            binary = candidate 
     503                            break 
     504 
     505                if not binary: 
     506                    self.stderr.write('Warning: no exuberant ctags found.\n') 
     507                    from moap.util import deps 
     508                    deps.handleMissingDependency(deps.ctags()) 
     509                    self.stderr.write('\n') 
     510                else: 
     511                    self.stdout.write('Extracting affected tags from source.\n') 
     512                    command = "%s -u --fields=+nlS -f - %s" % ( 
     513                        binary, " ".join(ctagsFiles)) 
     514                    self.debug('Running command %s' % command) 
     515                    output = commands.getoutput(command) 
     516                    ct.addString(output) 
    499517 
    500518        # prepare header for entry 
     
    523541        os.write(fd, "\n") 
    524542 
    525         for filePath in files: 
    526             lines = changes[filePath] 
    527             tags = [] 
    528             for oldLine, oldCount, newLine, newCount in lines: 
    529                 self.log("Looking in file %s, newLine %r, newCount %r" % ( 
    530                     filePath, newLine, newCount)) 
    531                 try: 
    532                     for t in ct.getTags(filePath, newLine, newCount): 
    533                         # we want unique tags, not several hits for one 
    534                         if not t in tags: 
    535                             tags.append(t) 
    536                 except KeyError: 
    537                     pass 
    538  
    539             # the paths are absolute because we asked for an absolute path diff 
    540             # strip them to be relative 
    541             if filePath.startswith(vcsPath): 
    542                 filePath = filePath[len(vcsPath) + 1:] 
    543             tagPart = "" 
    544             if tags: 
    545                 parts = [] 
    546                 for tag in tags: 
    547                     if tag.klazz: 
    548                         parts.append('%s.%s' % (tag.klazz, tag.name)) 
    549                     else: 
    550                         parts.append(tag.name) 
    551                 tagPart = " (" + ", ".join(parts) + ")" 
    552             line =  "\t* %s%s:\n" % (filePath, tagPart) 
    553             # wrap to maximum 72 characters, and keep tabs 
    554             lines = textwrap.wrap(line, 72, expand_tabs=False, 
    555                 replace_whitespace=False, 
    556                 subsequent_indent="\t  ") 
    557             os.write(fd, "\n".join(lines) + '\n') 
     543        if changes: 
     544            for filePath in files: 
     545                lines = changes[filePath] 
     546                tags = [] 
     547                for oldLine, oldCount, newLine, newCount in lines: 
     548                    self.log("Looking in file %s, newLine %r, newCount %r" % ( 
     549                        filePath, newLine, newCount)) 
     550                    try: 
     551                        for t in ct.getTags(filePath, newLine, newCount): 
     552                            # we want unique tags, not several hits for one 
     553                            if not t in tags: 
     554                                tags.append(t) 
     555                    except KeyError: 
     556                        pass 
     557 
     558                filePath = filePathRelative(vcsPath, filePath) 
     559                tagPart = "" 
     560                if tags: 
     561                    parts = [] 
     562                    for tag in tags: 
     563                        if tag.klazz: 
     564                            parts.append('%s.%s' % (tag.klazz, tag.name)) 
     565                        else: 
     566                            parts.append(tag.name) 
     567                    tagPart = " (" + ", ".join(parts) + ")" 
     568                writeLine(filePath + tagPart) 
     569 
     570        if propertyChanges: 
     571            for filePath in propertyChanges: 
     572                filePath = filePathRelative(vcsPath, filePath) 
     573                writeLine("%s (property)" % filePath) 
    558574 
    559575        os.write(fd, "\n") 
  • trunk/moap/test/test_vcs_svn.py

    r333 r344  
    179179            (1, 1, 1, 1), 
    180180        ]) 
     181 
     182class TestChangeProperties(SVNTestCase): 
     183 
     184    def testGetPropertyChanges(self): 
     185        v = svn.VCSClass(self.livedir)  
     186        self.failUnless(v) 
     187 
     188        # create a file 
     189        path = self.liveWriteFile('test', "test\n") 
     190        path2 = self.liveWriteFile('test2', "test\n") 
     191 
     192        # add it 
     193        os.system('svn add %s' % path) 
     194        os.system('svn add %s' % path2) 
     195        os.system('svn commit -m "test" %s' % self.livedir) 
     196         
     197        # change property on it 
     198        os.system('svn ps property value %s' % path) 
     199        os.system('svn ps property value %s' % path2) 
     200 
     201        # now get changes 
     202        c = v.getPropertyChanges(self.livedir) 
     203        self.assertEquals(c, [path, path2]) 
  • trunk/moap/vcs/svn.py

    r333 r344  
    125125        return reo.sub('', output) 
    126126 
     127    def getPropertyChanges(self, path): 
     128        ret = [] 
     129 
     130        cmd = "LANG=C svn diff %s" % path 
     131        output = commands.getoutput(cmd) 
     132        reo = re.compile('^Property changes on: (.*)$') 
     133        for line in output.split('\n'): 
     134            matcher = reo.match(line) 
     135            if matcher: 
     136                ret.append(matcher.expand('\\1')) 
     137 
     138        return ret 
     139 
    127140    def update(self, path): 
    128141        cmd = "svn update %s" % path 
  • trunk/moap/vcs/vcs.py

    • Property property set to property
    r343 r344  
    242242        return changes 
    243243 
     244    def getPropertyChanges(self, path): 
     245        """ 
     246        Get a list of property changes for the given path and subpaths. 
     247        These are metadata changes to files, not content changes. 
     248 
     249        @returns: list of path 
     250        """ 
     251        log.info('vcs',  
     252            "subclass %r should implement getPropertyChanges" % self.__class__) 
     253  
    244254    def update(self, path): 
    245255        """ 
Note: See TracChangeset for help on using the changeset viewer.