# -*- coding: utf-8 -*-
"""Functions for handling executables"""
import logging
import os
import os.path
logger = logging.getLogger(__name__)
[docs]
def check_executable(executable):
"""Check that an executable exists.
Check that an executable exists and is executable. If no path is
given, but just the executable name, then the current path is
checked. If the executable is missing or not actually executable
this function raises a useful error with a message letting the
user know where the path came from -- a command line option, an
environment variable, configuration file, or default.
Parameters:
executable -- required positional parameter giving the name of
the executable as a string. It can be a simple name or contain
a path to the executable.
Returns:
The string for the path to the executable. If it was found on the path,
the full path is returned, otherwise the return is the same as the
executable string passed in.
Errors:
FileNotFoundError if the executable is not found or is not executable.
The message contains information about where the option came from,
either the command-line, an environment variable, configuration
file or the default.
"""
if os.path.dirname(executable) == "":
# A simple name without a directory part was given, so see if the
# executable exists in the path.
path = os.get_exec_path()
exes = []
for dir in path:
exe = os.path.join(dir, executable)
if os.path.isfile(exe):
if os.access(exe, os.X_OK):
return exe
else:
exes.append(exe)
msg = "The executable '{}' was not found in the path:\n\t".format(executable)
msg += "\n\t".join(path)
msg += "\n"
if len(exes) > 0:
msg += (
"However, the following files were found, but were not "
"executable:\n\t"
)
msg += "\n\t".join(exes)
msg += "\n"
else:
# A path before the executable name was given, so try as is
if os.path.isfile(executable):
if os.access(executable, os.X_OK):
return executable
else:
msg = "The executable '{}' exists, but is not executable!\n".format(
executable
)
else:
msg = "The executable '{}' does not exist!\n".format(executable)
raise FileNotFoundError(msg)