line |
stmt |
bran |
cond |
sub |
pod |
time |
code |
1
|
|
|
|
|
|
|
package Acme::Module::Build::Tiny; |
2
|
1
|
|
|
1
|
|
153904
|
use strict; |
|
1
|
|
|
|
|
2
|
|
|
1
|
|
|
|
|
43
|
|
3
|
1
|
|
|
1
|
|
6
|
use warnings; |
|
1
|
|
|
|
|
2
|
|
|
1
|
|
|
|
|
31
|
|
4
|
1
|
|
|
1
|
|
4
|
use Config; |
|
1
|
|
|
|
|
2
|
|
|
1
|
|
|
|
|
41
|
|
5
|
1
|
|
|
1
|
|
1010
|
use Data::Dumper 0 (); |
|
1
|
|
|
|
|
11684
|
|
|
1
|
|
|
|
|
32
|
|
6
|
1
|
|
|
1
|
|
1059
|
use ExtUtils::Install 0 (); |
|
1
|
|
|
|
|
412727
|
|
|
1
|
|
|
|
|
40
|
|
7
|
1
|
|
|
1
|
|
722018
|
use ExtUtils::MakeMaker 0 (); |
|
1
|
|
|
|
|
475967
|
|
|
1
|
|
|
|
|
37
|
|
8
|
1
|
|
|
1
|
|
8
|
use File::Find 0 (); |
|
1
|
|
|
|
|
8882
|
|
|
1
|
|
|
|
|
104
|
|
9
|
1
|
|
|
1
|
|
20
|
use File::Path 0 (); |
|
1
|
|
|
|
|
40
|
|
|
1
|
|
|
|
|
29
|
|
10
|
1
|
|
|
1
|
|
7
|
use File::Spec 0 (); |
|
1
|
|
|
|
|
23
|
|
|
1
|
|
|
|
|
21
|
|
11
|
1
|
|
|
1
|
|
1791
|
use Getopt::Long 0 (); |
|
1
|
|
|
|
|
12979
|
|
|
1
|
|
|
|
|
58
|
|
12
|
1
|
|
|
1
|
|
3392
|
use Test::Harness 0 (); |
|
1
|
|
|
|
|
84380
|
|
|
1
|
|
|
|
|
35
|
|
13
|
1
|
|
|
1
|
|
1612
|
use Tie::File 0 (); |
|
1
|
|
|
|
|
21972
|
|
|
1
|
|
|
|
|
32
|
|
14
|
1
|
|
|
1
|
|
13
|
use Text::ParseWords 0 (); |
|
1
|
|
|
|
|
20
|
|
|
1
|
|
|
|
|
2283
|
|
15
|
|
|
|
|
|
|
our $VERSION = '0.06'; |
16
|
|
|
|
|
|
|
|
17
|
|
|
|
|
|
|
my %re = ( |
18
|
|
|
|
|
|
|
lib => qr{\.(?:pm|pod)$}, |
19
|
|
|
|
|
|
|
t => qr{\.t}, |
20
|
|
|
|
|
|
|
't/lib' => qr{\.(?:pm|pod)$}, |
21
|
|
|
|
|
|
|
prereq => qr{^\s*use[ \t]+(\S+)[ \t]+(v?[0-9._]+)[^;]*;}m, |
22
|
|
|
|
|
|
|
authors => qr{^=head1 AUTHORS?\s*\n(.*?)^=\w}sm, |
23
|
|
|
|
|
|
|
); |
24
|
|
|
|
|
|
|
|
25
|
|
|
|
|
|
|
my %install_map = map { +"blib/$_" => $Config{"installsite$_"} } qw/lib script/; |
26
|
|
|
|
|
|
|
|
27
|
|
|
|
|
|
|
my %install_base = ( lib => [qw/lib perl5/], script => [qw/lib bin/] ); |
28
|
|
|
|
|
|
|
|
29
|
|
|
|
|
|
|
my @opts_spec = ( 'install_base:s', 'uninst:i' ); |
30
|
|
|
|
|
|
|
|
31
|
|
|
|
|
|
|
sub _split_like_shell { |
32
|
0
|
|
|
0
|
|
|
my $string = shift; |
33
|
0
|
|
|
|
|
|
$string =~ s/^\s+|\s+$//g; |
34
|
0
|
|
|
|
|
|
return Text::ParseWords::shellwords($string); |
35
|
|
|
|
|
|
|
} |
36
|
|
|
|
|
|
|
|
37
|
0
|
|
0
|
0
|
|
|
sub _home { return $ENV{HOME} || $ENV{USERPROFILE} } |
38
|
|
|
|
|
|
|
|
39
|
0
|
|
|
0
|
|
|
sub _default_rc { return File::Spec->catfile( _home(), '.modulebuildrc' ) } |
40
|
|
|
|
|
|
|
|
41
|
|
|
|
|
|
|
sub _get_rc_opts { |
42
|
0
|
|
0
|
0
|
|
|
my $rc_file = ($ENV{MODULEBUILDRC} || _default_rc()); |
43
|
0
|
0
|
|
|
|
|
return {} unless -f $rc_file; |
44
|
0
|
|
|
|
|
|
my $guts = _slurp( $rc_file ); |
45
|
0
|
|
|
|
|
|
$guts =~ s{\n[ \t]+}{ }mg; # join lines with leading whitespace |
46
|
0
|
|
|
|
|
|
$guts =~ s{^#.*$}{}mg; # strip comments |
47
|
0
|
|
|
|
|
|
$guts =~ s{\n\s*\n}{\n}mg; # empty lines |
48
|
0
|
|
|
|
|
|
my %opt = map { my ($k,$v) = $_ =~ /(\S+)\s+(.*)/; $k => $v } |
|
0
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
49
|
0
|
|
|
|
|
|
grep { /\S/ } split /\n/, $guts; |
50
|
0
|
|
|
|
|
|
return \%opt; |
51
|
|
|
|
|
|
|
} |
52
|
|
|
|
|
|
|
|
53
|
|
|
|
|
|
|
sub _get_options { |
54
|
0
|
|
|
0
|
|
|
my ($action,$opt) = @_; |
55
|
0
|
|
|
|
|
|
my $rc_opts = _get_rc_opts; |
56
|
0
|
|
|
|
|
|
for my $s ( $ENV{PERL_MB_OPT}, $rc_opts->{$action}, $rc_opts->{'*'} ) { |
57
|
0
|
0
|
0
|
|
|
|
unshift @ARGV, _split_like_shell($s) if defined $s && length $s; |
58
|
|
|
|
|
|
|
} |
59
|
0
|
|
|
|
|
|
Getopt::Long::GetOptions($opt, @opts_spec); |
60
|
|
|
|
|
|
|
} |
61
|
|
|
|
|
|
|
|
62
|
|
|
|
|
|
|
sub run { |
63
|
0
|
|
0
|
0
|
0
|
|
my $opt = eval { do '_build/build_params' } || {}; |
64
|
0
|
0
|
|
|
|
|
my $action = ! defined $ARGV[0] ? 'build' |
|
|
0
|
|
|
|
|
|
65
|
|
|
|
|
|
|
: $ARGV[0] =~ /\A\w+\z/ ? $ARGV[0] |
66
|
|
|
|
|
|
|
: 'build'; |
67
|
0
|
|
|
|
|
|
_get_options($action, $opt); |
68
|
0
|
0
|
|
|
|
|
my $fcn = __PACKAGE__->can($action) or die "$action not implemented\n"; |
69
|
0
|
|
|
|
|
|
$fcn->(%$opt); |
70
|
|
|
|
|
|
|
} |
71
|
|
|
|
|
|
|
|
72
|
|
|
|
|
|
|
sub debug { |
73
|
0
|
|
|
0
|
0
|
|
my %opt = @_; |
74
|
0
|
|
|
|
|
|
print _data_dump(\%opt) . "\n"; |
75
|
|
|
|
|
|
|
} |
76
|
|
|
|
|
|
|
|
77
|
|
|
|
|
|
|
sub import { |
78
|
0
|
|
|
0
|
|
|
_get_options('Build_PL', my $opt = {}); |
79
|
0
|
|
|
|
|
|
my @f = _files('lib'); |
80
|
0
|
|
|
|
|
|
my $meta = { |
81
|
|
|
|
|
|
|
name => _mod2dist(_path2mod($f[0])), |
82
|
|
|
|
|
|
|
version => MM->parse_version($f[0]), |
83
|
|
|
|
|
|
|
}; |
84
|
0
|
|
|
|
|
|
print "Creating new 'Build' script for '$meta->{name}'" . |
85
|
|
|
|
|
|
|
" version '$meta->{version}'\n"; |
86
|
0
|
0
|
|
|
|
|
my $perl = $^X =~ /\Aperl[.0-9]*\z/ ? $Config{perlpath} : $^X; |
87
|
0
|
|
|
|
|
|
_spew('Build' => "#!$perl\n", _slurp( $INC{_mod2pm(shift)} ) ); |
88
|
0
|
|
|
|
|
|
chmod 0755, 'Build'; |
89
|
0
|
|
|
|
|
|
_spew( '_build/prereqs', _data_dump(_find_prereqs()) ); |
90
|
0
|
|
|
|
|
|
_spew( '_build/build_params', _data_dump($opt) ); |
91
|
0
|
|
|
|
|
|
_spew( '_build/meta', _data_dump(_fill_meta($meta, $f[0])) ); |
92
|
0
|
0
|
|
|
|
|
_spew( 'MYMETA.yml', _slurp('META.yml')) if -f 'META.yml'; |
93
|
|
|
|
|
|
|
} |
94
|
|
|
|
|
|
|
|
95
|
|
|
|
|
|
|
sub build { |
96
|
0
|
|
|
|
|
|
my $map = { |
97
|
|
|
|
|
|
|
(map {$_=>"blib/$_"} _files('lib')), |
98
|
0
|
|
|
0
|
0
|
|
(map {;"bin/$_"=>"blib/script/$_"} map {s{^bin/}{}; $_} _files('bin')), |
|
0
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
99
|
|
|
|
|
|
|
}; |
100
|
0
|
|
|
|
|
|
ExtUtils::Install::pm_to_blib($map, 'blib/lib/auto'); |
101
|
0
|
|
|
|
|
|
ExtUtils::MM->fixin($_), chmod(0555, $_) for _files('blib/script'); |
102
|
0
|
|
|
|
|
|
return 1; |
103
|
|
|
|
|
|
|
} |
104
|
|
|
|
|
|
|
|
105
|
|
|
|
|
|
|
sub test { |
106
|
0
|
|
|
0
|
1
|
|
build(); |
107
|
0
|
|
|
|
|
|
local @INC = (File::Spec->rel2abs('blib/lib'), @INC); |
108
|
0
|
|
|
|
|
|
Test::Harness::runtests(_files('t')); |
109
|
|
|
|
|
|
|
} |
110
|
|
|
|
|
|
|
|
111
|
|
|
|
|
|
|
sub _install_base { |
112
|
0
|
|
|
0
|
|
|
my $map = {map {$_=>File::Spec->catdir($_[0],@{$install_base{$_}})} keys %install_base}; |
|
0
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
113
|
|
|
|
|
|
|
} |
114
|
|
|
|
|
|
|
|
115
|
|
|
|
|
|
|
sub install { |
116
|
0
|
|
|
0
|
1
|
|
my %opt = @_; |
117
|
0
|
|
|
|
|
|
build(); |
118
|
0
|
0
|
|
|
|
|
ExtUtils::Install::install( |
119
|
|
|
|
|
|
|
($opt{install_base} ? _install_base($opt{install_base}) : \%install_map), 1 |
120
|
|
|
|
|
|
|
); |
121
|
0
|
|
|
|
|
|
return 1; |
122
|
|
|
|
|
|
|
} |
123
|
|
|
|
|
|
|
|
124
|
|
|
|
|
|
|
sub distdir { |
125
|
0
|
|
|
0
|
1
|
|
require ExtUtils::Manifest; ExtUtils::Manifest->VERSION(1.57); |
|
0
|
|
|
|
|
|
|
126
|
0
|
|
|
|
|
|
File::Path::rmtree(_distdir()); |
127
|
0
|
0
|
|
|
|
|
_spew('MANIFEST.SKIP', "#!include_default\n^"._distbase()."\n") unless -f 'MANIFEST.SKIP'; |
128
|
0
|
|
|
|
|
|
local $ExtUtils::Manifest::Quiet = 1; |
129
|
0
|
|
|
|
|
|
ExtUtils::Manifest::mkmanifest(); |
130
|
0
|
|
|
|
|
|
ExtUtils::Manifest::manicopy( ExtUtils::Manifest::maniread(), _distdir() ); |
131
|
0
|
|
|
|
|
|
_spew(_distdir("/inc/",_mod2pm(__PACKAGE__)) => _slurp( __FILE__ ) ); |
132
|
0
|
|
|
|
|
|
_append(_distdir("MANIFEST"), "inc/" . _mod2pm(__PACKAGE__) . "\n"); |
133
|
0
|
|
|
|
|
|
_write_meta(_distdir("META.yml")); |
134
|
0
|
|
|
|
|
|
_append(_distdir("MANIFEST"), "META.yml"); |
135
|
|
|
|
|
|
|
} |
136
|
|
|
|
|
|
|
|
137
|
|
|
|
|
|
|
sub dist { |
138
|
0
|
|
|
0
|
1
|
|
require Archive::Tar; Archive::Tar->VERSION(1.09); |
|
0
|
|
|
|
|
|
|
139
|
0
|
|
|
|
|
|
distdir(); |
140
|
0
|
|
|
|
|
|
my ($distdir,@f) = (_distdir(),_files(_distdir())); |
141
|
1
|
|
|
1
|
|
12
|
no warnings 'once'; |
|
1
|
|
|
|
|
8
|
|
|
1
|
|
|
|
|
1964
|
|
142
|
0
|
0
|
|
|
|
|
$Archive::Tar::DO_NOT_USE_PREFIX = (grep { length($_) >= 100 } @f) ? 0 : 1; |
|
0
|
|
|
|
|
|
|
143
|
0
|
|
|
|
|
|
my $tar = Archive::Tar->new; |
144
|
0
|
|
|
|
|
|
$tar->add_files(@f); |
145
|
0
|
|
|
|
|
|
$_->mode($_->mode & ~022) for $tar->get_files; |
146
|
0
|
|
|
|
|
|
$tar->write("$distdir.tar.gz", 1); |
147
|
0
|
|
|
|
|
|
File::Path::rmtree($distdir); |
148
|
|
|
|
|
|
|
} |
149
|
|
|
|
|
|
|
|
150
|
0
|
|
|
0
|
1
|
|
sub clean { File::Path::rmtree('blib'); 1 } |
|
0
|
|
|
|
|
|
|
151
|
|
|
|
|
|
|
|
152
|
0
|
|
|
0
|
1
|
|
sub realclean { clean(); File::Path::rmtree($_) for _distdir(), qw/Build _build/; 1; } |
|
0
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
153
|
|
|
|
|
|
|
|
154
|
0
|
|
|
0
|
|
|
sub _slurp { do { local (@ARGV,$/)=$_[0]; <> } } |
|
0
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
155
|
|
|
|
|
|
|
sub _spew { |
156
|
0
|
|
|
0
|
|
|
my $file = shift; |
157
|
0
|
|
|
|
|
|
File::Path::mkpath(File::Basename::dirname($file)); |
158
|
0
|
|
|
|
|
|
open my $fh, '>', $file; |
159
|
0
|
|
|
|
|
|
print {$fh} @_; |
|
0
|
|
|
|
|
|
|
160
|
|
|
|
|
|
|
} |
161
|
0
|
|
|
0
|
|
|
sub _append { open my $fh, ">>", shift; print {$fh} @_ } |
|
0
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
162
|
|
|
|
|
|
|
|
163
|
|
|
|
|
|
|
sub _data_dump { |
164
|
0
|
|
|
0
|
|
|
'do{ my ' . Data::Dumper->new([shift],['x'])->Purity(1)->Dump() . '$x; }' |
165
|
|
|
|
|
|
|
} |
166
|
|
|
|
|
|
|
|
167
|
0
|
|
|
0
|
|
|
sub _mod2pm { (my $mod = shift) =~ s{::}{/}g; return "$mod.pm" } |
|
0
|
|
|
|
|
|
|
168
|
0
|
|
|
0
|
|
|
sub _path2mod { (my $pm = shift) =~ s{/}{::}g; return substr $pm, 5, -3 } |
|
0
|
|
|
|
|
|
|
169
|
0
|
|
|
0
|
|
|
sub _mod2dist { (my $mod = shift) =~ s{::}{-}g; return $mod; } |
|
0
|
|
|
|
|
|
|
170
|
|
|
|
|
|
|
|
171
|
|
|
|
|
|
|
sub _files { |
172
|
0
|
|
|
0
|
|
|
my ($dir,@f) = shift; |
173
|
0
|
0
|
|
|
|
|
return unless -d $dir; |
174
|
0
|
|
0
|
|
|
|
my $regex = $re{$dir} || qr/./; |
175
|
0
|
0
|
0
|
0
|
|
|
File::Find::find( sub { -f && /$regex/ && push @f, $File::Find::name},$dir); |
|
0
|
|
|
|
|
|
|
176
|
0
|
|
|
|
|
|
return sort { length $a <=> length $b } @f; |
|
0
|
|
|
|
|
|
|
177
|
|
|
|
|
|
|
} |
178
|
|
|
|
|
|
|
|
179
|
0
|
|
|
0
|
|
|
sub _distbase { my @f = _files('lib'); return _mod2dist(_path2mod($f[0])) } |
|
0
|
|
|
|
|
|
|
180
|
|
|
|
|
|
|
|
181
|
|
|
|
|
|
|
sub _distdir { |
182
|
0
|
|
|
0
|
|
|
my @f = _files('lib'); |
183
|
0
|
|
|
|
|
|
return File::Spec->catfile(_distbase ."-". MM->parse_version($f[0]), @_); |
184
|
|
|
|
|
|
|
} |
185
|
|
|
|
|
|
|
|
186
|
|
|
|
|
|
|
sub _fill_meta { |
187
|
0
|
|
|
0
|
|
|
my ($m, $src) = @_; |
188
|
0
|
|
|
|
|
|
for ( split /\n/, _slurp($src) ) { |
189
|
0
|
0
|
|
|
|
|
next unless /^=(?!cut)/ .. /^=cut/; # in POD |
190
|
0
|
0
|
|
|
|
|
($m->{abstract}) = /^ (?: [a-z:]+ \s+ - \s+ ) (.*\S) /ix |
191
|
|
|
|
|
|
|
unless $m->{abstract}; |
192
|
|
|
|
|
|
|
} |
193
|
0
|
|
|
|
|
|
$m->{author} = _find_authors($src); |
194
|
0
|
|
|
|
|
|
return $m; |
195
|
|
|
|
|
|
|
} |
196
|
|
|
|
|
|
|
|
197
|
|
|
|
|
|
|
sub _find_authors { |
198
|
0
|
|
|
0
|
|
|
my $guts = _slurp($_[0]); |
199
|
0
|
|
|
|
|
|
my ($block) = $guts =~ $re{authors}; |
200
|
0
|
0
|
|
|
|
|
return $block ? [ map { s{^\s+}{}; s{\s+$}{}; $_ } grep { /\S/ } split /\n/, $block ] : []; |
|
0
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
201
|
|
|
|
|
|
|
} |
202
|
|
|
|
|
|
|
|
203
|
|
|
|
|
|
|
sub _write_meta { |
204
|
0
|
|
|
0
|
|
|
my $file = shift; |
205
|
0
|
|
0
|
|
|
|
my $meta = eval { do '_build/meta' } || {}; |
206
|
0
|
|
0
|
|
|
|
my $prereqs = eval { do '_build/prereqs' } || {}; |
207
|
0
|
|
|
|
|
|
$meta->{$_} = $prereqs->{$_} for keys %$prereqs; |
208
|
0
|
|
|
|
|
|
$meta->{generated_by} = sprintf("%s version %s", __PACKAGE__, $VERSION); |
209
|
0
|
|
|
|
|
|
$meta->{'meta-spec'} = { version => 1.4, url => 'http://module-build.sourceforge.net/META-spec-v1.4.html' }; |
210
|
0
|
|
|
|
|
|
$meta->{'license'} = 'perl'; |
211
|
0
|
|
|
|
|
|
require CPAN::Meta::YAML; |
212
|
0
|
|
|
|
|
|
CPAN::Meta::YAML::DumpFile($file,$meta); |
213
|
|
|
|
|
|
|
} |
214
|
|
|
|
|
|
|
|
215
|
|
|
|
|
|
|
sub _find_prereqs { |
216
|
0
|
|
|
0
|
|
|
my (%requires, %build_requires); |
217
|
0
|
|
|
|
|
|
for my $guts ( map { _slurp($_) } _files('lib'), _files('bin') ) { |
|
0
|
|
|
|
|
|
|
218
|
0
|
|
|
|
|
|
while ( $guts =~ m{$re{prereq}}g ) { $requires{$1}=$2; } |
|
0
|
|
|
|
|
|
|
219
|
|
|
|
|
|
|
} |
220
|
0
|
|
|
|
|
|
for my $guts ( map { _slurp($_) } _files('t'), _files('t/lib') ) { |
|
0
|
|
|
|
|
|
|
221
|
0
|
|
|
|
|
|
while ( $guts =~ m{$re{prereq}}g ) { $build_requires{$1}=$2; } |
|
0
|
|
|
|
|
|
|
222
|
|
|
|
|
|
|
} |
223
|
0
|
|
|
|
|
|
return { requires => \%requires, build_requires => \%build_requires }; |
224
|
|
|
|
|
|
|
} |
225
|
|
|
|
|
|
|
|
226
|
|
|
|
|
|
|
run() unless caller; # modulino :-) |
227
|
|
|
|
|
|
|
|
228
|
|
|
|
|
|
|
1; |
229
|
|
|
|
|
|
|
|
230
|
|
|
|
|
|
|
__END__ |