summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJason R. Coombs <jaraco@jaraco.com>2019-04-28 10:14:46 -0400
committerAlex Grönholm <alex.gronholm@nextday.fi>2019-04-28 17:14:46 +0300
commit369b1eeb05f1ce55363afd80edda446a4155d952 (patch)
tree1d6af8270ac87a73a45c16db7c8d22cbca2ce1cf
parent4fddbbaa0e7fab4ecfaab066e4cf2558b6c13dd8 (diff)
downloadwheel-git-369b1eeb05f1ce55363afd80edda446a4155d952.tar.gz
Include directory entries when building wheel (#289)
Fixes #287.
-rw-r--r--tests/test_bdist_wheel.py1
-rw-r--r--tests/test_wheelfile.py24
-rw-r--r--wheel/wheelfile.py15
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)