changeset 4482:62019c4427e3

Introduce find_exe. Use instead of find_in_path for programs. The behaviour of find_in_path was broken for config options containing path names, because it always searched the given path, even when not necessary. The find_exe function is more polite: if the name passed to it contains a path component, it just returns it.
author Bryan O'Sullivan <bos@serpentine.com>
date Sun, 27 May 2007 14:26:54 -0700
parents 1b5b98837bb5
children a11e13d50645
files mercurial/commands.py mercurial/patch.py mercurial/util.py
diffstat 3 files changed, 24 insertions(+), 15 deletions(-) [+]
line wrap: on
line diff
--- a/mercurial/commands.py
+++ b/mercurial/commands.py
@@ -880,11 +880,10 @@ def debuginstall(ui):
 
     # patch
     ui.status(_("Checking patch...\n"))
-    path = os.environ.get('PATH', '')
     patcher = ui.config('ui', 'patch')
-    if not patcher:
-        patcher = util.find_in_path('gpatch', path,
-                                    util.find_in_path('patch', path, None))
+    patcher = ((patcher and util.find_exe(patcher)) or
+               util.find_exe('gpatch') or
+               util.find_exe('patch'))
     if not patcher:
         ui.write(_(" Can't find patch or gpatch in PATH\n"))
         ui.write(_(" (specify a patch utility in your .hgrc file)\n"))
@@ -922,9 +921,7 @@ def debuginstall(ui):
     ui.status(_("Checking merge helper...\n"))
     cmd = (os.environ.get("HGMERGE") or ui.config("ui", "merge")
            or "hgmerge")
-    cmdpath = util.find_in_path(cmd, path)
-    if not cmdpath:
-        cmdpath = util.find_in_path(cmd.split()[0], path)
+    cmdpath = util.find_exe(cmd) or util.find_exe(cmd.split()[0])
     if not cmdpath:
         if cmd == 'hgmerge':
             ui.write(_(" No merge helper set and can't find default"
@@ -958,9 +955,7 @@ def debuginstall(ui):
     editor = (os.environ.get("HGEDITOR") or
               ui.config("ui", "editor") or
               os.environ.get("EDITOR", "vi"))
-    cmdpath = util.find_in_path(editor, path)
-    if not cmdpath:
-        cmdpath = util.find_in_path(editor.split()[0], path)
+    cmdpath = util.find_exe(editor) or util.find_exe(editor.split()[0])
     if not cmdpath:
         if editor == 'vi':
             ui.write(_(" No commit editor set and can't find vi in PATH\n"))
--- a/mercurial/patch.py
+++ b/mercurial/patch.py
@@ -295,11 +295,13 @@ def patch(patchname, ui, strip=1, cwd=No
 
         args = []
         patcher = ui.config('ui', 'patch')
+        patcher = ((patcher and util.find_exe(patcher)) or
+                   util.find_exe('gpatch') or
+                   util.find_exe('patch'))
         if not patcher:
-            patcher = util.find_in_path('gpatch', os.environ.get('PATH', ''),
-                                        'patch')
-            if util.needbinarypatch():
-                args.append('--binary')
+            raise util.Abort(_('no patch command found in hgrc or PATH'))
+        if util.needbinarypatch():
+            args.append('--binary')
                                     
         if cwd:
             args.append('-d %s' % util.shellquote(cwd))
@@ -643,7 +645,7 @@ def export(repo, revs, template='hg-%h.p
         single(rev, seqno+1, fp)
 
 def diffstat(patchlines):
-    if not util.find_in_path('diffstat', os.environ.get('PATH', '')):
+    if not util.find_exe('diffstat'):
         return
     fd, name = tempfile.mkstemp(prefix="hg-patchbomb-", suffix=".txt")
     try:
--- a/mercurial/util.py
+++ b/mercurial/util.py
@@ -1087,6 +1087,18 @@ else:
                 return p_name
         return default
 
+def find_exe(name, default=None):
+    '''find path of an executable.
+    if name contains a path component, return it as is.  otherwise,
+    use normal executable search path.'''
+
+    if os.sep in name:
+        # don't check the executable bit.  if the file isn't
+        # executable, whoever tries to actually run it will give a
+        # much more useful error message.
+        return name
+    return find_in_path(name, os.environ.get('PATH', ''), default=default)
+
 def _buildencodefun():
     e = '_'
     win_reserved = [ord(x) for x in '\\:*?"<>|']