From ba22589f6f48eec8a1d04ae87ede08d82e967ad4 Mon Sep 17 00:00:00 2001 From: Joe Rickerby Date: Tue, 11 Apr 2017 22:57:42 +0100 Subject: [PATCH] Implement CIBW_SKIP for linux --- README.md | 4 ++-- cibuildwheel/__main__.py | 5 +++++ cibuildwheel/linux.py | 40 ++++++++++++++++++++++++++++++++++++---- cibuildwheel/util.py | 10 ++++++++++ 4 files changed, 53 insertions(+), 6 deletions(-) diff --git a/README.md b/README.md index d8e85c55..2c5a1b6a 100644 --- a/README.md +++ b/README.md @@ -151,13 +151,13 @@ Platform-specific variants also available: Optional. -Space-separated list of builds to skip. Each build has an identifier like `cp27-linux_x86_64` or `cp34-macosx_10_6_intel` - you can list ones to skip here and `cibuildwheel` won't try to build them. +Space-separated list of builds to skip. Each build has an identifier like `cp27-manylinux1_x86_64` or `cp34-macosx_10_6_intel` - you can list ones to skip here and `cibuildwheel` won't try to build them. The format is `python_tag-platform_tag`. The tags are as defined in [PEP 0425](https://www.python.org/dev/peps/pep-0425/#details). Python tags look like `cp27` `cp34` `cp35` `cp36` -Platform tags look like `macosx_10_6_intel` `linux_x86_64` `linux_i386` `win32` `win_amd64` +Platform tags look like `macosx_10_6_intel` `manylinux1_x86_64` `manylinux1_i386` `win32` `win_amd64` You can also use shell-style globbing syntax (as per `fnmatch`) diff --git a/cibuildwheel/__main__.py b/cibuildwheel/__main__.py index 348d486e..c574b442 100644 --- a/cibuildwheel/__main__.py +++ b/cibuildwheel/__main__.py @@ -2,6 +2,7 @@ from __future__ import print_function import argparse, os, subprocess, sys from cibuildwheel import linux, windows, macos +from cibuildwheel.util import BuildSkipper def get_option_from_environment(option_name, platform=None): ''' @@ -69,6 +70,9 @@ def main(): test_requires = os.environ.get('CIBW_TEST_REQUIRES', '').split() project_dir = args.project_dir before_build = get_option_from_environment('CIBW_BEFORE_BUILD', platform=platform) + skip_config = os.environ.get('CIBW_SKIP', '') + + skip = BuildSkipper(skip_config) try: project_setup_py = os.path.join(project_dir, 'setup.py') @@ -96,6 +100,7 @@ def main(): test_command=test_command, test_requires=test_requires, before_build=before_build, + skip=skip, ) if platform == 'linux': diff --git a/cibuildwheel/linux.py b/cibuildwheel/linux.py index 057cd510..82bfe07f 100644 --- a/cibuildwheel/linux.py +++ b/cibuildwheel/linux.py @@ -1,5 +1,6 @@ from __future__ import print_function import os, subprocess +from collections import namedtuple from .util import prepare_command try: @@ -8,14 +9,44 @@ except ImportError: from pipes import quote as shlex_quote -def build(project_dir, package_name, output_dir, test_command, test_requires, before_build): - for docker_image in ['quay.io/pypa/manylinux1_x86_64', 'quay.io/pypa/manylinux1_i686']: +def build(project_dir, package_name, output_dir, test_command, test_requires, before_build, skip): + PythonConfiguration = namedtuple('PythonConfiguration', ['identifier', 'path']) + python_configurations = [ + PythonConfiguration(identifier='cp26-manylinux1_x86_64', path='/opt/python/cp26-cp26m'), + PythonConfiguration(identifier='cp26-manylinux1_x86_64', path='/opt/python/cp26-cp26mu'), + PythonConfiguration(identifier='cp27-manylinux1_x86_64', path='/opt/python/cp27-cp27m'), + PythonConfiguration(identifier='cp27-manylinux1_x86_64', path='/opt/python/cp27-cp27mu'), + PythonConfiguration(identifier='cp33-manylinux1_x86_64', path='/opt/python/cp33-cp33m'), + PythonConfiguration(identifier='cp34-manylinux1_x86_64', path='/opt/python/cp34-cp34m'), + PythonConfiguration(identifier='cp35-manylinux1_x86_64', path='/opt/python/cp35-cp35m'), + PythonConfiguration(identifier='cp36-manylinux1_x86_64', path='/opt/python/cp36-cp36m'), + PythonConfiguration(identifier='cp26-manylinux1_i686', path='/opt/python/cp26-cp26m'), + PythonConfiguration(identifier='cp26-manylinux1_i686', path='/opt/python/cp26-cp26mu'), + PythonConfiguration(identifier='cp27-manylinux1_i686', path='/opt/python/cp27-cp27m'), + PythonConfiguration(identifier='cp27-manylinux1_i686', path='/opt/python/cp27-cp27mu'), + PythonConfiguration(identifier='cp33-manylinux1_i686', path='/opt/python/cp33-cp33m'), + PythonConfiguration(identifier='cp34-manylinux1_i686', path='/opt/python/cp34-cp34m'), + PythonConfiguration(identifier='cp35-manylinux1_i686', path='/opt/python/cp35-cp35m'), + PythonConfiguration(identifier='cp36-manylinux1_i686', path='/opt/python/cp36-cp36m'), + ] + + # skip builds as required + python_configurations = [c for c in python_configurations if not skip(c.identifier)] + + platforms = [ + ('manylinux1_x86_64', 'quay.io/pypa/manylinux1_x86_64'), + ('manylinux1_i686', 'quay.io/pypa/manylinux1_i686'), + ] + + for platform_tag, docker_image in platforms: + platform_configs = [c for c in python_configurations if c.identifier.endswith(platform_tag)] + bash_script = ''' set -o errexit set -o xtrace cd /project - for PYBIN in /opt/python/*/bin; do + for PYBIN in {pybin_paths}; do if [ ! -z {before_build} ]; then PATH=$PYBIN:$PATH sh -c {before_build} fi @@ -28,7 +59,7 @@ def build(project_dir, package_name, output_dir, test_command, test_requires, be done # Install packages and test - for PYBIN in /opt/python/*/bin/; do + for PYBIN in {pybin_paths}; do # Install the wheel we just built "$PYBIN/pip" install {package_name} --no-index -f /output @@ -46,6 +77,7 @@ def build(project_dir, package_name, output_dir, test_command, test_requires, be done '''.format( package_name=package_name, + pybin_paths=' '.join(c.path+'/bin' for c in platform_configs), test_requires=' '.join(test_requires), test_command=shlex_quote( test_command.format(project='/project') if test_command else '' diff --git a/cibuildwheel/util.py b/cibuildwheel/util.py index c93a17c4..b660831f 100644 --- a/cibuildwheel/util.py +++ b/cibuildwheel/util.py @@ -1,3 +1,5 @@ +from fnmatch import fnmatch + def prepare_command(command, python, pip): ''' @@ -9,3 +11,11 @@ def prepare_command(command, python, pip): it out to python2 or python3 as appropriate. ''' return command.format(python=python, pip=pip) + + +class BuildSkipper(object): + def __init__(self, skip_config): + self.patterns = skip_config.split() + + def __call__(self, build_id): + return any(fnmatch(build_id, pattern) for pattern in self.patterns)