~abentley/bzrtools/bzrtools.dev

« back to all changes in this revision

Viewing changes to patch.py

  • Committer: ghigo
  • Date: 2006-03-03 20:40:43 UTC
  • mto: This revision was merged to the branch mainline in revision 330.
  • Revision ID: ghigo@venice-20060303204043-a0355f76fb8f6b1a
add support for bazaar diff

Show diffs side-by-side

added added

removed removed

Lines of Context:
14
14
#    You should have received a copy of the GNU General Public License
15
15
#    along with this program; if not, write to the Free Software
16
16
#    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
17
 
import sys
 
17
import sys, os
18
18
from subprocess import Popen, PIPE
19
19
from bzrlib.transport import get_transport
20
20
from urlparse import urlsplit, urlunsplit
21
 
def patch(branch, location, strip):
 
21
 
 
22
class BzrTagProc:
 
23
    """This class handle the additional bazaar diff tags
 
24
 
 
25
        TODO:
 
26
          error handling
 
27
    """
 
28
    def __init__(self):
 
29
        self.renamed = None
 
30
        self.link = None
 
31
 
 
32
    def _extractname(self, s):
 
33
        x = s[0]
 
34
        i = 1
 
35
        ls = len(s)
 
36
 
 
37
        while i < ls:
 
38
            if s[i] == '\\':
 
39
                assert(i+1 < ls )
 
40
                i += 2
 
41
                continue
 
42
 
 
43
            if s[i] == x:
 
44
                return s[1:i],i+1
 
45
 
 
46
            i += 1
 
47
 
 
48
        assert(False)
 
49
 
 
50
    def extractname(self, s):
 
51
        space = s.find(" ",9)    # find the 2nd space
 
52
        assert(space)
 
53
        return self._extractname(s[space+1:])[0]
 
54
 
 
55
    def extractnames(self, s):
 
56
        space = s.find(" ",10)    # find the 2nd space
 
57
        assert(space)
 
58
        s=s[space+1:]
 
59
        source, pos = self._extractname(s)
 
60
        assert( pos +4 < len(s) )
 
61
        dest,  dummy = self._extractname(s[pos+4:])
 
62
 
 
63
        return source,dest
 
64
 
 
65
    def flush(self):
 
66
        self.process( )
 
67
 
 
68
    def process(self, cmd = None):
 
69
        if self.renamed:
 
70
            os.rename(self.renamed[0], self.renamed[1])
 
71
            self.renamed = None
 
72
 
 
73
        if not cmd: return
 
74
 
 
75
        if ( cmd.startswith("removed file") or 
 
76
             cmd.startswith("removed symlink") ):
 
77
 
 
78
            target = self.extractname(cmd)
 
79
            print "removing '%s'"%target
 
80
            os.unlink(target)
 
81
 
 
82
        elif cmd.startswith("removed directory"):
 
83
 
 
84
            target = self.extractname(cmd)
 
85
            print "removing '%s'"%target
 
86
            os.rmdir(target)
 
87
 
 
88
        elif cmd.startswith("added file"):
 
89
            target = self.extractname(cmd)
 
90
            print "adding '%s'"%target
 
91
            f = open(target,"w")
 
92
            f.close( )
 
93
 
 
94
        elif cmd.startswith("added directory"):
 
95
            target = self.extractname(cmd)
 
96
            print "adding '%s'"%target
 
97
            os.mkdir(target)
 
98
 
 
99
        elif cmd.startswith("added symlink"):
 
100
            assert(not self.link)
 
101
            self.link = self.extractname(cmd)
 
102
 
 
103
        elif cmd.startswith("target is"):
 
104
            assert(self.link)
 
105
            source = self.extractname(cmd)
 
106
            print "symlinking '%s' => '%s'"%(source, self.link)
 
107
            os.symlink(source, self.link)
 
108
            self.link = None
 
109
 
 
110
        elif ( cmd.startswith("renamed symlink") or
 
111
               cmd.startswith("renamed file") or
 
112
               cmd.startswith("renamed directory") ):
 
113
 
 
114
            space = cmd.find(" ",10)    # find the 2nd space
 
115
            assert(space)
 
116
            source,dest = self.extractnames(cmd[space+1:])
 
117
            print "renaming '%s' => '%s'"%(source,dest)
 
118
 
 
119
            os.rename(source,dest)
 
120
 
 
121
        else:
 
122
            sys.stderr.write("Unsupported tag: '%s'\n"%cmd)
 
123
 
 
124
 
 
125
 
 
126
def patch(branch, location, strip, legacy):
22
127
    """Apply a patch to a branch, using patch(1).  URLs may be used."""
23
128
    my_file = None
24
129
    if location is None:
33
138
        if my_file is None:
34
139
            my_file = file(location, 'rb')
35
140
    cmd = ['patch', '--directory', branch.base, '--strip', str(strip)]
36
 
    child_proc = Popen(cmd, stdin=PIPE)
37
 
    for line in my_file:
38
 
        child_proc.stdin.write(line)
39
 
    child_proc.stdin.close()
40
 
    return child_proc.wait()
 
141
    if legacy:
 
142
        child_proc = Popen(cmd, stdin=PIPE)
 
143
        for line in my_file:
 
144
            child_proc.stdin.write(line)
 
145
        child_proc.stdin.close()
 
146
        r = child_proc.wait()
 
147
 
 
148
    else:
 
149
        bzr_tags_proc = BzrTagProc( )
 
150
        child_proc = None
 
151
 
 
152
        for line in my_file:
 
153
            if line.startswith("=== "):
 
154
                if child_proc:
 
155
                    child_proc.stdin.close()
 
156
                    r = child_proc.wait()
 
157
                    child_proc = None
 
158
                bzr_tags_proc.process(line[4:])
 
159
            else:
 
160
                if not child_proc:
 
161
                    child_proc = Popen(cmd, stdin=PIPE)
 
162
                #sys.stdout.write("# %s"%line)
 
163
                child_proc.stdin.write(line)
 
164
        if child_proc:
 
165
            child_proc.stdin.close()
 
166
            r = child_proc.wait()
 
167
        bzr_tags_proc.flush( )
 
168
 
 
169
    return r
 
 
b'\\ No newline at end of file'