Commit 21bffb67 authored by Jason R. Coombs's avatar Jason R. Coombs

Merge branch 'master' into sortzip

parents d12975ca b4d58d49
......@@ -4,6 +4,12 @@ v36.4.0
* #1068: Sort files and directories when building eggs for
deterministic order.
v36.3.0
-------
* #1131: Make possible using several files within ``file:`` directive
in metadata.long_description in ``setup.cfg``.
v36.2.7
-------
......
......@@ -2306,7 +2306,7 @@ boilerplate code in some cases.
name = my_package
version = attr: src.VERSION
description = My package description
long_description = file: README.rst
long_description = file: README.rst, CHANGELOG.rst, LICENSE.rst
keywords = one, two
license = BSD 3-Clause License
classifiers =
......@@ -2379,7 +2379,7 @@ Type names used below:
Special directives:
* ``attr:`` - value could be read from module attribute
* ``file:`` - value could be read from a file
* ``file:`` - value could be read from a list of files and then concatenated
.. note::
......
[bumpversion]
current_version = 36.2.7
current_version = 36.3.0
commit = True
tag = True
......@@ -19,7 +19,7 @@ repository = https://upload.pypi.org/legacy/
[sdist]
formats = zip
[wheel]
[bdist_wheel]
universal = 1
[bumpversion:file:setup.py]
......
......@@ -89,7 +89,7 @@ def pypi_link(pkg_filename):
setup_params = dict(
name="setuptools",
version="36.2.7",
version="36.3.0",
description="Easily download, build, install, upgrade, and uninstall "
"Python packages",
author="Python Packaging Authority",
......
......@@ -245,33 +245,39 @@ class ConfigHandler(object):
directory with setup.py.
Examples:
include: LICENSE
include: src/file.txt
file: LICENSE
file: README.rst, CHANGELOG.md, src/file.txt
:param str value:
:rtype: str
"""
include_directive = 'file:'
if not isinstance(value, string_types):
return value
include_directive = 'file:'
if not value.startswith(include_directive):
return value
current_directory = os.getcwd()
filepath = value.replace(include_directive, '').strip()
filepath = os.path.abspath(filepath)
if not filepath.startswith(current_directory):
spec = value[len(include_directive):]
filepaths = (os.path.abspath(path.strip()) for path in spec.split(','))
return '\n'.join(
cls._read_file(path)
for path in filepaths
if (cls._assert_local(path) or True)
and os.path.isfile(path)
)
@staticmethod
def _assert_local(filepath):
if not filepath.startswith(os.getcwd()):
raise DistutilsOptionError(
'`file:` directive can not access %s' % filepath)
if os.path.isfile(filepath):
with io.open(filepath, encoding='utf-8') as f:
value = f.read()
return value
@staticmethod
def _read_file(filepath):
with io.open(filepath, encoding='utf-8') as f:
return f.read()
@classmethod
def _parse_attr(cls, value):
......
......@@ -45,9 +45,18 @@ else:
safe_env = dict()
_msvc9_suppress_errors = (
# msvc9compiler isn't available on some platforms
ImportError,
# msvc9compiler raises DistutilsPlatformError in some
# environments. See #1118.
distutils.errors.DistutilsPlatformError,
)
try:
from distutils.msvc9compiler import Reg
except ImportError:
except _msvc9_suppress_errors:
pass
......
......@@ -139,6 +139,24 @@ class TestMetadata:
assert metadata.download_url == 'http://test.test.com/test/'
assert metadata.maintainer_email == 'test@test.com'
def test_file_mixed(self, tmpdir):
fake_env(
tmpdir,
'[metadata]\n'
'long_description = file: README.rst, CHANGES.rst\n'
'\n'
)
tmpdir.join('README.rst').write('readme contents\nline2')
tmpdir.join('CHANGES.rst').write('changelog contents\nand stuff')
with get_dist(tmpdir) as dist:
assert dist.metadata.long_description == (
'readme contents\nline2\n'
'changelog contents\nand stuff'
)
def test_file_sandboxed(self, tmpdir):
fake_env(
......
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