changeset 7547:c8c4514f4c3e

issue685275 - show retired/unretire commands For roundup-admin, add pragma show_retired [no, only, both] to control showing retired items in list and table commands: no - do not show retired only - only show retired both - show retired and unretired (active) items Also sort results of Class::getnodeids() in back_anydbm.py. Anydbm Class::list() expicitly sorts the returned values and a test depends on the order of the returned items. I can't find any docs that say Class::list() sorts and there is no explicit sort in the rdbms_common.py implementation. It looks like the natural order returned in the rdbms case for these methods is sorted. However the test fails for the anydbm case if I don't sort the results of back_anydbm.py:Class::getnodeids() to match back_anydbm.py:Class::list(). This also fixes a spelling error in comment.
author John Rouillard <rouilj@ieee.org>
date Fri, 14 Jul 2023 20:34:30 -0400
parents 534f8bdb8f94
children 793f4b63c538
files roundup/admin.py roundup/backends/back_anydbm.py test/test_admin.py
diffstat 3 files changed, 67 insertions(+), 9 deletions(-) [+]
line wrap: on
line diff
--- a/roundup/admin.py	Fri Jul 14 00:30:44 2023 -0400
+++ b/roundup/admin.py	Fri Jul 14 20:34:30 2023 -0400
@@ -107,7 +107,8 @@
             'display_protected': False,
             'indexer_backend': "as set in config.ini",
             '_reopen_tracker': False,
-            'show_retired': False,
+            'show_retired': "no",
+            '_retired_val': False,
             'verbose': False,
             '_inttest': 3,
             '_floattest': 3.5,
@@ -123,7 +124,8 @@
             '_reopen_tracker':
             _("Force reopening of tracker when running each command."),
 
-            'show_retired': _("Show retired items in table, list etc. NYI"),
+            'show_retired': _("Show retired items in table, list etc. One of 'no', 'only', 'both'"),
+            '_retired_val': _("internal mapping for show_retired."),
             'verbose': _("Enable verbose output: tracing, descriptions..."),
 
             '_inttest': "Integer valued setting. For testing only.",
@@ -533,7 +535,7 @@
 
             for key in keys:
                 value = cl.get(nodeid, key)
-                # prepend * for protected propeties else just indent
+                # prepend * for protected properties else just indent
                 # with space.
                 protected = "*" if key not in normal_props else ' '
                 print(_('%(protected)s%(key)s: %(value)s') % locals())
@@ -1296,6 +1298,9 @@
             raise UsageError(_('Too many arguments supplied'))
         if len(args) < 1:
             raise UsageError(_('Not enough arguments supplied'))
+
+        retired = self.settings['_retired_val']
+
         classname = args[0]
 
         # get the class
@@ -1311,7 +1316,7 @@
             if len(args) == 2:
                 # create a list of propnames since user specified propname
                 proplist = []
-                for nodeid in cl.list():
+                for nodeid in cl.getnodeids(retired=retired):
                     try:
                         proplist.append(cl.get(nodeid, propname))
                     except KeyError:
@@ -1321,9 +1326,9 @@
             else:
                 # create a list of index id's since user didn't specify
                 # otherwise
-                print(self.separator.join(cl.list()))
+                print(self.separator.join(cl.getnodeids(retired=retired)))
         else:
-            for nodeid in cl.list():
+            for nodeid in cl.getnodeids(retired=retired):
                 try:
                     value = cl.get(nodeid, propname)
                 except KeyError:
@@ -1544,7 +1549,18 @@
                     '%(value)s.') % {"setting": setting, "value": value})
             value = _val
         elif type(self.settings[setting]) is str:
-            pass
+            if setting == "show_retired":
+                if value not in ["no", "only", "both"]:
+                    raise UsageError(_(
+                        'Incorrect value for setting %(setting)s: '
+                        '%(value)s. Should be no, both, or only.') % {
+                            "setting": setting, "value": value})
+                if value == "both":
+                    self.settings['_retired_val'] = None
+                elif value == "only":  # numerical value not boolean
+                    self.settings['_retired_val'] = True
+                else:  # numerical value not boolean
+                    self.settings['_retired_val'] = False
         else:
             raise UsageError(_('Internal error: pragma can not handle '
                                'values of type: %s') %
@@ -1863,6 +1879,8 @@
             raise UsageError(_('Not enough arguments supplied'))
         classname = args[0]
 
+        retired = self.settings['_retired_val']
+
         # get the class
         cl = self.get_class(classname)
 
@@ -1903,7 +1921,7 @@
             else:
                 # this is going to be slow
                 maxlen = len(spec)
-                for nodeid in cl.list():
+                for nodeid in cl.getnodeids(retired=retired):
                     curlen = len(str(cl.get(nodeid, spec)))
                     if curlen > maxlen:
                         maxlen = curlen
@@ -1914,7 +1932,7 @@
                         for name, width in props]))
 
         # and the table data
-        for nodeid in cl.list():
+        for nodeid in cl.getnodeids(retired=retired):
             table_columns = []
             for name, width in props:
                 if name != 'id':
--- a/roundup/backends/back_anydbm.py	Fri Jul 14 00:30:44 2023 -0400
+++ b/roundup/backends/back_anydbm.py	Fri Jul 14 20:34:30 2023 -0400
@@ -1707,6 +1707,8 @@
         finally:
             if must_close:
                 db.close()
+
+        res.sort()
         return res
 
     num_re = re.compile(r'^\d+$')
--- a/test/test_admin.py	Fri Jul 14 00:30:44 2023 -0400
+++ b/test/test_admin.py	Fri Jul 14 20:34:30 2023 -0400
@@ -1612,6 +1612,44 @@
         expected="1: admin\n   2: anonymous\n   3: user1"
         self.assertEqual(out, expected)
 
+        # test show_retired pragma three cases:
+        # no - no retired items
+        # only - only retired items
+        # both - all items
+
+        # verify that user4 only is listed
+        self.admin=AdminTool()
+        with captured_output() as (out, err):
+            sys.argv=['main', '-i', self.dirname, '-P',
+                      'show_retired=only', 'list', 'user']
+            ret = self.admin.main()
+        out = out.getvalue().strip()
+        print(out)
+        expected="4: user1"
+        self.assertEqual(out, expected)
+
+        # verify that all users are shown
+        self.admin=AdminTool()
+        with captured_output() as (out, err):
+            sys.argv=['main', '-i', self.dirname, '-P',
+                      'show_retired=both', 'list', 'user']
+            ret = self.admin.main()
+        out = out.getvalue().strip()
+        print(out)
+        expected="1: admin\n   2: anonymous\n   3: user1\n   4: user1"
+        self.assertEqual(out, expected)
+
+
+        # verify that active users
+        self.admin=AdminTool()
+        with captured_output() as (out, err):
+            sys.argv=['main', '-i', self.dirname, '-P',
+                      'show_retired=no', 'list', 'user']
+            ret = self.admin.main()
+        out = out.getvalue().strip()
+        print(out)
+        expected="1: admin\n   2: anonymous\n   3: user1"
+        self.assertEqual(out, expected)
 
 
     def testTable(self):

Roundup Issue Tracker: http://roundup-tracker.org/