#!/usr/bin/perl -w # -*- perl -*- # # $Id: mkprereqinst,v 1.11 2003/05/01 21:29:24 eserte Exp $ # Author: Slaven Rezic # # Copyright (C) 2002, 2003 Slaven Rezic. All rights reserved. # This package is free software; you can redistribute it and/or # modify it under the same terms as Perl itself. # # Mail: slaven@rezic.de # The latest version of mkprereqinst may be found at # http://www.perl.com/CPAN-local/authors/id/S/SR/SREZIC/ # use Config; use Getopt::Long; use strict; use vars qw($VERSION); use ExtUtils::MakeMaker; use File::Basename qw(basename); $VERSION = sprintf("%d.%02d", q$Revision: 1.11 $ =~ /(\d+)\.(\d+)/); my $v; my $exec; my $do_cpan; my $do_ppm; my $o = "prereqinst.pl"; my $Makefile_PL; if (!GetOptions("v!" => \$v, "exec!" => \$exec, "cpan!" => \$do_cpan, "ppm!" => \$do_ppm, "o=s" => \$o, )) { require Pod::Usage; Pod::Usage::pod2usage(1); } my $prereq_pm; if (@ARGV) { $prereq_pm = set_prereq_pm(@ARGV); } elsif (-r "META.yml" && eval { require YAML }) { # Use META.yml of Build.PL my $meta = YAML::LoadFile("META.yml"); $prereq_pm = $meta->{requires}; } else { # Good old Makefile.PL { local $^W = 0; *ExtUtils::MakeMaker::WriteMakefile = sub { $Makefile_PL = { @_ }; }; do "Makefile.PL"; die $@ if $@; } $prereq_pm = $Makefile_PL->{PREREQ_PM}; if (ref $prereq_pm ne 'HASH') { warn "No prerequisites found in Makefile.PL\n"; exit 0; } } my $code = ""; $code .= < sub { $use = 'ppm' }, "cpan" => sub { $use = 'cpan' }, )) { die "usage: $0 [-ppm | -cpan]\n"; } EOF my(@installs, @ppm_installs, @requires, @modlist); while(my($mod, $ver) = each %$prereq_pm) { my $check_mod = "require $mod"; if ($ver) { $check_mod .= "; $mod->VERSION($ver)"; } push @installs, "install '$mod' if !eval '$check_mod';"; (my $ppm = $mod) =~ s/::/-/g; push @ppm_installs, "do { print STDERR 'Install $ppm'.qq(\\n); PPM::InstallPackage(package => '$ppm') or warn ' (not successful)'.qq(\\n); } if !eval '$check_mod';"; push @requires, "if (!eval 'require $mod;" . ($ver ? " $mod->VERSION($ver);" : "") . '\') { warn $@; $require_errors++ }'; push @modlist, $mod . ($ver ? " $ver" : ""); } $code .= < $o") or die "Can't write $o: $!"; print F $code; close F; chmod 0755, $o; } if ($v) { require Text::Wrap; print STDERR Text::Wrap::wrap("Dependencies: ", " ", join(", ", @modlist) . "\n"); } sub set_prereq_pm { my(@args) = @_; my $prereq_pm = {}; my $curr_mod; for(my $i=0; $i<=$#args; $i++) { if ($args[$i] =~ /^\d/) { if (!defined $curr_mod) { die "Got version <$args[$i]>, but expected module name!"; } $prereq_pm->{$curr_mod} = $args[$i]; undef $curr_mod; } else { if (defined $curr_mod) { $prereq_pm->{$curr_mod} = undef; } $curr_mod = $args[$i]; } } if (defined $curr_mod) { $prereq_pm->{$curr_mod} = undef; } $prereq_pm; } __END__ =head1 NAME mkprereqinst - create a prereqinst file for perl module distributions =head1 DESCRIPTION C creates a C file. The created file can be included to perl module and script distributions to help people to get and install module prerequisites through C or C. The standard installation process of perl distributions with a prereqinst file will look as following: perl Makefile.PL (if there are some modules missing then execute the next line) perl prereqinst make all test install For a Build.PL-based distribution, use the following perl Build (if there are some modules missing then execute the next line) perl prereqinst perl Build test perl Build install If the user needs superuser privileges to install something on his system, then C and C should be run as superuser, e.g. with help of the C or C command. ActivePerl users may use perl prereqinst.pl -ppm to fetch the modules through C instead of C. For an alternative approach see the CPAN module L. Some differences are: | mkpreqinst | ExtUtils::AutoInstall ---------------------------+------------+---------------------- Support for CPAN | yes | yes Support for CPANPLUS | no | yes Support for PPM | yes | no Needs Makefile.PL changes | no | yes Support for Build.PL | yes | ??? Different build process | yes | no Has a lot of fancy options | no | yes =head2 OPTIONS C accepts the following options: =over =item C<-v> Be verbose. =item C<-exec> Instead of creating the C, execute the generated code. =item C<-cpan>, C<-ppm> These options are only useful in conjunction with the C<-exec> option and force the type of auto-installation. =item C<-o> outfile Use another output file than the default C. =back It is also possible to supply a list of modules and version numbers on the command line. In this case the Makefile.PL and Build.PL are ignored. Example: mkprereqinst XML::Parser 2.30 Tk GD =head1 BUGS and TODO The script does nasty things with C and the C subroutine. It is annoying to create the prereqinst.pl file if the Makefile.PL is interactive. OS-related or other conditions in C are not handled. There are problems with the mapping of perl module names to PPM package names. prereqinst.pl should autodetected whether the system is a CPAN or a PPM system. With -cpan or -ppm it would be possible to change the default. =head1 README mkprereqinst creates a prereqinst file. The created file can be included to perl module and script distributions to help people to get and install module dependecies through CPAN.pm or PPM.pm =head1 PREREQUISITES only standard perl modules =head1 COREQUISITES YAML =head1 OSNAMES any =head1 SCRIPT CATEGORIES CPAN =head1 AUTHOR Slaven Rezic =head1 SEE ALSO L, L, L, L. =cut