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;
75 $ignore_pending{"mingw32-$1"} = 1;
80 # List of packages to ignore in Fedora checkout,
81 # because they confuse this script.
96 # Count of packages by branch.
99 # Collect the package names & status from the specfiles.
103 # Fedora and EPEL packages.
104 foreach $specfile (<$fedora/*/*/*.spec>) {
105 if ($specfile =~ m{/([^/]+)/([^/]+)\.spec$}) {
106 my $specfile_name = $2;
108 if (exists $branches{$branch} &&
109 !exists $ignore_fedora{$specfile_name}) {
110 collect_specfile ($specfile, $branch);
115 # Pending packages in review.
116 foreach $specfile (<$pending/*/*.spec>) {
117 collect_specfile ($specfile, "pending");
121 sub collect_specfile {
122 my $specfile = shift;
125 # Read the specfile and parse the bits we understand.
126 my ($name, $version, $summary, $description, $url, $is_mingw,
128 @rpmdefines = (["nil", ""]);
130 open SPEC, "$specfile" or die "$specfile: $!";
132 if (/^Name:\s*(\S+)/) {
134 $name = rpmsubst ($name, 1, @rpmdefines) if $name =~ /%{/;
135 $is_mingw = 1 if $name =~ /mingw32/;
136 } elsif (/^Version:\s*(\S+)/) {
138 $version = rpmsubst ($version, 1, @rpmdefines) if $version =~ /%{/;
139 } elsif (!$url && /^URL:\s*(\S+)/) {
141 $url = rpmsubst ($url, 1, @rpmdefines) if $url =~ /%{/;
142 } elsif (!$summary && /^Summary:\s*(.*)/) {
144 #$is_mingw = 1 if $summary =~ /mingw32/i;
145 } elsif (/^(Build)?Requires:.*mingw32/) {
147 } elsif (!$description && /^%description/) {
153 $description = rpmsubst ($description, 1, @rpmdefines)
154 if $description =~ /%{/;
155 #$is_mingw = 1 if $description =~ /mingw/i;
158 # Handle simple RPM defines.
159 elsif (/^%define\s+([A-Za-z_]+)\s+(.*)/) {
162 if (only_simple_substs ($val)) {
163 $val = rpmsubst ($val, 0, @rpmdefines);
164 push @rpmdefines, [ $name, $val ];
169 # Check it's a MinGW package. If name/summary/description contains
170 # 'mingw' or it Requires/BuildRequires some mingw32-* package then we
171 # assume it's related.
173 warn "warning: $name ($branch) ignored, not a MinGW package\n";
177 # Ignore certain packages appearing in pending branch.
178 if ($branch eq "pending") {
179 if (exists $ignore_pending{$name}) {
183 # Also ignore packages marked NOT-FOR-FEDORA in pending.
184 my $dirname = $specfile;
185 $dirname =~ s{/[^/]+$}{};
186 if (-f "$dirname/NOT-FOR-FEDORA") {
191 #print "$name $version $url\n";
193 # If the package is in "pending" then there shouldn't be a
194 # Fedora package also.
195 if ($branch eq "pending" && exists $packages{$name}) {
196 die "error: pending $name is also in Fedora repo\n"
200 $packages{$name} = {} unless exists $packages{$name};
201 if (exists $packages{$name}{$branch}) {
202 die "$name ($branch) package already seen\n";
204 $packages{$name}{$branch} = {
210 description => $description,
214 sub only_simple_substs {
218 s/%\([A-Za-z_]+\)//g;
222 # Simple RPM '%define' substitutions.
229 my $var = $pair->[0];
230 my $val = $pair->[1];
236 if ($fail && (m/%{/ || m/%\(/)) {
237 die "rpmsubst: string contains undefined substitutions: $_\n";
243 sub branchsortorder {
244 $branches{$a}{sortorder} <=> $branches{$b}{sortorder}
254 print "Status of packages in Fedora, EPEL and RHEL, last updated on ";
255 print strftime("%Y-%m-%d",gmtime);
258 print "<table class=\"top_table fedoratbl\">\n";
259 print "<tr><th>Name</th>\n";
260 foreach (sort branchsortorder (keys %branches)) {
261 my $name = $branches{$_}{name};
262 my $url = $branches{$_}{url};
263 my $class = $branches{$_}{class};
265 print "<th class=\"$class\">";
266 if (exists $branches{$_}{title}) {
267 my $title = escapeHTML ($branches{$_}{title});
268 print "<a title=\"$title\" href=\"$url\">",
269 nbsp(escapeHTML($name)),
272 print "<a href=\"$url\">",
273 nbsp(escapeHTML($name)),
280 # Count the packages in each branch.
282 foreach (keys %branches) {
290 # Get the URL, summary and description from devel
291 # or pending (if possible).
292 my ($url, $summary, $description);
293 if (exists $packages{$name}{devel}) {
294 $url = $packages{$name}{devel}{url};
295 $summary = $packages{$name}{devel}{summary};
296 $description = $packages{$name}{devel}{description};
297 } elsif (exists $packages{$name}{pending}) {
298 $url = $packages{$name}{pending}{url};
299 $summary = $packages{$name}{pending}{summary};
300 $description = $packages{$name}{pending}{description};
305 if (defined $summary && defined $description) {
307 escapeHTML($description),
311 escapeHTML($summary),
314 print "<a href=\"$url\">", escapeHTML($name), "</a>";
317 print (escapeHTML($name));
322 foreach $branch (sort branchsortorder (keys %branches)) {
323 my $brclass = $branches{$branch}{class};
325 if (exists $packages{$name}{$branch}) {
328 my %r = %{$packages{$name}{$branch}};
330 my $class = "released";
331 $class = "pending" if $branch eq "pending";
332 $class = "devel" if $branch eq "devel";
333 $class = "filesystem" if $name eq "mingw32-filesystem";
335 print "<td class=\"$brclass $class\">$r{version}</td>\n";
337 # No package in this branch.
338 print "<td class=\"$brclass\"> </td>\n"
346 # Summary of packages in each branch.
347 print "<tr><td>Totals</td>";
349 foreach $branch (sort branchsortorder (keys %branches)) {
350 print "<td>$count{$branch}</td>";
358 # Define a standard package name order.
360 # "mingw32-*" packages always sort first.
361 return -1 if $a =~ /^mingw32/ && $b !~ /^mingw32/;
362 return 1 if $a !~ /^mingw32/ && $b =~ /^mingw32/;
364 return (lc($a) cmp lc($b))
368 # Collect all the specfiles, into %packages hash.
371 # Get the package names.
372 my @names = sort pkgnameorder (keys %packages);
374 # Generate the output.