[Date Prev][Date Next] [Thread Prev][Thread Next] [Date Index] [Thread Index]

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: