mercurial/util.py
changeset 1307 3b717f27ffea
parent 1293 a6ffcebd3315
child 1312 c9cf171f30dd
equal deleted inserted replaced
1286:4f08da74cae8 1307:3b717f27ffea
    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