Merge pull request #4137 from pypeclub/feature/find_executable_enhancement

General: Find executable enhancement
This commit is contained in:
Jakub Trllo 2022-11-24 17:43:08 +01:00 committed by GitHub
commit 6ccd3eea74
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23

View file

@ -60,9 +60,10 @@ def find_executable(executable):
path to file. path to file.
Returns: Returns:
str: Full path to executable with extension (is file). Union[str, None]: Full path to executable with extension which was
None: When the executable was not found. found otherwise None.
""" """
# Skip if passed path is file # Skip if passed path is file
if is_file_executable(executable): if is_file_executable(executable):
return executable return executable
@ -70,24 +71,36 @@ def find_executable(executable):
low_platform = platform.system().lower() low_platform = platform.system().lower()
_, ext = os.path.splitext(executable) _, ext = os.path.splitext(executable)
# Prepare variants for which it will be looked # Prepare extensions to check
variants = [executable] exts = set()
# Add other extension variants only if passed executable does not have one if ext:
if not ext: exts.add(ext.lower())
if low_platform == "windows":
exts = [".exe", ".ps1", ".bat"]
for ext in os.getenv("PATHEXT", "").split(os.pathsep):
ext = ext.lower()
if ext and ext not in exts:
exts.append(ext)
else:
exts = [".sh"]
for ext in exts: else:
variant = executable + ext # Add other possible extension variants only if passed executable
if is_file_executable(variant): # does not have any
return variant if low_platform == "windows":
variants.append(variant) exts |= {".exe", ".ps1", ".bat"}
for ext in os.getenv("PATHEXT", "").split(os.pathsep):
exts.add(ext.lower())
else:
exts |= {".sh"}
# Executable is a path but there may be missing extension
# - this can happen primarily on windows where
# e.g. "ffmpeg" should be "ffmpeg.exe"
exe_dir, exe_filename = os.path.split(executable)
if exe_dir and os.path.isdir(exe_dir):
for filename in os.listdir(exe_dir):
filepath = os.path.join(exe_dir, filename)
basename, ext = os.path.splitext(filename)
if (
basename == exe_filename
and ext.lower() in exts
and is_file_executable(filepath)
):
return filepath
# Get paths where to look for executable # Get paths where to look for executable
path_str = os.environ.get("PATH", None) path_str = os.environ.get("PATH", None)
@ -97,13 +110,27 @@ def find_executable(executable):
elif hasattr(os, "defpath"): elif hasattr(os, "defpath"):
path_str = os.defpath path_str = os.defpath
if path_str: if not path_str:
paths = path_str.split(os.pathsep) return None
for path in paths:
for variant in variants: paths = path_str.split(os.pathsep)
filepath = os.path.abspath(os.path.join(path, variant)) for path in paths:
if is_file_executable(filepath): if not os.path.isdir(path):
return filepath continue
for filename in os.listdir(path):
filepath = os.path.abspath(os.path.join(path, filename))
# Filename matches executable exactly
if filename == executable and is_file_executable(filepath):
return filepath
basename, ext = os.path.splitext(filename)
if (
basename == executable
and ext.lower() in exts
and is_file_executable(filepath)
):
return filepath
return None return None
@ -272,8 +299,8 @@ def get_oiio_tools_path(tool="oiiotool"):
oiio_dir = get_vendor_bin_path("oiio") oiio_dir = get_vendor_bin_path("oiio")
if platform.system().lower() == "linux": if platform.system().lower() == "linux":
oiio_dir = os.path.join(oiio_dir, "bin") oiio_dir = os.path.join(oiio_dir, "bin")
default_path = os.path.join(oiio_dir, tool) default_path = find_executable(os.path.join(oiio_dir, tool))
if _oiio_executable_validation(default_path): if default_path and _oiio_executable_validation(default_path):
tool_executable_path = default_path tool_executable_path = default_path
# Look to PATH for the tool # Look to PATH for the tool