aboutsummaryrefslogtreecommitdiffstats
path: root/build/scripts/run_javac.py
blob: 2a870af7715a1080d19119b209cc7ec4d1dc2071 (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()