Re: Distribution installer that defaults to Debian?
On Mon, Dec 20, 2010 at 02:13:07PM +0200, Gabor Szabo wrote:
> It would be nice to see this on CPAN to encourage distributions to
> implement the same.
Okay, well, first what about having a look at the script
below? Does it do what you'd want?
Then, what about a name?
CPAN::NativePackageInstaller::Debian
CPAN::Installer::Debian
Debian::CPAN::HybridInstaller
Would there be any benefit to prefixing App:: ?
The script might be named 'dcpan', easy to type and remember
> I also wonder if it could be integrated into CPAN.pm (and friends)
> itself so if I type
>
> cpan Module::Name it will install dependencies using apt-get - if
> possible and using cpan (with local::lib)
> otherwise.
I think this would work at the top level, where
the user is not constraining the version number.
The harder problem is the dependency case you mentioned.
> BTW what happens if a secondary dependency is available as a
> .deb package ? I mean if I am installing package X which
> depends on Y which in turn depends on W and only W is in
> .deb X and Y are not. Will your script notice this situation
> and install W using apt-get ?
Say Y requires W (>=0.5), but the corresponding Debian
libw-perl is only 0.4.
It seems we can't reliably extract the upstream version from the
Debian package metadata. An enhanced CPAN client might
work around this limitation by:
- installing the Debian package for W
- seeing if Y's dependency is met
- falling back to installing W from CPAN.
cheers,
Joel
--- script: dcpan ----
#!/usr/bin/perl
use Debian::AptContents;
use Module::Load::Conditional 'check_install';
use YAML::Tiny;
use Getopt::Std;
use Modern::Perl;
no warnings 'uninitialized';
my $c = Debian::AptContents->new( { homedir => '/tmp/.dh-make-perl' } );
# flags:
# -i - install
our $opt_i;
getopt('i');
# input should be perl module name, i.e. DBIx::Class:Schema
my $want = shift;
say qq(\nSearching for "$want"\n);
my $href = check_install(module => $want);
if ( defined $href )
{
say qq(Module $want is already installed.);
my $y = YAML::Tiny->new;
$y->[0] = $href;
my $output = $y->write_string();
$output =~ s/^---.//s;
say join "\n ",'',split "\n",$output;
}
my( @apt_file_pkgs, @find_file_pkgs );
unless($want =~ /::/){
@apt_file_pkgs = split "\n",qx(apt-file -l find $want);
say_results("apt-file",@apt_file_pkgs);
@find_file_pkgs = $c->find_file_packages($want);
say_results("file name",@find_file_pkgs);
# hmm, no output at all for this
}
my $find_perl_pkg = $c->find_perl_module_package($want);
say_results("distribution name",$find_perl_pkg);
# which to install
my @debian_available = (
@find_file_pkgs,
@apt_file_pkgs,
);
my $debian_pkg = $find_perl_pkg || shift @debian_available;
say "Installation candidate for $want ",
($opt_i ? "is " : "would be "),
$debian_pkg ? qq("$debian_pkg") : "CPAN";
# stop here unless instructed to install (-i option)
say("\nUse -i flag to install."), exit unless $opt_i;
if ($debian_pkg)
{
system("sudo apt-get install $debian_pkg");
}
else
{
# choose installer, prefering cpanm to cpan
my $cpan_installer = qx(which cpanm) || qx(which cpan);
say("No installer found, neither 'cpan' nor 'cpanm'. Aborting."),
exit unless $cpan_installer;
system("$cpan_installer $want");
}
sub say_results {
my ($method, @results) = @_;
$results[0] or return;
say "Search by $method found packages:\n", join "\n ", '',@results;
say;
}
__END__
--
Joel Roth
Reply to: