diff options
| author | Jason R. Coombs <jaraco@jaraco.com> | 2019-04-28 10:14:46 -0400 |
|---|---|---|
| committer | Alex Grönholm <alex.gronholm@nextday.fi> | 2019-04-28 17:14:46 +0300 |
| commit | 369b1eeb05f1ce55363afd80edda446a4155d952 (patch) | |
| tree | 1d6af8270ac87a73a45c16db7c8d22cbca2ce1cf | |
| parent | 4fddbbaa0e7fab4ecfaab066e4cf2558b6c13dd8 (diff) | |
| download | wheel-git-369b1eeb05f1ce55363afd80edda446a4155d952.tar.gz | |
Include directory entries when building wheel (#289)
Fixes #287.
| -rw-r--r-- | tests/test_bdist_wheel.py | 1 | ||||
| -rw-r--r-- | tests/test_wheelfile.py | 24 | ||||
| -rw-r--r-- | wheel/wheelfile.py | 15 |
3 files changed, 39 insertions, 1 deletions
diff --git a/tests/test_bdist_wheel.py b/tests/test_bdist_wheel.py index 959dfa0..3df16db 100644 --- a/tests/test_bdist_wheel.py +++ b/tests/test_bdist_wheel.py @@ -8,6 +8,7 @@ import pytest from wheel.wheelfile import WheelFile DEFAULT_FILES = { + 'dummy_dist-1.0.dist-info/', 'dummy_dist-1.0.dist-info/top_level.txt', 'dummy_dist-1.0.dist-info/METADATA', 'dummy_dist-1.0.dist-info/WHEEL', diff --git a/tests/test_wheelfile.py b/tests/test_wheelfile.py index db11bcd..9fe3ce2 100644 --- a/tests/test_wheelfile.py +++ b/tests/test_wheelfile.py @@ -2,6 +2,7 @@ from __future__ import unicode_literals import sys +import operator from zipfile import ZipFile, ZIP_DEFLATED import pytest @@ -172,3 +173,26 @@ def test_attributes(tmpdir_factory, wheel_path): info = zf.getinfo('test-1.0.dist-info/RECORD') permissions = (info.external_attr >> 16) & 0o777 assert permissions == 0o664 + + +def test_directories(tmpdir, wheel_path): + """ + The WheelFile should contain entries for directories, + empty and not. + """ + build_dir = tmpdir + sub_dir = build_dir / 'sub' + sub_dir.mkdir() + (sub_dir / '__init__.py').write_text('', encoding='utf-8') + empty_dir = build_dir / 'empty' + empty_dir.mkdir() + + with WheelFile(wheel_path, 'w') as wf: + wf.write_files(str(build_dir)) + + with ZipFile(wheel_path, 'r') as zf: + infos = zf.infolist() + + names = set(map(operator.attrgetter('filename'), infos)) + assert 'sub/' in names + assert 'empty/' in names diff --git a/wheel/wheelfile.py b/wheel/wheelfile.py index 9a1c8d2..93b4bfa 100644 --- a/wheel/wheelfile.py +++ b/wheel/wheelfile.py @@ -111,6 +111,12 @@ class WheelFile(ZipFile): # Sort the directory names so that `os.walk` will walk them in a # defined order on the next iteration. dirnames.sort() + + for name in dirnames: + path = os.path.normpath(os.path.join(root, name)) + arcname = os.path.relpath(path, base_dir) + self.mkdir(path, arcname) + for name in sorted(filenames): path = os.path.normpath(os.path.join(root, name)) if os.path.isfile(path): @@ -136,12 +142,19 @@ class WheelFile(ZipFile): zinfo.compress_type = ZIP_DEFLATED self.writestr(zinfo, data, compress_type) + def mkdir(self, filename, arcname): + st = os.stat(filename) + zinfo = ZipInfo(arcname + '/', date_time=get_zipinfo_datetime(st.st_mtime)) + zinfo.external_attr = st.st_mode << 16 + zinfo.compress_type = ZIP_DEFLATED + self.writestr(zinfo, b'') + def writestr(self, zinfo_or_arcname, bytes, compress_type=None): ZipFile.writestr(self, zinfo_or_arcname, bytes, compress_type) fname = (zinfo_or_arcname.filename if isinstance(zinfo_or_arcname, ZipInfo) else zinfo_or_arcname) logger.info("adding '%s'", fname) - if fname != self.record_path: + if fname != self.record_path and not fname.endswith('/'): hash_ = self._default_algorithm(bytes) self._file_hashes[fname] = hash_.name, native(urlsafe_b64encode(hash_.digest())) self._file_sizes[fname] = len(bytes) |
