blob: d2fbbec8200f66cd86754a4b84b1804487e8c3f2 [file] [log] [blame]
#!/usr/bin/env python3
# Copyright 2019 The Fuchsia Authors. All rights reserved.
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.
"""Utilities to survey and analyze the relationships between components in the system.
"""
import json
import os
import re
from server.graph import ComponentGraphGenerator
"""Utility to dump the component graph in CSV form.
"""
class Surveyor:
groups_json_path = 'scripts/component_graph/surveyor/groups.json'
def __init__(self, groups_json):
"""Creates a new Surveyor.
`groups_json` is a dictionary that maps groups to lists of component names, which it will
use to label components. Any components in the `Tests` group will be omitted from the results.
"""
self.groups_json = groups_json
def export(self, packages, services):
"""Returns a information of all components in `packages` and their dependencies determined by
the mappings in `services`.
"""
gen = ComponentGraphGenerator()
graph = gen.generate(packages, services)
group_map = Surveyor._gen_group_map(self.groups_json)
tuples = []
# Hide tests from the results.
# TODO: Include and categorize tests?
test_re = re.compile('.*[_\\-](unit)?test.*\\.cmx')
for node in graph.nodes.values():
if node.ty == 'builtin' or node.ty == 'inferred':
continue
if test_re.match(node.id):
continue
offers = '\\n'.join(node.offers)
component_deps = '\\n'.join([dep.split('/')[-1] for dep in node.component_use_deps])
features = '\\n'.join(node.features)
uses = '\\n'.join(node.uses)
if node.name in group_map:
group = group_map[node.name]
else:
group = 'Misc'
if group == 'Tests':
continue
tuples.append((group, node.name, offers, component_deps, features, uses))
tuples.sort(key=lambda tup: tup[0])
tuples.insert(0, ('Group','Component','Services exposed','Component Deps','Features','Service deps'))
return tuples
@classmethod
def load_groups_json(cls, fuchsia_root):
"""Loads the `groups_json` dictionary from a file."""
path = os.path.join(fuchsia_root, cls.groups_json_path)
if os.path.exists(path):
return json.loads(open(path, 'r').read())
return {}
@staticmethod
def _gen_group_map(groups_json):
group_map = {}
for group in groups_json:
for name in groups_json[group]:
group_map[name + '.cmx'] = group
return group_map