File Coverage

blib/lib/Test/Requires/Git.pm
Criterion Covered Total %
statement 82 82 100.0
branch 35 36 97.2
condition 11 11 100.0
subroutine 12 12 100.0
pod 1 1 100.0
total 141 142 99.3


line stmt bran cond sub pod time code
1             package Test::Requires::Git;
2             $Test::Requires::Git::VERSION = '1.008';
3 14     14   240690 use strict;
  14         22  
  14         364  
4 14     14   60 use warnings;
  14         16  
  14         343  
5              
6 14     14   55 use Carp;
  14         16  
  14         1046  
7 14     14   6370 use Git::Version::Compare ();
  14         19833  
  14         357  
8              
9 14     14   65 use base 'Test::Builder::Module';
  14         18  
  14         2704  
10              
11             our $GIT = 'git';
12              
13             my %check = (
14             version_eq => \&Git::Version::Compare::eq_git,
15             version_ne => \&Git::Version::Compare::ne_git,
16             version_gt => \&Git::Version::Compare::gt_git,
17             version_le => \&Git::Version::Compare::le_git,
18             version_lt => \&Git::Version::Compare::lt_git,
19             version_ge => \&Git::Version::Compare::ge_git,
20             );
21              
22             # aliases
23             $check{'=='} = $check{eq} = $check{version} = $check{version_eq};
24             $check{'!='} = $check{ne} = $check{version_ne};
25             $check{'>'} = $check{gt} = $check{version_gt};
26             $check{'<='} = $check{le} = $check{version_le};
27             $check{'<'} = $check{lt} = $check{version_lt};
28             $check{'>='} = $check{ge} = $check{version_ge};
29              
30             my $quiet = 0;
31             my $lock = '.test.requires.git.lock';
32              
33             sub import {
34 15     15   3207 my $class = shift;
35 15         27 my $caller = caller(0);
36              
37             # export methods
38             {
39 14     14   61 no strict 'refs';
  14         17  
  14         5129  
  15         17  
40 15         22 *{"$caller\::test_requires_git"} = \&test_requires_git;
  15         66  
41             }
42              
43 15 100 100     9278 return if @_ == 1 && $_[0] eq '-nocheck';
44              
45             # reset the global $GIT value
46 10         31 my $args = _extract_arguments(@_);
47 10 100       26 $GIT = $args->{git} if exists $args->{git};
48              
49             # test arguments
50 10         17 test_requires_git(@_);
51             }
52              
53             sub _extract_arguments {
54 296     296   486 my (@args) = @_;
55              
56 296         254 my ( %args, @spec );
57 296         631 while (@args) {
58              
59             # assume a lone parameter is a minimum git version
60 538 100       912 unshift @args, 'version_ge' if @args == 1;
61              
62 538         689 my ( $key, $val ) = splice @args, 0, 2;
63 538 100       1560 if ( $key =~ /^(?:git|skip)/ ) {
    100          
64 258 100       564 croak "Duplicate '$key' argument" if exists $args{$key};
65 257         702 $args{$key} = $val;
66             }
67             elsif ( !exists $check{$key} ) {
68 2 100       12 if ( @args % 2 ) { # odd number of arguments (see above)
69 1         4 unshift @args, version_ge => $key, $val;
70 1         2 redo;
71             }
72 1         168 croak "Unknown git specification '$key'";
73             }
74             else {
75 278         607 push @spec, $key, $val;
76             }
77             }
78 294 100       916 return wantarray ? ( \%args, @spec ) : \%args;
79             }
80              
81 5     5   11540 sub _git_version { qx{$GIT --version} }
82              
83             sub test_requires_git {
84 286     286 1 78456 my ( $args, @spec ) = _extract_arguments(@_);
85 284         317 my $skip = $args->{skip};
86 284 100       442 local $GIT = $args->{git} if exists $args->{git};
87              
88             # get the git version
89 284         221 my ($version) = do {
90 14     14   76 no warnings 'uninitialized';
  14         22  
  14         3255  
91 284         641 __PACKAGE__->_git_version(); # tests may override this
92             };
93              
94 284         1443 my $builder = __PACKAGE__->builder;
95 284 100 100     5978 if ( !$quiet && time - ( ( stat $lock )[9] || 0 ) > 60 ) {
      100        
96 1         40 $builder->diag($version);
97 1         289 $quiet++;
98 1 50       111 open my $fh, '>', $lock if !-e $lock;
99 1         46 utime( undef, undef, $lock );
100             }
101              
102             # perform the check
103 284         501 my ( $ok, $why ) = ( 1, '' );
104 284 100 100     904 if ( defined $version && Git::Version::Compare::looks_like_git($version) ) {
105 279         2991 while ( my ( $spec, $arg ) = splice @spec, 0, 2 ) {
106 274 100       6351 if ( !$check{$spec}->( $version, $arg ) ) {
107 150         1483 $ok = 0;
108 150         651 $version =~ s/^git version|[\012\015]+$//g;
109 150         262 $why = "$version $spec $arg";
110 150         173 last;
111             }
112             }
113             }
114             else {
115 5         30 $ok = 0;
116 5         33 $why = "`$GIT` binary not available or broken";
117             }
118              
119             # skip if needed
120 282 100       12930 if ( !$ok ) {
121              
122             # skip a specified number of tests
123 155 100       255 if ( $skip ) {
    100          
    100          
124 146         410 $builder->skip($why) for 1 .. $skip;
125 14     14   63 no warnings 'exiting';
  14         18  
  14         2230  
126 146         14913 last SKIP;
127             }
128              
129             # no plan declared yet
130             elsif ( !defined $builder->has_plan ) {
131 3 100       34 if ( $builder->summary ) {
132 1         11 $builder->skip($why);
133 1         212 $builder->done_testing;
134 1         202 exit 0;
135             }
136             else {
137 2         23 $builder->skip_all($why);
138             }
139             }
140              
141             # the plan is no_plan
142             elsif ( $builder->has_plan eq 'no_plan' ) {
143 1         17 $builder->skip($why);
144 1         222 exit 0;
145             }
146              
147             # some plan was declared, skip all tests one by one
148             else {
149 5         100 $builder->skip($why) for 1 + $builder->summary .. $builder->has_plan;
150 5         2026 exit 0;
151             }
152             }
153             }
154              
155             'git';
156              
157             __END__