File Coverage

blib/lib/lib/gitroot.pm
Criterion Covered Total %
statement 49 51 96.0
branch 22 24 91.6
condition 8 11 72.7
subroutine 12 14 85.7
pod 0 2 0.0
total 91 102 89.2


line stmt bran cond sub pod time code
1             package lib::gitroot;
2              
3             our $VERSION = '0.004'; # VERSION
4              
5 3     3   133402 use Modern::Perl;
  3         7  
  3         19  
6 3     3   404 use Carp;
  3         7  
  3         182  
7 3     3   19 use File::Spec;
  3         7  
  3         61  
8 3     3   2527 use lib ();
  3         2287  
  3         927  
9              
10             our $_GIT_ROOT = undef;
11              
12 7     7 0 49 sub GIT_ROOT { $_GIT_ROOT };
13              
14             our %_default_values = ( lib => 'lib' );
15              
16             # :set_root
17             # :lib (implies :set_root, same as lib => 'lib')
18             # lib => library path
19             # use_base_dir => 'somedir_or_filename'
20             sub import
21             {
22 9 100 100 9   33678 my ($class, %args) = map { /^:(.*)$/ ? ($1 => $_default_values{$1} || 1) : $_ } @_;
  23         142  
23 9 100       37 $args{set_root} = 1 if defined $args{lib};
24              
25 9         28 my ($module, $filename) = caller;
26 9 100       28 $filename = $args{use_base_dir} if defined $args{use_base_dir};
27              
28 9 50       25 if ($args{set_root}) {
29              
30 9 100       21 if (defined $_GIT_ROOT) {
31 3 100       32 die "Git Root already set" unless $args{once};
32             } else {
33 6   33     13 $filename //= $args{path};
34 6         15 $_GIT_ROOT = _find_git_dir_for_filename($filename);
35 6 100 66     18954 lib->import($_GIT_ROOT.'/'.$args{lib}) if defined $args{lib} and defined $_GIT_ROOT;
36             }
37             }
38              
39              
40 3     3   20 no strict 'refs';
  3         6  
  3         99  
41 3     3   17 no warnings 'redefine';
  3         7  
  3         1548  
42 7         5411 *{"$module\::GIT_ROOT"} = \&GIT_ROOT;
  7         54  
43             }
44              
45              
46             # finds .git root
47             # $filename - file or directory name to start searching for .git. default to caller.
48             sub find_git_dir {
49 4     4 0 11953 my ($filename, %args) = @_;
50 4 50       14 (undef, $filename) = caller unless defined $filename;
51 4 100 100     21 $filename = _readlink($filename) if delete $args{resolve_symlink} && _is_link($filename);
52 4 100       788 confess "Unknown option(s) for find_git_dir: ".((keys %args)[0]) if %args;
53 2         5 _find_git_dir_for_filename($filename);
54             }
55              
56             # finds .git root
57             # $filename - file or directory name to start searching for .git
58             sub _find_git_dir_for_filename {
59 8     8   15 my ($filename) = @_;
60 8         32 _find_git_dir_for_path_and_isdir( File::Spec->rel2abs($filename), _is_dir($filename) );
61             }
62              
63             # finds .git root
64             # $abspath - file or directory name to start searching for .git. must be absolute
65             # $is_dir - should be TRUE if $abspath represent directory
66             sub _find_git_dir_for_path_and_isdir
67             {
68 16     16   22743 my ($abspath, $is_dir) = @_;
69 16         131 my @dirs = File::Spec->splitdir ( $abspath );
70 16 100       55 pop @dirs unless $is_dir;
71 16         44 while (@dirs) {
72 37         315 my $gitdir = File::Spec->catdir(@dirs, '.git');
73 37 100       119 if (_is_dir($gitdir)) {
74 12         7217 return File::Spec->catdir(@dirs);
75             }
76 25         14582 pop @dirs;
77             }
78 4         18 return;
79             }
80              
81             # like -d, made as function for testing purpose
82 0     0   0 sub _is_dir { -d shift(); };
83 1     1   32 sub _is_link { -l shift(); };
84 0     0     sub _readlink { readlink shift(); };
85              
86              
87             1;
88              
89             __END__