/brz/remove-bazaar

To get this branch, use:
bzr branch http://gegoxaren.bato24.eu/bzr/brz/remove-bazaar
1711.7.20 by John Arbash Meinel
always close files, minor PEP8 cleanup
1
# Copyright (C) 2005, 2006 Canonical Ltd
7296.5.1 by Jelmer Vernooij
Import patch code from bzrtools.
2
# Copyright (C) 2005, 2008 Aaron Bentley, 2006 Michael Ellerman
1711.7.20 by John Arbash Meinel
always close files, minor PEP8 cleanup
3
#
4
# This program is free software; you can redistribute it and/or modify
5
# it under the terms of the GNU General Public License as published by
6
# the Free Software Foundation; either version 2 of the License, or
7
# (at your option) any later version.
8
#
9
# This program is distributed in the hope that it will be useful,
10
# but WITHOUT ANY WARRANTY; without even the implied warranty of
11
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12
# GNU General Public License for more details.
13
#
14
# You should have received a copy of the GNU General Public License
15
# along with this program; if not, write to the Free Software
4183.7.1 by Sabin Iacob
update FSF mailing address
16
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
1711.7.20 by John Arbash Meinel
always close files, minor PEP8 cleanup
17
7296.5.1 by Jelmer Vernooij
Import patch code from bzrtools.
18
"""Diff and patch functionality"""
19
1534.7.130 by Aaron Bentley
More conflict handling, test porting
20
import errno
493 by Martin Pool
- Merge aaron's merge command
21
import os
974.1.2 by Aaron Bentley
Replaced popen with subprocess in patch..py
22
from subprocess import Popen, PIPE
7296.5.1 by Jelmer Vernooij
Import patch code from bzrtools.
23
import sys
7413.2.1 by Jelmer Vernooij
Add iter_patched_from_hunks implementation that calls out to the patch command.
24
import tempfile
1534.7.130 by Aaron Bentley
More conflict handling, test porting
25
7296.5.1 by Jelmer Vernooij
Import patch code from bzrtools.
26
from .errors import NoDiff3, BzrError
6624 by Jelmer Vernooij
Merge Python3 porting work ('py3 pokes')
27
from .textfile import check_text_path
1711.7.20 by John Arbash Meinel
always close files, minor PEP8 cleanup
28
7296.5.1 by Jelmer Vernooij
Import patch code from bzrtools.
29
class PatchFailed(BzrError):
30
31
    _fmt = """Patch application failed"""
32
33
34
class PatchInvokeError(BzrError):
35
36
    _fmt = """Error invoking patch: %(errstr)s%(stderr)s"""
37
    internal_error = False
38
39
    def __init__(self, e, stderr=''):
40
        self.exception = e
41
        self.errstr = os.strerror(e.errno)
42
        self.stderr = '\n' + stderr
493 by Martin Pool
- Merge aaron's merge command
43
1711.7.20 by John Arbash Meinel
always close files, minor PEP8 cleanup
44
45
_do_close_fds = True
46
if os.name == 'nt':
47
    _do_close_fds = False
48
49
974.1.2 by Aaron Bentley
Replaced popen with subprocess in patch..py
50
def write_to_cmd(args, input=""):
1711.7.20 by John Arbash Meinel
always close files, minor PEP8 cleanup
51
    """Spawn a process, and wait for the result
52
53
    If the process is killed, an exception is raised
54
55
    :param args: The command line, the first entry should be the program name
56
    :param input: [optional] The text to send the process on stdin
57
    :return: (stdout, stderr, status)
58
    """
59
    process = Popen(args, bufsize=len(input), stdin=PIPE, stdout=PIPE,
60
                    stderr=PIPE, close_fds=_do_close_fds)
974.1.2 by Aaron Bentley
Replaced popen with subprocess in patch..py
61
    stdout, stderr = process.communicate(input)
62
    status = process.wait()
63
    if status < 0:
7385.1.1 by Miro Hrončok
SyntaxWarning: 'str' object is not callable; perhaps you missed a comma?
64
        raise Exception("%s killed by signal %i" % (args[0], -status))
974.1.2 by Aaron Bentley
Replaced popen with subprocess in patch..py
65
    return stdout, stderr, status
3943.8.1 by Marius Kruger
remove all trailing whitespace from bzr source
66
974.1.2 by Aaron Bentley
Replaced popen with subprocess in patch..py
67
493 by Martin Pool
- Merge aaron's merge command
68
def patch(patch_contents, filename, output_filename=None, reverse=False):
69
    """Apply a patch to a file, to produce another output file.  This is should
70
    be suitable for our limited purposes.
71
72
    :param patch_contents: The contents of the patch to apply
73
    :type patch_contents: str
74
    :param filename: the name of the file to apply the patch to
75
    :type filename: str
76
    :param output_filename: The filename to produce.  If None, file is \
77
    modified in-place
78
    :type output_filename: str or NoneType
79
    :param reverse: If true, apply the patch in reverse
80
    :type reverse: bool
81
    :return: 0 on success, 1 if some hunks failed
82
    """
83
    args = ["patch", "-f", "-s", "--posix", "--binary"]
84
    if reverse:
85
        args.append("--reverse")
86
    if output_filename is not None:
87
        args.extend(("-o", output_filename))
88
    args.append(filename)
974.1.2 by Aaron Bentley
Replaced popen with subprocess in patch..py
89
    stdout, stderr, status = write_to_cmd(args, patch_contents)
3943.8.1 by Marius Kruger
remove all trailing whitespace from bzr source
90
    return status
