feat: documents and session tokens
This commit is contained in:
39 files changed
+1523
-199
No files matched your search
+49
-3
@@ -31,6 +31,8 @@ from tools.oracle.text import cp_to_utf16, letter_first, mint_node_id, norm, rec
|
||||
from tools.oracle.tree import Refusal # noqa: E402
|
||||
|
||||
FAILS = []
|
||||
# Folders that are not part of the repository: version control, environments and caches.
|
||||
SKIP_DIRS = {".git", ".pixi", "node_modules", "__pycache__"}
|
||||
COUNTS = {}
|
||||
|
||||
|
||||
@@ -55,6 +57,7 @@ def js(path):
|
||||
|
||||
|
||||
STORE = Store(p("schemas"))
|
||||
SCHEMA_FILES = sorted(f for f in os.listdir(p("schemas")) if f.endswith(".schema.json"))
|
||||
FORMAT_SCHEMA = {f["format"]: f["schema"] for f in js(p("registry", "formats.json"))["formats"]}
|
||||
|
||||
|
||||
@@ -63,7 +66,7 @@ def schema_errors(name, rec):
|
||||
|
||||
|
||||
def check_schemas():
|
||||
for f in sorted(os.listdir(p("schemas"))):
|
||||
for f in SCHEMA_FILES:
|
||||
s = STORE.load(f)
|
||||
ok("schemas", s.get("$id", "").endswith("/" + f), "%s: $id must end with its file name" % f)
|
||||
for f in js(p("registry", "formats.json"))["formats"]:
|
||||
@@ -73,7 +76,7 @@ def check_schemas():
|
||||
import jsonschema # noqa: F401
|
||||
from referencing import Registry, Resource
|
||||
reg = Registry().with_resources(
|
||||
[(STORE.load(f)["$id"], Resource.from_contents(STORE.load(f))) for f in os.listdir(p("schemas"))])
|
||||
[(STORE.load(f)["$id"], Resource.from_contents(STORE.load(f))) for f in SCHEMA_FILES])
|
||||
COUNTS["second-validator"] = 0
|
||||
globals()["SECOND"] = (jsonschema, reg)
|
||||
except ImportError:
|
||||
@@ -460,7 +463,7 @@ ABBREV = re.compile(r"\b(e\.g|i\.e|et al|cf|vs|Fig|Eq|Ref|ca|No|St|Dr|Mr|Ms|al)\
|
||||
def check_prose():
|
||||
mds = []
|
||||
for d, dirs, fs in os.walk(ROOT):
|
||||
dirs[:] = [x for x in dirs if x not in (".git", "node_modules", "__pycache__")]
|
||||
dirs[:] = [x for x in dirs if x not in SKIP_DIRS]
|
||||
mds += [os.path.join(d, f) for f in fs if f.endswith(".md")]
|
||||
for path in sorted(mds):
|
||||
rel = os.path.relpath(path, ROOT)
|
||||
@@ -479,6 +482,48 @@ def check_prose():
|
||||
ok("prose", not SENTENCE_BREAK.search(body), "%s:%d: one sentence per line" % (rel, i))
|
||||
|
||||
|
||||
def _slug(heading):
|
||||
"""A heading's anchor, as GitHub, Gitea and Forgejo compute it."""
|
||||
t = re.sub(r"[`*]", "", heading.strip().lower())
|
||||
t = "".join(ch for ch in t if ch.isalnum() or ch in " -_")
|
||||
return t.replace(" ", "-")
|
||||
|
||||
|
||||
def check_links():
|
||||
anchors = {}
|
||||
mds = []
|
||||
for d, dirs, fs in os.walk(ROOT):
|
||||
dirs[:] = [x for x in dirs if x not in SKIP_DIRS]
|
||||
mds += [os.path.join(d, f) for f in fs if f.endswith(".md")]
|
||||
for path in mds:
|
||||
seen, fence = {}, False
|
||||
for ln in open(path, encoding="utf-8"):
|
||||
if ln.startswith("```"):
|
||||
fence = not fence
|
||||
elif not fence and ln.startswith("#"):
|
||||
base = _slug(ln.lstrip("#"))
|
||||
n = seen.get(base, 0)
|
||||
seen[base] = n + 1
|
||||
anchors.setdefault(path, set()).add(base if n == 0 else "%s-%d" % (base, n))
|
||||
for path in sorted(mds):
|
||||
fence = False
|
||||
for i, ln in enumerate(open(path, encoding="utf-8"), 1):
|
||||
if ln.startswith("```"):
|
||||
fence = not fence
|
||||
continue
|
||||
if fence:
|
||||
continue
|
||||
for target in re.findall(r"\]\(([^)\s]+)\)", re.sub(r"`[^`]*`", "", ln)):
|
||||
if re.match(r"^[a-z]+:", target):
|
||||
continue
|
||||
file, _, frag = target.partition("#")
|
||||
dest = os.path.normpath(os.path.join(os.path.dirname(path), file)) if file else path
|
||||
rel = os.path.relpath(path, ROOT)
|
||||
ok("links", os.path.exists(dest), "%s:%d: no such file %s" % (rel, i, file))
|
||||
if frag and dest.endswith(".md") and os.path.exists(dest):
|
||||
ok("links", frag in anchors.get(dest, ()), "%s:%d: no heading #%s in %s" % (rel, i, frag, file or "this file"))
|
||||
|
||||
|
||||
def main():
|
||||
check_schemas()
|
||||
check_registry()
|
||||
@@ -490,6 +535,7 @@ def main():
|
||||
check_determinism()
|
||||
check_sql()
|
||||
check_prose()
|
||||
check_links()
|
||||
for k in sorted(COUNTS):
|
||||
print("%-17s %5d checks" % (k, COUNTS[k]))
|
||||
if FAILS:
|
||||
|
||||
Reference in new issue
Block a user