~abentley/bzrtools/bzrtools.dev

« back to all changes in this revision

Viewing changes to shelf.py

Initial import

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
#!/usr/bin/python
 
2
 
 
3
import patches
 
4
import os
 
5
import sys
 
6
import string
 
7
 
 
8
def parse_args(args):
 
9
    if len(args) == 2 and args[1] == '--bzr-usage':
 
10
        print '\n'
 
11
        return True
 
12
    elif len(args) == 2 and args[1] == '--bzr-help':
 
13
        print 'Shelve a patch, you can get it back later with unshelve.'
 
14
        return True
 
15
    elif len(args) == 1:
 
16
        pass
 
17
    else:
 
18
        raise Exception("Don't understand args %s" % args)
 
19
 
 
20
    return False
 
21
 
 
22
def unshelve():
 
23
    root = run_bzr('root')[0].strip()
 
24
    shelf = os.path.join(root, '.bzr-shelf')
 
25
 
 
26
    if not os.path.exists(shelf):
 
27
        raise Exception("No shelf found in '%s'" % shelf)
 
28
 
 
29
    patch = open(shelf, 'r').read()
 
30
 
 
31
    print >>sys.stderr, "Reapplying shelved patches"
 
32
    pipe = os.popen('patch -d %s -s -p0' % root, 'w')
 
33
    pipe.write(patch)
 
34
    pipe.flush()
 
35
 
 
36
    if pipe.close() is not None:
 
37
        raise Exception("Failed running patch!")
 
38
 
 
39
    os.remove(shelf)
 
40
    print 'Diff status is now:'
 
41
    os.system('bzr diff | diffstat')
 
42
 
 
43
    return True
 
44
 
 
45
def shelve():
 
46
    diff_lines = run_bzr('diff')
 
47
    patch_list = patches.parse_patches(diff_lines.__iter__())
 
48
    to_shelve = prompt_user(patch_list)
 
49
 
 
50
    if len(to_shelve) == 0:
 
51
        print >>sys.stderr, 'Nothing to shelve'
 
52
        return True
 
53
 
 
54
    root = run_bzr('root')[0].strip()
 
55
    shelf = os.path.join(root, '.bzr-shelf')
 
56
    print >>sys.stderr, "Saving shelved patches to", shelf
 
57
    shelf = open(shelf, 'a')
 
58
 
 
59
    for patch in to_shelve:
 
60
        shelf.write(str(patch))
 
61
 
 
62
    shelf.flush()
 
63
    os.fsync(shelf.fileno())
 
64
    shelf.close()
 
65
 
 
66
    print >>sys.stderr, "Reverting shelved patches"
 
67
    pipe = os.popen('patch -d %s -sR -p0' % root, 'w')
 
68
    for patch in to_shelve:
 
69
       pipe.write(str(patch))
 
70
    pipe.flush()
 
71
 
 
72
    if pipe.close() is not None:
 
73
        raise Exception("Failed running patch!")
 
74
 
 
75
    print 'Diff status is now:'
 
76
    os.system('bzr diff | diffstat')
 
77
 
 
78
    return True
 
79
 
 
80
def run_bzr(args):
 
81
    if type(args) is str:
 
82
        args = [ args ]
 
83
    pipe = os.popen('bzr %s' % string.join(args, ' '), 'r')
 
84
    lines = pipe.readlines()
 
85
    if pipe.close() is not None:
 
86
        raise Exception("Failed running bzr")
 
87
    return lines
 
88
 
 
89
def prompt_user(patch_list):
 
90
    total = 0
 
91
    for patch in patch_list:
 
92
        total += len(patch.hunks)
 
93
 
 
94
    out = sys.stdout
 
95
    inp = sys.stdin
 
96
 
 
97
    to_shelve = []
 
98
    i = 1
 
99
    for patch in patch_list:
 
100
        if patch.oldname != patch.newname:
 
101
            name = "%s -> %s" % (patch.oldname, patch.newname)
 
102
        else:
 
103
            name = patch.oldname
 
104
 
 
105
        hunks = patch.hunks[:]
 
106
        for hunk in hunks:
 
107
            print name
 
108
            print hunk
 
109
            while True:
 
110
                out.write('Shelve this change? (%d of %d) [yn] ' % (i, total))
 
111
                line = inp.readline().strip().lower()
 
112
                if line == 'y' or line == 'yes':
 
113
                    break
 
114
                elif line == 'n' or line == 'no':
 
115
                    patch.hunks.remove(hunk)
 
116
                    break
 
117
 
 
118
            i += 1
 
119
 
 
120
        if len(patch.hunks) > 0:
 
121
            to_shelve.append(patch)
 
122
 
 
123
    return to_shelve