~abentley/bzrtools/bzrtools.dev

« back to all changes in this revision

Viewing changes to diffstat.py

  • Committer: Michael Ellerman
  • Date: 2006-02-11 03:27:01 UTC
  • mto: (0.1.73 shelf-tmp)
  • mto: This revision was merged to the branch mainline in revision 334.
  • Revision ID: michael@ellerman.id.au-20060211032701-43996d6a9e744b1a
Make patch parsing cope with shelf messages, starting with '#'.

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.files = []
 
11
        self.__parse(lines)
 
12
 
 
13
    def __parse(self, lines):
 
14
        import string
 
15
        adds = 0
 
16
        removes = 0
 
17
        current = None
 
18
 
 
19
        for line in lines:
 
20
            if line.startswith('+') and not line.startswith('+++'):
 
21
                adds += 1
 
22
            elif line.startswith('-') and not line.startswith('---'):
 
23
                removes += 1
 
24
            elif line.startswith('=== '):
 
25
                self.__add_stats(current, adds, removes)
 
26
 
 
27
                adds = 0
 
28
                removes = 0
 
29
                context = 0
 
30
                current = None
 
31
            elif line.startswith('--- ') and current is None:
 
32
                current = line[4:].strip()
 
33
            elif line.startswith('+++ ') and current == '/dev/null':
 
34
                current = line[4:].strip()
 
35
 
 
36
        self.__add_stats(current, adds, removes)
 
37
 
 
38
    class Filestat:
 
39
        def __init__(self):
 
40
            self.adds = 0
 
41
            self.removes = 0
 
42
            self.total = 0
 
43
 
 
44
    def __add_stats(self, file, adds, removes):
 
45
        if file is None:
 
46
            return
 
47
        elif file in self.stats:
 
48
            fstat = self.stats[file]
 
49
        else:
 
50
            self.files.append(file)
 
51
            fstat = self.Filestat()
 
52
 
 
53
        fstat.adds += adds
 
54
        fstat.removes += removes
 
55
        fstat.total = adds + removes
 
56
        self.stats[file] = fstat
 
57
 
 
58
        self.maxname = max(self.maxname, len(file))
 
59
        self.maxtotal = max(self.maxtotal, fstat.total)
 
60
        self.total_adds += adds
 
61
        self.total_removes += removes
 
62
 
 
63
    def __str__(self):
 
64
        # Work out widths
 
65
        width = 78 - 5
 
66
        countwidth = len(str(self.maxtotal))
 
67
        graphwidth = width - countwidth - self.maxname
 
68
        factor = 1
 
69
 
 
70
        # The graph width can be <= 0 if there is a modified file with a
 
71
        # filename longer than 'width'. Use a minimum of 10.
 
72
        if graphwidth < 10:
 
73
            graphwidth = 10
 
74
 
 
75
        while (self.maxtotal / factor) > graphwidth:
 
76
            factor += 1
 
77
 
 
78
        s = ""
 
79
 
 
80
        for file in self.files:
 
81
            fstat = self.stats[file]
 
82
 
 
83
            s += ' %-*s | %*.d ' % (self.maxname, file, countwidth, fstat.total)
 
84
 
 
85
            # If diffstat runs out of room it doesn't print anything, which
 
86
            # isn't very useful, so always print at least one + or 1
 
87
            if fstat.adds > 0:
 
88
                s += '+' * max(fstat.adds / factor, 1)
 
89
 
 
90
            if fstat.removes > 0:
 
91
                s += '-' * max(fstat.removes / factor, 1)
 
92
 
 
93
            s += '\n'
 
94
 
 
95
        if len(self.stats):
 
96
            s += ' %d files changed, %d insertions(+), %d deletions(-)' % \
 
97
                (len(self.stats), self.total_adds, self.total_removes)
 
98
 
 
99
        return s
 
100
 
 
101
if __name__ == '__main__':
 
102
    import sys
 
103
    ds = DiffStat(sys.stdin.readlines())
 
104
    print ds