You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@perl.apache.org by Stas Bekman <st...@stason.org> on 2003/03/27 05:19:09 UTC

rfc: a new helper module for Apache:: CPAN module developers / chosing the right mp generation

I'm starting to abstract the Makefile.PL craft into a separate module which I 
plan to release on CPAN and bundle with both mod_perl versions when it's finished.

What name should I give to it? ModPerl::MMHelper? ModPerl::MMUtil? remember 
that we already have mp2-specific ModPerl::MM in mp2-core.

This first chunk of this helper module provides a unified/consistent method 
for all CPAN Apache:: module authors to let user select which mod_perl version 
to build against and for author to require the wanted version using as little 
code as possible. If this is used by all module authors then it'll be much 
easier to work with CPAN.pm and CPANPLUS.pm when there is an ambiguity of not 
knowing which version to choose.

So in your Makefile.PL you can say:

my $mp_gen = satisfy_mp_generation();

and the code will try to figure out which generation should be used. Once you 
know it, you can branch depending on the returned value.

Of course if your module works only with mp1 you will say in Makefile.PL:

   satisfy_mp_generation(1);

you don't need to check the return value, since if it's not satisfied 
(mod_perl 1 wasn't found) it will die.

Same for mp2, if your module works only with mp2, you say:

   satisfy_mp_generation(2);

The following logic is used:

# If a specific generation was passed as an argument,
#     if satisfied
#         return the same generation
#     else
#         die
# else @ARGV and %ENV will be checked for specific orders
#     if the specification will be found
#         if satisfied
#             return the specified generation
#         else
#             die
#     else if any mp generation is found
#              return it
#           else
#              die

and here is how users can tell Makefile.PL which version to use:

# I want to build against mp1:
perl Makefile.PL MOD_PERL=1
or
env MOD_PERL=1 perl Makefile.PL

# I want to build against mp2:
perl Makefile.PL MOD_PERL=2
or
env MOD_PERL=2 perl Makefile.PL

So, now CPAN.pm user can have two aliases:

alias cpan_mp1="MOD_PERL=1 perl -MCPAN -eshell"
alias cpan_mp2="MOD_PERL=2 perl -MCPAN -eshell"

and it'll do the right thing.

(the next issue I'm going to resolve is Apache::Test)

Here is the code. Just imagine that every CPAN Apache:: module developer has 
to reproduce it by himself...

sub satisfy_mp_generation {
     my $wanted = shift || wanted_mp_gen();

     unless ($wanted == 1 || $wanted == 2) {
         die "don't know anything about mod_perl generation: $wanted\n" .
             "currently supporting only generations 1 and 2";
     }

     my $selected = 0;

     if ($wanted == 1){
         require_mod_perl();
         if ($mod_perl::VERSION >= 1.99) {
             # so we don't pick 2.0 version if 1.0 is wanted
             die "You don't seem to have mod_perl 1.0 installed";
         }
         $selected = 1;
     }
     else if ($wanted == 2) {
         #warn "Looking for mod_perl 2.0";
         require Apache2;
         require_mod_perl();
         if ($mod_perl::VERSION < 1.99) {
             die "You don't seem to have mod_perl 2.0 installed";
         }
         $selected = 2;
     }
     else {
         require_mod_perl();
         $selected = $mod_perl::VERSION >= 1.99 ? 2 : 1:
         warn "Using $mod_perl::VERSION\n";
     }

     return $selected;
}

sub require_mod_perl {
     eval { require mod_perl };
     die "Can't find mod_perl installed\nThe error was: $@" if $@;
}

# the function looks at %ENV and Makefile.PL option to figure out
# whether a specific mod_perl generation was requested.
# It uses the following logic:
# via options:
# perl Makefile.PL MOD_PERL=2
# or via %ENV:
# env MOD_PERL=1 perl Makefile.PL
#
# return value is:
# 1 or 2 if the specification was found (mp 1 and mp 2 respectively)
# 0 otherwise
sub wanted_mp_generation {

     # check if we have a command line specification
     # flag: 0: unknown, 1: mp1, 2: mp2
     my $flag = 0;
     my @pass;
     while (@ARGV) {
         my $key = shift @ARGV;
         if ($key =~ /^MOD_PERL=(\d)$/) {
             $flag = $1;
         }
         else {
             push @pass, $key;
         }
     }
     @ARGV = @pass;

     # check %ENV
     my $env = exists $ENV{MOD_PERL} ? $ENV{MOD_PERL} : 0;

     # check for contradicting requirements
     if ($env && $flag && $flag != $env) {
         die <<EOF;
Can\'t decide which mod_perl version should be used, since you have
supplied contradicting requirements:
     enviroment variable MOD_PERL=$env
     Makefile.PL option  MOD_PERL=$flag
EOF
     }

     my $wanted = 0;
     $wanted = 2 if $env == 2 || $flag == 2;
     $wanted = 1 if $env == 1 || $flag == 1;

     return $wanted;
}

__________________________________________________________________
Stas Bekman            JAm_pH ------> Just Another mod_perl Hacker
http://stason.org/     mod_perl Guide ---> http://perl.apache.org
mailto:stas@stason.org http://use.perl.org http://apacheweek.com
http://modperlbook.org http://apache.org   http://ticketmaster.com


---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscribe@perl.apache.org
For additional commands, e-mail: dev-help@perl.apache.org