+use File::Spec;
+use File::Copy qw<copy>;
+use List::Util qw<max reduce>;
+use Storable ();
+use Term::ANSIColor;
+
+use CPAN::DistnameInfo 0.11;
+
+use Capture::Tiny qw<capture>;
+use LWP::UserAgent;
+use Parse::CPAN::Packages::Fast;
+
+use lib 'lib';
+use CPANPLUS::Dist::Gentoo::Atom;
+use CPANPLUS::Dist::Gentoo::Maps;
+
+use constant PACKAGES => File::Spec->catdir(
+ $ENV{HOME}, '.cpanplus', '02packages.details.txt.gz'
+);
+use constant CPAN_MIRROR => 'http://www.cpan.org/';
+use constant PORTAGE => '/usr/portage';
+use constant TARGET => 'lib/CPANPLUS/Dist/Gentoo/Maps.pm';
+use constant BACKUP => TARGET . '.bak';
+use constant DATA_FILE => 'gentooisms.data.sto';
+use constant STATE_FILE => 'gentooisms.state.sto';
+
+my %is_on_cpan = (
+ 'Audio-CD-disc-cover' => 0,
+ 'Video-Frequencies' => 0,
+ 'Sphinx-Search' => 1,
+ 'WattsUp-Daemon' => 1,
+);
+
+sub p {
+ my ($indent, $fmt, @args) = @_;
+ $fmt = (' ' x ($indent * 3)) . $fmt;
+ printf $fmt, @args;
+}
+
+my $timestamp = CPANPLUS::Dist::Gentoo::Maps::get_portage_timestamp(PORTAGE);
+die 'Could not read the timestamp from the portage tree ' . PORTAGE . "\n"
+ unless defined $timestamp;
+
+{
+ my $ua;
+
+ sub cpan_http_test {
+ my ($path) = @_;
+
+ unless (defined $ua) {
+ $ua = LWP::UserAgent->new;
+ $ua->agent('CPANPLUS::Dist::Gentoo gentooisms generator/1.0');
+ }
+
+ my $r = $ua->head(CPAN_MIRROR . $path);
+
+ return $r && $r->code == 200;
+ }
+}
+
+my %fetched_uri;
+my (@not_on_cpan, @unfindable, @missing, %name_mismatch, %version);
+
+sub parse_portage_tree {
+ my $pcp = Parse::CPAN::Packages::Fast->new(PACKAGES);
+
+ for my $category (qw<perl-core dev-perl>) {
+ p(0, "Browsing the $category category.\n");
+
+ my $cat_dir = File::Spec->catdir(PORTAGE, $category);
+
+ for my $pkg_dir (glob File::Spec->catdir($cat_dir, '*')) {
+ next unless -d $pkg_dir;
+
+ my $pkg_name = (File::Spec->splitdir($pkg_dir))[-1];
+
+ my $last = reduce { $a->[1] > $b->[1] ? $a : $b }
+ grep $_->[1] != 9999,
+ map [ $_, CPANPLUS::Dist::Gentoo::Atom->new_from_ebuild($_) ],
+ glob File::Spec->catfile($pkg_dir, "$pkg_name-*");
+ my ($ebuild, $atom) = @$last;
+ p(1, "%s/%s-%s\n", map $atom->$_, qw<category name version>);
+
+ if (exists $is_on_cpan{$pkg_name} and not $is_on_cpan{$pkg_name}) {
+ p(2, colored("$pkg_name is not a CPAN distribution (forced)", 'bright_red')
+ . "\n");
+ push @not_on_cpan, "$category/$pkg_name";
+ next;
+ }
+
+ my $uri;
+ if (exists $fetched_uri{$ebuild}) {
+ $uri = $fetched_uri{$ebuild};
+ } else {
+ my @cmd = ('ebuild', $ebuild, 'help', '--debug');
+ my ($ret, $code);
+ (undef, my $err) = capture {
+ $ret = system { $cmd[0] } @cmd;
+ $code = $?;
+ };
+ if ($ret != 0 or $code == -1 or $code & 127 or $code >> 8) {
+ die "system(\"@cmd\") returned $ret and/or failed with status $code";