Skip to content
This repository has been archived by the owner on Sep 20, 2024. It is now read-only.

General: Custom function for find executable #2822

Merged
merged 7 commits into from
Mar 8, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 0 additions & 5 deletions openpype/hosts/maya/plugins/publish/extract_look.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@
import sys
import json
import tempfile
import platform
import contextlib
import subprocess
from collections import OrderedDict
Expand Down Expand Up @@ -64,10 +63,6 @@ def maketx(source, destination, *args):

maketx_path = get_oiio_tools_path("maketx")

if platform.system().lower() == "windows":
# Ensure .exe extension
maketx_path += ".exe"

if not os.path.exists(maketx_path):
print(
"OIIO tool not found in {}".format(maketx_path))
Expand Down
17 changes: 9 additions & 8 deletions openpype/lib/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,14 @@
site.addsitedir(python_version_dir)


from .vendor_bin_utils import (
find_executable,
get_vendor_bin_path,
get_oiio_tools_path,
get_ffmpeg_tool_path,
ffprobe_streams,
is_oiio_supported
)
from .env_tools import (
env_value_to_bool,
get_paths_from_environ,
Expand Down Expand Up @@ -48,14 +56,6 @@

from .config import get_datetime_data

from .vendor_bin_utils import (
get_vendor_bin_path,
get_oiio_tools_path,
get_ffmpeg_tool_path,
ffprobe_streams,
is_oiio_supported
)

from .python_module_tools import (
import_filepath,
modules_from_path,
Expand Down Expand Up @@ -184,6 +184,7 @@
terminal = Terminal

__all__ = [
"find_executable",
"get_openpype_execute_args",
"get_pype_execute_args",
"get_linux_launcher_args",
Expand Down
9 changes: 5 additions & 4 deletions openpype/lib/applications.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,6 @@
import collections
import inspect
import subprocess
import distutils.spawn
from abc import ABCMeta, abstractmethod

import six
Expand Down Expand Up @@ -35,8 +34,10 @@
modules_from_path,
classes_from_module
)
from .execute import get_linux_launcher_args

from .execute import (
find_executable,
get_linux_launcher_args
)

_logger = None

Expand Down Expand Up @@ -646,7 +647,7 @@ def as_args(self):
def _realpath(self):
"""Check if path is valid executable path."""
# Check for executable in PATH
result = distutils.spawn.find_executable(self.executable_path)
result = find_executable(self.executable_path)
if result is not None:
return result

Expand Down
4 changes: 2 additions & 2 deletions openpype/lib/execute.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,9 @@
import platform
import json
import tempfile
import distutils.spawn

from .log import PypeLogger as Logger
from .vendor_bin_utils import find_executable

# MSDN process creation flag (Windows only)
CREATE_NO_WINDOW = 0x08000000
Expand Down Expand Up @@ -341,7 +341,7 @@ def get_linux_launcher_args(*args):
os.path.dirname(openpype_executable),
filename
)
executable_path = distutils.spawn.find_executable(new_executable)
executable_path = find_executable(new_executable)
if executable_path is None:
return None
launch_args = [executable_path]
Expand Down
92 changes: 83 additions & 9 deletions openpype/lib/vendor_bin_utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,87 @@
import json
import platform
import subprocess
import distutils

log = logging.getLogger("FFmpeg utils")
log = logging.getLogger("Vendor utils")


def is_file_executable(filepath):
"""Filepath lead to executable file.

Args:
filepath(str): Full path to file.
"""
if not filepath:
return False

if os.path.isfile(filepath):
if os.access(filepath, os.X_OK):
return True

log.info(
"Filepath is not available for execution \"{}\"".format(filepath)
)
return False


def find_executable(executable):
"""Find full path to executable.

Also tries additional extensions if passed executable does not contain one.

Paths where it is looked for executable is defined by 'PATH' environment
variable, 'os.confstr("CS_PATH")' or 'os.defpath'.

Args:
executable(str): Name of executable with or without extension. Can be
path to file.

Returns:
str: Full path to executable with extension (is file).
None: When the executable was not found.
"""
# Skip if passed path is file
if is_file_executable(executable):
return executable

low_platform = platform.system().lower()
_, ext = os.path.splitext(executable)

# Prepare variants for which it will be looked
variants = [executable]
# Add other extension variants only if passed executable does not have one
if not ext:
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:
variant = executable + ext
if is_file_executable(variant):
return variant
variants.append(variant)

# Get paths where to look for executable
path_str = os.environ.get("PATH", None)
if path_str is None:
if hasattr(os, "confstr"):
path_str = os.confstr("CS_PATH")
elif hasattr(os, "defpath"):
path_str = os.defpath

if path_str:
paths = path_str.split(os.pathsep)
for path in paths:
for variant in variants:
filepath = os.path.abspath(os.path.join(path, variant))
if is_file_executable(filepath):
return filepath
return None


def get_vendor_bin_path(bin_app):
Expand Down Expand Up @@ -41,11 +119,7 @@ def get_oiio_tools_path(tool="oiiotool"):
Default is "oiiotool".
"""
oiio_dir = get_vendor_bin_path("oiio")
if platform.system().lower() == "windows" and not tool.lower().endswith(
".exe"
):
tool = "{}.exe".format(tool)
return os.path.join(oiio_dir, tool)
return find_executable(os.path.join(oiio_dir, tool))


def get_ffmpeg_tool_path(tool="ffmpeg"):
Expand All @@ -61,7 +135,7 @@ def get_ffmpeg_tool_path(tool="ffmpeg"):
ffmpeg_dir = get_vendor_bin_path("ffmpeg")
if platform.system().lower() == "windows":
ffmpeg_dir = os.path.join(ffmpeg_dir, "bin")
return os.path.join(ffmpeg_dir, tool)
return find_executable(os.path.join(ffmpeg_dir, tool))


def ffprobe_streams(path_to_file, logger=None):
Expand Down Expand Up @@ -122,7 +196,7 @@ def is_oiio_supported():
"""
loaded_path = oiio_path = get_oiio_tools_path()
if oiio_path:
oiio_path = distutils.spawn.find_executable(oiio_path)
oiio_path = find_executable(oiio_path)

if not oiio_path:
log.debug("OIIOTool is not configured or not present at {}".format(
Expand Down