-
Notifications
You must be signed in to change notification settings - Fork 166
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #576 from remind101/graph-command
Add "graph" subcommand
- Loading branch information
Showing
7 changed files
with
267 additions
and
1 deletion.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,75 @@ | ||
import logging | ||
import sys | ||
import json | ||
|
||
from .base import BaseAction, plan | ||
|
||
|
||
logger = logging.getLogger(__name__) | ||
|
||
|
||
def each_step(graph): | ||
"""Returns an iterator that yields each step and it's direct | ||
dependencies. | ||
""" | ||
|
||
steps = graph.topological_sort() | ||
steps.reverse() | ||
|
||
for step in steps: | ||
deps = graph.downstream(step.name) | ||
yield (step, deps) | ||
|
||
|
||
def dot_format(out, graph, name="digraph"): | ||
"""Outputs the graph using the graphviz "dot" format.""" | ||
|
||
out.write("digraph %s {\n" % name) | ||
for step, deps in each_step(graph): | ||
for dep in deps: | ||
out.write(" \"%s\" -> \"%s\";\n" % (step, dep)) | ||
|
||
out.write("}\n") | ||
|
||
|
||
def json_format(out, graph): | ||
"""Outputs the graph in a machine readable JSON format.""" | ||
steps = {} | ||
for step, deps in each_step(graph): | ||
steps[step.name] = {} | ||
steps[step.name]["deps"] = [dep.name for dep in deps] | ||
|
||
json.dump({"steps": steps}, out, indent=4) | ||
out.write("\n") | ||
|
||
|
||
FORMATTERS = { | ||
"dot": dot_format, | ||
"json": json_format, | ||
} | ||
|
||
|
||
class Action(BaseAction): | ||
|
||
def _generate_plan(self): | ||
return plan( | ||
description="Print graph", | ||
action=None, | ||
stacks=self.context.get_stacks(), | ||
targets=self.context.stack_names) | ||
|
||
def run(self, format=None, reduce=False, *args, **kwargs): | ||
"""Generates the underlying graph and prints it. | ||
""" | ||
plan = self._generate_plan() | ||
if reduce: | ||
# This will performa a transitive reduction on the underlying | ||
# graph, producing less edges. Mostly useful for the "dot" format, | ||
# when converting to PNG, so it creates a prettier/cleaner | ||
# dependency graph. | ||
plan.graph.transitive_reduction() | ||
|
||
fn = FORMATTERS[format] | ||
fn(sys.stdout, plan.graph) | ||
sys.stdout.flush() |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,32 @@ | ||
"""Prints the the relationships between steps as a graph. | ||
""" | ||
|
||
from .base import BaseCommand | ||
from ...actions import graph | ||
|
||
|
||
class Graph(BaseCommand): | ||
|
||
name = "graph" | ||
description = __doc__ | ||
|
||
def add_arguments(self, parser): | ||
super(Graph, self).add_arguments(parser) | ||
parser.add_argument("-f", "--format", default="dot", | ||
choices=list(graph.FORMATTERS.iterkeys()), | ||
help="The format to print the graph in.") | ||
parser.add_argument("--reduce", action="store_true", | ||
help="When provided, this will create a " | ||
"graph with less edges, by performing " | ||
"a transitive reduction on the underlying " | ||
"graph. While this will produce a less " | ||
"noisy graph, it is slower.") | ||
|
||
def run(self, options, **kwargs): | ||
super(Graph, self).run(options, **kwargs) | ||
action = graph.Action(options.context, | ||
provider_builder=options.provider_builder) | ||
action.execute( | ||
format=options.format, | ||
reduce=options.reduce) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters