|  line  | 
 stmt  | 
 bran  | 
 cond  | 
 sub  | 
 pod  | 
 time  | 
 code  | 
| 
1
 | 
  
 
  
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 #!perl  | 
| 
2
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
3
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 package App::opan;  | 
| 
4
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
5
 | 
3
 | 
 
 | 
 
 | 
  
3
  
 | 
 
 | 
5119
 | 
 use strictures 2;  | 
| 
 
 | 
3
 | 
 
 | 
 
 | 
 
 | 
 
 | 
1683
 | 
    | 
| 
 
 | 
3
 | 
 
 | 
 
 | 
 
 | 
 
 | 
152
 | 
    | 
| 
6
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
7
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 our $VERSION = '0.003005';  | 
| 
8
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
9
 | 
3
 | 
 
 | 
 
 | 
  
3
  
 | 
 
 | 
2373
 | 
 use Dist::Metadata;  | 
| 
 
 | 
3
 | 
 
 | 
 
 | 
 
 | 
 
 | 
108733
 | 
    | 
| 
 
 | 
3
 | 
 
 | 
 
 | 
 
 | 
 
 | 
156
 | 
    | 
| 
10
 | 
3
 | 
 
 | 
 
 | 
  
3
  
 | 
 
 | 
2004
 | 
 use File::Open qw(fopen);  | 
| 
 
 | 
3
 | 
 
 | 
 
 | 
 
 | 
 
 | 
5088
 | 
    | 
| 
 
 | 
3
 | 
 
 | 
 
 | 
 
 | 
 
 | 
235
 | 
    | 
| 
11
 | 
3
 | 
 
 | 
 
 | 
  
3
  
 | 
 
 | 
1851
 | 
 use List::UtilsBy qw(sort_by);  | 
| 
 
 | 
3
 | 
 
 | 
 
 | 
 
 | 
 
 | 
6194
 | 
    | 
| 
 
 | 
3
 | 
 
 | 
 
 | 
 
 | 
 
 | 
369
 | 
    | 
| 
12
 | 
3
 | 
 
 | 
 
 | 
  
3
  
 | 
 
 | 
1517
 | 
 use IPC::System::Simple qw(capture);  | 
| 
 
 | 
3
 | 
 
 | 
 
 | 
 
 | 
 
 | 
19781
 | 
    | 
| 
 
 | 
3
 | 
 
 | 
 
 | 
 
 | 
 
 | 
325
 | 
    | 
| 
13
 | 
3
 | 
 
 | 
 
 | 
  
3
  
 | 
 
 | 
854
 | 
 use Mojo::Util qw(monkey_patch);  | 
| 
 
 | 
3
 | 
 
 | 
 
 | 
 
 | 
 
 | 
216346
 | 
    | 
| 
 
 | 
3
 | 
 
 | 
 
 | 
 
 | 
 
 | 
338
 | 
    | 
| 
14
 | 
3
 | 
 
 | 
 
 | 
  
3
  
 | 
 
 | 
746
 | 
 use Mojo::File qw(path);  | 
| 
 
 | 
3
 | 
 
 | 
 
 | 
 
 | 
 
 | 
32959
 | 
    | 
| 
 
 | 
3
 | 
 
 | 
 
 | 
 
 | 
 
 | 
176
 | 
    | 
| 
15
 | 
3
 | 
 
 | 
 
 | 
  
3
  
 | 
 
 | 
1266
 | 
 use Import::Into;  | 
| 
 
 | 
3
 | 
 
 | 
 
 | 
 
 | 
 
 | 
5569
 | 
    | 
| 
 
 | 
3
 | 
 
 | 
 
 | 
 
 | 
 
 | 
8749
 | 
    | 
