~abentley/bzrtools/bzrtools.dev

« back to all changes in this revision

Viewing changes to diffstat.py

  • Committer: Michael Ellerman
  • Date: 2005-11-29 07:12:26 UTC
  • mto: (0.3.1 shelf-dev) (325.1.2 bzrtools)
  • mto: This revision was merged to the branch mainline in revision 334.
  • Revision ID: michael@ellerman.id.au-20051129071226-a04b3f827880025d
Unshelve --pick was broken, because we deleted the whole patch, even when only
part of it was unshelved. So now if we unshelve part of a patch, the patch is
replaced with a new patch that has just the unshelved parts. That's a long way
of saying it does what you'd expect.

Implementing this required changing HunkSelector to return both the selected,
and unselected hunks (ie. patches to shelve, and patches to keep).

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
#!/usr/bin/python
 
2
 
 
3
class DiffStat(object):
 
4
    def __init__(self, lines):
 
5
        self.maxname = 0
 
6
        self.maxtotal = 0
 
7
        self.total_adds = 0
 
8
        self.total_removes = 0
 
9
        self.stats = {}
 
10
        self.__parse(lines)
 
11
 
 
12
    def __parse(self, lines):
 
13
        import string
 
14
        adds = 0
 
15
        removes = 0
 
16
        current = None
 
17
 
 
18
        for line in lines:
 
19
            if line.startswith('+') and not line.startswith('+++'):
 
20
                adds += 1
 
21
            elif line.startswith('-') and not line.startswith('---'):
 
22
                removes += 1
 
23
            elif line.startswith('=== '):
 
24
                self.__add_stats(current, adds, removes)
 
25
 
 
26
                adds = 0
 
27
                removes = 0
 
28
                context = 0
 
29
                current = None
 
30
            elif line.startswith('--- ') and current is None:
 
31
                current = line[4:].strip()
 
32
 
 
33
        self.__add_stats(current, adds, removes)
 
34
 
 
35
    class Filestat:
 
36
        def __init__(self):
 
37
            self.adds = 0
 
38
            self.removes = 0
 
39
            self.total = 0
 
40
 
 
41
    def __add_stats(self, file, adds, removes):
 
42
        if file is None:
 
43
            return
 
44
        elif file in self.stats:
 
45
            fstat = self.stats[file]
 
46
        else:
 
47
            fstat = self.Filestat()
 
48
 
 
49
        fstat.adds += adds
 
50
        fstat.removes += removes
 
51
        fstat.total = adds + removes
 
52
        self.stats[file] = fstat
 
53
 
 
54
        self.maxname = max(self.maxname, len(file))
 
55
        self.maxtotal = max(self.maxtotal, fstat.total)
 
56
        self.total_adds += adds
 
57
        self.total_removes += removes
 
58
 
 
59
    def __str__(self):
 
60
        # Work out widths
 
61
        width = 78 - 5
 
62
        countwidth = len(str(self.maxtotal))
 
63
        graphwidth = width - countwidth - self.maxname
 
64
        factor = 1
 
65
 
 
66
        while (self.maxtotal / factor) > graphwidth:
 
67
            factor += 1
 
68
 
 
69
        s = ""
 
70
 
 
71
        for file, fstat in self.stats.iteritems():
 
72
            s += ' %-*s | %*.d ' % (self.maxname, file, countwidth, fstat.total)
 
73
 
 
74
            # If diffstat runs out of room it doesn't print anything, which
 
75
            # isn't very useful, so always print at least one + or 1
 
76
            s += '+' * max(fstat.adds / factor, 1)
 
77
            s += '-' * max(fstat.removes / factor, 1)
 
78
            s += '\n'
 
79
 
 
80
        s += ' %d files changes, %d insertions(+), %d deletions(-)' % \
 
81
                (len(self.stats), self.total_adds, self.total_removes)
 
82
        return s
 
83
 
 
84
if __name__ == '__main__':
 
85
    import sys
 
86
    ds = DiffStat(sys.stdin.readlines())
 
87
    print ds