File Coverage

blib/lib/Module/Build/JSAN.pm
Criterion Covered Total %
statement 15 163 9.2
branch 0 50 0.0
condition 0 13 0.0
subroutine 5 19 26.3
pod 0 10 0.0
total 20 255 7.8


line stmt bran cond sub pod time code
1             package Module::Build::JSAN;
2              
3             # $Id$
4              
5 1     1   50710 use strict;
  1         4  
  1         32  
6 1     1   5 use vars qw($VERSION @ISA);
  1         2  
  1         70  
7              
8             $VERSION = '0.05';
9 1     1   25584 use Module::Build;
  1         407371  
  1         46  
10             @ISA = qw(Module::Build);
11 1     1   4094 use File::Spec::Functions qw(catdir catfile);
  1         3189  
  1         104  
12 1     1   11 use File::Basename qw(dirname);
  1         2  
  1         4418  
13              
14             sub new {
15 0     0 0   my $pkg = shift;
16 0           my %p = @_;
17 0   0       $p{metafile} ||= 'META.json';
18 0 0 0       if (my $keywords = delete $p{keywords} || delete $p{tags}) {
19 0 0         if ($p{meta_merge}) {
20 0           $p{meta_merge}->{keywords} = $keywords
21             } else {
22 0           $p{meta_merge} = { keywords => $keywords };
23             }
24             }
25 0           return $pkg->SUPER::new(%p);
26             }
27              
28              
29             sub ACTION_dist {
30 0     0 0   my $self = shift;
31              
32 0           require Pod::Simple::HTML;
33 0           require Pod::Simple::Text;
34 0           require Pod::Select;
35              
36 0           for (qw(html text pod)) {
37 0           my $dir = catdir 'doc', $_;
38 0 0         unless (-e $dir) {
39 0 0         File::Path::mkpath($dir, 0, 0755)
40             or die "Couldn't mkdir $dir: $!";
41 0           $self->add_to_cleanup($dir);
42             }
43             }
44              
45 0           my $lib_dir = catdir 'lib';
46 0           my $pod_dir = catdir 'doc', 'pod';
47 0           my $html_dir = catdir 'doc', 'html';
48 0           my $txt_dir = catdir 'doc', 'text';
49              
50 0           my $js_files = $self->find_dist_packages;
51 0           foreach my $file (map { $_->{file} } values %$js_files) {
  0            
52 0           (my $pod = $file) =~ s|^$lib_dir|$pod_dir|;
53 0           $pod =~ s/\.js$/.pod/;
54 0           my $dir = dirname $pod;
55 0 0         unless (-e $dir) {
56 0 0         File::Path::mkpath($dir, 0, 0755)
57             or die "Couldn't mkdir $dir: $!";
58             }
59             # Ignore existing documentation files.
60 0 0         next if -e $pod;
61 0 0         open my $fh, ">", $pod or die "Cannot open $pod: $!\n";
62              
63 0           Pod::Select::podselect( { -output => $fh }, $file );
64              
65 0           print $fh "\n=cut\n";
66              
67 0           close $fh;
68             }
69              
70 0           for my $pod (@{Module::Build->rscan_dir($pod_dir, qr/\.pod$/)}) {
  0            
71             # Generate HTML docs.
72 0           (my $html = $pod) =~ s|^\Q$pod_dir|$html_dir|;
73 0           $html =~ s/\.pod$/.html/;
74 0           my $dir = dirname $html;
75 0 0         unless (-e $dir) {
76 0 0         File::Path::mkpath($dir, 0, 0755)
77             or die "Couldn't mkdir $dir: $!";
78             }
79 0 0         open my $fh, ">", $html or die "Cannot open $html: $!\n";
80 0           my $parser = Pod::Simple::HTML->new;
81 0           $parser->output_fh($fh);
82 0           $parser->parse_file($pod);
83 0           close $fh;
84              
85             # Generate text docs.
86 0           (my $txt = $pod) =~ s|^\Q$pod_dir|$txt_dir|;
87 0           $txt =~ s/\.pod$/.txt/;
88 0           $dir = dirname $txt;
89 0 0         unless (-e $dir) {
90 0 0         File::Path::mkpath($dir, 0, 0755)
91             or die "Couldn't mkdir $dir: $!";
92             }
93 0 0         open $fh, ">", $txt or die "Cannot open $txt: $!\n";
94 0           $parser = Pod::Simple::Text->new;
95 0           $parser->output_fh($fh);
96 0           $parser->parse_file($pod);
97 0           close $fh;
98             }
99 0           $self->depends_on('manifest');
100              
101 0           $self->depends_on('distdir');
102              
103 0           my $dist_dir = $self->dist_dir;
104              
105 0           $self->_strip_pod($dist_dir);
106              
107 0           $self->make_tarball($dist_dir);
108 0           $self->delete_filetree($dist_dir);
109              
110              
111             # $self->add_to_cleanup('META.json');
112             # $self->add_to_cleanup('*.gz');
113             }
114              
115             sub ACTION_manifest {
116 0     0 0   my $self = shift;
117 0           $self->SUPER::ACTION_manifest(@_);
118 0           $self->add_to_cleanup('MANIFEST.bak');
119             }
120              
121             sub ACTION_deps {
122 0     0 0   my $self = shift;
123              
124 0           my $prefix = './tests/lib';
125              
126 0           require JSAN::Shell;
127 0           my $jsan = JSAN::Shell->new;
128 0           $jsan->index;
129              
130 0           my @deps = (
131 0           keys( %{$self->{properties}{build_requires}} ),
132 0           keys( %{$self->{properties}{requires}} ),
133             );
134              
135 0           eval { $jsan->install( $_, $prefix ) }, ($@ && print$@)
136 0   0       for @deps;
137              
138 0           $self->add_to_cleanup( $prefix );
139             }
140              
141             sub dist_version {
142 0     0 0   my $self = shift;
143 0           my $p = $self->{properties};
144 0 0         return $p->{dist_version} if defined $p->{dist_version};
145              
146 0 0         if ($self->module_name) {
147 0   0       $p->{dist_version_from} ||=
148             join( '/', 'lib', split /\./, $self->module_name ) . '.js';
149 0           print $p->{dist_version_from}, $/;
150             }
151              
152 0 0         die "Can't determine distribution version, must supply either "
153             . "'dist_version',\n'dist_version_from', or 'module_name' parameter"
154             unless $p->{dist_version_from};
155              
156             # Search for the version number.
157 0           return $p->{dist_version} = $self->_parse_version(
158             $self->module_name,
159             $p->{dist_version_from}
160             );
161             }
162              
163 0     0 0   sub find_js_files { shift->_find_file_by_type('js', 'lib') }
164              
165             sub find_dist_packages {
166 0     0 0   my $self = shift;
167             # Only packages in .js files are candidates for inclusion here.
168             # Only include things in the MANIFEST, not things in developer's
169             # private stock.
170              
171 0 0         my $manifest = $self->_read_manifest('MANIFEST')
172             or die "Can't find dist packages without a MANIFEST file "
173             . "- run 'manifest' action first";
174              
175             # Localize
176 0           my %dist_files = map { $self->localize_file_path($_) => $_ }
  0            
177             keys %$manifest;
178              
179 0           my @js_files = grep {exists $dist_files{$_}} keys %{ $self->find_js_files };
  0            
  0            
180              
181 0           my %out;
182 0           for my $file (@js_files) {
183 0 0         next if $file =~ m{^t/}; # Skip things in t/
184              
185             # Assume that the file name corresponds to the library. This may need
186             # to be more sophisticated in the future, but will do for now.
187 0           (my $lib = $file) =~ s|^[^/]+/||;
188 0           $lib = join '.', split m{/}, $lib;
189 0           $lib =~ s/\.js$//;
190 0           $out{$lib} = {
191             file => $dist_files{$file},
192             version => $self->_parse_version($lib, $file),
193             };
194             }
195 0           return \%out;
196             }
197              
198             sub _parse_version {
199 0     0     my ($self, $lib, $file) = @_;
200 0           my $version_from = File::Spec->catfile( split m{/}, $file );
201 0 0         open VF, "<$version_from" or die "Cannot open '$version_from': $!\n";
202 0           my $version = '';
203 0           my $find = qr/VERSION\s*(?:=|:)\s*[^\d._]*([\d._]+)/;
204 0           while () {
205 0 0         last if ($version) = /$find/;
206             }
207 0           close VF;
208 0           return $version;
209             }
210              
211             sub write_metafile {
212 0     0 0   my $self = shift;
213 0           my $metafile = $self->metafile;
214              
215 0           require Module::Build::JSAN::ConfigData; # Only works after the 'build'
216 0 0         if (Module::Build::JSAN::ConfigData->feature('JSON_support')) {
217 0           require JSON;
218 0           $self->prepare_metadata( my $node = {} );
219 0 0         open my $meta, '>', $metafile or die "Cannot open '$metafile': $!\n";
220 0           print $meta JSON->new->pretty->encode( $node );
221 0           close $meta;
222             } else {
223 0           $self->log_warn(
224             "\nCouldn't load JSON.pm, generating a minimal META.json without ",
225             "it.\nPlease check and edit the generated metadata, or consider ",
226             "installing\nJSON.pm.\n\n"
227             );
228 0           $self->_write_minimal_metadata;
229             }
230 0           $self->_add_to_manifest('MANIFEST', $metafile);
231             }
232              
233             sub _write_minimal_metadata {
234 0     0     my $self = shift;
235 0           my $p = $self->{properties};
236              
237 0           my $file = $self->metafile;
238 0 0         my $fh = IO::File->new("> $file") or die "Can't open $file: $!";
239              
240             # XXX Add the meta_add & meta_merge stuff
241 0           print $fh <<"END_OF_META";
242             {
243 0           "name": "$p->{dist_name}",
244             "version": "$p->{dist_version}",
245             "author":
246 0           @{[ join "\n", map qq{ "$_"}, @{$self->dist_author} ]},
  0            
247             "abstract": "@{[ $self->dist_abstract ]}",
248             "license": "$p->{license}",
249             "generated_by": "Module::Build::JSAN version $Module::Build::JSAN::VERSION, without JSON.pm"
250             }
251             END_OF_META
252             }
253              
254             sub _write_default_maniskip {
255 0     0     my $self = shift;
256 0   0       my $file = shift || 'MANIFEST.SKIP';
257              
258 0           $self->SUPER::_write_default_maniskip($file);
259              
260 0 0         my $fh = IO::File->new(">> $file")
261             or die "Can't open $file: $!";
262 0           print $fh <<'EOF';
263             ^Build.PL$
264             .tar.gz$
265             ^tests/lib/
266             EOF
267 0           print $fh $self->dist_dir, "\n";
268 0           $fh->close();
269             }
270              
271             sub _strip_pod {
272 0     0     my ($self, $dist_dir) = @_;
273              
274 0           require Pod::Stripper;
275              
276 0           my $files = $self->find_js_files;
277 0           my $stripper = Pod::Stripper->new;
278 0           foreach my $from ( keys %{$files} ) {
  0            
279 0           my $to = catfile $dist_dir, $from;
280             # This will leave empty comment blocks intact.
281             # That looks odd. Pod::Stripper::JSAN should be made.
282 0           chmod 0644, $to;
283 0           $stripper->parse_from_file($from => $to);
284 0           chmod 0444, $to;
285             }
286             }
287              
288 0     0 0   sub check_prereq { }
289 0     0 0   sub ignore_prereqs { 1 }
290              
291             1;
292             __END__