import os, os.path, subprocess, shutil try: from urllib.request import urlopen except ImportError: from urllib import urlopen python_versions = ['2.6.8', '2.7.5', '3.1.5', '3.2.5', '3.3.5', '3.4.1'] libcurl_versions = ['7.19.0', '7.46.0'] libcurl_meta = { '7.19.0': { 'patches': [ 'curl-7.19.0-sslv2-c66b0b32fba-modified.patch', #'curl-7.19.0-sslv2-2b0e09b0f98.patch', ], }, } root = os.path.abspath(os.path.dirname(__file__)) class in_dir: def __init__(self, dir): self.dir = dir def __enter__(self): self.oldwd = os.getcwd() os.chdir(self.dir) def __exit__(self, type, value, traceback): os.chdir(self.oldwd) def subprocess_check_call(cmd, **kwargs): try: subprocess.check_call(cmd, **kwargs) except OSError as exc: message = exc.args[0] message = '%s while trying to execute %s' % (message, str(cmd)) args = tuple([message] + exc.args[1:]) raise type(exc)(args) def fetch(url, archive=None): if archive is None: archive = os.path.basename(url) if not os.path.exists(archive): sys.stdout.write("Fetching %s\n" % url) io = urlopen(url) with open('.tmp.%s' % archive, 'wb') as f: while True: chunk = io.read(65536) if len(chunk) == 0: break f.write(chunk) os.rename('.tmp.%s' % archive, archive) def build(archive, dir, prefix, meta=None): if not os.path.exists(dir): sys.stdout.write("Building %s\n" % archive) subprocess_check_call(['tar', 'xf', archive]) with in_dir(dir): if meta and 'patches' in meta: for patch in meta['patches']: patch_path = os.path.join(root, 'matrix', patch) subprocess_check_call(['patch', '-p1', '-i', patch_path]) subprocess_check_call(['./configure', '--prefix=%s' % prefix]) if 'post-configure' in meta: for cmd in meta['post-configure']: subprocess_check_call(cmd, shell=True) subprocess_check_call(['make']) subprocess_check_call(['make', 'install']) def run_matrix(python_versions, libcurl_versions): for python_version in python_versions: url = 'http://www.python.org/ftp/python/%s/Python-%s.tgz' % (python_version, python_version) archive = os.path.basename(url) fetch(url, archive) dir = archive.replace('.tgz', '') prefix = os.path.abspath('i/%s' % dir) build(archive, dir, prefix) for libcurl_version in libcurl_versions: url = 'https://curl.haxx.se/download/curl-%s.tar.gz' % libcurl_version archive = os.path.basename(url) fetch(url, archive) dir = archive.replace('.tar.gz', '') prefix = os.path.abspath('i/%s' % dir) build(archive, dir, prefix, meta=libcurl_meta.get(libcurl_version)) fetch('https://raw.github.com/pypa/virtualenv/1.7/virtualenv.py', 'virtualenv-1.7.py') fetch('https://raw.github.com/pypa/virtualenv/1.9.1/virtualenv.py', 'virtualenv-1.9.1.py') if not os.path.exists('venv'): os.mkdir('venv') for python_version in python_versions: python_version_pieces = [int(piece) for piece in python_version.split('.')[:2]] for libcurl_version in libcurl_versions: python_prefix = os.path.abspath('i/Python-%s' % python_version) libcurl_prefix = os.path.abspath('i/curl-%s' % libcurl_version) venv = os.path.abspath('venv/Python-%s-curl-%s' % (python_version, libcurl_version)) if os.path.exists(venv): shutil.rmtree(venv) fetch('https://pypi.python.org/packages/2.6/s/setuptools/setuptools-0.6c11-py2.6.egg') fetch('https://pypi.python.org/packages/2.7/s/setuptools/setuptools-0.6c11-py2.7.egg') # I had virtualenv 1.8.2 installed systemwide which # did not work with python 3.0: # http://stackoverflow.com/questions/1422361/why-am-i-getting-this-error-related-to-pip-and-easy-install-when-trying-to-set # so, use known versions everywhere # md5=89e68df89faf1966bcbd99a0033fbf8e fetch('https://pypi.python.org/packages/source/d/distribute/distribute-0.6.49.tar.gz') subprocess_check_call(['python', 'virtualenv-1.9.1.py', venv, '-p', '%s/bin/python%d.%d' % (python_prefix, python_version_pieces[0], python_version_pieces[1]), '--no-site-packages', '--never-download']) curl_config_path = os.path.join(libcurl_prefix, 'bin/curl-config') curl_lib_path = os.path.join(libcurl_prefix, 'lib') with in_dir('pycurl'): extra_patches = [] extra_env = [] deps_cmd = 'pip install -r requirements-dev.txt' extra_patches = ' && '.join(extra_patches) extra_env = ' '.join(extra_env) cmd = ''' make clean && . %(venv)s/bin/activate && %(deps_cmd)s && %(extra_patches)s python -V && LD_LIBRARY_PATH=%(curl_lib_path)s PYCURL_CURL_CONFIG=%(curl_config_path)s %(extra_env)s make test ''' % dict( venv=venv, deps_cmd=deps_cmd, extra_patches=extra_patches, curl_lib_path=curl_lib_path, curl_config_path=curl_config_path, extra_env=extra_env ) print(cmd) subprocess_check_call(cmd, shell=True) if __name__ == '__main__': import sys def main(): import optparse parser = optparse.OptionParser() parser.add_option('-p', '--python', help='Specify python version to test against') parser.add_option('-c', '--curl', help='Specify libcurl version to test against') options, args = parser.parse_args() if options.python: python_version = options.python if python_version in python_versions: chosen_python_versions = [python_version] else: chosen_python_versions = [v for v in python_versions if v.startswith(python_version)] if len(chosen_python_versions) != 1: raise Exception('Bogus python version requested: %s' % python_version) else: chosen_python_versions = python_versions if options.curl: chosen_libcurl_versions = [options.curl] else: chosen_libcurl_versions = libcurl_versions run_matrix(chosen_python_versions, chosen_libcurl_versions) main()