File Coverage

blib/lib/Dist/Zilla/Plugin/MapMetro/MakeLinePod.pm
Criterion Covered Total %
statement 13 15 86.6
branch n/a
condition n/a
subroutine 5 5 100.0
pod n/a
total 18 20 90.0


line stmt bran cond sub pod time code
1 1     1   17161 use 5.10.1;
  1         4  
  1         63  
2 1     1   7 use strict;
  1         2  
  1         53  
3 1     1   5 use warnings;
  1         1  
  1         42  
4 1     1   898 use utf8;
  1         12  
  1         5  
5              
6             package Dist::Zilla::Plugin::MapMetro::MakeLinePod;
7              
8             our $VERSION = '0.1100'; # VERSION
9              
10 1     1   1108 use Moose;
  0            
  0            
11             use namespace::sweep;
12             use Path::Tiny;
13             use List::AllUtils qw/any all uniq/;
14             use Types::Standard qw/Str Maybe/;
15             use Map::Metro::Shim;
16             use syntax 'qs';
17              
18             use Dist::Zilla::File::InMemory;
19             with 'Dist::Zilla::Role::FileGatherer';
20              
21             has cityname => (
22             is => 'rw',
23             isa => Maybe[Str],
24             predicate => 1,
25             );
26              
27             sub gather_files {
28             my $self = shift;
29             my $arg = shift;
30              
31             return if $ENV{'MMNOLINES'};
32             $self->log('Set MMNOLINES=1 to skip building Lines.pm');
33              
34             my @cities = path(qw/lib Map Metro Plugin Map/)->children(qr/\.pm/);
35             return if !scalar @cities;
36              
37             my @mapfiles = path('share')->children(qr{map-.*\.metro});
38             return if !scalar @mapfiles;
39              
40             my $city = (shift @cities)->basename;
41             $city =~ s{\.pm}{};
42             my $mapfile = shift @mapfiles;
43              
44             my $graph = Map::Metro::Shim->new(filepath => $mapfile)->parse(override_line_change_weight => 99999999);
45              
46             my @linepod = ();
47              
48             LINE:
49             foreach my $line ($graph->all_lines) {
50              
51             my @stations = $graph->filter_stations(sub {
52             my $station = $_;
53             return any { $_->id eq $line->id } $station->all_lines;
54             });
55             $self->log(sprintf 'Line %s, found %s stations', $line->name, scalar @stations);
56              
57             my @routes;
58             ORIGIN:
59             foreach my $i (0 .. $#stations) {
60             my $origin_station = $stations[ $i ];
61              
62              
63             DESTINATION:
64             foreach my $j (0 .. $#stations) {
65             my $destination_station = $stations[ $j ];
66             next DESTINATION if $origin_station->id == $destination_station->id;
67              
68             my $route = $graph->routing_for($origin_station->id, $destination_station->id)->get_route(0);
69             push @routes => $route if defined $route;
70             }
71             }
72              
73             # Find the two longest routes (termini<->termini, and then pick the alphabetical order)
74             my $chosen_route = (sort { $a->get_step(0)->origin_line_station->station->name cmp $b->get_step(0)->origin_line_station->station->name }
75             (sort { $b->step_count <=> $a->step_count } @routes)[0, 1]
76             )[0];
77              
78             my @station_pod;
79             foreach my $step ($chosen_route->all_steps) {
80             my @change_to_strings = $self->make_change_to_string($graph, $step->origin_line_station);
81             push @station_pod => (' ' x 4) . join ' ' => $step->origin_line_station->station->name, @change_to_strings;
82              
83             if(!$step->has_next_step) {
84             @change_to_strings = $self->make_change_to_string($graph, $step->destination_line_station);
85             push @station_pod => (' ' x 4) . join ' ' => $step->destination_line_station->station->name, @change_to_strings;
86             }
87             }
88              
89             push @linepod => sprintf '=head2 %s: %s → %s [%s]' => $line->description,
90             $chosen_route->get_step(0)->origin_line_station->station->name,
91             $chosen_route->get_step(-1)->destination_line_station->station->name,
92             $line->name;
93              
94             push @linepod => '', @station_pod, '';
95              
96             }
97              
98             my $file = Dist::Zilla::File::InMemory->new(
99             name => "lib/Map/Metro/Plugin/Map/$city/Lines.pm",
100             content => $self->make_line_contents($city, @linepod),
101             );
102             $self->add_file($file);
103              
104             return;
105             }
106              
107             sub make_change_to_string {
108             my $self = shift;
109             my $graph = shift;
110             my $line_station = shift;
111              
112             my @change_strings = ();
113             my @other_lines = $line_station->station->filter_lines(sub { $_->id ne $line_station->line->id });
114             push @change_strings => scalar @other_lines ? sprintf '(%s)', join ', ' => map { $_->name } @other_lines
115             : ()
116             ;
117              
118             my @transfers = $graph->filter_transfers(sub { $_->origin_station->id == $line_station->station->id });
119             push @change_strings => scalar @transfers ? join ' ' => map {
120             sprintf ('[%s: %s]', $_->destination_station->name,
121             join ', ' => map { $_->name } $_->destination_station->all_lines ) } @transfers
122             : ()
123             ;
124              
125             @transfers = $graph->filter_transfers(sub { $_->destination_station->id == $line_station->station->id });
126             push @change_strings => scalar @transfers ? join ' ' => map {
127             sprintf ('[%s: %s]', $_->origin_station->name,
128             join ', ' => map { $_->name } $_->origin_station->all_lines ) } @transfers
129             : ()
130             ;
131              
132             return @change_strings;
133             }
134              
135             sub make_line_contents {
136             my $self = shift;
137             my $city = shift;
138             my $content = join "\n" => @_;
139              
140             $content = sprintf qs{
141             package Map::Metro::Plugin::Map::%s::Lines;
142              
143             our $VERSION = '0.1100'; # VERSION
144              
145             1;
146              
147             _%s_
148              
149             =encoding utf-8
150              
151             =head1 NAME
152              
153             Map::Metro::Plugin::Map::%s::Lines - Detailed information about Map::Metro::Plugin::Map::%s
154              
155             =head1 LINES
156              
157             %s
158              
159             =head1 SEE ALSO
160              
161             L<Map::Metro::Plugin::Map::%s>
162              
163             %s
164              
165             }, $city, '_END_', $city, $city, $content, $city, '=cut';
166              
167             $content =~ s{^[ \s]+}{}g;
168              
169             return $content;
170              
171             }
172              
173             __PACKAGE__->meta->make_immutable;
174              
175             1;
176              
177             __END__
178              
179             =encoding utf-8
180              
181             =head1 NAME
182              
183             Dist::Zilla::Plugin::MapMetro::MakeLinePod - Automatically include line and station information
184              
185             =head1 SYNOPSIS
186              
187             ; in dist.ini
188             [MapMetro::MakeLinePod]
189              
190             =head1 DESCRIPTION
191              
192             This L<Dist::Zilla> plugin creates a C<::Lines> pod detailing all lines, stations, changes and transfers in the map.
193              
194             =head1 SEE ALSO
195              
196             L<Task::MapMetro::Dev> - Map::Metro development tools
197              
198             L<Map::Metro::Plugin::Map::Barcelona::Lines> - An example
199              
200             L<Map::Metro>
201              
202             L<Map::Metro::Plugin::Map>
203              
204             =head1 AUTHOR
205              
206             Erik Carlsson E<lt>info@code301.comE<gt>
207              
208             =head1 COPYRIGHT
209              
210             Copyright 2015 - Erik Carlsson
211              
212             =head1 LICENSE
213              
214             This library is free software; you can redistribute it and/or modify
215             it under the same terms as Perl itself.
216              
217             =cut