3 # Produce a status page for all current and pending Fedora MinGW packages.
4 # By Richard W.M. Jones <rjones@redhat.com>
7 # . All Fedora MinGW packages have to be checked out
8 # under $HOME/d/fedora.
9 # . All pending packages to be available in
10 # $HOME/d/fedora-mingw--devel.
12 # The output is normally placed here:
13 # http://annexia.org/fedora_mingw
15 # Checks that the package build-requires mingw32-* in order to know if
16 # it's an MinGW-related package.
18 # Only recognizes the Fedora/EPEL branches listed below and ignores
19 # anything else. There are no MinGW packages in RHEL at this time.
21 # XXX This script is a bit crap. Instead of using lame specfile
22 # parsing, this should be generated from the SRPMs.
26 use POSIX qw(strftime);
27 use CGI qw/:standard/;
29 my $home = $ENV{HOME};
30 if ($home =~ m/(.*)/) { $home = $1; }
32 my $fedora = $home . "/d/fedora";
33 my $pending = $home . "/d/fedora-mingw--devel";
35 chdir $pending or die "$pending: $!\n";
40 url => "http://fedoraproject.org/wiki/EPEL",
41 title => "Packages for Red Hat Enterprise Linux 5",
47 url => "http://fedoraproject.org/",
53 url => "http://fedoraproject.org/wiki/Releases/Rawhide",
54 title => "Fedora 11 in development a.k.a. Rawhide",
60 url => "https://bugzilla.redhat.com/buglist.cgi?version=rawhide&component=Package+Review&target_milestone=&bug_status=NEW&bug_status=ASSIGNED&bug_status=NEEDINFO&bug_status=MODIFIED&short_desc_type=allwordssubstr&short_desc=mingw32&long_desc_type=allwordssubstr&long_desc=",
66 # List of packages to ignore in pending.
67 my %ignore_pending = ();
68 open IGNORE, "IGNORE" or die "IGNORE: $!\n";
70 next if /^\#/ || /^$/;
72 $ignore_pending{"mingw32-$1"} = 1;
76 # List of packages to ignore in Fedora checkout,
77 # because they confuse this script.
91 # Count of packages by branch.
94 # Collect the package names & status from the specfiles.
98 # Fedora and EPEL packages.
99 foreach $specfile (<$fedora/*/*/*.spec>) {
100 if ($specfile =~ m{/([^/]+)/([^/]+)\.spec$}) {
101 my $specfile_name = $2;
103 if (exists $branches{$branch} &&
104 !exists $ignore_fedora{$specfile_name}) {
105 collect_specfile ($specfile, $branch);
110 # Pending packages in review.
111 foreach $specfile (<$pending/*/*.spec>) {
112 collect_specfile ($specfile, "pending");
116 sub collect_specfile {
117 my $specfile = shift;
120 # Read the specfile and parse the bits we understand.
121 my ($name, $version, $summary, $description, $url, $is_mingw,
123 @rpmdefines = (["nil", ""]);
125 open SPEC, "$specfile" or die "$specfile: $!";
127 if (/^Name:\s*(\S+)/) {
129 $name = rpmsubst ($name, 1, @rpmdefines) if $name =~ /%{/;
130 $is_mingw = 1 if $name =~ /mingw32/;
131 } elsif (/^Version:\s*(\S+)/) {
133 $version = rpmsubst ($version, 1, @rpmdefines) if $version =~ /%{/;
134 } elsif (!$url && /^URL:\s*(\S+)/) {
136 $url = rpmsubst ($url, 1, @rpmdefines) if $url =~ /%{/;
137 } elsif (!$summary && /^Summary:\s*(.*)/) {
139 #$is_mingw = 1 if $summary =~ /mingw32/i;
140 } elsif (/^(Build)?Requires:.*mingw32/) {
142 } elsif (!$description && /^%description/) {
148 $description = rpmsubst ($description, 1, @rpmdefines)
149 if $description =~ /%{/;
150 #$is_mingw = 1 if $description =~ /mingw/i;
153 # Handle simple RPM defines.
154 elsif (/^%define\s+([A-Za-z_]+)\s+(.*)/) {
157 if (only_simple_substs ($val)) {
158 $val = rpmsubst ($val, 0, @rpmdefines);
159 push @rpmdefines, [ $name, $val ];
164 # Check it's a MinGW package. If name/summary/description contains
165 # 'mingw' or it Requires/BuildRequires some mingw32-* package then we
166 # assume it's related.
168 warn "warning: $name ($branch) ignored, not a MinGW package\n";
172 # Ignore certain packages appearing in pending branch.
173 if ($branch eq "pending") {
174 if (exists $ignore_pending{$name}) {
178 # Also ignore packages marked NOT-FOR-FEDORA in pending.
179 my $dirname = $specfile;
180 $dirname =~ s{/[^/]+$}{};
181 if (-f "$dirname/NOT-FOR-FEDORA") {
186 #print "$name $version $url\n";
188 # If the package is in "pending" then there shouldn't be a
189 # Fedora package also.
190 if ($branch eq "pending" && exists $packages{$name}) {
191 die "error: pending $name is also in Fedora repo\n"
195 $packages{$name} = {} unless exists $packages{$name};
196 if (exists $packages{$name}{$branch}) {
197 die "$name ($branch) package already seen\n";
199 $packages{$name}{$branch} = {
205 description => $description,
209 sub only_simple_substs {
213 s/%\([A-Za-z_]+\)//g;
217 # Simple RPM '%define' substitutions.
224 my $var = $pair->[0];
225 my $val = $pair->[1];
231 if ($fail && (m/%{/ || m/%\(/)) {
232 die "rpmsubst: string contains undefined substitutions: $_\n";
238 sub branchsortorder {
239 $branches{$a}{sortorder} <=> $branches{$b}{sortorder}
249 print "Status of packages in Fedora, EPEL and RHEL, last updated on ";
250 print strftime("%Y-%m-%d",gmtime);
253 print "<table class=\"top_table fedoratbl\">\n";
254 print "<tr><th>Name</th>\n";
255 foreach (sort branchsortorder (keys %branches)) {
256 my $name = $branches{$_}{name};
257 my $url = $branches{$_}{url};
258 my $class = $branches{$_}{class};
260 print "<th class=\"$class\">";
261 if (exists $branches{$_}{title}) {
262 my $title = escapeHTML ($branches{$_}{title});
263 print "<a title=\"$title\" href=\"$url\">",
264 nbsp(escapeHTML($name)),
267 print "<a href=\"$url\">",
268 nbsp(escapeHTML($name)),
275 # Count the packages in each branch.
277 foreach (keys %branches) {
285 # Get the URL, summary and description from devel
286 # or pending (if possible).
287 my ($url, $summary, $description);
288 if (exists $packages{$name}{devel}) {
289 $url = $packages{$name}{devel}{url};
290 $summary = $packages{$name}{devel}{summary};
291 $description = $packages{$name}{devel}{description};
292 } elsif (exists $packages{$name}{pending}) {
293 $url = $packages{$name}{pending}{url};
294 $summary = $packages{$name}{pending}{summary};
295 $description = $packages{$name}{pending}{description};
300 if (defined $summary && defined $description) {
302 escapeHTML($description),
306 escapeHTML($summary),
309 print "<a href=\"$url\">", escapeHTML($name), "</a>";
312 print (escapeHTML($name));
317 foreach $branch (sort branchsortorder (keys %branches)) {
318 my $brclass = $branches{$branch}{class};
320 if (exists $packages{$name}{$branch}) {
323 my %r = %{$packages{$name}{$branch}};
325 my $class = "released";
326 $class = "pending" if $branch eq "pending";
327 $class = "devel" if $branch eq "devel";
328 $class = "filesystem" if $name eq "mingw32-filesystem";
330 print "<td class=\"$brclass $class\">$r{version}</td>\n";
332 # No package in this branch.
333 print "<td class=\"$brclass\"> </td>\n"
341 # Summary of packages in each branch.
342 print "<tr><td>Totals</td>";
344 foreach $branch (sort branchsortorder (keys %branches)) {
345 print "<td>$count{$branch}</td>";
353 # Define a standard package name order.
355 # "mingw32-*" packages always sort first.
356 return -1 if $a =~ /^mingw32/ && $b !~ /^mingw32/;
357 return 1 if $a !~ /^mingw32/ && $b =~ /^mingw32/;
359 return (lc($a) cmp lc($b))
363 # Collect all the specfiles, into %packages hash.
366 # Get the package names.
367 my @names = sort pkgnameorder (keys %packages);
369 # Generate the output.