diff hgext/fix.py @ 52995:1330278b9029

fix: add a `extra-bin-paths` option See inline document for details.
author Pierre-Yves David <pierre-yves.david@octobus.net>
date Wed, 19 Feb 2025 23:15:43 +0100
parents f4733654f144
children
line wrap: on
line diff
--- a/hgext/fix.py	Tue Feb 18 23:30:50 2025 -0500
+++ b/hgext/fix.py	Wed Feb 19 23:15:43 2025 +0100
@@ -120,6 +120,9 @@
     mapping fixer tool names to lists of metadata values returned from
     executions that modified a file. This aggregates the same metadata
     previously passed to the "postfixfile" hook.
+
+You can specify a list of directories to search the tool command in using the
+`fix.extra-bin-paths` configuration.
 """
 
 from __future__ import annotations
@@ -129,6 +132,7 @@
 import os
 import re
 import subprocess
+import sys
 
 from mercurial.i18n import _
 from mercurial.node import (
@@ -143,6 +147,7 @@
     cmdutil,
     context,
     copies,
+    encoding,
     error,
     logcmdutil,
     match as matchmod,
@@ -193,6 +198,8 @@
 # problem.
 configitem(b'fix', b'failure', default=b'continue')
 
+configitem(b'fix', b'extra-bin-paths', default=list)
+
 
 def checktoolfailureaction(ui, message, hint=None):
     """Abort with 'message' if fix.failure=abort"""
@@ -678,6 +685,28 @@
         )
 
 
+def _augmented_env(wvfs, extra_paths):
+    if os.supports_bytes_environ:
+        env = encoding.environ.copy()
+        raw_path = env.get(b'PATH', b'')
+        extra_paths = [wvfs.join(i) for i in extra_paths]
+        path_items = extra_paths + raw_path.split(pycompat.ospathsep)
+        env[b'PATH'] = pycompat.ospathsep.join(path_items)
+    else:
+        path_encoding = sys.getfilesystemencoding() or sys.getdefaultencoding()
+        extra_str = [p.decode(path_encoding, 'ignore') for p in extra_paths]
+        base = wvfs.base.decode(path_encoding, 'ignore')
+        extra_str = [os.path.join(base, i) for i in extra_str]
+
+        # use (os).xxx to bypass checkcode complains. We are doing this
+        # unicode access on purpose.
+        env = (os).environ.copy()
+        raw_path = env.get('PATH', '')
+        path_items = extra_str + raw_path.split((os).pathsep)
+        env['PATH'] = (os).pathsep.join(path_items)
+    return env
+
+
 def fixfile(ui, repo, opts, fixers, fixctx, path, basepaths, basectxs):
     """Run any configured fixers that should affect the file in this context
 
@@ -692,6 +721,11 @@
     """
     metadata = {}
     newdata = fixctx[path].data()
+
+    env = None
+    extra_paths = ui.configlist(b'fix', b'extra-bin-paths')
+    if extra_paths:
+        env = _augmented_env(repo.wvfs, extra_paths)
     for fixername, fixer in fixers.items():
         if fixer.affects(opts, fixctx, path):
             ranges = lineranges(
@@ -711,6 +745,7 @@
                 stdin=subprocess.PIPE,
                 stdout=subprocess.PIPE,
                 stderr=subprocess.PIPE,
+                env=env,
             )
             stdout, stderr = proc.communicate(newdata)
             if stderr: