Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 8 additions & 1 deletion bin/check-site-rot.py
Original file line number Diff line number Diff line change
Expand Up @@ -227,7 +227,14 @@ def resolve(path):
homelinks = {m for m in re.findall(r'href="/([a-z0-9-]+)/"', texts[""])}
for p in sorted(homelinks - page_set):
bad("home: links /%s/ which is not a page" % p)
for p in sorted(page_set - homelinks):
# The home page links a few guides and /guides/, which lists every guide: a page linked from /guides/ counts as linked from home.
reachable = set(homelinks)
if "guides" in page_set:
if "guides" in homelinks:
reachable |= {m for m in re.findall(r'href="/([a-z0-9-]+)/"', texts.get("guides", ""))}
else:
bad("home: does not link /guides/ (the page that lists every guide)")
for p in sorted(page_set - reachable):
bad("home: does not link /%s/ (the Guides list or another section should)" % p)

for line in problems:
Expand Down
60 changes: 60 additions & 0 deletions bin/test-check-site-rot.sh
Original file line number Diff line number Diff line change
Expand Up @@ -83,9 +83,69 @@ import sys
p, slug = sys.argv[1:3]
s = open(p).read().replace('href="/%s/"' % slug, 'href="/"')
open(p, "w").write(s)
# a site with a /guides/ page lists every guide there: take the page off that list too
import os
g = os.path.join(os.path.dirname(p), "guides", "index.html")
if os.path.isfile(g):
gs = open(g).read()
open(g, "w").write(gs.replace('href="/%s/"' % slug, 'href="/"'))
EOF
expect_fail "a page the home page no longer links" "home: does not link"

# /guides/ lists the guides. Built in the throwaway copy, so these cases run on every site, with or without a real /guides/.
# The home page links /guides/ and not $first; /guides/ links $first.
with_guides() {
fresh
python3 - "$site" "$first" "$second" <<'EOF'
import os, re, sys
site, first, second = sys.argv[1:4]
real = os.path.join(site, "guides")
if os.path.isfile(os.path.join(real, "index.html")):
# a real /guides/ page: keep it, and make sure it lists $first
src = open(os.path.join(real, "index.html")).read()
else:
src = open(os.path.join(site, second, "index.html")).read()
src = re.sub(r"<title>.*?</title>", "<title>Guides</title>", src, count=1, flags=re.S)
src = src.replace("/%s/" % second, "/guides/")
os.makedirs(real, exist_ok=True)
if 'href="/%s/"' % first not in src:
src = src.replace("</main>", '<p><a href="/%s/">listed guide</a></p></main>' % first, 1)
open(os.path.join(real, "index.html"), "w").write(src)
home = os.path.join(site, "index.html")
h = open(home).read().replace('href="/%s/"' % first, 'href="/"')
if 'href="/guides/"' not in h:
h = h.replace("</main>", '<p><a href="/guides/">All guides</a></p></main>', 1)
open(home, "w").write(h)
sm = os.path.join(site, "sitemap.xml")
m = open(sm).read()
if "/guides/</loc>" not in m:
open(sm, "w").write(m.replace("</urlset>", "<url><loc>https://fosterstack.com/guides/</loc></url></urlset>", 1))
ll = os.path.join(site, "llms.txt")
l = open(ll).read()
if "fosterstack.com/guides/)" not in l:
open(ll, "w").write(l.rstrip("\n") + "\n- [Guides](https://fosterstack.com/guides/): all guides\n")
EOF
}

with_guides; expect_pass "a page linked only from /guides/ counts as linked from home"

with_guides; python3 - "$site/guides/index.html" "$first" <<'EOF'
import sys
p, slug = sys.argv[1:3]
s = open(p).read()
open(p, "w").write(s.replace('href="/%s/"' % slug, 'href="/"'))
EOF
expect_fail "a page on neither the home page nor /guides/" "home: does not link /$first/"

with_guides; python3 - "$site/index.html" <<'EOF'
import sys
p = sys.argv[1]
s = open(p).read()
open(p, "w").write(s.replace('href="/guides/"', 'href="/"'))
EOF
expect_fail "a home page that does not link /guides/" "home: does not link /guides/"
expect_fail "a /guides/ page the home page does not link lists nothing for home" "home: does not link /$first/"

fresh; edit "$site/$first/index.html" "REGEX:<title>.*?</title>" "<title>This title is deliberately far too long to be a good page title for a search result</title>"
expect_fail "a title over 60 characters" "characters (max 60)"

Expand Down
Loading