Commit 5f88c42f authored by Benoit Pierre's avatar Benoit Pierre

build_meta: fix 2 issues with `build_wheel` / `build_sdist`

Fix the following cases:

* `build_sdist` is called with another sdist already present
  in the destination directory

* `build_wheel` is called with the destination directory not
  already created
parent 97d75639
...@@ -38,6 +38,7 @@ import distutils ...@@ -38,6 +38,7 @@ import distutils
from setuptools.py31compat import TemporaryDirectory from setuptools.py31compat import TemporaryDirectory
from pkg_resources import parse_requirements from pkg_resources import parse_requirements
from pkg_resources.py31compat import makedirs
__all__ = ['get_requires_for_build_sdist', __all__ = ['get_requires_for_build_sdist',
'get_requires_for_build_wheel', 'get_requires_for_build_wheel',
...@@ -179,36 +180,38 @@ class _BuildMetaBackend(object): ...@@ -179,36 +180,38 @@ class _BuildMetaBackend(object):
return dist_infos[0] return dist_infos[0]
def build_wheel(self, wheel_directory, config_settings=None, def _build_with_temp_dir(self, setup_command, result_extension,
metadata_directory=None): result_directory, config_settings):
config_settings = self._fix_config(config_settings) config_settings = self._fix_config(config_settings)
wheel_directory = os.path.abspath(wheel_directory) result_directory = os.path.abspath(result_directory)
# Build the wheel in a temporary directory, then copy to the target # Build in a temporary directory, then copy to the target.
with TemporaryDirectory(dir=wheel_directory) as tmp_dist_dir: makedirs(result_directory, exist_ok=True)
sys.argv = (sys.argv[:1] + with TemporaryDirectory(dir=result_directory) as tmp_dist_dir:
['bdist_wheel', '--dist-dir', tmp_dist_dir] + sys.argv = (sys.argv[:1] + setup_command +
['--dist-dir', tmp_dist_dir] +
config_settings["--global-option"]) config_settings["--global-option"])
self.run_setup() self.run_setup()
wheel_basename = _file_with_extension(tmp_dist_dir, '.whl') result_basename = _file_with_extension(tmp_dist_dir, result_extension)
wheel_path = os.path.join(wheel_directory, wheel_basename) result_path = os.path.join(result_directory, result_basename)
if os.path.exists(wheel_path): if os.path.exists(result_path):
# os.rename will fail overwriting on non-unix env # os.rename will fail overwriting on non-Unix.
os.remove(wheel_path) os.remove(result_path)
os.rename(os.path.join(tmp_dist_dir, wheel_basename), wheel_path) os.rename(os.path.join(tmp_dist_dir, result_basename), result_path)
return wheel_basename return result_basename
def build_sdist(self, sdist_directory, config_settings=None):
config_settings = self._fix_config(config_settings)
sdist_directory = os.path.abspath(sdist_directory)
sys.argv = sys.argv[:1] + ['sdist', '--formats', 'gztar'] + \
config_settings["--global-option"] + \
["--dist-dir", sdist_directory]
self.run_setup()
return _file_with_extension(sdist_directory, '.tar.gz') def build_wheel(self, wheel_directory, config_settings=None,
metadata_directory=None):
return self._build_with_temp_dir(['bdist_wheel'], '.whl',
wheel_directory, config_settings)
def build_sdist(self, sdist_directory, config_settings=None):
return self._build_with_temp_dir(['sdist', '--formats', 'gztar'],
'.tar.gz', sdist_directory,
config_settings)
class _BuildMetaLegacyBackend(_BuildMetaBackend): class _BuildMetaLegacyBackend(_BuildMetaBackend):
......
...@@ -157,9 +157,10 @@ class TestBuildMetaBackend: ...@@ -157,9 +157,10 @@ class TestBuildMetaBackend:
assert os.path.isfile(os.path.join(dist_dir, wheel_name)) assert os.path.isfile(os.path.join(dist_dir, wheel_name))
def test_build_wheel_with_existing_wheel_file_present(self, tmpdir_cwd): @pytest.mark.parametrize('build_type', ('wheel', 'sdist'))
# Building a wheel should still succeed if there's already a wheel def test_build_with_existing_file_present(self, build_type, tmpdir_cwd):
# in the wheel directory # Building a sdist/wheel should still succeed if there's
# already a sdist/wheel in the destination directory.
files = { files = {
'setup.py': "from setuptools import setup\nsetup()", 'setup.py': "from setuptools import setup\nsetup()",
'VERSION': "0.0.1", 'VERSION': "0.0.1",
...@@ -177,28 +178,31 @@ class TestBuildMetaBackend: ...@@ -177,28 +178,31 @@ class TestBuildMetaBackend:
build_files(files) build_files(files)
dist_dir = os.path.abspath('pip-wheel-preexisting') dist_dir = os.path.abspath('preexisting-' + build_type)
os.makedirs(dist_dir)
# make first wheel
build_backend = self.get_build_backend() build_backend = self.get_build_backend()
wheel_one = build_backend.build_wheel(dist_dir) build_method = getattr(build_backend, 'build_' + build_type)
# Build a first sdist/wheel.
# Note: this also check the destination directory is
# successfully created if it does not exist already.
first_result = build_method(dist_dir)
# change version # Change version.
with open("VERSION", "wt") as version_file: with open("VERSION", "wt") as version_file:
version_file.write("0.0.2") version_file.write("0.0.2")
# make *second* wheel # Build a *second* sdist/wheel.
wheel_two = self.get_build_backend().build_wheel(dist_dir) second_result = build_method(dist_dir)
assert os.path.isfile(os.path.join(dist_dir, wheel_one)) assert os.path.isfile(os.path.join(dist_dir, first_result))
assert wheel_one != wheel_two assert first_result != second_result
# and if rebuilding the same wheel? # And if rebuilding the exact same sdist/wheel?
open(os.path.join(dist_dir, wheel_two), 'w').close() open(os.path.join(dist_dir, second_result), 'w').close()
wheel_three = self.get_build_backend().build_wheel(dist_dir) third_result = build_method(dist_dir)
assert wheel_three == wheel_two assert third_result == second_result
assert os.path.getsize(os.path.join(dist_dir, wheel_three)) > 0 assert os.path.getsize(os.path.join(dist_dir, third_result)) > 0
def test_build_sdist(self, build_backend): def test_build_sdist(self, build_backend):
dist_dir = os.path.abspath('pip-sdist') dist_dir = os.path.abspath('pip-sdist')
......
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