Parent directory

index_generator.py

2974 bytes
  1#!/usr/bin/env python3
  2
  3import os
  4import re
  5import shlex
  6import subprocess
  7from pathlib import Path
  8
  9from ansi2html import Ansi2HTMLConverter
 10from jinja2 import Environment, FileSystemLoader, select_autoescape
 11
 12orig_cwd = os.getcwd()
 13qmk_firmware_dir = Path(os.path.realpath(__file__)).parents[2]
 14build_dir = qmk_firmware_dir / ".build"
 15
 16KEYBOARD_PATTERN = re.compile("CI Metadata: KEYBOARD=(?P<keyboard>.*)\r?\n")
 17KEYMAP_PATTERN = re.compile("CI Metadata: KEYMAP=(?P<keymap>.*)\r?\n")
 18
 19env = Environment(
 20    loader=FileSystemLoader(Path(os.path.realpath(__file__)).parent / "templates"),
 21    autoescape=select_autoescape(),
 22)
 23
 24
 25def _run(command, capture_output=True, combined_output=False, text=True, **kwargs):
 26    if isinstance(command, str):
 27        command = shlex.split(command)
 28    if capture_output:
 29        kwargs["stdout"] = subprocess.PIPE
 30        kwargs["stderr"] = subprocess.PIPE
 31    if combined_output:
 32        kwargs["stderr"] = subprocess.STDOUT
 33    if "stdin" in kwargs and kwargs["stdin"] is None:
 34        del kwargs["stdin"]
 35    if text:
 36        kwargs["universal_newlines"] = True
 37    return subprocess.run(command, **kwargs)
 38
 39
 40def _ansi2html(value):
 41    return Ansi2HTMLConverter().convert(value, full=False)
 42
 43
 44def _ansi2html_styles():
 45    from ansi2html.style import get_styles
 46
 47    styles = get_styles(scheme="dracula")
 48    return "\n".join([str(s) for s in styles])
 49
 50
 51def _git_log(count=4):
 52    os.chdir(qmk_firmware_dir)
 53    ret = _run(f"git log -n {count} --color=always --no-merges --topo-order --stat").stdout.strip()
 54    os.chdir(orig_cwd)
 55    return ret
 56
 57
 58def _git_describe():
 59    os.chdir(qmk_firmware_dir)
 60    ret = _run("git describe --tags --always --dirty").stdout.strip()
 61    os.chdir(orig_cwd)
 62    return ret
 63
 64
 65def _git_revision():
 66    os.chdir(qmk_firmware_dir)
 67    ret = _run("git rev-parse HEAD").stdout.strip()
 68    os.chdir(orig_cwd)
 69    return ret
 70
 71
 72env.filters["ansi2html"] = _ansi2html
 73
 74binaries = []
 75binaries.extend(qmk_firmware_dir.glob("*.bin"))
 76binaries.extend(qmk_firmware_dir.glob("*.hex"))
 77binaries.extend(qmk_firmware_dir.glob("*.uf2"))
 78binaries = list(sorted(binaries))
 79
 80failures = []
 81for mdfile in list(sorted(build_dir.glob("failed.log.*"))):
 82    txt = Path(mdfile).read_text()
 83
 84    m_kb = KEYBOARD_PATTERN.search(txt)
 85    if not m_kb:
 86        raise Exception("Couldn't determine the keyboard from the failure output")
 87    m_km = KEYMAP_PATTERN.search(txt)
 88    if not m_km:
 89        raise Exception("Couldn't determine the keymap from the failure output")
 90
 91    txt = KEYBOARD_PATTERN.sub("", KEYMAP_PATTERN.sub("", txt)).strip()
 92
 93    failures.append({
 94        "stdout": txt,
 95        "keyboard": m_kb.group("keyboard"),
 96        "keymap": m_km.group("keymap"),
 97    })
 98
 99template = env.get_template("index.html.j2")
100print(template.render(
101    ansi2html_styles=_ansi2html_styles(),
102    git_log=_git_log(),
103    git_describe=_git_describe(),
104    git_revision=_git_revision(),
105    binaries=binaries,
106    failures=failures,
107))