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
import serialization
# Return values of categorize_dependency().
IGNORE = 'ignore'
CLEAR = 'clear'
PRINT = 'print'
@dataclass
class PrintMode:
"""Options of how and which dependencies to output."""
inbound: bool
outbound: bool
ignore_modularized: bool
ignore_same_package: bool
fully_qualified: bool
......@@ -100,15 +107,35 @@ def is_ignored_class_dependency(class_name: str) -> bool:
return class_name in IGNORED_CLASSES
def print_class_nodes(class_nodes: List[class_dependency.JavaClass],
print_mode: PrintMode, class_name: str,
direction: str) -> TargetDependencies:
def categorize_dependency(from_class: class_dependency.JavaClass,
to_class: class_dependency.JavaClass,
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.
If direction is OUTBOUND and print_mode.ignore_modularized is True, omits
modularized outbound dependencies and returns the build targets that need
to be added for those dependencies. In other cases, returns an empty
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
bullet_point = '<-' if direction == INBOUND else '->'
......@@ -121,43 +148,48 @@ def print_class_nodes(class_nodes: List[class_dependency.JavaClass],
suspect_dependencies = 0
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
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
if ignore_modularized:
if all(
is_allowed_target_dependency(target)
for target in class_node.build_targets):
target_dependencies.update_with_class_node(class_node)
continue
else:
suspect_dependencies += 1
build_target = str(class_node.build_targets)
elif ignore_allow == IGNORE:
continue
# Print the dependency
suspect_dependencies += 1
build_target = str(to_class.build_targets)
if last_build_target != build_target:
build_target_names = [
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)
print_backlog.append((4, f'[{build_target_names_string}]'))
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 header
class_name = get_class_name_to_display(from_class.name, print_mode)
if ignore_modularized:
cleared = len(class_nodes) - suspect_dependencies
cleared = len(to_classes) - suspect_dependencies
print(f'{class_name} has {suspect_dependencies} outbound dependencies '
f'that may need to be broken (omitted {cleared} cleared '
f'dependencies):')
else:
if direction == INBOUND:
print(f'{class_name} has {len(class_nodes)} inbound dependencies:')
print(f'{class_name} has {len(to_classes)} inbound dependencies:')
else:
print(
f'{class_name} has {len(class_nodes)} outbound dependencies:')
print(f'{class_name} has {len(to_classes)} outbound dependencies:')
# Print build targets and dependencies
for indent, message in print_backlog:
......@@ -173,15 +205,14 @@ def print_class_dependencies_for_key(
"""Prints dependencies for a valid key into the class graph."""
target_dependencies = TargetDependencies()
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:
print_class_nodes(graph.sorted_nodes_by_name(node.inbound), print_mode,
class_name, INBOUND)
print_class_dependencies(graph.sorted_nodes_by_name(node.inbound),
print_mode, node, INBOUND)
if print_mode.outbound:
target_dependencies = print_class_nodes(
graph.sorted_nodes_by_name(node.outbound), print_mode, class_name,
target_dependencies = print_class_dependencies(
graph.sorted_nodes_by_name(node.outbound), print_mode, node,
OUTBOUND)
return target_dependencies
......@@ -235,6 +266,10 @@ def main():
help='Do not print outbound dependencies on '
'allowed (modules, components, base, etc.) '
'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()
if not arguments.class_names and not arguments.package_names:
......@@ -244,6 +279,7 @@ def main():
print_mode = PrintMode(inbound=not arguments.outbound_only,
outbound=not arguments.inbound_only,
ignore_modularized=arguments.ignore_modularized,
ignore_same_package=arguments.ignore_same_package,
fully_qualified=arguments.fully_qualified)
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