Repository: takluyver/flit
Pull request #230 (2018-11-03 20:12:29)

better validator for home-page field
1. home-page is optional since https://github.com/takluyver/flit/issues/173 , so `flit init` shouldn't require that
2. `flit init` shouldn't accept a home-page value [for which `flit build` will refuse to build](https://github.com/takluyver/flit/blob/master/flit/validate.py#L210-L212)


Patch:
diff --git a/flit/init.py b/flit/init.py
index 794c964..2fc52ac 100644
--- a/flit/init.py
+++ b/flit/init.py
@@ -67,6 +67,9 @@ class IniterBase:
         # Properly validating an email address is much more complex
         return bool(re.match(r'.+@.+', s))
 
+    def validate_homepage(self, s):
+        return not s or s.startswith(('http://', 'https://'))
+
     def guess_module_name(self):
         packages, modules = [], []
         for p in self.directory.iterdir():
@@ -87,7 +90,7 @@ class IniterBase:
             return modules[0]
         else:
             return None
-    
+
     def update_defaults(self, author, author_email, module, home_page, license):
         new_defaults = {'author': author, 'author_email': author_email,
                         'license': license}
@@ -111,7 +114,7 @@ class IniterBase:
 
 
 class TerminalIniter(IniterBase):
-    def prompt_text(self, prompt, default, validator):
+    def prompt_text(self, prompt, default, validator, retry_msg="Try again."):
         if default is not None:
             p = "{} [{}]: ".format(prompt, default)
         else:
@@ -123,7 +126,7 @@ class TerminalIniter(IniterBase):
             if validator(response):
                 return response
 
-            print("Try again.")
+            print(retry_msg)
 
     def prompt_options(self, prompt, options, default=None):
         default_ix = None
@@ -165,8 +168,8 @@ class TerminalIniter(IniterBase):
                                                         '{modulename}', module)
         else:
             home_page_default = None
-        home_page = self.prompt_text('Home page', home_page_default,
-                                     lambda s: s != '')
+        home_page = self.prompt_text('Home page', home_page_default, self.validate_homepage,
+                                     retry_msg="Should start with http:// or https:// - try again.")
         license = self.prompt_options('Choose a license (see http://choosealicense.com/ for more info)',
                     license_choices, self.defaults.get('license'))
 
@@ -177,8 +180,9 @@ class TerminalIniter(IniterBase):
             ('module', module),
             ('author', author),
             ('author-email', author_email),
-            ('home-page', home_page),
         ])
+        if home_page:
+            metadata['home-page'] = home_page
         if license != 'skip':
             metadata['classifiers'] = [license_names_to_classifiers[license]]
             self.write_license(license, author)


Test patch:
diff --git a/tests/test_init.py b/tests/test_init.py
index 8c685e6..eead8a2 100644
--- a/tests/test_init.py
+++ b/tests/test_init.py
@@ -5,6 +5,8 @@ from tempfile import TemporaryDirectory
 from testpath import assert_isfile
 from unittest.mock import patch
 
+import pytoml
+
 from flit import init
 
 
@@ -89,3 +91,48 @@ def test_init():
         ti.initialise()
         assert_isfile('pyproject.toml')
         assert_isfile('LICENSE')
+
+def test_init_homepage_and_license_are_optional():
+    responses = ['test_module_name',
+                 'Test Author',
+                 'test_email@example.com',
+                 '',   # Home page omitted
+                 '4',  # Skip - choose a license later
+                ]
+    with TemporaryDirectory() as td, \
+          patch_data_dir(), \
+          faking_input(responses):
+        ti = init.TerminalIniter(td)
+        ti.initialise()
+        with Path(td, 'pyproject.toml').open() as f:
+            data = pytoml.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',
+    }
+
+def test_init_homepage_validator():
+    responses = ['test_module_name',
+                 'Test Author',
+                 'test_email@example.com',
+                 'www.uh-oh-spagghetti-o.com',  # fails validation
+                 'https://www.example.org',  # passes
+                 '4',  # Skip - choose a license later
+                ]
+    with TemporaryDirectory() as td, \
+          patch_data_dir(), \
+          faking_input(responses):
+        ti = init.TerminalIniter(td)
+        ti.initialise()
+        with Path(td, 'pyproject.toml').open() as f:
+            data = pytoml.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',
+    }