| 
16
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
17
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 our %TOKENS = map { $_=>1 } split/:/, $ENV{OPAN_AUTH_TOKENS} || '';  | 
| 
18
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
19
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 sub cpan_fetch {  | 
| 
20
 | 
5
 | 
 
 | 
 
 | 
  
5
  
 | 
 
 | 
253
 | 
   my $app = shift;  | 
| 
21
 | 
5
 | 
 
 | 
 
 | 
 
 | 
 
 | 
114
 | 
   my $url = Mojo::URL->new(shift)->to_abs($app->cpan_url);  | 
| 
22
 | 
5
 | 
 
 | 
 
 | 
 
 | 
 
 | 
6987
 | 
   my $tx = $app->ua->get($url);  | 
| 
23
 | 
5
 | 
  
100
  
 | 
 
 | 
 
 | 
 
 | 
346631
 | 
   return $tx->res unless my $err = $tx->error;  | 
| 
24
 | 
1
 | 
 
 | 
 
 | 
 
 | 
 
 | 
23
 | 
   die sprintf "%s %s: %s\n", $tx->req->method, $url, $err->{message};  | 
| 
25
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 }  | 
| 
26
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
27
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 sub packages_header {  | 
| 
28
 | 
18
 | 
 
 | 
 
 | 
  
18
  
 | 
 
 | 
139
 | 
   my ($count) = @_;  | 
| 
29
 | 
18
 | 
 
 | 
 
 | 
 
 | 
 
 | 
160
 | 
   (my $str = <<"  HEADER") =~ s/^    //mg;  | 
| 
30
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     File:         02packages.details.txt  | 
| 
31
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     Description:  Package names found in directory \$CPAN/authors/id/  | 
| 
32
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     Columns:      package name, version, path  | 
| 
33
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     Intended-For: Automated fetch routines, namespace documentation.  | 
| 
34
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     Written-By:   App::opan  | 
| 
35
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     Line-Count:   ${count}  | 
| 
36
 | 
18
 | 
 
 | 
 
 | 
 
 | 
 
 | 
425
 | 
     Last-Updated: ${\scalar gmtime} GMT  | 
| 
37
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
38
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
   HEADER  | 
| 
39
 | 
18
 | 
 
 | 
 
 | 
 
 | 
 
 | 
512
 | 
   return $str;  | 
| 
40
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 }  | 
| 
41
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
42
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 sub extract_provides_from_tarball {  | 
| 
43
 | 
5
 | 
 
 | 
 
 | 
  
5
  
 | 
 
 | 
35
 | 
   my ($tarball) = @_;  | 
| 
44
 | 
5
 | 
 
 | 
 
 | 
 
 | 
 
 | 
146
 | 
   Dist::Metadata->new(file => $tarball)->package_versions;  | 
| 
45
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 }  | 
| 
46
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
47
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 sub pod_section {  | 
| 
48
 | 
36
 | 
 
 | 
 
 | 
  
36
  
 | 
 
 | 
106
 | 
   my ($cmd, $for_description) = @_;  | 
| 
49
 | 
36
 | 
 
 | 
 
 | 
 
 | 
 
 | 
126
 | 
   my $fh = fopen __FILE__;  | 
| 
50
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
51
 | 
36
 | 
 
 | 
 
 | 
 
 | 
 
 | 
3581
 | 
   my $pod = '';  | 
| 
52
 | 
36
 | 
  
100
  
 | 
 
 | 
 
 | 
 
 | 
913
 | 
   while (<$fh>) { /^=head3 $cmd\s*$/ && last }  | 
| 
 
 | 
18972
 | 
 
 | 
 
 | 
 
 | 
 
 | 
54016
 | 
    | 
| 
53
 | 
36
 | 
  
 50
  
 | 
  
100
  
 | 
 
 | 
 
 | 
178
 | 
   while (<$fh>) { /^=head/ && last || ($pod .= $_) }  | 
| 
 
 | 
318
 | 
 
 | 
 
 | 
 
 | 
 
 | 
939
 | 
    | 
| 
54
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
55
 | 
36
 | 
  
100
  
 | 
 
 | 
 
 | 
 
 | 
86
 | 
   if ($for_description) {  | 
| 
56
 | 
24
 | 
  
 50
  
 | 
 
 | 
 
 | 
 
 | 
267
 | 
     $pod = $pod =~ m!\n(\S+.*?\.)(?:\s|$)!s ? $1 : "$0 $cmd --help for more info";  | 
| 
57
 | 
24
 | 
 
 | 
 
 | 
 
 | 
 
 | 
110
 | 
     $pod =~ s![\n\r]+! !g;  | 
| 
58
 | 
24
 | 
 
 | 
 
 | 
 
 | 
 
 | 
195
 | 
     $pod =~ s![\s\.]+$!!;  | 
| 
59
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
   }  | 
| 
60
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
61
 | 
36
 | 
 
 | 
 
 | 
 
 | 
 
 | 
308
 | 
   $pod =~ s!\b[CIL]<\/?([^>]+)\>!$1!g; # Remove C<...> pod notation  | 
| 
62
 | 
36
 | 
 
 | 
 
 | 
 
 | 
 
 | 
1750
 | 
   return $pod;  | 
| 
63
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 }  | 
| 
64
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
65
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 sub provides_to_packages_entries {  | 
| 
66
 | 
5
 | 
 
 | 
 
 | 
  
5
  
 | 
 
 | 
276246
 | 
   my ($path, $provides) = @_;  | 
| 
67
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
   # <@mst> ok, I officially have no idea what order 02packages is actually in  | 
| 
68
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
   # <@rjbs>     $list .= join "", sort {lc $a cmp lc $b} @listing02;  | 
| 
69
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
   [  | 
| 
70
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     map +[  | 
| 
71
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
       $_, defined($provides->{$_}) ? $provides->{$_} : 'undef', $path  | 
| 
72
 | 
5
 | 
  
 50
  
 | 
 
 | 
  
4
  
 | 
 
 | 
107
 | 
     ], sort_by { lc } keys %$provides  | 
| 
 
 | 
4
 | 
 
 | 
 
 | 
 
 | 
 
 | 
54
 | 
    | 
| 
73
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
   ]  | 
| 
74
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 }  | 
| 
75
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
76
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 sub entries_from_packages_file {  | 
| 
77
 | 
36
 | 
 
 | 
 
 | 
  
36
  
 | 
 
 | 
53230
 | 
   my ($file) = @_;  | 
| 
78
 | 
36
 | 
 
 | 
 
 | 
 
 | 
 
 | 
307
 | 
   my $fh = fopen $file;  | 
| 
79
 | 
36
 | 
 
 | 
 
 | 
 
 | 
 
 | 
4651
 | 
   while (my $header = <$fh>) {  | 
| 
80
 | 
295
 | 
  
100
  
 | 
 
 | 
 
 | 
 
 | 
1388
 | 
     last if $header =~ /^$/;  | 
| 
81
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
   }  | 
| 
82
 | 
36
 | 
 
 | 
 
 | 
 
 | 
 
 | 
91
 | 
   my @entries;  | 
| 
83
 | 
36
 | 
 
 | 
 
 | 
 
 | 
 
 | 
273
 | 
   while (my $line = <$fh>) {  | 
| 
84
 | 
502632
 | 
 
 | 
 
 | 
 
 | 
 
 | 
697570
 | 
     chomp($line);  | 
| 
85
 | 
502632
 | 
 
 | 
 
 | 
 
 | 
 
 | 
2583695
 | 
     push @entries, [ split /\s+/, $line ];  | 
| 
86
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
   }  | 
| 
87
 | 
36
 | 
 
 | 
 
 | 
 
 | 
 
 | 
811
 | 
   return \@entries;  | 
| 
88
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 }  | 
| 
89
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
90
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 sub merge_packages_entries {  | 
| 
91
 | 
17
 | 
 
 | 
 
 | 
  
17
  
 | 
 
 | 
213
 | 
   my ($base, $merge_these) = @_;  | 
| 
92
 | 
17
 | 
  
 50
  
 | 
 
 | 
 
 | 
 
 | 
82
 | 
   return $base unless $merge_these;  | 
| 
93
 | 
17
 | 
 
 | 
 
 | 
 
 | 
 
 | 
38
 | 
   my @merged;  | 
| 
94
 | 
17
 | 
 
 | 
 
 | 
 
 | 
 
 | 
52
 | 
   my @to_merge = @$merge_these;  | 
| 
95
 | 
17
 | 
 
 | 
 
 | 
 
 | 
 
 | 
170
 | 
   foreach my $idx (0..$#$base) {  | 
| 
96
 | 
1004902
 | 
 
 | 
  
 66
  
 | 
 
 | 
 
 | 
1635012
 | 
     while (@to_merge and lc($to_merge[0][0]) lt lc($base->[$idx][0])) {  | 
| 
97
 | 
  
0
  
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
       push @merged, shift @to_merge;  | 
| 
98
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     }  | 
| 
99
 | 
1004902
 | 
  
100
  
 | 
  
100
  
 | 
 
 | 
 
 | 
2140536
 | 
     push @merged, (  | 
| 
100
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
       (@to_merge and $to_merge[0][0] eq $base->[$idx][0])  | 
| 
101
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
         ? shift @to_merge  | 
| 
102
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
         : $base->[$idx]  | 
| 
103
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     );  | 
| 
104
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
   }  | 
| 
105
 | 
17
 | 
 
 | 
 
 | 
 
 | 
 
 | 
91
 | 
   push @merged, @to_merge;  | 
| 
106
 | 
17
 | 
 
 | 
 
 | 
 
 | 
 
 | 
135
 | 
   return \@merged;  | 
| 
107
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 }  | 
| 
108
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
109
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 sub write_packages_file {  | 
| 
110
 | 
18
 | 
 
 | 
 
 | 
  
18
  
 | 
 
 | 
14748
 | 
   my ($file, $entries) = @_;  | 
| 
111
 | 
18
 | 
 
 | 
 
 | 
 
 | 
 
 | 
230
 | 
   my $fh = fopen $file, 'w';  | 
| 
112
 | 
18
 | 
 
 | 
 
 | 
 
 | 
 
 | 
14978
 | 
   print $fh packages_header(scalar @$entries);  | 
| 
113
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
   local *_ = sub {  | 
| 
114
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     # mirroring 'sub rewrite02 {' in lib/PAUSE/mldistwatch.pm  | 
| 
115
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     # see http://github.com/andk/pause for the whole thing  | 
| 
116
 | 
1004906
 | 
 
 | 
 
 | 
  
1004906
  
 | 
 
 | 
1610703
 | 
     my ($one, $two) = (30, 8);  | 
| 
117
 | 
1004906
 | 
  
100
  
 | 
 
 | 
 
 | 
 
 | 
1573311
 | 
     if (length($_[0]) > $one) {  | 
| 
118
 | 
498056
 | 
 
 | 
 
 | 
 
 | 
 
 | 
609031
 | 
       $one += 8 - length($_[1]);  | 
| 
119
 | 
498056
 | 
 
 | 
 
 | 
 
 | 
 
 | 
550918
 | 
       $two = length($_[1]);  | 
| 
120
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     }  | 
| 
121
 | 
1004906
 | 
 
 | 
 
 | 
 
 | 
 
 | 
3882131
 | 
     sprintf "%-${one}s %${two}s  %s\n", @_;  | 
| 
122
 | 
18
 | 
 
 | 
 
 | 
 
 | 
 
 | 
332
 | 
   };  | 
| 
123
 | 
18
 | 
 
 | 
 
 | 
 
 | 
 
 | 
177
 | 
   print $fh _(@$_) for @$entries;  | 
| 
124
 | 
18
 | 
 
 | 
 
 | 
 
 | 
 
 | 
7401
 | 
   close $fh;  | 
| 
125
 | 
18
 | 
 
 | 
 
 | 
 
 | 
 
 | 
299
 | 
   path("${file}.gz")->spurt(scalar capture(gzip => -c => $file));  | 
| 
126
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 }  | 
| 
127
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
128
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 sub add_dist_to_index {  | 
| 
129
 | 
5
 | 
 
 | 
 
 | 
  
5
  
 | 
 
 | 
521
 | 
   my ($index, $dist) = @_;  | 
| 
130
 | 
5
 | 
 
 | 
 
 | 
 
 | 
 
 | 
47
 | 
   my $existing = entries_from_packages_file($index);  | 
| 
131
 | 
5
 | 
 
 | 
 
 | 
 
 | 
 
 | 
54
 | 
   my ($path) = $dist =~ m{pans/[a-z]+/dists/(.*)};  | 
| 
132
 | 
5
 | 
 
 | 
 
 | 
 
 | 
 
 | 
162
 | 
   write_packages_file(  | 
| 
133
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     $index,  | 
| 
134
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     merge_packages_entries(  | 
| 
135
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
       $existing,  | 
| 
136
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
       provides_to_packages_entries(  | 
| 
137
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
         $path,  | 
| 
138
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
         extract_provides_from_tarball($dist)  | 
| 
139
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
       ),  | 
| 
140
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     )  | 
| 
141
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
   );  | 
| 
142
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 }  | 
| 
143
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
144
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 sub remove_dist_from_index {  | 
| 
145
 | 
1
 | 
 
 | 
 
 | 
  
1
  
 | 
 
 | 
16
 | 
   my ($index, $dist) = @_;  | 
| 
146
 | 
1
 | 
 
 | 
 
 | 
 
 | 
 
 | 
14
 | 
   my $existing = entries_from_packages_file($index);  | 
| 
147
 | 
1
 | 
 
 | 
 
 | 
 
 | 
 
 | 
29
 | 
   my $exclude = qr/\Q${dist}\E$/;  | 
| 
148
 | 
1
 | 
 
 | 
 
 | 
 
 | 
 
 | 
26
 | 
   write_packages_file(  | 
| 
149
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     $index,  | 
| 
150
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     [ grep $_->[2] !~ $exclude, @$existing ],  | 
| 
151
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
   );  | 
| 
152
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 }  | 
| 
153
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
154
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 my @pan_names = qw(upstream custom pinset combined nopin);  | 
| 
155
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
156
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 sub do_init {  | 
| 
157
 | 
2
 | 
 
 | 
 
 | 
  
2
  
 | 
 
 | 
16
 | 
   my ($app) = @_;  | 
| 
158
 | 
2
 | 
 
 | 
 
 | 
 
 | 
 
 | 
14
 | 
   path("pans/$_/dists")->make_path for @pan_names;  | 
| 
159
 | 
2
 | 
 
 | 
 
 | 
 
 | 
 
 | 
2621
 | 
   write_packages_file("pans/$_/index", []) for qw(custom pinset);  | 
| 
160
 | 
2
 | 
 
 | 
 
 | 
 
 | 
 
 | 
14249
 | 
   do_pull($app);  | 
| 
161
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 }  | 
| 
162
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
163
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 sub do_fetch {  | 
| 
164
 | 
2
 | 
 
 | 
 
 | 
  
2
  
 | 
 
 | 
20
 | 
   my ($app) = @_;  | 
| 
165
 | 
2
 | 
 
 | 
 
 | 
 
 | 
 
 | 
141
 | 
   path('pans/upstream/index.gz')->spurt(  | 
| 
166
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     cpan_fetch($app, 'modules/02packages.details.txt.gz')->body  | 
| 
167
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
   );  | 
| 
168
 | 
2
 | 
 
 | 
 
 | 
 
 | 
 
 | 
12664
 | 
   path('pans/upstream/index')->spurt(  | 
| 
169
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     scalar capture qw(gzip -dc), 'pans/upstream/index.gz'  | 
| 
170
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
   );  | 
| 
171
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 }  | 
| 
172
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
173
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 sub do_merge {  | 
| 
174
 | 
4
 | 
 
 | 
 
 | 
  
4
  
 | 
 
 | 
92
 | 
   my ($app) = @_;  | 
| 
175
 | 
4
 | 
 
 | 
 
 | 
 
 | 
 
 | 
69
 | 
   my $upstream = entries_from_packages_file('pans/upstream/index');  | 
| 
176
 | 
4
 | 
 
 | 
 
 | 
 
 | 
 
 | 
47
 | 
   my $pinset = entries_from_packages_file('pans/pinset/index');  | 
| 
177
 | 
4
 | 
 
 | 
 
 | 
 
 | 
 
 | 
34
 | 
   my $custom = entries_from_packages_file('pans/custom/index');  | 
| 
178
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
179
 | 
4
 | 
 
 | 
 
 | 
 
 | 
 
 | 
39
 | 
   my $nopin = merge_packages_entries($upstream, $custom);  | 
| 
180
 | 
4
 | 
 
 | 
 
 | 
 
 | 
 
 | 
27
 | 
   write_packages_file('pans/nopin/index', $nopin);  | 
| 
181
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
182
 | 
4
 | 
 
 | 
 
 | 
 
 | 
 
 | 
1347384
 | 
   my $combined = merge_packages_entries(  | 
| 
183
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
                    $upstream, merge_packages_entries($pinset, $custom)  | 
| 
184
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
                  );  | 
| 
185
 | 
4
 | 
 
 | 
 
 | 
 
 | 
 
 | 
53
 | 
   write_packages_file('pans/combined/index', $combined);  | 
| 
186
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 }  | 
| 
187
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
188
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 sub do_pull {  | 
| 
189
 | 
2
 | 
 
 | 
 
 | 
  
2
  
 | 
 
 | 
35
 | 
   my ($app) = @_;  | 
| 
190
 | 
2
 | 
 
 | 
 
 | 
 
 | 
 
 | 
91
 | 
   do_fetch($app);  | 
| 
191
 | 
2
 | 
 
 | 
 
 | 
 
 | 
 
 | 
380502
 | 
   do_merge($app);  | 
| 
192
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 }  | 
| 
193
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
194
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 sub do_add {  | 
| 
195
 | 
2
 | 
 
 | 
 
 | 
  
2
  
 | 
 
 | 
33
 | 
   my ($app, $path_arg) = @_;  | 
| 
196
 | 
2
 | 
 
 | 
 
 | 
 
 | 
 
 | 
15
 | 
   my $path = path($path_arg);  | 
| 
197
 | 
2
 | 
 
 | 
 
 | 
 
 | 
 
 | 
47
 | 
   my $pan_dir = path('pans/custom/dists/M/MY/MY')->make_path;  | 
| 
198
 | 
2
 | 
  
 50
  
 | 
 
 | 
 
 | 
 
 | 
704
 | 
   $path->copy_to(my $pan_path = $pan_dir->child($path->basename))  | 
| 
199
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     or die "Failed to copy ${path} into custom pan: $!";  | 
| 
200
 | 
2
 | 
 
 | 
 
 | 
 
 | 
 
 | 
1808
 | 
   add_dist_to_index('pans/custom/index', $pan_path);  | 
| 
201
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 }  | 
| 
202
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
203
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 sub do_unadd {  | 
| 
204
 | 
  
0
  
 | 
 
 | 
 
 | 
  
0
  
 | 
 
 | 
0
 | 
   my ($app, $dist) = @_;  | 
| 
205
 | 
  
0
  
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
   remove_dist_from_index('pans/custom/index', $dist);  | 
| 
206
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 }  | 
| 
207
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
208
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 sub do_pin {  | 
| 
209
 | 
3
 | 
 
 | 
 
 | 
  
3
  
 | 
 
 | 
36
 | 
   my ($app, $path_arg) = @_;  | 
| 
210
 | 
3
 | 
  
100
  
 | 
 
 | 
 
 | 
 
 | 
36
 | 
   $path_arg =~ /^(([A-Z])[A-Z])[A-Z]/ and $path_arg = join('/', $2, $1, $path_arg);  | 
| 
211
 | 
3
 | 
 
 | 
 
 | 
 
 | 
 
 | 
15
 | 
   my $path = path($path_arg);  | 
| 
212
 | 
3
 | 
 
 | 
 
 | 
 
 | 
 
 | 
67
 | 
   my $res = cpan_fetch($app, "authors/id/$path");  | 
| 
213
 | 
2
 | 
 
 | 
 
 | 
 
 | 
 
 | 
54
 | 
   path("pans/pinset/dists/")->child($path->dirname)->make_path;  | 
| 
214
 | 
2
 | 
 
 | 
 
 | 
 
 | 
 
 | 
831
 | 
   add_dist_to_index('pans/pinset/index', path("pans/pinset/dists/$path")->spurt($res->body));  | 
| 
215
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 }  | 
| 
216
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
217
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 sub do_unpin {  | 
| 
218
 | 
1
 | 
 
 | 
 
 | 
  
1
  
 | 
 
 | 
17
 | 
   my ($app, $dist) = @_;  | 
| 
219
 | 
1
 | 
 
 | 
 
 | 
 
 | 
 
 | 
6
 | 
   remove_dist_from_index('pans/pinset/index', $dist);  | 
| 
220
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 }  | 
| 
221
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
222
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 sub generate_purgelist {  | 
| 
223
 | 
2
 | 
 
 | 
 
 | 
  
2
  
 | 
 
 | 
117
 | 
   my @list;  | 
| 
224
 | 
2
 | 
 
 | 
 
 | 
 
 | 
 
 | 
8
 | 
   foreach my $pan (qw(pinset custom)) {  | 
| 
225
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     my %indexed = map +("pans/${pan}/dists/".$_->[2] => 1),  | 
| 
226
 | 
4
 | 
 
 | 
 
 | 
 
 | 
 
 | 
16
 | 
                     @{entries_from_packages_file("pans/${pan}/index")};  | 
| 
 
 | 
4
 | 
 
 | 
 
 | 
 
 | 
 
 | 
21
 | 
    | 
| 
227
 | 
4
 | 
 
 | 
 
 | 
 
 | 
 
 | 
759
 | 
     foreach my $file (sort glob "pans/${pan}/dists/*/*/*/*") {  | 
| 
228
 | 
6
 | 
  
100
  
 | 
 
 | 
 
 | 
 
 | 
47
 | 
       push @list, $file unless $indexed{$file};  | 
| 
229
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     }  | 
| 
230
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
   }  | 
| 
231
 | 
2
 | 
 
 | 
 
 | 
 
 | 
 
 | 
191
 | 
   return @list;  | 
| 
232
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 }  | 
| 
233
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
234
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 sub do_purgelist {  | 
| 
235
 | 
1
 | 
 
 | 
 
 | 
  
1
  
 | 
 
 | 
20
 | 
   print "$_\n" for &generate_purgelist;  | 
| 
236
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 }  | 
| 
237
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
238
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 sub do_purge {  | 
| 
239
 | 
1
 | 
 
 | 
 
 | 
  
1
  
 | 
 
 | 
16
 | 
   unlink($_) for &generate_purgelist;  | 
| 
240
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 }  | 
| 
241
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
242
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 sub run_with_server {  | 
| 
243
 | 
  
0
  
 | 
 
 | 
 
 | 
  
0
  
 | 
 
 | 
0
 | 
   my ($app, $run, $pan, @args) = @_;  | 
| 
244
 | 
  
0
  
 | 
  
  0
  
 | 
  
  0
  
 | 
 
 | 
 
 | 
0
 | 
   unless (  | 
| 
245
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     defined($pan) and $pan =~ /^--(combined|nopin|autopin)$/  | 
| 
246
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
   ) {  | 
| 
247
 | 
  
0
  
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
     unshift @args, grep defined, $pan;  | 
| 
248
 | 
  
0
  
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
     $pan = '--combined';  | 
| 
249
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
   }  | 
| 
250
 | 
  
0
  
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
   $pan =~ s/^--//;  | 
| 
251
 | 
  
0
  
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
   require Mojo::IOLoop::Server;  | 
| 
252
 | 
  
0
  
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
   my $port = Mojo::IOLoop::Server->generate_port;  | 
| 
253
 | 
  
0
  
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
   my $url = "http://localhost:${port}/";  | 
| 
254
 | 
  
0
  
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
   my $pid = fork();  | 
| 
255
 | 
  
0
  
 | 
  
  0
  
 | 
 
 | 
 
 | 
 
 | 
0
 | 
   die "fork() fork()ed up: $!" unless defined $pid;  | 
| 
256
 | 
  
0
  
 | 
  
  0
  
 | 
 
 | 
 
 | 
 
 | 
0
 | 
   unless ($pid) {  | 
| 
257
 | 
  
0
  
 | 
  
  0
  
 | 
 
 | 
 
 | 
 
 | 
0
 | 
     $ENV{OPAN_AUTOPIN} = 1 if $pan eq 'autopin';  | 
| 
258
 | 
  
0
  
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
     $app->start(daemon => -l => $url);  | 
| 
259
 | 
  
0
  
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
     exit(0);  | 
| 
260
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
   }  | 
| 
261
 | 
  
0
  
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
   eval { $run->("${url}${pan}", @args) };  | 
| 
 
 | 
  
0
  
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
    | 
| 
262
 | 
  
0
  
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
   my $err = $@;  | 
| 
263
 | 
  
0
  
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
   kill TERM => $pid;  | 
| 
264
 | 
  
0
  
 | 
  
  0
  
 | 
 
 | 
 
 | 
 
 | 
0
 | 
   warn "Run block failed: $err" if $err;  | 
| 
265
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 }  | 
| 
266
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
267
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 sub do_cpanm {  | 
| 
268
 | 
  
0
  
 | 
 
 | 
 
 | 
  
0
  
 | 
 
 | 
0
 | 
   my ($app, @args) = @_;  | 
| 
269
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
   run_with_server($app, sub {  | 
| 
270
 | 
  
0
  
 | 
 
 | 
 
 | 
  
0
  
 | 
 
 | 
0
 | 
     my ($mirror, @args) = @_;  | 
| 
271
 | 
  
0
  
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
     system(cpanm => '--mirror', $mirror, '--mirror-only', @args);  | 
| 
272
 | 
  
0
  
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
   }, @args);  | 
| 
273
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 }  | 
| 
274
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
275
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 sub do_carton {  | 
| 
276
 | 
  
0
  
 | 
 
 | 
 
 | 
  
0
  
 | 
 
 | 
0
 | 
   my ($app, @args) = @_;  | 
| 
277
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
   run_with_server($app, sub {  | 
| 
278
 | 
  
0
  
 | 
 
 | 
 
 | 
  
0
  
 | 
 
 | 
0
 | 
     my ($mirror, @args) = @_;  | 
| 
279
 | 
  
0
  
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
     local $ENV{PERL_CARTON_MIRROR} = $mirror;  | 
| 
280
 | 
  
0
  
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
     system(carton => @args);  | 
| 
281
 | 
0
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
   }, @args);  | 
| 
282
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 }  | 
| 
283
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
284
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 foreach my $cmd (  | 
| 
285
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
   qw(init fetch add unadd pin unpin merge pull purgelist purge cpanm carton)  | 
| 
286
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 ) {  | 
| 
287
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
   my $pkg = "App::opan::Command::${cmd}";  | 
| 
288
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
   my $code = __PACKAGE__->can("do_${cmd}");  | 
| 
289
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
   Mojo::Base->import::into($pkg, 'Mojolicious::Command');  | 
| 
290
 | 
24
 | 
 
 | 
 
 | 
  
24
  
 | 
 
 | 
771
 | 
   monkey_patch $pkg, description => sub { pod_section($cmd, 1) };  | 
| 
 
 | 
 
 | 
 
 | 
 
 | 
  
24
  
 | 
 
 | 
 
 | 
    | 
| 
 
 | 
 
 | 
 
 | 
 
 | 
  
24
  
 | 
 
 | 
 
 | 
    | 
| 
 
 | 
 
 | 
 
 | 
 
 | 
  
24
  
 | 
 
 | 
 
 | 
    | 
| 
 
 | 
 
 | 
 
 | 
 
 | 
  
24
  
 | 
 
 | 
 
 | 
    | 
| 
 
 | 
 
 | 
 
 | 
 
 | 
  
24
  
 | 
 
 | 
 
 | 
    | 
| 
 
 | 
 
 | 
 
 | 
 
 | 
  
24
  
 | 
 
 | 
 
 | 
    | 
| 
 
 | 
 
 | 
 
 | 
 
 | 
  
24
  
 | 
 
 | 
 
 | 
    | 
| 
 
 | 
 
 | 
 
 | 
 
 | 
  
24
  
 | 
 
 | 
 
 | 
    | 
| 
 
 | 
 
 | 
 
 | 
 
 | 
  
24
  
 | 
 
 | 
 
 | 
    | 
| 
 
 | 
 
 | 
 
 | 
 
 | 
  
24
  
 | 
 
 | 
 
 | 
    | 
| 
 
 | 
 
 | 
 
 | 
 
 | 
  
24
  
 | 
 
 | 
 
 | 
    | 
| 
291
 | 
12
 | 
 
 | 
 
 | 
  
12
  
 | 
 
 | 
8718
 | 
   monkey_patch $pkg, usage => sub { pod_section($cmd, 0) };  | 
| 
 
 | 
 
 | 
 
 | 
 
 | 
  
12
  
 | 
 
 | 
 
 | 
    | 
| 
 
 | 
 
 | 
 
 | 
 
 | 
  
12
  
 | 
 
 | 
 
 | 
    | 
| 
 
 | 
 
 | 
 
 | 
 
 | 
  
12
  
 | 
 
 | 
 
 | 
    | 
| 
 
 | 
 
 | 
 
 | 
 
 | 
  
12
  
 | 
 
 | 
 
 | 
    | 
| 
 
 | 
 
 | 
 
 | 
 
 | 
  
12
  
 | 
 
 | 
 
 | 
    | 
| 
 
 | 
 
 | 
 
 | 
 
 | 
  
12
  
 | 
 
 | 
 
 | 
    | 
| 
 
 | 
 
 | 
 
 | 
 
 | 
  
12
  
 | 
 
 | 
 
 | 
    | 
| 
 
 | 
 
 | 
 
 | 
 
 | 
  
12
  
 | 
 
 | 
 
 | 
    | 
| 
 
 | 
 
 | 
 
 | 
 
 | 
  
12
  
 | 
 
 | 
 
 | 
    | 
| 
 
 | 
 
 | 
 
 | 
 
 | 
  
12
  
 | 
 
 | 
 
 | 
    | 
| 
 
 | 
 
 | 
 
 | 
 
 | 
  
12
  
 | 
 
 | 
 
 | 
    | 
| 
292
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
   monkey_patch $pkg,  | 
| 
293
 | 
10
 | 
 
 | 
 
 | 
  
10
  
 | 
 
 | 
71921
 | 
     run => sub { my $self = shift; $code->($self->app, @_) };  | 
| 
 
 | 
10
 | 
 
 | 
 
 | 
  
10
  
 | 
 
 | 
58
 | 
    | 
| 
 
 | 
 
 | 
 
 | 
 
 | 
  
10
  
 | 
 
 | 
 
 | 
    | 
| 
 
 | 
 
 | 
 
 | 
 
 | 
  
10
  
 | 
 
 | 
 
 | 
    | 
| 
 
 | 
 
 | 
 
 | 
 
 | 
  
10
  
 | 
 
 | 
 
 | 
    | 
| 
 
 | 
 
 | 
 
 | 
 
 | 
  
10
  
 | 
 
 | 
 
 | 
    | 
| 
 
 | 
 
 | 
 
 | 
 
 | 
  
10
  
 | 
 
 | 
 
 | 
    | 
| 
 
 | 
 
 | 
 
 | 
 
 | 
  
10
  
 | 
 
 | 
 
 | 
    | 
| 
 
 | 
 
 | 
 
 | 
 
 | 
  
10
  
 | 
 
 | 
 
 | 
    | 
| 
 
 | 
 
 | 
 
 | 
 
 | 
  
10
  
 | 
 
 | 
 
 | 
    | 
| 
 
 | 
 
 | 
 
 | 
 
 | 
  
10
  
 | 
 
 | 
 
 | 
    | 
| 
 
 | 
 
 | 
 
 | 
 
 | 
  
10
  
 | 
 
 | 
 
 | 
    | 
| 
294
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 }  | 
| 
295
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
296
 | 
