#!/usr/bin/perl -w # # rpmbuildupdate by Julien Danjou # # Copyright (c) 2003 by MandrakeSoft # # Permission to use, copy, modify, and distribute this software and its # documentation under the terms of the GNU General Public License is hereby # granted. No representations are made about the suitability of this software # for any purpose. It is provided "as is" without express or implied warranty. # See the GNU General Public License for more details. # use strict; use AppConfig; my %config; sub build_from_src { $_ = shift; my $nv = shift; my $b = qx[basename $_]; if($b =~ m|^(.*)-([^-]+)-([^-]+)\.[^\.]+\.rpm|) { &build($1, $nv, $_); } } sub build { my $pkg = shift; my $newversion = shift; my $pkgrpm = shift; my $found = 0; my ($version, $release); my ($spec, @url, @rpms, %specvars); print "===> Building $pkg $newversion\n"; my $pkge = $pkg; $pkge =~ s/\+/\\\+/; # Search for file if we do not use --src if(!$config{src}) { opendir(MP, $config{srpms}) or die "$config{srpms} is not a directory"; @rpms = readdir(MP); foreach (@rpms) { if(m|^($pkge)-([^-]+)-([^-]+)\.[^\.]+\.rpm|) { $pkgrpm = $_; $version = $2; $release = $3; $found = 1; last;} } closedir(MP); if($found == 0) { print "Package $pkg has no source, skipping.\n\n"; return; } } else { my $pkgrpm_basename = qx[basename $pkgrpm]; if($pkgrpm_basename =~ m|^($pkge)-([^-]+)-([^-]+)\.[^\.]+\.rpm|) { $version = $2; $release = $3; $found = 1;} } if ($config{src}) { system("rpm -ivh $pkgrpm"); } else { system("sudo /usr/sbin/urpmi --auto --force ".$config{srpms}."/".$pkgrpm); wait; system("/usr/sbin/urpmi --install-src --force ".$config{srpms}."/".$pkgrpm); } wait; my $top = `rpm --eval '%_topdir'`; chomp($top); chdir("$top/SOURCES") or die "Unable to chdir to $top/SOURCES"; $found = 0; if(!open(SPECFILE, "../SPECS/".$pkg.".spec")) { print STDERR "Unable to open spec file !\n"; return; } while() { # Doing a s/// version s/\%define\s+version\s+$version/\%define version $newversion/g; s/Version:\s+$version/Version: $newversion/g; $spec .= $_; $spec =~ s/\%define(\s+)release(\s+)(.*)/\%define release $config{release}/; push(@url, $2) if(/(Source|Url|Source0):\s+(\S+)/i); # For %vars ! $specvars{$1} = $2 if(/\%define\s+(.+?)\s+(.+)/g); $specvars{version} = $1 if(!$specvars{version} && /Version:\s+(.+)/gi); $specvars{name} = $1 if(!$specvars{name} && /Name:\s+(.+)/gi); if(/\%changelog/) { my $email; $email = $ENV{EMAIL} || qx[awk -F: '/$ENV{USER}/{print \$5}' /etc/passwd|tr -d '\n']." <$ENV{USER}\@mandrakesoft.com> "; $spec .= "* ".qx[LC_TIME=C date '+%a %b %d %Y'|tr -d '\n']." ".$email. " ".$newversion."-".$config{release}."\n"; $spec .= "- New release $newversion\n\n"; } } close(SPECFILE); if(!$url[0]) { print "URL was not found ! Skipping...\n"; return; } $found = 0; foreach (@url) { if(/ftp\.redhat\.com.*SRPMS/) { $found = 1; opendir(MP, $config{rawhide}) or die "$config{rawhide} is not a directory"; my @rpmsrh = readdir(MP); foreach (@rpmsrh) { if(m|^($pkge)-([^-]+)-([^-]+)\.[^\.]+\.rpm|) { my $pkgrpmrh = $_; last;} } closedir(MP); system("sudo /usr/sbin/urpmi --auto --force ".$config{rawhide}."/".$pkgrpmrh); wait; system("/usr/sbin/urpmi --install-src --force ".$config{rawhide}."/".$pkgrpmrh); wait; # Reinstall source to restore .spec file #system("/usr/sbin/urpmi --install-src --force ".$config{srpms}."/".$pkgrpm); #wait; } else { # Replace variable from spec (%blabla) while(/\%/) { s/\%\{(.*?)\}/$specvars{$1}/g; s/\%(\w+)/$specvars{$1}/g; s/\%\{name\}/$pkg/gi; s/\%\{version\}/$newversion/gi; } print "Trying $_...\n"; system("wget ".$_); my $basename = `basename $_`; chomp($basename); if($basename =~ /gz/) { s/gz/bz2/; $basename = `basename $_`; chomp($basename); print "Trying to fetch .bz2...\n"; system("wget ".$_); } elsif($basename =~ /bz2/) { s/bz2/gz/; print "Trying to fetch .gz...\n"; system("wget ".$_); $basename = `basename $_`; chomp($basename); # If gz was downloaded, recompressing it in bz2 if(-f $basename) { system("bzme ".$basename); $basename =~ s/bz2/gz/; } } } $found = 1 if(-e $basename); $basename =~ s/bz2/gz/; $found = 1 if(-e $basename); } open(SPECFILE, ">../SPECS/".$pkg.".spec") or die "Unable to open $pkg.spec"; print SPECFILE $spec; close(SPECFILE); if(!$found) { print "Unable to download file: URL is not valid ! :-(\n\n"; return; } if(system("rpm -ba ../SPECS/".$pkg.".spec")) { wait; print "Binary build fails: building source only\n"; system("rpm -bs ../SPECS/".$pkg.".spec"); } wait; } sub wget_check { my $wgetv = `wget --version`; $wgetv =~ /Wget/ or die "You need `wget' binary for FTP/HTTP download\n"; } sub parse_argv { my $conf = AppConfig->new({ CASE => 1 }); $conf->define("rpmmon", { ARGS => "=s", ALIAS => "r", ARGCOUNT => AppConfig::ARGCOUNT_ONE } ); $conf->define("release", { ARGS => "=s", ALIAS => "l", DEFAULT => "1mdk", ARGCOUNT => AppConfig::ARGCOUNT_ONE } ); $conf->define("srpms", { ARGS => "=s", ALIAS => "m", DEFAULT => "/mnt/BIG/distrib/cooker/SRPMS/", ARGCOUNT => AppConfig::ARGCOUNT_ONE } ); $conf->define("src", { ARGS => "=s", ALIAS => "s", ARGCOUNT => AppConfig::ARGCOUNT_ONE } ); $conf->define("rawhide", { ARGS => "=s", ALIAS => "h", DEFAULT => "/mnt/BIG/distrib/rawhide/SRPMS/SRPMS/", ARGCOUNT => AppConfig::ARGCOUNT_ONE } ); $conf->args(); $config{rpmmon} = $conf->get("rpmmon"); $config{srpms} = $conf->get("srpms"); $config{src} = $conf->get("src"); $config{release} = $conf->get("release"); $config{rawhide} = $conf->get("rawhide"); } sub usage { print "rpmbuildupdate v0.3 helps you build up to date RPMs.\n\n"; print "By Julien Danjou \n"; print "Copyright (c) 2003 by MandrakeSoft.\n"; print "This is free software under the GPL License.\n"; print "Usage: rpmbuildupdate [options] [pkg] [newversion]\n\n"; print " --rpmmon : Parse output of rpmmon from file\n"; print " --srpms : Specify SRPMS path\n"; print " --src : Build new version from this source RPM\n"; print " --release : Release version of package (default: 1mdk)\n"; exit 0; } sub parse_rpmmon { my $f; ($f = shift()); -f $f or die "Error: $f is not a file.\n"; open(RPMMON, $f); while() { &build($1, $3) if(/^\s+(\S+)\s+(\S+)\s+(\S+)$/ && ! /Package/); &build($2, $4) if(/^(\S+)\s+(\S+)\s+(\S+)\s+(\S+)$/ && ! /Package/); } close(RPMMON); } sub check_dir { $_ = shift; -d $_ or die $_." is not a directory.\n"; } sub main { &parse_argv; &wget_check; if($config{rpmmon}) { print($config{srpms}); &parse_rpmmon($config{rpmmon}); } elsif($config{src} && $ARGV[0]) { &build_from_src($config{src}, $ARGV[0]); } elsif($ARGV[0] && $ARGV[1]) { &check_dir($config{srpms}); &build($ARGV[0], $ARGV[1]); } else { &usage; } } &main;