]> git.puffer.fish Git - matthieu/frr.git/commitdiff
doc: add ability to disambiguate clicmds
authorQuentin Young <qlyoung@qlyoung.net>
Fri, 29 Sep 2023 00:11:31 +0000 (20:11 -0400)
committerQuentin Young <qlyoung@qlyoung.net>
Thu, 27 Jun 2024 18:47:30 +0000 (14:47 -0400)
Multiple daemons have the same CLI commands defined, but the current
directive used to document CLI commands only takes the command
definition string. Since CLI command objects can be cross-referenced
using the :clicmd: directive, and are placed in the index, each object
needs to be unique.

To accomplish this, add a custom directive. This directive extends the
directive class used by sphinx's add_object_type to add a :daemon:
option. By specifying this option where needed, the object name becomes
"(<daemon>) <definition>", disambiguating it.

Signed-off-by: Quentin Young <qlyoung@qlyoung.net>
doc/user/conf.py

index 629a972726010b0502f9b07b4c6824141c7e097d..a36d4406f3b8419cce206565fec1b36c935aa67e 100644 (file)
@@ -18,6 +18,8 @@ import re
 import pygments
 import sphinx
 from sphinx.highlighting import lexers
+from sphinx.domains.std import GenericObject
+from docutils.parsers.rst import directives
 
 # If extensions (or modules to document with autodoc) are in another directory,
 # add these directories to sys.path here. If the directory is relative to the
@@ -373,13 +375,49 @@ def vparse(s):
     return a[:3]
 
 
-# custom extensions here
+class ClicmdDirective(GenericObject):
+    """
+    Directive for documenting CLI commands.
+
+    The xref string, if no option is provided, will be the verbatim command
+    string. If the :daemon: option is provided, then it's
+    "(<daemon>) <command string>)".
+
+    Options:
+      :daemon: - specify the daemon this command belongs to. Useful for
+                 disambiguating multiple definitions of the same command.
+    """
+
+    has_content = True
+    required_arguments = 1
+    optional_arguments = 0
+    option_spec = {
+        **GenericObject.option_spec,
+        "daemon": directives.unchanged,
+    }
+
+    def handle_signature(self, sig, signode):
+        name = super().handle_signature(sig, signode)
+        daemon = self.options["daemon"] if "daemon" in self.options else ""
+        prefix = f"({daemon}) " if daemon else ""
+        return prefix + name
+
+    def run(self):
+        daemon = self.options["daemon"] if "daemon" in self.options else ""
+        if daemon:
+            self.indextemplate = f"pair: ({daemon}) %s; configuration command"
+        else:
+            self.indextemplate = f"pair: %s; configuration command"
+
+        nodes = super().run()
+
+        return nodes
+
+
 def setup(app):
-    # object type for FRR CLI commands, can be extended to document parent CLI
-    # node later on
-    app.add_object_type(
-        "clicmd", "clicmd", indextemplate="pair: %s; configuration command"
-    )
+    app.add_object_type("clicmd", "clicmd", objname="CLI command")
+    # Override the directive that was just created for us
+    app.add_directive_to_domain("std", "clicmd", ClicmdDirective, override=True)
 
     # I dont care how stupid this is
     if "add_js_file" in dir(app):