|
1 # Copyright (c) 2000-2009 Nokia Corporation and/or its subsidiary(-ies). |
|
2 # All rights reserved. |
|
3 # This component and the accompanying materials are made available |
|
4 # under the terms of the License "Eclipse Public License v1.0" |
|
5 # which accompanies this distribution, and is available |
|
6 # at the URL "http://www.eclipse.org/legal/epl-v10.html". |
|
7 # |
|
8 # Initial Contributors: |
|
9 # Nokia Corporation - initial contribution. |
|
10 # |
|
11 # Contributors: |
|
12 # |
|
13 # Description: |
|
14 # |
|
15 # |
|
16 # Description: |
|
17 # PathData/ComponentBased.pm |
|
18 # |
|
19 |
|
20 package PathData::ComponentBased; |
|
21 use strict; |
|
22 |
|
23 BEGIN { |
|
24 @PathData::ComponentBased::ISA=('PathData'); |
|
25 }; |
|
26 |
|
27 # |
|
28 # Public |
|
29 # |
|
30 # |
|
31 |
|
32 sub ProcessLine { |
|
33 my $self = shift; |
|
34 my $keywordref = shift; |
|
35 my $lineref = shift; |
|
36 |
|
37 die "Unknown keyword $$keywordref for component-based path data" unless ($$keywordref =~ m/archive_path_file/i); |
|
38 print "Warning: Deprecated keyword 'archive_path_file' found. Support for component-based archives is planned for removal - please see documention for the 'archive_path' keyword for how to use project-based archives.\n"; |
|
39 |
|
40 die "Can't have multiple archive_path_file keywords in reltools.ini." if ($self->{archive_path_file}); |
|
41 |
|
42 $self->{archive_path_file} = $$lineref; # store the filename, just in case anybody wants to debug us - it might be useful. |
|
43 $self->ParsePathData(); |
|
44 } |
|
45 |
|
46 sub LocalArchivePathForNewComponent { |
|
47 my $self = shift; |
|
48 my $comp = shift; |
|
49 my $ver = shift; |
|
50 my $project = shift; |
|
51 die "Project $project does not make any sense when we are using an archive_path_data.txt file"; |
|
52 return $self->LocalArchivePath($comp, $ver); |
|
53 } |
|
54 |
|
55 sub LocalArchivePathForExistingComponent { |
|
56 my $self = shift; |
|
57 my $comp = shift; |
|
58 my $ver = shift; |
|
59 return $self->LocalArchivePath($comp, $ver); |
|
60 } |
|
61 |
|
62 sub LocalArchivePathForImportingComponent { |
|
63 my $self = shift; |
|
64 my $comp = shift; |
|
65 my $ver = shift; |
|
66 my $remotepath = shift; |
|
67 return $self->LocalArchivePath($comp, $ver); |
|
68 } |
|
69 |
|
70 sub RemoteArchivePathForExistingComponent { |
|
71 my $self = shift; |
|
72 my $comp = shift; |
|
73 my $ver = shift; |
|
74 return $self->RemoteArchivePath($comp, $ver); |
|
75 } |
|
76 |
|
77 sub RemoteArchivePathForExportingComponent { |
|
78 my $self = shift; |
|
79 my $comp = shift; |
|
80 my $ver = shift; |
|
81 my $localpath = shift; |
|
82 return $self->RemoteArchivePath($comp, $ver); |
|
83 } |
|
84 |
|
85 sub ListComponents { |
|
86 my $self = shift; |
|
87 my $remote = shift || 0; |
|
88 my @comps; |
|
89 if ($remote) { # list those in the remote archive |
|
90 die "Must pass a remote site object to ListComponents if you want a list of the components on the remote site" unless ref $remote; |
|
91 foreach my $location (values %{$self->{remote_archive_path}}) { |
|
92 my $list = $remote->DirList($location); |
|
93 $location =~ s/\\/\//g; |
|
94 foreach (@$list) { |
|
95 s/^$location\/?//i; |
|
96 push @comps, $_; |
|
97 } |
|
98 } |
|
99 } else { # list those in the local archive |
|
100 foreach my $location (values %{$self->{local_archive_path}}) { |
|
101 push @comps, @{Utils::ReadDir($location)} if (-d $location); |
|
102 } |
|
103 } |
|
104 return \@comps; |
|
105 } |
|
106 |
|
107 sub ListProjects { |
|
108 my $self = shift; |
|
109 die "Cannot give a list of projects because we are using the component-based style of archive path data."; |
|
110 } |
|
111 |
|
112 sub ListVersions { |
|
113 my $self = shift; |
|
114 my $comp = shift; |
|
115 my $remote = shift; |
|
116 my $filter = shift; |
|
117 my $found; |
|
118 if ($remote) { # list those in the remote archive |
|
119 die "Must pass a remote site object to ListVersions if you want a list of the versions on the remote site" unless ref $remote; |
|
120 my $compDir = $self->GetArchivePath($comp, "remote_archive_path")."/$comp"; |
|
121 my $files = $remote->DirList($compDir); |
|
122 my @results = map { m/\Q$comp\E([^\\\/]*)\.zip/i; $1 } @$files; |
|
123 $found = \@results; |
|
124 } else { # list those in the local archive |
|
125 my $compDir = $self->GetArchivePath($comp, "local_archive_path")."\\$comp"; |
|
126 return [] unless (-d $compDir); |
|
127 $found = Utils::ReadDir($compDir); |
|
128 } |
|
129 @$found = grep { m/$filter/i } @$found if ($filter); |
|
130 return @$found if wantarray; |
|
131 return $found; |
|
132 } |
|
133 |
|
134 sub ComponentProjects { |
|
135 my $self = shift; |
|
136 my $comp = shift; |
|
137 my $ver = shift; |
|
138 return ("<n/a>"); |
|
139 } |
|
140 |
|
141 sub ComponentProject { |
|
142 my $self = shift; |
|
143 my $comp = shift; |
|
144 my $ver = shift; |
|
145 return ("<n/a>"); |
|
146 } |
|
147 |
|
148 # |
|
149 # Private |
|
150 # |
|
151 # |
|
152 # |
|
153 |
|
154 sub GetArchivePath { |
|
155 my $self = shift; |
|
156 my $component = lc(shift); |
|
157 my $type = shift; |
|
158 |
|
159 die "Couldn't get archive path for undefined component" unless defined $component; |
|
160 die unless defined $type; |
|
161 |
|
162 if ($self->{$type}->{$component}) { |
|
163 return $self->{$type}->{$component}; |
|
164 } |
|
165 elsif ($self->{$type}->{default}) { |
|
166 return $self->{$type}->{default}; |
|
167 } |
|
168 else { |
|
169 die "Error: archive path not specified for $component\n"; |
|
170 } |
|
171 } |
|
172 |
|
173 sub LocalArchivePath { |
|
174 my $self = shift; |
|
175 my $component = shift; |
|
176 my $ver = shift; |
|
177 |
|
178 return $self->GetArchivePath($component, "local_archive_path")."\\$component\\$ver"; |
|
179 } |
|
180 |
|
181 sub RemoteArchivePath { |
|
182 my $self = shift; |
|
183 my $component = shift; |
|
184 my $ver = shift; |
|
185 |
|
186 return $self->GetArchivePath($component, "remote_archive_path")."/$component"; |
|
187 } |
|
188 |
|
189 sub ParsePathData { |
|
190 my $self = shift; |
|
191 |
|
192 my $path_file = $self->{archive_path_file}; |
|
193 |
|
194 unless (-f $path_file) { |
|
195 die "Error: $path_file not found\n"; |
|
196 } |
|
197 |
|
198 open PATH, "$path_file" or die "Unable to open $path_file for reading\n"; |
|
199 |
|
200 while (my $line = <PATH>) { |
|
201 # Remove line feed, white space and comments. |
|
202 chomp $line; |
|
203 $line =~ s/^\s*$//; |
|
204 $line =~ s/#.*//; |
|
205 if ($line eq '') { |
|
206 # Nothing left. |
|
207 next; |
|
208 } |
|
209 my ($component, $local, $remote) = split (/\s+/, $line, 4); |
|
210 $component = lc($component); |
|
211 unless ($local and $remote) { |
|
212 die "Error: Path not defined for \"$component\" in \"$path_file\"\n"; |
|
213 } |
|
214 if (exists $self->{local_archive_path}->{$component}) { |
|
215 die "Error: \"$component\" specified more than once in \"$path_file\"\n"; |
|
216 } |
|
217 $self->{local_archive_path}->{$component} = $local; |
|
218 $self->{remote_archive_path}->{$component} = $remote; |
|
219 } |
|
220 close PATH; |
|
221 } |
|
222 |
|
223 |
|
224 1; |
|
225 |
|
226 __END__ |
|
227 |
|
228 =head1 NAME |
|
229 |
|
230 PathData/ComponentBased.pm - Provides the location of archived releases with an old-style archive arrangement. |
|
231 |
|
232 =head1 DESCRIPTION |
|
233 |
|
234 Parses a file containing paths to component release packets on both the local and remote archives. |
|
235 |
|
236 =head1 INTERFACE |
|
237 |
|
238 =head2 ProcessLine |
|
239 |
|
240 This interprets an C<archive_path_file> line from your F<reltools.ini>, and goes away to parse the F<archive_path.txt> file (which it does using the internal method C<ParsePathData>). |
|
241 |
|
242 The parser expects each line in the file to have the following form: |
|
243 |
|
244 <component_name> <local_archive_path> <remote_archive_path> |
|
245 |
|
246 So an example file might have the following structure: |
|
247 |
|
248 # |
|
249 # App Engines |
|
250 # |
|
251 agnmodel X:\ProjectX\appeng \ProjectX\appeng |
|
252 cntmodel X:\ProjectX\appeng \ProjectX\appeng |
|
253 damodel X:\ProjectX\appeng \ProjectX\appeng |
|
254 ... |
|
255 ... |
|
256 # |
|
257 # App Framework |
|
258 # |
|
259 apparc X:\ProjectX\appframework \ProjectX\appframework |
|
260 eikstd X:\ProjectX\appframework \ProjectX\appframework |
|
261 etext X:\ProjectX\appframework \ProjectX\appframework |
|
262 ... |
|
263 ... |
|
264 # |
|
265 # Default path |
|
266 # |
|
267 default X:\ProjectX\misc \ProjectX\misc |
|
268 |
|
269 The C<default> line is optional (and there should be only one in the file). The C<default> value is the path given to all component releases which are not explicity listed in the file. |
|
270 |
|
271 [Note: text following a # is treated as a comment] |
|
272 |
|
273 =head2 Methods that return paths |
|
274 |
|
275 All of these methods are expected to return the full location where the files should be stored; i.e. local archive paths should end in "\component\version" and remote archive paths should end in "/component". |
|
276 |
|
277 =head2 LocalArchivePathForNewComponent |
|
278 |
|
279 This takes a component and a version and (optionally) the name of the project to store the component in. |
|
280 |
|
281 =head2 LocalArchivePathForExistingComponent |
|
282 |
|
283 This takes a component and a version. |
|
284 |
|
285 =head2 LocalArchivePathForImportingComponent |
|
286 |
|
287 This takes a component, a version, and the remote path where the component was found. |
|
288 |
|
289 =head2 RemoteArchivePathForExistingComponent |
|
290 |
|
291 This takes a component and a version. |
|
292 |
|
293 =head2 RemoteArchivePathForExportingComponent |
|
294 |
|
295 This takes a component, a version, and the local path where the component was found. |
|
296 |
|
297 =head2 ListComponents |
|
298 |
|
299 This may take "1" to indicate that it should list the components stored remotely, not locally. |
|
300 |
|
301 =head2 ListVersions |
|
302 |
|
303 This takes a component. It may optionally take a "1" to indicate that it should list the versions stored remotely, not locally. |
|
304 |
|
305 =head2 ListProjects |
|
306 |
|
307 =head2 ComponentProjects |
|
308 |
|
309 =head2 ComponentProject |
|
310 |
|
311 These methods all throw an error, since projects aren't a relevant concept in this type of archive structure. |
|
312 |
|
313 =head1 IMPLEMENTATION |
|
314 |
|
315 =head2 LocalArchivePath |
|
316 |
|
317 Takes a component name. Returns the path of the component release packet on the local archive. Dies if not found. |
|
318 |
|
319 =head2 RemoteArchivePath |
|
320 |
|
321 Takes a component name. Returns the path of the component release packet on the remote archive (either an FTP site or a network drive). Dies if not found. |
|
322 |
|
323 =head1 KNOWN BUGS |
|
324 |
|
325 None. |
|
326 |
|
327 =head1 COPYRIGHT |
|
328 |
|
329 Copyright (c) 2000-2009 Nokia Corporation and/or its subsidiary(-ies). |
|
330 All rights reserved. |
|
331 This component and the accompanying materials are made available |
|
332 under the terms of the License "Eclipse Public License v1.0" |
|
333 which accompanies this distribution, and is available |
|
334 at the URL "http://www.eclipse.org/legal/epl-v10.html". |
|
335 |
|
336 Initial Contributors: |
|
337 Nokia Corporation - initial contribution. |
|
338 |
|
339 Contributors: |
|
340 |
|
341 Description: |
|
342 |
|
343 |
|
344 =cut |