find_program: Ignore programs in the WindowsApps directory
The latest Windows 10 release in May 2019 added zero-sized files that act as stubs which when launched from cmd.exe spawn the Windows Store to install those apps. This also includes python.exe and python3.exe: https://devblogs.microsoft.com/python/python-in-the-windows-10-may-2019-update/ Unfortunately, `import('python').find_installation('python3')` will then think that python3.exe is available on Windows. Or, worse, if the user has a fresh installation of Windows 10 and then installs the Python 3 using the official installer (not the Windows Store app), we will *still* pickup this stub because it will be first in `PATH`. Always remove the WindowsApps directory from `PATH` while searching. First reported at https://gitlab.freedesktop.org/gstreamer/cerbero/issues/223
This commit is contained in:
parent
71bbcc7669
commit
64432e9448
|
@ -1814,6 +1814,19 @@ class ExternalProgram:
|
|||
return NonExistingExternalProgram()
|
||||
return cls.from_entry(name, command)
|
||||
|
||||
@staticmethod
|
||||
@functools.lru_cache(maxsize=None)
|
||||
def _windows_sanitize_path(path: str) -> str:
|
||||
# Ignore executables in the WindowsApps directory which are
|
||||
# zero-sized wrappers that magically open the Windows Store to
|
||||
# install the application.
|
||||
appstore_dir = Path.home() / 'AppData' / 'Local' / 'Microsoft' / 'WindowsApps'
|
||||
paths = []
|
||||
for each in path.split(os.pathsep):
|
||||
if Path(each) != appstore_dir:
|
||||
paths.append(each)
|
||||
return os.pathsep.join(paths)
|
||||
|
||||
@staticmethod
|
||||
def from_entry(name, command):
|
||||
if isinstance(command, list):
|
||||
|
@ -1939,7 +1952,7 @@ class ExternalProgram:
|
|||
# On Windows, interpreted scripts must have an extension otherwise they
|
||||
# cannot be found by a standard PATH search. So we do a custom search
|
||||
# where we manually search for a script with a shebang in PATH.
|
||||
search_dirs = os.environ.get('PATH', '').split(';')
|
||||
search_dirs = self._windows_sanitize_path(os.environ.get('PATH', '')).split(';')
|
||||
for search_dir in search_dirs:
|
||||
commands = self._search_dir(name, search_dir)
|
||||
if commands:
|
||||
|
@ -1955,7 +1968,10 @@ class ExternalProgram:
|
|||
if commands:
|
||||
return commands
|
||||
# Do a standard search in PATH
|
||||
command = shutil.which(name)
|
||||
path = os.environ.get('PATH', None)
|
||||
if mesonlib.is_windows() and path:
|
||||
path = self._windows_sanitize_path(path)
|
||||
command = shutil.which(name, path=path)
|
||||
if mesonlib.is_windows():
|
||||
return self._search_windows_special_cases(name, command)
|
||||
# On UNIX-like platforms, shutil.which() is enough to find
|
||||
|
|
Loading…
Reference in New Issue