File Coverage

blib/lib/Mojo/ShareDir.pm
Criterion Covered Total %
statement 33 34 97.0
branch 11 12 91.6
condition 7 14 50.0
subroutine 6 7 85.7
pod 2 2 100.0
total 59 69 85.5


line stmt bran cond sub pod time code
1             package Mojo::ShareDir;
2 2     2   361021 use Mojo::Base 'Mojo::File';
  2         21  
  2         9  
3              
4 2     2   57393 use Carp qw(croak);
  2         5  
  2         102  
5              
6 2   50 2   12 use constant DEBUG => $ENV{MOJO_FILE_SHARE_DEBUG} || 0;
  2         3  
  2         1229  
7              
8             our @EXPORT_OK = qw(dist_path);
9             our $VERSION = '0.02';
10              
11             our @AUTO_SHARE_DIST = qw(auto share dist);
12             our @AUTO_SHARE_MODULE = qw(auto share module);
13             our $LOCAL_SHARE_DIR = 'share';
14              
15 0     0 1 0 sub dist_path { __PACKAGE__->new(@_) }
16              
17             sub new {
18 9 100   9 1 6799 return shift->SUPER::new(@_) if ref $_[0];
19              
20 4 50       14 my ($class, $class_name, @child) = (shift, @_ ? shift : scalar caller, @_);
21 4   33     34 my @class_parts = split /(?:-|::)/, (ref $class_name || $class_name);
22 4   66     14 my $path = $class->_new_from_inc(\@class_parts) || $class->_new_from_installed(\@class_parts);
23 4 100       246 croak qq(Could not find dist path for "$class_name".) unless $path;
24              
25 3 100       30 $path = $path->child(@child) if @child;
26 3         29 warn "[Share] $class->new($class_name, ...) == $path\n" if DEBUG;
27 3         25 return $path;
28             }
29              
30             sub _new_from_inc {
31 4     4   6 my ($class, $class_parts) = @_;
32              
33             # Check if the class exists in %INC
34 4         18 my $inc_key = sprintf '%s.pm', join '/', @$class_parts;
35 4 100 66     63 return undef unless $INC{$inc_key} and -e $INC{$inc_key};
36              
37             # Find the absolute path to the module and then find the project root
38 3         22 my $path = $class->SUPER::new($INC{$inc_key})->to_abs->to_array;
39 3         87 pop @$path for 0 .. @$class_parts;
40              
41             # Return the project "root/share" if the directory exists
42 3         9 my $share = $class->SUPER::new(@$path, $LOCAL_SHARE_DIR);
43 3   33     61 return -d $share && $share;
44             }
45              
46             sub _new_from_installed {
47 4     4   84 my ($class, $class_parts) = @_;
48              
49 4         6 my @auto_path;
50 4         15 push @auto_path, $class->SUPER::new(@AUTO_SHARE_DIST, join '-', @$class_parts); # File::ShareDir::_dist_dir_new()
51 4         63 push @auto_path, $class->SUPER::new('auto', @$class_parts); # File::ShareDir::_dist_dir_old()
52              
53 4         47 for my $auto_path (@auto_path) {
54 5         24 for my $inc (@INC) {
55 28         418 my $share = $class->SUPER::new($inc, $auto_path);
56 28 100       416 return $share if -d $share;
57             }
58             }
59              
60 1         13 return undef;
61             }
62              
63             1;
64              
65             =encoding utf8
66              
67             =head1 NAME
68              
69             Mojo::ShareDir - Shared files and directories as Mojo::File objects
70              
71             =head1 SYNOPSIS
72              
73             =head2 Example use of Mojo::ShareDir
74              
75             use Mojo::ShareDir;
76              
77             # This will result in the same thing
78             my $path = Mojo::ShareDir->new('My-Application');
79             my $path = Mojo::ShareDir->new('My::Application');
80             my $path = Mojo::ShareDir->new(My::Application->new);
81              
82             =head2 Example Makefile.PL
83              
84             use strict;
85             use warnings;
86             use ExtUtils::MakeMaker;
87             use File::ShareDir::Install;
88              
89             install_share 'share';
90             WriteMakefile(...);
91              
92             package MY;
93             use File::ShareDir::Install qw(postamble);
94              
95             =head1 DESCRIPTION
96              
97             L is a module that allows you to find shared files. This
98             module works together with L, which allow you to
99             install assets that are not Perl related. In addition, L
100             makes it very easy to find the files that you have not yet installed by
101             looking for projects after resolving C<@INC>.
102              
103             =head1 FUNCTIONS
104              
105             L implements the following functions, which can be imported
106             individually.
107              
108             =head2 dist_path
109              
110             my $path = dist_path;
111             my $path = dist_path "Some-Dist", @path;
112             my $path = dist_path "Some::Module", @path;
113             my $path = dist_path $some_object, @path;
114              
115             Construct a new L object. Follows the same rules as L.
116              
117             =head1 METHODS
118              
119             L inherits all methods from L and implements the
120             following new ones.
121              
122             =head2 new
123              
124             my $path = Mojo::ShareDir->new;
125             my $path = Mojo::ShareDir->new("Some-Dist", @path);
126             my $path = Mojo::ShareDir->new("Some::Module", @path);
127             my $path = Mojo::ShareDir->new($some_object, @path);
128              
129             Construct a new L object with C<$path> set to either the
130             local "share/" path or the installed for a given distribution.
131              
132             Will throw an exception if the distribution cannot be found.
133              
134             To resolve the shared path, these rules will apply:
135              
136             =over 2
137              
138             =item * No arguments
139              
140             Will use the caller package name.
141              
142             =item * A dist name
143              
144             To resolve the local path, by converting the dist name into a module name, and
145             look it up in C<%INC>. This means the module need to be loaded.
146              
147             =item * A module name
148              
149             See "A dist name" above.
150              
151             =item * An object
152              
153             Will find the class name for the object and apply the same rule as for "A
154             module name".
155              
156             =back
157              
158             =head1 AUTHOR
159              
160             Jan Henning Thorsen
161              
162             =head1 COPYRIGHT AND LICENSE
163              
164             Copyright (C), Jan Henning Thorsen.
165              
166             This program is free software, you can redistribute it and/or modify it under
167             the terms of the Artistic License version 2.0.
168              
169             =head1 SEE ALSO
170              
171             L
172              
173             L
174              
175             L
176              
177             =cut