aboutsummaryrefslogtreecommitdiffstats
path: root/tools/cpp_style_checker/__main__.py
blob: abaa32ee19c271575f35b16942a65b5b6b88e8b2 (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
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
import difflib
import json
import os
import subprocess
import time
import yaml

from build.plugins.lib.test_const import CLANG_FORMAT_RESOURCE
from library.python.testing.custom_linter_util import linter_params, reporter
from library.python.testing.style import rules


def main():
    params = linter_params.get_params()

    clang_format_binary = os.path.join(params.global_resources[CLANG_FORMAT_RESOURCE], 'clang-format')
    style_config_path = params.configs[0]

    with open(style_config_path) as f:
        style_config = yaml.safe_load(f)
    style_config_json = json.dumps(style_config)

    report = reporter.LintReport()
    for file_name in params.files:
        start_time = time.time()
        status, message = check_file(clang_format_binary, style_config_json, file_name)
        elapsed = time.time() - start_time
        report.add(file_name, status, message, elapsed=elapsed)

    report.dump(params.report_file)


def check_file(clang_format_binary, style_config_json, filename):
    with open(filename, "rb") as f:
        actual_source = f.read()

    skip_reason = rules.get_skip_reason(filename, actual_source, skip_links=False)
    if skip_reason:
        return reporter.LintStatus.SKIPPED, "Style check is omitted: {}".format(skip_reason)

    command = [clang_format_binary, '-assume-filename=' + filename, '-style=' + style_config_json]
    styled_source = subprocess.check_output(command, input=actual_source)

    if styled_source == actual_source:
        return reporter.LintStatus.GOOD, ""
    else:
        diff = make_diff(actual_source, styled_source)
        return reporter.LintStatus.FAIL, diff


def make_diff(left, right):
    result = ""
    for line in difflib.unified_diff(left.decode().splitlines(), right.decode().splitlines(), fromfile='L', tofile='R'):
        line = line.rstrip("\n")
        if line:
            if line[0] == "-":
                line = "[[bad]]" + line + "[[rst]]"
            elif line[0] == "+":
                line = "[[good]]" + line + "[[rst]]"
        result += line + "\n"
    return result


if __name__ == "__main__":
    main()