File Coverage

blib/lib/only/install.pm
Criterion Covered Total %
statement 104 113 92.0
branch 32 58 55.1
condition 6 12 50.0
subroutine 13 13 100.0
pod 0 6 0.0
total 155 202 76.7


line stmt bran cond sub pod time code
1             package only::install;
2             $VERSION = '0.26';
3             @EXPORT_OK = qw(install);
4 14     14   536947 use strict;
  14         39  
  14         555  
5 14     14   418 use 5.006001;
  14         50  
  14         568  
6 14     14   78 use base 'Exporter';
  14         31  
  14         1314  
7 14     14   11486 use only;
  14         56  
  14         113  
8 14     14   141 use File::Spec;
  14         30  
  14         386  
9 14     14   81 use Config;
  14         32  
  14         733  
10 14     14   79 use Carp;
  14         34  
  14         33833  
11              
12             sub install {
13 5     5 0 48722 my %args = @_;
14 5         100 check_env();
15 5         48 my ($dist_name, $dist_ver) = get_meta();
16 5   66     95 my $versionlib = $args{versionlib} || &only::config::versionlib;
17 5   66     52 my $version = $args{version} || $dist_ver;
18 5 50       76 if ($version !~ /^\d+(\.\d+)?$/) {
19 0         0 croak <
20             Install failed. '$version' is an invalid version string. Must be numeric.
21             END
22             }
23            
24 5         108 my $lib = File::Spec->catdir(qw(blib lib));
25 5 50       90 mkdir($lib, 0777) unless -d $lib;
26 5         46 my $arch = File::Spec->catdir(qw(blib arch));
27 5 50       95 mkdir($arch, 0777) unless -d $arch;
28              
29 5         53 my $install_lib = File::Spec->catdir(
30             $versionlib,
31             $version,
32             );
33 5         865 my $install_arch = File::Spec->catdir(
34             $versionlib,
35             $Config{archname},
36             $version,
37             );
38 5         90 my $install_map = {
39             $lib => $install_lib,
40             $arch => $install_arch,
41             read => '',
42             };
43              
44             { # 5.6.1 has a warning bug. :(
45 5         13 local $^W = 0;
  5         43  
46 5         7304 require ExtUtils::Install;
47             }
48 5         174594 ExtUtils::Install::install($install_map, 1, 0);
49              
50 5         155167 my @lib_pm_files = map trim_dir($_), find_pm($lib);
51 5         22 my @arch_pm_files = map trim_dir($_), find_pm($arch);
52 5         36 my $meta = <
53             # This meta file created by/for only.pm
54             meta_version: $only::VERSION
55             install_version: $version
56             distribution_name: $dist_name
57             distribution_version: $dist_ver
58             distribution_modules:
59             END
60 5         23 for my $file (sort(@lib_pm_files, @arch_pm_files)) {
61 7         55 my $pm_file = join '/', File::Spec->splitdir($file);
62 7         28 $meta .= " - $pm_file\n";
63             }
64 5         36 install_meta($meta, $install_lib, $_) for @lib_pm_files;
65 5         129 install_meta($meta, $install_arch, $_) for @arch_pm_files;
66             }
67              
68             sub install_meta {
69 7     7 0 17 my ($meta, $base, $module) = @_;
70 7         79 my $meta_file = File::Spec->catfile($base, $module);
71 7 50       72 $meta_file =~ s/\.pm$/\.yaml/
72             or croak;
73 7         25 my $old_meta = '';
74 7 50       197 if (-f $meta_file) {
75 7 50       473 open META, $meta_file
76             or croak "Can't open $meta_file for input\n";
77 7         15 $old_meta = do {local $/; };
  7         27  
  7         194  
78 7         77 close META;
79             }
80 7 50       34 if ($meta eq $old_meta) {
81 7         984 print "Skipping $meta_file (unchanged)\n";
82             }
83             else {
84 0         0 print "Installing $meta_file\n";
85 0 0       0 open META, '>', $meta_file
86             or croak "Can't open $meta_file for output\n";
87 0         0 print META $meta;
88 0         0 close META;
89             }
90             }
91              
92             sub trim_dir {
93 7     7 0 30 my ($path) = @_;
94 7         443 my ($vol, $dir, $file) = File::Spec->splitpath($path);
95 7         82 my @dirs = File::Spec->splitdir($dir);
96 7 50       178 pop @dirs unless $dirs[-1];
97 7         21 splice(@dirs, 0, 2);
98 7 100       45 $dir = scalar(@dirs) ? File::Spec->catdir(@dirs) : '';
99 7 100       105 $dir ? File::Spec->catfile($dir, $file) : $file
100             }
101              
102             sub find_pm {
103 13     13 0 94 my ($path, $base) = (@_, '');
104 13 50       115 croak unless $path;
105 13         38 my (@pm_files);
106 13 100       75 $path = File::Spec->catdir($base, $path) if $base;
107 13         64 local *DIR;
108 13 50       437 opendir(DIR, $path)
109             or croak "Can't open directory '$path':\n$!";
110 13         157 while (my $file = readdir(DIR)) {
111 36 100       244 next if $file =~ /^\./;
112 10         194 my $file_path = File::Spec->catfile($path, $file);
113 10         91 my $dir_path = File::Spec->catdir($path, $file);
114 10 100       1017 if ($file =~ /^\w+\.pm$/) {
    50          
115 7         45 push @pm_files, $file_path;
116             }
117             elsif (-d $dir_path) {
118 3         26 push @pm_files, find_pm($file, $path);
119             }
120             }
121 13         226 return @pm_files;
122             }
123              
124             sub check_env {
125 5     5 0 79 my $lib = File::Spec->catdir(qw(blib lib));
126 5         73 my $arch = File::Spec->catdir(qw(blib arch));
127 5 50 33     365 return 1 if -d 'blib' and (-d $lib or -d $arch);
      33        
128 0 0       0 if (-f 'Build.PL') {
    0          
129 0         0 croak <
130             First you need to run:
131            
132             perl Build.PL
133             ./Build
134             ./Build test # (optional)
135              
136             END
137             }
138             elsif (-f 'Makefile.PL') {
139 0         0 croak <
140             First you need to run:
141            
142             perl Makefile.PL
143             make
144             make test # (optional)
145              
146             END
147             }
148             else {
149 0         0 croak <
150             You don't appear to be inside a directory fit to install a Perl module.
151             See 'perldoc only' for more information.
152             END
153             }
154             }
155              
156             sub get_meta {
157 5     5 0 37 my $dist_name = '';
158 5         21 my $dist_ver = '';
159 5 100       95 if (-f 'META.yml') {
160 3 50       165 open META, "META.yml"
161             or croak "Can't open META.yml for input:\n$!\n";
162 3         23 local $/;
163 3         107 my $meta = ;
164 3         38 close META;
165 3 50       90 if ($meta =~ /^name\s*:\s+(\S+)$/m) {
166 3         55 $dist_name = $1;
167             }
168 3 50       36 if ($meta =~ /^version\s*:\s+(\S+)$/m) {
169 3         32 $dist_ver = $1;
170             }
171             }
172             else {
173 2 50       39 if (-f 'Makefile') {
174 2 50       99 open MAKEFILE, "Makefile"
175             or croak "Can't open Makefile for input:\n$!\n";
176 2         15 local $/;
177 2         67 my $makefile = ;
178 2         95 close MAKEFILE;
179 2 50       65 if ($makefile =~ /^DISTNAME\s*=\s*(\S+)$/m) {
180 2         21 $dist_name = $1;
181             }
182 2 50       20 if ($makefile =~ /^VERSION\s*=\s*(\S+)$/m) {
183 2         22 $dist_ver = $1;
184             }
185             }
186             }
187 5 50       24 croak <
188             Can't determine the version for this install. Please specify manually:
189              
190             perl -Monly=install - version=1.23
191              
192             END
193 5         37 return ($dist_name, $dist_ver);
194             }
195              
196             1;
197              
198             __END__