| # coding: utf-8 |
| from __future__ import unicode_literals, division, absolute_import, print_function |
| |
| import imp |
| import os |
| import subprocess |
| import sys |
| import warnings |
| import shutil |
| import tempfile |
| import platform |
| import site |
| |
| |
| OTHER_PACKAGES = [ |
| 'https://github.com/wbond/oscrypto.git', |
| 'https://github.com/wbond/certbuilder.git', |
| 'https://github.com/wbond/certvalidator.git', |
| 'https://github.com/wbond/crlbuilder.git', |
| 'https://github.com/wbond/csrbuilder.git', |
| 'https://github.com/wbond/ocspbuilder.git', |
| ] |
| |
| |
| def run(): |
| """ |
| Ensures a recent version of pip is installed, then uses that to install |
| required development dependencies. Uses git to checkout other modularcrypto |
| repos for more accurate coverage data. |
| """ |
| |
| package_root = os.path.abspath(os.path.join(os.path.dirname(__file__), '..')) |
| build_root = os.path.abspath(os.path.join(package_root, '..')) |
| try: |
| tmpdir = None |
| with warnings.catch_warnings(): |
| warnings.simplefilter("ignore") |
| |
| major_minor = '%s.%s' % sys.version_info[0:2] |
| tmpdir = tempfile.mkdtemp() |
| _pip = _bootstrap_pip(tmpdir) |
| |
| print("Using pip to install dependencies") |
| _pip(['install', '-q', '--upgrade', '-r', os.path.join(package_root, 'requires', 'ci')]) |
| |
| if OTHER_PACKAGES: |
| print("Checking out modularcrypto packages for coverage") |
| for pkg_url in OTHER_PACKAGES: |
| pkg_name = os.path.basename(pkg_url).replace('.git', '') |
| pkg_dir = os.path.join(build_root, pkg_name) |
| if os.path.exists(pkg_dir): |
| print("%s is already present" % pkg_name) |
| continue |
| print("Cloning %s" % pkg_url) |
| _execute(['git', 'clone', pkg_url], build_root) |
| print() |
| |
| finally: |
| if tmpdir: |
| shutil.rmtree(tmpdir, ignore_errors=True) |
| |
| return True |
| |
| def _download(url, dest): |
| """ |
| Downloads a URL to a directory |
| |
| :param url: |
| The URL to download |
| |
| :param dest: |
| The path to the directory to save the file in |
| |
| :return: |
| The filesystem path to the saved file |
| """ |
| |
| filename = os.path.basename(url) |
| dest_path = os.path.join(dest, filename) |
| |
| if sys.platform == 'win32': |
| system_root = os.environ.get('SystemRoot') |
| powershell_exe = os.path.join('system32\\WindowsPowerShell\\v1.0\\powershell.exe') |
| code = "[System.Net.ServicePointManager]::SecurityProtocol = [System.Net.SecurityProtocolType]::Tls12;" |
| code += " (New-Object Net.WebClient).DownloadFile('%s', '%s');" % (url, dest_path) |
| _execute([powershell_exe, '-Command', code], dest) |
| |
| else: |
| _execute(['curl', '--silent', '--show-error', '-O', url], dest) |
| |
| return dest_path |
| |
| |
| def _execute(params, cwd): |
| """ |
| Executes a subprocess |
| |
| :param params: |
| A list of the executable and arguments to pass to it |
| |
| :param cwd: |
| The working directory to execute the command in |
| |
| :return: |
| A 2-element tuple of (stdout, stderr) |
| """ |
| |
| proc = subprocess.Popen( |
| params, |
| stdout=subprocess.PIPE, |
| stderr=subprocess.PIPE, |
| cwd=cwd |
| ) |
| stdout, stderr = proc.communicate() |
| code = proc.wait() |
| if code != 0: |
| e = OSError('subprocess exit code was non-zero') |
| e.stdout = stdout |
| e.stderr = stderr |
| raise e |
| return (stdout, stderr) |
| |
| |
| def _get_pip_main(download_dir): |
| """ |
| Executes get-pip.py in the current Python interpreter |
| |
| :param download_dir: |
| The directory that contains get-pip.py |
| """ |
| |
| module_info = imp.find_module('get-pip', [download_dir]) |
| get_pip_module = imp.load_module('_cideps.get-pip', *module_info) |
| |
| orig_sys_exit = sys.exit |
| orig_sys_argv = sys.argv |
| sys.exit = lambda c: None |
| sys.argv = ['get-pip.py', '--user', '-q'] |
| |
| get_pip_module.main() |
| |
| sys.exit = orig_sys_exit |
| sys.argv = orig_sys_argv |
| |
| # Unload pip modules that came from the zip file |
| module_names = sorted(sys.modules.keys()) |
| end_token = os.sep + 'pip.zip' |
| mid_token = end_token + os.sep + 'pip' |
| for module_name in module_names: |
| try: |
| module_path = sys.modules[module_name].__file__ |
| if mid_token in module_path or module_path.endswith(end_token): |
| del sys.modules[module_name] |
| except AttributeError: |
| pass |
| |
| if sys.path[0].endswith('pip.zip'): |
| sys.path = sys.path[1:] |
| |
| if site.USER_SITE not in sys.path: |
| sys.path.append(site.USER_SITE) |
| |
| |
| def _bootstrap_pip(tmpdir): |
| """ |
| Bootstraps the current version of pip for use in the current Python |
| interpreter |
| |
| :param tmpdir: |
| A temporary directory to download get-pip.py and cacert.pem |
| |
| :return: |
| A function that invokes pip. Accepts one arguments, a list of parameters |
| to pass to pip. |
| """ |
| |
| try: |
| import pip |
| |
| print('Upgrading pip') |
| pip.main(['install', '-q', '--upgrade', 'pip']) |
| certs_path = None |
| |
| except ImportError: |
| print("Downloading cacert.pem from curl") |
| certs_path = _download('https://curl.haxx.se/ca/cacert.pem', tmpdir) |
| |
| print("Downloading get-pip.py") |
| if sys.version_info[0:2] == (3, 2): |
| path = _download('https://bootstrap.pypa.io/3.2/get-pip.py', tmpdir) |
| else: |
| path = _download('https://bootstrap.pypa.io/get-pip.py', tmpdir) |
| |
| print("Running get-pip.py") |
| _get_pip_main(tmpdir) |
| |
| import pip |
| |
| def _pip(args): |
| base_args = ['--disable-pip-version-check'] |
| if certs_path: |
| base_args += ['--cert', certs_path] |
| if sys.platform == 'darwin' and sys.version_info[0:2] in [(2, 6), (2, 7)]: |
| new_args = [] |
| for arg in args: |
| new_args.append(arg) |
| if arg == 'install': |
| new_args.append('--user') |
| args = new_args |
| pip.main(base_args + args) |
| |
| return _pip |