Skip to content

Commit f9680cc

Browse files
committed
cli(show-dependencies): allow filtering per actor
1 parent f7e5e24 commit f9680cc

1 file changed

Lines changed: 32 additions & 1 deletion

File tree

leapp/snactor/commands/show_dependencies.py

Lines changed: 32 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66
from leapp.logger import configure_logger
77
from leapp.repository.scan import find_and_scan_repositories
88
from leapp.snactor.context import with_snactor_context
9-
from leapp.utils.clicmd import command, command_arg
9+
from leapp.utils.clicmd import command, command_arg, command_opt
1010
from leapp.utils.repository import find_repository_basedir, requires_repository
1111

1212
_LONG_DESCRIPTION = '''
@@ -19,6 +19,9 @@
1919
help='Print dependency graph of a workflow in the DOT language.',
2020
description=_LONG_DESCRIPTION)
2121
@command_arg('workflow_name')
22+
@command_opt('only-influencing-actor',
23+
metavar='ActorName',
24+
help='Show only actors that influence the given actor by producing messages')
2225
@requires_repository
2326
@with_snactor_context
2427
def cli(params):
@@ -35,6 +38,12 @@ def cli(params):
3538
if not workflow:
3639
raise CommandError('Could not find any workflow named "{}"'.format(params.name))
3740

41+
actor_of_interest = None
42+
if params.only_influencing_actor:
43+
actor_of_interest = repository.lookup_actor(params.only_influencing_actor)
44+
if not actor_of_interest:
45+
raise CommandError('Could not find any workflow named "{}"'.format(params.name))
46+
3847
workflow_instance = workflow()
3948

4049
# Information about message consuments and producers:
@@ -50,12 +59,34 @@ def cli(params):
5059
for produced_message in actor.produces:
5160
dependency_graph[produced_message.__name__]['producers'].add(actor.name)
5261

62+
actors_to_include = set()
63+
if actor_of_interest:
64+
# Compute backwards reachability
65+
worklist = [actor_of_interest.name]
66+
while worklist:
67+
explored_actor = worklist.pop(-1)
68+
actors_to_include.add(explored_actor.name)
69+
70+
for consumed_message in explored_actor.consumes:
71+
message_producer_names = dependency_graph[consumed_message.__name__]['producers']
72+
for producer_name in message_producer_names:
73+
if producer_name in actors_to_include:
74+
continue
75+
76+
producer = repository.lookup_actor(producer_name)
77+
worklist.append(producer)
78+
5379
# Display the dependency graph in the DOT format. We don't want to add dependencies on another library,
5480
# so we do the formatting ourselves since its pretty straightforward
5581
dot_output_lines = ['digraph LeappDependencyGraph {']
5682

5783
for message, message_info in dependency_graph.items():
5884
for producent, consument in itertools.product(message_info['producers'], message_info['consumers']):
85+
# In case we show only influential actors, check that both message source and message targets
86+
# are to be displayed
87+
if actor_of_interest and not actors_to_include.issubset((producent, consument)):
88+
continue
89+
5990
output_line = ' "{0}" -> "{1}" [label="{2}"]'.format(producent, consument, message)
6091
dot_output_lines.append(output_line)
6192

0 commit comments

Comments
 (0)