Repository: takluyver/flit (python)

Issue:
Have a more helpful message when description-file is missing
I created a `pyproject.toml` file with a `description-file = "README.md"` but didn't create the README file. flit presented me with a not-so-direct message about a missing `README.md`. It would be nice if flit had suggested something like "did you not create a README.md file", instead of presenting a traceback (see also #174).

What I got currently:

```
Traceback (most recent call last):
  File "/Users/pradyunsg/.venvwrap/venvs/flit-trial/bin/flit", line 11, in <module>
    sys.exit(main())
  File "/Users/pradyunsg/.venvwrap/venvs/flit-trial/lib/python3.6/site-packages/flit/__init__.py", line 101, in main
    main(args.ini_file, formats=set(args.format or []))
  File "/Users/pradyunsg/.venvwrap/venvs/flit-trial/lib/python3.6/site-packages/flit/build.py", line 40, in main
    sb = SdistBuilder(ini_file)
  File "/Users/pradyunsg/.venvwrap/venvs/flit-trial/lib/python3.6/site-packages/flit/sdist.py", line 151, in __init__
    self.ini_info = inifile.read_pkg_ini(ini_path)
  File "/Users/pradyunsg/.venvwrap/venvs/flit-trial/lib/python3.6/site-packages/flit/inifile.py", line 53, in read_pkg_ini
    res = prep_toml_config(d, path)
  File "/Users/pradyunsg/.venvwrap/venvs/flit-trial/lib/python3.6/site-packages/flit/inifile.py", line 90, in prep_toml_config
    md_dict, module = _prep_metadata(d['metadata'], path)
  File "/Users/pradyunsg/.venvwrap/venvs/flit-trial/lib/python3.6/site-packages/flit/inifile.py", line 187, in _prep_metadata
    with description_file.open(encoding='utf-8') as f:
  File "/usr/local/Cellar/python/3.6.5/Frameworks/Python.framework/Versions/3.6/lib/python3.6/pathlib.py", line 1181, in open
    opener=self._opener)
  File "/usr/local/Cellar/python/3.6.5/Frameworks/Python.framework/Versions/3.6/lib/python3.6/pathlib.py", line 1035, in _opener
    return self._accessor.open(self, flags, mode)
  File "/usr/local/Cellar/python/3.6.5/Frameworks/Python.framework/Versions/3.6/lib/python3.6/pathlib.py", line 387, in wrapped
    return strfunc(str(pathobj), *args)
FileNotFoundError: [Errno 2] No such file or directory: 'README.md'
```


Pull request:
Show a nice error if the configured description-file is missing
Fixes #176.

Patch:
diff --git a/flit/inifile.py b/flit/inifile.py
index 266c495..6ed83a4 100644
--- a/flit/inifile.py
+++ b/flit/inifile.py
@@ -185,8 +185,13 @@ def _prep_metadata(md_sect, path):
     # Description file
     if 'description-file' in md_sect:
         description_file = path.parent / md_sect.get('description-file')
-        with description_file.open(encoding='utf-8') as f:
-            raw_desc =  f.read()
+        try:
+            with description_file.open(encoding='utf-8') as f:
+                raw_desc = f.read()
+        except FileNotFoundError:
+            raise ConfigError(
+                "Description file {} does not exist".format(description_file)
+            )
         ext = description_file.suffix
         try:
             mimetype = readme_ext_to_content_type[ext]


Test patch:
diff --git a/tests/samples/missing-description-file.toml b/tests/samples/missing-description-file.toml
new file mode 100644
index 0000000..00fae72
--- /dev/null
+++ b/tests/samples/missing-description-file.toml
@@ -0,0 +1,9 @@
+[build-system]
+requires = ["flit"]
+
+[tool.flit.metadata]
+module = "missingdescriptionfile"
+author = "Sir Robin"
+author-email = "robin@camelot.uk"
+home-page = "http://github.com/sirrobin/missingdescriptionfile"
+description-file = "definitely-missing.rst"
diff --git a/tests/test_inifile.py b/tests/test_inifile.py
index 07a452c..d64715d 100644
--- a/tests/test_inifile.py
+++ b/tests/test_inifile.py
@@ -1,4 +1,5 @@
 import logging
+import re
 from pathlib import Path
 
 import pytest
@@ -47,6 +48,10 @@ def test_description_file():
         "Sample description for test.\n"
     assert info['metadata']['description_content_type'] == 'text/x-rst'
 
+def test_missing_description_file():
+    with pytest.raises(ConfigError, match=r"Description file .* does not exist"):
+        read_pkg_ini(samples_dir / 'missing-description-file.toml')
+
 def test_bad_description_extension(caplog):
     info = read_pkg_ini(samples_dir / 'bad-description-ext.toml')
     assert info['metadata']['description_content_type'] is None