File Coverage

blib/lib/Test/NewVersion.pm
Criterion Covered Total %
statement 88 91 96.7
branch 21 30 70.0
condition 11 21 52.3
subroutine 22 22 100.0
pod 2 2 100.0
total 144 166 86.7


line stmt bran cond sub pod time code
1 4     4   113880 use strict;
  4         8  
  4         175  
2 4     4   23 use warnings;
  4         7  
  4         256  
3             package Test::NewVersion; # git description: 82930bd
4             # ABSTRACT: provides a test interface for checking that you are using a new $VERSION
5             # KEYWORDS: test distribution release author version unique new
6             # vim: set ts=8 sw=4 tw=78 et :
7              
8             our $VERSION = '0.001';
9              
10 4     4   1694 use parent 'Exporter';
  4         1113  
  4         23  
11             our @EXPORT = qw(all_new_version_ok new_version_ok);
12              
13 4     4   272 use File::Find;
  4         5  
  4         313  
14 4     4   21 use File::Spec;
  4         5  
  4         79  
15 4     4   2409 use Encode ();
  4         39469  
  4         121  
16 4     4   2859 use HTTP::Tiny;
  4         228779  
  4         197  
17 4     4   2403 use JSON::MaybeXS;
  4         32706  
  4         319  
18 4     4   2449 use version;
  4         8546  
  4         37  
19 4     4   3379 use Module::Metadata;
  4         31866  
  4         185  
20 4     4   29 use List::Util 'first';
  4         6  
  4         420  
21 4     4   2731 use CPAN::Meta 2.120920;
  4         100997  
  4         138  
22 4     4   38 use Test::Builder 0.88;
  4         63  
  4         75  
23 4     4   2255 use namespace::clean;
  4         66965  
  4         23  
24              
25             my $no_plan;
26              
27             sub import
28             {
29             # END block will check for this status
30 4     4   29 my @symbols = grep { $_ ne ':no_plan' } @_;
  4         12  
31 4         8 $no_plan = (@symbols != @_);
32              
33 4         2223 __PACKAGE__->export_to_level(1, @symbols);
34             }
35              
36             # for testing this module only!
37             my $tb;
38             sub _builder(;$)
39             {
40 4 50   4   18 if (not @_)
41             {
42 4   33     110 $tb ||= Test::Builder->new;
43 4         51 return $tb;
44             }
45              
46 0         0 $tb = shift;
47             }
48              
49             END {
50 4 50 33 4   39753 if (not $no_plan
      33        
51             and not _builder->expected_tests
52             # skip this if no tests have been run (e.g. compilation tests of this module!)
53             and (_builder->current_test > 0)
54             )
55             {
56 0         0 _builder->done_testing;
57             }
58             }
59              
60              
61             sub all_new_version_ok
62             {
63             # find all files in blib or lib
64 4     4 1 537 my @files;
65 4         12 my @lib_dirs = grep { -d } qw(blib/lib lib);
  8         86  
66              
67             find(
68             {
69             wanted => sub {
70 20 100 66 20   1610 push @files, File::Spec->no_upwards($File::Find::name)
      100        
71             if -r $File::Find::name
72             and $File::Find::name =~ /\.pm$/ or $File::Find::name =~ /\.pod$/;
73             },
74 4 50       399 no_chdir => 1,
75             },
76             $lib_dirs[0],
77             ) if @lib_dirs;
78              
79             # also add .pod, .pm files in the top level directory
80 4         382 push @files, grep { -f } glob('*.pod'), glob('*.pm');
  0         0  
81              
82 4         45 new_version_ok($_) foreach sort @files;
83             }
84              
85             sub new_version_ok
86             {
87 10     10 1 1031 my $filename = shift;
88              
89 10         155 my $builder = Test::Builder->new;
90              
91 10         126 my $module_metadata = Module::Metadata->new_from_file($filename);
92 10         9607 foreach my $pkg ($module_metadata->packages_inside)
93             {
94 10 100       87 next if $pkg eq 'main';
95 9         34 my ($bumped, $message) = _version_is_bumped($module_metadata, $pkg);
96              
97 9         32 local $Test::Builder::Level = $Test::Builder::Level + 1;
98 9 50       150 $builder->ok($bumped, $pkg . ' (' . $filename . ') VERSION is ok'
99             . ( $message ? (' (' . $message . ')') : '' )
100             );
101             }
102             }
103              
104             # 'provides' field from dist metadata, if needed
105             my $dist_provides;
106              
107             # returns bool, detailed message
108             sub _version_is_bumped
109             {
110 9     9   22 my ($module_metadata, $pkg) = @_;
111              
112 9         82 my $res = HTTP::Tiny->new->get("http://cpanidx.org/cpanidx/json/mod/$pkg");
113 9 50       213204 return (0, 'index could not be queried?') if not $res->{success};
114              
115 9         43 my $data = $res->{content};
116              
117 9         4558 require HTTP::Headers;
118 9 50       33154 if (my $charset = HTTP::Headers->new(%{ $res->{headers} })->content_type_charset)
  9         134  
119             {
120 9         7632 $data = Encode::decode($charset, $data, Encode::FB_CROAK);
121             }
122              
123 9         1604 my $payload = decode_json($data);
124 9 50       33 return (0, 'invalid payload returned') unless $payload;
125 9 100       70 return (1, 'not indexed') if not defined $payload->[0]{mod_vers};
126 5 100       38 return (1, 'VERSION is not set in index') if $payload->[0]{mod_vers} eq 'undef';
127              
128 4         60 my $indexed_version = version->parse($payload->[0]{mod_vers});
129 4         27 my $current_version = $module_metadata->version($pkg);
130              
131 4 100       62 if (not defined $current_version)
132             {
133 2   66     9 $dist_provides ||= do {
134 1     3   11 my $metafile = first { -e $_ } qw(MYMETA.json MYMETA.yml META.json META.yml);
  3         46  
135 1 50       20 my $dist_metadata = $metafile ? CPAN::Meta->load_file($metafile) : undef;
136 1 50       7312 $dist_metadata->provides if $dist_metadata;
137             };
138              
139 2         1023 $current_version = $dist_provides->{$pkg}{version};
140 2 100 33     58 return (0, 'VERSION is not set; indexed version is ' . $indexed_version)
141             if not $dist_provides or not $current_version;
142             }
143              
144             return (
145 3         148 $indexed_version < $current_version,
146             'indexed at ' . $indexed_version . '; local version is ' . $current_version,
147             );
148             }
149              
150             1;
151              
152             __END__