Re: How to indicate a dependency in my module

2003-11-11 Thread Martyn J. Pearce
On Mon, Nov 10, 2003 at 03:49:54PM -0500, Randy W. Sims wrote:
 It would be nice to see functionality like this incorporated into a 
 Module::Build::Configure package (or similar) along with other configure 
 type routines common in current Makefile.PLs. Routines that find if libs 
 or executables are installed, find appropriate install paths for 
 installing perl programs that don't belong in the perl tree, etc.

If anyone cares, I have an ExtUtils::MakeMaker wrapper (a single module that's
distributed but not installed with any package) that:

-) If a module is missing, tells you what package to find it in (it's not
   always obvious to find, say, Net::FTP in libnet before you're familiar with
   libnet)

-) Handles optional modules, i.e., if it's missing, doesn't die, but does
   issue a message to the user.

-) Can check for executables, too, with versions (by telling it how to look up
   version numbers for that module).

I've attached it for your edification.  Constructive criticisms welcome.

Mx.# (X)Emacs mode: -*- cperl -*-

use 5.005;
use strict;

=head1 NAME

make - tools for making makefiles with.

=head1 SYNOPSIS

  use constant MOD_REQS =
[
 { name= 'Pod::Usage',
   version = '1.12', },

 { name= 'IPC::Run',
   package = 'IPC-Run',
   version = '0.44', },

 { name = 'DBI::Wrap',
   package  = 'DBI-Wrap',
   version  = '1.00',
   optional = 1, },
];

  use constant EXEC_REQS =
[
 { name= 'blastpgp',
   version = '1.50',
   vopt= '--version', },

 { name= 'mkprofile', },

 { name= 'mp3id',
   version = '0.4',
   vopt= '--help',
   vexpect = 255, },
];

  use constant NAME = 'Module-Name';
  use constant VERSION_FROM = catfile (qw( lib Module Name.pm ));
  use constant AUTHOR   = 'Martyn J. Pearce [EMAIL PROTECTED]';
  use constant ABSTRACT = 'This module makes chocolate biscuits';

  use make.pm

=head1 DESCRIPTION

This package provides methods and initialization to build standard perl
modules.

The plan is, you define the requirements, and let the module take care of the
rest.

The requirements you must define are:

=over 4

=item MOD_REQS

An arrayref of hashrefs.  Each hashref represents a required Perl module, and
has the following keys:

=over 4

=item name

BMandatory Name of the module used.  The presence of this module is checked,
and an exception is raised if it does not exist.

=item package

BOptional Name of the package in which the module is to be found.  If not
defined, the package is assumed to be present in core Perl.

Modules that have been in core Perl since 5.005 need not be listed; the core
perl default is for modules such as CPod::Usage which have been added to
the core since 5.005.

=item version

BOptional If supplied, the version of the module is checked against this
number, and an exception raised if the version found is lower than that
requested.

=item optional

BOptional If true, then failure to locate the package (or a suitable
version) is not an error, but will generate a warning message.

=item message

If supplied, then this message will be given to the user in case of failure.

=back

=item EXEC_REQS

=over 4

=item name

Name of the executable used.  The presence of this executable is checked, and
an exception is raised if it does not exist (in the PATH).

=item package

BOptional Name of the package in which the executable is to be found.

=item version

BOptional If supplied, the version of the module is checked against this
number, and an exception raised if the version found is lower than that
requested.

If supplied, the Lvopt key must also be supplied.

=item vopt

BOptional This is used only if the Cversion key is also used.  This is the
option that is passed to the executable to ask for its version number.  It may
be the empty string if no option is used (but must be defined if Cversion is
defined).

=item vexpect

BOptional This is used only if the Cversion key is also used.  This is the
exit code to expect from the program when polling for its version number.
Defaults to 0.  This is the exit code (value of C$? in the shell) to use,
Inot the value of the Cwait call.

=item optional

BOptional If true, then failure to locate the package (or a suitable
version) is not an error, but will generate a warning message.

=item message

If supplied, then this message will be given to the user in case of failure.

=back

=item NAME

The module name.  It must conform to the established standard; in particular,
it must Bnot contain colon characters.  The usual process, when providing a
single-package module (e.g., to provide CMIME::Base64), is to replace the
C:: occurences with hyphens (hence, CMIME-Base64).

=item VERSION_FROM

The module from which to establish the version number.  This module must have
a line of the form C$VERSION = '0.01';.  Declarative prefixes (.e.g, Cour)
are fine; Cour is the usual one, since C$VERSION is 

Re: [Module::Build] Re: How to indicate a dependency in my module

2003-11-11 Thread Michael G Schwern
On Mon, Nov 10, 2003 at 05:42:03PM -0800, Terrence Brannon wrote:
 Thinking more about this, I guess META.yml would need to provide a 
 little more info to a configure module. Would something like the 
 following work?
 
 It's probably too late, but I am not keen on YAML. What is wrong with 
 pure Perl configuration information? 

In a nutshell: eval()ing the Perl structure back in is a major security hole.
Part of the point of META.yml is to avoid having to run any foreign code to
figure out module meta information.

To review (maybe this should be in a FAQ somewhere).

Data::Dumper/Perl code - Insecure (you have to eval it).  Perl specific.
Storable - Not human readable.  Format changes slightly from version to
   version.  Perl specific.
XML  - Overkill.  Ugly.  Requires translation between Perl data
   model (hashes, lists, scalars) and XML's (trees).
   Difficult to read and write by humans.

YAML was chosen because its human readable and writable, its data 
structures closely match those of Perl (ie. scalars, hashes and arrays),
it can be read without being eval'd, executable code cannot be hidden in
it and, as a bonus, its not Perl specific.

YAML's basic formatting is a structure we're already familiar with and tend
to use when writing ad-hoc data structures (ie. key: value).
Indentation as structure we're already more than comfortable with (ie. 
indented source code) so readers of YAML should have no problem. 
The less obvious features of YAML shouldn't be necessary for most META.yml
files.

Because YAML's data model closely matches that of Perl, writers of META.yml 
simply need to construct a mirroring Perl structure and let YAML dump it
out.  Its the closest thing to Data::Dumper evaling available.


-- 
Michael G Schwern[EMAIL PROTECTED]  http://www.pobox.com/~schwern/
I'll tell you what beats voodoo every time, a big ass knife.
-- Overkill Battlebot driver