From b44fac4a88cfa79b86aec9ed5467c1f8e5a7008d Mon Sep 17 00:00:00 2001 From: Thomas Kluyver Date: Sat, 31 Jul 2021 15:39:36 +0100 Subject: [PATCH] Update 'flit init' to use PEP 621 [project] table --- flit/init.py | 48 ++++++++++++++++++++++++++++++---------------- flit/tomlify.py | 11 ++++++++++- tests/test_init.py | 45 ++++++++++++++++++++----------------------- 3 files changed, 63 insertions(+), 41 deletions(-) diff --git a/flit/init.py b/flit/init.py index b0c77c66..496166c4 100644 --- a/flit/init.py +++ b/flit/init.py @@ -1,4 +1,3 @@ -from collections import OrderedDict from datetime import date import json import os @@ -181,7 +180,7 @@ def initialise(self): module = self.prompt_text('Module name', self.guess_module_name(), str.isidentifier) author = self.prompt_text('Author', self.defaults.get('author'), - lambda s: s != '') + lambda s: True) author_email = self.prompt_text('Author email', self.defaults.get('author_email'), self.validate_email) if 'home_page_template' in self.defaults: @@ -199,33 +198,50 @@ def initialise(self): self.update_defaults(author=author, author_email=author_email, home_page=home_page, module=module, license=license) - metadata = OrderedDict([ - ('module', module), - ('author', author), - ]) + # Format information as TOML + # This is ugly code, but I want the generated pyproject.toml, which + # will mostly be edited by hand, to look a particular way - e.g. authors + # in inline tables. It's easier to 'cheat' with some string formatting + # than to do this through a TOML library. + author_info = [] + if author: + author_info.append(f'name = {json.dumps(author)}') if author_email: - metadata['author-email'] = author_email - if home_page: - metadata['home-page'] = home_page + author_info.append(f'email = {json.dumps(author_email)}') + if author_info: + authors_list = "[{%s}]" % ", ".join(author_info) + else: + authors_list = "[]" + + classifiers = [] if license != 'skip': - metadata['classifiers'] = [license_names_to_classifiers[license]] + classifiers = [license_names_to_classifiers[license]] self.write_license(license, author) - if readme: - metadata['description-file'] = readme with (self.directory / 'pyproject.toml').open('w', encoding='utf-8') as f: - f.write(TEMPLATE.format(metadata=toml.dumps(metadata))) + f.write(TEMPLATE.format( + name=json.dumps(module), authors=authors_list + )) + if readme: + toml.dump({'readme': readme}, f) + if classifiers: + f.write(f"classifiers = {json.dumps(classifiers)}\n") + f.write('dynamic = ["version", "description"]\n') + if home_page: + f.write("\n") + toml.dump({'project': {'urls': {'Home': home_page}}}, f) print() print("Written pyproject.toml; edit that file to add optional extra info.") TEMPLATE = """\ [build-system] -requires = ["flit_core >=2,<4"] +requires = ["flit_core >=3.2,<4"] build-backend = "flit_core.buildapi" -[tool.flit.metadata] -{metadata} +[project] +name = {name} +authors = {authors} """ if __name__ == '__main__': diff --git a/flit/tomlify.py b/flit/tomlify.py index a9c9c605..d50cc9ee 100644 --- a/flit/tomlify.py +++ b/flit/tomlify.py @@ -8,7 +8,16 @@ import toml from .config import metadata_list_fields -from .init import TEMPLATE + + +TEMPLATE = """\ +[build-system] +requires = ["flit_core >=2,<4"] +build-backend = "flit_core.buildapi" + +[tool.flit.metadata] +{metadata} +""" class CaseSensitiveConfigParser(configparser.ConfigParser): optionxform = staticmethod(str) diff --git a/tests/test_init.py b/tests/test_init.py index 7330ff52..c30e6d36 100644 --- a/tests/test_init.py +++ b/tests/test_init.py @@ -108,8 +108,7 @@ def test_init(): assert_isfile(generated) with generated.open() as f: data = toml.load(f) - assert data['tool']['flit']['metadata'][ - 'author-email'] == "test@example.com" + assert data['project']['authors'][0]['email'] == "test@example.com" license = Path(td) / 'LICENSE' assert_isfile(license) with license.open() as f: @@ -133,11 +132,10 @@ def test_init_homepage_and_license_are_optional(): with Path(td, 'pyproject.toml').open() as f: data = toml.load(f) assert not Path(td, 'LICENSE').exists() - metadata = data['tool']['flit']['metadata'] - assert metadata == { - 'author': 'Test Author', - 'author-email': 'test_email@example.com', - 'module': 'test_module_name', + assert data['project'] == { + 'authors': [{'name': 'Test Author', 'email': 'test_email@example.com'}], + 'name': 'test_module_name', + 'dynamic': ['version', 'description'], } def test_init_homepage_validator(): @@ -155,12 +153,11 @@ def test_init_homepage_validator(): ti.initialise() with Path(td, 'pyproject.toml').open() as f: data = toml.load(f) - metadata = data['tool']['flit']['metadata'] - assert metadata == { - 'author': 'Test Author', - 'author-email': 'test_email@example.com', - 'home-page': 'https://www.example.org', - 'module': 'test_module_name', + assert data['project'] == { + 'authors': [{'name': 'Test Author', 'email': 'test_email@example.com'}], + 'name': 'test_module_name', + 'urls': {'Home': 'https://www.example.org'}, + 'dynamic': ['version', 'description'], } def test_author_email_field_is_optional(): @@ -178,11 +175,12 @@ def test_author_email_field_is_optional(): with Path(td, 'pyproject.toml').open() as f: data = toml.load(f) assert not Path(td, 'LICENSE').exists() - metadata = data['tool']['flit']['metadata'] - assert metadata == { - 'author': 'Test Author', - 'module': 'test_module_name', - 'home-page': 'https://www.example.org', + + assert data['project'] == { + 'authors': [{'name': 'Test Author'}], + 'name': 'test_module_name', + 'urls': {'Home': 'https://www.example.org'}, + 'dynamic': ['version', 'description'], } @@ -218,10 +216,9 @@ def test_init_readme_found_yes_choosen(): with Path(td, 'pyproject.toml').open() as f: data = toml.load(f) - metadata = data['tool']['flit']['metadata'] - assert metadata == { - 'author': 'Test Author', - 'author-email': 'test_email@example.com', - 'module': 'test_module_name', - 'description-file': 'readme.md' + assert data['project'] == { + 'authors': [{'name': 'Test Author', 'email': 'test_email@example.com'}], + 'name': 'test_module_name', + 'readme': 'readme.md', + 'dynamic': ['version', 'description'], }