package Padre::CPAN;
use 5.008;
use strict;
use warnings;
use File::Spec ();
use File::HomeDir ();
use Padre::Wx ();
our $VERSION = '1.00';
######################################################################
# Integration with CPAN.pm
my $SINGLETON = undef;
sub new {
my $class = shift;
unless ($SINGLETON) {
require CPAN;
$SINGLETON = bless {}, $class;
CPAN::HandleConfig->load(
be_silent => 1,
);
$SINGLETON->{modules} = [ map { $_->id } CPAN::Shell->expand( 'Module', '/^/' ) ];
}
return $SINGLETON;
}
sub get_modules {
my $self = shift;
my $regex = shift;
$regex ||= '^';
$regex =~ s/ //g;
my $MAX_DISPLAY = 100;
my $i = 0;
my @modules;
foreach my $module ( @{ $self->{modules} } ) {
next if $module !~ /$regex/i;
$i++;
last if $i > $MAX_DISPLAY;
push @modules, $module;
}
return \@modules;
}
sub cpan_config {
my $class = shift;
my $main = shift;
# Locate the CPAN config file(s)
my $default_dir = '';
eval {
require CPAN;
$default_dir = $INC{'CPAN.pm'};
$default_dir =~ s/\.pm$//is; # remove .pm
};
# Load the main config first
if ( $default_dir ne '' ) {
my $core = File::Spec->catfile( $default_dir, 'Config.pm' );
if ( -e $core ) {
$main->setup_editors($core);
return;
}
}
# Fallback to a personal config
my $user = File::Spec->catfile(
File::HomeDir->my_home,
'.cpan', 'CPAN', 'MyConfig.pm'
);
if ( -e $user ) {
$main->setup_editors($user);
return;
}
$main->error( Wx::gettext('Failed to find your CPAN configuration') );
}
######################################################################
# Integration with cpanm
sub install_file {
my $class = shift;
my $main = shift;
# Ask what we should install
my $dialog = Wx::FileDialog->new(
$main,
Wx::gettext('Select distribution to install'),
'', # Default directory
'', # Default file
'CPAN Packages (*.tar.gz)|*.tar.gz', # wildcard
Wx::FD_OPEN | Wx::FD_FILE_MUST_EXIST
);
$dialog->CentreOnParent;
if ( $dialog->ShowModal == Wx::ID_CANCEL ) {
return;
}
my $string = $dialog->GetPath;
$dialog->Destroy;
unless ( defined $string and $string =~ /\S/ ) {
$main->error( Wx::gettext('Did not provide a distribution') );
return;
}
$class->install_cpanm( $main, $string );
}
sub install_url {
my $class = shift;
my $main = shift;
# Ask what we should install
my $dialog = Wx::TextEntryDialog->new(
$main,
Wx::gettext("Enter URL to install\ne.g. http://svn.ali.as/cpan/releases/Config-Tiny-2.00.tar.gz"),
Wx::gettext('Install Local Distribution'),
'',
);
if ( $dialog->ShowModal == Wx::ID_CANCEL ) {
return;
}
my $string = $dialog->GetValue;
$dialog->Destroy;
unless ( defined $string and $string =~ /\S/ ) {
$main->error( Wx::gettext('Did not provide a distribution') );
return;
}
$class->install_cpanm( $main, $string );
}
sub install_cpanm {
my $class = shift;
my $main = shift;
my $module = shift;
# TODO cpanm might come with Padre but if we are dealing with another perl
# not the one that Padre runs on then we will need to look for cpanm
# in some other place
# Find 'cpanm', used to install modules
require Config;
my %seen = ();
my @where =
grep { defined $_ and length $_ and not $seen{$_}++ }
map { $Config::Config{$_} }
qw{
sitescriptexp
sitebinexp
vendorscriptexp
vendorbinexp
scriptdirexp
binexp
};
push @where, split /$Config::Config{path_sep}/, $ENV{PATH};
my $cpanm = '';
foreach my $dir (@where) {
my $path = File::Spec->catfile( $dir, 'cpanm' );
if ( -f $path ) {
$cpanm = $path;
last;
}
}
unless ($cpanm) {
$main->error( Wx::gettext('cpanm is unexpectedly not installed') );
return;
}
# Create the command
require Padre::Perl;
my $perl = Padre::Perl::cperl();
my $cmd = qq{"$perl" "$cpanm" "$module"};
$main->run_command($cmd);
return;
}
1;
# Copyright 2008-2013 The Padre development team as listed in Padre.pm.
# LICENSE
# This program is free software; you can redistribute it and/or
# modify it under the same terms as Perl 5 itself.