3
 | 
 
 | 
 
 | 
  
3
  
 | 
 
 | 
1983
 | 
 use Mojolicious::Lite;  | 
| 
 
 | 
3
 | 
 
 | 
 
 | 
 
 | 
 
 | 
720657
 | 
    | 
| 
 
 | 
3
 | 
 
 | 
 
 | 
 
 | 
 
 | 
23
 | 
    | 
| 
297
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
298
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 Mojo::IOLoop->recurring(600 => sub { do_pull(app); }) if $ENV{OPAN_RECURRING_PULL};  | 
| 
299
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
300
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 post "/upload" => sub {  | 
| 
301
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
   my $c = shift;  | 
| 
302
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
   unless ($TOKENS{$c->req->url->to_abs->password || ""}) {  | 
| 
303
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     $c->res->headers->www_authenticate("Basic realm=opan");  | 
| 
304
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     return $c->render(status => 401, text => "Token missing or not found\n");  | 
| 
305
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
   }  | 
| 
306
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
   my $upload = $c->req->upload('dist') || $c->req->upload('pause99_add_uri_httpupload')  | 
| 
307
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     or return $c->render(status => 400, text => "dist file missing\n");  | 
| 
308
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
   my $pan_dir = path('pans/custom/dists/M/MY/MY')->make_path;  | 
| 
309
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
   $upload->move_to(my $pan_path = $pan_dir->child($upload->filename))  | 
| 
310
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     or $c->render(  | 
| 
311
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     status => 500,  | 
| 
312
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     text   => "Failed to move ${upload} into custom pan: $!\n"  | 
| 
313
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     );  | 
| 
314
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
   add_dist_to_index('pans/custom/index', $pan_path);  | 
| 
315
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
   do_merge(app);  | 
| 
316
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
   $c->render(text => "$pan_path Added to opan\n");  | 
| 
317
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 };  | 
| 
318
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
319
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 push(@{app->commands->namespaces}, 'App::opan::Command');  | 
| 
320
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
321
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 helper cpan_url => sub { Mojo::URL->new($ENV{OPAN_MIRROR} || 'https://www.cpan.org/') };  | 
| 
322
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
323
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 my $nopin_static = Mojolicious::Static->new(  | 
| 
324
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
   paths => [ 'pans/custom/dists' ]  | 
| 
325
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 );  | 
| 
326
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
327
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 my $pinset_static = Mojolicious::Static->new(  | 
| 
328
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
   paths => [ 'pans/pinset/dists' ]  | 
| 
329
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 );  | 
| 
330
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
331
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 my $combined_static = Mojolicious::Static->new(  | 
| 
332
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
   paths => [ 'pans/custom/dists', 'pans/pinset/dists' ]  | 
| 
333
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 );  | 
| 
334
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
335
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 my $base_static = Mojolicious::Static->new(  | 
| 
336
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
   paths => [ 'pans' ]  | 
| 
337
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 );  | 
| 
338
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
339
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 foreach my $pan (qw(upstream nopin combined pinset custom)) {  | 
| 
340
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
   get "/${pan}/modules/02packages.details.txt" => sub {  | 
| 
341
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     $base_static->dispatch($_[0]->stash(path => "${pan}/index"));  | 
| 
342
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
   };  | 
| 
343
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
   get "/${pan}/modules/02packages.details.txt.gz" => sub {  | 
| 
344
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     $base_static->dispatch($_[0]->stash(path => "${pan}/index.gz"));  | 
| 
345
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
   };  | 
| 
346
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 }  | 
| 
347
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
348
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 my $serve_upstream = sub {  | 
| 
349
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
   my ($c) = @_;  | 
| 
350
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
   $c->render_later;  | 
| 
351
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
   $c->ua->get(  | 
| 
352
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     $c->cpan_url.'authors/id/'.$c->stash->{dist_path},  | 
| 
353
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
       sub {  | 
| 
354
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
       my (undef, $tx) = @_;  | 
| 
355
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
         $c->tx->res($tx->res);  | 
| 
356
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
       $c->rendered;  | 
| 
357
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     }  | 
| 
358
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
   );  | 
| 
359
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
   return;  | 
| 
360
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 };  | 
| 
361
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
362
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 get '/upstream/authors/id/*dist_path' => $serve_upstream;  | 
| 
363
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
364
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 get '/combined/authors/id/*dist_path' => sub {  | 
| 
365
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
   $_[0]->stash(path => $_[0]->stash->{dist_path});  | 
| 
366
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
   $combined_static->dispatch($_[0]) or $serve_upstream->($_[0]);  | 
| 
367
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 };  | 
| 
368
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
369
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 get '/nopin/authors/id/*dist_path' => sub {  | 
| 
370
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
   $_[0]->stash(path => $_[0]->stash->{dist_path});  | 
| 
371
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
   $nopin_static->dispatch($_[0]) or $serve_upstream->($_[0]);  | 
| 
372
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 };  | 
| 
373
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
374
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 get "/autopin/modules/02packages.details.txt" => sub {  | 
| 
375
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
   return $_[0]->render(text => 'Autopin off', status => 404)  | 
| 
376
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     unless $ENV{OPAN_AUTOPIN};  | 
| 
377
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
   $base_static->dispatch($_[0]->stash(path => "nopin/index"));  | 
| 
378
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 };  | 
| 
379
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
380
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 get "/autopin/modules/02packages.details.txt.gz" => sub {  | 
| 
381
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
   return $_[0]->render(text => 'Autopin off', status => 404)  | 
| 
382
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     unless $ENV{OPAN_AUTOPIN};  | 
| 
383
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
   $base_static->dispatch($_[0]->stash(path => "nopin/index.gz"));  | 
| 
384
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 };  | 
| 
385
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
386
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 get '/autopin/authors/id/*dist_path' => sub {  | 
| 
387
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
   return $_[0]->render(text => 'Autopin off', status => 404)  | 
| 
388
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     unless $ENV{OPAN_AUTOPIN};  | 
| 
389
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
   return if $nopin_static->dispatch($_[0]->stash(path => $_[0]->stash->{dist_path}));  | 
| 
390
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
   return if eval {  | 
| 
391
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     do_pin(app, $_[0]->stash->{path});  | 
| 
392
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     $pinset_static->dispatch($_[0]);  | 
| 
393
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
   };  | 
| 
394
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
   return $_[0]->render(text => 'Not found', status => 404);  | 
| 
395
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 };  | 
| 
396
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
397
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 caller() ? app : app->tap(sub { shift->log->level('fatal') })->start;  | 
| 
398
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
399
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 =head1 NAME  | 
| 
400
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
401
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 App::opan - A CPAN overlay for darkpan and pinning purposes  | 
| 
402
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
403
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 =head1 SYNOPSIS  | 
| 
404
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
405
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 Set up an opan (creates a directory tree in C):  | 
| 
406
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
407
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
   $ opan init  | 
