image support
authorAnas Nashif <anas.nashif@intel.com>
Fri, 4 May 2012 17:07:54 +0000 (18:07 +0100)
committerAnas Nashif <anas.nashif@intel.com>
Fri, 4 May 2012 17:07:54 +0000 (18:07 +0100)
depanneur

index 67c562c..6312242 100755 (executable)
--- a/depanneur
+++ b/depanneur
@@ -81,107 +81,14 @@ GetOptions (
     "man" => \$man,
     "overwrite" => \$overwrite,
     "suffix=s" => \$suffix,
-    ) or pod2usage (2);
-pod2usage (1) if $help;
-pod2usage (-exitstatus => 0, -verbose => 2) if $man;
-
-=pod
-
-=head1 NAME
-
- smock - Simpler mock
-
-=head1 SYNOPSIS
-
- smock.pl --arch=i386 --arch=x86_64 --distro=fedora-10 list of SRPMs ...
-
-=head1 DESCRIPTION
-
-This is a wrapper around I<mock> which lets you build a whole group of
-mutually dependent SRPMs in one go.
-
-The smock command will work out the correct order in which to build
-the SRPMs, and makes the result of previous RPM builds available as
-dependencies for later builds.
-
-Smock also works incrementally.  It won't rebuild RPMs which were
-built already in a previous run, which means if a package fails to
-build, you can just fix it and rerun the same smock command.  (In the
-unlikely case that you want to force smock to rebuild RPMs then you
-must bump the release number or delete the binary RPM from the
-localrepo directory).
-
-B<NOTE:> Please read the README file first.  You need to set up mock
-and optionally a web server before you can use this command.
-
-=head1 OPTIONS
-
-=over 4
-
-=item B<--arch>
-
-Specify the architecture(s) to build, eg. i386, x86_64.  You can
-list this option several times to build several architectures.
-
-=item B<--chain>
-
-Don't run any commands, just print the packages in the correct
-format for chain building.  See:
-L<http://fedoraproject.org/wiki/Koji/UsingKoji#Chained_builds>
-
-=item B<--distro>
-
-Specify the distribution(s) to build, eg. fedora-9, fedora-10.
-You can list this option several times to build several distributions.
-
-=item B<--dryrun>
-
-Don't run any commands, just print the packages in the order
-in which they must be built.
-
-=item B<--help>
-
-Print this help.
-
-=item B<--keepgoing>
-
-Don't exit if a package fails, but keep building.
-
-Note that this isn't always safe because new packages may be built
-against older packages, in the case where the older package couldn't
-be rebuilt because of an error.
-
-However, it is very useful.
-
-=item B<--localrepo>
-
-Local repository.  Defaults to C<$HOME/public_html/smock/yum>
-
-=item B<--man>
-
-Show this help using man.
-
-=item B<--overwrite>
-
-Overwrite existing files that are already in the repository. By default the
-build of an SRPM is skipped if there is already a package with the same name,
-version and release in the localrepo. With this option, the new build
-overwrites the old one. This may lead to unexpected results, if the new build
-does not create the same subpackages as the old one, because then the old
-subpackages will still be accessible in the repository.
-
-=item B<--suffix>
-
-Append a suffix to the mock configuration file in order to use
-a custom one.
-
-=back
-
-=cut
-
+    );
 
 my @packs = @ARGV;
 my $package_path = "";
