Add before_build option, that runs a shell command before 'pip wheel'

This commit is contained in:
Joe Rickerby
2017-04-10 21:42:12 +01:00
parent 56f9a37165
commit 2679cb7f46
9 changed files with 147 additions and 22 deletions
+38 -18
View File
@@ -3,6 +3,24 @@ import argparse, os, subprocess, sys
from cibuildwheel import linux, windows, macos
def get_option_from_environment(option_name, platform=None):
'''
Returns an option from the environment, optionally scoped by the platform.
Example:
get_option_from_environment('CIBW_COLOR', platform='macos')
This will return the value of CIBW_COLOR_MACOS if it exists, otherwise the value of
CIBW_COLOR.
'''
if platform:
option = os.environ.get('%s_%s' % (option_name, platform.upper()))
if option is not None:
return option
return os.environ.get(option_name)
def main():
parser = argparse.ArgumentParser(
description='Build wheels for all the platforms.',
@@ -29,10 +47,28 @@ def main():
args = parser.parse_args()
if args.platform != 'auto':
platform = args.platform
else:
if os.environ.get('TRAVIS_OS_NAME') == 'linux':
platform = 'linux'
elif os.environ.get('TRAVIS_OS_NAME') == 'osx':
platform = 'macos'
elif 'APPVEYOR' in os.environ:
platform = 'windows'
else:
print('Unable to detect platform. cibuildwheel should run on your CI server, '
'Travis CI and Appveyor are supported. You can run on your development '
'machine using the --platform argument. Check --help output for more '
'information.',
file=sys.stderr)
exit(2)
output_dir = args.output_dir
test_command = os.environ.get('CIBW_TEST_COMMAND', None)
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)
try:
project_setup_py = os.path.join(project_dir, 'setup.py')
@@ -58,26 +94,10 @@ def main():
package_name=package_name,
output_dir=output_dir,
test_command=test_command,
test_requires=test_requires
test_requires=test_requires,
before_build=before_build,
)
if args.platform != 'auto':
platform = args.platform
else:
if os.environ.get('TRAVIS_OS_NAME') == 'linux':
platform = 'linux'
elif os.environ.get('TRAVIS_OS_NAME') == 'osx':
platform = 'macos'
elif 'APPVEYOR' in os.environ:
platform = 'windows'
else:
print('Unable to detect platform. cibuildwheel should run on your CI server, '
'Travis CI and Appveyor are supported. You can run on your development '
'machine using the --platform argument. Check --help output for more '
'information.',
file=sys.stderr)
exit(2)
if platform == 'linux':
linux.build(**build_args)
elif platform == 'windows':
+12 -2
View File
@@ -1,5 +1,6 @@
from __future__ import print_function
import os, subprocess
from .util import prepare_command
try:
from shlex import quote as shlex_quote
@@ -7,7 +8,7 @@ except ImportError:
from pipes import quote as shlex_quote
def build(project_dir, package_name, output_dir, test_command, test_requires):
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']:
bash_script = '''
set -o errexit
@@ -15,6 +16,10 @@ def build(project_dir, package_name, output_dir, test_command, test_requires):
cd /project
for PYBIN in /opt/python/*/bin; do
if [ ! -z {before_build} ]; then
PATH=$PYBIN:$PATH sh -c {before_build}
fi
"$PYBIN/pip" wheel . -w /tmp/linux_wheels
done
@@ -42,7 +47,12 @@ def build(project_dir, package_name, output_dir, test_command, test_requires):
'''.format(
package_name=package_name,
test_requires=' '.join(test_requires),
test_command=shlex_quote(test_command.format(project='/project') if test_command else ''),
test_command=shlex_quote(
test_command.format(project='/project') if test_command else ''
),
before_build=shlex_quote(
prepare_command(before_build, python='python', pip='pip') if before_build else ''
),
)
docker_process = subprocess.Popen([
+8 -1
View File
@@ -7,8 +7,10 @@ try:
except ImportError:
from pipes import quote as shlex_quote
from .util import prepare_command
def build(project_dir, package_name, output_dir, test_command, test_requires):
def build(project_dir, package_name, output_dir, test_command, test_requires, before_build):
PythonConfiguration = namedtuple('PythonConfiguration', ['version', 'url'])
python_configurations = [
PythonConfiguration(version='2.7', url='https://www.python.org/ftp/python/2.7.13/python-2.7.13-macosx10.6.pkg'),
@@ -47,6 +49,11 @@ def build(project_dir, package_name, output_dir, test_command, test_requires):
shell([pip, 'install', 'wheel'], env=env)
shell([pip, 'install', 'delocate'], env=env)
# run the before_build command
if before_build:
before_build_prepared = prepare_command(before_build, python=python, pip=pip)
shell(shlex.split(before_build_prepared), env=env)
# build the wheel to temp dir
temp_wheel_dir = '/tmp/tmpwheel%s' % config.version
shell([pip, 'wheel', project_dir, '-w', temp_wheel_dir], env=env)
+11
View File
@@ -0,0 +1,11 @@
def prepare_command(command, python, pip):
'''
Preprocesses a command by expanding variables like {python} or {pip}.
For example, used for the before_build option, where the user would
like to run a command like `python setup.py test`. If the command should run on
Python 3, the user could write `{python} setup.py test`. This command would expand
it out to python2 or python3 as appropriate.
'''
return command.format(python=python, pip=pip)
+8 -1
View File
@@ -2,8 +2,10 @@ from __future__ import print_function
import os, tempfile, subprocess, urllib2
from collections import namedtuple
from .util import prepare_command
def build(project_dir, package_name, output_dir, test_command, test_requires):
def build(project_dir, package_name, output_dir, test_command, test_requires, before_build):
# run_with_env is a cmd file that sets the right environment variables to
run_with_env = os.path.join(tempfile.gettempdir(), 'appveyor_run_with_env.cmd')
if not os.path.exists(run_with_env):
@@ -51,6 +53,11 @@ def build(project_dir, package_name, output_dir, test_command, test_requires):
env=env)
shell(['pip', 'install', 'wheel'], env=env)
# run the before_build command
if before_build:
before_build_prepared = prepare_command(before_build, python='python', pip='pip')
shell([before_build_prepared], env=env)
# build the wheel
shell(['pip', 'wheel', project_dir, '-w', output_dir], env=env)