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