File Coverage

blib/lib/JSAN/Parse/FileDeps.pm
Criterion Covered Total %
statement 52 52 100.0
branch 8 12 66.6
condition 2 3 66.6
subroutine 11 11 100.0
pod 4 4 100.0
total 77 82 93.9


line stmt bran cond sub pod time code
1             package JSAN::Parse::FileDeps;
2              
3             =pod
4              
5             =head1 NAME
6              
7             JSAN::Parse::FileDeps - Parse file-level dependencies from JSAN modules
8              
9             =head1 DESCRIPTION
10              
11             As in Perl, two types of dependencies exist in L. Distribution-level
12             install-time dependencies, and run-time file-level dependencies.
13              
14             Because JSAN modules aren't explicitly required to provide the file-level
15             dependencies, this package was created to provide a single common module
16             by which to determine what these dependencies are, so that all processes
17             at all stages of the JSAN module lifecycle will have a common understanding
18             of the dependencies that a file has, and provide certainty for the
19             module developer.
20              
21             =head1 METHODS
22              
23             =cut
24              
25 2     2   32849 use 5.005;
  2         7  
  2         81  
26 2     2   12 use strict;
  2         4  
  2         66  
27 2     2   20 use Carp ();
  2         3  
  2         42  
28 2     2   11 use File::Spec ();
  2         4  
  2         42  
29 2     2   17 use File::Basename ();
  2         4  
  2         45  
30              
31 2     2   45 use vars qw{$VERSION};
  2         4  
  2         122  
32             BEGIN {
33 2     2   1627 $VERSION = '1.00';
34             }
35              
36             my $SEPERATOR = qr/__CODE__/;
37             my $LIB_DEP = qr/^\s*JSAN\.use\s*\(\s*(?:"([\w\.]+)"|'([\w\.]+)')\s*(?:\,|\))/;
38              
39              
40              
41              
42              
43              
44             #####################################################################
45             # JSAN::Parse::FileDeps Static Methods
46              
47             =pod
48              
49             =head2 library_deps $file
50              
51             The C method finds a list of all the libary dependencies for
52             a given file, where a library is specified in the form C<"Foo.Bar">
53             (using the pseudo-namespaces common to JSAN).
54              
55             Returns a list of libraries, or throws an exception on error.
56              
57             =cut
58              
59             sub library_deps {
60 2     2 1 526 my $class = shift;
61 2         9 my @head = $class->find_deps_js(@_);
62 2         3 my %libraries = ();
63 2         4 foreach my $line ( @head ) {
64 6 100       32 if ( $line =~ /$LIB_DEP/ ) {
65 4   66     15 my $library = $1 || $2;
66 4         10 $libraries{$library} = 1;
67             }
68             }
69 2         14 return sort keys %libraries;
70             }
71              
72             =pod
73              
74             =head2 file_deps $file
75              
76             The C method finds a list of all the file dependencies for
77             a given file, where a file is specified in the form C<"Foo/Bar.js">
78             (that is, relative to the root of the lib path for the modules).
79              
80             The list is identical to, and is calculated from, the list of libraries
81             returned by C.
82              
83             Returns a list of local filesytem relative paths, or throws an exception
84             on error.
85              
86             =cut
87              
88             sub file_deps {
89 1     1 1 553 my $class = shift;
90 1         3 my @libraries = $class->library_deps(shift);
91 1         2 my @files = ();
92 1         3 foreach my $library ( @libraries ) {
93 2         29 push @files, File::Spec->catfile( split /\./, $library ) . '.js';
94             }
95 1         4 return @files;
96             }
97              
98             =pod
99              
100             =head2 find_deps_js $file
101              
102             The C method is used to extract the header content from a file,
103             to be searched for dependencies, and potentially written to a C
104             file.
105              
106             Returns the content as a list of lines, or throws an exception on error.
107              
108             =cut
109              
110             sub find_deps_js {
111 4     4 1 795 my $class = shift;
112 4 50       11 my $input = defined $_[0] ? shift
113             : Carp::croak("No input file provided to ->find_deps_js");
114              
115             # Load the file
116 4 50       120 open( INFILE, '<', $input )
117             or Carp::croak("Failed to open $input for reading: $!");
118              
119             # Isolate the head content
120 4         9 my @lines = ();
121 4         58 while ( ) {
122 16 100       87 last if /$SEPERATOR/;
123 12         29 push @lines, $_;
124             }
125 4         43 close INFILE;
126              
127             # Return the header lines
128 4         16 @lines;
129             }
130              
131             =pod
132              
133             =head2 make_deps_js $file
134              
135             The C method takes a JSAN module filename in the form
136             C<"foo/bar.js"> and extracts the dependency header, writing it to
137             C<"foo/bar_deps.js">.
138              
139             Returns true on success, or throws an exception on error.
140              
141             =cut
142              
143             sub make_deps_js {
144 1     1 1 505 my $class = shift;
145              
146             # Get the header contents
147 1         2 my $input = shift;
148 1         4 my @head = $class->find_deps_js($input);
149            
150             # Work out what file to write to
151 1         74 my ($file, $dir, $ext) = File::Basename::fileparse( $input, qr/\..*/ );
152 1         16 my $output = File::Spec->catfile( $dir, $file . '_deps' . $ext );
153              
154             # Write the header to it
155 1 50       98 open( OUTFILE, '>', $output )
156             or Carp::croak("Failed to open $output for writing: $!");
157 1         2 foreach my $line ( @head ) {
158 3 50       11 print OUTFILE $line
159             or Carp::croak("Error writing to $output: $!");
160             }
161 1         45 close OUTFILE;
162              
163 1         5 1;
164             }
165              
166             1;
167              
168             =pod
169              
170             =head1 SUPPORT
171              
172             Bugs should always be submitted via the CPAN bug tracker
173              
174             L
175              
176             For other issues, contact the maintainer
177              
178             =head1 AUTHORS
179              
180             Completed and maintained by Adam Kennedy , L
181              
182             Original written by Rob Kinyon
183              
184             =head1 COPYRIGHT
185              
186             Copyright 2005, 2006 Rob Kinyon and Adam Kennedy. All rights reserved.
187              
188             This program is free software; you can redistribute
189             it and/or modify it under the same terms as Perl itself.
190              
191             The full text of the license can be found in the
192             LICENSE file included with this module.
193              
194             =cut