aboutsummaryrefslogtreecommitdiffstats
path: root/rpmbuildupdate
diff options
context:
space:
mode:
Diffstat (limited to 'rpmbuildupdate')
-rwxr-xr-xrpmbuildupdate671
1 files changed, 0 insertions, 671 deletions
diff --git a/rpmbuildupdate b/rpmbuildupdate
deleted file mode 100755
index 9d64ebc..0000000
--- a/rpmbuildupdate
+++ /dev/null
@@ -1,671 +0,0 @@
-#!/usr/bin/perl -w
-#
-# rpmbuildupdate by Julien Danjou
-#
-# Copyright (c) 2003-2005 by Mandriva
-#
-# 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.
-#
-# $Id$
-
-# TODO
-# rework configuration option
-# add debian url ( like gnome or rh ) => cannot be done i think
-# use more Hdlist ( see Hdlist->build() )
-# see if use force ( for RPM4::Spec ) could help when we buld a spec file from scrath
-
-# list of the return code :
-# 255 => usage
-# 6 => cannot open the spec file
-# 5 => random problem
-# 4 => a external command failed
-# 2 => invalid url
-# 1 => only src is build
-# 0 => no error
-
-use strict;
-use AppConfig;
-use File::Basename;
-use File::Copy;
-use Cwd;
-use File::Spec;
-use File::Path;
-use RPM4;
-use String::ShellQuote;
-use File::MimeInfo::Magic;
-
-my %config;
-
-my ($log, $top, $rpm);
-
-sub system_die {
- my ($command, $message) = @_;
- $message ||= "$command failed";
- # in case we die
- $! = 4;
- # do not forget , return value of 1 means failure in unix
- system($command) and die $message;
-}
-
-sub file_not_found {
- my ($basename) = @_;
- ! -f $basename and return 1;
- # sometimes, the webserver return a webpage when the file is not found, instead of letting wget fails
- # see wget http://www.wesnoth.org/files/wesnoth-0.7.1.tar.bz2
- # So if the file is a html page, then it is a error and it should be removed.
- is_html($basename) and do { rmtree($basename); return 1 };
- return 0;
-}
-
-sub is_html {
- my ($basename) = @_;
- mimetype($basename) =~ /HTML/i and return 1;
- return 0;
-}
-
-sub download {
- my $wget = "wget -N -q";
- my ($url)=@_;
- my $temp = basename($url);
- print "Trying to fetch $url...\n";
- system("$wget $url;");
- -f $temp && ! is_html($temp) && $temp !~ /.bz2$/ && system_die("bzme -F $temp", "Cannot convert $temp");
-}
-
-sub fetch {
- my ($url) = @_;
- # if you add a handler here, do not forget to add it to the body of build()
- return fetch_http($url) if $url =~ m!^(ftp|https?)://!;
- return fetch_svn($url) if $url =~ m!^svns?://!;
-}
-
-sub fetch_svn {
- my ($url) = @_;
- my ($basename, $repos);
-
- $basename = basename($url);
- ($repos = $url) =~ s|/$basename$||;
- $repos =~ s/^svn/http/;
- die "Cannot extract revision number from the name." if $basename !~ /^(.*)-([^-]*rev)(\d\d*).tar.bz2$/;
- my ($name, $prefix, $release) = ($1, $2, $3);
- my $dir="$ENV{TMP}/rpmbuildupdate-$$";
- my $current_dir = cwd();
- mkdir $dir or die "Cannot create dir $dir";
- chdir $dir or die "Cannot change dir to $dir";
- system_die("svn co -r $release $repos", "svn checkout failed on $repos");
- my $basedir = basename($repos);
-
- # FIXME quite inelegant, should use a dedicated cpan module.
- my $complete_name = "$name-$prefix$release";
- move($basedir, $complete_name);
- system_die("find $complete_name -name '.svn' | xargs rm -Rf");
- system_die("tar -cjf $complete_name.tar.bz2 $complete_name", "tar failed");
- system_die("mv -f $complete_name.tar.bz2 $current_dir");
- chdir $current_dir;
-}
-
-sub fetch_http {
- my ($url) = @_;
- my $basename = basename($url);
- my $turl;
-
- rmtree($basename);
-
- download($url);
- foreach ('.tar.gz', '.tgz', '.tar.Z', '.zip') {
- ($turl = $url) =~ s/\.tar\.bz2/$_/;
- download($turl) if file_not_found($basename);
- }
- return ! file_not_found($basename);
-}
-
-
-sub fill_global_variable {
- my ($pkgrpm) = @_;
- $top = $config{top} || RPM4::expand('%_topdir');
- chomp($top);
- if ($config{log}) {
- my $basename = basename($pkgrpm);
- mkdir_p("$top/log");
- my $logfile = "$top/log/${basename}.log";
- $log = " >> $logfile 2>&1";
- print "Logs are in $logfile\n";
- } else {
- $log = "";
- }
- #TODO replace with perl-hdlist
- RPM4::add_macro("_topdir $top");
- $rpm = qq(rpm --define "_topdir $top");
- $config{sourcedir} = RPM4::expand('%_sourcedir');
- chomp( $config{sourcedir}); #"$top/SOURCES";
-}
-
-
-sub build_from_spec {
- my ($spec_path, $newversion) = @_;
- #TODO replace with perl-hdlist binding
- my $rpm_tag = (split(/\n/,`rpm -q $config{rpmoption} --queryformat '%{NAME} %{VERSION} %{RELEASE}\n' --specfile $spec_path`))[0];
- my ($pkg, $version, $release) = split(/ /, $rpm_tag);
- fill_global_variable($pkg);
- $spec_path = File::Spec->rel2abs($spec_path);
-
- chdir($config{sourcedir}) or die "Unable to chdir to $config{sourcedir}";
- build($spec_path,$pkg,$version,$release,$newversion);
-}
-
-sub build_from_repository {
- my ($pkg, $newversion) = @_;
- my $pkgrpm;
-
- foreach my $srpm_dir (split(/,/, $config{srpms})) {
- opendir(MP, $srpm_dir) or die "$srpm_dir is not a directory";
- my @rpms = readdir(MP);
- foreach (@rpms) {
- if (/^\Q$pkg\E-[^-]+-[^-]+\.\w+\.rpm/) {
- $pkgrpm = "$srpm_dir/$_";
- last;
- }
- }
- closedir(MP);
- last if $pkgrpm;
- }
- unless ($pkgrpm) {
- print "Package $pkg has no source, skipping.\n\n";
- return;
- }
- build_from_src($pkgrpm,$newversion);
-}
-
-sub build_from_src {
- my ($pkgrpm, $newversion) = @_;
-
- $pkgrpm = File::Spec->rel2abs($pkgrpm);
- fill_global_variable($pkgrpm);
- my $found = 0;
- my ($name, $version, $release);
-
- chdir($config{sourcedir}) or die "Unable to chdir to $config{sourcedir}";
-
- my $pkgrpm_basename = basename($pkgrpm);
- if ($pkgrpm_basename =~ /^(.*)-([^-]+)-([^-]+)\.\w+\.rpm/) {
- $name = $1;
- $version = $2;
- $release = $3;
- } else {
- die "Cannot parse the name of rpm $pkgrpm_basename";
- }
-
- # TODO log, check return
- my ($spec_path) = RPM4::installsrpm($pkgrpm);
- build($spec_path, $name, $version, $release, $newversion);
-}
-
-sub get_email() {
- my $packager = RPM4::expand('%packager');
- my @l = getpwuid($<);
- chomp($packager);
- # if macro is undefined
- $packager =~ s/\%packager//g;
- return ( $packager ? $packager : $l[6] . ($ENV{EMAIL} ? " <$ENV{EMAIL}>" : " <$l[0]\@mandriva.com>"));
-
-}
-
-sub build {
- $! = 5;
- my ($spec_path, $pkg, $version, $release, $newversion) = @_;
- my ($message, $spec, @url, %specvars);
- my ($newrelease, $release_prefix) = ($1,$2) if $release =~ /^(.*\d+)(\D*)$/g;
- my $email = get_email();
- my $hdlist_spec = RPM4::specnew($spec_path,force => 1) or die "Unable to parse spec $spec_path\n";
- if ($newversion) {
- print "===> Building $pkg $newversion\n";
- } else {
- print "===> Rebuilding $pkg\n";
- }
-
- if ( $config{installbuildrequires} ) {
- my @requires = split(/\s+/, $hdlist_spec->srcheader->queryformat("[%{requires} ]"));
- @requires = grep { $_ ne '(none)' } @requires;
- if (@requires) {
- print "===> Installing BuildRequires : @requires\n";
- system("$config{installbuildrequires} " . shell_quote @requires);
- }
- };
-
- if (! defined($newversion)) {
- $newversion = $version;
- my @tmp = split(/\./,$newrelease);
- $tmp[-1]++;
- $newrelease = join('.',@tmp) . $release_prefix;
- $message = $config{message} || '- Rebuild';
- } else {
- $message = $config{message} || '- New release %%VERSION';
- $newrelease = "1$release_prefix";
- }
- $newrelease = $config{release} if $config{release};
-
-
- my $SPECFILE;
- if (!open($SPECFILE, $spec_path)) {
- print STDERR "Unable to open spec file $spec_path.\n";
- $! = 6;
- return;
- }
-
- my $tar_ball='';
-
- while (<$SPECFILE>) {
- # Doing a s/// version
- s/(\%define\s+version\s+)$version/$1$newversion/;
- s/(\%define\s+release\s+)$release/$1$newrelease/;
- s/Version:(\s+)$version/Version:$1$newversion/i;
- s/Release:(\s+)$release/Release:$1$newrelease/i;
- # TODO factorisation
- # case of %define release %mkrel 2
- if ( /^(.*\s\%mkrel\s+)(\d+)(.*)$/ )
- {
- $_ = "$1" . ((( $version eq $newversion ) ? $2 : 0 ) + 1 ) . "$3\n";
- }
-
- # case of %define release %mkrel %rel
- # and %define rel 2
- if ( /^(\%define\s+rel\s+)(\d+)(.*)$/ )
- {
- $_ = "$1" . ((( $version eq $newversion ) ? $2 : 0 ) + 1 ) . "$3\n";
- }
-
-
- eval $config{execute} if $config{execute};
-
- $spec .= $_;
-
-
- # For %vars !
- $specvars{$1} = $2 if /\%define\s+(\S+?)\s+(\S+)/g;
- foreach my $i ('url', 'name', 'version', 'release', 'epoch') {
- $specvars{$i} = $1 if !$specvars{$i} && /\b$i\s*:\s+(\S+)/gi;
- }
-
- if (/^Source[0-9]*:\s+(\S+)/i) {
- my $source = $1;
- # TODO could it be done cleanly with RPM4::expand ?
- $source =~ s/\%url/$specvars{'url'}/;
- $source =~ s/\%{url}/$specvars{'url'}/;
- if ($source =~ /(?:ftp|svns?|https?):\/\/\S+/) {
- push(@url, $source);
- } else {
- $tar_ball= $source unless $tar_ball;
- };
- }
-
- if (/^\%changelog/) {
- $message =~ s/\%\%VERSION/$newversion/;
- my $epoch = ( $specvars{'epoch'} ? "$specvars{'epoch'}:" : "" );
- $spec .= "* " . `LC_TIME=C date '+%a %b %d %Y'|tr -d '\n'` . " $email $epoch$newversion-$newrelease\n";
- $spec .= "$message\n\n";
- }
-
- }
- close($SPECFILE);
-
-
- if (!$url[0]) {
- print "URL of sources was not found ! Trying to guess it with url tag ...\n";
-
- my $url = $specvars{url};
- # add jabberstudio, collabnet, http://www.sourcefubar.net/, http://sarovar.org/
- my @sf_like = ( {
- download => 'http://prdownloads.sourceforge.net/$1/$2' ,
- regexp => 'http://(.*)\.(?:sourceforge|sf)\.net/?(.*)'
- },
- { # to test
- download => 'http://download.gna.org/$1/$2',
- regexp => 'https?://gna.org/projects/([^/]*)/(.*)'
- },
- {
- download => 'http://download.berlios.de/$1/$2' ,
- regexp => 'http://(.*)\.berlios.de/(.*)'
- },
- { # to test , and to merge with regular savanah ?
- download => 'http://savannah.nongnu.org/download//$1/$2',
- regexp => 'https?://savannah.nongnu.org/projects/([^/]*)/(.*)'
- },
- { # to test
- download => 'http://savannah.gnu.org/download//$1/$2',
- regexp => 'https?://savannah.gnu.org/projects/([^/]*)/(.*)'
- }
- );
-
- # http://jabberstudio.org/files/ejogger/
- # http://jabberstudio.org/projects/ejogger/project/view.php
- foreach my $sf (@sf_like) {
- if ($url =~ m/$sf->{regexp}/) {
- $sf->{download} =~ s/^/"/;
- $sf->{download} =~ s/$/"/;
- $url =~ s/$sf->{regexp}/"$sf->{download}"/eeg;
- }
- }
-
- push(@url, "$url/$tar_ball")
- }
- my $found = 0;
-
- unless ($config{nodownload}) {
- foreach (@url) {
- # Replace variable from spec (%blabla)
- while (/\%[^(]?/) {
- s/\%\{?(\w+)\}?/$specvars{$1}/g;
- s/\%\{name\}/$pkg/g;
- s/\%\{version\}/$newversion/g;
- }
-
- my $basename = basename($_);
- rmtree("$config{sourcedir}/$basename");
-
- # GNOME: add the major version to the URL automatically
- # for example: ftp://ftp://ftp.gnome.org/pub/GNOME/sources/ORbit2/ORbit2-2.10.0.tar.bz2
- # is rewritten in ftp://ftp.gnome.org/pub/GNOME/sources/ORbit2/2.10/ORbit2-2.10.0.tar.bz2
- if (m!ftp.gnome.org/pub/GNOME/sources/!) {
- (my $major = $newversion) =~ s/([^.]+\.[^.]+).*/$1/;
- s!(.*/)(.*)!$1$major/$2!;
- }
-
- # download from Fedora rpms
- if (/ftp\.redhat\.com/) {
- opendir(MP, $config{fedora}) or die "$config{fedora} is not a directory";
- my @rpmsrh = readdir(MP);
-
- my $pkgrpmrh;
-
- foreach (@rpmsrh) {
- if (/^\Q$pkg\E-[^-]+-[^-]+\.\w+\.rpm/) {
- $pkgrpmrh = $_;
- last;
- }
- }
-
- closedir(MP);
-
- print "Trying from fedora($basename): $config{fedora}/$pkgrpmrh\n";
- system_die("cd $config{sourcedir}; rpm2cpio $config{fedora}/$pkgrpmrh | cpio -id $basename", "Rpm extraction failed");
- if (! -f "$config{sourcedir}/$basename") {
- (my $bname = $basename) =~ s/bz2/gz/;
- print "Trying from fedora($bname): $config{fedora}/$pkgrpmrh\n";
- system("cd $config{sourcedir}; rpm2cpio $config{fedora}/$pkgrpmrh | cpio -id $bname; bzme -F $bname", "rpm recompression failed");
- }
- }
- # download from sourceforge mirrors
- if (m!http://prdownloads.sourceforge.net!) {
- foreach my $site ("http://ovh.dl.sourceforge.net/sourceforge/",
- "http://mesh.dl.sourceforge.net/sourceforge/",
- "http://switch.dl.sourceforge.net/sourceforge/",
- "http://belnet.dl.sourceforge.net/sourceforge/",
- "http://puzzle.dl.sourceforge.net/sourceforge/",
- "http://heanet.dl.sourceforge.net/sourceforge/",
- "http://kent.dl.sourceforge.net/sourceforge/",
- "http://voxel.dl.sourceforge.net/sourceforge/",
- "http://easynews.dl.sourceforge.net/sourceforge/",
- "http://cogent.dl.sourceforge.net/sourceforge/",
- "http://optusnet.dl.sourceforge.net/sourceforge/",
- "http://jaist.dl.sourceforge.net/sourceforge/",
- "http://nchc.dl.sourceforge.net/sourceforge/",
- "http://citkit.dl.sourceforge.net/sourceforge/",
- )
- {
- (my $dest = $_) =~ s!http://prdownloads.sourceforge.net/!$site!;
- last if fetch_http($dest);
- }
- }
- # download specified url
- if (! -f "$config{sourcedir}/$basename") {
- fetch($_);
- }
- $found++ if -e $basename;
- chmod(0644, "$config{sourcedir}/$basename");
- }
- }
- # some specs have no source ( php )
- $found++ if ! $tar_ball or $config{'nodownload'};
-
- unless ($found) {
- print "Unable to download file: URL is not valid ! :-(\n\n";
- $! = 2;
- return;
- }
-
-
-
- unless ($config{noupdate}) {
- # TODO use output ?
- open($SPECFILE, ">$spec_path") or die "Unable to open $pkg.spec";
- print $SPECFILE $spec;
- close($SPECFILE);
- }
-
- unless ($config{nobuild}) {
- if (system("$rpm -ba $config{rpmoption} $spec_path $log")) {
- print "Binary build fails: building source only\n";
- system("$rpm -bs $config{rpmoption} --nodeps $spec_path $log");
- $! = 1;
- } else {
- $! = 0;
- }
- }
- if ($config{execafterbuild})
- {
- my @rpms_upload;
- push(@rpms_upload, $hdlist_spec->srcrpm);
- foreach ($hdlist_spec->binrpm())
- {
- -f $_ or next;
- push(@rpms_upload, $_);
- }
- system("$config{execafterbuild} " . shell_quote @rpms_upload);
- }
-}
-
-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, ERROR => \&usage });
-
- $conf->define("rpmmon", {
- ARGS => "=s",
- ALIAS => "r",
- ARGCOUNT => AppConfig::ARGCOUNT_ONE
- });
-
- $conf->define("release", {
- ARGS => "=s",
- DEFAULT => "",
- ARGCOUNT => AppConfig::ARGCOUNT_ONE
- });
-
- $conf->define("srpms", {
- ARGS => "=s",
- ALIAS => "m",
- DEFAULT => "/mnt/BIG/distrib/cooker/SRPMS/",
- ARGCOUNT => AppConfig::ARGCOUNT_ONE
- });
-
- $conf->define("rpmoption", {
- ARGS => "=s",
- DEFAULT => "",
- ARGCOUNT => AppConfig::ARGCOUNT_ONE
- });
-
- $conf->define("fedora", {
- ARGS => "=s",
- ALIAS => "h",
- DEFAULT => "/mnt/BIG/distrib/fedora/development/SRPMS/",
- ARGCOUNT => AppConfig::ARGCOUNT_ONE
- });
-
- $conf->define("nosource", {
- ALIAS => "n",
- DEFAULT => 0,
- ARGCOUNT => AppConfig::ARGCOUNT_NONE
- });
-
- $conf->define("noupdate", {
- DEFAULT => 0,
- ARGCOUNT => AppConfig::ARGCOUNT_NONE
- });
-
- $conf->define("top", {
- ARGS => "=t",
- ALIAS => "h",
- DEFAULT => 0,
- ARGCOUNT => AppConfig::ARGCOUNT_ONE
- });
-
- $conf->define("nobuild", {
- ALIAS => "c",
- DEFAULT => 0,
- ARGCOUNT => AppConfig::ARGCOUNT_NONE
- });
-
- $conf->define("nodownload", {
- DEFAULT => 0,
- ARGCOUNT => AppConfig::ARGCOUNT_NONE
- });
-
-
- $conf->define("log", {
- ALIAS => "l",
- DEFAULT => 0,
- ARGCOUNT => AppConfig::ARGCOUNT_NONE
- });
-
- $conf->define("changelog", {
- ARGS => "=s",
- # default is defined at the beggining of build
- # as it depend if this is a new version or a simple rebuild
- DEFAULT => "",
- ARGCOUNT => AppConfig::ARGCOUNT_ONE
- });
-
- $conf->define("execute", {
- ARGS => "=s",
- DEFAULT => "",
- ARGCOUNT => AppConfig::ARGCOUNT_ONE
- });
-
- $conf->define("execafterbuild", {
- ARGS => "=s",
- DEFAULT => "",
- ARGCOUNT => AppConfig::ARGCOUNT_ONE
- });
-
- $conf->define("installbuildrequires", {
- ARGS => "=s",
- DEFAULT => "",
- ARGCOUNT => AppConfig::ARGCOUNT_ONE
- });
-
-
-
- foreach my $f ('/etc/rpmbuildupdate.conf', "$ENV{HOME}/.rpmbuildupdaterc") {
- -f $f && $conf->file($f);
- }
- $conf->args;
- # TODO remove this useless piece of code and use directly $conf->get
- $config{rpmmon} = $conf->get("rpmmon");
- $config{srpms} = $conf->get("srpms");
- $config{release} = $conf->get("release");
- $config{noupdate} = $conf->get("noupdate");
- $config{nosource} = $conf->get("nosource");
- $config{fedora} = $conf->get("fedora");
- $config{top} = $conf->get("top");
- $config{nodownload} = $conf->get("nodownload");
- $config{nobuild} = $conf->get("nobuild");
- $config{message} = $conf->get("changelog");
- $config{rpmoption} = $conf->get("rpmoption");
- $config{log} = $conf->get("log");
- $config{execute} = $conf->get("execute");
- $config{execafterbuild} = $conf->get("execafterbuild");
- $config{installbuildrequires} = $conf->get("installbuildrequires");
-}
-
-sub usage {
- my $id = '$Id$';
- print <<EOF;
-rpmbuildupdate v0.5 helps you build up to date RPMs.
-cvs version : $id
-
-By Julien Danjou, Michael Scherer, Guillaume Rousse
-
-Copyright (c) 2003-2005 Mandriva.
-This is free software under the GPL License.
-Usage: rpmbuildupdate [options] [pkg] [newversion]
-
- --rpmmon <file>: parse output of rpmmon from file
- --srpms <path_to_srpms>: specify SRPMS path, separate folder with a comma
- --rpmoption <rpm option>: use this option when rebuilding ( --with , mainly )
- --release <mdk_release>: release version of package (default: 1mdk)
- --changelog <changelog message>: use a alternate message. \%\%VERSION is replace by version
- --log: log builds
- --nosource: do not install source from (urpmi x.src.rpm)
- --noupdate: do not touch to the spec file
- --top <dir>: specify rpm top dir (default: `rpm --eval \%_topdir`)
- --nodownload: do not download any files.
- --nobuild|-c: do not build the package. Only download files.
- --execute <command>: execute an arbitrary perl command for each line of the spec file
- --execafterbuild <command>: execute a shell command after the build, with the source and binary rpm as argument
- --installbuildrequires <command>: command executed with the list of BuildRequires to install
-EOF
- exit 255;
-}
-
-sub parse_rpmmon {
- my ($f) = @_;
- -f $f or die "Error: $f is not a file.\n";
-
- open(my $RPMMON, $f);
- while (<$RPMMON>) {
- build_from_repository($1, $3) if /^\s+(\S+)\s+(\S+)\s+(\S+)$/ && ! /Package/;
- build_from_repository($2, $4) if /^(\S+)\s+(\S+)\s+(\S+)\s+(\S+)$/ && ! /Package/;
- }
- close($RPMMON);
-}
-
-sub check_dir {
- my ($list) = @_;
- foreach my $dir (split(/,/, $list)) {
- -d $dir or die $dir . " is not a directory.\n";
- }
-}
-
-sub main {
- parse_argv;
- wget_check;
- if ($config{rpmmon}) {
- print($config{srpms});
- parse_rpmmon($config{rpmmon})
- } else {
- my ($name, $version);
- if ($ARGV[0]) {
- $name = $ARGV[0];
- $version = $ARGV[1];
- if (-f $name && $name =~ /(?:.spec|.(?:no)?src.rpm)$/) {
- build_from_spec($name, $version) if $name =~ /.spec$/;
- build_from_src($name, $version) if $name =~ /.(?:no)?src.rpm$/;
- } else {
- check_dir($config{srpms});
- build_from_repository($name, $version)
- }
- } else {
- usage;
- }
- }
-}
-
-main;
-exit $!;