8000 Use internal pip unzip_file definition to ensure executable bit is re… · AutomatedTester/rules_python@8c9ed92 · GitHub
[go: up one dir, main page]

Skip to content

Commit 8c9ed92

Browse files
gmweaverGarrett WeaverJonathon Belotti
authored
Use internal pip unzip_file definition to ensure executable bit is retained when unpacking (bazel-contrib#333)
* keep file permissions when unpacking * regenerate tools Co-authored-by: Garrett Weaver <garrett.weaver@csscompany.com> Co-authored-by: Jonathon Belotti <jonathon@canva.com>
1 parent 0f8183b commit 8c9ed92

File tree

3 files changed

+31
-2
lines changed

3 files changed

+31
-2
lines changed

packaging/whl.py

Lines changed: 31 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -18,9 +18,25 @@
1818
import os
1919
import pkg_resources
2020
import re
21+
import stat
2122
import zipfile
2223

2324

25+
def current_umask():
26+
"""Get the current umask which involves having to set it temporarily."""
27+
mask = os.umask(0)
28+
os.umask(mask)
29+
return mask
30+
31+
32+
def set_extracted_file_to_default_mode_plus_executable(path):
33+
"""
34+
Make file present at path have execute for user/group/world
35+
(chmod +x) is no-op on windows per python docs
36+
"""
37+
os.chmod(path, (0o777 & ~current_umask() | 0o111))
38+
39+
2440
class Wheel(object):
2541

2642
def __init__(self, path):
@@ -107,8 +123,21 @@ def extras(self):
107123
return self.metadata().get('extras', [])
108124

109125
def expand(self, directory):
110-
with zipfile.ZipFile(self.path(), 'r') as whl:
111-
whl.extractall(directory)
126+
with zipfile.ZipFile(self.path(), "r", allowZip64=True) as whl:
127+
whl.extractall(directory)
128+
# The following logic is borrowed from Pip:
129+
# https://github.com/pypa/pip/blob/cc48c07b64f338ac5e347d90f6cb4efc22ed0d0b/src/pip/_internal/utils/unpacking.py#L240
130+
for info in whl.infolist():
131+
name = info.filename
132+
# Do not attempt to modify directories.
133+
if name.endswith("/") or name.endswith("\\"):
134+
continue
135+
mode = info.external_attr >> 16
136+
# if mode and regular file and any execute permissions for
137+
# user/group/world?
138+
if mode and stat.S_ISREG(mode) and mode & 0o111:
139+
name = os.path.join(directory, name)
140+
set_extracted_file_to_default_mode_plus_executable(name)
112141

113142
# _parse_metadata parses METADATA files according to https://www.python.org/dev/peps/pep-0314/
114143
def _parse_metadata(self, content):

tools/piptool.par

1.41 KB
Binary file not shown.

tools/whltool.par

2.81 KB
Binary file not shown.

0 commit comments

Comments
 (0)
0