File Coverage

blib/lib/JavaScript/Dependency/Manager.pm
Criterion Covered Total %
statement 51 51 100.0
branch 16 18 88.8
condition 7 10 70.0
subroutine 9 9 100.0
pod 1 1 100.0
total 84 89 94.3


line stmt bran cond sub pod time code
1             package JavaScript::Dependency::Manager;
2             {
3             $JavaScript::Dependency::Manager::VERSION = '0.001002';
4             }
5              
6             # ABSTRACT: Manage your JavaScript dependencies
7              
8 1     1   44440 use Moo;
  1         39764  
  1         7  
9 1     1   9794 use Sub::Quote;
  1         6486  
  1         116  
10 1     1   1224 use Tie::IxHash;
  1         8596  
  1         35  
11 1     1   1018 use autodie;
  1         16219  
  1         6  
12              
13             has lib_dir => (
14             is => 'ro',
15             required => 1,
16             );
17              
18             has recurse => (
19             is => 'ro',
20             default => quote_sub q{ 0 },
21             );
22              
23             has scan_files => (
24             is => 'ro',
25             default => quote_sub q{ 1 },
26             );
27              
28             has _scanned_files => (
29             is => 'rw',
30             );
31              
32             # hashref where the provision (what a file provides) is the key,
33             # and an arrayref of the files that provide the feature are the value
34             has provisions => (
35             is => 'ro',
36             default => quote_sub q{ {} },
37             );
38              
39             # hashref where the filename is the key, and the value is required provisions in
40             # an arrayref
41             has requirements => (
42             is => 'ro',
43             default => quote_sub q{ {} },
44             );
45              
46             sub file_list_for_provisions {
47 26     26 1 5913 my ($self, $provisions) = @_;
48              
49 26 100 66     160 if ($self->scan_files && !$self->_scanned_files) {
50 2         5 for my $dir (@{$self->lib_dir}) {
  2         10  
51 2         12 $self->_scan_dir($dir);
52             }
53 2         11 $self->_scanned_files(1);
54             }
55              
56 26         31 my %ret;
57 26         111 tie %ret, 'Tie::IxHash';
58 26         310 for my $requested_provision (@$provisions) {
59 30         95 my $files = $self->_files_providing($requested_provision);
60              
61             # for now we just use the first file
62 30         55 my $file = $files->[0];
63 30 100       58 if (my $requirements = $self->_direct_requirements_for($file)) {
64 22         55 $ret{$_} = 1 for $self->file_list_for_provisions($requirements);
65             }
66 30         1258 $ret{$file} = 1;
67             }
68              
69 26         1086 return keys %ret;
70             }
71              
72             sub _scan_dir {
73 3     3   7 my ($self, $dir) = @_;
74 3         5 my $dh;
75 3         16 opendir $dh, $dir;
76 3 100       3177 my @files = grep { $_ ne '.' && $_ ne '..' } readdir $dh;
  17         82  
77 3         12 for (@files) {
78 11         30 my $fqfn = "$dir/$_";
79 11 100 100     177 $self->_scan_dir($fqfn) if $self->recurse && -d $fqfn;
80 11 100       197 $self->_scan_file($fqfn) if -f $fqfn;
81             }
82             }
83              
84             sub _scan_file {
85 9     9   15 my ($self, $file) = @_;
86 9 50       42 return unless $file =~ /\.js$/;
87 9         36 open my $fh, '<', $file;
88 9         3255 while (<$fh>) {
89 40 100       598 if (m[//\s*provides:\s*(\S+)]) {
    100          
90 7   50     63 $self->provisions->{$1} ||= [];
91 7         11 push @{$self->provisions->{$1}}, $file
  7         49  
92             } elsif (m[//\s*requires:\s*(\S+)]) {
93 6   50     42 $self->requirements->{$file} ||= [];
94 6         9 push @{$self->requirements->{$file}}, $1
  6         38  
95             }
96             }
97             }
98              
99             sub _files_providing {
100 30     30   42 my ($self, $provision) = @_;
101              
102 30 50       107 $self->provisions->{$provision}
103             or die "no such provision '$provision' found!";
104             }
105              
106             sub _direct_requirements_for {
107 30     30   33 my ($self, $file) = @_;
108              
109 30         103 $self->requirements->{$file}
110             }
111              
112              
113             1;
114              
115             # This code was written at the Tallulah Travel Center in Louisiana
116              
117             __END__