Commit 7e2f3074 authored by Jason R. Coombs's avatar Jason R. Coombs Committed by GitHub

Merge pull request #2046 from pypa/bugfix/1607-retain-executable-mode

Retain executable mode
parents e5a8bfed ef3a3864
Preserve file modes during pkg files copying, but clear read only flag for target afterwards.
...@@ -7,6 +7,7 @@ import textwrap ...@@ -7,6 +7,7 @@ import textwrap
import io import io
import distutils.errors import distutils.errors
import itertools import itertools
import stat
from setuptools.extern import six from setuptools.extern import six
from setuptools.extern.six.moves import map, filter, filterfalse from setuptools.extern.six.moves import map, filter, filterfalse
...@@ -20,6 +21,10 @@ except ImportError: ...@@ -20,6 +21,10 @@ except ImportError:
"do nothing" "do nothing"
def make_writable(target):
os.chmod(target, os.stat(target).st_mode | stat.S_IWRITE)
class build_py(orig.build_py, Mixin2to3): class build_py(orig.build_py, Mixin2to3):
"""Enhanced 'build_py' command that includes data files with packages """Enhanced 'build_py' command that includes data files with packages
...@@ -120,8 +125,8 @@ class build_py(orig.build_py, Mixin2to3): ...@@ -120,8 +125,8 @@ class build_py(orig.build_py, Mixin2to3):
target = os.path.join(build_dir, filename) target = os.path.join(build_dir, filename)
self.mkpath(os.path.dirname(target)) self.mkpath(os.path.dirname(target))
srcfile = os.path.join(src_dir, filename) srcfile = os.path.join(src_dir, filename)
outf, copied = self.copy_file( outf, copied = self.copy_file(srcfile, target)
srcfile, target, preserve_mode=False) make_writable(target)
srcfile = os.path.abspath(srcfile) srcfile = os.path.abspath(srcfile)
if (copied and if (copied and
srcfile in self.distribution.convert_2to3_doctests): srcfile in self.distribution.convert_2to3_doctests):
......
...@@ -2,6 +2,8 @@ import os ...@@ -2,6 +2,8 @@ import os
import stat import stat
import shutil import shutil
import pytest
from setuptools.dist import Distribution from setuptools.dist import Distribution
...@@ -26,9 +28,10 @@ def test_directories_in_package_data_glob(tmpdir_cwd): ...@@ -26,9 +28,10 @@ def test_directories_in_package_data_glob(tmpdir_cwd):
def test_read_only(tmpdir_cwd): def test_read_only(tmpdir_cwd):
""" """
Ensure mode is not preserved in copy for package modules Ensure read-only flag is not preserved in copy
and package data, as that causes problems for package modules and package data, as that
with deleting read-only files on Windows. causes problems with deleting read-only files on
Windows.
#1451 #1451
""" """
...@@ -47,3 +50,35 @@ def test_read_only(tmpdir_cwd): ...@@ -47,3 +50,35 @@ def test_read_only(tmpdir_cwd):
dist.parse_command_line() dist.parse_command_line()
dist.run_commands() dist.run_commands()
shutil.rmtree('build') shutil.rmtree('build')
@pytest.mark.xfail(
'platform.system() == "Windows"',
reason="On Windows, files do not have executable bits",
raises=AssertionError,
strict=True,
)
def test_executable_data(tmpdir_cwd):
"""
Ensure executable bit is preserved in copy for
package data, as users rely on it for scripts.
#2041
"""
dist = Distribution(dict(
script_name='setup.py',
script_args=['build_py'],
packages=['pkg'],
package_data={'pkg': ['run-me']},
name='pkg',
))
os.makedirs('pkg')
open('pkg/__init__.py', 'w').close()
open('pkg/run-me', 'w').close()
os.chmod('pkg/run-me', 0o700)
dist.parse_command_line()
dist.run_commands()
assert os.stat('build/lib/pkg/run-me').st_mode & stat.S_IEXEC, \
"Script is not executable"
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