| 
408
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
   $ opan pin MSTROUT/M-1.tar.gz  | 
| 
409
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
   $ opan add ./My-Dist-1.23.tar.gz  | 
| 
410
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
411
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 Now, you can start the server:  | 
| 
412
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
413
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
   $ opan daemon -l http://localhost:8030/  | 
| 
414
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
   Server available at http://localhost:8030/  | 
| 
415
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
416
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 Then in another terminal, run one of:  | 
| 
417
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
418
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
   $ cpanm --mirror http://localhost:8030/combined/ --mirror-only --installdeps .  | 
| 
419
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
   $ PERL_CARTON_MIRROR=http://localhost:8030/combined/ carton install  | 
| 
420
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
421
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 Or, to let opan do that part for you, skip starting the server and run one of:  | 
| 
422
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
423
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
   $ opan cpanm --installdeps .  | 
| 
424
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
   $ opan carton install  | 
| 
425
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
426
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 =head1 DESCRIPTION  | 
| 
427
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
428
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 Two basic approaches to using this thing. First, if you're using carton, you  | 
| 
429
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 can probably completely ignore the pinning system, so just do:  | 
| 
430
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
431
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
   $ opan init  | 
| 
432
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
   $ opan add ./My-DarkPan-Dist-1.23.tar.gz  | 
