~bzr-pqm/bzr/bzr.dev

« back to all changes in this revision

Viewing changes to bzrlib/patch.py

  • Committer: Martin Pool
  • Date: 2005-05-09 03:03:55 UTC
  • Revision ID: mbp@sourcefrog.net-20050509030355-ad6ab558d1362959
- Don't give an error if the trace file can't be opened

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
import errno
2
 
import os
3
 
from subprocess import Popen, PIPE
4
 
 
5
 
from bzrlib.errors import NoDiff3
6
 
"""
7
 
Diff and patch functionality
8
 
"""
9
 
__docformat__ = "restructuredtext"
10
 
 
11
 
def write_to_cmd(args, input=""):
12
 
    if os.name != 'nt':
13
 
        process = Popen(args, bufsize=len(input), stdin=PIPE, stdout=PIPE,
14
 
                        stderr=PIPE, close_fds=True)
15
 
    else:
16
 
        process = Popen(args, bufsize=len(input), stdin=PIPE, stdout=PIPE,
17
 
                        stderr=PIPE)
18
 
 
19
 
    stdout, stderr = process.communicate(input)
20
 
    status = process.wait()
21
 
    if status < 0:
22
 
        raise Exception("%s killed by signal %i" (args[0], -status))
23
 
    return stdout, stderr, status
24
 
    
25
 
 
26
 
def patch(patch_contents, filename, output_filename=None, reverse=False):
27
 
    """Apply a patch to a file, to produce another output file.  This is should
28
 
    be suitable for our limited purposes.
29
 
 
30
 
    :param patch_contents: The contents of the patch to apply
31
 
    :type patch_contents: str
32
 
    :param filename: the name of the file to apply the patch to
33
 
    :type filename: str
34
 
    :param output_filename: The filename to produce.  If None, file is \
35
 
    modified in-place
36
 
    :type output_filename: str or NoneType
37
 
    :param reverse: If true, apply the patch in reverse
38
 
    :type reverse: bool
39
 
    :return: 0 on success, 1 if some hunks failed
40
 
    """
41
 
    args = ["patch", "-f", "-s", "--posix", "--binary"]
42
 
    if reverse:
43
 
        args.append("--reverse")
44
 
    if output_filename is not None:
45
 
        args.extend(("-o", output_filename))
46
 
    args.append(filename)
47
 
    stdout, stderr, status = write_to_cmd(args, patch_contents)
48
 
    return status 
49
 
 
50
 
 
51
 
def diff3(out_file, mine_path, older_path, yours_path):
52
 
    def add_label(args, label):
53
 
        args.extend(("-L", label))
54
 
    args = ['diff3', "-E", "--merge"]
55
 
    add_label(args, "TREE")
56
 
    add_label(args, "ANCESTOR")
57
 
    add_label(args, "MERGE-SOURCE")
58
 
    args.extend((mine_path, older_path, yours_path))
59
 
    try:
60
 
        output, stderr, status = write_to_cmd(args)
61
 
    except OSError, e:
62
 
        if e.errno == errno.ENOENT:
63
 
            raise NoDiff3
64
 
        else:
65
 
            raise
66
 
    if status not in (0, 1):
67
 
        raise Exception(stderr)
68
 
    file(out_file, "wb").write(output)
69
 
    return status