Blob Blame History Raw
diff --git a/setup.py b/setup.py
index 6a65b52ecb9c84c7e771da3d80902f1e9c73ade1..2d44dcc8b53406d9e6e2eba5579ff37044a00a7a 100644
--- a/setup.py
+++ b/setup.py
@@ -107,7 +107,7 @@ case second `m'.  Any other spelling is incorrect.""",
         'aiosmtpd>=1.1',
         'alembic',
         'atpublic',
-        'click',
+        'click>=7.0',
         'dnspython>=1.14.0',
         'falcon>=1.0.0rc1',
         'flufl.bounce',
diff --git a/src/mailman/commands/docs/create.rst b/src/mailman/commands/docs/create.rst
index c80ff7a3dd3087b65ae60cf48a4ba2df0fbdf0b3..d619302e59afe0774365f11a32648c21aa5ae318 100644
--- a/src/mailman/commands/docs/create.rst
+++ b/src/mailman/commands/docs/create.rst
@@ -10,6 +10,7 @@ You can prevent creation of a mailing list in an unknown domain.
 
     >>> command('mailman create --no-domain ant@example.xx')
     Usage: create [OPTIONS] LISTNAME
+    Try "create --help" for help.
     <BLANKLINE>
     Error: Undefined domain: example.xx
 
@@ -86,6 +87,7 @@ The language must be known to Mailman.
 
     >>> command('mailman create --language xx ewe@example.com')
     Usage: create [OPTIONS] LISTNAME
+    Try "create --help" for help.
     <BLANKLINE>
     Error: Invalid language code: xx
 
diff --git a/src/mailman/commands/docs/import.rst b/src/mailman/commands/docs/import.rst
index 5c5883921d0c99a788b9856c85082700d501a3e3..765e41be2021b37a75555169a461ba6bb55af66f 100644
--- a/src/mailman/commands/docs/import.rst
+++ b/src/mailman/commands/docs/import.rst
@@ -11,15 +11,17 @@ You must specify the mailing list you are importing into, and it must exist.
 
     >>> command('mailman import21')
     Usage: ... [OPTIONS] LISTSPEC PICKLE_FILE
+    Try "import21 --help" for help.
     <BLANKLINE>
-    Error: Missing argument "listspec".
+    Error: Missing argument "LISTSPEC".
 
 You must also specify a pickle file to import.
 
     >>> command('mailman import21 import@example.com')
     Usage: ... [OPTIONS] LISTSPEC PICKLE_FILE
+    Try "import21 --help" for help.
     <BLANKLINE>
-    Error: Missing argument "pickle_file".
+    Error: Missing argument "PICKLE_FILE".
 
 Too bad the list doesn't exist.
 
@@ -27,6 +29,7 @@ Too bad the list doesn't exist.
     >>> pickle_file = resource_filename('mailman.testing', 'config.pck')
     >>> command('mailman import21 import@example.com ' + pickle_file)
     Usage: ... [OPTIONS] LISTSPEC PICKLE_FILE
+    Try "import21 --help" for help.
     <BLANKLINE>
     Error: No such list: import@example.com
 
@@ -38,6 +41,7 @@ from.
     >>> transaction.commit()
     >>> command('mailman import21 import@example.com ' + __file__)
     Usage: ... [OPTIONS] LISTSPEC PICKLE_FILE
+    Try "import21 --help" for help.
     <BLANKLINE>
     Error: Not a Mailman 2.1 configuration file: .../import.rst'...
 
diff --git a/src/mailman/commands/tests/test_cli_conf.py b/src/mailman/commands/tests/test_cli_conf.py
index 044a1789445f74db90762da22ea87c86802b254c..b7a6bf4cef030a09022ea7978a0aeaff9d34f3c3 100644
--- a/src/mailman/commands/tests/test_cli_conf.py
+++ b/src/mailman/commands/tests/test_cli_conf.py
@@ -38,7 +38,8 @@ class TestConf(unittest.TestCase):
         self.assertEqual(result.exit_code, 2)
         self.assertEqual(
             result.output,
-            'Usage: conf [OPTIONS]\n\n'
+            'Usage: conf [OPTIONS]\n'
+            'Try "conf --help" for help.\n\n'
             'Error: No such section: thissectiondoesnotexist\n')
 
     def test_cannot_access_nonexistent_section_and_key(self):
@@ -47,7 +48,8 @@ class TestConf(unittest.TestCase):
         self.assertEqual(result.exit_code, 2)
         self.assertEqual(
             result.output,
-            'Usage: conf [OPTIONS]\n\n'
+            'Usage: conf [OPTIONS]\n'
+            'Try "conf --help" for help.\n\n'
             'Error: No such section: thissectiondoesnotexist\n')
 
     def test_cannot_access_nonexistent_key(self):
@@ -56,7 +58,8 @@ class TestConf(unittest.TestCase):
         self.assertEqual(result.exit_code, 2)
         self.assertEqual(
             result.output,
-            'Usage: conf [OPTIONS]\n\n'
+            'Usage: conf [OPTIONS]\n'
+            'Try "conf --help" for help.\n\n'
             'Error: Section mailman: No such key: thiskeydoesnotexist\n')
 
     def test_output_to_explicit_stdout(self):
diff --git a/src/mailman/commands/tests/test_cli_control.py b/src/mailman/commands/tests/test_cli_control.py
index 74aa451c3f80935c9ba8253976c7a582cbf09a9e..1cb38b32523ad31664470d4464c136ec3a30f284 100644
--- a/src/mailman/commands/tests/test_cli_control.py
+++ b/src/mailman/commands/tests/test_cli_control.py
@@ -236,7 +236,8 @@ class TestControl(unittest.TestCase):
         self.assertEqual(result.exit_code, 2)
         self.assertEqual(
             result.output,
-            'Usage: start [OPTIONS]\n\n'
+            'Usage: start [OPTIONS]\n'
+            'Try "start --help" for help.\n\n'
             'Error: A previous run of GNU Mailman did not exit cleanly '
             '(stale_lock).  Try using --force\n')
 
@@ -267,7 +268,8 @@ class TestControlSimple(unittest.TestCase):
             self.assertEqual(results.exit_code, 2)
             self.assertEqual(
                 results.output,
-                'Usage: start [OPTIONS]\n\n'
+                'Usage: start [OPTIONS]\n'
+                'Try "start --help" for help.\n\n'
                 'Error: GNU Mailman is already running\n')
 
     def test_reopen(self):
diff --git a/src/mailman/commands/tests/test_cli_create.py b/src/mailman/commands/tests/test_cli_create.py
index a6cfe5603dfb8101fcdcee7d1aef2ee2eedd2ab7..7aedb5587ba86e87c7f06c5b5465a8ca4b1164f0 100644
--- a/src/mailman/commands/tests/test_cli_create.py
+++ b/src/mailman/commands/tests/test_cli_create.py
@@ -40,7 +40,8 @@ class TestCreate(unittest.TestCase):
         self.assertEqual(result.exit_code, 2)
         self.assertEqual(
             result.output,
-            'Usage: create [OPTIONS] LISTNAME\n\n'
+            'Usage: create [OPTIONS] LISTNAME\n'
+            'Try "create --help" for help.\n\n'
             'Error: List already exists: ant@example.com\n')
 
     def test_invalid_posting_address(self):
@@ -49,7 +50,8 @@ class TestCreate(unittest.TestCase):
         self.assertEqual(result.exit_code, 2)
         self.assertEqual(
             result.output,
-            'Usage: create [OPTIONS] LISTNAME\n\n'
+            'Usage: create [OPTIONS] LISTNAME\n'
+            'Try "create --help" for help.\n\n'
             'Error: Illegal list name: foo\n')
 
     def test_invalid_owner_addresses(self):
@@ -59,7 +61,8 @@ class TestCreate(unittest.TestCase):
         self.assertEqual(result.exit_code, 2)
         self.assertEqual(
             result.output,
-            'Usage: create [OPTIONS] LISTNAME\n\n'
+            'Usage: create [OPTIONS] LISTNAME\n'
+            'Try "create --help" for help.\n\n'
             'Error: Illegal owner addresses: invalid\n')
 
     def test_create_without_domain_option(self):
@@ -88,7 +91,8 @@ class TestCreate(unittest.TestCase):
         self.assertEqual(result.exit_code, 2)
         self.assertEqual(
             result.output,
-            'Usage: create [OPTIONS] LISTNAME\n\n'
+            'Usage: create [OPTIONS] LISTNAME\n'
+            'Try "create --help" for help.\n\n'
             'Error: Undefined domain: example.org\n')
 
     def test_create_with_nodomain(self):
@@ -97,7 +101,8 @@ class TestCreate(unittest.TestCase):
         self.assertEqual(result.exit_code, 2)
         self.assertEqual(
             result.output,
-            'Usage: create [OPTIONS] LISTNAME\n\n'
+            'Usage: create [OPTIONS] LISTNAME\n'
+            'Try "create --help" for help.\n\n'
             'Error: Undefined domain: example.org\n')
 
 
diff --git a/src/mailman/commands/tests/test_cli_import.py b/src/mailman/commands/tests/test_cli_import.py
index a134b933f2e59eaf25d728f2e9625bd98c139720..fe82f71daac30d7b6413ebeab5822b20bc8aa8c9 100644
--- a/src/mailman/commands/tests/test_cli_import.py
+++ b/src/mailman/commands/tests/test_cli_import.py
@@ -56,8 +56,9 @@ class TestImport(unittest.TestCase):
         self.assertEqual(result.exit_code, 2, result.output)
         self.assertEqual(
             result.output,
-            'Usage: import21 [OPTIONS] LISTSPEC PICKLE_FILE\n\n'
-            'Error: Missing argument "listspec".\n')
+            'Usage: import21 [OPTIONS] LISTSPEC PICKLE_FILE\n'
+            'Try "import21 --help" for help.\n\n'
+            'Error: Missing argument "LISTSPEC".\n')
 
     def test_pickle_with_nondict(self):
         with NamedTemporaryFile() as pckfile:
diff --git a/src/mailman/commands/tests/test_cli_inject.py b/src/mailman/commands/tests/test_cli_inject.py
index b797537801b5fd42557d3dbc7e8a051b229b86fc..8e53e5c2a7da9f2c12db21d4d12af7c2d282c59c 100644
--- a/src/mailman/commands/tests/test_cli_inject.py
+++ b/src/mailman/commands/tests/test_cli_inject.py
@@ -62,7 +62,8 @@ class TestInject(unittest.TestCase):
         self.assertEqual(result.exit_code, 2)
         self.assertEqual(
             result.output,
-            'Usage: inject [OPTIONS] LISTSPEC\n\n'
+            'Usage: inject [OPTIONS] LISTSPEC\n'
+            'Try "inject --help" for help.\n\n'
             'Error: No such list: bee.example.com\n')
 
     def test_inject_no_such_queue(self):
@@ -71,7 +72,8 @@ class TestInject(unittest.TestCase):
         self.assertEqual(result.exit_code, 2)
         self.assertEqual(
             result.output,
-            'Usage: inject [OPTIONS] LISTSPEC\n\n'
+            'Usage: inject [OPTIONS] LISTSPEC\n'
+            'Try "inject --help" for help.\n\n'
             'Error: No such queue: bogus\n')
 
     def test_inject_no_filename_option(self):
diff --git a/src/mailman/commands/tests/test_cli_members.py b/src/mailman/commands/tests/test_cli_members.py
index 91eda0687c60a0477c0ceeb79b604f28e4d61f8d..f6a4c593bd42aed3662593e0217bdd54b3f4f2e6 100644
--- a/src/mailman/commands/tests/test_cli_members.py
+++ b/src/mailman/commands/tests/test_cli_members.py
@@ -40,7 +40,8 @@ class TestCLIMembers(unittest.TestCase):
         self.assertEqual(result.exit_code, 2)
         self.assertEqual(
             result.output,
-            'Usage: members [OPTIONS] LISTSPEC\n\n'
+            'Usage: members [OPTIONS] LISTSPEC\n'
+            'Try "members --help" for help.\n\n'
             'Error: No such list: bee.example.com\n')
 
     def test_role_administrator(self):
diff --git a/src/mailman/commands/tests/test_cli_shell.py b/src/mailman/commands/tests/test_cli_shell.py
index 6ddcae2b0a1e0b255db2c374ae94580310955bf1..1606f6e11ed5e9f8193d38a04a564277d63cfaab 100644
--- a/src/mailman/commands/tests/test_cli_shell.py
+++ b/src/mailman/commands/tests/test_cli_shell.py
@@ -132,7 +132,8 @@ class TestShell(unittest.TestCase):
         self.assertEqual(results.exit_code, 2)
         self.assertEqual(
             results.output,
-            'Usage: shell [OPTIONS] [RUN_ARGS]...\n\n'
+            'Usage: shell [OPTIONS] [RUN_ARGS]...\n'
+            'Try "shell --help" for help.\n\n'
             'Error: Regular expression requires --run\n')
 
     def test_listspec_without_run(self):
@@ -154,7 +155,8 @@ class TestShell(unittest.TestCase):
         self.assertEqual(results.exit_code, 2)
         self.assertEqual(
             results.output,
-            'Usage: shell [OPTIONS] [RUN_ARGS]...\n\n'
+            'Usage: shell [OPTIONS] [RUN_ARGS]...\n'
+            'Try "shell --help" for help.\n\n'
             'Error: No such list: ant.example.com\n')
 
     def test_run_without_listspec(self):
@@ -171,5 +173,6 @@ class TestShell(unittest.TestCase):
         self.assertEqual(results.exit_code, 2)
         self.assertEqual(
             results.output,
-            'Usage: shell [OPTIONS] [RUN_ARGS]...\n\n'
+            'Usage: shell [OPTIONS] [RUN_ARGS]...\n'
+            'Try "shell --help" for help.\n\n'
             'Error: No such list: bee.example.com\n')