Newer Older
134 lines | 3.226kb
add files
Yuki Kimoto authored on 2014-03-26
1
package Mojolicious::Command::routes;
2
use Mojo::Base 'Mojolicious::Command';
3

            
4
use re 'regexp_pattern';
5
use Getopt::Long qw(GetOptionsFromArray :config no_auto_abbrev no_ignore_case);
6
use Mojo::Util 'encode';
7

            
8
has description => "Show available routes.\n";
9
has usage       => <<EOF;
10
usage: $0 routes [OPTIONS]
11

            
12
These options are available:
13
  -v, --verbose   Print additional details about routes.
14
EOF
15

            
16
sub run {
17
  my ($self, @args) = @_;
18

            
19
  GetOptionsFromArray \@args, 'v|verbose' => \my $verbose;
20

            
21
  my $routes = [];
22
  $self->_walk($_, 0, $routes) for @{$self->app->routes->children};
23
  $self->_draw($routes, $verbose);
24
}
25

            
26
sub _draw {
27
  my ($self, $routes, $verbose) = @_;
28

            
29
  my @table = (0, 0, 0);
30
  for my $node (@$routes) {
31

            
32
    # Methods
33
    my $via = $node->[0]->via;
34
    $node->[2] = !$via ? '*' : uc join ',', @$via;
35

            
36
    # Name
37
    my $name = $node->[0]->name;
38
    $node->[3] = $node->[0]->has_custom_name ? qq{"$name"} : $name;
39

            
40
    # Check column width
41
    $table[$_] = _max($table[$_], length $node->[$_ + 1]) for 0 .. 2;
42
  }
43

            
44
  for my $node (@$routes) {
45
    my @parts = map { _padding($node->[$_ + 1], $table[$_]) } 0 .. 2;
46

            
47
    # Regex (verbose)
48
    my $pattern = $node->[0]->pattern;
49
    $pattern->match('/', $node->[0]->is_endpoint);
50
    my $regex = (regexp_pattern $pattern->regex)[0];
51
    my $format = (regexp_pattern($pattern->format_regex || ''))[0];
52
    my $optional
53
      = !$pattern->constraints->{format} || $pattern->defaults->{format};
54
    $regex .= $optional ? "(?:$format)?" : $format
55
      if $format && !$node->[0]->partial;
56
    push @parts, $regex if $verbose;
57

            
58
    say encode('UTF-8', join('  ', @parts));
59
  }
60
}
61

            
62
sub _max { $_[1] > $_[0] ? $_[1] : $_[0] }
63

            
64
sub _padding { $_[0] . ' ' x ($_[1] - length $_[0]) }
65

            
66
sub _walk {
67
  my ($self, $route, $depth, $routes) = @_;
68

            
69
  my $prefix = '';
70
  if (my $i = $depth * 2) { $prefix .= ' ' x $i . '+' }
71
  push @$routes, [$route, $prefix . ($route->pattern->pattern || '/')];
72

            
73
  $depth++;
74
  $self->_walk($_, $depth, $routes) for @{$route->children};
75
  $depth--;
76
}
77

            
78
1;
79

            
80
=encoding utf8
81

            
82
=head1 NAME
83

            
84
Mojolicious::Command::routes - Routes command
85

            
86
=head1 SYNOPSIS
87

            
88
  use Mojolicious::Command::routes;
89

            
90
  my $routes = Mojolicious::Command::routes->new;
91
  $routes->run(@ARGV);
92

            
93
=head1 DESCRIPTION
94

            
95
L<Mojolicious::Command::routes> lists all your application routes.
96

            
97
This is a core command, that means it is always enabled and its code a good
98
example for learning to build new commands, you're welcome to fork it.
99

            
100
=head1 ATTRIBUTES
101

            
102
L<Mojolicious::Command::routes> inherits all attributes from
103
L<Mojolicious::Command> and implements the following new ones.
104

            
105
=head2 description
106

            
107
  my $description = $routes->description;
108
  $routes         = $routes->description('Foo!');
109

            
110
Short description of this command, used for the command list.
111

            
112
=head2 usage
113

            
114
  my $usage = $routes->usage;
115
  $routes   = $routes->usage('Foo!');
116

            
117
Usage information for this command, used for the help screen.
118

            
119
=head1 METHODS
120

            
121
L<Mojolicious::Command::routes> inherits all methods from
122
L<Mojolicious::Command> and implements the following new ones.
123

            
124
=head2 run
125

            
126
  $routes->run(@ARGV);
127

            
128
Run this command.
129

            
130
=head1 SEE ALSO
131

            
132
L<Mojolicious>, L<Mojolicious::Guides>, L<http://mojolicio.us>.
133

            
134
=cut