1package Module::Starter::BuilderSet;
2
3use strict;
4use warnings;
5
6use Carp qw( carp );
7
8=head1 NAME
9
10Module::Starter::BuilderSet - determine builder metadata
11
12=head1 VERSION
13
14version 1.77
15
16=cut
17
18our $VERSION = '1.77';
19
20=head1 SYNOPSIS
21
22    use Module::Starter::BuilderSet;
23
24    my $builder_set = Module::Starter::BuilderSet->new;
25    my @supported_builders = $builder_set->supported_builders();
26    my $default_builder = $builder_set->default_builder();
27    my $output_file = $builder_set->file_for_builder($default_builder);
28
29    my $create_method = $builder_set->method_for_builder($default_builder);
30    Module::Starter::Simple->$create_method($default_builder); # eeew.
31
32    my @build_commands = $builder_set->instructions_for_builder($default_builder);
33    my @builder_dependencies = $builder_set->deps_for_builder($default_builder);
34    my @compatible_builders = $builder_set->check_compatibility(@builder_list);
35
36    my $ms_simple    = Module::Starter::Simple->new();
37    my $build_method = $builder_set->manifest_method($builder);
38    $ms_simple->$build_method();
39
40=head1 DESCRIPTION
41
42Module::Starter::BuilderSet is a collection of utility methods used to
43provide metadata about builders supported by Module::Starter.
44
45=head1 CLASS METHODS
46
47=head2 C<< new() >>
48
49This method initializes and returns an object representing the set of
50Builders supported by Module::Starter
51
52=cut
53
54sub new {
55    my $class = shift;
56
57    my $self =
58      {
59       'Module::Build' =>
60       {
61        file           => "Build.PL",
62        build_method   => "create_Build_PL",
63        build_deps     => [],
64        build_manifest => 'create_MB_MANIFEST',
65        instructions   => [ 'perl Build.PL',
66                            './Build',
67                            './Build test',
68                            './Build install',
69                          ],
70       },
71       'Module::Install' =>
72       {
73        file           => "Makefile.PL",
74        build_method   => "create_MI_Makefile_PL",
75        build_deps     => [],
76        build_manifest => 'create_MI_MANIFEST',
77        instructions   => [ 'perl Makefile.PL',
78                            'make',
79                            'make test',
80                            'make install',
81                          ],
82       },
83       'ExtUtils::MakeMaker' =>
84       {
85        file           => "Makefile.PL",
86        build_method   => "create_Makefile_PL",
87        build_manifest => 'create_EUMM_MANIFEST',
88        build_deps     => [ { command => 'make',
89                              aliases => [ 'make', 'gmake' ],
90                            },
91                            { command => 'chmod',
92                              aliases => [ 'chmod' ],
93                            },
94                          ],
95        instructions   => [ 'perl Makefile.PL',
96                            'make',
97                            'make test',
98                            'make install',
99                          ],
100       }
101      };
102
103    return bless $self, $class;
104}
105
106sub _builder {
107    my $self = shift;
108    my $builder = shift;
109
110    $builder = $self->default_builder unless $builder;
111
112    unless (exists $self->{$builder}) {
113        carp("Don't know anything about builder '$builder'.");
114        return undef;
115    }
116
117    return $self->{$builder};
118}
119
120=head2 C<< supported_builders() >>
121
122This method returns a list of builders supported by Module::Starter
123
124=cut
125
126sub supported_builders {
127    my $self = shift;
128
129    return keys %$self;
130}
131
132=head2 C<< file_for_builder($builder) >>
133
134This method returns the name of the file generated by Module::Starter
135that will be used to build the generated module
136
137=cut
138
139sub file_for_builder {
140    my $self = shift;
141    my $builder = shift;
142
143    return $self->_builder($builder)->{file};
144}
145
146=head2 C<< method_for_builder($builder) >>
147
148This method returns the name of the method in the
149C<Module::Starter::Simple> package that is called to create the file
150returned by C<file_for_builder($builder)>
151
152=cut
153
154sub method_for_builder {
155    my $self = shift;
156    my $builder = shift;
157
158    return $self->_builder($builder)->{build_method};
159}
160
161=head2 C<< instructions_for_builder($builder) >>
162
163This method returns a list of commands that, when run from the command
164line (or with C<system()>), will cause the generated module to be
165built, tested and installed.
166
167=cut
168
169sub instructions_for_builder {
170    my $self = shift;
171    my $builder = shift;
172
173    return @{ $self->_builder($builder)->{instructions} };
174}
175
176=head2 C<< deps_for_builder($builder) >>
177
178This method returns a list of dependencies in the following format:
179C<<
180( { command => "make",
181    aliases => [ 'make', 'gmake' ],
182   },
183  { command => "another_command",
184    aliases => [ 'alias0', 'alias1', '...' ],
185   },
186)
187>>
188
189=cut
190
191sub deps_for_builder {
192    my $self = shift;
193    my $builder = shift;
194
195    return @{ $self->_builder($builder)->{build_deps} };
196}
197
198=head2 C<< manifest_method($builder) >>
199
200This method returns the command to run to create the manifest according to the
201builder asked.
202
203=cut
204
205sub manifest_method {
206    my ( $self, $builder ) = @_;
207
208    return $self->_builder($builder)->{'build_manifest'};
209}
210
211=head2 C<< check_compatibility(@builders) >>
212
213This method accepts a list of builders and filters out the ones that
214are unsupported or mutually exclusive, returning the builders that
215passed the filter.  If none pass the filter, the default builder is
216returned.
217
218=cut
219
220sub check_compatibility {
221    my $self = shift;
222    my @builders = @_;
223
224    # if we're passed an array reference (or even a list of array
225    # references), de-reference the first one passed and assign
226    # @builders its contents
227
228    @builders = @{$builders[0]} if(@builders && ref $builders[0] eq 'ARRAY');
229
230    # remove empty and unsupported builders
231    @builders = grep { $self->_builder($_) } @builders;
232
233    # if we stripped all of them, use the default
234    push(@builders, $self->default_builder) unless int( @builders ) > 0;
235
236    my %uniq;
237    my @good;
238    foreach my $builder (@builders) {
239        # Builders that generate the same build file are mutually exclusive
240
241        # If given a list of builder modules that includes mutually
242        # exclusive modules, we'll use the first in the list
243
244        my $file = $self->file_for_builder($builder);
245        if (exists $uniq{$file}) {
246            # don't print a warning if the same builder was listed twice.
247            # Otherwise, inform the caller that these builders are mutually
248            # exclusive
249            carp("Builders '$builder' and '$uniq{$file}' are mutually exclusive.".
250                 "  Using '$uniq{$file}'."
251                ) unless $builder eq $uniq{$file};
252        } else {
253            $uniq{$file} = $builder;
254            push(@good, $uniq{$file});
255        }
256    }
257
258    return( @good );
259}
260
261=head2 C<< default_builder() >>
262
263This method returns the module name of the default builder.
264
265=cut
266
267sub default_builder {
268    my $self = shift;
269
270    return 'ExtUtils::MakeMaker';
271}
272
273=head1 BUGS
274
275Please report any bugs or feature requests to the bugtracker for this project
276on GitHub at: L<https://github.com/xsawyerx/module-starter/issues>. I will be
277notified, and then you'll automatically be notified of progress on your bug
278as I make changes.
279
280=head1 AUTHOR
281
282C.J. Adams-Collier, C<< <cjac@colliertech.org> >>
283
284=head1 Copyright & License
285
286Copyright 2007 C.J. Adams-Collier, All Rights Reserved.
287
288This program is free software; you can redistribute it and/or modify it
289under the same terms as Perl itself.
290
291Please note that these modules are not products of or supported by the
292employers of the various contributors to the code.
293
294=cut
295
2961;
297
298# vi:et:sw=4 ts=4
299