This is an automated email from the ASF dual-hosted git repository.

zrhoffman pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/trafficcontrol.git


The following commit(s) were added to refs/heads/master by this push:
     new 4d807577df Add the ability to markup things as being removed in the 
documentation (#7800)
4d807577df is described below

commit 4d807577dfd20fba2e62c04a48eef86d2ce64846
Author: ocket8888 <[email protected]>
AuthorDate: Thu Sep 28 09:05:21 2023 -0600

    Add the ability to markup things as being removed in the documentation 
(#7800)
    
    * Add versionremoved directive
    
    * Best practices updates
    
    - Move imports to the top of the file
    - Ensure type hints everywhere
    - Add docstrings wherever they're missing
    
    * Use old metatypes instead of type literals
---
 docs/source/_ext/atc.py                            | 319 ++++++++++++++-------
 .../v4/deliveryservices_required_capabilities.rst  |   2 +
 2 files changed, 225 insertions(+), 96 deletions(-)

diff --git a/docs/source/_ext/atc.py b/docs/source/_ext/atc.py
index 4b020bb63a..3d60ed762f 100644
--- a/docs/source/_ext/atc.py
+++ b/docs/source/_ext/atc.py
@@ -1,3 +1,7 @@
+"""
+This file is a Sphinx extension used by the ATC project to provide some custom
+behavior to the Sphinx runtime.
+"""
 #
 # Licensed under the Apache License, Version 2.0 (the "License");
 # you may not use this file except in compliance with the License.
@@ -11,116 +15,197 @@
 # See the License for the specific language governing permissions and
 # limitations under the License.
 #
+import os
+import re
+from typing import Any, Final, Optional, Dict, List, Tuple
 
-REPO_URI = "https://github.com/apache/trafficcontrol/";
-
-# -- Implementation detail directive -----------------------------------------
-from docutils import nodes
+from docutils import nodes, utils
+from sphinx.application import Sphinx
 from sphinx.util.docutils import SphinxDirective
-from sphinx.locale import translators, _
+from sphinx.locale import _
+from sphinx.domains import changeset
+
+
+REPO_URI: Final = "https://github.com/apache/trafficcontrol/";
 
 class impl(nodes.Admonition, nodes.Element):
-       pass
+       """
+       This class is just used to provide translatability for the 
documentation.
+       Which is currently unimplemented, but the translators will choke on
+       directives that don't have visit and depart methods defined, so if 
that's
+       ever added in the future the sort of "incomplete" definitions of 
directives
+       here would be a problem.
+       """
 
-def visit_impl_node(self, node):
+def visit_impl_node(self: nodes.Admonition, node: nodes.Node):
+       """
+       Implementation of Node entry for custom admonitions for translation
+       purposes.
+       """
        self.visit_admonition(node)
 
-def depart_impl_node(self, node):
+def depart_impl_node(self: nodes.Admonition, node: nodes.Node):
+       """
+       Implementation of Node entry for custom admonitions for translation
+       purposes.
+       """
        self.depart_admonition(node)
 
+# -- Implementation detail directive -----------------------------------------
 class ImplementationDetail(SphinxDirective):
+       """
+       An admonition that describes something that is possibly interesting or
+       informative context for our particular implementation of something.
+
+       Example:
 
+               .. impl-detail::
+                       This is because the underlying number is 32 bits wide.
+       """
        has_content = True
        required_arguments = 0
        optional_arguments = 1
        final_argument_whitespace = True
 
-       label_text = 'Implementation Detail'
+       label_text = "Implementation Detail"
 
-       def run(self):
-               impl_node = impl('\n'.join(self.content))
+       def run(self) -> List[nodes.Node]:
+               """
+               Converts the content of the directive into a proper Node.
+               """
+               impl_node = impl("\n".join(self.content))
                impl_node += nodes.title(_(self.label_text), _(self.label_text))
                self.state.nested_parse(self.content, self.content_offset, 
impl_node)
                if self.arguments:
                        n, m = self.state.inline_text(self.arguments[0], 
self.lineno)
-                       impl_node.append(nodes.paragraph('', '', *(n + m)))
+                       impl_node.append(nodes.paragraph("", "", *(n + m)))
                return [impl_node]
 
+# -- Version Removed directive ----------------------------------------
+changeset.versionlabels["versionremoved"] = "Removed in version %s"
+changeset.versionlabel_classes["versionremoved"] = "removed"
+class VersionRemoved(changeset.VersionChange):
+       """
+       A directive that annotates the version at which something has been 
removed.
+
+       Example:
+
+               ******************************************
+               ``deliveryservices_required_capabilities``
+               ******************************************
+               .. versionremoved:: 5.0
+                       This is now a property of Delivery Services themselves 
instead.
+       """
+
 # -- Go Version role --------------------------------------------------
 # Returns the value of the Go version stored in GO_VERSION to minor version
 # precision.
-import os
-import re
 
-from docutils.nodes import strong
-from docutils.parsers.rst.states import Inliner
-from typing import Tuple, List
-
-def atc_go_version(unused_typ: str,
-                   unused_rawtext: str,
-                   unused_text: str,
-                   unused_lineno: int,
-                   unused_inliner: Inliner,
-                   options=None,
-                   content=None) -> Tuple[List[strong], list]:
-       go_version_file = os.path.join(os.path.dirname(__file__), 
'../../../GO_VERSION')
-       with open(file=go_version_file) as go_version_file:
+def atc_go_version(
+       unused_typ: None,
+       unused_rawtext: None,
+       unused_text: None,
+       lineno: int,
+       unused_inliner: None,
+       unused_options: None=None,
+       unused_content: None=None
+) -> Tuple[List[nodes.Node], List[nodes.Node]]:
+       """
+       A role that inserts the Go version used/required by this version of ATC.
+
+       Example:
+
+               :atc-go-version:_
+       """
+       go_version_file = os.path.join(os.path.dirname(__file__), 
"../../../GO_VERSION")
+       with open(file=go_version_file, encoding="utf-8") as go_version_file:
                go_version = go_version_file.read()
-       major_minor_version = re.match(pattern=r'\d+\.\d+', 
string=go_version).group()
+
+       matches = re.match(pattern=r"\d+\.\d+", string=go_version)
+       if matches is None:
+               raise ValueError(f"Go version found that could not be parsed: 
'{go_version}' (from line {lineno})")
+       major_minor_version = matches.group()
        strong_node = nodes.strong(major_minor_version, major_minor_version)
        return [strong_node], []
 
 # -- Issue role --------------------------------------------------------------
-from docutils import utils
 
-ISSUE_URI = REPO_URI + "issues/%s"
+ISSUE_URI: Final = REPO_URI + "issues/%s"
+
+def issue_role(
+       unused_typ: None,
+       unused_rawtext: None,
+       text: str,
+       unused_lineno: None,
+       unused_inliner: None,
+       options: Optional[Dict[str, Any]]=None,
+       content: Optional[List[Any]]=None
+) -> Tuple[List[nodes.Node], List[nodes.Node]]:
+       """
+       A role that can be used to link to an Issue by number.
 
-def issue_role(unused_typ,
-               unused_rawtext,
-               text,
-               unused_lineno,
-               unused_inliner,
-               options=None,
-               content=None):
+       Example:
+
+               This is tracked by :issue:1234
+       """
        if options is None:
                options = {}
        if content is None:
                content = []
 
        issue = utils.unescape(text)
-       text = 'Issue #' + issue
+       text = f"Issue #{issue}"
        refnode = nodes.reference(text, text, refuri=ISSUE_URI % issue)
        return [refnode], []
 
 # -- Pull Request Role -------------------------------------------------------
-PR_URI = REPO_URI + "pull/%s"
-
-def pr_role(unused_typ,
-            unused_rawtext,
-            text,
-            unused_lineno,
-            unused_inliner,
-            options=None,
-            content=None):
+PR_URI: Final = REPO_URI + "pull/%s"
+
+def pr_role(
+       unused_typ: None,
+       unused_rawtext: None,
+       text: str,
+       unused_lineno: None,
+       unused_inliner: None,
+       options: Optional[Dict[str, Any]]=None,
+       content: Optional[List[Any]]=None
+) -> Tuple[List[nodes.Node], List[nodes.Node]]:
+       """
+       A role that can be used to link to a Pull Request by number.
+
+       Example:
+
+               This is tracked by :pr:1234
+       """
+
        if options is None:
                options = {}
        if content is None:
                content = []
 
        pr = utils.unescape(text)
-       text = 'Pull Request ' + pr
+       text = f"Pull Request {pr}"
        refnode = nodes.reference(text, text, refuri=PR_URI % pr)
        return [refnode], []
 
 # -- ATC file role -----------------------------------------------------------
 FILE_URI = REPO_URI + "tree/master/%s"
-def atc_file_role(unused_typ,
-                  unused_rawtext,
-                  text,
-                  unused_lineno,
-                  unused_inliner,
-                  options=None,
-                  content=None):
+def atc_file_role(
+       unused_typ: None,
+       unused_rawtext: None,
+       text: str,
+       unused_lineno: None,
+       unused_inliner: None,
+       options: Optional[Dict[str, Any]]=None,
+       content: Optional[List[Any]]=None
+) -> Tuple[List[nodes.Node], List[nodes.Node]]:
+       """
+       A role that can be used to link to a file within the ATC repository.
+
+       Example:
+
+               The version of the ATC project is maintained in 
:atc-file:VERSION
+       """
        if options is None:
                options = {}
        if content is None:
@@ -128,18 +213,27 @@ def atc_file_role(unused_typ,
 
        text = utils.unescape(text)
        litnode = nodes.literal(text, text)
-       refnode = nodes.reference(text, '', litnode, refuri=FILE_URI % text)
+       refnode = nodes.reference(text, "", litnode, refuri=FILE_URI % text)
        return [refnode], []
 
 # -- GoDoc role (absolute) ---------------------------------------------------
-GODOC_URI = "https://pkg.go.dev/";
-def godoc_role(unused_typ,
-               unused_rawtext,
-               text,
-               unused_lineno,
-               unused_inliner,
-               options=None,
-               content=None):
+GODOC_URI: Final = "https://pkg.go.dev/";
+def godoc_role(
+       unused_typ: None,
+       unused_rawtext: None,
+       text: str,
+       unused_lineno: None,
+       unused_inliner: None,
+       options: Optional[Dict[str, Any]]=None,
+       content: Optional[List[Any]]=None
+) -> Tuple[List[nodes.Node], List[nodes.Node]]:
+       """
+       Links to the GoDoc documentation for some package.
+
+       Example:
+
+               We use the :godoc:`github.com/jmoiron/sqlx` package for SQL 
stuff.
+       """
        if options is None:
                options = {}
        if content is None:
@@ -147,22 +241,34 @@ def godoc_role(unused_typ,
 
        text = utils.unescape(text)
        litnode = nodes.literal(text, text)
-       last_period_index = text.rfind('.')
-       if last_period_index != -1 and text.rfind('/') < last_period_index:
-               text = text[:last_period_index] + '#' + text[last_period_index 
+ 1:]
-       refnode = nodes.reference(text, '', litnode, refuri=GODOC_URI + text)
+       last_period_index = text.rfind(".")
+       if last_period_index != -1 and text.rfind("/") < last_period_index:
+               text = text[:last_period_index] + "#" + text[last_period_index 
+ 1:]
+       refnode = nodes.reference(text, "", litnode, refuri=GODOC_URI + text)
        return [refnode], []
 
 # -- GoDoc role (atc-relative) ----------------------------------------------
-ATC_GODOC_PREFIX = "github.com/apache/trafficcontrol/v8/"
-ATC_GODOC_URI = GODOC_URI + ATC_GODOC_PREFIX
-def atc_godoc_role(unused_typ,
-                   unused_rawtext,
-                   text,
-                   unused_lineno,
-                   unused_inliner,
-                   options=None,
-                   content=None):
+ATC_GODOC_PREFIX: Final = "github.com/apache/trafficcontrol/"
+ATC_GODOC_URI: Final = GODOC_URI + ATC_GODOC_PREFIX
+def atc_godoc_role(
+       unused_typ: None,
+       unused_rawtext: None,
+       text: str,
+       unused_lineno: None,
+       unused_inliner: None,
+       options: Optional[Dict[str, Any]]=None,
+       content: Optional[List[Any]]=None
+) -> Tuple[List[nodes.Node], List[nodes.Node]]:
+       """
+       A role that can be used to link to the GoDoc documentation for a symbol 
from
+       the ATC project. This is equivalent to using the ``godoc`` role, but 
allows
+       one to omit "github.com/apache/trafficcontrol", which can be tedious and
+       consume a lot of space.
+
+       Example:
+
+               Servers are modeled by :atc-godoc:`lib/go-tc#ServerV5`
+       """
        if options is None:
                options = {}
        if content is None:
@@ -171,19 +277,32 @@ def atc_godoc_role(unused_typ,
        text = utils.unescape(text)
        literaltext = ATC_GODOC_PREFIX + text
        litnode = nodes.literal(literaltext, literaltext)
-       refnode = nodes.reference(text, '', litnode, refuri=ATC_GODOC_URI + 
text.replace('.', '#', 1))
+       refnode = nodes.reference(text, "", litnode, refuri=ATC_GODOC_URI + 
text.replace(".", "#", 1))
        return [refnode], []
 
 # -- GoDoc role (to-relative) -----------------------------------------------
-TO_GODOC_PREFIX = ATC_GODOC_PREFIX + "traffic_ops/traffic_ops_golang/"
-TO_GODOC_URI = GODOC_URI + TO_GODOC_PREFIX
-def to_godoc_role(unused_typ,
-                  unused_rawtext,
-                  text,
-                  unused_lineno,
-                  unused_inliner,
-                  options=None,
-                  content=None):
+TO_GODOC_PREFIX: Final = ATC_GODOC_PREFIX + "traffic_ops/traffic_ops_golang/"
+TO_GODOC_URI: Final = GODOC_URI + TO_GODOC_PREFIX
+def to_godoc_role(
+       unused_typ: None,
+       unused_rawtext: None,
+       text: str,
+       unused_lineno: None,
+       unused_inliner: None,
+       options: Optional[Dict[Any, Any]]=None,
+       content: Optional[List[Any]]=None
+) -> Tuple[List[nodes.Node], List[nodes.Node]]:
+       """
+       A role that can be used to link to the GoDoc documentation for a symbol 
from
+       within Traffic Ops's package. This is equivalent to using the ``godoc``
+       role, but allows one to omit
+       "github.com/apache/trafficcontrol/traffic_ops/traffic_ops_golang/", 
which
+       can be tedious and consume a lot of space.
+
+       Example:
+
+               API endpoints make heavy use of :to-godoc:`api#APIInfo` objects.
+       """
        if options is None:
                options = {}
        if content is None:
@@ -192,16 +311,24 @@ def to_godoc_role(unused_typ,
        text = utils.unescape(text)
        literaltext = TO_GODOC_PREFIX + text
        litnode = nodes.literal(literaltext, literaltext)
-       refnode = nodes.reference(text, '', litnode, refuri=TO_GODOC_URI + 
text.replace('.', '#', 1))
+       refnode = nodes.reference(text, "", litnode, refuri=TO_GODOC_URI + 
text.replace(".", "#", 1))
        return [refnode], []
 
 
-def setup(app: object) -> dict:
-       app.add_node(impl,
-                    html=(visit_impl_node, depart_impl_node),
-                    latex=(visit_impl_node, depart_impl_node),
-                    text=(visit_impl_node, depart_impl_node))
+def setup(app: Sphinx) -> Dict[str, Any]:
+       """
+       This is the function that adds all of the above declared directives and
+       roles to the Sphinx environment. In order to make use of a new 
directive or
+       role, you **must** add it to the app within this setup function.
+       """
+       app.add_node(
+               impl,
+               html=(visit_impl_node, depart_impl_node),
+               latex=(visit_impl_node, depart_impl_node),
+               text=(visit_impl_node, depart_impl_node)
+       )
        app.add_directive("impl-detail", ImplementationDetail)
+       app.add_directive("versionremoved", VersionRemoved)
        app.add_role("atc-go-version", atc_go_version)
        app.add_role("issue", issue_role)
        app.add_role("pr", pr_role)
@@ -212,7 +339,7 @@ def setup(app: object) -> dict:
        app.add_role("to-godoc", to_godoc_role)
 
        return {
-               'version': '0.2',
-               'parallel_read_safe': True,
-               'parallel_write_safe': True,
+               "version": "1.0",
+               "parallel_read_safe": True,
+               "parallel_write_safe": True,
        }
diff --git a/docs/source/api/v4/deliveryservices_required_capabilities.rst 
b/docs/source/api/v4/deliveryservices_required_capabilities.rst
index e9086e701b..35076fc436 100644
--- a/docs/source/api/v4/deliveryservices_required_capabilities.rst
+++ b/docs/source/api/v4/deliveryservices_required_capabilities.rst
@@ -22,6 +22,8 @@
 .. deprecated:: 4.1
        This endpoint will be removed in a future release, in favor of 
:ref:`ds-required-capabilities` being a part of :term:`Delivery Services`.
 
+.. versionremoved:: 5.0
+
 ``GET``
 =======
 Gets all associations of :term:`Server Capability` to :term:`Delivery 
Services`.

Reply via email to