| 
433
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
   $ git add pans/; git commit -m 'fresh opan'  | 
| 
434
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
   $ opan carton install  | 
| 
435
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
436
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 You can reproduce this install with simply:  | 
| 
437
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
438
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
   $ opan carton install --deployment  | 
| 
439
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
440
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 When you want to update to a new version of the cpan index (assuming you  | 
| 
441
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 already have an additional requirement that's too old in your current  | 
| 
442
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 snapshot):  | 
| 
443
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
444
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
   $ opan pull  | 
| 
445
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
   $ git add pans/; git commit -m 'update pans'  | 
| 
446
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
   $ opan carton install  | 
| 
447
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
448
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 Second, if you're not using carton, but you want reproducible installs, you  | 
| 
449
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 can still mostly ignore the pinning system by doing:  | 
| 
450
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
451
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
   $ opan init  | 
| 
452
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
   $ opan add ./My-DarkPan-Dist-1.23.tar.gz  | 
| 
453
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
   $ opan cpanm --autopin --installdeps .  | 
| 
454
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
   $ git add pans/; git commit -m 'opan with current version pinning'  | 
| 
455
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
456
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 Your reproducible install is now:  | 
| 
457
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
458
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
   $ opan cpanm --installdeps .  | 
| 
459
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
460
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 When you want to update to a new version of the cpan index (assuming you  | 
| 
461
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 already have an additional requirement that's too old in your current  | 
| 
462
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 snapshot):  | 
| 
463
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
464
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
   $ opan pull  | 
