1import contextlib
2import pathlib
3from pathlib import Path
4import re
5import time
6from typing import Union
7from unittest import mock
8
9
10def flatten_result(result):
11    return re.sub(r"[\s\r\n]+", " ", result).strip()
12
13
14def result_lines(result):
15    return [
16        x.strip()
17        for x in re.split(r"\r?\n", re.sub(r" +", " ", result))
18        if x.strip() != ""
19    ]
20
21
22def make_path(
23    filespec: Union[Path, str],
24    make_absolute: bool = True,
25    check_exists: bool = False,
26) -> Path:
27    path = Path(filespec)
28    if make_absolute:
29        path = path.resolve(strict=check_exists)
30    if check_exists and (not path.exists()):
31        raise FileNotFoundError(f"No file or directory at {filespec}")
32    return path
33
34
35def _unlink_path(path, missing_ok=False):
36    # Replicate 3.8+ functionality in 3.7
37    cm = contextlib.nullcontext()
38    if missing_ok:
39        cm = contextlib.suppress(FileNotFoundError)
40
41    with cm:
42        path.unlink()
43
44
45def replace_file_with_dir(pathspec):
46    path = pathlib.Path(pathspec)
47    _unlink_path(path, missing_ok=True)
48    path.mkdir(exist_ok=True)
49    return path
50
51
52def file_with_template_code(filespec):
53    with open(filespec, "w") as f:
54        f.write(
55            """
56i am an artificial template just for you
57"""
58        )
59    return filespec
60
61
62@contextlib.contextmanager
63def rewind_compile_time(hours=1):
64    rewound = time.time() - (hours * 3_600)
65    with mock.patch("mako.codegen.time") as codegen_time:
66        codegen_time.time.return_value = rewound
67        yield
68