line |
stmt |
bran |
cond |
sub |
pod |
time |
code |
1
|
|
|
|
|
|
|
package PAR::Repository; |
2
|
|
|
|
|
|
|
|
3
|
7
|
|
|
7
|
|
175055
|
use 5.006; |
|
7
|
|
|
|
|
30
|
|
|
7
|
|
|
|
|
270
|
|
4
|
7
|
|
|
7
|
|
36
|
use strict; |
|
7
|
|
|
|
|
14
|
|
|
7
|
|
|
|
|
237
|
|
5
|
7
|
|
|
7
|
|
30
|
use warnings; |
|
7
|
|
|
|
|
18
|
|
|
7
|
|
|
|
|
252
|
|
6
|
|
|
|
|
|
|
|
7
|
7
|
|
|
7
|
|
35
|
use Carp qw/croak/; |
|
7
|
|
|
|
|
14
|
|
|
7
|
|
|
|
|
556
|
|
8
|
7
|
|
|
7
|
|
12648
|
use File::Spec::Functions qw/catfile catdir splitpath/; |
|
7
|
|
|
|
|
6139
|
|
|
7
|
|
|
|
|
534
|
|
9
|
7
|
|
|
7
|
|
41
|
use File::Path qw/mkpath/; |
|
7
|
|
|
|
|
14
|
|
|
7
|
|
|
|
|
427
|
|
10
|
7
|
|
|
7
|
|
6846
|
use PAR::Dist qw//; |
|
7
|
|
|
|
|
56098
|
|
|
7
|
|
|
|
|
194
|
|
11
|
7
|
|
|
7
|
|
6193
|
use YAML::Syck qw//; |
|
7
|
|
|
|
|
15709
|
|
|
7
|
|
|
|
|
146
|
|
12
|
7
|
|
|
7
|
|
6615
|
use File::Copy qw//; |
|
7
|
|
|
|
|
41146
|
|
|
7
|
|
|
|
|
211
|
|
13
|
7
|
|
|
7
|
|
131
|
use Cwd qw//; |
|
7
|
|
|
|
|
13
|
|
|
7
|
|
|
|
|
114
|
|
14
|
7
|
|
|
7
|
|
7599
|
use Archive::Zip qw//; |
|
7
|
|
|
|
|
614024
|
|
|
7
|
|
|
|
|
186
|
|
15
|
7
|
|
|
7
|
|
72
|
use File::Temp qw//; |
|
7
|
|
|
|
|
12
|
|
|
7
|
|
|
|
|
111
|
|
16
|
7
|
|
|
7
|
|
5581
|
use version qw//; |
|
7
|
|
|
|
|
14713
|
|
|
7
|
|
|
|
|
183
|
|
17
|
7
|
|
|
7
|
|
12317
|
use PAR::Indexer qw//; |
|
0
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
18
|
|
|
|
|
|
|
|
19
|
|
|
|
|
|
|
use PAR::Repository::Zip; |
20
|
|
|
|
|
|
|
use PAR::Repository::DBM; |
21
|
|
|
|
|
|
|
use PAR::Repository::Query; |
22
|
|
|
|
|
|
|
our @ISA = qw( |
23
|
|
|
|
|
|
|
PAR::Repository::Zip |
24
|
|
|
|
|
|
|
PAR::Repository::DBM |
25
|
|
|
|
|
|
|
PAR::Repository::Query |
26
|
|
|
|
|
|
|
); |
27
|
|
|
|
|
|
|
|
28
|
|
|
|
|
|
|
use constant REPOSITORY_INFO_FILE => 'repository_info.yml'; |
29
|
|
|
|
|
|
|
|
30
|
|
|
|
|
|
|
our $VERSION = '0.21'; |
31
|
|
|
|
|
|
|
our $VERBOSE = 0; |
32
|
|
|
|
|
|
|
|
33
|
|
|
|
|
|
|
# does the running platform have symlinks? |
34
|
|
|
|
|
|
|
our $Supports_Symlinks = |
35
|
|
|
|
|
|
|
exists($ENV{PAR_REPOSITORY_SYMLINK_SUPPORT}) |
36
|
|
|
|
|
|
|
? $ENV{PAR_REPOSITORY_SYMLINK_SUPPORT} |
37
|
|
|
|
|
|
|
: eval { symlink("",""); 1 }; |
38
|
|
|
|
|
|
|
|
39
|
|
|
|
|
|
|
# template for a repository_info.yml file |
40
|
|
|
|
|
|
|
our $Info_Template = { |
41
|
|
|
|
|
|
|
repository_version => $VERSION, |
42
|
|
|
|
|
|
|
# on platforms which don't have symlinks, fake them for new repositories! |
43
|
|
|
|
|
|
|
($Supports_Symlinks ? () : (fake_symlinks => 1)), |
44
|
|
|
|
|
|
|
}; |
45
|
|
|
|
|
|
|
|
46
|
|
|
|
|
|
|
# Hash of compatible PAR::Repository versions |
47
|
|
|
|
|
|
|
our $Compatible_Versions = { |
48
|
|
|
|
|
|
|
$VERSION => 1, |
49
|
|
|
|
|
|
|
'0.19'=> 1, |
50
|
|
|
|
|
|
|
'0.18_01'=> 1, |
51
|
|
|
|
|
|
|
'0.17_01'=> 1, |
52
|
|
|
|
|
|
|
'0.17'=> 1, |
53
|
|
|
|
|
|
|
'0.16_02' => 1, |
54
|
|
|
|
|
|
|
'0.16_01' => 1, |
55
|
|
|
|
|
|
|
'0.16' => 1, |
56
|
|
|
|
|
|
|
'0.15' => 1, |
57
|
|
|
|
|
|
|
'0.14' => 1, |
58
|
|
|
|
|
|
|
'0.13' => 1, |
59
|
|
|
|
|
|
|
'0.12' => 1, |
60
|
|
|
|
|
|
|
'0.11' => 1, |
61
|
|
|
|
|
|
|
'0.10' => 1, |
62
|
|
|
|
|
|
|
'0.03' => 1, |
63
|
|
|
|
|
|
|
'0.02' => 1, |
64
|
|
|
|
|
|
|
}; |
65
|
|
|
|
|
|
|
|
66
|
|
|
|
|
|
|
=head1 NAME |
67
|
|
|
|
|
|
|
|
68
|
|
|
|
|
|
|
PAR::Repository - Create and modify PAR repositories |
69
|
|
|
|
|
|
|
|
70
|
|
|
|
|
|
|
=head1 SYNOPSIS |
71
|
|
|
|
|
|
|
|
72
|
|
|
|
|
|
|
# Usually, you want to use the 'parrepo' script which comes with |
73
|
|
|
|
|
|
|
# this distribution. |
74
|
|
|
|
|
|
|
use PAR::Repository; |
75
|
|
|
|
|
|
|
|
76
|
|
|
|
|
|
|
my $repo = PAR::Repository->new( path => '/path/to/repository' ); |
77
|
|
|
|
|
|
|
# creates a new repository if it doesn't exist, opens it if it |
78
|
|
|
|
|
|
|
# does exist. |
79
|
|
|
|
|
|
|
|
80
|
|
|
|
|
|
|
$repo->inject( |
81
|
|
|
|
|
|
|
file => 'Foo-Bar-0.01-x86_64-linux-gnu-thread-multi-5.8.7.par' |
82
|
|
|
|
|
|
|
); |
83
|
|
|
|
|
|
|
$repo->remove( |
84
|
|
|
|
|
|
|
file => '...' |
85
|
|
|
|
|
|
|
); |
86
|
|
|
|
|
|
|
$repo->query_module(regex => 'Foo::Bar'); |
87
|
|
|
|
|
|
|
|
88
|
|
|
|
|
|
|
=head1 DESCRIPTION |
89
|
|
|
|
|
|
|
|
90
|
|
|
|
|
|
|
This module is intended for creation and maintenance of PAR repositories. |
91
|
|
|
|
|
|
|
A PAR repository is collection of F<.par> archives which contain Perl code |
92
|
|
|
|
|
|
|
and associated libraries for use on specific platforms. In the most common |
93
|
|
|
|
|
|
|
case, these archives differ from CPAN distributions in that they ship the |
94
|
|
|
|
|
|
|
(possibly compiled) output of C in the F subdirectory of the |
95
|
|
|
|
|
|
|
CPAN distribution's build directory. |
96
|
|
|
|
|
|
|
|
97
|
|
|
|
|
|
|
You can access a PAR repository using the L module |
98
|
|
|
|
|
|
|
or the L module which provides syntactic sugar around the client. |
99
|
|
|
|
|
|
|
L allows you to load libraries from repositories on demand. |
100
|
|
|
|
|
|
|
|
101
|
|
|
|
|
|
|
=head2 PAR REPOSITORIES |
102
|
|
|
|
|
|
|
|
103
|
|
|
|
|
|
|
A PAR repository is, basically, just a directory with certain stuff in it. |
104
|
|
|
|
|
|
|
It contains: |
105
|
|
|
|
|
|
|
|
106
|
|
|
|
|
|
|
=over 2 |
107
|
|
|
|
|
|
|
|
108
|
|
|
|
|
|
|
=item modules_dists.dbm.zip |
109
|
|
|
|
|
|
|
|
110
|
|
|
|
|
|
|
An index that maps module names to file names. |
111
|
|
|
|
|
|
|
Details can be found in L. |
112
|
|
|
|
|
|
|
|
113
|
|
|
|
|
|
|
=item symlinks.dbm.zip |
114
|
|
|
|
|
|
|
|
115
|
|
|
|
|
|
|
An index that maps file names to other files. You shouldn't have to care |
116
|
|
|
|
|
|
|
about it. |
117
|
|
|
|
|
|
|
Details can be found in L. |
118
|
|
|
|
|
|
|
|
119
|
|
|
|
|
|
|
=item scripts_dists.dbm.zip |
120
|
|
|
|
|
|
|
|
121
|
|
|
|
|
|
|
An index that maps script names to file names. |
122
|
|
|
|
|
|
|
Details can be found in L. |
123
|
|
|
|
|
|
|
|
124
|
|
|
|
|
|
|
=item repository_info.yml |
125
|
|
|
|
|
|
|
|
126
|
|
|
|
|
|
|
A simple YAML file which contains meta information for the repository. |
127
|
|
|
|
|
|
|
It currently contains the following bits of information: |
128
|
|
|
|
|
|
|
|
129
|
|
|
|
|
|
|
=item dbm_checksums.txt |
130
|
|
|
|
|
|
|
|
131
|
|
|
|
|
|
|
A text file associating the DBM files with their MD5 checksums. (new in 0.15) |
132
|
|
|
|
|
|
|
|
133
|
|
|
|
|
|
|
=over 2 |
134
|
|
|
|
|
|
|
|
135
|
|
|
|
|
|
|
=item repository_version |
136
|
|
|
|
|
|
|
|
137
|
|
|
|
|
|
|
The version of PAR::Repository this repository was created with. |
138
|
|
|
|
|
|
|
When opening an existing repository, PAR::Repository checks that the |
139
|
|
|
|
|
|
|
repository was created by a compatible PAR::Repository version. |
140
|
|
|
|
|
|
|
|
141
|
|
|
|
|
|
|
Similarily, PAR::Repository::Client checks that the repository has |
142
|
|
|
|
|
|
|
a compatible version. |
143
|
|
|
|
|
|
|
|
144
|
|
|
|
|
|
|
=back |
145
|
|
|
|
|
|
|
|
146
|
|
|
|
|
|
|
=item I directories |
147
|
|
|
|
|
|
|
|
148
|
|
|
|
|
|
|
Your system architecture is identified with a certain string. |
149
|
|
|
|
|
|
|
For example, my development box is C. |
150
|
|
|
|
|
|
|
For every such architecture for which there are PAR archives |
151
|
|
|
|
|
|
|
in the repository, there is a directory with the name of the |
152
|
|
|
|
|
|
|
architecture. |
153
|
|
|
|
|
|
|
|
154
|
|
|
|
|
|
|
There is one special directory called C which is meant |
155
|
|
|
|
|
|
|
for PAR archives that are architecture independent. (Usually |
156
|
|
|
|
|
|
|
I modules.) |
157
|
|
|
|
|
|
|
|
158
|
|
|
|
|
|
|
In every such architecture directory, there is a number of directories |
159
|
|
|
|
|
|
|
for every Perl version. (5.6.0, 5.6.1, 5.8.0, ...) |
160
|
|
|
|
|
|
|
Again, there is a special directory for modules |
161
|
|
|
|
|
|
|
that work with any version of Perl. |
162
|
|
|
|
|
|
|
This directory is called C. |
163
|
|
|
|
|
|
|
|
164
|
|
|
|
|
|
|
Of course, a module won't run with Perl 4 and probably not even with |
165
|
|
|
|
|
|
|
5.001. Whether a module works with I of perl is something |
166
|
|
|
|
|
|
|
you need to decide when injecting modules into the repository and depends |
167
|
|
|
|
|
|
|
on the scope of the repository. |
168
|
|
|
|
|
|
|
|
169
|
|
|
|
|
|
|
These inner directories contain the PAR archives. The directories exist |
170
|
|
|
|
|
|
|
mostly because large repositories with a lot of modules for a lot of |
171
|
|
|
|
|
|
|
architectures would otherwise have too large directory lists. |
172
|
|
|
|
|
|
|
|
173
|
|
|
|
|
|
|
=item PAR archives |
174
|
|
|
|
|
|
|
|
175
|
|
|
|
|
|
|
Within the I directories come the actual PAR archives. |
176
|
|
|
|
|
|
|
The name of each such file is of the following form: |
177
|
|
|
|
|
|
|
|
178
|
|
|
|
|
|
|
I-I-I-I.par |
179
|
|
|
|
|
|
|
|
180
|
|
|
|
|
|
|
=back |
181
|
|
|
|
|
|
|
|
182
|
|
|
|
|
|
|
=head1 METHODS |
183
|
|
|
|
|
|
|
|
184
|
|
|
|
|
|
|
Following is a list of class and instance methods. |
185
|
|
|
|
|
|
|
(Instance methods until otherwise mentioned.) |
186
|
|
|
|
|
|
|
|
187
|
|
|
|
|
|
|
Other methods callable on C objects are inherited |
188
|
|
|
|
|
|
|
from classes listed in the I section. |
189
|
|
|
|
|
|
|
|
190
|
|
|
|
|
|
|
=cut |
191
|
|
|
|
|
|
|
|
192
|
|
|
|
|
|
|
=head2 new |
193
|
|
|
|
|
|
|
|
194
|
|
|
|
|
|
|
Creates a new PAR::Repository object. Takes named arguments. |
195
|
|
|
|
|
|
|
|
196
|
|
|
|
|
|
|
Mandatory paramater: |
197
|
|
|
|
|
|
|
|
198
|
|
|
|
|
|
|
C should be the path to the |
199
|
|
|
|
|
|
|
PAR repository. If the repository does not exist yet, it |
200
|
|
|
|
|
|
|
is created empty. If the repository exists, it is I. |
201
|
|
|
|
|
|
|
That means any modifications you apply to the repository object |
202
|
|
|
|
|
|
|
are applied to the I repository on disk. |
203
|
|
|
|
|
|
|
|
204
|
|
|
|
|
|
|
Optional parameters: |
205
|
|
|
|
|
|
|
|
206
|
|
|
|
|
|
|
Additionally, you may supply the C 1> |
207
|
|
|
|
|
|
|
or C 1> parameters. Both default to |
208
|
|
|
|
|
|
|
false. I will convert an existing repository |
209
|
|
|
|
|
|
|
that uses symbolic links to using no symbolic links as if it |
210
|
|
|
|
|
|
|
had been created with the I option. |
211
|
|
|
|
|
|
|
If the repository has to be created, I |
212
|
|
|
|
|
|
|
flags it as using no symbolic links. Copies will be used instead. |
213
|
|
|
|
|
|
|
this may result is a larger but more portable repository. |
214
|
|
|
|
|
|
|
I implies I. See also I below. |
215
|
|
|
|
|
|
|
|
216
|
|
|
|
|
|
|
I is the default for creating new repositories |
217
|
|
|
|
|
|
|
on platforms which do not support symlinks. |
218
|
|
|
|
|
|
|
|
219
|
|
|
|
|
|
|
=cut |
220
|
|
|
|
|
|
|
|
221
|
|
|
|
|
|
|
sub new { |
222
|
|
|
|
|
|
|
my $proto = shift; |
223
|
|
|
|
|
|
|
my $class = ref($proto) || $proto; |
224
|
|
|
|
|
|
|
|
225
|
|
|
|
|
|
|
croak(__PACKAGE__."->new() takes an even number of arguments.") |
226
|
|
|
|
|
|
|
if @_ % 2; |
227
|
|
|
|
|
|
|
my %args = @_; |
228
|
|
|
|
|
|
|
|
229
|
|
|
|
|
|
|
croak(__PACKAGE__."->new() needs a 'path' argument.") |
230
|
|
|
|
|
|
|
if not defined $args{path}; |
231
|
|
|
|
|
|
|
|
232
|
|
|
|
|
|
|
my $path = $args{path}; |
233
|
|
|
|
|
|
|
my $self = bless { |
234
|
|
|
|
|
|
|
path => $path, |
235
|
|
|
|
|
|
|
|
236
|
|
|
|
|
|
|
# The tied dbm hashes |
237
|
|
|
|
|
|
|
modules_hash => undef, |
238
|
|
|
|
|
|
|
symlinks_hash => undef, |
239
|
|
|
|
|
|
|
scripts_hash => undef, |
240
|
|
|
|
|
|
|
dependencies_hash => undef, |
241
|
|
|
|
|
|
|
|
242
|
|
|
|
|
|
|
# The temp dbm files on disk |
243
|
|
|
|
|
|
|
modules_dbm_temp_file => undef, |
244
|
|
|
|
|
|
|
symlinks_dbm_temp_file => undef, |
245
|
|
|
|
|
|
|
scripts_dbm_temp_file => undef, |
246
|
|
|
|
|
|
|
dependencies_dbm_temp_file => undef, |
247
|
|
|
|
|
|
|
|
248
|
|
|
|
|
|
|
# The YAML info as Perl data structure |
249
|
|
|
|
|
|
|
info => undef, |
250
|
|
|
|
|
|
|
} => $class; |
251
|
|
|
|
|
|
|
|
252
|
|
|
|
|
|
|
$self->verbose(2, "Created new repository object in path '$path'"); |
253
|
|
|
|
|
|
|
|
254
|
|
|
|
|
|
|
# check that the repository exists or create it. |
255
|
|
|
|
|
|
|
my $mod_dbm = catfile($path, PAR::Repository::DBM::MODULES_DBM_FILE()); |
256
|
|
|
|
|
|
|
my $sym_dbm = catfile($path, PAR::Repository::DBM::SYMLINKS_DBM_FILE()); |
257
|
|
|
|
|
|
|
my $scr_dbm = catfile($path, PAR::Repository::DBM::SCRIPTS_DBM_FILE()); |
258
|
|
|
|
|
|
|
my $dep_dbm = catfile($path, PAR::Repository::DBM::DEPENDENCIES_DBM_FILE()); |
259
|
|
|
|
|
|
|
my $info_file = catfile($path, PAR::Repository::REPOSITORY_INFO_FILE()); |
260
|
|
|
|
|
|
|
|
261
|
|
|
|
|
|
|
if (-d $path |
262
|
|
|
|
|
|
|
and -f $mod_dbm.'.zip' and -f $sym_dbm.'.zip' |
263
|
|
|
|
|
|
|
and -f $info_file ) { |
264
|
|
|
|
|
|
|
# everything is in place. good. |
265
|
|
|
|
|
|
|
$self->verbose(3, "Repository exists"); |
266
|
|
|
|
|
|
|
|
267
|
|
|
|
|
|
|
# load repository info |
268
|
|
|
|
|
|
|
$self->{info} = YAML::Syck::LoadFile($info_file); |
269
|
|
|
|
|
|
|
if ( not defined $self->{info} |
270
|
|
|
|
|
|
|
or not exists $self->{info}{repository_version} ) { |
271
|
|
|
|
|
|
|
croak("Repository exists, but it does not contain a valid repository_info.yml file."); |
272
|
|
|
|
|
|
|
} |
273
|
|
|
|
|
|
|
elsif ( not exists $Compatible_Versions->{$self->{info}{repository_version}} ) { |
274
|
|
|
|
|
|
|
croak("Repository exists, but it was created with an incompatible version of PAR::Repository (".$self->{info}{repository_version}.")"); |
275
|
|
|
|
|
|
|
} |
276
|
|
|
|
|
|
|
# the following is a special case because the "incompatible changes |
277
|
|
|
|
|
|
|
# with every "\d+.\d" release" rule was introduced in 0.10 |
278
|
|
|
|
|
|
|
elsif ( $Compatible_Versions->{$self->{info}{repository_version}} eq '0.03' ) { |
279
|
|
|
|
|
|
|
$self->_update_info_version or return (); |
280
|
|
|
|
|
|
|
$self->verbose(3, "Updated repository version"); |
281
|
|
|
|
|
|
|
} |
282
|
|
|
|
|
|
|
|
283
|
|
|
|
|
|
|
if ($args{convert_symlinks}) { |
284
|
|
|
|
|
|
|
$self->_convert_symlinks(); |
285
|
|
|
|
|
|
|
} |
286
|
|
|
|
|
|
|
|
287
|
|
|
|
|
|
|
if (!$Supports_Symlinks and !$self->{info}{fake_symlinks}) { |
288
|
|
|
|
|
|
|
croak("Repository may use symlinks but your platform does not support them. " |
289
|
|
|
|
|
|
|
."Use the convert_symlinks => 1 option to the PAR::Repository constructor " |
290
|
|
|
|
|
|
|
."to convert the repository to one which does not use symbolic links."); |
291
|
|
|
|
|
|
|
} |
292
|
|
|
|
|
|
|
|
293
|
|
|
|
|
|
|
$self->verbose(3, "Opened repository successfully"); |
294
|
|
|
|
|
|
|
|
295
|
|
|
|
|
|
|
# Generate scripts db and upgrade repository version |
296
|
|
|
|
|
|
|
# if the scripts db doesn't exist. |
297
|
|
|
|
|
|
|
if (not -f $scr_dbm.'.zip') { |
298
|
|
|
|
|
|
|
$self->verbose(1, "Upgrading repository version to $VERSION"); |
299
|
|
|
|
|
|
|
$self->_update_info_version or return (); |
300
|
|
|
|
|
|
|
$self->verbose(3, "Creating scripts database"); |
301
|
|
|
|
|
|
|
$self->_create_dbm($scr_dbm.'.zip'); |
302
|
|
|
|
|
|
|
} |
303
|
|
|
|
|
|
|
|
304
|
|
|
|
|
|
|
# Generate deps db and upgrade repository version |
305
|
|
|
|
|
|
|
# if the deps db doesn't exist. |
306
|
|
|
|
|
|
|
if (not -f $dep_dbm.'.zip') { |
307
|
|
|
|
|
|
|
$self->verbose(1, "Upgrading repository version to $VERSION"); |
308
|
|
|
|
|
|
|
$self->_update_info_version or return (); |
309
|
|
|
|
|
|
|
$self->verbose(3, "Creating dependencies database"); |
310
|
|
|
|
|
|
|
$self->_create_dbm($dep_dbm.'.zip'); |
311
|
|
|
|
|
|
|
} |
312
|
|
|
|
|
|
|
|
313
|
|
|
|
|
|
|
} # end if everything is in place |
314
|
|
|
|
|
|
|
else { |
315
|
|
|
|
|
|
|
$self->verbose(3, "Repository doesn't exist yet"); |
316
|
|
|
|
|
|
|
$self->_create_repository($path, !$Supports_Symlinks||$args{fake_symlinks}); |
317
|
|
|
|
|
|
|
} |
318
|
|
|
|
|
|
|
|
319
|
|
|
|
|
|
|
return $self; |
320
|
|
|
|
|
|
|
} |
321
|
|
|
|
|
|
|
|
322
|
|
|
|
|
|
|
# creates a new repository |
323
|
|
|
|
|
|
|
# called by the constructor if the directory doesn't exist |
324
|
|
|
|
|
|
|
sub _create_repository { |
325
|
|
|
|
|
|
|
my $self = shift; |
326
|
|
|
|
|
|
|
my $path = shift; |
327
|
|
|
|
|
|
|
my $fake_symlinks = shift; |
328
|
|
|
|
|
|
|
|
329
|
|
|
|
|
|
|
if (-d $path) { |
330
|
|
|
|
|
|
|
croak("The repository path exists, but is not a repository. Delete it to create a new repository."); |
331
|
|
|
|
|
|
|
} |
332
|
|
|
|
|
|
|
mkpath([$path]); |
333
|
|
|
|
|
|
|
|
334
|
|
|
|
|
|
|
my $mod_dbm = catfile($path, PAR::Repository::DBM::MODULES_DBM_FILE()); |
335
|
|
|
|
|
|
|
my $sym_dbm = catfile($path, PAR::Repository::DBM::SYMLINKS_DBM_FILE()); |
336
|
|
|
|
|
|
|
my $scr_dbm = catfile($path, PAR::Repository::DBM::SCRIPTS_DBM_FILE()); |
337
|
|
|
|
|
|
|
my $dep_dbm = catfile($path, PAR::Repository::DBM::DEPENDENCIES_DBM_FILE()); |
338
|
|
|
|
|
|
|
my $info_file = catfile($path, PAR::Repository::REPOSITORY_INFO_FILE()); |
339
|
|
|
|
|
|
|
|
340
|
|
|
|
|
|
|
$self->verbose(3, "Creating repository databases"); |
341
|
|
|
|
|
|
|
foreach my $dbm ($mod_dbm, $sym_dbm, $scr_dbm, $dep_dbm) { |
342
|
|
|
|
|
|
|
$self->_create_dbm($dbm.'.zip'); |
343
|
|
|
|
|
|
|
} |
344
|
|
|
|
|
|
|
|
345
|
|
|
|
|
|
|
my $info_copy = {%$Info_Template}; |
346
|
|
|
|
|
|
|
$info_copy->{fake_symlinks} = 1 if $fake_symlinks; |
347
|
|
|
|
|
|
|
YAML::Syck::DumpFile($info_file, $info_copy); |
348
|
|
|
|
|
|
|
$self->{info} = YAML::Syck::LoadFile($info_file); |
349
|
|
|
|
|
|
|
} |
350
|
|
|
|
|
|
|
|
351
|
|
|
|
|
|
|
# converts all symlinks to files, sets {info}->{fake_symlinks}, |
352
|
|
|
|
|
|
|
# and saves it |
353
|
|
|
|
|
|
|
# called by the constructor |
354
|
|
|
|
|
|
|
sub _convert_symlinks { |
355
|
|
|
|
|
|
|
my $self = shift; |
356
|
|
|
|
|
|
|
$self->{error} = undef; |
357
|
|
|
|
|
|
|
$self->verbose(1, "Converting symlinks to files!"); |
358
|
|
|
|
|
|
|
|
359
|
|
|
|
|
|
|
# change to repo path |
360
|
|
|
|
|
|
|
my $old_dir = Cwd::cwd(); |
361
|
|
|
|
|
|
|
chdir($self->{path}); |
362
|
|
|
|
|
|
|
|
363
|
|
|
|
|
|
|
my $info_file = catfile($self->{path}, PAR::Repository::REPOSITORY_INFO_FILE()); |
364
|
|
|
|
|
|
|
|
365
|
|
|
|
|
|
|
my ($symdbm, $temp_file) = $self->symlinks_dbm; |
366
|
|
|
|
|
|
|
while (my ($file, $symlinks) = each %$symdbm) { |
367
|
|
|
|
|
|
|
my ($distname, $distver, $arch, $perlver) = PAR::Dist::parse_dist_name($file); |
368
|
|
|
|
|
|
|
my $file_fullpath = File::Spec->catfile($arch, $perlver, $file); |
369
|
|
|
|
|
|
|
|
370
|
|
|
|
|
|
|
foreach my $symlink_file (@$symlinks) { |
371
|
|
|
|
|
|
|
my ($distname, $distver, $arch, $perlver) = PAR::Dist::parse_dist_name($symlink_file); |
372
|
|
|
|
|
|
|
my $symlink_file_fullpath = File::Spec->catfile($arch, $perlver, $symlink_file); |
373
|
|
|
|
|
|
|
# first unlink or else File::Copy may claim it can't copy because the files are |
374
|
|
|
|
|
|
|
# the same. |
375
|
|
|
|
|
|
|
(unlink( $symlink_file_fullpath ) and File::Copy::copy( $file_fullpath, $symlink_file_fullpath )) |
376
|
|
|
|
|
|
|
or chdir($old_dir), |
377
|
|
|
|
|
|
|
die "Error converting symlinks in repository to real files: Could not copy " |
378
|
|
|
|
|
|
|
."'$file' to '$symlink_file'. Your repository may be in an inconsistent " |
379
|
|
|
|
|
|
|
."state now. Reason: $!"; |
380
|
|
|
|
|
|
|
} |
381
|
|
|
|
|
|
|
} |
382
|
|
|
|
|
|
|
chdir($old_dir); |
383
|
|
|
|
|
|
|
|
384
|
|
|
|
|
|
|
$self->{info}{fake_symlinks} = 1; |
385
|
|
|
|
|
|
|
YAML::Syck::DumpFile($info_file, $self->{info}); |
386
|
|
|
|
|
|
|
$self->{info} = YAML::Syck::LoadFile($info_file); |
387
|
|
|
|
|
|
|
return 1; |
388
|
|
|
|
|
|
|
} |
389
|
|
|
|
|
|
|
|
390
|
|
|
|
|
|
|
=head2 inject |
391
|
|
|
|
|
|
|
|
392
|
|
|
|
|
|
|
Injects a new PAR distribution into the repository. Takes named parameters. |
393
|
|
|
|
|
|
|
|
394
|
|
|
|
|
|
|
Mandatory parameters: I, the path and filename of the PAR distribution |
395
|
|
|
|
|
|
|
to inject. The name of the file can be used to automatically determine the |
396
|
|
|
|
|
|
|
I, I, I, and I parameters if the |
397
|
|
|
|
|
|
|
form of the file name is as follows: |
398
|
|
|
|
|
|
|
|
399
|
|
|
|
|
|
|
Dist-Name-0.01-x86_64-linux-gnu-thread-multi-5.8.7.par |
400
|
|
|
|
|
|
|
|
401
|
|
|
|
|
|
|
This would set C 'Dist-Name', distversion => '0.01', |
402
|
|
|
|
|
|
|
arch => 'linux-gnu-thread-multi', perlversion => '5.8.7'>. You can override |
403
|
|
|
|
|
|
|
this automatic detection using the corresponding parameters. |
404
|
|
|
|
|
|
|
|
405
|
|
|
|
|
|
|
If the file exists in the repository, inject returns false. If the file |
406
|
|
|
|
|
|
|
was added successfully, inject returns true. See the C parameter |
407
|
|
|
|
|
|
|
for details. |
408
|
|
|
|
|
|
|
|
409
|
|
|
|
|
|
|
C scans the distribution for modules and indexes these in |
410
|
|
|
|
|
|
|
the modules-dists dbm. Additionally, it scans the distribution for |
411
|
|
|
|
|
|
|
scripts in the C |