|
1 #!perl -w |
|
2 |
|
3 # Copyright (c) 2009 Symbian Foundation Ltd |
|
4 # This component and the accompanying materials are made available |
|
5 # under the terms of the License "Eclipse Public License v1.0" |
|
6 # which accompanies this distribution, and is available |
|
7 # at the URL "http://www.eclipse.org/legal/epl-v10.html". |
|
8 # |
|
9 # Initial Contributors: |
|
10 # Symbian Foundation Ltd - initial contribution. |
|
11 # |
|
12 # Contributors: |
|
13 # |
|
14 # Description: |
|
15 # Automates the creation of part of the PDK Release Notes: "Mercurial Comparison with PDK XXXXX" |
|
16 |
|
17 use strict; |
|
18 use XML::Parser; |
|
19 |
|
20 my $sourcesCsv = shift or die "First argument must be sources.csv file for build being built/released\n"; |
|
21 my $sysDef = shift or die "Second argument must be system definition file\n"; |
|
22 my $previousPdkLabel = shift or die "Third argument must be hg tag to compare against\n"; |
|
23 defined shift and die "No more than three arguments please\n"; |
|
24 |
|
25 my $packages = { current => {}, previous => {} }; |
|
26 |
|
27 # Load current manifest |
|
28 open(my $manifest, "<", $sourcesCsv) or die; |
|
29 my @manifest = <$manifest>; |
|
30 close $manifest; |
|
31 populate($packages->{current}, @manifest); |
|
32 |
|
33 # Load prev manifest |
|
34 @manifest = `hg cat -r $previousPdkLabel $sourcesCsv`; |
|
35 populate($packages->{previous}, @manifest); |
|
36 |
|
37 my $xml = XML::Parser->new(Style => "Objects") or die; |
|
38 # Load current names from current system definition |
|
39 my $tree = $xml->parsefile($sysDef); |
|
40 populateNames($packages->{current}, $tree); |
|
41 # Load previous names from previous system definition |
|
42 eval { $tree = $xml->parsestring(scalar `hg cat -r $previousPdkLabel $sysDef`) } or die $!; |
|
43 populateNames($packages->{previous}, $tree); |
|
44 |
|
45 # Output release note info... |
|
46 |
|
47 my $currPackageCount = scalar keys %{$packages->{current}}; |
|
48 my $prevPackageCount = scalar keys %{$packages->{previous}}; |
|
49 print <<EOT; |
|
50 == Packages == |
|
51 |
|
52 This section provides general information on the packages included in this PDK release compared to '''$previousPdkLabel'''. |
|
53 |
|
54 Number total of packages in this PDK release is: '''$currPackageCount''' |
|
55 |
|
56 Number total of packages in $previousPdkLabel is: '''$prevPackageCount''' |
|
57 |
|
58 EOT |
|
59 |
|
60 my @addedPackages = sort { packageSort($packages->{current}) } grep { !exists $packages->{previous}->{$_} } keys %{$packages->{current}}; |
|
61 my $addedPackageCount = scalar @addedPackages; |
|
62 print <<EOT; |
|
63 === Packages added === |
|
64 |
|
65 Number total of packages added is: '''$addedPackageCount''' |
|
66 |
|
67 EOT |
|
68 foreach (@addedPackages) |
|
69 { |
|
70 print "==== $packages->{current}->{$_}->{name} ([$packages->{current}->{$_}->{url} $packages->{current}->{$_}->{path}]) ====\n"; |
|
71 } |
|
72 print "\n" if @addedPackages; |
|
73 |
|
74 my @removedPackages = sort { packageSort($packages->{previous}) } grep { !exists $packages->{current}->{$_} } keys %{$packages->{previous}}; |
|
75 my $removedPackageCount = scalar @removedPackages; |
|
76 print <<EOT; |
|
77 === Packages removed === |
|
78 |
|
79 Number total of packages removed is: '''$removedPackageCount''' |
|
80 |
|
81 EOT |
|
82 foreach (@removedPackages) |
|
83 { |
|
84 print "==== $packages->{previous}->{$_}->{name} ([$packages->{previous}->{$_}->{url} $packages->{previous}->{$_}->{path}]) ====\n"; |
|
85 } |
|
86 print "\n" if @removedPackages; |
|
87 |
|
88 my @movedPackages = sort { packageSort($packages->{current}) } grep { inPrev($_) && $packages->{current}->{$_}->{path} ne $packages->{previous}->{$_}->{path} } keys %{$packages->{current}}; |
|
89 my $movedPackageCount = scalar @movedPackages; |
|
90 print <<EOT; |
|
91 === Packages moved === |
|
92 |
|
93 Number total of packages moved is: '''$movedPackageCount''' |
|
94 |
|
95 EOT |
|
96 foreach (@movedPackages) |
|
97 { |
|
98 print "==== $packages->{current}->{$_}->{name} ([$packages->{previous}->{$_}->{url} $packages->{previous}->{$_}->{path}] to [$packages->{current}->{$_}->{url} $packages->{current}->{$_}->{path}]) ====\n"; |
|
99 } |
|
100 print "\n" if @movedPackages; |
|
101 |
|
102 my @openedPackages = sort { packageSort($packages->{current}) } grep { inPrev($_) && $packages->{current}->{$_}->{license} eq "oss" && $packages->{previous}->{$_}->{license} eq "sfl" } keys %{$packages->{current}}; |
|
103 my $openedPackageCount = scalar @openedPackages; |
|
104 if ($openedPackageCount) |
|
105 { |
|
106 print <<EOT; |
|
107 === Packages newly released under a fully Open license === |
|
108 |
|
109 Number total of packages relicensed is: '''$openedPackageCount''' |
|
110 |
|
111 EOT |
|
112 foreach (@openedPackages) |
|
113 { |
|
114 print "==== $packages->{current}->{$_}->{name} ([$packages->{current}->{$_}->{url} $packages->{current}->{$_}->{path}]) ====\n"; |
|
115 } |
|
116 print "\n"; |
|
117 } |
|
118 |
|
119 print <<EOT; |
|
120 == FCLs == |
|
121 |
|
122 This PDK was built using the FCL versions of the packages listed below: for each one we list the changes in the FCL which are not in the MCL. |
|
123 |
|
124 The previous PDK also involved some FCLs, so we indicate which problems are now fixed in the MCL, and which FCLs are new to this build. |
|
125 |
|
126 Cloning the source from Mercurial is made more awkward by using a mixture of MCLs and FCLs, but we provide a tool to help - see [[How to build the Platform]] for details. |
|
127 |
|
128 EOT |
|
129 # Newly from FCL |
|
130 foreach (sort { packageSort($packages->{current}) } grep { inPrev($_) && $packages->{previous}->{$_}->{codeline} eq "MCL" && $packages->{current}->{$_}->{codeline} eq "FCL" } keys %{$packages->{current}}) |
|
131 { |
|
132 print "==== $packages->{current}->{$_}->{name} ([$packages->{current}->{$_}->{url} $packages->{current}->{$_}->{path}]) -- NEW ====\n"; |
|
133 } |
|
134 # Still from FCL |
|
135 foreach (sort { packageSort($packages->{current}) } grep {inPrev($_) && $packages->{previous}->{$_}->{codeline} eq "FCL" && $packages->{current}->{$_}->{codeline} eq "FCL"} keys %{$packages->{current}}) |
|
136 { |
|
137 print "==== $packages->{current}->{$_}->{name} ([$packages->{current}->{$_}->{url} $packages->{current}->{$_}->{path}]) ====\n"; |
|
138 } |
|
139 |
|
140 print "\n=== FCLs used in PDK_2.0.0 but no longer needed ===\n\n"; |
|
141 my @revertedToMCL = sort { packageSort($packages->{current}) } grep { inPrev($_) && $packages->{previous}->{$_}->{codeline} eq "FCL" && $packages->{current}->{$_}->{codeline} eq "MCL" } keys %{$packages->{current}}; |
|
142 print "(none)\n" unless @revertedToMCL; |
|
143 foreach (@revertedToMCL) |
|
144 { |
|
145 print "==== $packages->{current}->{$_}->{name} ([$packages->{current}->{$_}->{url} $packages->{current}->{$_}->{path}]) ====\n"; |
|
146 } |
|
147 print "\n"; |
|
148 exit(0); |
|
149 |
|
150 sub populate |
|
151 { |
|
152 my $hash = shift; |
|
153 my @entries = @_; |
|
154 |
|
155 # Discard the column headings |
|
156 shift @entries; |
|
157 |
|
158 foreach my $entry (@entries) |
|
159 { |
|
160 chomp $entry; |
|
161 my ($repo) = $entry =~ m{^(.*?),}; |
|
162 my ($packageId) = $repo =~ m{/(\w+)/?$}; |
|
163 my ($codeline) = $repo =~ m{/(MCL|FCL)/}; |
|
164 # Skip the RnD repos and other complications |
|
165 next unless $codeline; |
|
166 my ($license, $path) = $repo =~ m{/([^/\\]*)/$codeline/(.+?)/?$}; |
|
167 my $url = "http://developer.symbian.org/$license/$codeline/$path"; |
|
168 $hash->{$packageId} = {license => $license, codeline => $codeline, path => $path, name => "''$packageId''", url => $url, sortKey => lc $packageId}; |
|
169 } |
|
170 } |
|
171 |
|
172 sub populateNames |
|
173 { |
|
174 my $packages = shift; |
|
175 my $itemsUnderThisElement = shift; |
|
176 foreach (@$itemsUnderThisElement) |
|
177 { |
|
178 if (ref $_) |
|
179 { |
|
180 if (ref $_ eq "main::block" || ref $_ eq "main::package") |
|
181 { |
|
182 if (exists $packages->{$_->{name}}) |
|
183 { |
|
184 $packages->{$_->{name}}->{name} = $_->{"long-name"}; |
|
185 $packages->{$_->{name}}->{sortKey} = lc $_->{"long-name"}; |
|
186 } |
|
187 } |
|
188 else |
|
189 { |
|
190 populateNames($packages, $_->{Kids}); |
|
191 } |
|
192 } |
|
193 } |
|
194 } |
|
195 |
|
196 sub inPrev |
|
197 { |
|
198 my $id = shift; |
|
199 exists $packages->{previous}->{$id}; |
|
200 } |
|
201 |
|
202 sub packageSort |
|
203 { |
|
204 my $details = shift; |
|
205 $details->{$a}->{sortKey} cmp $details->{$b}->{sortKey}; |
|
206 } |
|
207 |
|
208 |