File Coverage

blib/lib/Shipwright/Script/List.pm
Criterion Covered Total %
statement 25 147 17.0
branch 0 66 0.0
condition 0 23 0.0
subroutine 9 11 81.8
pod 0 2 0.0
total 34 249 13.6


line stmt bran cond sub pod time code
1             package Shipwright::Script::List;
2              
3 2     2   1351 use strict;
  2         5  
  2         48  
4 2     2   9 use warnings;
  2         3  
  2         46  
5 2     2   8 use Shipwright::Util;
  2         5  
  2         154  
6              
7 2     2   11 use base qw/App::CLI::Command Shipwright::Base Shipwright::Script/;
  2         9  
  2         335  
8             __PACKAGE__->mk_accessors(qw/with_latest_version only_update/);
9              
10 2     2   11 use Shipwright;
  2         5  
  2         12  
11 2     2   54 use Cwd qw/getcwd/;
  2         5  
  2         76  
12 2     2   14 use File::Temp qw/tempdir/;
  2         4  
  2         75  
13 2     2   9 use File::Spec::Functions qw/catdir/;
  2         4  
  2         2576  
14              
15             sub options {
16             (
17 5     5 0 1444 'with-latest-version' => 'with_latest_version',
18             'only-update' => 'only_update',
19             );
20             }
21              
22             sub run {
23 0     0 0   my $self = shift;
24 0           my $name = shift;
25              
26 0           my $shipwright = Shipwright->new( repository => $self->repository, );
27              
28 0           my $versions = $shipwright->backend->version;
29 0           my $source = $shipwright->backend->source;
30 0   0       my $refs = $shipwright->backend->refs || {};
31 0           my $branches;
32              
33 0 0         if ( $shipwright->backend->has_branch_support ) {
34 0           $branches = $shipwright->backend->branches;
35             }
36              
37 0           my $latest_version = {};
38              
39             # only_update option implies with_latest_version
40 0 0         $self->with_latest_version(1) if $self->only_update;
41              
42 0 0         if ( $self->with_latest_version ) {
43 0           my $map = $shipwright->backend->map;
44              
45 0 0         if ($name) {
46 0 0 0       if ( $name =~ /^cpan-/ && !$source->{$name} ) {
47 0           my %reversed = reverse %$map;
48 0           my $module = $reversed{$name};
49 0           $latest_version->{$name} =
50             $self->_latest_version( name => $module );
51             }
52             else {
53             $latest_version->{$name} =
54 0           $self->_latest_version( url => $source->{$name} );
55             }
56             }
57             else {
58              
59 0           for my $module ( keys %$map ) {
60 0 0         next if exists $latest_version->{ $map->{$module} };
61 0           $latest_version->{ $map->{$module} } =
62             $self->_latest_version( name => $module );
63             }
64 0           for my $name ( keys %$source ) {
65 0 0         next if exists $latest_version->{$name};
66 0           for my $branch ( keys %{ $source->{$name} } ) {
  0            
67 0 0         if ( $source->{$name}{$branch} =~
68             m{^(sv[nk]|git|shipwright):} )
69             {
70             $latest_version->{$name}{$branch} =
71             $self->_latest_version(
72 0           url => $source->{$name}{$branch} );
73             }
74             }
75             }
76             }
77             }
78              
79 0 0         if ($name) {
80 0           my $new_versions = {};
81             $new_versions->{$name} = $versions->{$name}
82 0 0         if exists $versions->{$name};
83 0           $versions = $new_versions;
84             }
85 0           for my $name ( sort keys %$versions ) {
86 0           my $flip = 1;
87              
88 0 0         if ( $self->only_update ) {
89 0           $flip = 0;
90 0 0         if ( $latest_version->{$name} ) {
91 0           require version;
92 0           my $latest = version->new( $latest_version->{$name} );
93 0 0         if ( ref $versions->{$name} ) {
    0          
94              
95             # we show this dist if at least one of the branches has update
96 0           for my $branch ( keys %{ $versions->{$name} } ) {
  0            
97 0 0         if ( $latest gt $versions->{$name}{$branch} ) {
98 0           $flip = 1;
99 0           last;
100             }
101             }
102             }
103             elsif ( $latest gt $versions->{$name} ) {
104 0           $flip = 1;
105             }
106             }
107             }
108              
109 0 0         if ($flip) {
110 0           $self->log->fatal( $name, ':' );
111 0           my $version_info;
112 0 0         if ( ref $versions->{$name} ) {
113              
114 0 0         if ( $name =~ /^cpan-/ ) {
115 0           $version_info = $versions->{$name}{'vendor'};
116             }
117             else {
118 0           $version_info = "\n";
119 0           for my $branch ( keys %{ $versions->{$name} } ) {
  0            
120             $version_info .= ' ' x 8 .
121 0   0       $branch . ': ' . $versions->{$name}{$branch}
122             || '' . "\n";
123             }
124 0           chomp $version_info;
125             }
126             }
127             else {
128 0   0       $version_info = $versions->{$name} || '';
129             }
130 0           $self->log->fatal( ' ' x 4 . 'version: ' . $version_info );
131              
132 0           my $from_info;
133 0 0         if ( ref $source->{$name} ) {
134 0           $from_info = "\n";
135 0           for my $branch ( keys %{ $source->{$name} } ) {
  0            
136             $from_info .= ' ' x 8 . $branch .
137 0   0       ': ' . $source->{$name}{$branch} || '' . "\n";
138             }
139 0           chomp $from_info;
140             }
141             else {
142 0   0       $from_info = $source->{$name} || 'CPAN';
143             }
144 0           $self->log->fatal( ' ' x 4 . 'from: ' . $from_info );
145              
146             $self->log->fatal( ' ' x 4 . 'references: ',
147 0 0         defined $refs->{$name} ? $refs->{$name} : 'unknown' );
148              
149 0 0         if ( $self->with_latest_version ) {
150 0           my $latest_version_info;
151 0 0         if ( ref $source->{$name} ) {
152 0           $latest_version_info = "\n";
153 0           for my $branch ( keys %{ $source->{$name} } ) {
  0            
154             $latest_version_info .=
155             ' ' x 8
156             . $branch . ': '
157 0   0       . ( $latest_version->{$name}{$branch} || 'unknown' )
158             . "\n";
159             }
160 0           chomp $latest_version_info;
161             }
162             else {
163 0   0       $latest_version_info = $latest_version->{$name} || 'unknown';
164             }
165 0           $self->log->fatal( ' ' x 4,
166             'latest_version: ' . $latest_version_info );
167             }
168              
169 0 0 0       if ($branches && $name !~ /^cpan-/) {
170             $self->log->fatal( ' ' x 4 . 'branches: ',
171 0           join ', ', @{ $branches->{$name} } );
  0            
172             }
173             }
174             }
175              
176 0 0 0       if ( $name && keys %$versions == 0 ) {
177 0           $self->log->fatal( "$name doesn't exist" );
178             }
179             }
180              
181             sub _latest_version {
182 0     0     my $self = shift;
183 0           my %args = @_;
184 0 0         if ( $args{url} ) {
    0          
185              
186 0           my ( $cmd, $out );
187              
188             # XXX TODO we need a better latest_version for shipwright source
189             # using the source shipwright repo's whole version seems lame
190 0 0         if ( $args{url} =~ s/^shipwright:// ) {
191 0           $args{url} =~ s!/[^/]+$!!;
192             }
193              
194             # has url, meaning svn, svk or git
195 0 0         if ( $args{url} =~ /^svn[:+]/ ) {
    0          
    0          
196 0           $args{url} =~ s{^svn:(?!//)}{};
197 0           $cmd = [ $ENV{'SHIPWRIGHT_SVN'}, 'info', $args{url} ];
198 0           $cmd = [ $ENV{'SHIPWRIGHT_SVK'}, 'info', $args{url} ];
199 0           ($out) = run_cmd( $cmd, 1 ); # ignore failure
200 0 0         if ( $out =~ /^Revision:\s*(\d+)/m ) {
201 0           return $1;
202             }
203             }
204             elsif ( $args{url} =~ m{^(svk:|//)} ) {
205 0           $args{url} =~ s/^svk://;
206 0           $cmd = [ $ENV{'SHIPWRIGHT_SVK'}, 'info', $args{url} ];
207 0           ($out) = run_cmd( $cmd, 1 ); # ignore failure
208 0 0         if ( $out =~ /^Revision:\s*(\d+)/m ) {
209 0           return $1;
210             }
211             }
212             elsif ( $args{url} =~ /^git:/ ) {
213 0           $args{url} =~ s{^git:(?!//)}{};
214              
215             # TODO XXX is there a better way that we can get latest version of git?
216             # current way is not too heavy: it needs clone and log
217              
218 0           my $cwd = getcwd();
219 0           my $dir = tempdir(
220             'shipwright_list_git_XXXXXX',
221             CLEANUP => 1,
222             TMPDIR => 1
223             );
224 0           my $path = catdir( $dir, 'git' );
225             run_cmd(
226 0           [ $ENV{SHIPWRIGHT_GIT}, 'clone', $args{url}, $path, ] );
227 0           chdir $path;
228 0           ($out) = run_cmd( [ $ENV{SHIPWRIGHT_GIT}, 'log' ] );
229 0           chdir $cwd;
230              
231 0 0         if ( $out =~ /^commit\s+(\w+)/m ) {
232 0           return $1;
233             }
234             }
235              
236             }
237             elsif ( $args{name} ) {
238              
239             # cpan
240 0           require CPAN;
241 0           require CPAN::DistnameInfo;
242              
243 0           select_fh('cpan');
244              
245 0           my $module = CPAN::Shell->expand( 'Module', $args{name} );
246              
247 0           select_fh('stdout');
248              
249 0           my $info = CPAN::DistnameInfo->new( $module->cpan_file );
250 0           my $version = $info->version;
251 0           $version =~ s/^v//; # we don't want the leading 'v'
252 0           return $version;
253             }
254 0           return;
255             }
256              
257             1;
258              
259             __END__