10 platform-specific details from the core. |
10 platform-specific details from the core. |
11 """ |
11 """ |
12 |
12 |
13 import os, errno |
13 import os, errno |
14 from demandload import * |
14 from demandload import * |
15 demandload(globals(), "re cStringIO shutil popen2 threading") |
15 demandload(globals(), "re cStringIO shutil popen2 tempfile threading") |
16 |
16 |
17 def filter(s, cmd): |
17 def pipefilter(s, cmd): |
18 "filter a string through a command that transforms its input to its output" |
18 '''filter string S through command CMD, returning its output''' |
19 (pout, pin) = popen2.popen2(cmd, -1, 'b') |
19 (pout, pin) = popen2.popen2(cmd, -1, 'b') |
20 def writer(): |
20 def writer(): |
21 pin.write(s) |
21 pin.write(s) |
22 pin.close() |
22 pin.close() |
23 |
23 |
27 w.start() |
27 w.start() |
28 f = pout.read() |
28 f = pout.read() |
29 pout.close() |
29 pout.close() |
30 w.join() |
30 w.join() |
31 return f |
31 return f |
|
32 |
|
33 def tempfilter(s, cmd): |
|
34 '''filter string S through a pair of temporary files with CMD. |
|
35 CMD is used as a template to create the real command to be run, |
|
36 with the strings INFILE and OUTFILE replaced by the real names of |
|
37 the temporary files generated.''' |
|
38 inname, outname = None, None |
|
39 try: |
|
40 infd, inname = tempfile.mkstemp(prefix='hgfin') |
|
41 fp = os.fdopen(infd, 'wb') |
|
42 fp.write(s) |
|
43 fp.close() |
|
44 outfd, outname = tempfile.mkstemp(prefix='hgfout') |
|
45 os.close(outfd) |
|
46 cmd = cmd.replace('INFILE', inname) |
|
47 cmd = cmd.replace('OUTFILE', outname) |
|
48 code = os.system(cmd) |
|
49 if code: raise Abort("command '%s' failed: %s" % |
|
50 (cmd, explain_exit(code))) |
|
51 return open(outname, 'rb').read() |
|
52 finally: |
|
53 try: |
|
54 if inname: os.unlink(inname) |
|
55 except: pass |
|
56 try: |
|
57 if outname: os.unlink(outname) |
|
58 except: pass |
|
59 |
|
60 filtertable = { |
|
61 'tempfile:': tempfilter, |
|
62 'pipe:': pipefilter, |
|
63 } |
|
64 |
|
65 def filter(s, cmd): |
|
66 "filter a string through a command that transforms its input to its output" |
|
67 for name, fn in filtertable.iteritems(): |
|
68 if cmd.startswith(name): |
|
69 return fn(s, cmd[len(name):].lstrip()) |
|
70 return pipefilter(s, cmd) |
32 |
71 |
33 def patch(strip, patchname, ui): |
72 def patch(strip, patchname, ui): |
34 """apply the patch <patchname> to the working directory. |
73 """apply the patch <patchname> to the working directory. |
35 a list of patched files is returned""" |
74 a list of patched files is returned""" |
36 fp = os.popen('patch -p%d < "%s"' % (strip, patchname)) |
75 fp = os.popen('patch -p%d < "%s"' % (strip, patchname)) |
41 if line.startswith('patching file '): |
80 if line.startswith('patching file '): |
42 pf = parse_patch_output(line) |
81 pf = parse_patch_output(line) |
43 files.setdefault(pf, 1) |
82 files.setdefault(pf, 1) |
44 code = fp.close() |
83 code = fp.close() |
45 if code: |
84 if code: |
46 raise Abort("patch command failed: exit status %s " % code) |
85 raise Abort("patch command failed: %s" % explain_exit(code)) |
47 return files.keys() |
86 return files.keys() |
48 |
87 |
49 def binary(s): |
88 def binary(s): |
50 """return true if a string is binary data using diff's heuristic""" |
89 """return true if a string is binary data using diff's heuristic""" |
51 if s and '\0' in s[:4096]: |
90 if s and '\0' in s[:4096]: |
52 return True |
91 return True |
53 return False |
92 return False |
329 |
368 |
330 # Platform specific variants |
369 # Platform specific variants |
331 if os.name == 'nt': |
370 if os.name == 'nt': |
332 nulldev = 'NUL:' |
371 nulldev = 'NUL:' |
333 |
372 |
|
373 rcpath = (r'c:\mercurial\mercurial.ini', |
|
374 os.path.join(os.path.expanduser('~'), 'mercurial.ini')) |
|
375 |
334 def parse_patch_output(output_line): |
376 def parse_patch_output(output_line): |
335 """parses the output produced by patch and returns the file name""" |
377 """parses the output produced by patch and returns the file name""" |
336 pf = output_line[14:] |
378 pf = output_line[14:] |
337 if pf[0] == '`': |
379 if pf[0] == '`': |
338 pf = pf[1:-1] # Remove the quotes |
380 pf = pf[1:-1] # Remove the quotes |
380 def explain_exit(code): |
422 def explain_exit(code): |
381 return "exited with status %d" % code, code |
423 return "exited with status %d" % code, code |
382 |
424 |
383 else: |
425 else: |
384 nulldev = '/dev/null' |
426 nulldev = '/dev/null' |
|
427 |
|
428 rcpath = map(os.path.normpath, |
|
429 ('/etc/mercurial/hgrc', os.path.expanduser('~/.hgrc'))) |
385 |
430 |
386 def parse_patch_output(output_line): |
431 def parse_patch_output(output_line): |
387 """parses the output produced by patch and returns the file name""" |
432 """parses the output produced by patch and returns the file name""" |
388 return output_line[14:] |
433 return output_line[14:] |
389 |
434 |