File Coverage

blib/lib/Dancer2/Core/Role/HasLocation.pm
Criterion Covered Total %
statement 32 32 100.0
branch 8 8 100.0
condition 11 11 100.0
subroutine 6 6 100.0
pod n/a
total 57 57 100.0


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.0.1';
4 158     158   819818 use Moo::Role;
  158         21128  
  158         1589  
5 158     158   96122 use Dancer2::Core::Types;
  158         515  
  158         1470  
6 158     158   2392345 use Dancer2::FileUtils;
  158         1264  
  158         11049  
7 158     158   1208 use File::Spec;
  158         413  
  158         6483  
8 158     158   1165 use Sub::Quote 'quote_sub';
  158         377  
  158         76905  
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             my ( $caller, $script ) = CORE::caller;
20             $script = File::Spec->abs2rel( $script ) if File::Spec->file_name_is_absolute( $script );
21             $script;
22             } ),
23             );
24              
25             has location => (
26             is => 'ro',
27             isa => Str,
28             lazy => 1,
29             builder => '_build_location',
30             );
31              
32             # FIXME: i hate you most of all -- Sawyer X
33             sub _build_location {
34 256     256   41783 my $self = shift;
35 256         1379 my $script = $self->caller;
36              
37             # default to the dir that contains the script...
38 256         1744 my $location = Dancer2::FileUtils::dirname($script);
39              
40             #we try to find bin and lib
41 256         931 my $subdir = $location;
42 256         589 my $subdir_found = 0;
43              
44             #maximum of 10 iterations, to prevent infinite loop
45 256         1214 for ( 1 .. 10 ) {
46              
47             #try to find libdir and bindir to determine the root of dancer app
48 2481         6999 my $libdir = Dancer2::FileUtils::path( $subdir, 'lib' );
49 2481         5693 my $bindir = Dancer2::FileUtils::path( $subdir, 'bin' );
50              
51             #try to find .dancer_app file to determine the root of dancer app
52 2481         5256 my $dancerdir = Dancer2::FileUtils::path( $subdir, '.dancer' );
53              
54             # if one of them is found, keep that; but skip ./blib since both lib and bin exist
55             # under it, but views and public do not.
56 2481 100 100     95158 if (
      100        
      100        
57             ( $subdir !~ m![\\/]blib[\\/]?$! && -d $libdir && -d $bindir ) ||
58             ( -f $dancerdir )
59             ) {
60 9         25 $subdir_found = 1;
61 9         32 last;
62             }
63              
64 2472   100     8158 $subdir = Dancer2::FileUtils::path( $subdir, '..' ) || '.';
65 2472 100       49368 last if File::Spec->rel2abs($subdir) eq File::Spec->rootdir;
66              
67             }
68              
69 256 100       1426 my $path = $subdir_found ? $subdir : $location;
70              
71             # return if absolute
72 256 100       1718 File::Spec->file_name_is_absolute($path)
73             and return $path;
74              
75             # convert relative to absolute
76 251         10963 return File::Spec->rel2abs($path);
77             }
78              
79             1;
80              
81             __END__