602
|
1 |
# Copyright (c) 2007-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 |
# Symbian::CBR::Release::Manifest.pm
|
|
18 |
#
|
|
19 |
|
|
20 |
package Symbian::CBR::Release::Manifest;
|
|
21 |
|
|
22 |
use File::Basename;
|
|
23 |
use File::Spec;
|
|
24 |
use File::Path;
|
|
25 |
use RelData;
|
|
26 |
use XML::Simple;
|
|
27 |
use Carp;
|
|
28 |
use POSIX qw(strftime);
|
|
29 |
|
|
30 |
|
|
31 |
#
|
|
32 |
#Constants
|
|
33 |
#
|
|
34 |
|
|
35 |
use constant MD5 => 'md5';
|
|
36 |
use constant SIZE => 'size';
|
|
37 |
use constant MODIFIED_TIME => 'modified-timestamp';
|
|
38 |
use constant VERSION => '1.0.0';
|
|
39 |
|
|
40 |
|
|
41 |
#
|
|
42 |
#Public.
|
|
43 |
#
|
|
44 |
|
|
45 |
sub new {
|
|
46 |
my $pkg = shift;
|
|
47 |
my $iniData = shift;
|
|
48 |
my $verbose = shift;
|
|
49 |
my $self;
|
|
50 |
$self->{iniData} = $iniData;
|
|
51 |
$self->{verbose} = $verbose;
|
|
52 |
bless $self, $pkg;
|
|
53 |
return $self;
|
|
54 |
}
|
|
55 |
|
|
56 |
sub GenerateManifest {
|
|
57 |
my $self = shift;
|
|
58 |
my $comp = shift;
|
|
59 |
my $version = shift;
|
|
60 |
my $archive = shift;
|
|
61 |
|
|
62 |
my $relData;
|
|
63 |
if (defined $archive) {
|
|
64 |
$relData = RelData->OpenExternal($archive, $comp, $version);
|
|
65 |
}
|
|
66 |
else {
|
|
67 |
$relData = RelData->Open($self->{iniData}, $comp, $version, $self->{verbose});
|
|
68 |
}
|
|
69 |
|
|
70 |
$self->{'baselineName'} = $comp;
|
|
71 |
$self->{'baselineVersion'} = $version;
|
|
72 |
|
|
73 |
print "Generating Release manifest file.\n";
|
|
74 |
|
|
75 |
#Get envirnoment from baseline's reldata.
|
|
76 |
my $environment = $relData->Environment();
|
|
77 |
|
|
78 |
foreach my $thisComp (sort keys %{$environment}){
|
|
79 |
#Identify the release directory for all components.
|
|
80 |
my $thisVer = $environment->{$thisComp};
|
|
81 |
print "Reading $thisComp $thisVer.\n " if($self->{verbose});
|
|
82 |
|
|
83 |
my $relDir;
|
|
84 |
if (defined $archive) {
|
|
85 |
$relDir = File::Spec->catdir($archive, $thisComp, $thisVer);
|
|
86 |
}
|
|
87 |
else {
|
|
88 |
$relDir = $self->{iniData}->PathData->LocalArchivePathForExistingComponent($thisComp, $thisVer);
|
|
89 |
}
|
|
90 |
croak "$thisComp $thisVer doesn't exist.\n" unless(-e $relDir);
|
|
91 |
|
|
92 |
opendir(RELDIR, $relDir) or croak "Error: can't opendir $relDir\n";
|
|
93 |
my @allFiles = grep {$_ ne '.' and $_ ne '..'} map {"$relDir\\$_"} readdir(RELDIR);
|
|
94 |
close RELDIR;
|
|
95 |
$self->{components}{$thisComp}{version} = $thisVer;
|
|
96 |
#List all files from component release.
|
|
97 |
foreach my $thisFile (@allFiles) {
|
|
98 |
my $file = basename($thisFile);
|
|
99 |
next if($file eq "." or $file eq "..");
|
|
100 |
|
|
101 |
#Record size, md5 checksum and modified timestamp for all files.
|
|
102 |
open(FILEHANDLE,"$thisFile") or croak "Couldn't open file \"$thisFile\".\n";
|
|
103 |
$md5 = Digest::MD5->new;
|
|
104 |
$md5->addfile(FILEHANDLE);
|
|
105 |
close FILEHANDLE;
|
|
106 |
|
|
107 |
my $modifiedTimeStamp = Utils::FileModifiedTime($thisFile);
|
|
108 |
|
|
109 |
$self->{components}{$thisComp}{files}{$file}{+SIZE} = -s $thisFile;
|
|
110 |
$self->{components}{$thisComp}{files}{$file}{+MD5} = $md5->hexdigest;
|
|
111 |
$self->{components}{$thisComp}{files}{$file}{+MODIFIED_TIME} = $modifiedTimeStamp;
|
|
112 |
}
|
|
113 |
}
|
|
114 |
|
|
115 |
}
|
|
116 |
|
|
117 |
sub Save {
|
|
118 |
my $self = shift;
|
|
119 |
my $manifestFilePath = shift;
|
|
120 |
|
|
121 |
unless (-d $manifestFilePath) {
|
|
122 |
eval {mkpath($manifestFilePath)};
|
|
123 |
if ($@) {
|
|
124 |
my $error = $@;
|
|
125 |
$error =~ s/ at .*?(?i:manifest\.pm) line \d+$//;
|
|
126 |
die "Error: Unable to create path $manifestFilePath: $error\n";
|
|
127 |
}
|
|
128 |
}
|
|
129 |
print "Writing release manifest to $manifestFilePath path.\n ";
|
|
130 |
my $release = {
|
|
131 |
version => VERSION,
|
|
132 |
meta => { 'baseline-name' => { 'value' => $self->{'baselineName'} },
|
|
133 |
'baseline-version' => { 'value' => $self->{'baselineVersion'} },
|
|
134 |
'created-time' => { 'value' => strftime( '%Y-%m-%dT%H:%M:%S', localtime() ) } },
|
|
135 |
manifest => { component => [] }
|
|
136 |
};
|
|
137 |
my $manifest = $self->{'baselineName'} ."_".$self->{'baselineVersion'}."_manifest.xml";
|
|
138 |
my $manifestFile = File::Spec->catfile( $manifestFilePath, $manifest );
|
|
139 |
my $components = {};
|
|
140 |
foreach my $thisComp(sort keys %{$self->{components}}) {
|
|
141 |
$thisVer = $self->{components}{$thisComp}{version};
|
|
142 |
my $index = "$thisComp,$thisVer";
|
|
143 |
foreach my $thisFile (sort keys %{$self->{components}{$thisComp}{files}}) {
|
|
144 |
my $file = {
|
|
145 |
'name' => $thisFile,
|
|
146 |
'size' => $self->{components}{$thisComp}{files}{$thisFile}{+SIZE},
|
|
147 |
'md5' => $self->{components}{$thisComp}{files}{$thisFile}{+MD5},
|
|
148 |
'modified-timestamp' => $self->{components}{$thisComp}{files}{$thisFile}{+MODIFIED_TIME}
|
|
149 |
};
|
|
150 |
if (!defined $components->{$index}) {
|
|
151 |
$components->{$index} = { file => [], name => $thisComp, version => $thisVer }; # make ref
|
|
152 |
push @{$release->{manifest}{component}}, $components->{$index};
|
|
153 |
}
|
|
154 |
push @{$components->{$index}{file}}, $file;
|
|
155 |
}
|
|
156 |
}
|
|
157 |
|
|
158 |
eval {XMLout(
|
|
159 |
$release,
|
|
160 |
xmldecl => '<?xml version="1.0" ?>',
|
|
161 |
rootname => 'release',
|
|
162 |
outputfile => $manifestFile )};
|
|
163 |
|
|
164 |
croak "Error: Can't write manifest file: $@\n" if $@;
|
|
165 |
}
|
|
166 |
|
|
167 |
sub Load {
|
|
168 |
my $self = shift;
|
|
169 |
my $manifestFile = shift;
|
|
170 |
|
|
171 |
if (!-e $manifestFile) {
|
|
172 |
die "Error: Can't read manifest file '$manifestFile': File does not exist\n";
|
|
173 |
}
|
|
174 |
|
|
175 |
my %metaFieldMap = qw(baseline-name baselineName baseline-version baselineVersion created-time createdTime);
|
|
176 |
my $release = eval{XMLin(
|
|
177 |
$manifestFile,
|
|
178 |
forcearray => [ qw(component file) ],
|
|
179 |
keyattr => [])};
|
|
180 |
|
|
181 |
|
|
182 |
die "Error: Can't read manifest file '$manifestFile': $@\n" if $@;
|
|
183 |
print "Reading $manifestFile file.\n " if($self->{verbose});
|
|
184 |
|
|
185 |
for my $meta (@{$release->{meta}}) {
|
|
186 |
$self->{$metaFieldMap{$meta->{name}}} = $meta->{value};
|
|
187 |
}
|
|
188 |
foreach my $component ( @{ $release->{manifest}{component} } ) {
|
|
189 |
my $comp = $component->{'name'};
|
|
190 |
my $version = $component->{version};
|
|
191 |
$self->{components}{$comp}{version} = $version;
|
|
192 |
foreach my $file ( @{ $component->{file} } ) {
|
|
193 |
my $fileName = $file->{'name'};
|
|
194 |
$self->{components}{$comp}{files}{$fileName}{+SIZE} = $file->{+SIZE};
|
|
195 |
$self->{components}{$comp}{files}{$fileName}{+MD5} = $file->{+MD5};
|
|
196 |
$self->{components}{$comp}{files}{$fileName}{+MODIFIED_TIME} = $file->{+MODIFIED_TIME};
|
|
197 |
}
|
|
198 |
}
|
|
199 |
}
|
|
200 |
|
|
201 |
sub FileExists {
|
|
202 |
my $self = shift;
|
|
203 |
my $comp = shift;
|
|
204 |
my $file = shift;
|
|
205 |
croak "Error: Component and file name must be specified.\n" unless(defined $comp and defined $file);
|
|
206 |
return exists $self->{components}{$comp}{files}{$file};
|
|
207 |
}
|
|
208 |
|
|
209 |
1;
|
|
210 |
|
|
211 |
__END__
|
|
212 |
|
|
213 |
=head1 NAME
|
|
214 |
|
|
215 |
Symbian::CBR::Release::Manifest.pm - Provides an interface to data associated with a particular release.
|
|
216 |
|
|
217 |
=head2 new
|
|
218 |
|
|
219 |
Creates a new Symbian::CBR::Release::Manifest object. Expects to be passed a reference to an iniData object and verbose level.
|
|
220 |
|
|
221 |
=head2 GenerateManifest
|
|
222 |
|
|
223 |
Expects to be passed a component, version and optionally archive path. Generates a release manifest hash using component version and archive if provided. Otherwise uses archive specified in reltools.ini.
|
|
224 |
|
|
225 |
=head2 Save
|
|
226 |
|
|
227 |
Expects to be passed a destination path. Create destination path if destination path is not existing, and save the hash structure to manifest.xml file.
|
|
228 |
|
|
229 |
=head2 Load
|
|
230 |
|
|
231 |
Expects to be passed a manifest file path. Reads manifest file and converts into a hash structure.
|
|
232 |
|
|
233 |
=head2 FileExists
|
|
234 |
|
|
235 |
Expects to be passed a component name and file name. If file is present in the component returns 1, otherwise 0.
|
|
236 |
|
|
237 |
=head1 KNOWN BUGS
|
|
238 |
|
|
239 |
None.
|
|
240 |
|
|
241 |
=head1 COPYRIGHT
|
|
242 |
|
|
243 |
Copyright (c) 2007-2009 Nokia Corporation and/or its subsidiary(-ies).
|
|
244 |
All rights reserved.
|
|
245 |
This component and the accompanying materials are made available
|
|
246 |
under the terms of the License "Eclipse Public License v1.0"
|
|
247 |
which accompanies this distribution, and is available
|
|
248 |
at the URL "http://www.eclipse.org/legal/epl-v10.html".
|
|
249 |
|
|
250 |
Initial Contributors:
|
|
251 |
Nokia Corporation - initial contribution.
|
|
252 |
|
|
253 |
Contributors:
|
|
254 |
|
|
255 |
Description:
|
|
256 |
|
|
257 |
|
|
258 |
=cut
|