Skip to content

Commit b0e9e0c

Browse files
committed
Add support for Markdown README files
1 parent deff8fa commit b0e9e0c

File tree

9 files changed

+75
-50
lines changed

9 files changed

+75
-50
lines changed

CHANGELOG.md

+1
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88
- Added the `run` command to execute commands inside the created virtualenvs.
99
- Added the `debug:resolve` command to debug dependency resolution.
1010
- Added `pyproject.toml` file validation.
11+
- Added support for Markdown readme files.
1112

1213
### Fixed
1314

poetry/masonry/builders/builder.py

+2
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99
from poetry.semver.version_parser import VersionParser
1010
from poetry.vcs import get_vcs
1111

12+
from ..metadata import Metadata
1213
from ..utils.module import Module
1314

1415

@@ -33,6 +34,7 @@ def __init__(self, poetry, venv, io):
3334
self._module = Module(
3435
self._package.name, self._path.as_posix()
3536
)
37+
self._meta = Metadata.from_package(self._package)
3638

3739
def build(self):
3840
raise NotImplementedError()

poetry/masonry/builders/sdist.py

+14-17
Original file line numberDiff line numberDiff line change
@@ -89,14 +89,13 @@ def build(self, target_dir: Path = None) -> Path:
8989
tar_info.size = len(setup)
9090
tar.addfile(tar_info, BytesIO(setup))
9191

92-
author = self.convert_author(self._package.authors[0])
9392
pkg_info = PKG_INFO.format(
94-
name=self._package.name,
95-
version=self._package.version,
96-
summary=self._package.description,
97-
home_page=self._package.homepage or self._package.repository_url,
98-
author=author['name'],
99-
author_email=author['email'],
93+
name=self._meta.name,
94+
version=self._meta.version,
95+
summary=self._meta.summary,
96+
home_page=self._meta.home_page,
97+
author=self._meta.author,
98+
author_email=self._meta.author_email,
10099
).encode('utf-8')
101100

102101
tar_info = tarfile.TarInfo(pjoin(tar_dir, 'PKG-INFO'))
@@ -146,21 +145,19 @@ def build_setup(self) -> bytes:
146145
extra.append("'entry_points': entry_points,")
147146

148147
if self._package.python_versions != '*':
149-
python_requires = format_python_constraint(self._package.python_constraint)
148+
python_requires = self._meta.requires_python
150149

151150
extra.append("'python_requires': {!r},".format(python_requires))
152151

153-
author = self.convert_author(self._package.authors[0])
154-
155152
return SETUP.format(
156153
before='\n'.join(before),
157-
name=self._package.name,
158-
version=self._package.version,
159-
description=self._package.description,
160-
long_description=self._package.readme,
161-
author=author['name'],
162-
author_email=author['email'],
163-
url=self._package.homepage or self._package.repository_url,
154+
name=self._meta.name,
155+
version=self._meta.version,
156+
description=self._meta.summary,
157+
long_description=self._meta.description,
158+
author=self._meta.author,
159+
author_email=self._meta.author_email,
160+
url=self._meta.home_page,
164161
extra='\n '.join(extra),
165162
after='\n'.join(after)
166163
).encode('utf-8')

poetry/masonry/builders/wheel.py

+27-23
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@
1818
from poetry.vcs import get_vcs
1919
from poetry.version.helpers import format_python_constraint
2020

21+
from ..metadata import Metadata
2122
from ..utils.helpers import normalize_file_permissions
2223
from ..utils.tags import get_abbr_impl
2324
from ..utils.tags import get_abi_tag
@@ -292,36 +293,39 @@ def _write_wheel_file(self, fp):
292293

293294
def _write_metadata_file(self, fp):
294295
"""
295-
Write out metadata in the 1.x format (email like)
296+
Write out metadata in the 2.x format (email like)
296297
"""
297-
fp.write('Metadata-Version: 1.2\n')
298-
fp.write(f'Name: {self._package.name}\n')
299-
fp.write(f'Version: {self._package.version}\n')
300-
fp.write(f'Summary: {self._package.description}\n')
301-
fp.write(f'Home-page: {self._package.homepage or self._package.repository_url or "UNKNOWN"}\n')
302-
fp.write(f'License: {self._package.license or "UNKOWN"}\n')
298+
fp.write('Metadata-Version: 2.1\n')
299+
fp.write(f'Name: {self._meta.name}\n')
300+
fp.write(f'Version: {self._meta.version}\n')
301+
fp.write(f'Summary: {self._meta.summary}\n')
302+
fp.write(f'Home-page: {self._meta.home_page or "UNKNOWN"}\n')
303+
fp.write(f'License: {self._meta.license or "UNKOWN"}\n')
303304

304305
# Optional fields
305-
if self._package.keywords:
306-
fp.write(f"Keywords: {','.join(self._package.keywords)}\n")
306+
if self._meta.keywords:
307+
fp.write(f"Keywords: {self._meta.keywords}\n")
307308

308-
if self._package.authors:
309-
author = self.convert_author(self._package.authors[0])
309+
if self._meta.author:
310+
fp.write(f'Author: {self._meta.author}\n')
310311

311-
fp.write(f'Author: {author["name"]}\n')
312-
fp.write(f'Author-email: {author["email"]}\n')
312+
if self._meta.author_email:
313+
fp.write(f'Author-email: {self._meta.author_email}\n')
313314

