from functools import wraps from tempfile import mkdtemp from shutil import rmtree from subprocess import check_output, CalledProcessError from sys import exit VERBOSE = True def call_verbose(before_message='', after_message='Done!'): def tag(f): @wraps(f) def wrapper(*args, **kwargs): print_opt(before_message, end='', flush=True) f(*args, **kwargs) print_opt(after_message) return wrapper return tag def print_opt(*args, **kwargs): if VERBOSE: print(*args, **kwargs) def yes_no_question(question, default): valid = {"yes": True, "y": True, "ye": True, "no": False, "n": False} if default is None: prompt = " [y/n] " elif default == "yes": prompt = " [Y/n] " elif default == "no": prompt = " [y/N] " else: raise ValueError("Invalid default answer: {}!".format(default)) while True: print(question + prompt) choice = input().lower() if default is not None and choice == '': return valid[default] elif choice in valid: return valid[choice] else: print("Please respond with 'yes'(y) or 'no'(n)!") # tempfile.TemporaryDirectory replacement to provide backwards compatibility class temporary_directory: def __enter__(self): self.name = mkdtemp() return self.name def __exit__(self, exc_type, exc_val, exc_tb): rmtree(self.name) def get_output(*args, **kwargs): return check_output(*args, **kwargs).decode().rstrip('\n') @call_verbose(before_message='Checking your system for dependencies... ', after_message='Found all!') def check_dependencies(check_for): error_str = '\nMissing dependencies: {}' missing = [] for command in check_for: try: check_output(command) except (CalledProcessError, FileNotFoundError): missing.append(command[0]) if missing: exit(error_str.format(', '.join(missing)))