#!/usr/bin/perl -w # author: J Robert Ray # # # History: # 12/03/02: mcummings; Added checks for /var/db/pkg and manually installed # modules # 11/07/02: jrray : Initial upload to bug 3450 # # use strict; use File::Spec; use CPAN; unless (@ARGV) { print "Feed me perl modules on the command line\n"; exit; } my $overlay_dir = `grep ^PORTDIR_OVERLAY= /etc/make.conf`; chomp $overlay_dir; $overlay_dir =~ s/.*?="?(.*?)"?$/$1/; if (!$overlay_dir) { $overlay_dir = '/tmp/perl-modules'; } $overlay_dir = '/tmp/perl-modules'; unless (-d $overlay_dir) { mkdir $overlay_dir, 0755 or die "Couldn't create '$overlay_dir': $|"; } my $perldev_overlay = File::Spec->catfile($overlay_dir, 'dev-perl'); unless (-d $perldev_overlay) { mkdir $perldev_overlay, 0755 or die "Couldn't create '$perldev_overlay': $|"; } #Commented out since we will be using a temp overlay #unless (length $overlay_dir && -d $overlay_dir) { # print "You need to set PORTDIR_OVERLAY in /etc/make.conf for this to work\n"; # exit; #} sub printbig { print '*' x 72, "\n"; print '*', "\n"; print '*', "\n"; print '* ', @_; print '*', "\n"; print '*', "\n"; print '*' x 72, "\n"; } sub ebuild_exists($) { my ($dir) = @_; # check the main portage tree return 1 if (-d File::Spec->catfile('/usr/portage/dev-perl', $dir)); # check the overlay return 1 if (-d File::Spec->catfile($perldev_overlay, $dir)); # check to see if we've pseduo-built this before return 1 if (-d File::Spec->catfile('/var/tmp/db/dev-perl', $dir)); return 0; } sub module_exists ($) { my ($module) = @_; #check to see if the user has manually installed the module return 1 if (&module_check($module)); } sub module_check ($) { my $check = $_; my $tmp = "use $check;"; my $tmpinstalled = 0; eval $tmp; $tmpinstalled = 1 unless $@; if ($tmpinstalled == 1) { return 1;} else { return 0;} } sub portage_dir ($) { my $obj = shift; my $file = $obj->cpan_file; # turn this into a directory name suitable for portage tree return unless ($file =~ m|.*/(.*)-[^-]+\.|); return $1; } sub create_ebuild ($$$$$) { my ($module, $dir, $file, $prereq_pm, $MD5) = @_; # First, make the directory my $fulldir = File::Spec->catdir($perldev_overlay, $dir); my $filesdir = File::Spec->catdir($fulldir, 'files'); mkdir $fulldir, 0755 or die "Couldn't create '$fulldir': $!"; mkdir $filesdir, 0755 or die "Couldn't create '$filesdir': $!"; # What to call this ebuild? unless ($file =~ m#(.*)/(.*?)\.(?:tar|tgz|zip|bz2|gz)#) { print STDERR "Couldn't turn '$file' into an ebuild name\n"; return; } my ($modpath, $filename) = ($1, $2); my $ebuild = File::Spec->catdir($fulldir, "$filename.ebuild"); my $digest = File::Spec->catdir($filesdir, "digest-$filename"); my $desc = $module->description; open EBUILD, ">$ebuild" or die "Could not write to '$ebuild': $!"; print EBUILD <<"HERE"; # Copyright 1999-2002 Gentoo Technologies, Inc. # Distributed under the terms of the GNU General Public License v2 inherit perl-module S=\${WORKDIR}/\${P} DESCRIPTION="$desc" SRC_URI="http://www.cpan.org/modules/by-authors/id/$modpath/\${P}.tar.gz" HOMEPAGE="http://www.cpan.org/modules/by-authors/id/$modpath/\${P}.readme" SLOT="0" LICENSE="Artistic | GPL-2" KEYWORDS="x86 ppc alpha" HERE if ($prereq_pm && keys %$prereq_pm) { print EBUILD q|DEPEND="|; my $first = 1; for (keys %$prereq_pm) { my $obj = CPAN::Shell->expandany($_); my $dir = portage_dir($obj); print EBUILD "\n\t" unless $first; print EBUILD "dev-perl/$dir"; $first = 0; } print EBUILD qq|"\n\n|; } close EBUILD; # write the digest too open DIGEST, ">$digest" or die "Could not write to '$digest': $!"; print DIGEST $MD5, "\n"; close DIGEST; } sub install_module ($); sub install_module ($) { my ($module_name) = @_; my $obj = CPAN::Shell->expandany($module_name); unless (ref $obj eq "CPAN::Module") { print STDERR "Don't know what '$module_name' is\n"; return; } my $file = $obj->cpan_file; my $dir = portage_dir($obj); unless ($dir) { print STDERR "Couldn't turn '$file' into a directory name\n"; return; } if (ebuild_exists($dir)) { printbig "Module already exists for '$module_name': $dir\n"; return; } if (module_exists($module_name)) { printbig "Module already installed for '$module_name'\n"; return; } printbig "Need to create ebuild for '$module_name': $dir\n"; # check depends ... with CPAN have to make the module # before it can tell us what the depends are, this stinks $CPAN::Config->{prerequisites_policy} = ""; $CPAN::Config->{inactivity_timeout} = 30; my $pack = $CPAN::META->instance('CPAN::Distribution', $file); $pack->called_for($obj->id); $pack->make; $pack->unforce if $pack->can("unforce") && exists $obj->{'force_update'}; delete $obj->{'force_update'}; # grab the MD5 checksum for the source file now my $localfile = $pack->{localfile}; (my $base = $file) =~ s|.*/(.*)|$1|; my $MD5 = sprintf "MD5 %s %s %d", (split/\s/,`md5sum $localfile`)[0], $base, -s $localfile; # make ebuilds for all the prereqs my $prereq_pm = $pack->prereq_pm; install_module($_) for (keys %$prereq_pm); create_ebuild($obj, $dir, $file, $prereq_pm, $MD5); printbig "You may now install '$module_name' by typing 'emerge $dir'\n"; } install_module($_) for (@ARGV);