Merge pull request #60 from Dunedan/graphviz

Add different output options for dependency graph
This commit is contained in:
Vineet Naik 2016-12-28 21:11:54 +05:30 committed by GitHub
commit 6e095e658f
3 changed files with 74 additions and 2 deletions

View File

@ -201,6 +201,16 @@ tools.
$ python pipdeptree.py --json
The dependency graph can be layed out as any of the formats supported by
GraphViz`GraphViz<http://www.graphviz.org/>`_:
.. code-block:: bash
$ pipdeptree --graph-output dot > dependencies.dot
$ pipdeptree --graph-output pdf > dependencies.pdf
$ pipdeptree --graph-output png > dependencies.png
$ pipdeptree --graph-output svg > dependencies.svg
Usage
-----
@ -233,6 +243,10 @@ Usage
-j, --json Display dependency tree as json. This will yield "raw"
output that may be used by external tools. This option
overrides all other options.
--graph-output OUTPUT_FORMAT
Print a dependency graph in the specified output
format. Available are all formats supported by
GraphViz, e.g.: dot, jpeg, pdf, png, svg
Known Issues

View File

@ -14,6 +14,8 @@ except ImportError:
import pip
import pkg_resources
# inline:
# from graphviz import backend, Digraph
__version__ = '0.8.0'
@ -339,6 +341,52 @@ def jsonify_tree(tree, indent):
indent=indent)
def dump_graphviz(tree, output_format='dot'):
"""Output dependency graph as one of the supported GraphViz output formats.
:param dict tree: dependency graph
:param string output_format: output format
:returns: representation of tree in the specified output format
:rtype: str or binary representation depending on the output format
"""
try:
from graphviz import backend, Digraph
except ImportError:
print('graphviz is not available, but necessary for the output '
'option. Please install it.', file=sys.stderr)
sys.exit(1)
if output_format not in backend.FORMATS:
print('{} is no supported output format.'.format(output_format),
file=sys.stderr)
print('Supported formats are: {}'.format(
', '.join(sorted(backend.FORMATS))), file=sys.stderr)
sys.exit(1)
graph = Digraph(format=output_format)
for package, deps in tree.items():
project_name = package.project_name
label = '{}\n{}'.format(project_name, package.version)
graph.node(project_name, label=label)
for dep in deps:
label = dep.version_spec
if not label:
label = 'any'
graph.edge(project_name, dep.project_name, label=label)
# Allow output of dot format, even if GraphViz isn't installed.
if output_format == 'dot':
return graph.source
# As it's unknown if the selected output format is binary or not, try to
# decode it as UTF8 and only print it out in binary if that's not possible.
try:
return graph.pipe().decode('utf-8')
except UnicodeDecodeError:
return graph.pipe()
def conflicting_deps(tree):
"""Returns dependencies which are not present or conflict with the
requirements of other packages.
@ -418,6 +466,12 @@ def main():
'"raw" output that may be used by external tools. '
'This option overrides all other options.'
))
parser.add_argument('--graph-output', dest='output_format',
help=(
'Print a dependency graph in the specified output '
'format. Available are all formats supported by '
'GraphViz, e.g.: dot, jpeg, pdf, png, svg'
))
args = parser.parse_args()
pkgs = pip.get_installed_distributions(local_only=args.local_only)
@ -428,6 +482,9 @@ def main():
if args.json:
print(jsonify_tree(tree, indent=4))
return 0
elif args.output_format:
print(dump_graphviz(tree, output_format=args.output_format))
return 0
return_code = 0
@ -440,10 +497,10 @@ def main():
file=sys.stderr)
for p, reqs in conflicting.items():
pkg = p.render_as_root(False)
print('* %s' % pkg, file=sys.stderr)
print('* {}'.format(pkg), file=sys.stderr)
for req in reqs:
req_str = req.render_as_branch(False)
print(' - %s' % req_str, file=sys.stderr)
print(' - {}'.format(req_str), file=sys.stderr)
print('-'*72, file=sys.stderr)
cyclic = cyclic_deps(tree)

View File

@ -33,6 +33,7 @@ setup(
description='Command line utility to show dependency tree of packages',
long_description=long_desc,
install_requires=install_requires,
extras_require={'graphviz': ['graphviz']},
py_modules=['pipdeptree'],
entry_points={
'console_scripts': [