File Coverage

blib/lib/Dancer2/Core/Role/HasLocation.pm
Criterion Covered Total %
statement 34 34 100.0
branch 7 8 87.5
condition 9 9 100.0
subroutine 7 7 100.0
pod n/a
total 57 58 98.2


line stmt bran cond sub pod time code
1             package Dancer2::Core::Role::HasLocation;
2             # ABSTRACT: Role for application location "guessing"
3             $Dancer2::Core::Role::HasLocation::VERSION = '2.1.0';
4 162     162   940338 use Carp ();
  162         453  
  162         5812  
5 162     162   1603 use Moo::Role;
  162         20192  
  162         1515  
6 162     162   94047 use Sub::Quote 'quote_sub';
  162         19538  
  162         11869  
7 162     162   2147 use Path::Tiny ();
  162         19143  
  162         8985  
8 162     162   2284 use Dancer2::Core::Types;
  162         429  
  162         1742  
9              
10             # the path to the caller script/app
11             # Note: to remove any ambiguity between the accessor for the
12             # 'caller' attribute and the core function caller(), explicitly
13             # specify we want the function 'CORE::caller' as the default for
14             # the attribute.
15             has caller => (
16             is => 'ro',
17             isa => Str,
18             default => quote_sub( q{
19             require Path::Tiny;
20             my ( $caller, $script ) = CORE::caller;
21             Path::Tiny::path($script)->relative->stringify;
22             } ),
23             );
24              
25             has location => (
26             is => 'ro',
27             isa => Str,
28             lazy => 1,
29             builder => '_build_location',
30             );
31              
32             has _location_path => (
33             is => 'ro',
34             lazy => 1,
35             builder => '_build_location_path',
36             init_arg => undef,
37             );
38              
39             sub _build_location_path {
40 259     259   3239 my $self = shift;
41 259         5913 return Path::Tiny::path( $self->location );
42             }
43              
44             # FIXME: i hate you most of all -- Sawyer X
45             sub _build_location {
46 262     262   45197 my $self = shift;
47 262         2480 my $script = $self->caller;
48              
49             # default to the dir that contains the script...
50 262         1934 my $location = Path::Tiny::path($script)->parent;
51              
52 262 50       52134 $location->is_dir
53             or Carp::croak("Caller $script is not an existing file");
54              
55             #we try to find bin and lib
56 262         10205 my $subdir = $location;
57 262         705 my $subdir_found = 0;
58              
59             #maximum of 10 iterations, to prevent infinite loop
60 262         1244 for ( 1 .. 10 ) {
61              
62             #try to find libdir and bindir to determine the root of dancer app
63 1492         226540 my $libdir = $subdir->child('lib');
64 1492         60334 my $bindir = $subdir->child('bin');
65              
66             #try to find .dancer_app file to determine the root of dancer app
67 1492         58390 my $dancerdir = $subdir->child('.dancer');
68              
69             # if one of them is found, keep that; but skip ./blib since both lib and bin exist
70             # under it, but views and public do not.
71 1492 100 100     56127 if (
      100        
      100        
72             ( $subdir !~ m![\\/]blib[\\/]?$! && $libdir->is_dir && $bindir->is_dir ) ||
73             ( $dancerdir->is_file )
74             ) {
75 9         815 $subdir_found = 1;
76 9         46 last;
77             }
78              
79 1483         66136 $subdir = $subdir->parent;
80              
81 1483 100       82287 last if $subdir->realpath->stringify eq Path::Tiny->rootdir->stringify;
82             }
83              
84 262 100       41225 my $path = $subdir_found ? $subdir : $location;
85              
86             # convert relative to absolute
87 262         1157 return $path->realpath->stringify;
88             }
89              
90             1;
91              
92             __END__