File Coverage

blib/lib/Module/Build/JSAN/Installable.pm
Criterion Covered Total %
statement 65 215 30.2
branch 11 68 16.1
condition 0 7 0.0
subroutine 14 37 37.8
pod 0 22 0.0
total 90 349 25.7


line stmt bran cond sub pod time code
1             package Module::Build::JSAN::Installable;
2             BEGIN {
3 4     4   114078 $Module::Build::JSAN::Installable::VERSION = '0.13';
4             }
5              
6 4     4   36 use strict;
  4         7  
  4         118  
7 4     4   18 use vars qw(@ISA);
  4         6  
  4         145  
8              
9 4     4   3617 use Module::Build::JSAN;
  4         633002  
  4         191  
10             @ISA = qw(Module::Build::JSAN);
11              
12 4     4   40 use File::Spec::Functions qw(catdir catfile);
  4         9  
  4         216  
13 4     4   23 use File::Basename qw(dirname);
  4         9  
  4         151  
14              
15 4     4   3733 use Path::Class;
  4         155405  
  4         249  
16 4     4   40 use Config;
  4         6  
  4         162  
17 4     4   4307 use JSON;
  4         58498  
  4         26  
18              
19              
20             __PACKAGE__->add_property('task_name' => 'Core');
21             __PACKAGE__->add_property('static_dir' => 'static');
22             __PACKAGE__->add_property('docs_markup' => 'pod');
23              
24              
25             #================================================================================================================================================================================================================================================
26             sub new {
27 0     0 0 0 my $self = shift->SUPER::new(@_);
28            
29 0         0 $self->add_build_element('js');
30            
31 0         0 $self->add_build_element('static');
32            
33 0 0       0 $self->install_base($self->get_jsan_libroot) unless $self->install_base;
34 0         0 $self->install_base_relpaths(lib => 'lib');
35 0         0 $self->install_base_relpaths(arch => 'arch');
36            
37 0         0 return $self;
38             }
39              
40              
41              
42             #================================================================================================================================================================================================================================================
43             sub get_jsan_libroot {
44 0   0 0 0 0 return $ENV{JSANLIB} || (($^O eq 'MSWin32') ? 'c:\JSAN' : (split /\s+/, $Config{'libspath'})[1] . '/jsan');
45             }
46              
47              
48             #================================================================================================================================================================================================================================================
49             sub process_static_files {
50 0     0 0 0 my $self = shift;
51            
52 0         0 my $static_dir = $self->static_dir;
53            
54 0 0       0 return if !-d $static_dir;
55            
56             #find all files except directories
57             my $files = $self->rscan_dir($static_dir, sub {
58 0     0   0 !-d $_
59 0         0 });
60            
61 0         0 foreach my $file (@$files) {
62 0         0 $self->copy_if_modified(from => $file, to => File::Spec->catfile($self->blib, 'lib', $self->dist_name_as_dir, $file) );
63             }
64            
65             }
66              
67              
68             #================================================================================================================================================================================================================================================
69             sub ACTION_install {
70 0     0 0 0 my $self = shift;
71            
72 0         0 require ExtUtils::Install;
73            
74 0         0 $self->depends_on('build');
75            
76 0         0 my $map = $self->install_map;
77 0         0 my $dist_name = quotemeta $self->dist_name();
78            
79             #trying to be cross-platform
80 0         0 my $dist_name_to_dir = catdir( split(/\./, $self->dist_name()) );
81            
82 0         0 $map->{'write'} =~ s/$dist_name/$dist_name_to_dir/;
83            
84 0   0     0 ExtUtils::Install::install($map, !$self->quiet, 0, $self->{args}{uninst}||0);
85             }
86              
87              
88             #================================================================================================================================================================================================================================================
89             sub dist_name_as_dir {
90 0     0 0 0 return split(/\.|-/, shift->dist_name());
91             }
92              
93              
94             #================================================================================================================================================================================================================================================
95             sub comp_to_filename {
96 0     0 0 0 my ($self, $comp) = @_;
97            
98 0         0 my @dirs = split /\./, $comp;
99 0         0 $dirs[-1] .= '.js';
100            
101 0         0 return file('lib', @dirs);
102             }
103              
104              
105             #================================================================================================================================================================================================================================================
106             sub ACTION_task {
107 0     0 0 0 my $self = shift;
108            
109 0         0 my $components = file('Components.JS')->slurp;
110              
111             #removing // style comments
112 0         0 $components =~ s!//.*$!!gm;
113              
114             #extracting from most outer {} brackets
115 0         0 $components =~ m/(\{.*\})/s;
116 0         0 $components = $1;
117              
118 0         0 my $deploys = decode_json $components;
119            
120 0         0 $self->concatenate_for_task($deploys, $self->task_name);
121             }
122              
123              
124             #================================================================================================================================================================================================================================================
125             sub expand_task_entry {
126 0     0 0 0 my ($self, $deploys, $task_name, $seen) = @_;
127            
128 0 0       0 $seen = {} if !$seen;
129            
130 0 0       0 die "Recursive visit to task [$task_name] when expanding entries" if $seen->{ $task_name };
131            
132 0         0 $seen->{ $task_name } = 1;
133            
134 0 0       0 return map {
135            
136 0         0 /^\+(.+)/ ? $self->expand_task_entry($deploys, $1, $seen) : $_;
137            
138 0         0 } @{$deploys->{ $task_name }};
139             }
140              
141              
142             #================================================================================================================================================================================================================================================
143             sub concatenate_for_task {
144 0     0 0 0 my ($self, $deploys, $task_name) = @_;
145            
146 0 0       0 if ($task_name eq 'all') {
147            
148 0         0 foreach my $deploy (keys(%$deploys)) {
149 0         0 $self->concatenate_for_task($deploys, $deploy);
150             }
151            
152             } else {
153 0         0 my @components = $self->expand_task_entry($deploys, $task_name);
154 0 0       0 die "No components in task: [$task_name]" unless @components > 0;
155            
156 0         0 my @dist_dirs = split /\./, $self->dist_name();
157 0         0 push @dist_dirs, $task_name;
158 0         0 $dist_dirs[-1] .= '.js';
159            
160 0         0 my $bundle_file = file('lib', 'Task', @dist_dirs);
161 0         0 $bundle_file->dir()->mkpath();
162            
163 0         0 my $bundle_fh = $bundle_file->openw();
164            
165 0         0 foreach my $comp (@components) {
166 0         0 print $bundle_fh $self->get_component_content($comp) . ";\n";
167             }
168            
169 0         0 $bundle_fh->close();
170             };
171             }
172              
173              
174             #================================================================================================================================================================================================================================================
175             sub get_component_content {
176 0     0 0 0 my ($self, $component) = @_;
177            
178 0 0       0 if ($component =~ /^jsan:(.+)/) {
    0          
179 0         0 my @file = ($self->get_jsan_libroot, 'lib', split /\./, $1);
180 0         0 $file[ -1 ] .= '.js';
181            
182 0         0 return file(@file)->slurp;
183             } elsif ($component =~ /^=(.+)/) {
184 0         0 return file($1)->slurp;
185             } else {
186 0         0 return $self->comp_to_filename($component)->slurp;
187             }
188             }
189              
190              
191              
192             #================================================================================================================================================================================================================================================
193             sub ACTION_test {
194 0     0 0 0 my ($self) = @_;
195            
196 0         0 my $result = (system 'jsan-prove') >> 8;
197            
198 0 0       0 if ($result == 1) {
199 0         0 print "All tests successfull\n";
200             } else {
201 0         0 print "There were failures\n";
202             }
203             }
204              
205              
206             #================================================================================================================================================================================================================================================
207             sub ACTION_dist {
208 0     0 0 0 my $self = shift;
209              
210 0         0 $self->depends_on('manifest');
211 0         0 $self->depends_on('docs');
212 0         0 $self->depends_on('distdir');
213              
214 0         0 my $dist_dir = $self->dist_dir;
215              
216 0         0 $self->_strip_pod($dist_dir);
217              
218 0         0 $self->make_tarball($dist_dir);
219 0         0 $self->delete_filetree($dist_dir);
220              
221 0         0 $self->add_to_cleanup('META.json');
222             # $self->add_to_cleanup('*.gz');
223             }
224              
225              
226              
227             #================================================================================================================================================================================================================================================
228             sub ACTION_docs {
229 1     1 0 516666 my $self = shift;
230            
231             #preparing 'doc' directory possible adding to cleanup
232 1         11 my $doc_dir = catdir 'doc';
233            
234 1 50       16 unless (-e $doc_dir) {
235 1 50       202 File::Path::mkpath($doc_dir, 0, 0755) or die "Couldn't mkdir $doc_dir: $!";
236            
237 1         9 $self->add_to_cleanup($doc_dir);
238             }
239            
240 1         305 my $markup = $self->docs_markup;
241            
242 1 50       39 if ($markup eq 'pod') {
    50          
    50          
243 0         0 $self->generate_docs_from_pod()
244             } elsif ($markup eq 'md') {
245 0         0 $self->generate_docs_from_md()
246             } elsif ($markup eq 'mmd') {
247 1         7 $self->generate_docs_from_mmd()
248             }
249             }
250              
251              
252             #================================================================================================================================================================================================================================================
253             sub generate_docs_from_md {
254 0     0 0 0 my $self = shift;
255            
256 0         0 require Text::Markdown;
257            
258             $self->extract_inlined_docs({
259             html => \sub {
260 0     0   0 my ($comments, $content) = @_;
261 0         0 return (Text::Markdown::markdown($comments), 'html')
262             },
263            
264             md => \sub {
265 0     0   0 my ($comments, $content) = @_;
266 0         0 return ($comments, 'txt');
267             }
268             })
269 0         0 }
270              
271              
272             #================================================================================================================================================================================================================================================
273             sub generate_docs_from_mmd {
274 1     1 0 5 my $self = shift;
275            
276 1         1274 require Text::MultiMarkdown;
277            
278             $self->extract_inlined_docs({
279             html => sub {
280 1     1   2 my ($comments, $content) = @_;
281 1         5 return (Text::MultiMarkdown::markdown($comments), 'html')
282             },
283            
284             mmd => sub {
285 1     1   1 my ($comments, $content) = @_;
286 1         8 return ($comments, 'txt');
287             }
288             })
289 1         1345402 }
290              
291              
292             #================================================================================================================================================================================================================================================
293             sub extract_inlined_docs {
294 1     1 0 3 my ($self, $convertors) = @_;
295            
296 1         7 my $markup = $self->docs_markup;
297 1         27 my $lib_dir = dir('lib');
298 1         269 my $js_files = $self->find_dist_packages;
299            
300            
301 1         1099 foreach my $file (map { $_->{file} } values %$js_files) {
  1         5  
302 1         8 (my $separate_docs_file = $file) =~ s|\.js$|.$markup|;
303            
304 1         8 my $content = file($file)->slurp;
305            
306 1 50       671 my $docs_content = -e $separate_docs_file ? file($separate_docs_file)->slurp : $self->strip_doc_comments($content);
307              
308              
309 1         241 foreach my $format (keys(%$convertors)) {
310            
311             #receiving formatted docs
312 2         4 my $convertor = $convertors->{$format};
313            
314 2         6 my ($result, $result_ext) = &$convertor($docs_content, $content);
315            
316            
317             #preparing 'doc' directory for current format
318 2         3502 my $format_dir = catdir 'doc', $format;
319            
320 2 50       55 unless (-e $format_dir) {
321 2 50       331 File::Path::mkpath($format_dir, 0, 0755) or die "Couldn't mkdir $format_dir: $!";
322            
323 2         11 $self->add_to_cleanup($format_dir);
324             }
325            
326            
327             #saving results
328 2         806 (my $res = $file) =~ s|^$lib_dir|$format_dir|;
329            
330 2         92 $res =~ s/\.js$/.$result_ext/;
331            
332 2         59 my $res_dir = dirname $res;
333            
334 2 50       40 unless (-e $res_dir) {
335 2 50       219 File::Path::mkpath($res_dir, 0, 0755) or die "Couldn't mkdir $res_dir: $!";
336            
337 2         9 $self->add_to_cleanup($res_dir);
338             }
339            
340 2 50       672 open my $fh, ">", $res or die "Cannot open $res: $!\n";
341            
342 2         8 print $fh $result;
343            
344 2         76 close $fh;
345             }
346             }
347             }
348              
349              
350              
351             #================================================================================================================================================================================================================================================
352             sub strip_doc_comments {
353 0     0 0   my ($self, $content) = @_;
354            
355 0           my @comments = ($content =~ m[^\s*/\*\*(.*?)\*/]msg);
356            
357 0           return join '', @comments;
358             }
359              
360              
361             #================================================================================================================================================================================================================================================
362             sub generate_docs_from_pod {
363 0     0 0   my $self = shift;
364              
365 0           require Pod::Simple::HTML;
366 0           require Pod::Simple::Text;
367 0           require Pod::Select;
368              
369 0           for (qw(html text pod)) {
370 0           my $dir = catdir 'doc', $_;
371            
372 0 0         unless (-e $dir) {
373 0 0         File::Path::mkpath($dir, 0, 0755) or die "Couldn't mkdir $dir: $!";
374            
375 0           $self->add_to_cleanup($dir);
376             }
377             }
378              
379 0           my $lib_dir = catdir 'lib';
380 0           my $pod_dir = catdir 'doc', 'pod';
381 0           my $html_dir = catdir 'doc', 'html';
382 0           my $txt_dir = catdir 'doc', 'text';
383              
384 0           my $js_files = $self->find_dist_packages;
385            
386 0           foreach my $file (map { $_->{file} } values %$js_files) {
  0            
387 0           (my $pod = $file) =~ s|^$lib_dir|$pod_dir|;
388            
389 0           $pod =~ s/\.js$/.pod/;
390            
391 0           my $dir = dirname $pod;
392            
393 0 0         unless (-e $dir) {
394 0 0         File::Path::mkpath($dir, 0, 0755) or die "Couldn't mkdir $dir: $!";
395             }
396            
397             # Ignore existing documentation files.
398 0 0         next if -e $pod;
399            
400            
401 0 0         open my $fh, ">", $pod or die "Cannot open $pod: $!\n";
402              
403 0           Pod::Select::podselect( { -output => $fh }, $file );
404              
405 0           print $fh "\n=cut\n";
406              
407 0           close $fh;
408             }
409            
410              
411 0           for my $pod (@{Module::Build->rscan_dir($pod_dir, qr/\.pod$/)}) {
  0            
412             # Generate HTML docs.
413 0           (my $html = $pod) =~ s|^\Q$pod_dir|$html_dir|;
414            
415 0           $html =~ s/\.pod$/.html/;
416            
417 0           my $dir = dirname $html;
418            
419 0 0         unless (-e $dir) {
420 0 0         File::Path::mkpath($dir, 0, 0755) or die "Couldn't mkdir $dir: $!";
421             }
422            
423 0 0         open my $fh, ">", $html or die "Cannot open $html: $!\n";
424            
425 0           my $parser = Pod::Simple::HTML->new;
426 0           $parser->output_fh($fh);
427 0           $parser->parse_file($pod);
428            
429 0           close $fh;
430              
431             # Generate text docs.
432 0           (my $txt = $pod) =~ s|^\Q$pod_dir|$txt_dir|;
433            
434 0           $txt =~ s/\.pod$/.txt/;
435            
436 0           $dir = dirname $txt;
437            
438 0 0         unless (-e $dir) {
439 0 0         File::Path::mkpath($dir, 0, 0755) or die "Couldn't mkdir $dir: $!";
440             }
441            
442 0 0         open $fh, ">", $txt or die "Cannot open $txt: $!\n";
443            
444 0           $parser = Pod::Simple::Text->new;
445 0           $parser->output_fh($fh);
446 0           $parser->parse_file($pod);
447            
448 0           close $fh;
449             }
450             }
451              
452              
453             #================================================================================================================================================================================================================================================
454             sub _write_default_maniskip {
455 0     0     my $self = shift;
456 0   0       my $file = shift || 'MANIFEST.SKIP';
457              
458 0           $self->SUPER::_write_default_maniskip($file);
459              
460 0 0         my $fh = IO::File->new(">> $file") or die "Can't open $file: $!";
461 0           print $fh <<'EOF';
462             ^\.project$
463             ^\.git\b
464             ^\.externalToolBuilders\b
465             EOF
466 0           $fh->close();
467             }
468              
469              
470              
471             #================================================================================================================================================================================================================================================
472             # Overriding newly created Module::Build method, which add itself to 'configure_requires' - we need to keep it clean
473 0     0 0   sub auto_require {
474            
475             }
476              
477              
478             #================================================================================================================================================================================================================================================
479             # Overriding Module::Build method, which checks for prerequisites being installed
480             sub check_prereq {
481 0     0 0   return 1
482             }
483              
484              
485             #================================================================================================================================================================================================================================================
486             # Overriding Module::Build method, which checks some other feature
487             sub check_autofeatures {
488 0     0 0   return 1
489             }
490              
491              
492             #================================================================================================================================================================================================================================================
493             sub prepare_metadata {
494 0     0 0   my ($self, $node, $keys, $args) = @_;
495            
496 0           $self->meta_add('static_dir' => $self->static_dir);
497            
498 0           return $self->SUPER::prepare_metadata($node, $keys, $args);
499             }
500              
501              
502              
503             __PACKAGE__ # nothingmuch (c)
504              
505             __END__