#!/usr/bin/env python import os import sys import argparse import subprocess import warnings from importlib import import_module def main(): usage = """./tools/provision Creates a Python virtualenv. Its Python version is equal to the Python version this command is executed with.""" parser = argparse.ArgumentParser(usage=usage) parser.parse_args() base_dir = os.path.abspath(os.path.join(__file__, '..', '..')) python_interpreter = os.path.abspath(sys.executable) venv_name = 'zulip-api-py{}-venv'.format(sys.version_info.major) venv_dir = os.path.join(base_dir, venv_name) if not os.path.isdir(venv_dir): try: return_code = subprocess.call(['virtualenv', '-p', python_interpreter, venv_dir]) except OSError: if subprocess.call(['which', 'virtualenv']): print("{red}Please install the virtualenv package and try again.{end_format}" .format(red='\033[91m', end_format='\033[0m')) sys.exit(1) raise else: if return_code: raise OSError("The command `virtualenv -p {} {}` failed. Virtualenv not created!" .format(python_interpreter, venv_dir)) print("New virtualenv created.") else: print("Virtualenv already exists.") if os.path.isdir(os.path.join(venv_dir, 'Scripts')): # POSIX compatibility layer and Linux environment emulation for Windows # Virtual uses /Scripts instead of /bin on Windows. # Read https://virtualenv.pypa.io/en/stable/userguide/ venv_exec_dir = 'Scripts' else: venv_exec_dir = 'bin' # In order to install all required packages for the venv, we need to activate it. Since # the activation script sets environmental variables, it needs to be executed inline with # `import_module`. activate_module_dir = os.path.abspath(os.path.join(venv_dir, venv_exec_dir)) sys.path.append(activate_module_dir) import_module('activate_this') # In order to install all required packages for the venv, `pip` needs to be executed by # the venv's Python interpreter. `--prefix venv_dir` ensures that all modules are installed # in the right place. def install_dependencies(requirements_filename): pip_path = os.path.join(venv_dir, venv_exec_dir, 'pip') # We first install a modern version of pip that supports --prefix subprocess.call([pip_path, 'install', 'pip>=9.0']) if subprocess.call([pip_path, 'install', '--prefix', venv_dir, '-r', os.path.join(base_dir, requirements_filename)]): raise OSError("The command `pip install -r {}` failed. Dependencies not installed!" .format(os.path.join(base_dir, requirements_filename))) install_dependencies('requirements.txt') if sys.version_info > (3, 1): install_dependencies('py3_requirements.txt') else: warnings.warn("Your Python version does not support mypy. `tools/run-mypy` will fail.") print("{green}Success!{end_format} Run\n {bold}source '{activate}'{end_format}\nto activate virtualenv.".format( green='\033[92m', bold='\033[1m', end_format='\033[0m', activate=os.path.join(base_dir, venv_dir, venv_exec_dir, 'activate'))) if __name__ == '__main__': main()