evcc: 0.131.8 -> 0.131.10 (#364658)
[NixPkgs.git] / pkgs / build-support / vm / rpm / rpm-closure.pl
blob6442cd91a9575fca3e8425e457bc61588d90f266
1 use strict;
2 use XML::Simple;
3 use List::Util qw(min);
5 my @packagesFiles = ();
6 my @urlPrefixes = ();
8 # rpm-closure.pl (<package-file> <url-prefix>)+ <toplevel-pkg>+
10 while(-f $ARGV[0]) {
11 my $packagesFile = shift @ARGV;
12 my $urlPrefix = shift @ARGV;
13 push(@packagesFiles, $packagesFile);
14 push(@urlPrefixes, $urlPrefix);
18 sub rpmvercmp {
19 my ($version1, $version2) = @_;
20 my @vercmps1 = split /\./, $version1;
21 my @vercmps2 = split /\./, $version2;
22 my $l1 = scalar(@vercmps1);
23 my $l2 = scalar(@vercmps2);
24 my $l = min($l1, $l2);
26 for(my $i=0; $i<$l; $i++) {
27 my $v1 = $vercmps1[$i];
28 my $v2 = $vercmps2[$i];
30 if($v1 =~ /^[0-9]*$/ && $v2 =~ /^[0-9]*$/) {
31 if ( int($v1) > int($v2) ) {
32 return 1;
34 elsif ( int($v1) < int($v2) ) {
35 return -1;
37 } else {
38 if ( $v1 gt $v2 ) {
39 return 1;
41 elsif ( $v1 lt $v2 ) {
42 return -1;
46 if($l1 == $l2) {
47 return 0;
48 } elsif ($l1 > $l2) {
49 return 1;
50 } elsif ($l1 < $l2) {
51 return -1;
55 my @toplevelPkgs = @ARGV;
57 my @archs = split ' ', ($ENV{'archs'} or "");
59 my %pkgs;
60 for (my $i = 0; $i < scalar(@packagesFiles); $i++) {
61 my $packagesFile = $packagesFiles[$i];
62 print STDERR "parsing packages in $packagesFile...\n";
64 my $xml = XMLin($packagesFile, ForceArray => ['package', 'rpm:entry', 'file'], KeyAttr => []) or die;
66 print STDERR "$packagesFile contains $xml->{packages} packages\n";
68 foreach my $pkg (@{$xml->{'package'}}) {
69 if (scalar @archs > 0) {
70 my $arch = $pkg->{arch};
71 my $found = 0;
72 foreach my $a (@archs) { $found = 1 if $arch eq $a; }
73 next if !$found;
75 if (defined $pkgs{$pkg->{name}}) {
76 my $earlierPkg = $pkgs{$pkg->{name}};
77 print STDERR "WARNING: duplicate occurrence of package $pkg->{name}\n";
78 # <version epoch="0" ver="1.28.0" rel="2.el6"/>
79 my $cmp = rpmvercmp($pkg->{'version'}->{ver}, $earlierPkg->{'version'}->{ver});
80 if ($cmp > 0 || ($cmp == 0 && rpmvercmp($pkg->{'version'}->{rel}, $earlierPkg->{'version'}->{rel})>0)) {
81 print STDERR "WARNING: replaced package $pkg->{name} (".$earlierPkg->{'version'}->{ver}." ".$earlierPkg->{'version'}->{rel}.") with newer one (".$pkg->{'version'}->{ver}." ".$pkg->{'version'}->{rel}.")\n";
82 $pkg->{urlPrefix} = $urlPrefixes[$i];
83 $pkgs{$pkg->{name}} = $pkg;
85 next;
87 $pkg->{urlPrefix} = $urlPrefixes[$i];
88 $pkgs{$pkg->{name}} = $pkg;
92 my %provides;
93 PKG: foreach my $pkgName (sort(keys %pkgs)) {
94 #print STDERR "looking at $pkgName\n";
95 my $pkg = $pkgs{$pkgName};
97 # Skip packages that conflict with a required package.
98 my $conflicts = $pkg->{format}->{'rpm:conflicts'}->{'rpm:entry'} // [];
99 foreach my $conflict (@{$conflicts}) {
100 next if $conflict->{flags} // "" eq "LT" || $conflict->{flags} // "" eq "LE";
101 #print STDERR " $pkgName conflicts with $conflict->{name}\n";
102 if (grep { $_ eq $conflict->{name} } @toplevelPkgs) {
103 print STDERR "skipping package $pkgName because it conflicts with a required package\n";
104 next PKG;
108 my $provides = $pkg->{format}->{'rpm:provides'}->{'rpm:entry'} or die;
109 foreach my $req (@{$provides}) {
110 #print STDERR " $pkgName provides $req->{name}\n";
111 #die "multiple provides for $req->{name}" if defined $provides{$req->{name}};
112 $provides{$req->{name}} = $pkgName;
115 if (defined $pkg->{format}->{file}) {
116 foreach my $file (@{$pkg->{format}->{file}}) {
117 #print STDERR " provides file $file\n";
118 $provides{$file} = $pkgName;
124 my %donePkgs;
125 my @needed = ();
127 sub closePackage {
128 my $pkgName = shift;
130 return if defined $donePkgs{$pkgName};
131 $donePkgs{$pkgName} = 1;
133 print STDERR ">>> $pkgName\n";
135 my $pkg = $pkgs{$pkgName} or die "package $pkgName doesn't exist";
137 my $requires = $pkg->{format}->{'rpm:requires'}->{'rpm:entry'} || [];
139 my @deps = ();
140 foreach my $req (@{$requires}) {
141 next if $req->{name} =~ /^rpmlib\(/;
142 #print STDERR " needs $req->{name}\n";
143 my $provider = $provides{$req->{name}};
144 if (!defined $provider) {
145 print STDERR " WARNING: no provider for $req->{name}\n";
146 next;
148 #print STDERR " satisfied by $provider\n";
149 push @deps, $provider;
152 closePackage($_) foreach @deps;
154 push @needed, $pkgName;
158 foreach my $pkgName (@toplevelPkgs) {
159 closePackage $pkgName;
163 # Generate the output Nix expression.
164 print "# This is a generated file. Do not modify!\n";
165 print "# Following are the RPM packages constituting the closure of: @toplevelPkgs\n\n";
166 print "{fetchurl}:\n\n";
167 print "[\n\n";
169 foreach my $pkgName (@needed) {
170 my $pkg = $pkgs{$pkgName};
171 print " (fetchurl {\n";
172 print " url = $pkg->{urlPrefix}/$pkg->{location}->{href};\n";
173 if ($pkg->{checksum}->{type} eq "sha") {
174 print " sha1 = \"$pkg->{checksum}->{content}\";\n";
175 } elsif ($pkg->{checksum}->{type} eq "sha256") {
176 print " sha256 = \"$pkg->{checksum}->{content}\";\n";
177 } else {
178 die "unsupported hash type";
180 print " })\n";
181 print "\n";
184 print "]\n";