| 
465
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
   $ opan cpanm --autopin --installdeps .  | 
| 
466
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
   $ git add pans/; git commit -m 'update pans'  | 
| 
467
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
468
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 To update a single dist in this system, the easy route is:  | 
| 
469
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
470
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
   $ opan unpin Thingy-1.23.tar.gz  | 
| 
471
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
   $ opan cpanm Thingy  | 
| 
472
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
   Fetching http://www.cpan.org/authors/id/S/SO/SOMEONE/Thingy-1.25.tar.gz  | 
| 
473
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
   ...  | 
| 
474
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
   $ opan pin SOMEONE/Thing-1.25.tar.gz  | 
| 
475
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
476
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 This will probably make more sense if you read the L and L  | 
| 
477
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 documentation following before trying to set things up.  | 
| 
478
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
479
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 =head2 Commands  | 
| 
480
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
481
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 =head3 init  | 
| 
482
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
483
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
   opan init  | 
| 
484
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
485
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 Creates a C directory with empty indexes for L and L  | 
| 
486
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 and a fresh index for L (i.e. runs L for you at the end  | 
| 
487
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 of initialisation).  | 
| 
488
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
489
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 =head3 fetch  | 
| 
490
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
491
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
   opan fetch  | 
| 
492
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
493
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 Fetches 02packages from www.cpan.org into the L PAN.  | 
| 
494
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
495
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 =head3 add  | 
| 
496
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
497
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
   opan add Dist-Name-1.23.tar.gz  | 
