Commit fbda8004 authored by Xavier Thompson's avatar Xavier Thompson

[feat] Enable build of pyproject.toml projects

Enable zc.buildout.easy_install.build, which builds a project manually
from an unpacked sdist archive and is used by zc.recipe.egg:custom, to
build a project which only has a pyproject.toml but no setup.py.
parent 43f6fee7
...@@ -939,35 +939,41 @@ class Installer(object): ...@@ -939,35 +939,41 @@ class Installer(object):
try: try:
setuptools.archive_util.unpack_archive(dist.location, setuptools.archive_util.unpack_archive(dist.location,
build_tmp) build_tmp)
if os.path.exists(os.path.join(build_tmp, 'setup.py')):
base = build_tmp # Find pyproject.toml or setup.py
for filename in ('pyproject.toml', 'setup.py'):
if os.path.exists(os.path.join(build_tmp, filename)):
base = build_tmp
break
else: else:
setups = glob.glob( for filename in ('pyproject.toml', 'setup.py'):
os.path.join(build_tmp, '*', 'setup.py')) setups = glob.glob(
if not setups: os.path.join(build_tmp, '*', filename))
raise distutils.errors.DistutilsError( if setups:
"Couldn't find a setup script in %s" if len(setups) > 1:
% os.path.basename(dist.location) raise distutils.errors.DistutilsError(
) "Multiple %s in %s" % (
if len(setups) > 1: filename, os.path.basename(dist.location)))
base = os.path.dirname(setups[0])
break
else:
raise distutils.errors.DistutilsError( raise distutils.errors.DistutilsError(
"Multiple setup scripts in %s" "Couldn't find a pyproject.toml nor setup.py in %s"
% os.path.basename(dist.location) % os.path.basename(dist.location)
) )
base = os.path.dirname(setups[0])
setup_cfg_dict = {'build_ext':build_ext} # Apply patches.
patch_dict = (patch_dict or {}).get(re.sub('[<>=].*', '', spec))
if patch_dict: if patch_dict:
setup_cfg_dict.update( patch_dict = patch_dict.get(re.sub('[<>=].*', '', spec))
{'egg_info':{'tag_build':'+%s%03d' % (PATCH_MARKER,
patch_dict['patch_revision'])}})
for i, patch in enumerate(patch_dict['patches']): for i, patch in enumerate(patch_dict['patches']):
url, md5sum = (patch.strip().split('#', 1) + [''])[:2] url, md5sum = (patch.strip().split('#', 1) + [''])[:2]
download = zc.buildout.download.Download() download = zc.buildout.download.Download()
path, is_temp = download(url, md5sum=md5sum or None, path, is_temp = download(
path=os.path.join(tmp, 'patch.%s' % i)) url,
args = [patch_dict['patch_binary']] + patch_dict['patch_options'] md5sum=md5sum or None,
path=os.path.join(tmp, 'patch.%s' % i))
args = [patch_dict['patch_binary']]
args.extend(patch_dict['patch_options'])
kwargs = {'cwd':base, kwargs = {'cwd':base,
'stdin':open(path)} 'stdin':open(path)}
popen = subprocess.Popen(args, **kwargs) popen = subprocess.Popen(args, **kwargs)
...@@ -975,12 +981,44 @@ class Installer(object): ...@@ -975,12 +981,44 @@ class Installer(object):
if popen.returncode != 0: if popen.returncode != 0:
raise subprocess.CalledProcessError( raise subprocess.CalledProcessError(
popen.returncode, ' '.join(args)) popen.returncode, ' '.join(args))
setup_cfg = os.path.join(base, 'setup.cfg')
if not os.path.exists(setup_cfg): # Attempt to determine whether setuptools is used.
f = open(setup_cfg, 'w') def uses_setuptools():
f.close() if filename == 'setup.py':
setuptools.command.setopt.edit_config( return True
setup_cfg, setup_cfg_dict) for setup in ('setup.py', 'setup.cfg'):
if os.path.exists(os.path.join(base, setup)):
return True
with open(os.path.join(base, 'pyproject.toml')) as f:
config = f.read()
pattern = "^build-backend\s*=\s*['\"]+setuptools"
if re.search(pattern, config, re.MULTILINE):
return True
return False
# Edit setup.cfg if required; warn if setuptools is not used.
if uses_setuptools():
setup_cfg_dict = {'build_ext': build_ext}
if patch_dict:
# TODO: find alternative for without setuptools.
setup_cfg_dict.update(
{'egg_info':{'tag_build':'+%s%03d' % (
PATCH_MARKER,
patch_dict['patch_revision'])}})
setup_cfg = os.path.join(base, 'setup.cfg')
if not os.path.exists(setup_cfg):
with open(setup_cfg, 'w'):
pass
setuptools.command.setopt.edit_config(
setup_cfg, setup_cfg_dict)
else:
if build_ext or patch_dict:
logger.warning(
"Build options call for editing setup.cfg "
"but project %s does not use setuptools. "
"Proceeding without."
% dist
)
dists = self._call_pip_wheel(base, self._dest, dist) dists = self._call_pip_wheel(base, self._dest, dist)
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment