mercurial/util.py
changeset 2085 f71e9656524f
parent 2083 345107e167a0
parent 2071 67a0a3852024
child 2090 eb40db373717
equal deleted inserted replaced
2084:d66278012853 2085:f71e9656524f
    69     for name, fn in filtertable.iteritems():
    69     for name, fn in filtertable.iteritems():
    70         if cmd.startswith(name):
    70         if cmd.startswith(name):
    71             return fn(s, cmd[len(name):].lstrip())
    71             return fn(s, cmd[len(name):].lstrip())
    72     return pipefilter(s, cmd)
    72     return pipefilter(s, cmd)
    73 
    73 
       
    74 def find_in_path(name, path, default=None):
       
    75     '''find name in search path. path can be string (will be split
       
    76     with os.pathsep), or iterable thing that returns strings.  if name
       
    77     found, return path to name. else return default.'''
       
    78     if isinstance(path, str):
       
    79         path = path.split(os.pathsep)
       
    80     for p in path:
       
    81         p_name = os.path.join(p, name)
       
    82         if os.path.exists(p_name):
       
    83             return p_name
       
    84     return default
       
    85 
    74 def patch(strip, patchname, ui):
    86 def patch(strip, patchname, ui):
    75     """apply the patch <patchname> to the working directory.
    87     """apply the patch <patchname> to the working directory.
    76     a list of patched files is returned"""
    88     a list of patched files is returned"""
    77     fp = os.popen('patch -p%d < "%s"' % (strip, patchname))
    89     patcher = find_in_path('gpatch', os.environ.get('PATH', ''), 'patch')
       
    90     fp = os.popen('"%s" -p%d < "%s"' % (patcher, strip, patchname))
    78     files = {}
    91     files = {}
    79     for line in fp:
    92     for line in fp:
    80         line = line.rstrip()
    93         line = line.rstrip()
    81         ui.status("%s\n" % line)
    94         ui.status("%s\n" % line)
    82         if line.startswith('patching file '):
    95         if line.startswith('patching file '):
   371 
   384 
   372 def unlink(f):
   385 def unlink(f):
   373     """unlink and remove the directory if it is empty"""
   386     """unlink and remove the directory if it is empty"""
   374     os.unlink(f)
   387     os.unlink(f)
   375     # try removing directories that might now be empty
   388     # try removing directories that might now be empty
   376     try: os.removedirs(os.path.dirname(f))
   389     try:
   377     except: pass
   390         os.removedirs(os.path.dirname(f))
       
   391     except OSError:
       
   392         pass
   378 
   393 
   379 def copyfiles(src, dst, hardlink=None):
   394 def copyfiles(src, dst, hardlink=None):
   380     """Copy a directory tree using hardlinks if possible"""
   395     """Copy a directory tree using hardlinks if possible"""
   381 
   396 
   382     if hardlink is None:
   397     if hardlink is None:
   528                 self.close()
   543                 self.close()
   529                 raise IOError(errno.EPIPE, 'Broken pipe')
   544                 raise IOError(errno.EPIPE, 'Broken pipe')
   530 
   545 
   531     sys.stdout = winstdout(sys.stdout)
   546     sys.stdout = winstdout(sys.stdout)
   532 
   547 
       
   548     def system_rcpath():
       
   549         return [r'c:\mercurial\mercurial.ini']
       
   550 
   533     def os_rcpath():
   551     def os_rcpath():
   534         '''return default os-specific hgrc search path'''
   552         '''return default os-specific hgrc search path'''
   535         try:
   553         return system_rcpath() + [os.path.join(os.path.expanduser('~'),
   536             import win32api, win32process
   554                                                'mercurial.ini')]
   537             proc = win32api.GetCurrentProcess()
       
   538             filename = win32process.GetModuleFileNameEx(proc, 0)
       
   539             systemrc = os.path.join(os.path.dirname(filename), 'mercurial.ini')
       
   540         except ImportError:
       
   541             systemrc = r'c:\mercurial\mercurial.ini'
       
   542 
       
   543         return [systemrc,
       
   544                 os.path.join(os.path.expanduser('~'), 'mercurial.ini')]
       
   545 
   555 
   546     def parse_patch_output(output_line):
   556     def parse_patch_output(output_line):
   547         """parses the output produced by patch and returns the file name"""
   557         """parses the output produced by patch and returns the file name"""
   548         pf = output_line[14:]
   558         pf = output_line[14:]
   549         if pf[0] == '`':
   559         if pf[0] == '`':
   550             pf = pf[1:-1] # Remove the quotes
   560             pf = pf[1:-1] # Remove the quotes
   551         return pf
   561         return pf
   552 
   562 
   553     try: # Mark Hammond's win32all package allows better functionality on Windows
   563     def testpid(pid):
   554         import win32api, win32con, win32file, pywintypes
   564         '''return False if pid dead, True if running or not known'''
   555 
   565         return True
   556         # create hard links using win32file module
       
   557         def os_link(src, dst): # NB will only succeed on NTFS
       
   558             win32file.CreateHardLink(dst, src)
       
   559 
       
   560         def nlinks(pathname):
       
   561             """Return number of hardlinks for the given file."""
       
   562             try:
       
   563                 fh = win32file.CreateFile(pathname,
       
   564                     win32file.GENERIC_READ, win32file.FILE_SHARE_READ,
       
   565                     None, win32file.OPEN_EXISTING, 0, None)
       
   566                 res = win32file.GetFileInformationByHandle(fh)
       
   567                 fh.Close()
       
   568                 return res[7]
       
   569             except:
       
   570                 return os.stat(pathname).st_nlink
       
   571 
       
   572         def testpid(pid):
       
   573             '''return True if pid is still running or unable to
       
   574             determine, False otherwise'''
       
   575             try:
       
   576                 import win32process, winerror
       
   577                 handle = win32api.OpenProcess(
       
   578                     win32con.PROCESS_QUERY_INFORMATION, False, pid)
       
   579                 if handle:
       
   580                     status = win32process.GetExitCodeProcess(handle)
       
   581                     return status == win32con.STILL_ACTIVE
       
   582             except pywintypes.error, details:
       
   583                 return details[0] != winerror.ERROR_INVALID_PARAMETER
       
   584             return True
       
   585 
       
   586     except ImportError:
       
   587         def testpid(pid):
       
   588             '''return False if pid dead, True if running or not known'''
       
   589             return True
       
   590 
   566 
   591     def is_exec(f, last):
   567     def is_exec(f, last):
   592         return last
   568         return last
   593 
   569 
   594     def set_exec(f, mode):
   570     def set_exec(f, mode):
   609     makelock = _makelock_file
   585     makelock = _makelock_file
   610     readlock = _readlock_file
   586     readlock = _readlock_file
   611 
   587 
   612     def explain_exit(code):
   588     def explain_exit(code):
   613         return _("exited with status %d") % code, code
   589         return _("exited with status %d") % code, code
       
   590 
       
   591     try:
       
   592         # override functions with win32 versions if possible
       
   593         from util_win32 import *
       
   594     except ImportError:
       
   595         pass
   614 
   596 
   615 else:
   597 else:
   616     nulldev = '/dev/null'
   598     nulldev = '/dev/null'
   617 
   599 
   618     def rcfiles(path):
   600     def rcfiles(path):