aboutsummaryrefslogtreecommitdiff
path: root/util/ci/index_generator.py
blob: f2f7f4d41671a19cdd6499d5ddb9ea7734005922 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
#!/usr/bin/env python3

import os
import re
import shlex
import subprocess
from pathlib import Path

from ansi2html import Ansi2HTMLConverter
from jinja2 import Environment, FileSystemLoader, select_autoescape

orig_cwd = os.getcwd()
qmk_firmware_dir = Path(os.path.realpath(__file__)).parents[2]
build_dir = qmk_firmware_dir / ".build"

KEYBOARD_PATTERN = re.compile("CI Metadata: KEYBOARD=(?P<keyboard>.*)\r?\n")
KEYMAP_PATTERN = re.compile("CI Metadata: KEYMAP=(?P<keymap>.*)\r?\n")

env = Environment(
    loader=FileSystemLoader(Path(os.path.realpath(__file__)).parent / "templates"),
    autoescape=select_autoescape(),
)


def _run(command, capture_output=True, combined_output=False, text=True, **kwargs):
    if isinstance(command, str):
        command = shlex.split(command)
    if capture_output:
        kwargs["stdout"] = subprocess.PIPE
        kwargs["stderr"] = subprocess.PIPE
    if combined_output:
        kwargs["stderr"] = subprocess.STDOUT
    if "stdin" in kwargs and kwargs["stdin"] is None:
        del kwargs["stdin"]
    if text:
        kwargs["universal_newlines"] = True
    return subprocess.run(command, **kwargs)


def _ansi2html(value):
    return Ansi2HTMLConverter().convert(value, full=False)


def _ansi2html_styles():
    from ansi2html.style import get_styles

    styles = get_styles(scheme="dracula")
    return "\n".join([str(s) for s in styles])


def _git_log(count=4):
    os.chdir(qmk_firmware_dir)
    ret = _run(f"git log -n {count} --color=always --no-merges --topo-order --stat").stdout.strip()
    os.chdir(orig_cwd)
    return ret


def _git_describe():
    os.chdir(qmk_firmware_dir)
    ret = _run("git describe --tags --always --dirty").stdout.strip()
    os.chdir(orig_cwd)
    return ret


def _git_revision():
    os.chdir(qmk_firmware_dir)
    ret = _run("git rev-parse HEAD").stdout.strip()
    os.chdir(orig_cwd)
    return ret


env.filters["ansi2html"] = _ansi2html

binaries = []
binaries.extend(qmk_firmware_dir.glob("*.bin"))
binaries.extend(qmk_firmware_dir.glob("*.hex"))
binaries.extend(qmk_firmware_dir.glob("*.uf2"))
binaries = list(sorted(binaries))

failures = []
for mdfile in list(sorted(build_dir.glob("failed.log.*"))):
    txt = Path(mdfile).read_text()

    m_kb = KEYBOARD_PATTERN.search(txt)
    if not m_kb:
        raise Exception("Couldn't determine the keyboard from the failure output")
    m_km = KEYMAP_PATTERN.search(txt)
    if not m_km:
        raise Exception("Couldn't determine the keymap from the failure output")

    txt = KEYBOARD_PATTERN.sub("", KEYMAP_PATTERN.sub("", txt)).strip()

    failures.append({
        "stdout": txt,
        "keyboard": m_kb.group("keyboard"),
        "keymap": m_km.group("keymap"),
    })

template = env.get_template("index.html.j2")
print(template.render(
    ansi2html_styles=_ansi2html_styles(),
    git_log=_git_log(),
    git_describe=_git_describe(),
    git_revision=_git_revision(),
    binaries=binaries,
    failures=failures,
))