File Coverage

blib/lib/Alien/Build/MM.pm
Criterion Covered Total %
statement 135 174 77.5
branch 31 52 59.6
condition 4 11 36.3
subroutine 20 25 80.0
pod 7 7 100.0
total 197 269 73.2


line stmt bran cond sub pod time code
1             package Alien::Build::MM;
2              
3 2     2   1383 use strict;
  2         7  
  2         63  
4 2     2   10 use warnings;
  2         4  
  2         48  
5 2     2   31 use 5.008004;
  2         7  
6 2     2   594 use Alien::Build;
  2         5  
  2         57  
7 2     2   11 use Path::Tiny ();
  2         5  
  2         39  
8 2     2   9 use Capture::Tiny qw( capture );
  2         5  
  2         96  
9 2     2   11 use Carp ();
  2         5  
  2         4927  
10              
11             # ABSTRACT: Alien::Build installer code for ExtUtils::MakeMaker
12             our $VERSION = '2.46'; # VERSION
13              
14              
15             sub new
16             {
17 9     9 1 63709 my($class, %prop) = @_;
18              
19 9         35 my $self = bless {}, $class;
20              
21 9         34 my %meta = map { $_ => $prop{$_} } grep /^my_/, keys %prop;
  0         0  
22              
23             my $build = $self->{build} =
24 9 100       230 Alien::Build->load('alienfile',
25             root => "_alien",
26             (-d 'patch' ? (patch => 'patch') : ()),
27             meta_prop => \%meta,
28             )
29             ;
30              
31 9 50       27 if(%meta)
32             {
33 0         0 $build->meta->add_requires(configure => 'Alien::Build::MM' => '1.20');
34 0         0 $build->meta->add_requires(configure => 'Alien::Build' => '1.20');
35             }
36              
37 9 50       31 if(defined $prop{alienfile_meta})
38             {
39 0         0 $self->{alienfile_meta} = $prop{alienfile_meta};
40             }
41             else
42             {
43 9         21 $self->{alienfile_meta} = 1;
44             }
45              
46 9         22 $self->{clean_install} = $prop{clean_install};
47              
48 9         28 $self->build->load_requires('configure');
49 9         27 $self->build->root;
50 9         35 $self->build->checkpoint;
51              
52 9         63 $self;
53             }
54              
55              
56             sub build
57             {
58 104     104 1 3947 shift->{build};
59             }
60              
61              
62             sub alienfile_meta
63             {
64 8     8 1 27 shift->{alienfile_meta};
65             }
66              
67              
68             sub clean_install
69             {
70 9     9 1 107 shift->{clean_install};
71             }
72              
73              
74             sub mm_args
75             {
76 8     8 1 659 my($self, %args) = @_;
77              
78 8 50       36 if($args{DISTNAME})
79             {
80 8         27 $self->build->set_stage(Path::Tiny->new("blib/lib/auto/share/dist/$args{DISTNAME}")->absolute->stringify);
81 8         47 $self->build->install_prop->{mm}->{distname} = $args{DISTNAME};
82 8         21 my $module = $args{DISTNAME};
83 8         63 $module =~ s/-/::/g;
84             # See if there is an existing version installed, without pulling it into this process
85 8     8   259 my($old_prefix, $err, $ret) = capture { system $^X, "-M$module", -e => "print $module->dist_dir"; $? };
  8         66024  
  8         539  
86 8 50       11158 if($ret == 0)
87             {
88 0         0 chomp $old_prefix;
89 0         0 my $file = Path::Tiny->new($old_prefix, qw( _alien alien.json ));
90 0 0       0 if(-r $file)
91             {
92 0         0 my $old_runtime = eval {
93 0         0 require JSON::PP;
94 0         0 JSON::PP::decode_json($file->slurp);
95             };
96 0 0       0 unless($@)
97             {
98 0         0 $self->build->install_prop->{old}->{runtime} = $old_runtime;
99 0         0 $self->build->install_prop->{old}->{prefix} = $old_prefix;
100             }
101             }
102             }
103             }
104             else
105             {
106 0         0 Carp::croak "DISTNAME is required";
107             }
108              
109 8         59 my $ab_version = '0.25';
110              
111 8 100       111 if($self->clean_install)
112             {
113 1         15 $ab_version = '1.74';
114             }
115              
116             $args{CONFIGURE_REQUIRES} = Alien::Build::_merge(
117             'Alien::Build::MM' => $ab_version,
118 8 100       150 %{ $args{CONFIGURE_REQUIRES} || {} },
119 8 50       26 %{ $self->build->requires('configure') || {} },
  8         82  
120             );
121              
122 8 100       54 if($self->build->install_type eq 'system')
    50          
123             {
124             $args{BUILD_REQUIRES} = Alien::Build::_merge(
125             'Alien::Build::MM' => $ab_version,
126 2 100       27 %{ $args{BUILD_REQUIRES} || {} },
127 2 50       197 %{ $self->build->requires('system') || {} },
  2         10  
128             );
129             }
130             elsif($self->build->install_type eq 'share')
131             {
132             $args{BUILD_REQUIRES} = Alien::Build::_merge(
133             'Alien::Build::MM' => $ab_version,
134 6 100       84 %{ $args{BUILD_REQUIRES} || {} },
135 6 50       46 %{ $self->build->requires('share') || {} },
  6         36  
136             );
137             }
138             else
139             {
140 0         0 die "unknown install type: @{[ $self->build->install_type ]}"
  0         0  
141             }
142              
143             $args{PREREQ_PM} = Alien::Build::_merge(
144             'Alien::Build' => $ab_version,
145 8 50       37 %{ $args{PREREQ_PM} || {} },
  8         92  
146             );
147              
148             #$args{META_MERGE}->{'meta-spec'}->{version} = 2;
149 8         45 $args{META_MERGE}->{dynamic_config} = 1;
150              
151 8 50       32 if($self->alienfile_meta)
152             {
153             $args{META_MERGE}->{x_alienfile} = {
154 8   50     68 generated_by => "@{[ __PACKAGE__ ]} version @{[ __PACKAGE__->VERSION || 'dev' ]}",
  8         254  
155             requires => {
156             map {
157 8         17 my %reqs = %{ $self->build->requires($_) };
  16         36  
  16         39  
158 16         59 $reqs{$_} = "$reqs{$_}" for keys %reqs;
159 16         173 $_ => \%reqs;
160             } qw( share system )
161             },
162             };
163             }
164              
165 8         46 $self->build->checkpoint;
166 8         219 %args;
167             }
168              
169              
170             sub mm_postamble
171             {
172             # NOTE: older versions of the Alien::Build::MM documentation
173             # didn't include $mm and @rest args, so anything that this
174             # method uses them for has to be optional.
175             # (as of this writing they are unused, but are being added
176             # to match the way mm_install works).
177              
178 1     1 1 27 my($self, $mm, @rest) = @_;
179              
180 1         8 my $postamble = '';
181              
182             # remove the _alien directory on a make realclean:
183 1         9 $postamble .= "realclean :: alien_realclean\n" .
184             "\n" .
185             "alien_realclean:\n" .
186             "\t\$(RM_RF) _alien\n\n";
187              
188             # remove the _alien directory on a make clean:
189 1         8 $postamble .= "clean :: alien_clean\n" .
190             "\n" .
191             "alien_clean:\n" .
192             "\t\$(RM_RF) _alien\n\n";
193              
194             my $dirs = $self->build->meta_prop->{arch}
195 1 50       15 ? '$(INSTALLARCHLIB) $(INSTALLSITEARCH) $(INSTALLVENDORARCH)'
196             : '$(INSTALLPRIVLIB) $(INSTALLSITELIB) $(INSTALLVENDORLIB)'
197             ;
198              
199             # set prefix
200 1         15 $postamble .= "alien_prefix : _alien/mm/prefix\n\n" .
201             "_alien/mm/prefix :\n" .
202             "\t\$(FULLPERL) -MAlien::Build::MM=cmd -e prefix \$(INSTALLDIRS) $dirs\n\n";
203              
204             # set verson
205 1         9 $postamble .= "alien_version : _alien/mm/version\n\n" .
206             "_alien/mm/version : _alien/mm/prefix\n" .
207             "\t\$(FULLPERL) -MAlien::Build::MM=cmd -e version \$(VERSION)\n\n";
208              
209             # download
210 1         12 $postamble .= "alien_download : _alien/mm/download\n\n" .
211             "_alien/mm/download : _alien/mm/prefix _alien/mm/version\n" .
212             "\t\$(FULLPERL) -MAlien::Build::MM=cmd -e download\n\n";
213              
214             # build
215 1         14 $postamble .= "alien_build : _alien/mm/build\n\n" .
216             "_alien/mm/build : _alien/mm/download\n" .
217             "\t\$(FULLPERL) -MAlien::Build::MM=cmd -e build\n\n";
218              
219             # append to all
220 1         10 $postamble .= "pure_all :: _alien/mm/build\n\n";
221              
222 1         5 $postamble .= "subdirs-test_dynamic subdirs-test_static subdirs-test :: alien_test\n\n";
223 1         10 $postamble .= "alien_test :\n" .
224             "\t\$(FULLPERL) -MAlien::Build::MM=cmd -e test\n\n";
225              
226             # prop
227 1         4 $postamble .= "alien_prop :\n" .
228             "\t\$(FULLPERL) -MAlien::Build::MM=cmd -e dumpprop\n\n";
229 1         7 $postamble .= "alien_prop_meta :\n" .
230             "\t\$(FULLPERL) -MAlien::Build::MM=cmd -e dumpprop meta\n\n";
231 1         3 $postamble .= "alien_prop_install :\n" .
232             "\t\$(FULLPERL) -MAlien::Build::MM=cmd -e dumpprop install\n\n";
233 1         7 $postamble .= "alien_prop_runtime :\n" .
234             "\t\$(FULLPERL) -MAlien::Build::MM=cmd -e dumpprop runtime\n\n";
235              
236             # install
237 1         4 $postamble .= "alien_clean_install : _alien/mm/prefix\n" .
238             "\t\$(FULLPERL) -MAlien::Build::MM=cmd -e clean_install\n\n";
239              
240 1         14 $postamble;
241             }
242              
243              
244             sub mm_install
245             {
246             # NOTE: older versions of the Alien::Build::MM documentation
247             # didn't include this method, so anything that this method
248             # does has to be optional
249              
250 0     0 1 0 my($self, $mm, @rest) = @_;
251              
252 0         0 my $section = do {
253             package
254             MY;
255 0         0 $mm->SUPER::install(@rest);
256             };
257              
258             return
259 0         0 ".NOTPARALLEL : \n\n"
260             . ".NO_PARALLEL : \n\n"
261             . "install :: alien_clean_install\n\n"
262             . $section;
263             }
264              
265             sub import
266             {
267 1     1   14 my(undef, @args) = @_;
268 1         2 foreach my $arg (@args)
269             {
270 1 50       5 if($arg eq 'cmd')
271             {
272             package main;
273              
274             *_args = sub
275             {
276 6     6   62 my $build = Alien::Build->resume('alienfile', '_alien');
277 6         85 $build->load_requires('configure');
278 6         37 $build->load_requires($build->install_type);
279 6         46 ($build, @ARGV)
280 1         6 };
281              
282             *_touch = sub {
283 6     6   47 my($name) = @_;
284 6         55 my $path = Path::Tiny->new("_alien/mm/$name");
285 6         226 $path->parent->mkpath;
286 6         1618 $path->touch;
287 1         5 };
288              
289             *prefix = sub
290             {
291 4     4   5847 my($build, $type, $perl, $site, $vendor) = _args();
292              
293 4         40 my $distname = $build->install_prop->{mm}->{distname};
294              
295 4 50       27 my $prefix = $type eq 'perl'
    100          
    100          
296             ? $perl
297             : $type eq 'site'
298             ? $site
299             : $type eq 'vendor'
300             ? $vendor
301             : die "unknown INSTALLDIRS ($type)";
302 4         89 $prefix = Path::Tiny->new($prefix)->child("auto/share/dist/$distname")->absolute->stringify;
303              
304 4         526 $build->log("prefix $prefix");
305 4         73 $build->set_prefix($prefix);
306 4         52 $build->checkpoint;
307 4         21 _touch('prefix');
308 1         4 };
309              
310             *version = sub
311             {
312 0     0   0 my($build, $version) = _args();
313              
314 0         0 $build->runtime_prop->{perl_module_version} = $version;
315 0         0 $build->checkpoint;
316 0         0 _touch('version');
317 1         3 };
318              
319             *download = sub
320             {
321 1     1   3201 my($build) = _args();
322 1         10 $build->download;
323 1         164 $build->checkpoint;
324 1         13 _touch('download');
325 1         3 };
326              
327             *build = sub
328             {
329 1     1   3642 my($build) = _args();
330              
331 1         19 $build->build;
332              
333 1         5 my $distname = $build->install_prop->{mm}->{distname};
334              
335 1 50       4 if($build->meta_prop->{arch})
336             {
337 1         4 my $archdir = Path::Tiny->new("blib/arch/auto/@{[ join '/', split /-/, $distname ]}");
  1         11  
338 1         38 $archdir->mkpath;
339 1         373 my $archfile = $archdir->child($archdir->basename . '.txt');
340 1         70 $archfile->spew('Alien based distribution with architecture specific file in share');
341             }
342              
343 1         433 my $cflags = $build->runtime_prop->{cflags};
344 1         4 my $libs = $build->runtime_prop->{libs};
345              
346 1 50 33     19 if(($cflags && $cflags !~ /^\s*$/)
      33        
      33        
347             || ($libs && $libs !~ /^\s*$/))
348             {
349 0         0 my $mod = join '::', split /-/, $distname;
350 0         0 my $install_files_pm = Path::Tiny->new("blib/lib/@{[ join '/', split /-/, $distname ]}/Install/Files.pm");
  0         0  
351 0         0 $install_files_pm->parent->mkpath;
352 0         0 $install_files_pm->spew(
353             "package ${mod}::Install::Files;\n",
354             "use strict;\n",
355             "use warnings;\n",
356             "require ${mod};\n",
357             "sub Inline { shift; ${mod}->Inline(\@_) }\n",
358             "1;\n",
359             "\n",
360             "=begin Pod::Coverage\n",
361             "\n",
362             " Inline\n",
363             "\n",
364             "=cut\n",
365             );
366             }
367              
368 1         12 $build->checkpoint;
369 1         6 _touch('build');
370 1         17 };
371              
372             *test = sub
373             {
374 0     0   0 my($build) = _args();
375 0         0 $build->test;
376 0         0 $build->checkpoint;
377 1         5 };
378              
379             *clean_install = sub
380             {
381 0     0   0 my($build) = _args();
382 0         0 $build->clean_install;
383 0         0 $build->checkpoint;
384 1         4 };
385              
386             *dumpprop = sub
387             {
388 0     0     my($build, $type) = _args();
389              
390 0           my %h = (
391             meta => $build->meta_prop,
392             install => $build->install_prop,
393             runtime => $build->runtime_prop,
394             );
395              
396 0           require Alien::Build::Util;
397 0 0         print Alien::Build::Util::_dump($type ? $h{$type} : \%h);
398             }
399 1         34 }
400             }
401             }
402              
403             1;
404              
405             __END__