File Coverage

blib/lib/App/sourcepan.pm
Criterion Covered Total %
statement 18 82 21.9
branch 0 64 0.0
condition 0 6 0.0
subroutine 6 10 60.0
pod 0 3 0.0
total 24 165 14.5


line stmt bran cond sub pod time code
1             # You may distribute under the terms of either the GNU General Public License
2             # or the Artistic License (the same terms as Perl itself)
3             #
4             # (C) Paul Evans, 2013-2021 -- leonerd@leonerd.org.uk
5              
6             package App::sourcepan;
7              
8 1     1   733 use strict;
  1         2  
  1         30  
9 1     1   5 use warnings;
  1         2  
  1         39  
10              
11             our $VERSION = '0.05';
12              
13 1     1   3020 use CPAN;
  1         325563  
  1         532  
14 1     1   36 use File::Basename qw( basename );
  1         8  
  1         109  
15 1     1   16 use File::Copy qw( copy );
  1         8  
  1         145  
16 1     1   1997 use IPC::Run qw();
  1         35444  
  1         1195  
17              
18             =head1 NAME
19              
20             C - modulino implementation of F
21              
22             =head1 SYNOPSIS
23              
24             This module contains the code to implement the F command.
25              
26             See L for usage information.
27              
28             =cut
29              
30             # TODO: damnit does CPAN::Shell not have a method for this??
31             sub _split_version
32             {
33 0     0     shift =~ m/^(.*?)(?:-(\d+[[:digit:].]*))?$/;
34             }
35              
36             sub run
37             {
38 0     0 0   shift;
39 0           my ( $opts, @items ) = @_;
40              
41 0           my $type = $opts->{type};
42              
43 0           my %dists;
44 0 0         if( $type eq "module" ) {
45 0           foreach my $module ( CPAN::Shell->expand( Module => @items ) ) {
46 0           my $dist = $module->distribution;
47 0           $dists{$dist->pretty_id} = $dist;
48             }
49             }
50             else {
51             # Dists have full names; search by regexp to match on dist base name
52 0           foreach ( @items ) {
53 0           my ( $basename, $ver ) = _split_version( $_ );
54              
55             # CPAN::Shell doesn't like a qr//, only a literal string
56 0 0         my $match = defined $ver ? "/\\/$basename-$ver\\./"
57             : "/\\/$basename-\\d+/";
58              
59 0           my $latestver;
60 0           foreach my $dist ( CPAN::Shell->expand( Distribution => $match ) ) {
61 0           $dists{$dist->pretty_id} = $dist;
62 0           my ( undef, $thisver ) = _split_version $dist->base_id;
63 0 0 0       if( !defined $latestver or $latestver < $thisver ) {
64 0           $latestver = $thisver;
65             }
66             }
67              
68 0 0         if( !defined $ver ) {
69 0           foreach ( keys %dists ) {
70 0           my ( $thisname, $thisver ) = _split_version $dists{$_}->base_id;
71 0 0         next if $thisname ne $basename;
72 0 0         next if $thisver == $latestver;
73 0           delete $dists{$_};
74             }
75             }
76             }
77             }
78              
79 0           foreach my $id ( sort keys %dists ) {
80 0           my $dist = $dists{$id};
81              
82             # Peeking inside
83 0           $dist->get_file_onto_local_disk;
84              
85 0           my $basename = basename $id;
86 0 0         copy( $dist->{localfile}, $basename ) or die "Cannot copy - $!";
87              
88 0           print "$id => $basename\n";
89              
90 0 0         next unless $opts->{extract};
91              
92 0           my @unpack_cmd;
93             my $dirname;
94              
95 0 0         if( $id =~ m/\.tar\.(?:gz|bz2)$/ ) {
    0          
96 0 0         my $tarflags = ( $id =~ m/bz2$/ ) ? "xjf" : "xzf";
97 0           @unpack_cmd = ( "tar", $tarflags, $basename );
98 0           ( $dirname = $basename ) =~ s/\.tar.(?:gz|bz2)$//;
99             }
100             elsif( $id =~ m/\.zip$/ ) {
101 0           @unpack_cmd = ( "unzip", $basename );
102 0           ( $dirname = $basename ) =~ s/\.zip$//;
103             }
104             else {
105 0           die "Unsure how to unpack $id\n";
106             }
107              
108 0 0 0       !$opts->{overwrite} and -d $dirname and
109             die "Target directory $dirname already exists; rename it out of the way first or pass --overwrite\n";
110              
111 0 0         IPC::Run::run [ @unpack_cmd ], ">/dev/null" or
112             die "Unable to extract - $unpack_cmd[0] failed with exit code $?\n";
113              
114 0 0         -d $dirname or
115             die "Expected to extract a directory called $dirname\n";
116              
117 0 0         if( $opts->{unversioned} ) {
118 0 0         ( my $newname = $dirname ) =~ s/-[0-9._]+$// or
119             die "Unable to determine the unversioned name for $dirname\n";
120              
121 0 0         rename $dirname, $newname or
122             die "Unable to rename $dirname to $newname - $!";
123              
124 0           $dirname = $newname;
125             }
126              
127 0           print "Unpacked $basename to $dirname\n";
128              
129 0 0         if( my $vc = $opts->{vc_init} ) {
130 0 0         my $code = __PACKAGE__->can( "vc_init_$vc" ) or
131             die "Unsure how to initialise version control system $vc\n";
132              
133 0 0         $code->( $dirname,
134             id => $id
135             ) or exit $?;
136             }
137             }
138             }
139              
140             sub vc_init_bzr
141             {
142 0     0 0   my ( $dirname, %opts ) = @_;
143              
144 0 0         defined( my $kid = fork() ) or die "Cannot fork - $!";
145 0 0         return waitpid $kid, 0 if $kid;
146              
147             # In a subprocess
148 0 0         chdir $dirname or die "Cannot chdir $dirname - $!";
149              
150 0 0         system( "bzr", "init" ) == 0
151             or die "Unable to 'bzr init' ($?)\n";
152 0 0         system( "bzr", "add", "." ) == 0
153             or die "Unable to 'bzr add ($?)\n";
154 0 0         system( "bzr", "commit", "-m", "Imported $opts{id}" ) == 0
155             or die "Unable to 'bzr commit' ($?)\n";
156             }
157              
158             sub vc_init_git
159             {
160 0     0 0   my ( $dirname, %opts ) = @_;
161              
162 0 0         defined( my $kid = fork() ) or die "Cannot fork - $!";
163 0 0         return waitpid $kid, 0 if $kid;
164              
165             # In a subprocess
166 0 0         chdir $dirname or die "Cannot chdir $dirname - $!";
167              
168 0 0         system( "git", "init" ) == 0
169             or die "Unable to 'git init' ($?)\n";
170 0 0         system( "git", "add", "." ) == 0
171             or die "Unable to 'git add ($?)\n";
172 0 0         system( "git", "commit", "-m", "Imported $opts{id}" ) == 0
173             or die "Unable to 'git commit' ($?)\n";
174             }
175              
176             =head1 AUTHOR
177              
178             Paul Evans
179              
180             =cut
181              
182             0x55AA;