Skip to content

Commit

Permalink
docs: Add a test to validate URLs in markdown/Users.md
Browse files Browse the repository at this point in the history
Avoid piling up dead URLs.
  • Loading branch information
dnicolodi committed Jan 11, 2025
1 parent a86476c commit e348bf9
Show file tree
Hide file tree
Showing 3 changed files with 46 additions and 2 deletions.
2 changes: 1 addition & 1 deletion .github/workflows/website.yml
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ jobs:
- name: Install package
run: |
sudo apt-get -y install python3-pip ninja-build libjson-glib-dev
pip install hotdoc chevron strictyaml
pip install hotdoc chevron strictyaml aiohttp
- uses: actions/cache/save@v4
with:
Expand Down
4 changes: 3 additions & 1 deletion docs/meson.build
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
project('Meson documentation', version: '1.0')

yaml_modname = get_option('unsafe_yaml') ? 'yaml' : 'strictyaml'
py = import('python').find_installation('python3', modules: [yaml_modname], required: false)
py = import('python').find_installation('python3', modules: [yaml_modname, 'aiohttp'], required: false)
if not py.found()
error(f'Cannot build documentation without yaml support')
endif
Expand Down Expand Up @@ -145,3 +145,5 @@ run_target('upload',
],
depends: documentation,
)

test('validate_links', find_program('./validatelinks.py'), args: meson.current_source_dir() / 'markdown' / 'Users.md')
42 changes: 42 additions & 0 deletions docs/validatelinks.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
#!/usr/bin/env python3

# SPDX-License-Identifier: Apache-2.0
# Copyright 2025 The Meson development team

import sys
import re
import aiohttp
import asyncio

LINK = re.compile(r'\[(?P<name>[A-Za-z0-9 ]+)\]\((?P<url>.*?)\)')


async def fetch(session, name, url, timeout):
try:
async with session.get(url, timeout=timeout) as r:
if not r.ok:
return (name, url, r.status)
except Exception as e:
return (name, url, str(e))


async def main(filename):
with open(filename) as f:
text = f.read()
timeout = aiohttp.ClientTimeout(total=60)
async with aiohttp.ClientSession() as session:
tasks = []
for link in LINK.finditer(text):
name, url = link.groups()
task = asyncio.ensure_future(fetch(session, name, url, timeout))
tasks.append(task)
responses = asyncio.gather(*tasks)
errors = [r for r in await responses if r is not None]
for name, url, result in errors:
print(f'"{name}" {url} {result}')
if errors:
sys.exit(1)


if __name__ == '__main__':
asyncio.run(main(sys.argv[1]))

0 comments on commit e348bf9

Please sign in to comment.