# -*- Mode: cperl; coding: utf-8; cperl-indent-level: 4 -*-
# vim: ts=4 sts=4 sw=4:
package CPAN::InfoObj;
use strict;
use CPAN::Debug;
@CPAN::InfoObj::ISA = qw(CPAN::Debug);
use Cwd qw(chdir);
use vars qw(
$VERSION
);
$VERSION = "5.5";
sub ro {
my $self = shift;
exists $self->{RO} and return $self->{RO};
}
#-> sub CPAN::InfoObj::cpan_userid
sub cpan_userid {
my $self = shift;
my $ro = $self->ro;
if ($ro) {
return $ro->{CPAN_USERID} || "N/A";
} else {
$self->debug("ID[$self->{ID}]");
# N/A for bundles found locally
return "N/A";
}
}
sub id { shift->{ID}; }
#-> sub CPAN::InfoObj::new ;
sub new {
my $this = bless {}, shift;
%$this = @_;
$this
}
# The set method may only be used by code that reads index data or
# otherwise "objective" data from the outside world. All session
# related material may do anything else with instance variables but
# must not touch the hash under the RO attribute. The reason is that
# the RO hash gets written to Metadata file and is thus persistent.
#-> sub CPAN::InfoObj::safe_chdir ;
sub safe_chdir {
my($self,$todir) = @_;
# we die if we cannot chdir and we are debuggable
Carp::confess("safe_chdir called without todir argument")
unless defined $todir and length $todir;
if (chdir $todir) {
$self->debug(sprintf "changed directory to %s", CPAN::anycwd())
if $CPAN::DEBUG;
} else {
if (-e $todir) {
unless (-x $todir) {
unless (chmod 0755, $todir) {
my $cwd = CPAN::anycwd();
$CPAN::Frontend->mywarn("I have neither the -x permission nor the ".
"permission to change the permission; cannot ".
"chdir to '$todir'\n");
$CPAN::Frontend->mysleep(5);
$CPAN::Frontend->mydie(qq{Could not chdir from cwd[$cwd] }.
qq{to todir[$todir]: $!});
}
}
} else {
$CPAN::Frontend->mydie("Directory '$todir' has gone. Cannot continue.\n");
}
if (chdir $todir) {
$self->debug(sprintf "changed directory to %s", CPAN::anycwd())
if $CPAN::DEBUG;
} else {
my $cwd = CPAN::anycwd();
$CPAN::Frontend->mydie(qq{Could not chdir from cwd[$cwd] }.
qq{to todir[$todir] (a chmod has been issued): $!});
}
}
}
#-> sub CPAN::InfoObj::set ;
sub set {
my($self,%att) = @_;
my $class = ref $self;
# This must be ||=, not ||, because only if we write an empty
# reference, only then the set method will write into the readonly
# area. But for Distributions that spring into existence, maybe
# because of a typo, we do not like it that they are written into
# the readonly area and made permanent (at least for a while) and
# that is why we do not "allow" other places to call ->set.
unless ($self->id) {
CPAN->debug("Bug? Empty ID, rejecting");
return;
}
my $ro = $self->{RO} =
$CPAN::META->{readonly}{$class}{$self->id} ||= {};
while (my($k,$v) = each %att) {
$ro->{$k} = $v;
}
}
#-> sub CPAN::InfoObj::as_glimpse ;
sub as_glimpse {
my($self) = @_;
my(@m);
my $class = ref($self);
$class =~ s/^CPAN:://;
my $id = $self->can("pretty_id") ? $self->pretty_id : $self->{ID};
push @m, sprintf "%-15s %s\n", $class, $id;
join "", @m;
}
#-> sub CPAN::InfoObj::as_string ;
sub as_string {
my($self) = @_;
my(@m);
my $class = ref($self);
$class =~ s/^CPAN:://;
push @m, $class, " id = $self->{ID}\n";
my $ro;
unless ($ro = $self->ro) {
if (substr($self->{ID},-1,1) eq ".") { # directory
$ro = +{};
} else {
$CPAN::Frontend->mywarn("Unknown object $self->{ID}\n");
$CPAN::Frontend->mysleep(5);
return;
}
}
for (sort keys %$ro) {
# next if m/^(ID|RO)$/;
my $extra = "";
if ($_ eq "CPAN_USERID") {
$extra .= " (";
$extra .= $self->fullname;
my $email; # old perls!
if ($email = $CPAN::META->instance("CPAN::Author",
$self->cpan_userid
)->email) {
$extra .= " <$email>";
} else {
$extra .= " <no email>";
}
$extra .= ")";
} elsif ($_ eq "FULLNAME") { # potential UTF-8 conversion
push @m, sprintf " %-12s %s\n", $_, $self->fullname;
next;
}
next unless defined $ro->{$_};
push @m, sprintf " %-12s %s%s\n", $_, $ro->{$_}, $extra;
}
KEY: for (sort keys %$self) {
next if m/^(ID|RO)$/;
unless (defined $self->{$_}) {
delete $self->{$_};
next KEY;
}
if (ref($self->{$_}) eq "ARRAY") {
push @m, sprintf " %-12s %s\n", $_, "@{$self->{$_}}";
} elsif (ref($self->{$_}) eq "HASH") {
my $value;
if (/^CONTAINSMODS$/) {
$value = join(" ",sort keys %{$self->{$_}});
} elsif (/^prereq_pm$/) {
my @value;
my $v = $self->{$_};
for my $x (sort keys %$v) {
my @svalue;
for my $y (sort keys %{$v->{$x}}) {
push @svalue, "$y=>$v->{$x}{$y}";
}
push @value, "$x\:" . join ",", @svalue if @svalue;
}
$value = join ";", @value;
} else {
$value = $self->{$_};
}
push @m, sprintf(
" %-12s %s\n",
$_,
$value,
);
} else {
push @m, sprintf " %-12s %s\n", $_, $self->{$_};
}
}
join "", @m, "\n";
}
#-> sub CPAN::InfoObj::fullname ;
sub fullname {
my($self) = @_;
$CPAN::META->instance("CPAN::Author",$self->cpan_userid)->fullname;
}
#-> sub CPAN::InfoObj::dump ;
sub dump {
my($self, $what) = @_;
unless ($CPAN::META->has_inst("Data::Dumper")) {
$CPAN::Frontend->mydie("dump command requires Data::Dumper installed");
}
local $Data::Dumper::Sortkeys;
$Data::Dumper::Sortkeys = 1;
my $out = Data::Dumper::Dumper($what ? eval $what : $self);
if (length $out > 100000) {
my $fh_pager = FileHandle->new;
local($SIG{PIPE}) = "IGNORE";
my $pager = $CPAN::Config->{'pager'} || "cat";
$fh_pager->open("|$pager")
or die "Could not open pager $pager\: $!";
$fh_pager->print($out);
close $fh_pager;
} else {
$CPAN::Frontend->myprint($out);
}
}
1;
Copyright 2K16 - 2K18 Indonesian Hacker Rulez