File Coverage

blib/lib/Module/Starter/App.pm
Criterion Covered Total %
statement 34 84 40.4
branch 9 30 30.0
condition 0 7 0.0
subroutine 8 17 47.0
pod 1 1 100.0
total 52 139 37.4


line stmt bran cond sub pod time code
1             package Module::Starter::App;
2              
3             =head1 NAME
4              
5             Module::Starter::App - the code behind the command line program
6              
7             =head1 VERSION
8              
9             version 1.82
10              
11             =cut
12              
13 1     1   88292 use warnings;
  1         2  
  1         91  
14 1     1   7 use strict;
  1         10  
  1         55  
15              
16             our $VERSION = '1.82';
17              
18 1     1   6 use File::Spec;
  1         3  
  1         27  
19 1     1   818 use Getopt::Long;
  1         19519  
  1         9  
20 1     1   792 use Pod::Usage;
  1         72054  
  1         162  
21 1     1   10 use Carp qw( croak );
  1         3  
  1         74  
22 1     1   639 use Module::Runtime qw( require_module );
  1         2296  
  1         7  
23              
24             sub _config_file {
25 0     0   0 my $self = shift;
26 0   0     0 my $configdir = $ENV{'MODULE_STARTER_DIR'} || '';
27              
28 0 0 0     0 if ( !$configdir && $ENV{'HOME'} ) {
29 0         0 $configdir = File::Spec->catdir( $ENV{'HOME'}, '.module-starter' );
30             }
31              
32 0         0 return File::Spec->catfile( $configdir, 'config' );
33             }
34              
35              
36             sub _config_read {
37 0     0   0 my $self = shift;
38              
39 0         0 my $filename = $self->_config_file;
40 0 0       0 return () unless -e $filename;
41            
42 0 0       0 open( my $config_file, '<', $filename )
43             or die "couldn't open config file $filename: $!\n";
44              
45 0         0 my %config;
46 0         0 while (my $line = <$config_file>) {
47 0         0 chomp $line;
48 0 0       0 next if $line =~ /\A\s*\Z/sm;
49 0 0       0 if ($line =~ /\A(\w+):\s*(.+)\Z/sm) { $config{$1} = $2; }
  0         0  
50             }
51            
52 0         0 return $self->_config_multi_process(%config);
53             }
54              
55             sub _config_multi_process {
56 22     22   271567 my ( $self, %config ) = @_;
57              
58             # The options that accept multiple arguments must be set to an arrayref
59 22         57 foreach my $key (qw( author builder ignores_type modules plugins )) {
60 110 100       347 $config{$key} = [] unless exists $config{$key};
61              
62 110 100       221 if ( $key eq 'author' ) {
63 22 50       61 next if ref $config{$key};
64              
65             # Split author strings on whitespace or comma.
66             # Spec: 'Author Name '
67 22         33 my @authors;
68 22         257 while ($config{$key} =~ s/
69             ^\s*
70             ((?>
71             (?: # Author
72             [^\s<>]+
73             \s+
74             )+
75             )
76             <[^<>]+>) # Email
77             (?: # Separators (or end of string)
78             \s*,\s*
79             | \s+
80             | \z
81             )
82             //x) {
83 20         147 push @authors, $1;
84             }
85 22 100       72 push @authors, $config{$key} if length $config{$key};
86 22         62 $config{$key} = \@authors;
87             }
88             else {
89 88 50       237 $config{$key} = [ split /(?:\s*,\s*|\s+)/, (ref $config{$key} ? join(',', @{$config{$key}}) : $config{$key}) ] if $config{$key};
  88 50       302  
90             }
91             }
92              
93 22         152 return %config;
94             }
95              
96             sub _process_command_line {
97 0     0     my ( $self, %config ) = @_;
98              
99 0           $config{'argv'} = [ @ARGV ];
100              
101 0 0         pod2usage(2) unless @ARGV;
102              
103             GetOptions(
104             'class=s' => \$config{class},
105             'plugin=s@' => \$config{plugins},
106             'dir=s' => \$config{dir},
107             'distro=s' => \$config{distro},
108             'module=s@' => \$config{modules},
109             'builder=s@' => \$config{builder},
110             'ignores=s@' => \$config{ignores_type},
111 0     0     eumm => sub { push @{$config{builder}}, 'ExtUtils::MakeMaker' },
  0            
112 0     0     mb => sub { push @{$config{builder}}, 'Module::Build' },
  0            
113 0     0     mi => sub { push @{$config{builder}}, 'Module::Install' },
  0            
114              
115 0           'author=s@' => \@{ $config{author} },
116             'email=s' => \$config{email},
117             'github=s' => \$config{github},
118             'license=s' => \$config{license},
119             genlicense => \$config{genlicense},
120             'minperl=s' => \$config{minperl},
121             'fatalize' => \$config{fatalize},
122              
123             force => \$config{force},
124             verbose => \$config{verbose},
125             version => sub {
126 0     0     require Module::Starter;
127 0           print "module-starter v$Module::Starter::VERSION\n";
128 0           exit 1;
129             },
130 0     0     help => sub { pod2usage(1); },
131 0 0         ) or pod2usage(2);
132              
133 0 0         if (@ARGV) {
134 0           pod2usage(
135             -msg => "Unparseable arguments received: " . join(',', @ARGV),
136             -exitval => 2,
137             );
138             }
139              
140 0   0       $config{class} ||= 'Module::Starter';
141              
142 0 0         $config{builder} = ['ExtUtils::MakeMaker'] unless $config{builder};
143              
144 0           return %config;
145             }
146              
147             =head2 run
148              
149             Module::Starter::App->run;
150              
151             This is equivalent to running F. Its behavior is still subject
152             to change.
153              
154             =cut
155              
156             sub run {
157 0     0 1   my $self = shift;
158 0           my %config = $self->_config_read;
159              
160 0           %config = $self->_process_command_line(%config);
161 0           %config = $self->_config_multi_process(%config);
162              
163 0           require_module $config{class};
164 0           $config{class}->import( @{ $config{'plugins'} } );
  0            
165              
166 0           my $starter = $config{class}->new( %config );
167 0           $starter->postprocess_config;
168 0           $starter->pre_create_distro;
169 0           $starter->create_distro;
170 0           $starter->post_create_distro;
171 0           $starter->pre_exit;
172              
173 0           return 1;
174             }
175              
176             1;