Gentoo Archives: gentoo-perl

From: antoine.raillon@××××××.net
To: gentoo-perl@l.g.o
Subject: [gentoo-perl] r1 - /
Date: Thu, 12 May 2005 21:57:03
Message-Id: 20050512215610.F31778280DB@gredin.dragou.net
1 Author: cab
2 Date: 2005-05-10 23:19:46 +0200 (Tue, 10 May 2005)
3 New Revision: 1
4
5 Added:
6 g-cpan.pl
7 Log:
8
9
10 Added: g-cpan.pl
11 ===================================================================
12 --- g-cpan.pl 2005-05-10 21:07:00 UTC (rev 0)
13 +++ g-cpan.pl 2005-05-10 21:19:46 UTC (rev 1)
14 @@ -0,0 +1,824 @@
15 +#!/usr/bin/perl -w
16 +# Copyright 1999-2004 Gentoo Foundation
17 +# Distributed under the terms of the GNU General Public License v2
18 +# $Header: $
19 +#
20 +
21 +# modules to use - these will need to be marked as
22 +# dependencies, and installable by portage
23 +use strict;
24 +use diagnostics;
25 +use File::Spec;
26 +use File::Path;
27 +use List::Util qw(first);
28 +
29 +sub printbig;
30 +
31 +# Do we need to generate a config ?
32 +eval 'use CPAN::Config;';
33 +my $needs_cpan_stub = $@ ? 1 : 0;
34 +
35 +# Test Replacement - ((A&B)or(C&B)) should be the same as ((A or C) and B)
36 +if (( ($needs_cpan_stub) || ( $> > 0 ) ) && ( !-f "$ENV{HOME}/.cpan/CPAN/MyConfig.pm" ) ) {
37 + # In case match comes from the UID test
38 + $needs_cpan_stub = 1;
39 +
40 + # Generate a fake config for CPAN
41 + cpan_stub();
42 +}
43 +else {
44 + $needs_cpan_stub = 0;
45 +}
46 +
47 +use CPAN;
48 +
49 +use Getopt::Long;
50 +Getopt::Long::Configure("bundling");
51 +
52 +use Digest::MD5;
53 +
54 +my $VERSION = "0.13";
55 +
56 +my @perl_dirs = (
57 + "dev-perl", "perl-core", "perl-gcpan", "perl-text",
58 + "perl-tools", "perl-xml", "perl-dev"
59 +);
60 +
61 +###############################
62 +# Command line interpretation #
63 +###############################
64 +
65 +# Init all options
66 +my ( $verbose, $search, $install, $upgrade, $list ) = (0,0,0,0,0);
67 +
68 +#Get & Parse them
69 +GetOptions(
70 + 'verbose|v' => \$verbose,
71 + 'search|s' => \$search,
72 + 'install|i' => \$install,
73 + 'upgrade|u' => \$upgrade,
74 + 'list|l' => \$list,
75 + 'help|h' => sub { exit_usage(); }
76 + )
77 + or exit_usage();
78 +
79 +# Output error if more than one switch is activated
80 +if ($search + $list + $install + $upgrade > 1) {
81 + print "You can't combine search, list, install or upgrade with each other. Pick up one !\n\n";
82 + exit_usage();
83 +}
84 +
85 +# Output error if no arguments
86 +if ( !( defined( $ARGV[0] ) ) and (!($upgrade) or !($list)) ) {
87 + print "Not even one module name or expression given !\n\n";
88 + exit_usage();
89 +}
90 +
91 +
92 +##########
93 +# main() #
94 +##########
95 +
96 +# Taking care of Searches. This has to be improved a lot, since it uses a call to
97 +# CPAN Shell to do the job, thus making it impossible to have a clean output..
98 +if ($search) {
99 + foreach my $expr (@ARGV) {
100 +
101 + # Assume they gave us module-name instead of module::name
102 + if ( $expr !~ m|::| ) {
103 + $expr =~ s/-/::/g;
104 + }
105 + print "Searching for $expr on CPAN\n\n";
106 + CPAN::Shell->m("/$expr/");
107 + }
108 +
109 + clean_the_mess();
110 + exit;
111 +}
112 +
113 +
114 +# Take care of List requests. This should return all the ebuilds managed by g-cpan
115 +if ( $list ) {
116 + print "List function not implemented yet.\n";
117 + exit_usage();
118 +}
119 +
120 +# Set our temporary overlay directory for the scope of this run.
121 +# By setting an overlay directory, we bypass the predefined portage
122 +# directory and allow portage to build a package outside of its
123 +# normal tree.
124 +my $tmp_overlay_dir;
125 +if ( $ENV{TMPDIR} ) { $tmp_overlay_dir = "$ENV{TMPDIR}/perl-modules_$$" }
126 +else { $tmp_overlay_dir = "/tmp/perl-modules_$$" }
127 +
128 +my @ebuild_list;
129 +
130 +# Set up global paths
131 +# my $TMP_DEV_PERL_DIR = '/var/db/pkg/dev-perl';
132 +my $MAKECONF = '/etc/make.conf';
133 +my ( $PORTAGE_DISTDIR, $PORTAGE_DIR, @OVERLAYS ) = get_globals();
134 +
135 +my @OVERLAY_PERLS;
136 +my @PORTAGE_DEV_PERL;
137 +my @TMP_DEV_PERL_DIRS;
138 +
139 +foreach my $pdir (@perl_dirs) {
140 + my $tmp_dir = File::Spec->catdir( $PORTAGE_DIR, $pdir );
141 + push @PORTAGE_DEV_PERL, $tmp_dir;
142 + foreach my $odir (@OVERLAYS) {
143 + my $otmp = File::Spec->catdir( $odir, $pdir );
144 + push @OVERLAY_PERLS, $otmp;
145 + }
146 + my $vtmp_dir = File::Spec->catdir( '/var/db/pkg/dev-perl', $pdir );
147 + push @TMP_DEV_PERL_DIRS, $vtmp_dir;
148 +}
149 +
150 +# Create the ebuild in PORTDIR_OVERLAY, if it is defined and exists
151 +if ( $OVERLAYS[0] ) {
152 + $tmp_overlay_dir = $OVERLAYS[0];
153 + if ($verbose) {
154 + print
155 + "Setting $tmp_overlay_dir as the PORTDIR_OVERLAY for this session.\n";
156 + }
157 +}
158 +
159 +my $arches =
160 + join( ' ', map { chomp; $_ } `cat $PORTAGE_DIR/profiles/arch.list` );
161 +
162 +#this should never find the dir, but just to be safe
163 +unless ( -d $tmp_overlay_dir ) {
164 + mkpath( [$tmp_overlay_dir], 1, 0755 )
165 + or die "Couldn't create '$tmp_overlay_dir': $|";
166 +}
167 +
168 +# Now we cat our dev-perl directory onto our overlay directory.
169 +# This is done so that portage records the appropriate path
170 +#i.e. dev-perl/package
171 +my $perldev_overlay = File::Spec->catfile( $tmp_overlay_dir, 'perl-gcpan' );
172 +
173 +unless ( -d $perldev_overlay ) {
174 +
175 + # create perldev overlay dir if not present
176 + mkpath( [$perldev_overlay], 1, 0755 )
177 + or die "Couldn't create '$perldev_overlay': $|";
178 +}
179 +
180 +# Now we export our overlay directory into the session's env vars
181 +$ENV{'PORTDIR_OVERLAY'} = $tmp_overlay_dir;
182 +
183 +# sub main.. well, sort of ;p
184 +if ($install) {
185 + install_module($_) for (@ARGV);
186 + emerge_module($_) for (@ARGV);
187 +}
188 +if ($upgrade) {
189 + if (@ARGV) {
190 + upgrade_module($_) for (@ARGV);
191 + emerge_up_module($_) for (@ARGV);
192 + }
193 + else {
194 + my @GLIST = get_gcpans();
195 + upgrade_module($_) for (@GLIST);
196 + emerge_up_module(@GLIST);
197 + }
198 +
199 +}
200 +if ( $install or $upgrade ) { clean_up() }
201 +exit;
202 +
203 +##########
204 +# subs ! #
205 +##########
206 +
207 +# jrray printing functions
208 +sub printbig {
209 + print '*' x 72, "\n";
210 + print '*', "\n";
211 + print '*', "\n";
212 + print '* ', @_;
213 + print '*', "\n";
214 + print '*', "\n";
215 + print '*' x 72, "\n";
216 +}
217 +
218 +sub ebuild_exists {
219 + my ($dir) = @_;
220 +
221 + # need to try harder here - see &portage_dir comments.
222 + # should return an ebuild name from this, as case matters.
223 +
224 + # see if an ebuild for $dir exists already. If so, return its name.
225 + my $found = '';
226 +
227 + foreach my $sdir (
228 + grep { -d $_ } (
229 + @PORTAGE_DEV_PERL, @OVERLAY_PERLS,
230 + $perldev_overlay, @TMP_DEV_PERL_DIRS
231 + )
232 + )
233 + {
234 + opendir PDIR, $sdir;
235 + my @dirs = readdir(PDIR);
236 + closedir PDIR;
237 + $found ||= first { lc($_) eq lc($dir) }(@dirs);
238 + if ( ($found) && ($verbose) ) {
239 + print "$0: Looking for ebuilds in $sdir, found $found so far.\n";
240 + }
241 + }
242 +
243 + # check for ebuilds that have been created by g-cpan.pl
244 + for my $ebuild (@ebuild_list) {
245 + $found = $ebuild if ( $ebuild eq $dir );
246 + }
247 +
248 + return $found;
249 +}
250 +
251 +sub get_gcpans {
252 + my @g_list;
253 + foreach my $sdir ( grep { -d $_ } ( @PORTAGE_DEV_PERL, @OVERLAY_PERLS ) ) {
254 + if ( $sdir =~ m/perl-gcpan/ ) {
255 + opendir PDIR, $sdir;
256 + my @dirs = readdir(PDIR);
257 + closedir PDIR;
258 + foreach my $dir (@dirs) {
259 + push @g_list, $dir
260 + unless ( ( $dir eq "." ) or ( $dir eq ".." ) );
261 + }
262 +
263 + }
264 + }
265 + return @g_list;
266 +}
267 +
268 +sub build_catdep {
269 +
270 +# Needed a way to add category to the dependancy instead of hardcoding dev-perl :/
271 +# On the upside, at this point we know the ebuild exists *somewhere* so we just need to locate it
272 + my ($dir) = @_;
273 +
274 + my $found = '';
275 +
276 + foreach my $sdir (
277 + grep { -d $_ } (
278 + @PORTAGE_DEV_PERL, @OVERLAY_PERLS,
279 + $perldev_overlay, @TMP_DEV_PERL_DIRS
280 + )
281 + )
282 + {
283 + opendir PDIR, $sdir;
284 + my @dirs = readdir(PDIR);
285 + closedir PDIR;
286 + $found ||= first { lc($_) eq lc($dir) }(@dirs);
287 + if ($found) {
288 + $sdir =~ s/.*\///;
289 + $found = "$sdir/$found";
290 + return $found;
291 + }
292 + }
293 +
294 +}
295 +
296 +sub module_check {
297 +
298 +# module_check evaluates whether a module can be loaded from @INC.
299 +# This allows us to assure that if a module has been manually installed, we know about it.
300 + my $check = shift;
301 + eval "use $check;";
302 + return $@ ? 0 : 1;
303 +}
304 +
305 +sub portage_dir {
306 + my $obj = shift;
307 + my $file = $obj->cpan_file;
308 +
309 + # need to try harder here than before (bugs 64403 74149 69464 23951 +more?)
310 +
311 + # remove ebuild-incompatible characters
312 + $file =~ tr/a-zA-Z0-9\.\//-/c;
313 +
314 + $file =~ s/\.pm//; # e.g. CGI.pm
315 +
316 + # turn this into a directory name suitable for portage tree
317 + # at least one module omits the hyphen between name and version.
318 + # these two regexps are 'better' matches than previously.
319 + if ( $file =~ m|.*/(.*)-[0-9]+\.| ) { return $1; }
320 + if ( $file =~ m|.*/([a-zA-Z-]*)[0-9]+\.| ) { return $1; }
321 + if ( $file =~ m|.*/([^.]*)\.| ) { return $1; }
322 +
323 + warn "$0: Unable to coerce $file into a portage dir name";
324 + return;
325 +}
326 +
327 +sub create_ebuild {
328 + my ( $module, $dir, $file, $build_dir, $prereq_pm, $md5 ) = @_;
329 +
330 + # First, make the directory
331 + my $fulldir = File::Spec->catdir( $perldev_overlay, $dir );
332 + my $filesdir = File::Spec->catdir( $fulldir, 'files' );
333 + unless ( -d $fulldir ) {
334 + mkdir $fulldir, 0755 or die "Couldn't create '$fulldir': $!";
335 + }
336 + unless ( -d $filesdir ) {
337 + mkdir $filesdir, 0755 or die "Couldn't create '$filesdir': $!";
338 + }
339 +
340 + unless ( -d $fulldir ) { die "$fulldir not created!!\n" }
341 + unless ( -d $filesdir ) { die "$fulldir not created!!\n" }
342 +
343 + # What to call this ebuild?
344 + # CGI::Builder's '1.26+' version breaks portage
345 + unless ( $file =~ m/(.*)\/(.*?)(-?)([0-9\.]+).*\.(?:tar|tgz|zip|bz2|gz)/ ) {
346 + warn("Couldn't turn '$file' into an ebuild name\n");
347 + return;
348 + }
349 +
350 + my ( $modpath, $filename, $filenamever ) = ( $1, $2, $4 );
351 +
352 + # remove underscores
353 + $filename =~ tr/A-Za-z0-9\./-/c;
354 + $filename =~ s/\.pm//; # e.g. CGI.pm
355 +
356 + # Remove double .'s - happens on occasion with odd packages
357 + $filenamever =~ s/\.$//;
358 +
359 + my $ebuild =
360 + File::Spec->catdir( $fulldir, "$filename-$filenamever.ebuild" );
361 + my $digest =
362 + File::Spec->catdir( $filesdir, "digest-$filename-$filenamever" );
363 +
364 + my $desc = $module->description || 'No description available.';
365 +
366 + print "Writing to $ebuild\n" if ($verbose);
367 + open EBUILD, ">$ebuild" or die "Could not write to '$ebuild': $!";
368 + print EBUILD <<"HERE";
369 +
370 +# Copyright 1999-2004 Gentoo Foundation
371 +# Distributed under the terms of the GNU General Public License v2
372 +
373 +inherit perl-module
374 +
375 +S=\${WORKDIR}/$build_dir
376 +DESCRIPTION="$desc"
377 +SRC_URI="mirror://cpan/authors/id/$file"
378 +HOMEPAGE="http://www.cpan.org/modules/by-authors/id/$modpath/\${P}.readme"
379 +
380 +IUSE=""
381 +
382 +SLOT="0"
383 +LICENSE="|| ( Artistic GPL-2 )"
384 +KEYWORDS="$arches"
385 +
386 +HERE
387 +
388 + if ( $prereq_pm && keys %$prereq_pm ) {
389 +
390 + print EBUILD q|DEPEND="|;
391 +
392 + my $first = 1;
393 + my %dup_check;
394 + for ( keys %$prereq_pm ) {
395 + my $obj = CPAN::Shell->expandany($_);
396 + my $dir = portage_dir($obj);
397 + if ( $dir =~ m/Module-Build/ ) {
398 + $dir =~ s/Module-Build/module-build/;
399 + }
400 + if ( $dir =~ m/PathTools/i ) {
401 + $dir = ">=dev-perl/File-Spec-3.01";
402 + } # Will need to fix once File-Spec is moved to perl-core - mcummings
403 + next if $dir eq "perl";
404 + if ( ( !$dup_check{$dir} ) && ( !module_check($dir) ) ) {
405 + $dup_check{$dir} = 1;
406 +
407 + # remove trailing .pm to fix emerge breakage.
408 + $dir =~ s/.pm$//;
409 + $dir = build_catdep($dir);
410 + print EBUILD "\n\t" unless $first;
411 + print EBUILD "$dir";
412 + }
413 + $first = 0;
414 + }
415 + print EBUILD qq|"\n\n|;
416 + }
417 +
418 + close EBUILD;
419 +
420 + # write the digest too
421 + open DIGEST, ">$digest" or die "Could not write to '$digest': $!";
422 + print DIGEST $md5, "\n";
423 + close DIGEST;
424 +}
425 +
426 +sub install_module {
427 + my ( $module_name, $recursive ) = @_;
428 + if ( $module_name !~ m|::| ) {
429 + $module_name =~ s/-/::/g;
430 + } # Assume they gave us module-name instead of module::name
431 +
432 + my $obj = CPAN::Shell->expandany($module_name);
433 + unless ( ( ref $obj eq "CPAN::Module" ) || ( ref $obj eq "CPAN::Bundle" ) )
434 + {
435 + warn("Don't know what '$module_name' is\n");
436 + return;
437 + }
438 +
439 + my $file = $obj->cpan_file;
440 + my $dir = portage_dir($obj);
441 + print "$0: portage_dir returned $dir\n" if ($verbose);
442 + unless ($dir) {
443 + warn("Couldn't turn '$file' into a directory name\n");
444 + return;
445 + }
446 +
447 + if ( ebuild_exists($dir) ) {
448 + printbig "Ebuild already exists for '$module_name': "
449 + . &ebuild_exists($dir) . "\n";
450 + return;
451 + }
452 + elsif ( !defined $recursive && module_check($module_name) ) {
453 + printbig "Module already installed for '$module_name'\n";
454 + return;
455 + }
456 + elsif ( $dir eq 'perl' ) {
457 + printbig "Module '$module_name' is part of the base perl install\n";
458 + return;
459 + }
460 +
461 + printbig "Need to create ebuild for '$module_name': $dir\n";
462 +
463 + # check depends ... with CPAN have to make the module
464 + # before it can tell us what the depends are, this stinks
465 +
466 + $CPAN::Config->{prerequisites_policy} = "";
467 + $CPAN::Config->{inactivity_timeout} = 30;
468 +
469 + my $pack = $CPAN::META->instance( 'CPAN::Distribution', $file );
470 + $pack->called_for( $obj->id );
471 + $pack->make;
472 +
473 + # A cheap ploy, but this lets us add module-build as needed
474 + # instead of forcing it on everyone
475 + my $add_mb = 0;
476 + if ( -f "Build.PL" ) { $add_mb = 1 }
477 + $pack->unforce if $pack->can("unforce") && exists $obj->{'force_update'};
478 + delete $obj->{'force_update'};
479 +
480 + # grab the MD5 checksum for the source file now
481 +
482 + my $localfile = $pack->{localfile};
483 + ( my $base = $file ) =~ s/.*\/(.*)/$1/;
484 +
485 + my $md5digest;
486 + open( DIGIFILE, $localfile ) or die "Can't open '$file': $!";
487 + binmode(DIGIFILE);
488 + $md5digest = Digest::MD5->new->addfile(*DIGIFILE)->hexdigest;
489 + close(DIGIFILE);
490 +
491 + my $md5string = sprintf "MD5 %s %s %d", $md5digest, $base, -s $localfile;
492 +
493 + # make ebuilds for all the prereqs
494 + my $prereq_pm = $pack->prereq_pm;
495 + if ($add_mb) { $prereq_pm->{'Module::Build'} = "0" }
496 + install_module( $_, 1 ) for ( keys %$prereq_pm );
497 +
498 + # get the build dir from CPAN, this will tell us definitively
499 + # what we should set S to in the ebuild
500 + # strip off the path element
501 + ( my $build_dir = $pack->{build_dir} ) =~ s|.*/||;
502 +
503 + create_ebuild( $obj, $dir, $file, $build_dir, $prereq_pm, $md5string );
504 +
505 + system( '/bin/mv', '-f', $localfile, $PORTAGE_DISTDIR );
506 +
507 + push @ebuild_list, "perl-gcpan/$dir";
508 +}
509 +
510 +sub upgrade_module {
511 +
512 +# My counter intuituve function - this time we *want* there to be an ebuild, because we want to track versions to make sure the ebuild is >= the module on cpan
513 + my ( $module_name, $recursive ) = @_;
514 + if ( $module_name !~ m|::| ) {
515 + $module_name =~ s/-/::/g;
516 + } # Assume they gave us module-name instead of module::name
517 + print "Looking for $module_name...\n";
518 + my $obj = CPAN::Shell->expandany($module_name);
519 + unless ( ( ref $obj eq "CPAN::Module" ) || ( ref $obj eq "CPAN::Bundle" ) )
520 + {
521 + warn("Don't know what '$module_name' is\n");
522 + return;
523 + }
524 +
525 + my $file = $obj->cpan_file;
526 + my $dir = portage_dir($obj);
527 + print "$0: portage_dir returned $dir\n" if ($verbose);
528 + unless ($dir) {
529 + warn("Couldn't turn '$file' into a directory name\n");
530 + return;
531 + }
532 +
533 + unless ( ebuild_exists($dir) ) {
534 + printbig "No ebuild available for '$module_name': "
535 + . &ebuild_exists($dir) . "\n";
536 + return;
537 + }
538 + elsif ( defined $recursive && !module_check($module_name) ) {
539 + printbig "No module installed for '$module_name'\n";
540 + return;
541 + }
542 + elsif ( $dir eq 'perl' ) {
543 + printbig
544 +"Module '$module_name' is part of the base perl install - we don't touch perl here\n";
545 + return;
546 + }
547 +
548 + printbig "Checking ebuild for '$module_name': $dir\n";
549 +
550 + # check depends ... with CPAN have to make the module
551 + # before it can tell us what the depends are, this stinks
552 +
553 + $CPAN::Config->{prerequisites_policy} = "";
554 + $CPAN::Config->{inactivity_timeout} = 30;
555 +
556 + my $pack = $CPAN::META->instance( 'CPAN::Distribution', $file );
557 + $pack->called_for( $obj->id );
558 + $pack->make;
559 +
560 + # A cheap ploy, but this lets us add module-build as needed
561 + # instead of forcing it on everyone
562 + my $add_mb = 0;
563 + if ( -f "Build.PL" ) { $add_mb = 1 }
564 + $pack->unforce if $pack->can("unforce") && exists $obj->{'force_update'};
565 + delete $obj->{'force_update'};
566 +
567 + # grab the MD5 checksum for the source file now
568 +
569 + my $localfile = $pack->{localfile};
570 + ( my $base = $file ) =~ s/.*\/(.*)/$1/;
571 +
572 + my $md5digest;
573 + open( DIGIFILE, $localfile ) or die "Can't open '$file': $!";
574 + binmode(DIGIFILE);
575 + $md5digest = Digest::MD5->new->addfile(*DIGIFILE)->hexdigest;
576 + close(DIGIFILE);
577 +
578 + my $md5string = sprintf "MD5 %s %s %d", $md5digest, $base, -s $localfile;
579 +
580 + # make ebuilds for all the prereqs
581 + my $prereq_pm = $pack->prereq_pm;
582 + if ($add_mb) { $prereq_pm->{'Module::Build'} = "0" }
583 + install_module( $_, 1 ) for ( keys %$prereq_pm );
584 +
585 + # get the build dir from CPAN, this will tell us definitively
586 + # what we should set S to in the ebuild
587 + # strip off the path element
588 + ( my $build_dir = $pack->{build_dir} ) =~ s|.*/||;
589 +
590 + create_ebuild( $obj, $dir, $file, $build_dir, $prereq_pm, $md5string );
591 + unless ( -f "$PORTAGE_DISTDIR/$localfile" ) {
592 + system( '/bin/mv', '-f', $localfile, $PORTAGE_DISTDIR );
593 + push @ebuild_list, "perl-gcpan/$dir";
594 + }
595 +}
596 +
597 +sub clean_up {
598 +
599 + #Probably don't need to do this, but for sanity's sake, we reset this var
600 + # $ENV{'PORTDIR_OVERLAY'} = $OVERLAYS[0];
601 +
602 + if ($needs_cpan_stub) { unlink "$ENV{HOME}/.cpan/CPAN/MyConfig.pm" }
603 +
604 + #Clean out the /tmp tree we were using
605 + rmtree( ["$tmp_overlay_dir"] ) if ( !$OVERLAYS[0] );
606 +}
607 +
608 +sub emerge_module {
609 + foreach my $ebuild_name (@ebuild_list) {
610 + $ebuild_name =~ m/.*\/(.*)-[^-]+\./;
611 + print "$0: emerging $ebuild_name\n";
612 + system( "emerge", "--oneshot", "--digest", $ebuild_name );
613 + }
614 +}
615 +
616 +sub emerge_up_module {
617 +
618 + #my @e_list = @_;
619 + print "\n\n";
620 + foreach my $ebuild_name (@ebuild_list) {
621 + $ebuild_name =~ m/.*\/(.*)-[^-]+\./;
622 + print "* Upgrade available for $ebuild_name\n";
623 + }
624 + print "\nContinue with upgrade? (Y|N) ";
625 + my $answer = <STDIN>;
626 + chomp($answer);
627 + if ( $answer =~ m|y|i ) {
628 + foreach my $ebuild_name (@ebuild_list) {
629 + system( "emerge", "--oneshot", "--digest", $ebuild_name );
630 + }
631 + }
632 + return;
633 +
634 +}
635 +
636 +sub get_globals {
637 +
638 + # Setting default configs
639 + my %conf;
640 + $conf{PORTDIR} = "/usr/portage";
641 + $conf{DISTDIR} = "/usr/portage/distfiles";
642 + my @OVERLAYS = ();
643 +
644 + # Opening make.conf to find real user settings
645 + open CONF, "<$MAKECONF" or die "Open $MAKECONF failed : $!";
646 +
647 + # And parsing it :)
648 + while ( defined( my $line = <CONF> ) ) {
649 +
650 + # Improving speed by ignoring comments
651 + next if ( substr( $line, 0, 1 ) eq '#' );
652 + chomp $line;
653 +
654 + $line =~ tr/"'//d; # Remove quotes to be safe
655 +
656 + # Now replacing defaults, if other values are set
657 + if ( $line =~ m/^PORTDIR\s*=\s*(.+)$/ ) {
658 + $conf{PORTDIR} = $1;
659 + }
660 + if ( $line =~ m/^DISTDIR\s*=\s*(.+)$/ ) {
661 + $conf{DISTDIR} = $1;
662 + }
663 + if ( $line =~ m/^PORTDIR_OVERLAY\s*=\s*(.+)$/ ) {
664 + my $hold_overlay = $1;
665 + if ( $hold_overlay =~
666 + m/\b\s*/ ) # make.conf contains multiple overlay options
667 + {
668 + my @hold_ov = split( ' ', $hold_overlay );
669 + foreach my $hold_o (@hold_ov) { push @OVERLAYS, $hold_o }
670 + }
671 + else {
672 + push @OVERLAYS, $hold_overlay;
673 + }
674 + }
675 + }
676 + close CONF;
677 +
678 + # If the PORTDIR_OVERLAY is an env var, test to see if it is multiples are not
679 + if ( $ENV{PORTDIR_OVERLAY} ) {
680 + if ( $ENV{PORTDIR_OVERLAY} =~ m/\b\s*/ ) # At least 2, space seperated
681 + {
682 + my @tmp_overlays = split( ' ', $ENV{PORTDIR_OVERLAY} );
683 + foreach my $tmp_o (@tmp_overlays) {
684 + if ( $tmp_o =~ m/\w+/ ) { push @OVERLAYS, $tmp_o }
685 + }
686 + }
687 + else {
688 + push @OVERLAYS, $ENV{PORTDIR_OVERLAY};
689 + }
690 + }
691 +
692 + $conf{DISTDIR} = clean_vars( $conf{DISTDIR}, %conf );
693 + my $count_o = @OVERLAYS;
694 + for ( my $i = 0 ; $i < $count_o ; $i++ ) {
695 + $OVERLAYS[$i] = clean_vars( $OVERLAYS[$i], %conf );
696 + }
697 +
698 + return ( $conf{DISTDIR}, $conf{PORTDIR}, @OVERLAYS );
699 +}
700 +
701 +sub clean_vars {
702 +
703 + # In order to parse strange but allowed constructions,
704 + # (i.e. DISTDIR=${PORTDIR}/disfiles), we are cycling some times
705 + # (3 should be enough) on DISTDIR and PORTDIR_OVERLAY settings,
706 + # using a nice regexp (thx Sniper - sniper@×××××××××.net)
707 + my ( $toclean, %conf ) = @_;
708 + foreach my $i ( 1 .. 3 ) { $toclean =~ s/\$\{ ( [^}]+ ) \}/$conf{$1}/egx }
709 + return ($toclean);
710 +}
711 +
712 +sub cpan_stub {
713 + printbig
714 +"No CPAN Config found, auto-generating a basic one in $ENV{HOME}/.cpan/CPAN\n";
715 + unless ( -d "$ENV{HOME}/.cpan" ) {
716 + mkpath( "$ENV{HOME}/.cpan", 1, 0755 )
717 + or die "Couldn't create $ENV{HOME}/.cpan: $|";
718 + }
719 + unless ( -d "$ENV{HOME}/.cpan/CPAN" ) {
720 + mkpath( "$ENV{HOME}/.cpan/CPAN", 1, 0755 )
721 + or die "Couldn't create $ENV{HOME}/.cpan/CPAN: $|";
722 + }
723 +
724 + my (
725 + $tmp_dir, $ftp_prog, $gpg_prog, $gzip_prog,
726 + $lynx_prog, $make_prog, $ncftpget_prog, $less_prog,
727 + $tar_prog, $unzip_prog, $wget_prog, $ftp_proxy,
728 + $http_proxy, $user_shell
729 + );
730 + if ( $ENV{TMPDIR} ) { $tmp_dir = $ENV{TMPDIR} }
731 + else { $tmp_dir = "$ENV{HOME}" }
732 + if ( -f "/usr/bin/ftp" ) { $ftp_prog = "/usr/bin/ftp" }
733 + else { $ftp_prog = "" }
734 + if ( -f "/usr/bin/gpg" ) { $gpg_prog = "/usr/bin/gpg" }
735 + else { $gpg_prog = "" }
736 + if ( -f "/bin/gzip" ) { $gzip_prog = "/bin/gzip" }
737 + else { $gzip_prog = "" }
738 + if ( -f "/usr/bin/lynx" ) { $lynx_prog = "/usr/bin/lynx" }
739 + else { $lynx_prog = "" }
740 + if ( -f "/usr/bin/make" ) { $make_prog = "/usr/bin/make" }
741 + else { $make_prog = "" }
742 + if ( -f "/usr/bin/ncftpget" ) { $ncftpget_prog = "/usr/bin/ncftpget" }
743 + else { $ncftpget_prog = "" }
744 + if ( -f "/usr/bin/less" ) { $less_prog = "/usr/bin/less" }
745 + else { $less_prog = "" }
746 + if ( -f "/bin/tar" ) { $tar_prog = "/bin/tar" }
747 + else { $tar_prog = "" }
748 + if ( -f "/usr/bin/unzip" ) { $unzip_prog = "/usr/bin/unzip" }
749 + else { $unzip_prog = "" }
750 + if ( -f "/usr/bin/wget" ) { $wget_prog = "/usr/bin/wget" }
751 + else { $wget_prog = "" }
752 + if ( $ENV{ftp_proxy} ) { $ftp_proxy = $ENV{ftp_proxy} }
753 + else { $ftp_proxy = "" }
754 + if ( $ENV{http_proxy} ) { $http_proxy = $ENV{http_proxy} }
755 + else { $http_proxy = "" }
756 + if ( $ENV{SHELL} ) { $user_shell = $ENV{SHELL} }
757 + else { $user_shell = "/bin/bash" }
758 + open( CPANCONF, ">$ENV{HOME}/.cpan/CPAN/MyConfig.pm" );
759 + print CPANCONF <<"SHERE";
760 +
761 +# This is CPAN.pm's systemwide configuration file. This file provides
762 +# defaults for users, and the values can be changed in a per-user
763 +# configuration file. The user-config file is being looked for as
764 +# ~/.cpan/CPAN/MyConfig\.pm. This was generated by g-cpan for temporary usage
765 +
766 +\$CPAN::Config = {
767 + 'build_cache' => q[10],
768 + 'build_dir' => q[$tmp_dir/.cpan/build],
769 + 'cache_metadata' => q[1],
770 + 'cpan_home' => q[$tmp_dir/.cpan],
771 + 'dontload_hash' => { },
772 + 'ftp' => q[$ftp_prog],
773 + 'ftp_proxy' => q[$ftp_proxy],
774 + 'getcwd' => q[cwd],
775 + 'gpg' => q[$gpg_prog],
776 + 'gzip' => q[$gzip_prog],
777 + 'histfile' => q[$tmp_dir/.cpan/histfile],
778 + 'histsize' => q[100],
779 + 'http_proxy' => q[$http_proxy],
780 + 'inactivity_timeout' => q[0],
781 + 'index_expire' => q[1],
782 + 'inhibit_startup_message' => q[0],
783 + 'keep_source_where' => q[$tmp_dir/.cpan/sources],
784 + 'lynx' => q[$lynx_prog],
785 + 'make' => q[$make_prog],
786 + 'make_arg' => q[],
787 + 'make_install_arg' => q[],
788 + 'makepl_arg' => q[],
789 + 'ncftpget' => q[$ncftpget_prog],
790 + 'no_proxy' => q[],
791 + 'pager' => q[$less_prog],
792 + 'prerequisites_policy' => q[follow],
793 + 'scan_cache' => q[atstart],
794 + 'shell' => q[$user_shell],
795 + 'tar' => q[$tar_prog],
796 + 'term_is_latin' => q[1],
797 + 'unzip' => q[$unzip_prog],
798 + 'urllist' => [q[http://search.cpan.org/CPAN],],
799 + 'wget' => q[$wget_prog],
800 +};
801 +1;
802 +__END__
803 +
804 +
805 +SHERE
806 +
807 + close(CPANCONF);
808 +
809 +}
810 +
811 +sub clean_the_mess {
812 + if ($verbose) {
813 + print "Now cleaning up the system of all the junk we put in !\n";
814 + }
815 + if ($needs_cpan_stub) {
816 + unlink "$ENV{HOME}/.cpan/CPAN/MyConfig.pm";
817 + #add something here to take care of the .cpan dir, if not empty
818 + }
819 +}
820 +
821 +sub exit_usage {
822 + print <<"USAGE";
823 +Usage : $0 [-i|--install] [-s|--search] [-v|--verbose] Module Name(s)
824 +
825 +--install,-i Try to generate ebuild for the given module name
826 + and, if successful, emerge it. Important : installation
827 + requires exact CPAN Module Name.
828 +
829 +--search,-s Search CPAN for the given expression (similar to
830 + the "m /EXPR/" from the CPAN Shell). Searches are
831 + case insensitive.
832 +
833 +--verbose,-v Enable (some) verbose output.
834 +
835 +USAGE
836 +
837 + exit;
838 +}
839
840
841 Property changes on: g-cpan.pl
842 ___________________________________________________________________
843 Name: svn:executable
844 + *
845
846
847 --
848 gentoo-perl@g.o mailing list