| 
498
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
499
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 Imports a distribution file into the L PAN under author C. Any  | 
| 
500
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 path parts provided before the filename will be stripped.  | 
| 
501
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
502
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 Support for other authors is pending somebody explaining why that would have  | 
| 
503
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 a point. See L for the command you probably wanted instead.  | 
| 
504
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
505
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 =head3 unadd  | 
| 
506
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
507
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
   opan unadd Dist-Name-1.23.tar.gz  | 
| 
508
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
509
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 Looks for a C path in the L PAN index  | 
| 
510
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 and removes the entries.  | 
| 
511
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
512
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 Does not remove the dist file, see L.  | 
| 
513
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
514
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 =head3 pin  | 
| 
515
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
516
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
   opan pin AUTHOR/Dist-Name-1.23.tar.gz  | 
| 
517
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
518
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 Fetches the file from the L PAN and adds it to L.  | 
| 
519
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
520
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 =head3 unpin  | 
| 
521
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
522
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
   opan unpin Dist-Name-1.23.tar.gz  | 
| 
523
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
524
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 Looks for a C path in the L PAN index  | 
| 
525
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 and removes the entries.  | 
| 
526
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
527
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 Does not remove the dist file, see L.  | 
| 
528
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
529
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 =head3 merge  | 
| 
530
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
531
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
   opan merge  | 