314-
if self._package.python_versions != '*':
315-
python_requires = format_python_constraint(self._package.python_constraint)
315+
if self._meta.requires_python:
316+
fp.write(f'Requires-Python: {self._meta.requires_python}\n')
316317

317-
fp.write(f'Requires-Python: {python_requires}\n')
318-
319-
classifiers = self.get_classifers()
320-
for classifier in classifiers:
318+
for classifier in self._meta.classifiers:
321319
fp.write(f'Classifier: {classifier}\n')
322320

323-
for dep in self._package.requires:
324-
fp.write('Requires-Dist: {}\n'.format(dep.to_pep_508()))
321+
for dep in self._meta.requires_dist:
322+
fp.write(f'Requires-Dist: {dep}\n')
323+
324+
if self._meta.description_content_type:
325+
fp.write(f'Description-Content-Type: '
326+
f'{self._meta.description_content_type}\n')
327+
328+
# TODO: Provides extra
325329

326-
if self._package.readme is not None:
327-
fp.write('\n' + self._package.readme + '\n')
330+
if self._meta.description is not None:
331+
fp.write('\n' + self._meta.description + '\n')

poetry/masonry/metadata.py

+19-3
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,10 @@
1-
from poetry.semver.constraints import MultiConstraint
21
from poetry.utils.helpers import canonicalize_name
32
from poetry.version.helpers import format_python_constraint
43

54

65
class Metadata:
76

8-
metadata_version = '1.2'
7+
metadata_version = '2.1'
98
# version 1.0
109
name = None
1110
version = None
@@ -34,14 +33,21 @@ class Metadata:
3433
obsoletes_dist = ()
3534
project_urls = ()
3635

36+
# Version 2.1
37+
description_content_type = None
38+
provides_extra = []
39+
3740
@classmethod
3841
def from_package(cls, package) -> 'Metadata':
3942
meta = cls()
4043

4144
meta.name = canonicalize_name(package.name)
4245
meta.version = package.version
4346
meta.summary = package.description
44-
meta.description = package.readme
47+
if package.readme:
48+
with package.readme.open() as f:
49+
meta.description = f.read()
50+
4551
meta.keywords = ','.join(package.keywords)
4652
meta.home_page = package.homepage or package.repository_url
4753
meta.author = package.author_name
@@ -58,4 +64,14 @@ def from_package(cls, package) -> 'Metadata':
5864
# Requires python
5965
meta.requires_python = format_python_constraint(package.python_constraint)
6066

67+
# Version 2.1
68+
if package.readme:
69+
if package.readme.suffix == '.rst':
70+
meta.description_content_type = 'text/x-rst'
71+
elif package.readme.suffix in ['.md', '.markdown']:
72+
meta.description_content_type = 'text/markdown'
73+
else:
74+
meta.description_content_type = 'text/plain'
75+
76+
# TODO: Provides extra
6177
return meta

poetry/masonry/publishing/publisher.py

+9-1
Original file line numberDiff line numberDiff line change
@@ -187,7 +187,7 @@ def post_data(self, file):
187187
else:
188188
py_version = None
189189

190-
return {
190+
data = {
191191
# identify release
192192
"name": meta.name,
193193
"version": meta.version,
@@ -230,6 +230,14 @@ def post_data(self, file):
230230
"requires_python": meta.requires_python,
231231
}
232232

233+
# Metadata 2.1
234+
if meta.description_content_type:
235+
data['description_content_type'] = meta.description_content_type
236+
237+
# TODO: Provides extra
238+
239+
return data
240+
233241
def _upload(self, session, url):
234242
dist = self._poetry.file.parent / 'dist'
235243
packages = dist.glob(f'{self._package.name}-{self._package.version}*')

poetry/packages/package.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -69,7 +69,7 @@ def __init__(self, name, version, pretty_version=None):
6969
self.repository_url = None
7070
self.keywords = []
7171
self.license = None
72-
self.readme = ''
72+
self.readme = None
7373

7474
self.source_type = ''
7575
self.source_reference = ''

poetry/poetry.py

+1-2
Original file line numberDiff line numberDiff line change
@@ -90,8 +90,7 @@ def create(cls, cwd) -> 'Poetry':
9090
package.keywords = local_config.get('keywords', [])
9191

9292
if 'readme' in local_config:
93-
with open(poetry_file.parent / local_config['readme']) as f:
94-
package.readme = f.read()
93+
package.readme = Path(cwd) / local_config['readme']
9594

9695
if 'platform' in local_config:
9796
package.platform = local_config['platform']

tests/test_poetry.py

+1-3
Original file line numberDiff line numberDiff line change
@@ -18,9 +18,7 @@ def test_poetry():
1818
assert package.description == 'Some description.'
1919
assert package.authors == ['Sébastien Eustace <[email protected]>']
2020
assert package.license == 'MIT'
21-
assert package.readme == """My Package
22-
==========
23-
"""
21+
assert str(package.readme.relative_to(fixtures_dir)) == "sample_project/README.rst"
2422
assert package.homepage == 'https://poetry.eustace.io'
2523
assert package.repository_url == 'https://github.com/sdispater/poetry'
2624
assert package.keywords == ["packaging", "dependency", "poetry"]

0 commit comments

Comments
 (0)