#!/usr/bin/perl -w # # Grab a module from CPAN and sock it into an RPM using cpanflute2 # use strict; use CPAN; use File::Path; use File::Copy; use Config; use Getopt::Long; my $debug = 0; my $dist = ""; my $release = 1; # Pick up RPM settings # these depend on you having a sane (ish) rpmmacros file my $srpmdir = `/bin/rpm --eval \%_srcrpmdir`; my $rpmdir = `/bin/rpm --eval \%_rpmdir`; my $email = `/bin/rpm --eval \%packager`; my $name = ""; chomp( $srpmdir ); chomp( $rpmdir ); chomp( $email ); GetOptions( "debug!" => \$debug, "name=s" => \$name ); if ( $name ) { $name = "--name $name"; } my $wanted = shift or die "tell me what you want\n"; my $cpanflute2 = ""; for my $candidate ( "/usr/bin/cpanflute2", $Config{sitebin} . "/cpanflute2", "/home/waider/perl/bin/cpanflute2", "/usr/lib/rpm/cpanflute2" ) { if ( -x $candidate ) { $cpanflute2 = $candidate; } } die "No CPANFLUTE2 found... install RPM::Specfile!\n" unless $cpanflute2; my $topdir = "/var/tmp/cpan"; # figure out what our distro is, approximately. if ( !$dist ) { if ( -f "/etc/redhat-release" ) { my $p = `/bin/rpm -qf /etc/redhat-release`; if ( `grep Enterprise /etc/redhat-release 2>/dev/null` ) { $dist = "el"; } elsif ( `grep Fedora /etc/redhat-release 2>/dev/null` ) { $dist = "fc"; } else { $dist = "rh"; } $dist .= `rpm -q --queryformat "\%{VERSION}" $p`; $dist =~ s/(S|C)(erver|lient)/$1/; } else { $dist = "nodist"; } } $release .= ".$dist"; # hardcoded to modules for now, and only one of, thanks. my $filename = ""; if ( $wanted =~ m@/@ ) { $filename = $wanted; CPAN::Shell->get( $wanted ); } else { my $obj = CPAN::Shell->expand( "Module", $wanted ); if ( !defined( $obj )) { print "No idea what that is, mate\n"; exit( 1 ); } $filename = $obj->cpan_file; # now fetch it CPAN::Shell->get( $obj ); } my $tarfile = $CPAN::Config->{keep_source_where} . "/authors/id/$filename"; if ( ! -f $tarfile ) { print "Can't find the module file!\n"; exit( 1 ); } # sample command # /usr/lib/rpm/cpanflute2 --noarch --buildall --email="Waider " --release 1 --test RPM-Specfile-1.17.tar.gz # we should check the arch, if possible # email should come from .rpmmacros, possibly output dir also should # allow for optional arguments, to control testing for example [ ! -d "$topdir" ] and mkdir "$topdir", 0755; # Instead of any smart processing we'll bluntly build an i386 version, # see if it has any i386 data, and if it hasn't then we'll rebuild it # as a noarch package. my $noarch = ""; ARCHBUILD: print STDERR "Doing " . ( $noarch ? "noarch" : "i386" ) . " compilation...\n"; my $compiler = "$cpanflute2 $name --buildall --release $release $noarch --outdir $topdir --email \"$email\" \"$tarfile\" 2>&1 "; open( COMPILER, "$compiler|" ) or die "can't fork: $!"; my $compilation = ""; while ( my $line = ) { $compilation .= $line; print $line; } close( COMPILER ) or die "bad $cpanflute2: $! $?"; print STDERR "done.\n"; if ( open( BL, ">/var/tmp/cpan-build.log" )) { print BL $compilation; close( BL ); } # check for useless "debuginfo" file(s) my @files; if ( opendir( CP, "$topdir" )) { my $arch = 0; for my $file ( grep /\.rpm$/, readdir( CP )) { my $files = `/usr/bin/rpm2cpio "$topdir/$file" | /bin/cpio -t --quiet 2>/dev/null`; if ( !$files ) { print "Nuking useless $file\n"; unlink( "$topdir/$file" ); } else { # XXX all the world's i386 if ( $files =~ /i386/ ) { print "Found architecture-specific files in $file\n"; $arch = 1; } } } if ( !$arch and !$noarch ) { print "No architecture-specific files found, rebuilding as a noarch package.\n"; $noarch = "--noarch"; goto ARCHBUILD; } # now fetch the list of files rewinddir( CP ); for my $file ( grep /\.rpm$/, readdir( CP )) { if ( $file =~ /\.src\.rpm$/ ) { [ ! -d "$srpmdir" ] and mkpath $srpmdir, 0, 0755; move( "$topdir/$file", "$srpmdir/$file" ) or die "$topdir/$file: $!"; push @files, "$srpmdir/$file"; } elsif ( $file =~ /\.([^.]+)\.rpm/ ) { my $a = $1; if ( $a ne "noarch" and $noarch ) { unlink( "$topdir/$file" ); next; } [ ! -d "$rpmdir/$a" ] and mkpath "$rpmdir/$a", 0, 0755; move( "$topdir/$file", "$rpmdir/$a/$file" ) or die "$topdir/$file: $!"; push @files, "$rpmdir/$a/$file"; } else { warn "don't know what to do with $file\n"; } } } if ( @files ) { print "built: \n\t" . join( "\n\t", @files ) . "\n"; unlink "/var/tmp/cpan-build.log"; } else { print "Build failed, check /var/tmp/cpan-build.log for errors\n"; print "build command was $compiler\n"; }