| 
532
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
533
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 Rebuilds the L and L PANs' index files.  | 
| 
534
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
535
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 =head3 pull  | 
| 
536
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
537
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
   opan pull  | 
| 
538
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
539
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 Does a L and then a L. There's no equivalent for others,  | 
| 
540
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 on the assumption what you'll do is roughly L, L, L,  | 
| 
541
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 L, ... repeat ..., L.  | 
| 
542
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
543
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 =head3 purgelist  | 
| 
544
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
545
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
   opan purgelist  | 
| 
546
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
547
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 Outputs a list of all non-indexed dists in L and L.  | 
| 
548
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
549
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 =head3 purge  | 
| 
550
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
551
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
   opan purge  | 
| 
552
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
553
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 Deletes all files that would have been listed by L.  | 
| 
554
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
555
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 =head3 daemon  | 
| 
556
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
557
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
   opan daemon  | 
| 
558
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
559
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 Starts a single process server using L.  | 
| 
560
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
561
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 =head3 prefork  | 
| 
562
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
563
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
   opan prefork  | 
| 
564
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
565
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 Starts a multi-process preforking server using  | 
| 
566
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 L.  | 
| 
567
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
568
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 =head3 get  | 
| 
569
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
570
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
   opan get /upstream/modules/02packages.details.txt.gz  | 
| 
571
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
572
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 Runs a request against the opan URL space using L.  | 
| 
573
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
574
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 =head3 cpanm  | 
| 
575
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
576
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
   opan cpanm --installdeps .  | 
| 
577
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
578
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 Starts a temporary server process and runs cpanm.  | 
| 
579
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
580
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
   cpanm --mirror http://localhost:/combined/ --mirror-only   | 
| 
581
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
582
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 Can also be run with one of:  | 
| 
583
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
584
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
   opan cpanm --nopin   | 
| 
585
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
   opan cpanm --autopin   | 
| 
586
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
   opan cpanm --combined   | 
| 
587
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
588
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 to request a specific PAN.  | 
| 
589
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
590
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 =head3 carton  | 
| 
591
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
592
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
   opan carton install  | 
| 
593
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
594
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 Starts a temporary server process and runs carton.  | 
| 
595
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
596
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
   PERL_CARTON_MIRROR=http://localhost:/combined/ carton   | 
| 
597
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
598
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 Can also be run with one of:  | 
| 
599
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
600
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
   opan carton --nopin   | 
| 
601
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
   opan carton --autopin   | 
| 
602
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
   opan carton --combined   | 
| 
603
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
604
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 to request a specific PAN.  | 
| 
605
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
606
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 =head2 PANs  | 
| 
607
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
608
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 =head3 upstream  | 
| 
609
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
610
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 02packages: Fetched from www.cpan.org by the L command.  | 
| 
611
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
612
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 Dist files: Fetched from www.cpan.org on-demand.  | 
| 
613
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
614
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 =head3 pinset  | 
| 
615
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
616
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 02packages: Managed by L and L commands.  | 
| 
617
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
618
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 Dist files: Fetched from www.cpan.org by L command.  | 
| 
619
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
620
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 =head3 custom  | 
| 
621
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
622
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 02packages: Managed by L and L commands.  | 
| 
623
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
624
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 Dist files: Imported from local disk by L command.  | 
| 
625
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
626
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 =head3 combined  | 
| 
627
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
628
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 02packages: Merged from upstream, pinset and custom PANs by L command.  | 
| 
629
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
630
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 Dist files: Fetched from custom, pinset and upstream in that order.  | 
| 
631
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
632
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 =head3 nopin  | 
| 
633
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
634
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 02packages: Merged from upstream and custom PANs by L command.  | 
| 
635
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
636
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 Dist files: Fetched from custom, pinset and upstream in that order.  | 
| 
637
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
638
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 =head3 autopin  | 
| 
639
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
640
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 Virtual PAN with no presence on disk.  | 
| 
641
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
642
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 Identical to nopin, but fetching a dist from upstream does an implict L.  | 
| 
643
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
644
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 Since this can modify your opan config, it's only enabled if the environment  | 
| 
645
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 variable C is set to a true value (calling the L or  | 
| 
646
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 L commands with C<--autopin> sets this for you, because you already  | 
| 
647
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 specified you wanted that).  | 
| 
648
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
649
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 =head2 uploads  | 
| 
650
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
651
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 To enable the /upload endpoint, set the ENV var OPAN_AUTH_TOKENS to a colon  | 
| 
652
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 separated list of accepted tokens for uploads. This will allow a post with a  | 
| 
653
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 'file' upload argument, checking http basic auth password against the provided  | 
| 
654
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 auth tokens.  | 
| 
655
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
656
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 =head2 recurring pull  | 
| 
657
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
658
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 Set ENV OPAN_RECURRING_PULL to a true value to make opan automatically pull  | 
| 
659
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 from upstream every 600 seconds  | 
| 
660
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
661
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 =head2 custom upstream  | 
| 
662
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
663
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 Set the ENV var OPAN_MIRROR to specify a cpan mirror - the default is  | 
| 
664
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 www.cpan.org. Remember that if you need to temporarily overlay your overlay  | 
| 
665
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 but only for one user, there's nothing stopping you setting OPAN_MIRROR to  | 
| 
666
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 another opan.  | 
| 
667
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
668
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 =head1 AUTHOR  | 
| 
669
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
670
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 Matt S. Trout (mst)   | 
| 
671
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
672
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 =head1 CONTRIBUTORS  | 
| 
673
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
674
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 Aaron Crane (arc)   | 
| 
675
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
676
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 Marcus Ramburg (marcus)   | 
| 
677
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
678
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 =head1 COPYRIGHT  | 
| 
679
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
680
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 Copyright (c) 2016-2018 the L L and L  | 
| 
681
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 as listed above.  | 
| 
682
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
683
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 =head1 LICENSE  | 
| 
684
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
685
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 This library is free software and may be distributed under the same terms  | 
| 
686
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 as perl itself.  | 
| 
687
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
688
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 =cut  |