82 lines
2.3 KiB
Python
82 lines
2.3 KiB
Python
import os
|
|
import subprocess
|
|
|
|
from ..console_write import console_write
|
|
from ..cmd import create_cmd
|
|
from .non_clean_exit_error import NonCleanExitError
|
|
from .binary_not_found_error import BinaryNotFoundError
|
|
|
|
|
|
class CliDownloader(object):
|
|
"""
|
|
Base for downloaders that use a command line program
|
|
|
|
:param settings:
|
|
A dict of the various Package Control settings. The Sublime Text
|
|
Settings API is not used because this code is run in a thread.
|
|
"""
|
|
|
|
def __init__(self, settings):
|
|
self.settings = settings
|
|
|
|
def clean_tmp_file(self):
|
|
if os.path.exists(self.tmp_file):
|
|
os.remove(self.tmp_file)
|
|
|
|
def find_binary(self, name):
|
|
"""
|
|
Finds the given executable name in the system PATH
|
|
|
|
:param name:
|
|
The exact name of the executable to find
|
|
|
|
:return:
|
|
The absolute path to the executable
|
|
|
|
:raises:
|
|
BinaryNotFoundError when the executable can not be found
|
|
"""
|
|
|
|
dirs = os.environ['PATH'].split(os.pathsep)
|
|
if os.name != 'nt':
|
|
# This is mostly for OS X, which seems to launch ST with a
|
|
# minimal set of environmental variables
|
|
dirs.append('/usr/local/bin')
|
|
|
|
for dir_ in dirs:
|
|
path = os.path.join(dir_, name)
|
|
if os.path.exists(path):
|
|
return path
|
|
|
|
raise BinaryNotFoundError('The binary %s could not be located' % name)
|
|
|
|
def execute(self, args):
|
|
"""
|
|
Runs the executable and args and returns the result
|
|
|
|
:param args:
|
|
A list of the executable path and all arguments to be passed to it
|
|
|
|
:return:
|
|
The text output of the executable
|
|
|
|
:raises:
|
|
NonCleanExitError when the executable exits with an error
|
|
"""
|
|
|
|
if self.settings.get('debug'):
|
|
console_write(u"Trying to execute command %s" % create_cmd(args), True)
|
|
|
|
proc = subprocess.Popen(args, stdin=subprocess.PIPE,
|
|
stdout=subprocess.PIPE, stderr=subprocess.PIPE)
|
|
|
|
output = proc.stdout.read()
|
|
self.stderr = proc.stderr.read()
|
|
returncode = proc.wait()
|
|
if returncode != 0:
|
|
error = NonCleanExitError(returncode)
|
|
error.stderr = self.stderr
|
|
error.stdout = output
|
|
raise error
|
|
return output
|