493 by Martin Pool
- Merge aaron's merge command
91
92
93
def diff3(out_file, mine_path, older_path, yours_path):
94
    def add_label(args, label):
95
        args.extend(("-L", label))
1558.15.3 by Aaron Bentley
Handle binary files for diff3 merges
96
    check_text_path(mine_path)
97
    check_text_path(older_path)
98
    check_text_path(yours_path)
493 by Martin Pool
- Merge aaron's merge command
99
    args = ['diff3', "-E", "--merge"]
100
    add_label(args, "TREE")
101
    add_label(args, "ANCESTOR")
102
    add_label(args, "MERGE-SOURCE")
103
    args.extend((mine_path, older_path, yours_path))
1534.7.130 by Aaron Bentley
More conflict handling, test porting
104
    try:
105
        output, stderr, status = write_to_cmd(args)
6619.3.2 by Jelmer Vernooij
Apply 2to3 except fix.
106
    except OSError as e:
1534.7.130 by Aaron Bentley
More conflict handling, test porting
107
        if e.errno == errno.ENOENT:
108
            raise NoDiff3
109
        else:
110
            raise
493 by Martin Pool
- Merge aaron's merge command
111
    if status not in (0, 1):
974.1.2 by Aaron Bentley
Replaced popen with subprocess in patch..py
112
        raise Exception(stderr)
7296.5.4 by Jelmer Vernooij
Improve formatting.
113
    with open(out_file, 'wb') as f:
1711.7.20 by John Arbash Meinel
always close files, minor PEP8 cleanup
114
        f.write(output)
493 by Martin Pool
- Merge aaron's merge command
115
    return status
7296.5.1 by Jelmer Vernooij
Import patch code from bzrtools.
116
117
7296.5.4 by Jelmer Vernooij
Improve formatting.
118
def patch_tree(tree, patches, strip=0, reverse=False, dry_run=False,
119
               quiet=False, out=None):
7296.5.5 by Jelmer Vernooij
Add docstring.
120
    """Apply a patch to a tree.
121
122
    Args:
123
      tree: A MutableTree object
124
      patches: list of patches as bytes
125
      strip: Strip X segments of paths
126
      reverse: Apply reversal of patch
127
      dry_run: Dry run
128
    """
7296.5.4 by Jelmer Vernooij
Improve formatting.
129
    return run_patch(tree.basedir, patches, strip, reverse, dry_run,
130
                     quiet, out=out)
7296.5.1 by Jelmer Vernooij
Import patch code from bzrtools.
131
132
133
def run_patch(directory, patches, strip=0, reverse=False, dry_run=False,
7296.5.2 by Jelmer Vernooij
Import the patch command.
134
              quiet=False, _patch_cmd='patch', target_file=None, out=None):
7296.5.1 by Jelmer Vernooij
Import patch code from bzrtools.
135
    args = [_patch_cmd, '-d', directory, '-s', '-p%d' % strip, '-f']
136
    if quiet:
137
        args.append('--quiet')
138
139
    if sys.platform == "win32":
140
        args.append('--binary')
141
142
    if reverse:
143
        args.append('-R')
144
    if dry_run:
145
        if sys.platform.startswith('freebsd'):
146
            args.append('--check')
147
        else:
148
            args.append('--dry-run')
149
        stderr = PIPE
150
    else:
151
        stderr = None
152
    if target_file is not None:
153
        args.append(target_file)
154
155
    try:
156
        process = Popen(args, stdin=PIPE, stdout=PIPE, stderr=stderr)
157
    except OSError as e:
158
        raise PatchInvokeError(e)
159
    try:
160
        for patch in patches:
7296.5.3 by Jelmer Vernooij
Fix some tests.
161
            process.stdin.write(bytes(patch))
7296.5.1 by Jelmer Vernooij
Import patch code from bzrtools.
162
        process.stdin.close()
163
164
    except IOError as e:
165
        raise PatchInvokeError(e, process.stderr.read())
166
167
    result = process.wait()
168
    if not dry_run:
7296.5.2 by Jelmer Vernooij
Import the patch command.
169
        if out is not None:
170
            out.write(process.stdout.read())
171
        else:
172
            process.stdout.read()
7296.5.1 by Jelmer Vernooij
Import patch code from bzrtools.
173
    if result != 0:
174
        raise PatchFailed()
175
176
    return result
7413.2.1 by Jelmer Vernooij
Add iter_patched_from_hunks implementation that calls out to the patch command.
177
178
179
def iter_patched_from_hunks(orig_lines, hunks):
180
    """Iterate through a series of lines with a patch applied.
181
    This handles a single file, and does exact, not fuzzy patching.
182
183
    :param orig_lines: The unpatched lines.
184
    :param hunks: An iterable of Hunk instances.
185
186
    This is different from breezy.patches in that it invokes the patch
187
    command.
188
    """
189
    with tempfile.NamedTemporaryFile() as f:
190
        f.writelines(orig_lines)
191
        f.flush()
192
        # TODO(jelmer): Stream patch contents to command, rather than
193
        # serializing the entire patch upfront.
194
        serialized = b''.join([hunk.as_bytes() for hunk in hunks])
7413.2.2 by Jelmer Vernooij
Discard reject file.
195
        args = ["patch", "-f", "-s", "--posix", "--binary",
196
                "-o", "-", f.name, "-r", "-"]
7413.2.1 by Jelmer Vernooij
Add iter_patched_from_hunks implementation that calls out to the patch command.
197
        stdout, stderr, status = write_to_cmd(args, serialized)
7413.2.3 by Jelmer Vernooij
Raise PatchFailed error.
198
    if status == 0:
199
        return [stdout]
200
    raise PatchFailed(stderr)