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.
92 # Count of packages by branch.
95 # Collect the package names & status from the specfiles.
99 # Fedora and EPEL packages.
100 foreach $specfile (<$fedora/*/*/*.spec>) {
101 if ($specfile =~ m{/([^/]+)/([^/]+)\.spec$}) {
102 my $specfile_name = $2;
104 if (exists $branches{$branch} &&
105 !exists $ignore_fedora{$specfile_name}) {
106 collect_specfile ($specfile, $branch);
111 # Pending packages in review.
112 foreach $specfile (<$pending/*/*.spec>) {
113 collect_specfile ($specfile, "pending");
117 sub collect_specfile {
118 my $specfile = shift;
121 # Read the specfile and parse the bits we understand.
122 my ($name, $version, $summary, $description, $url, $is_mingw,
124 @rpmdefines = (["nil", ""]);
126 open SPEC, "$specfile" or die "$specfile: $!";
128 if (/^Name:\s*(\S+)/) {
130 $name = rpmsubst ($name, 1, @rpmdefines) if $name =~ /%{/;
131 $is_mingw = 1 if $name =~ /mingw32/;
132 } elsif (/^Version:\s*(\S+)/) {
134 $version = rpmsubst ($version, 1, @rpmdefines) if $version =~ /%{/;
135 } elsif (!$url && /^URL:\s*(\S+)/) {
137 $url = rpmsubst ($url, 1, @rpmdefines) if $url =~ /%{/;
138 } elsif (!$summary && /^Summary:\s*(.*)/) {
140 #$is_mingw = 1 if $summary =~ /mingw32/i;
141 } elsif (/^(Build)?Requires:.*mingw32/) {
143 } elsif (!$description && /^%description/) {
149 $description = rpmsubst ($description, 1, @rpmdefines)
150 if $description =~ /%{/;
151 #$is_mingw = 1 if $description =~ /mingw/i;
154 # Handle simple RPM defines.
155 elsif (/^%define\s+([A-Za-z_]+)\s+(.*)/) {
158 if (only_simple_substs ($val)) {
159 $val = rpmsubst ($val, 0, @rpmdefines);
160 push @rpmdefines, [ $name, $val ];
165 # Check it's a MinGW package. If name/summary/description contains
166 # 'mingw' or it Requires/BuildRequires some mingw32-* package then we
167 # assume it's related.
169 warn "warning: $name ($branch) ignored, not a MinGW package\n";
173 # Ignore certain packages appearing in pending branch.
174 if ($branch eq "pending") {
175 if (exists $ignore_pending{$name}) {
179 # Also ignore packages marked NOT-FOR-FEDORA in pending.
180 my $dirname = $specfile;
181 $dirname =~ s{/[^/]+$}{};
182 if (-f "$dirname/NOT-FOR-FEDORA") {
187 #print "$name $version $url\n";
189 # If the package is in "pending" then there shouldn't be a
190 # Fedora package also.
191 if ($branch eq "pending" && exists $packages{$name}) {
192 die "error: pending $name is also in Fedora repo\n"
196 $packages{$name} = {} unless exists $packages{$name};
197 if (exists $packages{$name}{$branch}) {
198 die "$name ($branch) package already seen\n";
200 $packages{$name}{$branch} = {
206 description => $description,
210 sub only_simple_substs {
214 s/%\([A-Za-z_]+\)//g;
218 # Simple RPM '%define' substitutions.
225 my $var = $pair->[0];
226 my $val = $pair->[1];
232 if ($fail && (m/%{/ || m/%\(/)) {
233 die "rpmsubst: string contains undefined substitutions: $_\n";
239 sub branchsortorder {
240 $branches{$a}{sortorder} <=> $branches{$b}{sortorder}
250 print "Status of packages in Fedora, EPEL and RHEL, last updated on ";
251 print strftime("%Y-%m-%d",gmtime);
254 print "<table class=\"top_table fedoratbl\">\n";
255 print "<tr><th>Name</th>\n";
256 foreach (sort branchsortorder (keys %branches)) {
257 my $name = $branches{$_}{name};
258 my $url = $branches{$_}{url};
259 my $class = $branches{$_}{class};
261 print "<th class=\"$class\">";
262 if (exists $branches{$_}{title}) {
263 my $title = escapeHTML ($branches{$_}{title});
264 print "<a title=\"$title\" href=\"$url\">",
265 nbsp(escapeHTML($name)),
268 print "<a href=\"$url\">",
269 nbsp(escapeHTML($name)),
276 # Count the packages in each branch.
278 foreach (keys %branches) {
286 # Get the URL, summary and description from devel
287 # or pending (if possible).
288 my ($url, $summary, $description);
289 if (exists $packages{$name}{devel}) {
290 $url = $packages{$name}{devel}{url};
291 $summary = $packages{$name}{devel}{summary};
292 $description = $packages{$name}{devel}{description};
293 } elsif (exists $packages{$name}{pending}) {
294 $url = $packages{$name}{pending}{url};
295 $summary = $packages{$name}{pending}{summary};
296 $description = $packages{$name}{pending}{description};
301 if (defined $summary && defined $description) {
303 escapeHTML($description),
307 escapeHTML($summary),
310 print "<a href=\"$url\">", escapeHTML($name), "</a>";
313 print (escapeHTML($name));
318 foreach $branch (sort branchsortorder (keys %branches)) {
319 my $brclass = $branches{$branch}{class};
321 if (exists $packages{$name}{$branch}) {
324 my %r = %{$packages{$name}{$branch}};
326 my $class = "released";
327 $class = "pending" if $branch eq "pending";
328 $class = "devel" if $branch eq "devel";
329 $class = "filesystem" if $name eq "mingw32-filesystem";
331 print "<td class=\"$brclass $class\">$r{version}</td>\n";
333 # No package in this branch.
334 print "<td class=\"$brclass\"> </td>\n"
342 # Summary of packages in each branch.
343 print "<tr><td>Totals</td>";
345 foreach $branch (sort branchsortorder (keys %branches)) {
346 print "<td>$count{$branch}</td>";
354 # Define a standard package name order.
356 # "mingw32-*" packages always sort first.
357 return -1 if $a =~ /^mingw32/ && $b !~ /^mingw32/;
358 return 1 if $a !~ /^mingw32/ && $b =~ /^mingw32/;
360 return (lc($a) cmp lc($b))
364 # Collect all the specfiles, into %packages hash.
367 # Get the package names.
368 my @names = sort pkgnameorder (keys %packages);
370 # Generate the output.