Close #5208: linkcheck: Support checks for local links

This commit is contained in:
Takeshi KOMIYA 2020-02-09 20:22:22 +09:00
parent f30284ef92
commit f95ba21f4a
4 changed files with 26 additions and 7 deletions

View File

@ -27,6 +27,7 @@ Features added
* #7902: html theme: Add a new option :confval:`globaltoc_maxdepth` to control
the behavior of globaltoc in sidebar
* #7840: i18n: Optimize the dependencies check on bootstrap
* #5208: linkcheck: Support checks for local links
* #7052: add ``:noindexentry:`` to the Python, C, C++, and Javascript domains.
Update the documentation to better reflect the relationship between this option
and the ``:noindex:`` option.

View File

@ -35,6 +35,8 @@ from sphinx.util.requests import is_ssl_error
logger = logging.getLogger(__name__)
uri_re = re.compile('[a-z]+://')
DEFAULT_REQUEST_HEADERS = {
'Accept': 'text/html,application/xhtml+xml;q=0.9,*/*;q=0.8',
@ -210,10 +212,21 @@ class CheckExternalLinksBuilder(Builder):
def check() -> Tuple[str, str, int]:
# check for various conditions without bothering the network
if len(uri) == 0 or uri.startswith(('#', 'mailto:', 'ftp:')):
if len(uri) == 0 or uri.startswith(('#', 'mailto:')):
return 'unchecked', '', 0
elif not uri.startswith(('http:', 'https:')):
return 'local', '', 0
if uri_re.match(uri):
# non supported URI schemes (ex. ftp)
return 'unchecked', '', 0
else:
if path.exists(path.join(self.srcdir, uri)):
return 'working', '', 0
else:
for rex in self.to_ignore:
if rex.match(uri):
return 'ignored', '', 0
else:
return 'broken', '', 0
elif uri in self.good:
return 'working', 'old', 0
elif uri in self.broken:

View File

@ -11,6 +11,8 @@ Some additional anchors to exercise ignore code
* `Example Bar invalid <https://www.google.com/#top>`_
* `Example anchor invalid <http://www.sphinx-doc.org/en/1.7/intro.html#does-not-exist>`_
* `Complete nonsense <https://localhost:7777/doesnotexist>`_
* `Example valid local file <conf.py>`_
* `Example invalid local file <path/to/notfound>`_
.. image:: https://www.google.com/image.png
.. figure:: https://www.google.com/image2.png

View File

@ -30,7 +30,9 @@ def test_defaults(app, status, warning):
# images should fail
assert "Not Found for url: https://www.google.com/image.png" in content
assert "Not Found for url: https://www.google.com/image2.png" in content
assert len(content.splitlines()) == 5
# looking for local file should fail
assert "[broken] path/to/notfound" in content
assert len(content.splitlines()) == 6
@pytest.mark.sphinx('linkcheck', testroot='linkcheck', freshenv=True)
@ -47,8 +49,8 @@ def test_defaults_json(app, status, warning):
"info"]:
assert attr in row
assert len(content.splitlines()) == 8
assert len(rows) == 8
assert len(content.splitlines()) == 10
assert len(rows) == 10
# the output order of the rows is not stable
# due to possible variance in network latency
rowsby = {row["uri"]:row for row in rows}
@ -69,7 +71,7 @@ def test_defaults_json(app, status, warning):
assert dnerow['uri'] == 'https://localhost:7777/doesnotexist'
assert rowsby['https://www.google.com/image2.png'] == {
'filename': 'links.txt',
'lineno': 16,
'lineno': 18,
'status': 'broken',
'code': 0,
'uri': 'https://www.google.com/image2.png',
@ -92,7 +94,8 @@ def test_defaults_json(app, status, warning):
'https://localhost:7777/doesnotexist',
'http://www.sphinx-doc.org/en/1.7/intro.html#',
'https://www.google.com/image.png',
'https://www.google.com/image2.png']
'https://www.google.com/image2.png',
'path/to/notfound']
})
def test_anchors_ignored(app, status, warning):
app.builder.build_all()