about summary refs log tree commit diff stats
path: root/archive/2024/winter/bsc_dichler/scripts/execution.py
blob: 51c1db4be398eee53e1d9f2e47c95bc17391183f (plain) (blame)
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
import asyncio
from logging import info, error


async def run(command: str | list[str], cwd: str | None = None) -> str:
    if isinstance(command, list):
        command = " && ".join(command)

    command = command.strip()
    assert command.startswith("&&") == False, "already prefixed with '&&'"

    info(command)
    cp = await asyncio.create_subprocess_shell(
        cmd=command,
        stdout=asyncio.subprocess.PIPE,
        stderr=asyncio.subprocess.PIPE,
        cwd=cwd,
    )

    async def read_stream(stream, logger):
        lines = ""
        while True:
            line = await stream.readline()
            if not line:
                return lines
            line = line.decode().strip()
            lines += line
            logger(line)

    output: tuple[str, str] = await asyncio.gather(
        read_stream(cp.stdout, info),
        read_stream(cp.stderr, error),
    )

    _ = await cp.wait()
    if cp.returncode == 1:
        error("Failed.")
        exit(1)

    return output[0]