aboutsummaryrefslogtreecommitdiffstats
path: root/build/scripts/run_javac.py
blob: 0adf42a2e07357282bc88e3157186b705298876c (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
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
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
import sys
import subprocess
import optparse
import re


def parse_args():
    parser = optparse.OptionParser()
    parser.disable_interspersed_args()
    parser.add_option('--sources-list')
    parser.add_option('--verbose', default=False, action='store_true')
    parser.add_option('--remove-notes', default=False, action='store_true')
    parser.add_option('--ignore-errors', default=False, action='store_true') 
    parser.add_option('--kotlin', default=False, action='store_true') 
    return parser.parse_args()


COLORING = {
    r'^(?P<path>.*):(?P<line>\d*): error: (?P<msg>.*)': lambda m: '[[unimp]]{path}[[rst]]:[[alt2]]{line}[[rst]]: [[c:light-red]]error[[rst]]: [[bad]]{msg}[[rst]]'.format(
        path=m.group('path'),
        line=m.group('line'),
        msg=m.group('msg'),
    ),
    r'^(?P<path>.*):(?P<line>\d*): warning: (?P<msg>.*)': lambda m: '[[unimp]]{path}[[rst]]:[[alt2]]{line}[[rst]]: [[c:light-yellow]]warning[[rst]]: {msg}'.format(
        path=m.group('path'),
        line=m.group('line'),
        msg=m.group('msg'),
    ),
    r'^warning: ': lambda m: '[[c:light-yellow]]warning[[rst]]: ',
    r'^error: (?P<msg>.*)': lambda m: '[[c:light-red]]error[[rst]]: [[bad]]{msg}[[rst]]'.format(msg=m.group('msg')),
    r'^Note: ': lambda m: '[[c:light-cyan]]Note[[rst]]: ',
}


def colorize(err):
    for regex, sub in COLORING.iteritems():
        err = re.sub(regex, sub, err, flags=re.MULTILINE)
    return err


def remove_notes(err):
    return '\n'.join([line for line in err.split('\n') if not line.startswith('Note:')])


def find_javac(cmd): 
    if not cmd: 
        return None 
    if cmd[0].endswith('javac') or cmd[0].endswith('javac.exe'): 
        return cmd[0] 
    if len(cmd) > 2 and cmd[1].endswith('build_java_with_error_prone.py'): 
        for javas in ('java', 'javac'): 
            if cmd[2].endswith(javas) or cmd[2].endswith(javas + '.exe'): 
                return cmd[2] 
    return None 
 
 
# temporary, for jdk8/jdk9+ compatibility 
def fix_cmd(cmd): 
    if not cmd: 
        return cmd 
    javac = find_javac(cmd) 
    if not javac: 
        return cmd 
    p = subprocess.Popen([javac, '-version'], stdout=subprocess.PIPE, stderr=subprocess.PIPE) 
    out, err = p.communicate() 
    out, err = out.strip(), err.strip() 
    for prefix in ('javac 1.8', 'java version "1.8'): 
        for raw_out in ((out or ''), (err or '')): 
            for line in raw_out.split('\n'): 
                if line.startswith(prefix): 
                    res = [] 
                    i = 0 
                    while i < len(cmd): 
                        for option in ('--add-exports', '--add-modules'): 
                            if cmd[i] == option: 
                                i += 1 
                                break 
                            elif cmd[i].startswith(option + '='): 
                                break 
                        else: 
                            res.append(cmd[i]) 
                        i += 1 
                    return res 
    return cmd 
 
 
def main():
    opts, cmd = parse_args()

    with open(opts.sources_list) as f:
        input_files = f.read().strip().split()

    if opts.kotlin: 
        input_files = [i for i in input_files if i.endswith('.kt')] 
 
    if not input_files:
        if opts.verbose:
            sys.stderr.write('No files to compile, javac is not launched.\n')

    else:
        p = subprocess.Popen(fix_cmd(cmd), stderr=subprocess.PIPE) 
        _, err = p.communicate()
        rc = p.wait()

        if opts.remove_notes:
            err = remove_notes(err)

        try:
            err = colorize(err)

        except Exception:
            pass

        if opts.ignore_errors and rc: 
            sys.stderr.write('error: javac actually failed with exit code {}\n'.format(rc)) 
            rc = 0 
        sys.stderr.write(err)
        sys.exit(rc)


if __name__ == '__main__':
    main()