File Coverage

blib/lib/Module/Build/Functions/DSL.pm
Criterion Covered Total %
statement 36 59 61.0
branch 13 22 59.0
condition 4 6 66.6
subroutine 4 7 57.1
pod 0 2 0.0
total 57 96 59.3


line stmt bran cond sub pod time code
1             package Module::Build::Functions::DSL;
2              
3 1     1   4 use strict;
  1         1  
  1         31  
4 1     1   6 use vars qw( $VERSION );
  1         2  
  1         68  
5              
6             BEGIN {
7 1     1   1 $VERSION = '0.04';
8              
9 1         3 *inc::Module::Build::Functions::DSL::VERSION = *VERSION;
10 1         610 @inc::Module::Build::Functions::DSL::ISA = __PACKAGE__;
11             }
12              
13             sub import {
14 0     0   0 my $package = shift;
15              
16             # Read in the rest of the Makefile.PL
17 0 0       0 open 0 or die "Couldn't open $0: $!";
18 0         0 my $dsl;
19 0         0 SCOPE: {
20 0         0 local $/ = undef;
21 0         0 $dsl = join "", <0>;
22             }
23              
24             # Change inc::Module::Build::Functions::DSL to the regular one.
25             # Remove anything before the use inc::... line.
26 0         0 $dsl =~ s/.*?^\s*use\s+(?:inc::)?$package(\b[^;]*);\s*\n//sm;
27              
28             # Stripping leading prefix
29 0         0 $package =~ s/^\Qinc\E:://;
30              
31              
32 0         0 my $code = $package->get_header_code(@_);
33              
34             # Execute the header code
35 0 0       0 if (ref $code eq 'CODE') {
36 0         0 eval { &$code() }
  0         0  
37             } else {
38 0         0 eval $code
39             }
40 0 0       0 print STDERR "Failed to execute the generated code: $@" if $@;
41              
42             # Add the DSL plugin to the list of packages in /inc
43 0         0 Module::Build::Functions::copy_package($package);
44              
45             # Convert the basic syntax to code
46 0         0 $code = "package main;\n\n" . dsl2code($dsl) . "\n\nWriteAll();\n";
47              
48             # Execute the script
49 0         0 eval $code;
50 0 0       0 print STDERR "Failed to execute the generated code: $@" if $@;
51              
52 0         0 exit(0);
53             } ## end sub import
54              
55              
56             sub get_header_code {
57 0     0 0 0 my ($self, @import_params) = @_;
58            
59              
60             # Load inc::Module::Build::Functions as we would in a regular Makefile.Pl
61             return sub {
62             package main;
63            
64 0     0   0 require inc::Module::Build::Functions;
65 0         0 inc::Module::Build::Functions->import(@import_params);
66             }
67 0         0 }
68              
69              
70             sub dsl2code {
71 4     4 0 2202 my $dsl = shift;
72              
73             # Split into lines and strip blanks
74 4         20 my @lines = grep {/\S/} split /[\012\015]+/, $dsl;
  11         26  
75              
76             # Each line represents one command
77 4         7 my @code = ();
78 4         4 foreach my $line (@lines) {
79              
80             # Split the lines into tokens
81 11         29 my @tokens = split /\s+/, $line;
82              
83             # The first word is the command
84 11         17 my $command = shift @tokens;
85 11         13 my @params = ();
86 11         11 my @suffix = ();
87 11         23 while (@tokens) {
88 15         19 my $token = shift @tokens;
89 15         13 my $next_token;
90             my $token_quoted;
91              
92 15 100       41 if ( $token =~ /^(\'|\")/ ) {
93 6         7 $token_quoted = 1;
94              
95 6 100       19 if ( $token !~ /(\'|\")$/ ) {
96 2   66     3 do {
97 4         6 $next_token = shift @tokens;
98              
99 4 50       29 $token .= ' ' . $next_token if $next_token;
100              
101             } while ( $next_token && $next_token !~ /(\'|\")$/ );
102             }
103             } ## end if ( $token =~ /^(\'|\")/)
104              
105 15 100 66     56 if ( $token eq 'if' or $token eq 'unless' ) {
106              
107             # This is the beginning of a suffix
108 1         3 push @suffix, $token;
109 1         3 push @suffix, @tokens;
110 1         2 last;
111             } else {
112              
113             # Convert to a string
114 14 100       28 $token =~ s/([\\\'\"])/\\$1/g unless $token_quoted;
115 14 100       48 push @params, $token_quoted ? $token : "'$token'";
116             }
117             } ## end while (@tokens)
118              
119             # Merge to create the final line of code
120             @tokens =
121 11 100       31 ( $command, @params ? join( ', ', @params ) : (), @suffix );
122 11         38 push @code, join( ' ', @tokens ) . ";\n";
123             } ## end foreach my $line (@lines)
124              
125             # Join into the complete code block
126 4         17 return join( '', @code );
127             } ## end sub dsl2code
128              
129             1;