Skip to content

Commit ed16517

Browse files
committed
Find viable bash.exe for running hooks on Windows
When running hooks on Windows, bash.exe must be supplied on the command line to run the hook script. This change tries to find a viable bash.exe from the user's PATH, while avoiding the bash.exe stub in the OS's System32 directory. This change is adapted from Michael Wild's PR #103. Signed-off-by: Peter Grayson <[email protected]>
1 parent ad85e5f commit ed16517

File tree

1 file changed

+35
-6
lines changed

1 file changed

+35
-6
lines changed

stgit/utils.py

Lines changed: 35 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,8 @@
22

33
import os
44
import re
5+
import shutil
6+
import sys
57
import tempfile
68
from io import open
79

@@ -90,16 +92,43 @@ def get_hook(repository, hook_name, extra_env=None):
9092
extra_env = add_dict(extra_env, {'GIT_PREFIX': prefix})
9193

9294
def hook(*parameters):
93-
argv = [hook_path]
94-
argv.extend(parameters)
95+
if sys.platform == 'win32':
96+
# On Windows, run the hook using "bash" explicitly.
97+
# Try to locate bash.exe in user's PATH, but avoid the WSL
98+
# shim/bootstrapper %SYSTEMROOT%/System32/bash.exe
99+
systemroot = os.environ.get('SYSTEMROOT')
100+
if systemroot:
101+
system32 = os.path.normcase(os.path.join(systemroot, 'system32'))
102+
path = os.pathsep.join(
103+
p
104+
for p in os.environ.get('PATH', '').split(os.pathsep)
105+
if os.path.normcase(p) != system32
106+
)
107+
else:
108+
path = None
109+
110+
# Find bash with user's path (sans System32).
111+
bash_exe = shutil.which('bash.exe', path=path)
112+
if not bash_exe:
113+
# Next try finding the bash.exe that came with Git for Windows.
114+
git_exe = shutil.which('git.exe', path=path)
115+
if not git_exe:
116+
raise StgException('Failed to locate either bash.exe or git.exe')
117+
bash_exe = os.path.join(
118+
os.path.dirname(os.path.dirname(git_exe)),
119+
'bin',
120+
'bash.exe',
121+
)
122+
123+
argv = [bash_exe, hook_path]
124+
else:
125+
argv = [hook_path]
95126

96-
# On Windows, run the hook using "bash" explicitly
97-
if os.name != 'posix':
98-
argv.insert(0, 'bash')
127+
argv.extend(parameters)
99128

100129
repository.default_iw.run(argv, extra_env).run()
101130

102-
hook.__name__ = str(hook_name)
131+
hook.__name__ = hook_name
103132
return hook
104133

105134

0 commit comments

Comments
 (0)