Ignore NSS tarballs.
[fedora-mingw.git] / show-build-order.pl
1 #!/usr/bin/perl -w
2 #
3 # Show the order to build Fedora MinGW spec files.
4 # By Richard Jones <rjones@redhat.com>
5
6 use strict;
7
8 my $debug = 0;
9 chomp (my $pwd = `pwd`);
10
11 sub main {
12     my %br;
13     my $specfile;
14     my $packagename;
15
16     my @specfiles = <*/*.spec>;
17
18     # Get BRs for each specfile.
19     foreach $specfile (@specfiles) {
20         $packagename = $specfile;
21         $packagename =~ s{^.*/}{};
22         $packagename =~ s{\.spec$}{};
23
24         $br{$packagename} = [];
25
26         open SPEC,$specfile or die "$specfile: $!";
27         while (<SPEC>) {
28             if (m/^BuildRequires:(.*)/) {
29                 my $brs = $1;
30                 my @brs = eval 'split /,/, $brs';
31                 @brs = map { trim ($_) } @brs;
32                 @brs = map { remove_trailers ($_) } @brs;
33                 unshift @{$br{$packagename}}, @brs;
34             }
35         }
36
37         if ($debug) {
38             print "BRs for $packagename = [";
39             print (join "],[", @{$br{$packagename}});
40             print "]\n";
41         }
42     }
43
44     foreach $packagename (keys %br) {
45         my @brs = @{$br{$packagename}};
46         @brs = uniq (sort @brs);
47         $br{$packagename} = \@brs;
48
49         if ($debug) {
50             print "uniq BRs for $packagename = [";
51             print (join "],[", @{$br{$packagename}});
52             print "]\n";
53         }
54     }
55
56     # Some packages we want to ignore for now.
57     delete $br{"mingw32-cyrus-sasl"};
58     delete $br{"mingw32-wix"};
59     delete $br{"mingw32-example"};
60     delete $br{"mingw32-gdb"};
61     delete $br{"mingw32-python"};
62     delete $br{"mingw32-ocaml"};
63     delete $br{"mingw32-curl"};
64     delete $br{"mingw32-pidgin"};
65     delete $br{"mingw32-nspr"};
66     delete $br{"mingw32-nss"};
67
68     # There is a dependency loop (gcc -> runtime/w32api -> gcc)
69     # which has to be manually resolved below.  Break that loop.
70     my @gcc_brs = @{$br{"mingw32-gcc"}};
71     @gcc_brs = grep { $_ ne "mingw32-runtime" && $_ ne "mingw32-w32api" } @gcc_brs;
72     $br{"mingw32-gcc"} = \@gcc_brs;
73
74     # Use tsort to generate a topological ordering.
75     open TSORT,">/tmp/tsort.tmp" or die "/tmp/tsort.tmp: $!";
76     foreach $packagename (keys %br) {
77         my $br;
78         foreach $br (@{$br{$packagename}}) {
79             print "writing $br $packagename\n" if $debug;
80             print TSORT $br, " ", $packagename, "\n";
81         }
82     }
83     close TSORT;
84
85     system ("tsort < /tmp/tsort.tmp > /tmp/tsort2.tmp") == 0
86         or die "system: tsort: $?";
87
88     # Read in list of packages.
89     open PACKAGES,"/tmp/tsort2.tmp" or die "/tmp/tsort2.tmp: $!";
90     unless ($debug) {
91         unlink "/tmp/tsort.tmp";
92         unlink "/tmp/tsort2.tmp";
93     }
94
95     my %installed;
96
97     while (<PACKAGES>) {
98         chomp;
99         if (/^mingw32-(.*)/ && exists $br{$_}) {
100             $packagename = $_;
101             my $dirname = $1;
102
103             print "considering $packagename\n" if $debug;
104
105             my @brs = @{$br{$packagename}};
106
107             # Are all BR RPMs installed?
108             my $br;
109             foreach $br (@brs) {
110                 if (! rpm_installed ($br) && !exists $installed{$br}) {
111                     print "# as root: rpm -Uvh $br*.rpm\n";
112                     $installed{$br} = 1;
113                 }
114             }
115
116             # Special case for mingw32-gcc deps.
117             if ($packagename eq "mingw32-gcc" &&
118                 (!rpm_installed ("mingw32-runtime") ||
119                  !rpm_installed ("mingw32-w32api"))) {
120                 print "rpmbuild -ba --define \"_sourcedir $pwd/runtime-bootstrap\" runtime-bootstrap/mingw32-runtime-bootstrap.spec\n";
121                 print "# as root: rpm -Uvh mingw32-runtime-bootstrap*.rpm\n";
122                 $installed{"mingw32-runtime-bootstrap"} = 1;
123
124                 print "rpmbuild -ba --define \"_sourcedir $pwd/w32api-bootstrap\" w32api-bootstrap/mingw32-w32api-bootstrap.spec\n";
125                 print "# as root: rpm -Uvh mingw32-w32api-bootstrap*.rpm\n";
126                 $installed{"mingw32-w32api-bootstrap"} = 1;
127             }
128
129             # Spec file.
130             my $specfile = "$dirname/$packagename.spec";
131             die "$specfile: file missing" unless -f $specfile;
132
133             my $rpmbuild =
134                 "rpmbuild -ba --define \"_sourcedir $pwd/$dirname\"";
135             print "$rpmbuild $specfile\n";
136         }
137     }
138 }
139
140 sub rpm_installed {
141     local $_ = shift;
142     return (system ("rpm -q $_ > /dev/null") == 0);
143 }
144
145 sub trim {
146     local $_ = shift;
147     s/^\s+//;
148     s/\s+$//;
149     return $_;
150 }
151
152 sub uniq {
153     my %hash;
154     local $_;
155
156     $hash{$_} = 1 foreach (@_);
157     return sort keys %hash;
158 }
159
160 # foo >= 3.1 --> foo
161 # foo-devel --> foo
162 # and a few other exceptions
163 sub remove_trailers {
164     local $_ = shift;
165     s/\s*[<>=].*$//;
166
167     # -devel & -doc come from the base package.
168     s/-devel$//;
169     s/-doc$//;
170
171     # mingw32-gcc-c++ etc.
172     s/^mingw32-gcc-.*/mingw32-gcc/;
173
174     return $_;
175 }
176
177 &main()