Analizo

 view release on metacpan or  search on metacpan

lib/Analizo/Command/graph.pm  view on Meta::CPAN

package Analizo::Command::graph;
use Analizo -command;
use parent qw(Analizo::Command);
use strict;
use warnings;
use Analizo::Extractor;
use Graph::Writer::Dot;
use File::Basename;

# ABSTRACT: dependency graph generator

=head1 NAME

analizo-graph - dependency graph generator

=head1 USAGE

  analizo graph [OPTIONS] <input> [<input> [<input> ...]]

=cut

sub usage_desc { "%c graph %o <input> [<input> [<input> ...]]" }

sub opt_spec {
  return (
    [ 'extractor=s', 'which extractor method use to parse the source code' ],
    [ 'output|o=s',  'output file name' ],
    [ 'omit=s',      'omit the given functions from the call graph', { default => '' } ],
    [ 'cluster',     'cluster the functions into files' ],
    [ 'modules',     'group the functions by modules(files)' ],
  );
}

sub validate {
  my ($self, $opt, $args) = @_;
  $self->usage_error("No input files!") unless @$args;
  my @unreadable = grep { ! -r $_ || ! -e $_ } @$args;
  if (@unreadable) {
    foreach my $file (@unreadable) {
      $self->usage_error("$file is not readable");
    }
  }
  if ($opt->output && ! -w dirname($opt->output)) {
    $self->usage_error("No such file or directory");
  }
}

sub execute {
  my ($self, $opt, $args) = @_;
  my $extractor = Analizo::Extractor->load($opt->extractor);
  $extractor->process(@$args);
  my @omitted = split /,/, $opt->omit;
  my $graph = $extractor->model->callgraph(
    group_by_module => $opt->modules,
    omit => \@omitted,
  );
  if ($opt->output) {
    open STDOUT, '>', $opt->output or die "$!";
  }
  my $stdout = \*STDOUT;
  my $graph_writer = Graph::Writer::Dot->new(
    cluster => ($opt->cluster ? 'group' : undef),
  );
  $graph_writer->write_graph($graph, $stdout);
  close STDOUT;
}

=head1 DESCRIPTION

analizo graph reads the dependency information from one or more source code
directories passed as arguments, and produces as output the graph of
dependencies between the modules of the software in the graphviz(1) format.

analizo graph is part of the analizo suite.

=head1 REQUIRED ARGUMENTS

=over

=item <input>...

The input directories (or files) with source code to be processed.

Although you can pass individual files as input, this tool is more useful if
you pass entire source directories. If you pass just a couple of files, their
dependencies on modules that are not declared and/or implemented in those
files will not be calculated.

=back

=head1 OPTIONS

=over



( run in 0.715 second using v1.01-cache-2.11-cpan-d01c6094234 )