~abentley/bzrtools/bzrtools.dev

611 by Aaron Bentley
Handle missing patch, fix tabs
1
# Copyright (C) 2005, 2008 Aaron Bentley, 2006 Michael Ellerman
612 by Aaron Bentley
Update email address
2
# <aaron@aaronbentley.com>
257.1.2 by Aaron Bentley
Updated GPL notices
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
16
#    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
473 by Aaron Bentley
Clean up patch command (support http urls again)
17
import sys
610 by Aaron Bentley
Unify patch invocation
18
import subprocess
473 by Aaron Bentley
Clean up patch command (support http urls again)
19
321.2.3 by ghigo
Inform bzr of a renaming
20
import bzrlib.add
473 by Aaron Bentley
Clean up patch command (support http urls again)
21
563 by Aaron Bentley
Allow importing directly from a URL
22
from bzrlib.plugins.bzrtools.bzrtools import open_from_url
776.2.1 by Jelmer Vernooij
Remove unused imports and fix two imports.
23
from errors import PatchFailed, PatchInvokeError
563 by Aaron Bentley
Allow importing directly from a URL
24
496 by Aaron Bentley
Add --silent option to patch
25
def patch(tree, location, strip, quiet=False):
259 by Aaron Bentley
Got patch working with urls
26
    """Apply a patch to a branch, using patch(1).  URLs may be used."""
27
    my_file = None
28
    if location is None:
152 by Aaron Bentley
Added new bzr patch command
29
        my_file = sys.stdin
30
    else:
563 by Aaron Bentley
Allow importing directly from a URL
31
        my_file = open_from_url(location)
610 by Aaron Bentley
Unify patch invocation
32
    patches = [my_file.read()]
33
    return run_patch(tree.basedir, patches, strip, quiet=quiet)
34
35
36
def run_patch(directory, patches, strip=0, reverse=False, dry_run=False,
662 by Aaron Bentley
Add target_file param
37
              quiet=False, _patch_cmd='patch', target_file=None):
611 by Aaron Bentley
Handle missing patch, fix tabs
38
    args = [_patch_cmd, '-d', directory, '-s', '-p%d' % strip, '-f']
496 by Aaron Bentley
Add --silent option to patch
39
    if quiet:
610 by Aaron Bentley
Unify patch invocation
40
        args.append('--quiet')
41
42
    if sys.platform == "win32":
43
        args.append('--binary')
44
45
    if reverse:
46
        args.append('-R')
47
    if dry_run:
48
        if sys.platform.startswith('freebsd'):
49
            args.append('--check')
50
        else:
51
            args.append('--dry-run')
52
        stderr = subprocess.PIPE
53
    else:
54
        stderr = None
662 by Aaron Bentley
Add target_file param
55
    if target_file is not None:
56
        args.append(target_file)
610 by Aaron Bentley
Unify patch invocation
57
58
    try:
59
        process = subprocess.Popen(args, stdin=subprocess.PIPE,
60
                                   stdout=subprocess.PIPE, stderr=stderr)
611 by Aaron Bentley
Handle missing patch, fix tabs
61
    except OSError, e:
62
        raise PatchInvokeError(e)
63
    try:
610 by Aaron Bentley
Unify patch invocation
64
        for patch in patches:
65
            process.stdin.write(str(patch))
66
        process.stdin.close()
67
68
    except IOError, e:
69
        raise PatchInvokeError(e, process.stderr.read())
70
71
    result = process.wait()
72
    if not dry_run:
73
        sys.stdout.write(process.stdout.read())
74
    if result != 0:
75
        raise PatchFailed()
76
77
    return result