File Coverage

blib/lib/Meta/Grapher/Moose/Renderer/Graphviz.pm
Criterion Covered Total %
statement 12 12 100.0
branch n/a
condition n/a
subroutine 4 4 100.0
pod n/a
total 16 16 100.0


line stmt bran cond sub pod time code
1             package Meta::Grapher::Moose::Renderer::Graphviz;
2              
3 1     1   393 use strict;
  1         1  
  1         21  
4 1     1   3 use warnings;
  1         1  
  1         17  
5 1     1   2 use namespace::autoclean;
  1         1  
  1         5  
6 1     1   473 use autodie qw( :all );
  1         9932  
  1         4  
7              
8             our $VERSION = '1.01';
9              
10             use File::Temp qw( tempfile );
11             use GraphViz2;
12             use Meta::Grapher::Moose::Constants qw( CLASS ROLE P_ROLE ANON_ROLE );
13              
14             use Moose;
15              
16             with(
17             'Meta::Grapher::Moose::Role::HasOutput',
18             'Meta::Grapher::Moose::Role::Renderer',
19             );
20              
21             has _graph => (
22             is => 'ro',
23             isa => 'GraphViz2',
24             lazy => 1,
25             builder => '_build_graph',
26             );
27              
28             has output => (
29             is => 'ro',
30             isa => 'Str',
31             );
32              
33             # TODO: Make this configurable from the command line, either by accepting some
34             # sort of JSON-as-command-line-argument-flag setting, or by having multiple
35             # attributes that *are* individually settable and are lazily built into this
36             # formatting hashref if nothing is passed.
37             has formatting => (
38             is => 'ro',
39             isa => 'HashRef[HashRef]',
40             builder => '_build_formatting',
41             );
42              
43             sub render {
44             my $self = shift;
45              
46             # are we rendering to a named file or a temp file?
47             my $output = (
48             $self->has_output ? $self->output : do {
49             my ( undef, $filename ) = tempfile();
50             $filename;
51             }
52             );
53              
54             $self->_graph->run(
55             format => ( $self->format eq 'src' ? 'dot' : $self->format ),
56             output_file => $output,
57             );
58              
59             # If we were rendering to STDOUT, send to STDOUT
60             unless ( $self->has_output ) {
61             open my $fh, '<:raw', $output;
62             while (<$fh>) {
63             print or die $!;
64             }
65             close $fh;
66             unlink $output;
67             }
68              
69             return;
70             }
71              
72             sub _build_graph {
73             return GraphViz2->new;
74             }
75              
76             sub add_package {
77             my $self = shift;
78             my %args = @_;
79              
80             $self->_graph->add_node(
81             name => $args{id},
82             label => $args{label},
83             %{ $self->formatting->{ $args{type} } },
84             );
85              
86             return;
87             }
88              
89             sub _build_formatting {
90             my @std = (
91             fontname => 'Helvetica',
92             fontsize => 9,
93             shape => 'rect',
94             );
95              
96             return {
97             CLASS() => { @std, style => 'bold', },
98             ROLE() => { @std, },
99             P_ROLE() => { @std, style => 'dashed', },
100             ANON_ROLE() => { @std, style => 'dotted', },
101             };
102             }
103              
104             sub add_edge {
105             my $self = shift;
106             my %p = @_;
107              
108             $self->_graph->add_edge(
109             from => $p{from},
110             to => $p{to},
111             weight => $p{weight},
112             );
113              
114             return;
115             }
116              
117             __PACKAGE__->meta->make_immutable;
118              
119             1;
120              
121             # ABSTRACT: Render a Meta::Grapher::Moose as a graph using GraphViz2
122              
123             __END__
124              
125             =pod
126              
127             =encoding UTF-8
128              
129             =head1 NAME
130              
131             Meta::Grapher::Moose::Renderer::Graphviz - Render a Meta::Grapher::Moose as a graph using GraphViz2
132              
133             =head1 VERSION
134              
135             version 1.01
136              
137             =head1 SYNOPSIS
138              
139             Meta::Grapher::Moose->new(
140             renderer => Meta::Grapher::Moose::Renderer::Graphviz->new(),
141             ...
142             );
143              
144             =head1 DESCRIPTION
145              
146             This is one of the standard renderers that ships as part of the
147             Meta-Grapher-Moose distribution.
148              
149             It uses the L<GraphViz2> module to use GraphViz to create graphs.
150              
151             =head2 Attributes
152              
153             =head3 output
154              
155             The name of the file that output should be written to. For example C<foo.png>.
156             If no output is specified then output will be sent to STDOUT.
157              
158             =head3 format
159              
160             The format of the output; Accepts any value that GraphViz2 will accept,
161             including C<png>, C<jpg>, C<svg>, C<pdf> and C<dot>
162              
163             If this is not specified then, if possible, it will be extracted from the
164             extension of the C<output>. If either the C<output> has not been set or the
165             output filename has no file extension then the output will default to
166             outputting raw dot source code.
167              
168             =head3 formatting
169              
170             The GraphViz attributes that you want to apply to your package nodes depending
171             on what type they are. The default values are:
172              
173             {
174             class => {
175             fontname => 'Helvetica',
176             fontsize => 9,
177             shape => 'rect',
178             style => 'bold',
179             },
180             role => {
181             fontname => 'Helvetica',
182             fontsize => 9,
183             shape => 'rect',
184             },
185             prole => {
186             fontname => 'Helvetica',
187             fontsize => 9,
188             shape => 'rect',
189             style => 'dotted',
190             },
191             anonrole => {
192             fontname => 'Helvetica',
193             fontsize => 9,
194             shape => 'rect',
195             style => 'dashed',
196             },
197             }
198              
199             More information on GraphViz attributes can be found at
200             L<http://www.graphviz.org/doc/info/attrs.html>
201              
202             =for Pod::Coverage render add_package add_edge
203              
204             =head1 SUPPORT
205              
206             Bugs may be submitted through L<the RT bug tracker|http://rt.cpan.org/Public/Dist/Display.html?Name=Meta-Grapher-Moose>
207             (or L<bug-meta-grapher-moose@rt.cpan.org|mailto:bug-meta-grapher-moose@rt.cpan.org>).
208              
209             I am also usually active on IRC as 'drolsky' on C<irc://irc.perl.org>.
210              
211             =head1 AUTHOR
212              
213             Dave Rolsky <autarch@urth.org>
214              
215             =head1 COPYRIGHT AND LICENSE
216              
217             This software is Copyright (c) 2016 by Dave Rolsky.
218              
219             This is free software, licensed under:
220              
221             The Artistic License 2.0 (GPL Compatible)
222              
223             =cut