79 lines
2.3 KiB
Python
Executable File
79 lines
2.3 KiB
Python
Executable File
#!/usr/bin/env python
|
|
# Copyright 2020 The Chromium Authors. All rights reserved.
|
|
# Use of this source code is governed by a BSD-style license that can be
|
|
# found in the LICENSE file.
|
|
|
|
|
|
"""
|
|
Finds unreachable gn targets by analysing --ide=json output
|
|
from gn gen.
|
|
|
|
Usage:
|
|
# Generate json file with targets info, will be located at out/project.json:
|
|
gn gen out --ide=json
|
|
# Lists all targets that are not reachable from //:all or //ci:test_all:
|
|
find_unreachable.py --from //:all --from //ci:test_all --json-file out/project.json
|
|
# Lists targets unreachable from //:all that aren't referenced by any other target:
|
|
find_unreachable.py --from //:all --json-file out/project.json --no-refs
|
|
"""
|
|
|
|
import argparse
|
|
import json
|
|
import sys
|
|
|
|
|
|
def find_reachable_targets(known, graph):
|
|
reachable = set()
|
|
to_visit = known
|
|
while to_visit:
|
|
next = to_visit.pop()
|
|
if next in reachable:
|
|
continue
|
|
reachable.add(next)
|
|
to_visit += graph[next]['deps']
|
|
return reachable
|
|
|
|
|
|
def find_source_targets_from(targets, graph):
|
|
source_targets = set(targets)
|
|
for target in targets:
|
|
source_targets -= set(graph[target]['deps'])
|
|
return source_targets
|
|
|
|
|
|
def main():
|
|
parser = argparse.ArgumentParser(description='''
|
|
Tool to find unreachable targets.
|
|
This can be useful to inspect forgotten targets,
|
|
for example tests or intermediate targets in templates
|
|
that are no longer needed.
|
|
''')
|
|
parser.add_argument(
|
|
'--json-file', required=True,
|
|
help='JSON file from gn gen with --ide=json option')
|
|
parser.add_argument(
|
|
'--from', action='append', dest='roots',
|
|
help='Known "root" targets. Can be multiple. Those targets \
|
|
and all their recursive dependencies are considered reachable.\
|
|
Examples: //:all, //ci:test_all')
|
|
parser.add_argument(
|
|
'--no-refs', action='store_true',
|
|
help='Show only targets that aren\'t referenced by any other target')
|
|
cmd_args = parser.parse_args()
|
|
|
|
with open(cmd_args.json_file) as json_file:
|
|
targets_graph = json.load(json_file)['targets']
|
|
|
|
reachable = find_reachable_targets(cmd_args.roots, targets_graph)
|
|
all = set(targets_graph.keys())
|
|
unreachable = all - reachable
|
|
|
|
result = find_source_targets_from(unreachable, targets_graph) \
|
|
if cmd_args.no_refs else unreachable
|
|
|
|
print '\n'.join(sorted(result))
|
|
|
|
|
|
if __name__ == '__main__':
|
|
sys.exit(main())
|