Commit 3c16c5b4 authored by Henrique Nakashima's avatar Henrique Nakashima Committed by Commit Bot

[Lorenz] Add --ignore-same-package arg to print_class_dependencies.py

This argument makes dependencies to classes in the same package be
ignored in the audit. This is especially useful when auditing a package
that will be entirely modularized.

Change-Id: I115c8bfc3bf123a5b0eedcc66d369aba620b72f1
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2480626
Commit-Queue: Henrique Nakashima <hnakashima@chromium.org>
Reviewed-by: default avatarMohamed Heikal <mheikal@chromium.org>
Cr-Commit-Position: refs/heads/master@{#818020}
parent 3893bd52
...@@ -16,12 +16,19 @@ import print_dependencies_helper ...@@ -16,12 +16,19 @@ import print_dependencies_helper
import serialization import serialization
# Return values of categorize_dependency().
IGNORE = 'ignore'
CLEAR = 'clear'
PRINT = 'print'
@dataclass @dataclass
class PrintMode: class PrintMode:
"""Options of how and which dependencies to output.""" """Options of how and which dependencies to output."""
inbound: bool inbound: bool
outbound: bool outbound: bool
ignore_modularized: bool ignore_modularized: bool
ignore_same_package: bool
fully_qualified: bool fully_qualified: bool
...@@ -100,15 +107,35 @@ def is_ignored_class_dependency(class_name: str) -> bool: ...@@ -100,15 +107,35 @@ def is_ignored_class_dependency(class_name: str) -> bool:
return class_name in IGNORED_CLASSES return class_name in IGNORED_CLASSES
def print_class_nodes(class_nodes: List[class_dependency.JavaClass], def categorize_dependency(from_class: class_dependency.JavaClass,
print_mode: PrintMode, class_name: str, to_class: class_dependency.JavaClass,
direction: str) -> TargetDependencies: ignore_modularized: bool,
ignore_same_package: bool) -> str:
"""Decides if a class dependency should be printed, cleared, or ignored."""
if is_ignored_class_dependency(to_class.name):
return IGNORE
if ignore_modularized and all(
is_allowed_target_dependency(target)
for target in to_class.build_targets):
return CLEAR
if ignore_same_package and to_class.package == from_class.package:
return IGNORE
return PRINT
def print_class_dependencies(to_classes: List[class_dependency.JavaClass],
print_mode: PrintMode,
from_class: class_dependency.JavaClass,
direction: str) -> TargetDependencies:
"""Prints the class dependencies to or from a class, grouped by target. """Prints the class dependencies to or from a class, grouped by target.
If direction is OUTBOUND and print_mode.ignore_modularized is True, omits If direction is OUTBOUND and print_mode.ignore_modularized is True, omits
modularized outbound dependencies and returns the build targets that need modularized outbound dependencies and returns the build targets that need
to be added for those dependencies. In other cases, returns an empty to be added for those dependencies. In other cases, returns an empty
TargetDependencies. TargetDependencies.
If print_mode.ignore_same_package is True, omits outbound dependencies in
the same package.
""" """
ignore_modularized = direction == OUTBOUND and print_mode.ignore_modularized ignore_modularized = direction == OUTBOUND and print_mode.ignore_modularized
bullet_point = '<-' if direction == INBOUND else '->' bullet_point = '<-' if direction == INBOUND else '->'
...@@ -121,43 +148,48 @@ def print_class_nodes(class_nodes: List[class_dependency.JavaClass], ...@@ -121,43 +148,48 @@ def print_class_nodes(class_nodes: List[class_dependency.JavaClass],
suspect_dependencies = 0 suspect_dependencies = 0
target_dependencies = TargetDependencies() target_dependencies = TargetDependencies()
class_nodes = sorted(class_nodes, key=lambda c: str(c.build_targets)) to_classes = sorted(to_classes, key=lambda c: str(c.build_targets))
last_build_target = None last_build_target = None
for class_node in class_nodes:
if is_ignored_class_dependency(class_node.name): for to_class in to_classes:
# Check if dependency should be ignored due to --ignore-modularized,
# --ignore-same-package, or due to being an ignored class.
# Check if dependency should be listed as a cleared dep.
ignore_allow = categorize_dependency(from_class, to_class,
ignore_modularized,
print_mode.ignore_same_package)
if ignore_allow == CLEAR:
target_dependencies.update_with_class_node(to_class)
continue continue
if ignore_modularized: elif ignore_allow == IGNORE:
if all( continue
is_allowed_target_dependency(target)
for target in class_node.build_targets): # Print the dependency
target_dependencies.update_with_class_node(class_node) suspect_dependencies += 1
continue build_target = str(to_class.build_targets)
else:
suspect_dependencies += 1
build_target = str(class_node.build_targets)
if last_build_target != build_target: if last_build_target != build_target:
build_target_names = [ build_target_names = [
get_build_target_name_to_display(target, print_mode) get_build_target_name_to_display(target, print_mode)
for target in class_node.build_targets for target in to_class.build_targets
] ]
build_target_names_string = ", ".join(build_target_names) build_target_names_string = ", ".join(build_target_names)
print_backlog.append((4, f'[{build_target_names_string}]')) print_backlog.append((4, f'[{build_target_names_string}]'))
last_build_target = build_target last_build_target = build_target
display_name = get_class_name_to_display(class_node.name, print_mode) display_name = get_class_name_to_display(to_class.name, print_mode)
print_backlog.append((8, f'{bullet_point} {display_name}')) print_backlog.append((8, f'{bullet_point} {display_name}'))
# Print header # Print header
class_name = get_class_name_to_display(from_class.name, print_mode)
if ignore_modularized: if ignore_modularized:
cleared = len(class_nodes) - suspect_dependencies cleared = len(to_classes) - suspect_dependencies
print(f'{class_name} has {suspect_dependencies} outbound dependencies ' print(f'{class_name} has {suspect_dependencies} outbound dependencies '
f'that may need to be broken (omitted {cleared} cleared ' f'that may need to be broken (omitted {cleared} cleared '
f'dependencies):') f'dependencies):')
else: else:
if direction == INBOUND: if direction == INBOUND:
print(f'{class_name} has {len(class_nodes)} inbound dependencies:') print(f'{class_name} has {len(to_classes)} inbound dependencies:')
else: else:
print( print(f'{class_name} has {len(to_classes)} outbound dependencies:')
f'{class_name} has {len(class_nodes)} outbound dependencies:')
# Print build targets and dependencies # Print build targets and dependencies
for indent, message in print_backlog: for indent, message in print_backlog:
...@@ -173,15 +205,14 @@ def print_class_dependencies_for_key( ...@@ -173,15 +205,14 @@ def print_class_dependencies_for_key(
"""Prints dependencies for a valid key into the class graph.""" """Prints dependencies for a valid key into the class graph."""
target_dependencies = TargetDependencies() target_dependencies = TargetDependencies()
node: class_dependency.JavaClass = class_graph.get_node_by_key(key) node: class_dependency.JavaClass = class_graph.get_node_by_key(key)
class_name = get_class_name_to_display(node.name, print_mode)
if print_mode.inbound: if print_mode.inbound:
print_class_nodes(graph.sorted_nodes_by_name(node.inbound), print_mode, print_class_dependencies(graph.sorted_nodes_by_name(node.inbound),
class_name, INBOUND) print_mode, node, INBOUND)
if print_mode.outbound: if print_mode.outbound:
target_dependencies = print_class_nodes( target_dependencies = print_class_dependencies(
graph.sorted_nodes_by_name(node.outbound), print_mode, class_name, graph.sorted_nodes_by_name(node.outbound), print_mode, node,
OUTBOUND) OUTBOUND)
return target_dependencies return target_dependencies
...@@ -235,6 +266,10 @@ def main(): ...@@ -235,6 +266,10 @@ def main():
help='Do not print outbound dependencies on ' help='Do not print outbound dependencies on '
'allowed (modules, components, base, etc.) ' 'allowed (modules, components, base, etc.) '
'dependencies.') 'dependencies.')
arg_parser.add_argument('--ignore-same-package',
action='store_true',
help='Do not print outbound dependencies on '
'classes in the same package.')
arguments = arg_parser.parse_args() arguments = arg_parser.parse_args()
if not arguments.class_names and not arguments.package_names: if not arguments.class_names and not arguments.package_names:
...@@ -244,6 +279,7 @@ def main(): ...@@ -244,6 +279,7 @@ def main():
print_mode = PrintMode(inbound=not arguments.outbound_only, print_mode = PrintMode(inbound=not arguments.outbound_only,
outbound=not arguments.inbound_only, outbound=not arguments.inbound_only,
ignore_modularized=arguments.ignore_modularized, ignore_modularized=arguments.ignore_modularized,
ignore_same_package=arguments.ignore_same_package,
fully_qualified=arguments.fully_qualified) fully_qualified=arguments.fully_qualified)
class_graph, package_graph = \ class_graph, package_graph = \
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment