File Coverage

blib/lib/Document/Maker.pm
Criterion Covered Total %
statement 7 9 77.7
branch n/a
condition n/a
subroutine 3 3 100.0
pod n/a
total 10 12 83.3


line stmt bran cond sub pod time code
1             package Document::Maker;
2              
3 1     1   18421 use warnings;
  1         2  
  1         25  
4 1     1   5 use strict;
  1         2  
  1         60  
5              
6             =head1 NAME
7              
8             Document::Maker - Makefile-like functionality in Perl
9              
10             =head1 VERSION
11              
12             Version 0.022
13              
14             =cut
15              
16             our $VERSION = '0.022';
17              
18             =head1 SYNOPSIS
19              
20             my $maker = Document::Maker->new;
21              
22             $maker->parser->parse_target( "tgt/a.out" => "src/defs.txt",
23             do => sub {
24             my $target = shift;
25             my $file = shift; # tgt/a.out
26             ....
27             },
28             );
29              
30             $maker->make("tgt/a.out"); # Will only make if "tgt/a.out" is older than "src/defs.txt" or doesn't exist
31              
32             =head1 DESCRIPTION
33              
34             Document::Maker is intended to have similar functionality as GNU make with additional enhancements.
35              
36             WARNING: Although this is a 3rd-iteration attempt at Makefile-ness, the API is very fluid
37             and could change in future versions.
38              
39             WARNING: There may be bugs lurking about, I'll be happy to entertain bug reports.
40              
41             =head2 Already working
42              
43             =head3 Target-from-one-source
44              
45             $maker->parser->parse_target( "tgt/a.out" => "src/defs.txt",
46             do => sub {
47             my $target = shift;
48             my $file = shift; # tgt/a.out
49             ....
50             },
51             );
52              
53             =head3 Target-from-many-sources
54              
55             $maker->parser->parse_target( "tgt/a.out" => [ "src/defs.txt", "src/xyzzy.txt" ],
56             do => sub {
57             my $target = shift;
58             my $file = shift; # tgt/a.out
59             ....
60             },
61             );
62              
63             =head3 Many-targets-dependent-on-many-sources
64              
65             $maker->parser->parse_target( [ "tgt/a.out", "tgt/b.out" ] => [ "src/defs.txt", "src/xyzzy.txt" ],
66             do => sub {
67             my $target = shift;
68             my $file = shift;
69             ....
70             },
71             );
72              
73             =head3 Non-file, Target-only
74              
75             $maker->parser->parse_simple_target( "configure",
76             do => sub {
77             my $target = shift; # No second argument
78             ....
79             },
80             );
81              
82             =head3 Target/source-patterns
83              
84             $maker->parser->parse_pattern_target(qw( tgt/%.html src/%.in a b c d e ), [ "header.html" ], {
85             do => sub {
86             my $target = shift;
87             my $file = shift; # tgt/a.html, tgt/b.html, etc.
88             my $source_file = shift; # src/a.in, src/b.in, etc.
89             ....
90             },
91             });
92              
93             =head3 Target/source-patterns based on crawling through a directory
94              
95             # This will crawl src/ looking for every file matching the src pattern and making a target out of it
96             $maker->parser->parse_pattern_target(qw( tgt/%.html src/%.in src/* ), [ "header.html" ], {
97             do => sub {
98             my $target = shift;
99             my $file = shift;
100             my $source_file = shift;
101             ....
102             },
103             });
104              
105             =head2 Waiting to be implemented
106              
107             =head3 .PHONY targets (always_make flag, sort-of implemented via simple targets)
108              
109             =head3 Control of intermediate targets/sources
110              
111             =head3 Better control of make conditions (should_make parameter)
112              
113             =head3 Shell-like "do" arguments, similar to a real Makefile
114              
115             For example, something like:
116              
117             $maker->parser->parse...(..., do => \<<_END_);
118             @echo "Using m4 first before getting a line count"
119             m4 < main.m4 $< | wc -l > $@
120             _END_
121              
122             =head3 Consistent handling of make failures/stale files
123              
124             =head3 Last-chance wildcard targets
125              
126             =head3 Document and test advanced patterns (embedded regexp, etc.)
127              
128             =head1 AUTHOR
129              
130             Robert Krimen, C<< <rkrimen at cpan.org> >>
131              
132             =head1 BUGS
133              
134             Please report any bugs or feature requests to
135             C<bug-document-maker at rt.cpan.org>, or through the web interface at
136             L<http://rt.cpan.org/NoAuth/ReportBug.html?Queue=Document-Maker>.
137             I will be notified, and then you'll automatically be notified of progress on
138             your bug as I make changes.
139              
140             =head1 SUPPORT
141              
142             You can find documentation for this module with the perldoc command.
143              
144             perldoc Document::Maker
145              
146             You can also look for information at:
147              
148             =over 4
149              
150             =item * AnnoCPAN: Annotated CPAN documentation
151              
152             L<http://annocpan.org/dist/Document-Maker>
153              
154             =item * CPAN Ratings
155              
156             L<http://cpanratings.perl.org/d/Document-Maker>
157              
158             =item * RT: CPAN's request tracker
159              
160             L<http://rt.cpan.org/NoAuth/Bugs.html?Dist=Document-Maker>
161              
162             =item * Search CPAN
163              
164             L<http://search.cpan.org/dist/Document-Maker>
165              
166             =back
167              
168             =head1 ACKNOWLEDGEMENTS
169              
170             =head1 COPYRIGHT & LICENSE
171              
172             Copyright 2007 Robert Krimen, all rights reserved.
173              
174             This program is free software; you can redistribute it and/or modify it
175             under the same terms as Perl itself.
176              
177             =cut
178              
179 1     1   398 use Moose;
  0            
  0            
180              
181             use Moose::Util::TypeConstraints;
182             use Path::Class;
183              
184             type 'Path::Class::File' => where { $_->isa("Path::Class::File") };
185             coerce 'Path::Class::File' => from 'Str' => via { Path::Class::File->new($_) };
186              
187             with map { "Document::Maker::Role::$_" } qw/Logging/;
188              
189             has target_maker_registry => qw/is ro/, default => sub { [] };
190             has parser => qw/is ro lazy 1/, default => sub {
191             require Document::Maker::Parser;
192             return Document::Maker::Parser->new(maker => shift)
193             };
194              
195             sub can_make {
196             my $self = shift;
197             my $name = shift;
198              
199             return 1 if $self->find_target($name);
200             return 0;
201             }
202              
203             sub should_make {
204             my $self = shift;
205             my $name = shift;
206              
207             return 0 unless my $target = $self->find_target($name);
208             return $target->should_make;
209             }
210              
211             sub make {
212             my $self = shift;
213             for my $name (@_) {
214             $self->log->debug("Try to make: $name");
215             $self->log->debug("Couldn't find target to make: $name") and next unless my $target = $self->find_target($name);
216             $self->log->debug("Shouldn't make: $name") and next unless $target->should_make;
217             $target->make;
218             }
219             }
220              
221             sub find_target {
222             my $self = shift;
223             my $name = shift;
224              
225             return unless my $target_maker_registry = $self->target_maker_registry;
226             my $target;
227             for (@$target_maker_registry) {
228             last if $target = $_->can_make($name);
229             }
230             return $target;
231             }
232              
233             sub register_target_maker {
234             my $self = shift;
235             my $target_maker = shift;
236             push @{ $self->target_maker_registry }, $target_maker;
237             }
238              
239             1; # End of Document::Maker