+# FIXME
+my @archs = ("i586", "i686", "noarch");
+my $configdir="$ENV{TIZEN_BUILD_ROOT}/tools/dist-configs";
+my $bd = "$ENV{'VIRTUAL_ENV'}/usr/lib/build";
 
 if ( $path == "" ) {
     $package_path = "$ENV{TIZEN_DEVEL_ROOT}/packages";
@@ -189,9 +96,13 @@ if ( $path == "" ) {
     $package_path = $path;
 }
 
+if ($binarylist ne "") {
+    $buildall = 1;
+}
+
 if ($buildall) {
     if ($style eq "git") {
-        File::Find::find({wanted => \&wanted}, $path );
+        File::Find::find({wanted => \&git_wanted}, $path );
     } elsif ($style eq "obs") {
         File::Find::find({wanted => \&obs_wanted}, $path );
     }
@@ -200,34 +111,33 @@ if ($buildall) {
         die("Please provide a list of packages to build.");
     }
 }
-sub wanted {
+sub git_wanted {
     my ($dev,$ino,$mode,$nlink,$uid,$gid);
 
     /^packaging\z/s &&
     (($dev,$ino,$mode,$nlink,$uid,$gid) = lstat($_)) &&
     -d _
-    && fill_pacs($name);
+    && fill_packs_from_git($name);
 }
 
 sub obs_wanted {
-    /^.*\.spec\z/s && obs_pacs($name);
+    /^.*\.spec\z/s && fill_packs_from_obs($name);
 }
-sub obs_pacs()
+
+sub fill_packs_from_obs()
 {
     my $name = shift;
     $name =~ m/\.osc/ || push(@packs, $name);
 }
 
-sub fill_pacs()
+
+sub fill_pacs_from_git()
 {
     my $name = shift;
     my $pattern = "$name/*.spec";
     my @specs = glob $pattern;
     foreach my $spec (@specs) {
-        my $dist="tizen";
-        my $archs="i586";
-        my $configdir="$ENV{TIZEN_BUILD_ROOT}/tools/dist-configs";
-        my $config = Build::read_config_dist($dist, $archs, $configdir);
+        my $config = Build::read_config_dist($dist, $archs[1], $configdir);
         my $pack = Build::Rpm::parse($config, $spec);
 
         my $pwd = getcwd;
@@ -241,28 +151,13 @@ sub fill_pacs()
     }
 }
 
-sub get_lines
-{
-    local $_;
-    open PIPE, "$_[0] |" or die "$_[0]: $!";
-    my @lines;
-    foreach (<PIPE>) {
-        chomp;
-        push @lines, $_;
-    }
-    close PIPE;
-    return @lines;
-}
 
-my %packs = ();
 
-sub parse_pacs {
-    my @localArray = @_;
-    foreach my $spec (@localArray) {
-        my $dist="tizen";
-        my $archs="i586";
-        my $configdir="$ENV{TIZEN_BUILD_ROOT}/tools/dist-configs";
-        my $config = Build::read_config_dist($dist, $archs, $configdir);
+sub parse_packs {
+    my @packs = @_;
+    my %packs = ();
+    foreach my $spec (@packs) {
+        my $config = Build::read_config_dist($dist, "i586", $configdir);
         my $pack = Build::Rpm::parse($config, $spec);
         #print Dumper($pack);
         my $name = $pack->{name};
@@ -270,7 +165,6 @@ sub parse_pacs {
         my $release = $pack->{release};
         my @buildrequires = $pack->{deps};
         my @subpacks = $pack->{subpacks};
-        #print Dumper(@buildrequires);
         $packs{$name} = {
             name => $name,
             version => $version,
@@ -280,51 +174,244 @@ sub parse_pacs {
             filename => $spec
         }
     }
+    return %packs;
 }
-parse_pacs(@packs);
+
+sub expand_deps {
+    my $repo_assist = "http://download.tz.otcshare.org/live/Tizen:/Main/standard/";
+    my $rpmdeps = "$ENV{TIZEN_DEVEL_ROOT}/local/order/.repo_assist.cache";
+    if (system("$bd/createrepomddeps --cachedir=$ENV{TIZEN_DEVEL_ROOT}/local/order $repo_assist > $rpmdeps ") != 0 ) {
+        return 1;
+    }
+    my (%fn, %prov, %req);
+
+    my %packs;
+    my %repo;
+    my %ids;
+
+    my %packs_arch;
+    my %packs_done;
+    open(F, '<', $rpmdeps) || die("$rpmdeps: $!\n");
+# WARNING: the following code assumes that the 'I' tag comes last
+    my ($pkgF, $pkgP, $pkgR);
+    while(<F>) {
+      chomp;
+      if (/^F:(.*?)-\d+\/\d+\/\d+: (.*)$/) {
+        $pkgF = $2;
+        next if $fn{$1};
+        $fn{$1} = $2;
+        my $pack = $1;
+        $pack =~ /^(.*)\.([^\.]+)$/ or die;
+        push @{$packs_arch{$2}}, $1;
+      } elsif (/^P:(.*?)-\d+\/\d+\/\d+: (.*)$/) {
+        $pkgP = $2;
+        next if $prov{$1};
+        $prov{$1} = $2;
+      } elsif (/^R:(.*?)-\d+\/\d+\/\d+: (.*)$/) {
+        $pkgR = $2;
+        next if $req{$1};
+        $req{$1} = $2;
+      } elsif (/^I:(.*?)-\d+\/\d+\/\d+: (.*)$/) {
+        if ($ids{$1} && $packs_done{$1} && defined($pkgF) && defined($pkgP) && defined($pkgR)) {
+            #print STDERR  "XXXXXXXXXXXXXXXX   " . $1 . " " . $2 . "\n";
+          my $i = $1;
+          my $oldid = $ids{$1};
+          my $newid = $2;
+          if (Build::Rpm::verscmp($oldid, $newid) < 0) {
+            $ids{$i}  = $newid;
+            $fn{$i}   = $pkgF;
+            $prov{$i} = $pkgP;
+            $req{$i}  = $pkgR;
+          }
+        } else {
+          next if $ids{$1};
+          #print STDERR  "YYYYYYYYYYYYY   " . $1 . " " . $2 . "\n";
+          $ids{$1} = $2;
+        }
+        undef $pkgF;
+        undef $pkgP;
+        undef $pkgR;
+      } elsif ($_ eq 'D:') {
+        %packs_done = %ids;
+      }
+    }
+    close F;
+
+    for my $arch (@archs) {
+      $packs{$_} ||= "$_.$arch" for @{$packs_arch{$arch} || []};
+    }
+
+    my $cf = Build::read_config_dist($dist, $archs[0], $configdir);
+    $cf->{'warnings'} = 1;
+
+    my $dofileprovides = %{$cf->{'fileprovides'}};
+
+    for my $pack (keys %packs) {
+      my $r = {};
+      my (@s, $s, @pr, @re);
+      @s = split(' ', $prov{$packs{$pack}} || '');
+      while (@s) {
+        $s = shift @s;
+        next if !$dofileprovides && $s =~ /^\//;
+        if ($s =~ /^rpmlib\(/) {
+          splice(@s, 0, 2);
+          next;
+        }
+        push @pr, $s;
+        splice(@s, 0, 2) if @s && $s[0] =~ /^[<=>]/;
+      }
+      @s = split(' ', $req{$packs{$pack}} || '');
+      while (@s) {
+        $s = shift @s;
+        next if !$dofileprovides && $s =~ /^\//;
+        if ($s =~ /^rpmlib\(/) {
+          splice(@s, 0, 2);
+          next;
+        }
+        push @re, $s;
+        splice(@s, 0, 2) if @s && $s[0] =~ /^[<=>]/;
+      }
+      $r->{'provides'} = \@pr;
+      $r->{'requires'} = \@re;
+      $repo{$pack} = $r;
+    }
+    return %repo;
+}
+
+
+
+my %packs = parse_packs(@packs);
+
 
 my @tobuild = ();
 my @tofind = ();
-if ($binarylist ne "" ) {
-    if ( -e $binarylist ) {
-        open FILE, "<", $binarylist or die $!;
-        my @bins = <FILE>;
-        chomp(@bins);
-        close(FILE);
-        foreach my $b (@bins) {
-            next if $b eq "";
-            my $found = 0;
-            foreach my $name (keys %packs) {
-                my @sp = @{$packs{$name}->{subpacks}};
-                my $debuginfo = $b;
-                $debuginfo =~ s/(.*)-debuginfo/$1/;
-                $debuginfo =~ s/(.*)-debugsource/$1/;
-                $debuginfo =~ s/(.*)-docs/$1/;
-                my $nb;
-                if ($b ne $debuginfo) { 
-                    $nb = $debuginfo;
-                } else {
-                    $nb = $b;
+my @final = ();
+if ($binarylist ne "" && -e $binarylist ) 
+{
+    my %repo_assist = expand_deps();
+
+    open FILE, "<", $binarylist or die $!;
+    my @bins = <FILE>;
+    chomp(@bins);
+    close(FILE);
+    foreach my $b (@bins) {
+        next if $b eq "";
+        my $found = 0;
+        foreach my $name (keys %packs) {
+            my @sp = @{$packs{$name}->{subpacks}};
+            my $debuginfo = $b;
+            $debuginfo =~ s/(.*)-debuginfo/$1/;
+            $debuginfo =~ s/(.*)-debugsource/$1/;
+            $debuginfo =~ s/(.*)-docs/$1/;
+            my $nb;
+            if ($b ne $debuginfo) { 
+                $nb = $debuginfo;
+            } else {
+                $nb = $b;
+            }
+            if ( grep $_ eq $nb, @sp ) {
+                push(@tobuild, $name);
+                $found =1 ;
+                last;
+            } 
+        }
+        if (!$found) {
+            push(@tofind, $b);
+        }
+    }
+
+    print "Initial set:\n";
+    foreach my $p (@tobuild) {
+        print "$p, ";
+    }
+    print "\n";
+
+    foreach my $p (@tobuild) {
+        my @deps = @{$packs{$p}->{deps}};    
+        foreach my $dep (@deps) {
+            foreach my $prr (keys %repo_assist) {
+                if (grep $_ eq $dep, @{$repo_assist{$prr}->{provides}}) {
+                    my $mainp = source_of($prr, %packs);
+                    if (defined($mainp)) {
+                        push(@tobuild, $mainp);
+                        print "adding $mainp because $p needs it\n";
+                    }
                 }
-                if ( grep $_ eq $nb, @sp ) {
-                    my $fn = $packs{$name}->{filename};
-                    push(@tobuild, $fn);
-                    $found =1 ;
-                    last;
-                } 
             }
-            if (!$found) {
-                push(@tofind, $b);
+        }
+    }
+    print "Improved set:\n";
+    foreach my $p (@tobuild) {
+        print "$p, ";
+    }
+    print "\n";
+    foreach my $p (@tobuild) {
+        my @deps = @{$packs{$p}->{deps}};    
+        foreach my $dep (@deps) {
+            foreach my $prr (keys %repo_assist) {
+                if (grep $_ eq $dep, @{$repo_assist{$prr}->{provides}}) {
+                    my $mainp = source_of($prr, %packs);
+                    if (defined($mainp)) {
+                        push(@tobuild, $mainp);
+                        print "adding $mainp because $p needs it\n";
+                    }
+                }
             }
         }
+    }
+    print "Improved set:\n";
+    foreach my $p (@tobuild) {
+        print "$p, ";
+    }
+    print "\n";
+
+    foreach my $name (@tobuild) {
+        my $fn = $packs{$name}->{filename};
+        push(@final, $fn);
+    }
+
+    print "Still " . ($#tofind + 1 ) . " to find:\n";
+    print "Check if binaries are provided by a repo\n";
+    my $rpmdeps = "$ENV{TIZEN_DEVEL_ROOT}/local/order/.repo.cache";
+    open(F, '<', $rpmdeps) || die("$rpmdeps: $!\n");
+    my @bindeps = <F>;
+    close(F);
+    chomp(@bindeps);
+    my @tofind_2 = ();
+    foreach my $missing (@tofind) {
+        print "Checking for $missing: ";
+        if ( grep /^I:$missing.(i586|i686|noarch)-.*/, @bindeps ) {
+            print "provided as binary, skipping...\n";
+        } else {
+            print "can't be found.\n";
+            push(@tofind_2, $missing);
+        }
+    }
+    if ($#tofind_2 > 0 ) {
+        print "Still " . ($#tofind_2 + 1 ) . " to find:\n";
+    }
+    foreach my $m (@tofind_2) {
+        print $m . "\n";
+    }
+}
+
 
+
+
+sub source_of {
+    my ($sub, %packs) = @_;
+    foreach my $x (keys %packs) {
+        my @sp = @{$packs{$x}->{subpacks}};
+        if (grep $_ eq $sub, @sp ) {
+            return $x;
+        }
     }
+    return undef;
 }
 
-#print "To build:\n" . Dumper(@tobuild);
-#print "To find:\n" . Dumper(@tofind);
-%packs = ();
-parse_pacs(@tobuild);
+my %to_build = parse_packs(@final);
+
+#exit(1);
 
 
 sub my_mkdir
@@ -364,19 +451,20 @@ my @errors = ();
 my @done = ();
 my %caught;
 my $packages_built = 0;
+createrepo ($arch, $dist);
 while (1) {
     my @order = ();
     #my $repo = "http://biruni.local:82/Tizen:/Base/standard/";
+    #my $repo_assist = "http://biruni.local:82/Tizen:/Base/standard/";
     my $repo = "http://download.tz.otcshare.org/live/Tizen:/Base/standard/";
 
-    my $bd = "$ENV{'VIRTUAL_ENV'}/usr/lib/build";
     if ( system("$bd/createrepomddeps --cachedir=$ENV{TIZEN_DEVEL_ROOT}/local/order $repo > $ENV{TIZEN_DEVEL_ROOT}/local/order/.repo.cache ") == 0 && 
         system("$bd/createrpmdeps $localrepo/$dist/$arch/RPMS >> $ENV{TIZEN_DEVEL_ROOT}/local/order/.repo.cache ") == 0 ) {
-        foreach my $name (keys %packs) {
+        foreach my $name (keys %to_build) {
             if( ! (grep $_ eq $name, @done) && ! (grep $_ eq $name, @exclude)) {
-                my $fn = $packs{$name}->{filename};
-                my $version = $packs{$name}->{version};
-                my $release = $packs{$name}->{release};
+                my $fn = $to_build{$name}->{filename};
+                my $version = $to_build{$name}->{version};
+                my $release = $to_build{$name}->{release};
                 my $pattern = "$localrepo/$dist/src/SRPMS/$name-$version-$release.*.rpm";
                 my @binaries = glob $pattern;
                 if (@binaries != 0 && $overwrite) {
@@ -409,9 +497,9 @@ while (1) {
     }
     
     foreach my $name (@order) {
-        my $version = $packs{$name}->{version};
-        my $release = $packs{$name}->{release};
-        my $srpm_filename = $packs{$name}->{filename};
+        my $version = $to_build{$name}->{version};
+        my $release = $to_build{$name}->{release};
+        my $srpm_filename = $to_build{$name}->{filename};
 
         # Rebuild the package.
         print "*** building $name-$version-$release $arch $dist ***\n";