"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";
$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 );
}
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;
}
}
-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};
my $release = $pack->{release};
my @buildrequires = $pack->{deps};
my @subpacks = $pack->{subpacks};
- #print Dumper(@buildrequires);
$packs{$name} = {
name => $name,
version => $version,
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
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) {
}
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";