| Index: recipe_engine/depgraph.py
|
| diff --git a/recipe_engine/depgraph.py b/recipe_engine/depgraph.py
|
| index efd2022e991620d7a271e3734e874033eff4a720..91a1f2ffb0d06d18036d55a54d80fa67d8b02622 100644
|
| --- a/recipe_engine/depgraph.py
|
| +++ b/recipe_engine/depgraph.py
|
| @@ -4,6 +4,9 @@
|
|
|
| from __future__ import print_function
|
|
|
| +import argparse
|
| +import sys
|
| +
|
| from . import loader
|
|
|
|
|
| @@ -17,25 +20,53 @@ _GRAPH_FOOTER = """}
|
| """
|
|
|
|
|
| -def main(universe, own_package, ignore_packages, stdout, recipe_filter):
|
| +def add_subparser(parser):
|
| + depgraph_p = parser.add_parser(
|
| + 'depgraph',
|
| + description=(
|
| + 'Produce graph of recipe and recipe module dependencies. Example: '
|
| + './recipes.py --package infra/config/recipes.cfg depgraph | tred | '
|
| + 'dot -Tpdf > graph.pdf'))
|
| + depgraph_p.add_argument(
|
| + '--output', type=argparse.FileType('w'), default=sys.stdout,
|
| + help='The file to write output to')
|
| + depgraph_p.add_argument(
|
| + '--ignore-package', action='append', default=[],
|
| + dest='ignore_packages',
|
| + help='Ignore a recipe package (e.g. recipe_engine). Can be passed '
|
| + 'multiple times')
|
| + depgraph_p.add_argument(
|
| + '--recipe-filter', default='',
|
| + help='A recipe substring to examine. If present, the depgraph will '
|
| + 'include a recipe section containing recipes whose names contain '
|
| + 'this substring. It will also filter all nodes of the graph to only '
|
| + 'include modules touched by the filtered recipes.')
|
| +
|
| + depgraph_p.set_defaults(command='depgraph', func=main)
|
| +
|
| +
|
| +def main(package_deps, args):
|
| + universe = loader.RecipeUniverse(package_deps, args.package)
|
| + own_package = package_deps.root_package
|
| +
|
| module_to_package = {}
|
|
|
| # All deps maps a tuple of (is_recipe, id) to deps (list of ids). is_recipe is
|
| # a boolean, all ids are strings.
|
| all_deps = {}
|
| for package, module_name in universe.loop_over_recipe_modules():
|
| - if package in ignore_packages:
|
| + if package in args.ignore_packages:
|
| continue
|
| mod = universe.load(package, module_name)
|
|
|
| all_deps[(False, mod.NAME)] = mod.LOADED_DEPS
|
| module_to_package[mod.NAME] = package.name
|
|
|
| - if recipe_filter:
|
| + if args.recipe_filter:
|
| recipe_to_package = {}
|
| universe_view = loader.UniverseView(universe, own_package)
|
| for _, recipe_name in universe_view.loop_over_recipes():
|
| - if recipe_filter not in recipe_name:
|
| + if args.recipe_filter not in recipe_name:
|
| continue
|
|
|
| recipe = universe_view.load_recipe(recipe_name)
|
| @@ -72,7 +103,7 @@ def main(universe, own_package, ignore_packages, stdout, recipe_filter):
|
| if r_name in recipe_names}
|
|
|
|
|
| - print(_GRAPH_HEADER, file=stdout)
|
| + print(_GRAPH_HEADER, file=args.output)
|
| edges = []
|
| for (is_recipe, name), deps in all_deps.items():
|
| for dep in deps:
|
| @@ -82,33 +113,33 @@ def main(universe, own_package, ignore_packages, stdout, recipe_filter):
|
| (is_recipe, first_name), second_name = edge
|
|
|
| if not is_recipe:
|
| - if module_to_package[first_name] in ignore_packages:
|
| + if module_to_package[first_name] in args.ignore_packages:
|
| continue
|
| else:
|
| - if recipe_to_package[first_name] in ignore_packages:
|
| + if recipe_to_package[first_name] in args.ignore_packages:
|
| continue
|
| first_name = 'recipe ' + first_name
|
|
|
| - if module_to_package[second_name] in ignore_packages:
|
| + if module_to_package[second_name] in args.ignore_packages:
|
| continue
|
|
|
| - print(' "%s" -> "%s"' % (first_name, second_name), file=stdout)
|
| + print(' "%s" -> "%s"' % (first_name, second_name), file=args.output)
|
|
|
| packages = {}
|
| for module, package in module_to_package.iteritems():
|
| packages.setdefault(package, []).append(module)
|
| for package, modules in packages.iteritems():
|
| - if package in ignore_packages:
|
| + if package in args.ignore_packages:
|
| continue
|
| # The "cluster_" prefix has magic meaning for graphviz and makes it
|
| # draw a box around the subgraph.
|
| print(' subgraph "cluster_%s" { label="%s"; %s; }' % (
|
| - package, package, '; '.join(modules)), file=stdout)
|
| + package, package, '; '.join(modules)), file=args.output)
|
|
|
| - if recipe_filter and recipe_to_package:
|
| + if args.recipe_filter and recipe_to_package:
|
| recipe_names = [
|
| '"recipe %s"' % name for name in recipe_to_package.keys()]
|
| print(' subgraph "cluster_recipes" { label="recipes"; %s; }' % (
|
| - '; '.join(recipe_names)), file=stdout)
|
| + '; '.join(recipe_names)), file=args.output)
|
|
|
| - print(_GRAPH_FOOTER, file=stdout)
|
| + print(_GRAPH_FOOTER, file=args.output)
|
|
|