Skip to content

Commit

Permalink
Fix singlehtml builder explosions, most of the time
Browse files Browse the repository at this point in the history
  • Loading branch information
bitprophet committed Dec 31, 2022
1 parent aee0de5 commit 3efc088
Showing 1 changed file with 29 additions and 15 deletions.
44 changes: 29 additions & 15 deletions releases/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -581,34 +581,48 @@ def construct_nodes(releases):


class BulletListVisitor(nodes.NodeVisitor):
def __init__(self, document, app):
def __init__(self, document, app, docnames):
nodes.NodeVisitor.__init__(self, document)
self.found_changelog = False
self.app = app
# document names to seek out (eg "changelog")
self.docnames = docnames

def visit_bullet_list(self, node):
# The first found bullet list (which should be the first one at the top
# level of the document) is the changelog.
if not self.found_changelog:
self.found_changelog = True
# Walk + parse into release mapping
releases, _ = construct_releases(node.children, self.app)
# Construct new set of nodes to replace the old, and we're done
node.replace_self(construct_nodes(releases))
# Short circuit if already mutated a changelog bullet list or if the
# one being visited doesn't appear to apply.
if self.found_changelog:
return
# The bullet list's parent should be a 'section' node with 'ids'
# attribute derived from the original document name (even in singlehtml
# mode). If we don't see this, move on.
if not set(self.docnames).intersection(node.parent.attributes["ids"]):
return
# At this point, we can safely assume the node we're visiting is the
# right one to mutate.
self.found_changelog = True
# Walk + parse into release mapping
releases, _ = construct_releases(node.children, self.app)
# Construct new set of nodes to replace the old, and we're done
node.replace_self(construct_nodes(releases))

def unknown_visit(self, node):
pass


def generate_changelog(app, doctree, docname):
# Don't scan/mutate documents that don't match the configured document name
# (which by default is ['changelog.rst', ]).
if docname not in app.config.releases_document_name:
desired_docnames = app.config.releases_document_name
# Ensure we still work mostly-correctly in singlehtml builder situations
# (must use name substring test as RTD's singlehtml builder doesn't
# actually inherit from Sphinx's own!)
is_singlepage = "singlehtml" in app.builder.name
changelog_names = ["index"] if is_singlepage else desired_docnames
if docname not in changelog_names:
return

# Find the first bullet-list node & replace it with our organized/parsed
# elements.
changelog_visitor = BulletListVisitor(doctree, app)
# Find an appropriate bullet-list node & replace it with our
# organized/parsed elements.
changelog_visitor = BulletListVisitor(doctree, app, desired_docnames)
doctree.walk(changelog_visitor)


Expand Down

0 comments on commit 3efc088

Please sign in to comment.