source: tracdarcs/tracdarcs/command.py @ 107

Revision 107, 4.4 KB checked in by lele@…, 5 years ago (diff)

Renewed the copyright on all the sources

Line 
1# -*- coding: iso-8859-1 -*-
2#
3# Copyright (C) 2005 Edgewall Software
4# Copyright (C) 2006 K.S.Sreeram <sreeram@tachyontech.net>
5# Copyright (C) 2007,2008 Lele Gaifax <lele@metapensiero.it>
6#
7# This software is licensed as described in the file COPYING, which
8# you should have received as part of this distribution. The terms
9# are also available at http://trac.edgewall.com/license.html.
10#
11# This software consists of voluntary contributions made by many
12# individuals. For the exact contribution history, see the revision
13# history and logs, available at http://projects.edgewall.com/trac/.
14#
15# Author: K.S.Sreeram <sreeram@tachyontech.net>
16
17import sys, os, StringIO
18from trac.util import TracError, NaivePopen
19import ann2ascii
20
21class DarcsCommand(object):
22    '''
23    A simple wrapper around the 'darcs' command.
24    '''
25    def __init__(self, darcs_bin, repo_dir, log=None):
26        self.darcs_bin = darcs_bin
27        self.repo_dir = repo_dir
28        self.log = log
29        self.darcs_version = self._run('--version').strip()
30        if self.log:
31            self.log.info('Using %s, version %s',
32                          self.darcs_bin, self.darcs_version)
33
34    def _run(self, command, input=None):
35        ''' Run the darcs command 'command', and return the output'''
36        if sys.platform == 'win32':
37            command = 'cd %s & set TZ=UTC & %s %s' % (self.repo_dir,
38                                                      self.darcs_bin,
39                                                      command)
40        else:
41            command = 'cd %s; TZ=UTC %s %s' % (self.repo_dir,
42                                               self.darcs_bin,
43                                               command)
44        if self.log:
45            self.log.debug(command)
46        np = NaivePopen(command, input=input, capturestderr=True)
47        if np.errorlevel:
48            err = 'Running (%s) failed: %s, %s: %s' % (command,
49                    np.errorlevel,np.err,np.out)
50            raise TracError(err, title='Darcs execution failed')
51        return np.out
52
53    def changes(self, from_hash=None):
54        '''
55        Returns all changes since patch 'from_hash'. If 'from_hash'
56        is None, then all changes are returned. The changes are
57        ordered from oldest to latest.
58        '''
59        cmd = 'changes --xml-output --reverse --summary'
60        if from_hash is not None:
61            cmd += ' --from-match "hash %s"' % from_hash
62        return self._run(cmd)
63
64    def annotate(self, hash, path):
65        '''
66        This is used to feed ann2ascii.py to get the contents of
67        file 'path', as of patch 'hash'.
68        '''
69        cmd = 'annotate --xml-output --match "hash %s" %s'
70        cmd = cmd % (hash,path)
71        return self._run(cmd)
72
73    def simulate_cat(self, hash, path, cat_cmd):
74        # This is an ugly hack to simulate 'darcs query contents' on darcs 1.0.
75        # We basically do a 'darcs diff' giving 'cat %2'
76        # as the diff command!!
77        # When using --diff-command, darcs prints:
78        #  Running command <blah blah>...
79        #  Hit return to move on...
80        # So we need to pass a dummy '\n' as input to the command
81        # and remove the prompt messages from the output.
82        cmd = 'diff --diff-command "%s %%2"' % cat_cmd
83        cmd += ' --to-match "hash %s" "%s"' % (hash,path)
84        data = self._run(cmd, input='\n')
85        # Remove cruft added by darcs...
86        marker = 'Hit return to move on...'
87        pos = data.find(marker)
88        data = data[pos+len(marker):]
89        # Remove extra newline at the end
90        if data.endswith('\r\n'):
91            data = data[:-2]
92        elif data.endswith('\n'):
93            data = data[:-1]
94        return data
95
96    def cat(self, hash, path):
97        if self.darcs_version >= '2.0':
98            return self._run('query contents --quiet --match "hash %s" "%s"' %
99                             (hash, path))
100        elif sys.platform == 'win32':
101            # see if cygwin's cat is available
102            # if yes then use 'simulate_cat'
103            # else use annotate
104            cygwin_cat = r'c:\cygwin\bin\cat.exe'
105            if os.path.isfile(cygwin_cat):
106                return self.simulate_cat(hash, path, cat_cmd=cygwin_cat)
107            annotate = self.annotate(hash, self.path)
108            ann = ann2ascii.parse_annotate(StringIO.StringIO(annotate))
109            out = StringIO.StringIO()
110            ann.write(out)
111            return out.getvalue()
112        else:
113            return self.simulate_cat(hash, path, cat_cmd='cat')
Note: See TracBrowser for help on using the repository browser.