File Coverage

blib/lib/Alien/Build/Plugin/Download/Negotiate.pm
Criterion Covered Total %
statement 67 79 84.8
branch 43 54 79.6
condition 11 15 73.3
subroutine 10 10 100.0
pod 2 2 100.0
total 133 160 83.1


line stmt bran cond sub pod time code
1             package Alien::Build::Plugin::Download::Negotiate;
2              
3 7     7   1373 use strict;
  7         15  
  7         194  
4 7     7   29 use warnings;
  7         16  
  7         168  
5 7     7   145 use 5.008004;
  7         21  
6 7     7   391 use Alien::Build::Plugin;
  7         15  
  7         52  
7 7     7   44 use Alien::Build::Util qw( _has_ssl );
  7         13  
  7         352  
8 7     7   39 use Carp ();
  7         14  
  7         6905  
9              
10             # ABSTRACT: Download negotiation plugin
11             our $VERSION = '2.47'; # VERSION
12              
13              
14             has '+url' => undef;
15              
16              
17             has 'filter' => undef;
18              
19              
20             has 'version' => undef;
21              
22              
23             has 'ssl' => 0;
24              
25              
26             has 'passive' => 0;
27              
28             has 'scheme' => undef;
29              
30              
31             has 'bootstrap_ssl' => 0;
32              
33              
34             has 'prefer' => 1;
35              
36              
37             has 'decoder' => undef;
38              
39              
40             sub pick
41             {
42 26     26 1 93 my($self) = @_;
43 26         77 my($fetch, @decoders) = $self->_pick;
44 26 100       111 if($self->decoder)
45             {
46 2 100       5 @decoders = ref $self->decoder ? @{ $self->decoder } : ($self->decoder);
  1         4  
47             }
48 26         157 ($fetch, @decoders);
49             }
50              
51             sub _pick_decoder
52             {
53 5     5   11 my($self) = @_;
54              
55 5 50       7 if(eval { require Mojo::DOM58; Mojo::DOM58->VERSION(1.00); 1 })
  5 50       552  
  0 50       0  
  0         0  
56 0         0 { return "Decode::Mojo" }
57 5         448 elsif(eval { require Mojo::DOM; require Mojolicious; Mojolicious->VERSION('7.00'); 1 })
  0         0  
  0         0  
  0         0  
58 0         0 { return "Decode::Mojo" }
59 5         471 elsif(eval { require HTML::LinkExtor; 1; })
  5         13971  
60 5         40 { return "Decode::HTML" }
61             else
62 0         0 { return "Decode::Mojo" }
63             }
64              
65             sub _pick
66             {
67 26     26   51 my($self) = @_;
68              
69 26 100       71 $self->scheme(
    50          
70             $self->url !~ m!(ftps?|https?|file):!i
71             ? 'file'
72             : $self->url =~ m!^([a-z]+):!i
73             ) unless defined $self->scheme;
74              
75 26 100 66     70 if($self->scheme eq 'https' || ($self->scheme eq 'http' && $self->ssl))
    100 66        
    100          
    50          
76             {
77 8 100 100     25 if($self->bootstrap_ssl && ! _has_ssl)
    100          
    100          
78             {
79 1         10 return (['Fetch::CurlCommand','Fetch::Wget'], __PACKAGE__->_pick_decoder);
80             }
81             elsif(_has_ssl)
82             {
83 5         34 return ('Fetch::HTTPTiny', __PACKAGE__->_pick_decoder);
84             }
85 2         24 elsif(do { require Alien::Build::Plugin::Fetch::CurlCommand; Alien::Build::Plugin::Fetch::CurlCommand->protocol_ok('https') })
  2         13  
86             {
87 1         10 return ('Fetch::CurlCommand', __PACKAGE__->_pick_decoder);
88             }
89             else
90             {
91 1         9 return ('Fetch::HTTPTiny', __PACKAGE__->_pick_decoder);
92             }
93             }
94             elsif($self->scheme eq 'http')
95             {
96 6         22 return ('Fetch::HTTPTiny', __PACKAGE__->_pick_decoder);
97             }
98             elsif($self->scheme eq 'ftp')
99             {
100 2 100 66     10 if($ENV{ftp_proxy} || $ENV{all_proxy})
101             {
102 1 50       3 return $self->scheme =~ /^ftps?/
103             ? ('Fetch::LWP', 'Decode::DirListing', __PACKAGE__->_pick_decoder)
104             : ('Fetch::LWP', __PACKAGE__->_pick_decoder);
105             }
106             else
107             {
108 1         4 return ('Fetch::NetFTP');
109             }
110             }
111             elsif($self->scheme eq 'file')
112             {
113 10         37 return ('Fetch::Local');
114             }
115             else
116             {
117 0         0 die "do not know how to handle scheme @{[ $self->scheme ]} for @{[ $self->url ]}";
  0         0  
  0         0  
118             }
119             }
120              
121             sub init
122             {
123 13     13 1 36 my($self, $meta) = @_;
124              
125 13 100       46 unless(defined $self->url)
126             {
127 4 50       11 if(defined $meta->prop->{start_url})
128             {
129 4         9 $self->url($meta->prop->{start_url});
130             }
131             else
132             {
133 0         0 Carp::croak "url is a required property unless you use the start_url directive";
134             }
135             }
136              
137 13 50       43 $meta->add_requires('share' => 'Alien::Build::Plugin::Download::Negotiate' => '0.61')
138             if $self->passive;
139              
140 13         33 $meta->prop->{plugin_download_negotiate_default_url} = $self->url;
141              
142 13         54 my($fetch, @decoders) = $self->pick;
143              
144 13 50       44 $fetch = [ $fetch ] unless ref $fetch;
145              
146 13         34 foreach my $fetch (@$fetch)
147             {
148 13         22 my @args;
149 13         38 push @args, ssl => $self->ssl;
150             # For historical reasons, we pass the URL into older fetch plugins, because
151             # this used to be the interface. Using start_url is now preferred!
152 13 50       120 push @args, url => $self->url if $fetch =~ /^Fetch::(HTTPTiny|LWP|Local|LocalDir|NetFTP|CurlCommand)$/;
153 13 50       52 push @args, passive => $self->passive if $fetch eq 'Fetch::NetFTP';
154 13 100       62 push @args, bootstrap_ssl => $self->bootstrap_ssl if $self->bootstrap_ssl;
155              
156 13         62 $meta->apply_plugin($fetch, @args);
157             }
158              
159 13 100       41 if($self->version)
160             {
161 7         22 $meta->apply_plugin($_) for @decoders;
162              
163 7 100 66     24 if(defined $self->prefer && ref($self->prefer) eq 'CODE')
    100          
164             {
165 1         6 $meta->add_requires('share' => 'Alien::Build::Plugin::Download::Negotiate' => '1.30');
166 1         4 $meta->register_hook(
167             prefer => $self->prefer,
168             );
169             }
170             elsif($self->prefer)
171             {
172 5 100       15 $meta->apply_plugin('Prefer::SortVersions',
173             (defined $self->filter ? (filter => $self->filter) : ()),
174             version => $self->version,
175             );
176             }
177             else
178             {
179 1         5 $meta->add_requires('share' => 'Alien::Build::Plugin::Download::Negotiate' => '1.30');
180             }
181             }
182             }
183              
184             1;
185              
186             __END__