|
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 |
|
17 package MakeRel; |
|
18 |
|
19 use strict; |
|
20 use File::Path; |
|
21 use File::Spec; |
|
22 use File::Basename; |
|
23 use IniData; |
|
24 use EnvDb; |
|
25 use MrpData; |
|
26 use RelData; |
|
27 use CatData; |
|
28 use Utils; |
|
29 use Symbian::CBR::Component::Manifest; |
|
30 use Cwd; |
|
31 |
|
32 # |
|
33 # Public. |
|
34 # |
|
35 |
|
36 sub MakeReleases { |
|
37 my $self; |
|
38 $self->{iniData} = shift; |
|
39 $self->{envDb} = shift; |
|
40 $self->{mrpData} = shift; |
|
41 $self->{notesSrc} = shift; |
|
42 $self->{toolName} = shift; |
|
43 $self->{verbose} = shift; |
|
44 $self->{project} = shift; |
|
45 $self->{useCachedManifest} = shift; |
|
46 |
|
47 bless $self, "MakeRel"; |
|
48 |
|
49 if (scalar(@{$self->{mrpData}}) == 0) { # Abort if there's nothing to do. |
|
50 return; |
|
51 } |
|
52 if (!$self->CheckArchive()) { # Abort if any of the releases already exist |
|
53 return; |
|
54 } |
|
55 |
|
56 my $versionInfo = $self->VersionInfo(); |
|
57 eval { |
|
58 $self->GenerateReleaseFiles($versionInfo); |
|
59 }; |
|
60 if ($@) { |
|
61 print $@; |
|
62 |
|
63 if($self->{toolName} =~ /MakeEnv/i){ |
|
64 print "\nError: Unable to create environment successfully, archive might be corrupted.\n"; |
|
65 } |
|
66 else{ |
|
67 print "\nError: Unable to create component release successfully, archive might be corrupted.\n"; |
|
68 } |
|
69 |
|
70 $self->Cleanup(); |
|
71 return; |
|
72 } |
|
73 |
|
74 # Now that we know all releases have been successfully made, update the environment database. |
|
75 foreach my $thisMrpData (@{$self->{mrpData}}) { |
|
76 my $comp = $thisMrpData->Component(); |
|
77 my $ver = $thisMrpData->ExternalVersion(); |
|
78 $self->{envDb}->SetVersion($comp, $ver); |
|
79 $self->{envDb}->GenerateSignature($comp, $ver); |
|
80 $self->{envDb}->SetMrpName($comp, $thisMrpData->MrpName()); |
|
81 $self->{envDb}->SetStatus($comp, EnvDb::STATUS_CLEAN); |
|
82 } |
|
83 } |
|
84 |
|
85 |
|
86 # |
|
87 # Private. |
|
88 # |
|
89 |
|
90 sub VersionInfo { |
|
91 my $self = shift; |
|
92 |
|
93 # Get a copy of the current version information from the environment database and update it with the new versions. |
|
94 my $versionInfo = $self->{envDb}->VersionInfo(); |
|
95 foreach my $thisMrpData (@{$self->{mrpData}}) { |
|
96 $versionInfo->{lc($thisMrpData->Component())} = $thisMrpData->ExternalVersion(); |
|
97 } |
|
98 |
|
99 return $versionInfo; |
|
100 } |
|
101 |
|
102 sub CheckArchive { |
|
103 my $self = shift; |
|
104 my $good = 1; |
|
105 foreach my $thisMrpData (@{$self->{mrpData}}) { |
|
106 if (!$self->CheckDirs($thisMrpData)) { |
|
107 $good = 0; # Continue and check the rest |
|
108 } |
|
109 } |
|
110 return $good; |
|
111 } |
|
112 |
|
113 sub GenerateReleaseFiles { |
|
114 my $self = shift; |
|
115 my $versionInfo = shift; |
|
116 my $numMrps = scalar(@{$self->{mrpData}}); |
|
117 foreach my $thisMrpData (@{$self->{mrpData}}) { |
|
118 $self->MakeDirs($thisMrpData); |
|
119 $self->ZipSource($thisMrpData); |
|
120 $self->ZipBinaries($thisMrpData); |
|
121 $self->ZipExports($thisMrpData); |
|
122 $self->WriteRelData($thisMrpData, $versionInfo); |
|
123 $self->WriteManifest($thisMrpData); |
|
124 |
|
125 # This line must come after the others, because with a project-based archive path configuration it relies on |
|
126 # LocalArchivePathForNewOrExistingComponent finding the directories created above. |
|
127 my $comp = $thisMrpData->Component(); |
|
128 my $extVer = $thisMrpData->ExternalVersion(); |
|
129 my $intVer = $thisMrpData->InternalVersion(); |
|
130 unless (defined $intVer) { |
|
131 $intVer = ''; |
|
132 } |
|
133 my $relDir = $self->LocalArchivePath($thisMrpData); |
|
134 Utils::SetFileReadOnly($relDir); |
|
135 print "Made $comp $extVer $intVer\n"; |
|
136 } |
|
137 } |
|
138 |
|
139 sub ComponentDir { |
|
140 require Carp; |
|
141 confess("Obsolete method called"); |
|
142 } |
|
143 |
|
144 sub ReleaseDir { |
|
145 require Carp; |
|
146 confess("Obsolete method called"); |
|
147 } |
|
148 |
|
149 sub CheckDirs { |
|
150 my $self = shift; |
|
151 my $mrpData = shift; |
|
152 my $relDir = $self->LocalArchivePath($mrpData); |
|
153 if (-e $relDir) { |
|
154 print STDERR "Error: $relDir already exists\n"; |
|
155 return 0; |
|
156 } |
|
157 return 1; |
|
158 } |
|
159 |
|
160 sub MakeDirs { |
|
161 my $self = shift; |
|
162 my $mrpData = shift; |
|
163 my $relDir = $self->LocalArchivePath($mrpData); |
|
164 unless (-e $relDir) { |
|
165 Utils::MakeDir($relDir); |
|
166 } |
|
167 } |
|
168 |
|
169 sub ZipSource { |
|
170 my $self = shift; |
|
171 my $mrpData = shift; |
|
172 my @categories = @{$mrpData->SourceCategories()}; |
|
173 my $zipName; |
|
174 |
|
175 foreach my $category (@categories) { |
|
176 my @sourceFiles = @{$mrpData->Source($category)}; |
|
177 if (@sourceFiles) { |
|
178 $zipName = $self->LocalArchivePath($mrpData) . "\\source".uc($category).".zip"; |
|
179 |
|
180 Utils::ZipSourceList($zipName, \@sourceFiles, $self->{verbose}, Utils::SourceRoot(), $self->{iniData}); |
|
181 |
|
182 Utils::SetFileReadOnly($zipName); |
|
183 } |
|
184 } |
|
185 if ($self->{verbose} > 1 and not defined $zipName) { |
|
186 print "No source for " . $mrpData->Component() . "\n"; |
|
187 } |
|
188 } |
|
189 |
|
190 sub ZipBinaries { |
|
191 my $self = shift; |
|
192 my $mrpData = shift; |
|
193 foreach my $thisBinCat (@{$mrpData->BinaryCategories()}) { |
|
194 my $bins = $mrpData->Binaries($thisBinCat); |
|
195 if ($bins and scalar(@$bins) > 0) { |
|
196 my $zipName; |
|
197 if ($thisBinCat eq 'unclassified') { |
|
198 $zipName = $self->LocalArchivePath($mrpData) . "\\binaries.zip"; |
|
199 } |
|
200 else { |
|
201 $zipName = $self->LocalArchivePath($mrpData) . "\\binaries_$thisBinCat.zip"; |
|
202 } |
|
203 Utils::ZipList($zipName, $bins, $self->{verbose}, 0, Utils::EpocRoot()); |
|
204 Utils::SetFileReadOnly($zipName); |
|
205 } |
|
206 } |
|
207 } |
|
208 |
|
209 sub ZipExports { |
|
210 my $self = shift; |
|
211 my $mrpData = shift; |
|
212 |
|
213 foreach my $thisExportCat (@{$mrpData->ExportCategories()}) { |
|
214 my $exports = $mrpData->Exports($thisExportCat); |
|
215 if ($exports and scalar(@$exports) > 0) { |
|
216 my $zipName = $self->LocalArchivePath($mrpData) . "\\exports".uc($thisExportCat).".zip"; |
|
217 Utils::ZipList($zipName, $exports, $self->{verbose}, 0, Utils::EpocRoot()); |
|
218 Utils::SetFileReadOnly($zipName); |
|
219 # Need to create an exports<CAT>.txt file which details necessary info... |
|
220 my $txtName = $self->LocalArchivePath($mrpData) . "\\exports".uc($thisExportCat).".txt"; |
|
221 CatData->New($self->{iniData}, $txtName, $mrpData, uc($thisExportCat)); |
|
222 } |
|
223 } |
|
224 } |
|
225 |
|
226 sub WriteRelData { |
|
227 my $self = shift; |
|
228 my $mrpData = shift; |
|
229 my $versionInfo = shift; |
|
230 |
|
231 my $notesSource = $self->{notesSrc}; |
|
232 if (defined $notesSource) { |
|
233 Utils::CheckExists($notesSource); |
|
234 Utils::CheckIsFile($notesSource); |
|
235 } |
|
236 else { |
|
237 $notesSource = Utils::PrependSourceRoot($mrpData->NotesSource()); |
|
238 } |
|
239 my $relData = RelData->New($self->{iniData}, $mrpData, $notesSource, $versionInfo, $self->{toolName}, $self->{verbose}, undef, $self->{project}); # undef = dontPersist |
|
240 } |
|
241 |
|
242 sub WriteManifest { |
|
243 my $self = shift; |
|
244 my $mrpData = shift; |
|
245 my $componentName = $mrpData->Component(); |
|
246 my $manifest = undef; |
|
247 |
|
248 |
|
249 if ($self->{useCachedManifest}) { |
|
250 #Check if manifest file is available in temp location |
|
251 my $manifestTempFile = File::Spec->catfile( File::Spec->tmpdir(), "manifest_".$componentName.".xml" ); |
|
252 |
|
253 if (-e $manifestTempFile ) { |
|
254 #Construct manifest object from the manifest file |
|
255 $manifest = Symbian::CBR::Component::Manifest->new( $manifestTempFile ); |
|
256 |
|
257 #Delete the temp manifest file |
|
258 my $unlinkCount = 100; |
|
259 while(-e $manifestTempFile and $unlinkCount > 0){ |
|
260 unlink($manifestTempFile) or print "Warning: unlink $manifestTempFile failed[$unlinkCount].\n"; |
|
261 $unlinkCount--; |
|
262 } |
|
263 if ( $unlinkCount == 0 ) { |
|
264 die "Error: unlink $manifestTempFile failed.\n"; |
|
265 } |
|
266 } |
|
267 } |
|
268 |
|
269 if (!defined $manifest) { |
|
270 my $mrpName = Utils::RelativeToAbsolutePath( $mrpData->MrpName(), $mrpData->{iniData}, SOURCE_RELATIVE ); |
|
271 |
|
272 #Construct manifest object from MRP file |
|
273 $manifest = Symbian::CBR::Component::Manifest->new( $mrpName ); |
|
274 } |
|
275 |
|
276 #Save the manifest file to the archive release location for the component |
|
277 $manifest->Save ( $self->LocalArchivePath($mrpData) ); |
|
278 } |
|
279 |
|
280 sub Cleanup { |
|
281 my $self = shift; |
|
282 if ($self->{verbose}) { print "Cleaning up...\n"; } |
|
283 foreach my $thisMrpData (@{$self->{mrpData}}) { |
|
284 my $relDir = $self->LocalArchivePath($thisMrpData); |
|
285 if (-e $relDir) { |
|
286 if ($self->{verbose}) { print "Deleting $relDir...\n"; } |
|
287 my $origDir = cwd(); |
|
288 |
|
289 chdir(dirname($relDir)); #If you try to rmtree a UNC path the cwd must also be a UNC path |
|
290 rmtree ($relDir); |
|
291 chdir($origDir); |
|
292 } |
|
293 } |
|
294 } |
|
295 |
|
296 sub LocalArchivePath { |
|
297 my $self = shift; |
|
298 my $mrpData = shift; |
|
299 my $name = $mrpData->Component(); |
|
300 my $ver = $mrpData->ExternalVersion(); |
|
301 |
|
302 if (not exists $self->{pathCache}->{$name}->{$ver}) { |
|
303 $self->{pathCache}->{$name}->{$ver} = $self->{iniData}->PathData->LocalArchivePathForExistingOrNewComponent($name, $ver, $self->{project}); |
|
304 } |
|
305 |
|
306 return $self->{pathCache}->{$name}->{$ver}; |
|
307 } |
|
308 |
|
309 1; |
|
310 |
|
311 =head1 NAME |
|
312 |
|
313 MakeRel.pm - Provides an interface for making releases. |
|
314 |
|
315 =head1 INTERFACE |
|
316 |
|
317 =head2 MakeReleases |
|
318 |
|
319 Expects to be passed an C<IniData> reference, an C<EnvDb> reference, a reference to a list of C<MrpData> objects, the name of a notes source file, the name of the tool using C<MakeRel> and a verbosity level. Firstly, the binary files referred to by the C<MrpData> objects are cross checked to ensure that more than one component isn't attempting to release the same file. Dies if this is the case. Secondly, generates release directories and files for each C<MrpData> object. Thirdly, updates local signature files and the environment database. |
|
320 |
|
321 =head1 KNOWN BUGS |
|
322 |
|
323 None. |
|
324 |
|
325 =head1 COPYRIGHT |
|
326 |
|
327 Copyright (c) 2000-2009 Nokia Corporation and/or its subsidiary(-ies). |
|
328 All rights reserved. |
|
329 This component and the accompanying materials are made available |
|
330 under the terms of the License "Eclipse Public License v1.0" |
|
331 which accompanies this distribution, and is available |
|
332 at the URL "http://www.eclipse.org/legal/epl-v10.html". |
|
333 |
|
334 Initial Contributors: |
|
335 Nokia Corporation - initial contribution. |
|
336 |
|
337 Contributors: |
|
338 |
|
339 Description: |
|
340 |
|
341 |
|
342 =cut |