File Coverage

blib/lib/Shipwright/Script/Update.pm
Criterion Covered Total %
statement 30 130 23.0
branch 0 76 0.0
condition 0 26 0.0
subroutine 10 14 71.4
pod 0 2 0.0
total 40 248 16.1


line stmt bran cond sub pod time code
1             package Shipwright::Script::Update;
2              
3 1     1   751 use strict;
  1         1  
  1         29  
4 1     1   4 use warnings;
  1         1  
  1         23  
5              
6 1     1   4 use base qw/App::CLI::Command Shipwright::Base Shipwright::Script/;
  1         1  
  1         104  
7             __PACKAGE__->mk_accessors(
8             qw/all follow builder utility inc version only_sources as add_deps delete_deps/
9             );
10              
11 1     1   4 use Shipwright;
  1         2  
  1         4  
12 1     1   21 use File::Spec::Functions qw/catdir/;
  1         1  
  1         37  
13 1     1   294 use Shipwright::Source;
  1         2  
  1         10  
14 1     1   26 use Shipwright::Util;
  1         1  
  1         73  
15 1     1   4 use File::Copy qw/copy move/;
  1         1  
  1         39  
16 1     1   4 use File::Temp qw/tempdir/;
  1         2  
  1         28  
17 1     1   5 use Config;
  1         1  
  1         1192  
