blob: d8676980b7bc10728bd5c790219d01105f6e9d69 [file] [log] [blame]
Brian Silvermand4aea1d2015-12-09 00:24:18 -05001#!/usr/bin/python3
2
3# This reads the _compile_command files :generate_compile_commands_action
4# generates a outputs a compile_commands.json file at the top of the source
5# tree for things like clang-tidy to read.
6
7# Overall usage directions: run bazel with
8# --experimental_action_listener=//tools/actions:generate_compile_commands_listener
9# for all the files you want to use clang-tidy with and then run this script.
10# Afer that, `clang-tidy build_tests/gflags.cc` should work.
11
12import sys
13import pathlib
14import os.path
15import subprocess
16
17'''
18Args:
19 path: The pathlib.Path to _compile_command file.
20 command_directory: The directory commands are run from.
21
22Returns a string to stick in compile_commands.json.
23'''
24def _get_command(path, command_directory):
25 with path.open('r') as f:
26 contents = f.read().split('\0')
27 if len(contents) != 2:
28 # Old/incomplete file or something; silently ignore it.
29 return None
30 return '''{
31 "directory": "%s",
32 "command": "%s",
33 "file": "%s",
34 },''' % (command_directory, contents[0].replace('"', '\\"'), contents[1])
35
36'''
37Args:
38 path: A directory pathlib.Path to look for _compile_command files under.
39 command_directory: The directory commands are run from.
40
41Yields strings to stick in compile_commands.json.
42'''
43def _get_compile_commands(path, command_directory):
44 for f in path.iterdir():
45 if f.is_dir():
46 yield from _get_compile_commands(f, command_directory)
47 elif f.name.endswith('_compile_command'):
48 command = _get_command(f, command_directory)
49 if command:
50 yield command
51
52def main(argv):
53 source_path = os.path.join(os.path.dirname(__file__), '../..')
54 action_outs = os.path.join(source_path,
55 'bazel-bin/../extra_actions',
56 'tools/actions/generate_compile_commands_action')
57 command_directory = subprocess.check_output(
58 ('bazel', 'info', 'execution_root'),
59 cwd=source_path).decode('utf-8').rstrip()
60 commands = _get_compile_commands(pathlib.Path(action_outs), command_directory)
61 with open(os.path.join(source_path, 'compile_commands.json'), 'w') as f:
62 f.write('[')
63 for command in commands:
64 f.write(command)
65 f.write(']')
66
67if __name__ == '__main__':
68 sys.exit(main(sys.argv))