changeset 49253:a321304269cf

debugindex: move to a flexible column Each column is now declared as a decorated function. This will make it much simpler to add more new column in the future.
author Pierre-Yves David <pierre-yves.david@octobus.net>
date Wed, 01 Jun 2022 00:59:44 +0200
parents 4141951dacff
children 69983adfed06
files mercurial/debugcommands.py mercurial/revlogutils/debug.py
diffstat 2 files changed, 103 insertions(+), 17 deletions(-) [+]
line wrap: on
line diff
--- a/mercurial/debugcommands.py	Wed Jun 01 01:13:13 2022 +0200
+++ b/mercurial/debugcommands.py	Wed Jun 01 00:59:44 2022 +0200
@@ -1877,11 +1877,13 @@
 
     fm = ui.formatter(b'debugindex', opts)
 
+    revlog = getattr(store, b'_revlog', store)
+
     return revlog_debug.debug_index(
         ui,
         repo,
         formatter=fm,
-        revlog=store,
+        revlog=revlog,
         full_node=ui.debugflag,
     )
 
--- a/mercurial/revlogutils/debug.py	Wed Jun 01 01:13:13 2022 +0200
+++ b/mercurial/revlogutils/debug.py	Wed Jun 01 00:59:44 2022 +0200
@@ -10,6 +10,86 @@
     node as nodemod,
 )
 
+from . import (
+    constants,
+)
+
+INDEX_ENTRY_DEBUG_COLUMN = []
+
+NODE_SIZE = object()
+
+
+class _column_base:
+    """constains the definition of a revlog column
+
+    name:       the column header,
+    value_func: the function called to get a value,
+    size:       the width of the column.
+    """
+
+    def __init__(self, name, value_func, size=None):
+        self.name = name
+        self.value_func = value_func
+        if size is not NODE_SIZE:
+            if size is None:
+                size = 8  # arbitrary default
+            size = max(len(name), size)
+        self._size = size
+
+    def get_size(self, node_size):
+        if self._size is NODE_SIZE:
+            return node_size
+        else:
+            return self._size
+
+
+def debug_column(name, size=None):
+    """decorated function is registered as a column
+
+    name: the name of the column,
+    size: the expected size of the column.
+    """
+
+    def register(func):
+        entry = _column_base(
+            name=name,
+            value_func=func,
+            size=size,
+        )
+        INDEX_ENTRY_DEBUG_COLUMN.append(entry)
+        return entry
+
+    return register
+
+
+@debug_column(b"rev", size=6)
+def _rev(index, rev, entry, hexfn):
+    return b"%d" % rev
+
+
+@debug_column(b"linkrev", size=6)
+def _linkrev(index, rev, entry, hexfn):
+    return b"%d" % entry[constants.ENTRY_LINK_REV]
+
+
+@debug_column(b"nodeid", size=NODE_SIZE)
+def _nodeid(index, rev, entry, hexfn):
+    return hexfn(entry[constants.ENTRY_NODE_ID])
+
+
+@debug_column(b"p1-nodeid", size=NODE_SIZE)
+def _p1_node(index, rev, entry, hexfn):
+    parent = entry[constants.ENTRY_PARENT_1]
+    p_entry = index[parent]
+    return hexfn(p_entry[constants.ENTRY_NODE_ID])
+
+
+@debug_column(b"p2-nodeid", size=NODE_SIZE)
+def _p2_node(index, rev, entry, hexfn):
+    parent = entry[constants.ENTRY_PARENT_2]
+    p_entry = index[parent]
+    return hexfn(p_entry[constants.ENTRY_NODE_ID])
+
 
 def debug_index(
     ui,
@@ -31,25 +111,29 @@
 
     fm = formatter
 
-    fm.plain(
-        b'   rev linkrev %s %s %s\n'
-        % (
-            b'nodeid'.rjust(idlen),
-            b'p1-nodeid'.rjust(idlen),
-            b'p2-nodeid'.rjust(idlen),
-        )
-    )
+    header_pieces = []
+    for column in INDEX_ENTRY_DEBUG_COLUMN:
+        size = column.get_size(idlen)
+        name = column.name
+        header_pieces.append(name.rjust(size))
+
+    fm.plain(b' '.join(header_pieces) + b'\n')
+
+    index = revlog.index
 
     for rev in revlog:
-        node = revlog.node(rev)
-        parents = revlog.parents(node)
+        fm.startitem()
+        entry = index[rev]
+        first = True
+        for column in INDEX_ENTRY_DEBUG_COLUMN:
+            if not first:
+                fm.plain(b' ')
+            first = False
 
-        fm.startitem()
-        fm.write(b'rev', b'%6d ', rev)
-        fm.write(b'linkrev', b'%7d ', revlog.linkrev(rev))
-        fm.write(b'node', b'%s ', hexfn(node))
-        fm.write(b'p1', b'%s ', hexfn(parents[0]))
-        fm.write(b'p2', b'%s', hexfn(parents[1]))
+            size = column.get_size(idlen)
+            value = column.value_func(index, rev, entry, hexfn)
+            display = b"%%%ds" % size
+            fm.write(column.name, display, value)
         fm.plain(b'\n')
 
     fm.end()