sphinxext: Support rootdir discovery without git

Change I49b659948f35381a44e2fb5f91dd6bf9e8ef619e provided a mechanism to
include the release note cache into generated sdists. Unfortunately,
attempting to build documentation with these tarballs generates the
following error:

  Exception occurred:
  File ".../lib/python3.7/site-packages/dulwich/repo.py", line 1004, in discover
    "No git repository was found at %(path)s" % dict(path=start)
  dulwich.errors.NotGitRepository: No git repository was found at PATH

This is because we're attempting to find the root of the git repo using
dulwich, which clearly isn't possible outside of a git repo.

Work around this by falling back to a search. We consider three options:
'.', '..', and '../..', which will handle calling Sphinx from the
rootdir, a 'docs' dir, and a 'docs/source' dir, which seem to be the
most common configurations.

We have no test coverage of the Sphinx integration so this is tested
manually.

Change-Id: Ic3a8ab8b127fd5bf51b91ac6e83d459ffc087fc4
Signed-off-by: Stephen Finucane <stephenfin@redhat.com>
Story: #1520096
Task: #6724
This commit is contained in:
Stephen Finucane 2020-04-20 16:15:28 +01:00
parent 130d9ae143
commit a19cd28f20
2 changed files with 35 additions and 7 deletions

View File

@ -0,0 +1,9 @@
---
fixes:
- |
Previously, it was not possible build documentation that used the
``release-notes`` Sphinx extension from tarballs. The Sphinx extension
will now search the following directories, relative to the working
directory of the ``sphinx-build`` tool, to find the release notes
directory: ``.``, ``..``, and ``../..``. This only applies when it is
not possible to discover this information using git.

View File

@ -50,16 +50,35 @@ class ReleaseNotesDirective(rst.Directive):
'unreleased-version-title': directives.unchanged,
}
def run(self):
title = ' '.join(self.content)
branch = self.options.get('branch')
reporoot_opt = self.options.get('reporoot', '.')
def _find_reporoot(self, reporoot_opt, relnotessubdir_opt):
"""Find root directory of project."""
reporoot = os.path.abspath(reporoot_opt)
# When building on RTD.org the root directory may not be
# the current directory, so look for it.
reporoot = repo.Repo.discover(reporoot).path
relnotessubdir = self.options.get('relnotessubdir',
defaults.RELEASE_NOTES_SUBDIR)
try:
return repo.Repo.discover(reporoot).path
except Exception:
pass
for root in ('.', '..', '../..'):
if os.path.exists(os.path.join(root, relnotessubdir_opt)):
return root
raise Exception(
'Could not discover root directory; tried: %s' % ', '.join([
os.path.abspath(root) for root in ('.', '..', '../..')
])
)
def run(self):
title = ' '.join(self.content)
branch = self.options.get('branch')
relnotessubdir = self.options.get(
'relnotessubdir', defaults.RELEASE_NOTES_SUBDIR,
)
reporoot = self._find_reporoot(
self.options.get('reporoot', '.'), relnotessubdir,
)
ignore_notes = [
name.strip()
for name in self.options.get('ignore-notes', '').split(',')