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`.