Uzdevumu teksta pirmie vārdi 68. lpp. bija nonākuši ailē „Nr.”; pārbaudei pievienota apgrieztā vārdu pārbaude. Atribūts currentOrg/currentSince: septiņiem VARAM vides un klimata uzdevumiem — KEM 20-0000. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_016679RwmHsuTFfxt26wP6rk
71 lines
3.3 KiB
Python
71 lines
3.3 KiB
Python
#!/usr/bin/env python3
|
|
"""Strategy-as-Code pārbaudītājs.
|
|
|
|
python3 tools/validate.py [--registry organizacijas.xml]
|
|
|
|
Katram dokumentam katalogā planosanas-dokumenti.yaml:
|
|
- datne atbilst XSD shēmai schemas/strategija-0.1.xsd (arī atslēgas un atsauces shēmā);
|
|
- datnes nosaukums = dokumenta identifikators;
|
|
- avota PDF sha256 sakrīt ar Metadata/Source/SHA256;
|
|
- visi VPK ID (Actors, Responsible, CoResponsible, Abbreviation, Developer) ir Valsts institūciju reģistrā;
|
|
- pārbaudes atskaite verification/<id>.verify.json ir par šo pašu avota PDF un ir izturēta.
|
|
Reģistrs pēc noklusējuma — ProcessGit Valdibas-Deklaracija-as-Code data/organizacijas.xml.
|
|
"""
|
|
import hashlib
|
|
import json
|
|
import os
|
|
import sys
|
|
import urllib.request
|
|
|
|
import yaml
|
|
from lxml import etree
|
|
|
|
ROOT = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
|
|
NS = {"s": "urn:pppa:vpk:strategija:0.1"}
|
|
REG_URL = "https://processgit.org/Valsts-Pirmkods/Valdibas-Deklaracija-as-Code/raw/branch/main/data/organizacijas.xml"
|
|
|
|
|
|
def main():
|
|
reg_src = sys.argv[sys.argv.index("--registry") + 1] if "--registry" in sys.argv else REG_URL
|
|
reg = etree.parse(reg_src if os.path.exists(reg_src) else
|
|
urllib.request.urlopen(urllib.request.Request(reg_src, headers={"User-Agent": "strategy-as-code-validate/0.1"})))
|
|
ids = {o.get("id") for o in reg.getroot() if etree.QName(o).localname == "Organization"}
|
|
xsd = etree.XMLSchema(etree.parse(os.path.join(ROOT, "schemas/strategija-0.1.xsd")))
|
|
cat = yaml.safe_load(open(os.path.join(ROOT, "planosanas-dokumenti.yaml"), encoding="utf-8"))
|
|
errors, n = [], 0
|
|
for d in cat["documents"]:
|
|
if not d.get("as_code", {}).get("path"):
|
|
continue
|
|
n += 1
|
|
path = os.path.join(ROOT, d["as_code"]["path"])
|
|
doc = etree.parse(path)
|
|
if not xsd.validate(doc):
|
|
errors += [f"{d['id']}: XSD {e.line}: {e.message}" for e in list(xsd.error_log)[:10]]
|
|
root = doc.getroot()
|
|
if root.get("id") != d["id"] or os.path.basename(path) != d["id"] + ".xml":
|
|
errors.append(f"{d['id']}: datnes nosaukums vai id neatbilst katalogam")
|
|
src = os.path.join(ROOT, root.findtext("s:Metadata/s:Source/s:File", namespaces=NS))
|
|
sha = hashlib.sha256(open(src, "rb").read()).hexdigest()
|
|
if sha != root.findtext("s:Metadata/s:Source/s:SHA256", namespaces=NS):
|
|
errors.append(f"{d['id']}: avota sha256 nesakrīt")
|
|
used = {e.get(k) for e in root.iter() for k in ("org", "currentOrg") if e.get(k)}
|
|
missing = sorted(used - ids)
|
|
if missing:
|
|
errors.append(f"{d['id']}: VPK ID nav reģistrā: {', '.join(missing)}")
|
|
vpath = os.path.join(ROOT, "verification", d["id"] + ".verify.json")
|
|
if os.path.exists(vpath):
|
|
v = json.load(open(vpath, encoding="utf-8"))
|
|
if v.get("pdf_sha256") != sha or not v.get("passed"):
|
|
errors.append(f"{d['id']}: pārbaudes atskaite nav izturēta vai ir par citu avota datni")
|
|
else:
|
|
errors.append(f"{d['id']}: nav pārbaudes atskaites {vpath}")
|
|
print(f"{d['id']}: {len(doc.findall('.//s:Item', NS))} punkti, {len(used)} VPK ID")
|
|
for e in errors:
|
|
print("KĻŪDA", e)
|
|
print("pārbaudīti dokumenti:", n, "kļūdas:", len(errors))
|
|
sys.exit(1 if errors else 0)
|
|
|
|
|
|
if __name__ == "__main__":
|
|
main()
|