Sign in

Search issue titles and bodies, change requests and comments. Private repositories you cannot read are not included.

vole
Clone

Read only, no credentials:

https://rodent.software/vole.git

Write over SSH with a registered key:

git clone ssh://git@rodent.software:2222/vole.git

A free and open-source forge that lives in your Git repo.

Code

395 commit(s) on main

update readme Keenan Nemetz · 29m ago 32290114
history blame raw 1.2 KiB
1#!/usr/bin/env python3
2"""Fail when a Markdown file links to a relative path that does not exist.
3
4Absolute URLs, mail links, and fragments are left alone: only links that claim to
5point at a file in this checkout are checked, which is what a reorganisation
6quietly breaks.
7"""
8
9import os
10import re
11import sys
12
13SKIP_DIRS = {".git", "data", "dist"}
14
15
16def main() -> int:
17 bad = []
18 for root, dirs, files in os.walk("."):
19 dirs[:] = [d for d in dirs if d not in SKIP_DIRS]
20 for name in files:
21 if not name.endswith(".md"):
22 continue
23 path = os.path.join(root, name)
24 with open(path, encoding="utf-8") as f:
25 text = f.read()
26 for match in re.finditer(r"\]\(([^)#][^)]*)\)", text):
27 target = match.group(1)
28 if target.startswith(("http://", "https://", "mailto:")):
29 continue
30 resolved = os.path.normpath(os.path.join(root, target.split("#")[0]))
31 if not os.path.exists(resolved):
32 bad.append(f"{path}: {target}")
33 if bad:
34 print("\n".join(bad))
35 return 1
36 return 0
37
38
39if __name__ == "__main__":
40 sys.exit(main())
41