Repository: takluyver/flit
Pull request #147 (2017-11-14 17:44:19)

Tool to convert flit.ini to pyproject.toml
In a folder containing `flit.ini`, run:

```shell
python3 -m flit.tomlify
```

I haven't currently given this a subcommand, because it's a rougher temporary tool.


Patch:
diff --git a/doc/pyproject_toml.rst b/doc/pyproject_toml.rst
index aae8bc0..422cda7 100644
--- a/doc/pyproject_toml.rst
+++ b/doc/pyproject_toml.rst
@@ -9,6 +9,9 @@ This file lives next to the module or package.
    similar information. Flit can still read these files for now, but you should
    switch to ``pyproject.toml`` soon.
 
+   Run ``python3 -m flit.tomlify`` to convert a ``flit.ini`` file to
+   ``pyproject.toml``.
+
 Build system section
 --------------------
 
diff --git a/flit/init.py b/flit/init.py
index 9b67769..794c964 100644
--- a/flit/init.py
+++ b/flit/init.py
@@ -189,7 +189,7 @@ class TerminalIniter(IniterBase):
         print()
         print("Written pyproject.toml; edit that file to add optional extra info.")
 
-TEMPLATE = """
+TEMPLATE = """\
 [build-system]
 requires = ["flit"]
 build-backend = "flit.buildapi"
diff --git a/flit/tomlify.py b/flit/tomlify.py
new file mode 100644
index 0000000..2bfe942
--- /dev/null
+++ b/flit/tomlify.py
@@ -0,0 +1,74 @@
+"""Convert a flit.ini file to pyproject.toml
+"""
+import argparse
+from collections import OrderedDict
+import configparser
+import os
+from pathlib import Path
+import pytoml
+
+from .inifile import metadata_list_fields
+from .init import TEMPLATE
+
+class CaseSensitiveConfigParser(configparser.ConfigParser):
+    optionxform = staticmethod(str)
+
+def convert(path):
+    cp = configparser.ConfigParser()
+    with path.open(encoding='utf-8') as f:
+        cp.read_file(f)
+
+    ep_file = Path('entry_points.txt')
+    metadata = OrderedDict()
+    for name, value in cp['metadata'].items():
+        if name in metadata_list_fields:
+            metadata[name] = [l for l in value.splitlines() if l.strip()]
+        elif name == 'entry-points-file':
+            ep_file = Path(value)
+        else:
+            metadata[name] = value
+
+    if 'scripts' in cp:
+        scripts = OrderedDict(cp['scripts'])
+    else:
+        scripts = {}
+
+    entrypoints = CaseSensitiveConfigParser()
+    if ep_file.is_file():
+        with ep_file.open(encoding='utf-8') as f:
+            entrypoints.read_file(f)
+
+    written_entrypoints = False
+    with Path('pyproject.toml').open('w', encoding='utf-8') as f:
+        f.write(TEMPLATE.format(metadata=pytoml.dumps(metadata)))
+
+        if scripts:
+            f.write('\n[tool.flit.scripts]\n')
+            pytoml.dump(scripts, f)
+
+        for groupname, group in entrypoints.items():
+            if not dict(group):
+                continue
+
+            if '.' in groupname:
+                groupname = '"{}"'.format(groupname)
+            f.write('\n[tool.flit.entrypoints.{}]\n'.format(groupname))
+            pytoml.dump(OrderedDict(group), f)
+            written_entrypoints = True
+
+    print("Written 'pyproject.toml'")
+    files = str(path)
+    if written_entrypoints:
+        files += ' and ' + str(ep_file)
+    print("Please check the new file, then remove", files)
+
+def main(argv=None):
+    ap = argparse.ArgumentParser()
+    ap.add_argument('-f', '--ini-file', type=Path, default='flit.ini')
+    args = ap.parse_args(argv)
+
+    os.chdir(str(args.ini_file.parent))
+    convert(Path(args.ini_file.name))
+
+if __name__ == '__main__':
+    main()


Test patch:
diff --git a/tests/test_tomlify.py b/tests/test_tomlify.py
new file mode 100644
index 0000000..9a88fb2
--- /dev/null
+++ b/tests/test_tomlify.py
@@ -0,0 +1,31 @@
+import os
+from pathlib import Path
+import pytoml
+from shutil import copy
+from testpath import assert_isfile
+from testpath.tempdir import TemporaryWorkingDirectory
+
+from flit import tomlify
+
+samples_dir = Path(__file__).parent / 'samples'
+
+def test_tomlify():
+    with TemporaryWorkingDirectory() as td:
+        copy(str(samples_dir / 'entrypoints_valid.ini'),
+             os.path.join(td, 'flit.ini'))
+        copy(str(samples_dir / 'some_entry_points.txt'), td)
+        tomlify.main(argv=[])
+
+        pyproject_toml = Path(td, 'pyproject.toml')
+        assert_isfile(pyproject_toml)
+
+        with pyproject_toml.open(encoding='utf-8') as f:
+            content = pytoml.load(f)
+
+        assert 'build-system' in content
+        assert 'tool' in content
+        assert 'flit' in content['tool']
+        flit_table = content['tool']['flit']
+        assert 'metadata' in flit_table
+        assert 'scripts' in flit_table
+        assert 'entrypoints' in flit_table