18              
19             sub options {
20             (
21 0     0 0   'a|all' => 'all',
22             'follow' => 'follow',
23             'builder' => 'builder',
24             'utility' => 'utility',
25             'inc' => 'inc',
26             'version=s' => 'version',
27             'only-sources' => 'only_sources',
28             'as=s' => 'as',
29             'add-deps=s' => 'add_deps',
30             'delete-deps=s' => 'delete_deps',
31             );
32             }
33              
34             my ( $shipwright, $map, $source, $branches );
35              
36             sub run {
37 0     0 0   my $self = shift;
38              
39 0           $shipwright = Shipwright->new(
40             repository => $self->repository,
41             log_level => $self->log_level,
42             log_file => $self->log_file
43             );
44              
45 0 0         if ( $self->builder ) {
    0          
    0          
    0          
    0          
46 0           $shipwright->backend->update( path => '/bin/shipwright-builder' );
47             }
48             elsif ( $self->utility ) {
49 0           $shipwright->backend->update( path => '/bin/shipwright-utility' );
50              
51             }
52             elsif ( $self->inc ) {
53 0           $shipwright->backend->update( path => '/inc/' );
54              
55             }
56             elsif ( $self->add_deps ) {
57 0           my @deps = split /\s*,\s*/, $self->add_deps;
58 0 0         my $name = shift or confess_or_die 'need name arg';
59 0   0       my $requires = $shipwright->backend->requires( name => $name ) || {};
60 0           for my $dep ( @deps ) {
61 0           my $new_dep;
62 0           my $version = 0;
63 0 0         if ( $dep =~ /(.*)=(.*)/ ) {
64 0           $dep = $1;
65 0           $version = $2;
66             }
67              
68 0 0         $new_dep = 1 unless $requires->{requires}{$dep};
69 0           $requires->{requires}{$dep} = { version => $version };
70 0           $shipwright->backend->_yml( "/scripts/$name/require.yml", $requires );
71              
72 0 0         if ($new_dep) {
73              
74             # we need to update refs.yml
75 0           my $refs = $shipwright->backend->refs;
76 0           $refs->{$dep}++;
77 0           $shipwright->backend->refs($refs);
78             }
79             }
80             }
81             elsif ( $self->delete_deps ) {
82 0           my @deps = split /\s*,\s*/, $self->delete_deps;
83 0 0         my $name = shift or confess_or_die 'need name arg';
84 0   0       my $requires = $shipwright->backend->requires( name => $name ) || {};
85 0           my $deleted;
86 0           for my $dep ( @deps ) {
87 0           for my $type ( qw/requires build_requires recommends test_requires/ ) {
88 0 0 0       if ( $requires->{$type} && exists $requires->{$type}{$dep} ) {
89 0           delete $requires->{$type}{$dep};
90 0           $deleted = 1;
91             }
92             }
93              
94 0           $shipwright->backend->_yml( "/scripts/$name/require.yml", $requires );
95 0           my $refs = $shipwright->backend->refs;
96 0 0         $refs->{$dep}-- if $refs->{$dep} > 0;
97 0           $shipwright->backend->refs($refs);
98             }
99 0 0         if ( $deleted ) {
100 0           $self->log->fatal( 'successfully updated' );
101             }
102             else {
103 0           $self->log->fatal( "not updated: no such deps in $name" );
104             }
105 0           return;
106             }
107             else {
108 0   0       $map = $shipwright->backend->map || {};
109 0   0       $source = $shipwright->backend->source || {};
110 0           $branches = $shipwright->backend->branches;
111              
112 0 0         if ( $self->all ) {
113 0 0 0       confess_or_die '--all can not be specified with --as or NAME'
114             if @_ || $self->as;
115              
116 0   0       my $dists = $shipwright->backend->order || [];
117 0           for (@$dists) {
118 0           $self->_update($_);
119             }
120             }
121             else {
122 0           my $name = shift;
123 0 0         confess_or_die "need name arg\n" unless $name;
124              
125             # die if the specified branch doesn't exist
126 0 0 0       if ( $branches && $self->as ) {
127 0           confess_or_die "$name doesn't have branch "
128             . $self->as
129             . ". please use import cmd instead"
130 0 0         unless grep { $_ eq $self->as } @{ $branches->{$name} || [] };
  0 0          
131             }
132              
133 0           my $new_source = shift;
134 0 0         if ($new_source) {
135 0 0         system(
    0          
    0          
    0          
136             "$0 relocate -r "
137             . $self->repository
138             . (
139             $self->log_level
140             ? ( " --log-level " . $self->log_level )
141             : ''
142             )
143             . (
144             $self->log_file ? ( " --log-file " . $self->log_file )
145             : ''
146             )
147             . (
148             $self->as ? ( " --as " . $self->as )
149             : ''
150             )
151             . " $name $new_source"
152             ) && die "relocate $name to $new_source failed: $!";
153             # renew our $source
154 0   0       $source = $shipwright->backend->source || {};
155             }
156              
157 0           my @dists;
158 0 0         if ( $self->follow ) {
159 0           my (%checked);
160             my $find_deps;
161             $find_deps = sub {
162 0     0     my $name = shift;
163 0 0         return if $checked{$name}++;
164              
165 0           my ($require) =
166             $shipwright->backend->requires( name => $name );
167 0           for my $type (
168             qw/requires build_requires recommends
169             test_requires/
170             )
171             {
172 0           for ( keys %{ $require->{$type} } ) {
  0            
173 0           $find_deps->($_);
174             }
175             }
176 0           };
177              
178 0           $find_deps->($name);
179 0           @dists = keys %checked;
180             }
181             else {
182 0           @dists = $name;
183             }
184              
185 0           for (@dists) {
186 0 0         if ( $self->only_sources ) {
187 0 0         if ( $_ eq $name ) {
188 0           $self->_update( $_, $self->version, $self->as );
189             }
190             else {
191 0           $self->_update($_);
192             }
193             }
194             else {
195 0           local $ENV{SHIPWRIGHT_SOURCE_ROOT} = tempdir(
196             'shipwright_source_XXXXXX',
197             CLEANUP => 1,
198             TMPDIR => 1
199             );
200 0 0         system(
    0          
    0          
    0          
201             "$0 import -r "
202             . $self->repository
203             . (
204             $self->log_level
205             ? ( " --log-level " . $self->log_level )
206             : ''
207             )
208             . (
209             $self->log_file
210             ? ( " --log-file " . $self->log_file )
211             : ''
212             )
213             . (
214             $self->as ? ( " --as " . $self->as )
215             : ''
216             )
217             . (
218             $self->version ? ( " --version " . $self->version )
219             : ''
220             )
221             . " --name $_"
222             );
223             }
224             }
225             }
226             }
227 0           $self->log->fatal( 'successfully updated' );
228             }
229              
230             sub _update {
231 0     0     my $self = shift;
232 0           my $name = shift;
233 0           my $version = shift;
234 0           my $as = shift;
235 0 0         if ( $source->{$name} ) {
236 0 0 0       $shipwright->source(
237             Shipwright::Source->new(
238             name => $name,
239             source => (
240             ref $source->{$name}
241             ? $source->{$name}{ $as || $branches->{$name}[0] }
242             : $source->{$name}
243             ),
244             follow => 0,
245             version => $version,
246             )
247             );
248             }
249             else {
250              
251             # it's a cpan dist
252 0           my $s;
253              
254 0 0         if ( $name =~ /^cpan-/ ) {
    0          
255 0           $s = { reverse %$map }->{$name};
256             }
257             elsif ( $map->{$name} ) {
258 0           $s = $name;
259 0           $name = $map->{$name};
260             }
261             else {
262 0           confess_or_die 'invalid name ' . $name . "\n";
263             }
264              
265 0 0         unless ( $s ) {
266 0           warn "can't find the source name of $name, skipping";
267 0           next;
268             }
269              
270             $shipwright->source(
271 0           Shipwright::Source->new(
272             source => "cpan:$s",
273             follow => 0,
274             version => $version,
275             )
276             );
277             }
278              
279 0           $shipwright->source->run;
280              
281 0           $version = load_yaml_file( $shipwright->source->version_path );
282              
283 0           my $branches = $shipwright->backend->branches;
284 0 0 0       $shipwright->backend->import(
285             source => catdir( $shipwright->source->directory, $name ),
286             comment => "update $name",
287             overwrite => 1,
288             version => $version->{$name},
289             as => $as,
290             branches => $shipwright->source->isa('Shipwright::Source::Shipyard')
291             ? ( $branches->{$name} || [] )
292             : (undef),
293             );
294             }
295              
296             1;
297              
298             __END__