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