FiniWiki, Powered by Foswiki Free and Open Source Wiki
RichmondPM > BundleYourPerlCode
FiniWiki webs: Main | System | Sandbox   Login or Register
Users | Groups | Offices | Changes | Index | Search | Go

Bundle your Perl Code

Why?

If we look at Egypt, it is been marveled as the home of the architecture for man. It is home to great Pryamids of Egypt (one of the seven wonders of the world) and hundreds of buildings which have lasted thousands of years. The buildings are not only reknown for their long existence but also the percision used to building them (A number of articles covering Egyptian construction can be found here).

The Romans had built one of the largest empires of ancient times. The Roman legion was used to constantly expand their empire. To increase the power of their legions they built roads that spanned Europe, Africa and the Middle East. At its peak they had constructed 53,000 miles of road! ( from Wikipedia). A major marvel of this road system, is the milestone. A milestone was not a guess of what a mile should be, but an exact measurement. The device they used to determine how far a mile was? The odometer( You don't think that was invented just for cars did you?).

Both of these are models for projects grande in scope and their longetivity. Another thing that they had in common? The techniques used to build them were lost for long periods of time. Despite being 4,000 years old, we are still unsure how the pyramids were actually constructed, though there are numerous theories on many construction methods. The Roman odometer also remained a mystery, it was finally reinvented in the late 1600's nearly 1,500 years after the fall of the Roman empire.

What does this have to do with programming?

The most amazing projects will fall to the wayside without tests and documentation. Even if a program does what it is designed to do; if people cannot understand how it works, they will never be able to build upon it. Instead, the knowledge will be thrown away and then reinvented later, by someone who has to accomplish the same task again.

CPAN-style Distributions

CPAN (Comprehensive Perl Archive Network) is a collection of Perl software and documentation that is available to the public. CPAN is also a program used to download and install software from a CPAN repository (a place where the Perl software is stored). The CPAN program is able to install this software from a simple concept;

"all Perl software on CPAN follows a standard set of rules for bundling and installing software and documentation"

Having a standard provides a framework of,

  • What files should be included in a distribution
  • What information should be in those files
  • Where those files should be located
  • How those files should be bundled

These standards provide a map of how to make a bundle so that it is easy to distribute your code.

Building a framework with module-starter

First, we use a utility to creat a distribution framework. The utility that I will use is module-starter. To install;

  • On * NIX systems "cpan install Module::Starter"
  • On Windows systems (ActivePerl installed) "ppm install Module-Starter"

After it is installed you can run the "module-starter" utility from the command line. From the command line run type this command in to create our sample distribution.

module-starter --module=Sample::Distro --builder=Module::Build --author="Your Name Here" --email="Your@email.com" --verbose

You should see the following,
Created Sample-Distro
 Created Sample-Distro\l ib\Sample
 Created Sample-Distro\l ib\Sample\Distr o.pm
 Created Sample-Distro\t
 Created Sample-Distro\t\pod-coverage.t
 Created Sample-Distro\t\pod.t
 Created Sample-Distro\t\boilerplate.t
 Created Sample-Distro\t\00-load.t
 Created Sample-Distro\.cvsignore
 Created Sample-Distro\B uild.PL
 Created Sample-Distro\M ANIFEST
 Created starter directories and files

These are the items created by module-starter,

  • A directory based upon the module name ( Sample-Distro). All other files are created under this directory.
  • lib directory and then subdirectories based upon the module name where our module should be installed.
  • t directory and some basic tests that be built upon to test our distribution
  • .cvsignore file (a regular expression list of files that cvs could ignore when backing files up.
  • Build.PL file (a perl script that will install our code onto target system).
  • Manifest file (a list of all the files that are to be included in our distribution, including tests).
  • Changes file (a on going record of the problems that were addressed in each version release).
  • README file (includes any special notes that are needed for your distribution).

Now that we have a framework of a distribution to work with, lets walk through the steps to create a basic distribution, starting with our Perl module Sample::Distro.

Sample::Distro

This will be our code for the Sample::Distro module, cut and paste this code into the Sample-Distro\lib\Sample\Distro.pm file,

package Sample::Distro;

use strict;
use warnings;

our $VERSION = '0.01';  # Used for keeping track of the distribution  version

sub new {
  my $self = shift;

  return bless {};
}

sub add {
  my $self = shift;
  my $first_no = shift;
  my $second_no = shift;

  return ($first_no + $second_no);
}
1;
__END__
=head1 NAME

Sample::Distro

=head1 VERSION

This documentation refers to version 0.01

=head1 SYNOPSIS

c<< my $sample = Sample::Distro->new();
       printing "Adding 2 + 3 = " . $sample->add( 2, 3) . "\n"; >>

=head1 DESCRIPTION

This module is used as a sample to create a simple distribution.

=head1 SUBROUTINES/METHODS

=head2 c<new()>

Creates our object.

=head2 c<add( $first_no, $second_no )>

Takes two numbers and adds then together.

=head1 DEPENDENCIES

None

=head1 DIAGNOSTICS

None

=head1 CONFIGURATION AND ENVIRONMENT

None

=head1 BUGS AND LIMITATIONS

None

=head1 AUTHOR

Your Name Here    (Your@email.com)

=head1 COPYRIGHT

Perl standard distribution license.

The Sample-Distro\Build.PL file will need one line added as well, change the Build.PL file to this,

use strict;
use warnings;
use Module::Build;

my $builder = Module::Build->new(
    module_name         => 'Sample::Distro',
    license             => 'perl',
    dist_author         => 'Your Name Here <Your@email.com>',
    dist_abstract       => 'This is just a Sample Distro', # Add just this line
    dist_version_from   => 'lib/Sample/Distro.pm',
    build_requires => {
        'Test::More' => 0,
    },
    add_to_cleanup      => [ 'Sample-Distro-*' ],
);

$builder->create_build_script();

At this point we have enough to create our distribution. From the command line change the Sample-Distro directory. Then type perl Build.PL you will see,

Checking whether your kit is complete...
WARNING: the following files are missing in your kit:
        META.yml
 Please inform the author.

Checking prerequisites...
Looks good

Creating new 'Build' script for 'Sample-Distro' version '0.01'

Note: You can ignore the warning for the META.yml, that file will be created when we create the distribution file.

Next type in perl Build and then perl Build test, this will run all the tests that are in the t directory.

lib\Sample\Distro.pm -> blib\lib\Sample\Distro.pm
 t\00-load.........ok 1/1# Testing Sample::Distro 0.01, Perl 5.008008, C:\Perl\bi
 n\perl.exe
 t\00-load.........ok
 t\boilerplate.....
t\boilerplate.....NOK 1#   Failed test 'README contains boilerplate text'
#   in t\boilerplate.t at line 23.
# The README is used... appears on lines 3
# 'version information here' appears on lines 11

t\boilerplate.....NOK 2#   Failed test 'Changes contains boilerplate text'
#   in t\boilerplate.t at line 23.
# placeholder date/time appears on lines 3
 t\boilerplate.....ok 3/3# Looks like you failed 2 tests of 3.
t\boilerplate.....dubious
        Test returned status 2 (wstat 512, 0x200)
DIED. FAILED tests 1-2
        Failed 2/3 tests, 33.33% okay
 t\pod-coverage....ok
 t\pod.............ok
 Failed Test     Stat Wstat Total Fail  Failed  List of Failed
-------------------------------------------------------------------------------
t\boilerplate.t    2   512     3    2  66.67%  1-2
 Failed 1/4 test scripts, 75.00% okay. 2/6 subtests failed, 66.67% okay.

The only tests to fail are the boilerplate.t tests. The messages that are being displayed all relate to the basic file text that was automatically generated. It is saying, "Update the Changes file, and the Readme".

We are not worried about getting beyond the boilerplate samples; for this project we are going to delete this test. From the t directory delete the boilerplate.t file. Go into the MANIFEST file, and delete the line that has t\boilerplate.t. Save the MANIFEST file and type in perl Build test.

t\00-load.........ok 1/1# Testing Sample::Distro 0.01, Perl 5.008008, C:\Perl\bi
 n\perl.exe
 t\00-load.........ok
 t\pod-coverage....ok
 t\pod.............ok
 All tests successful.
Files=3, Tests=3,  1 wallclock secs ( 0.00 cusr +  0.00 csys =  0.00 CPU)

This time all of our tests pass. The last step for creating a distribution, type in perl Build dist. You will see,

Deleting META.yml
 Creating META.yml
 Creating Sample-Distro-0.01
 Creating Sample-Distro-0.01.tar.gz
 Deleting Sample-Distro-0.01

When you look in the Sample-Distro directory you will see a new file, Sample-Distro-0.01.tar.gz. This file is all the files listed in the MANIFEST file, in a compressed tarball ready for distribution. To expand the tarball type, tar xvzf Sample-Distro-0.01.tar.gz (Note: this only good for *NIX based systems, Windows does not come with gzip or tar by default, though most ZIP utilities can decompress this file for you).

What is the next step?

What we are going to do now is add items to our distribution and show the steps that we need to take to put newer versions of the distribution. The first step we will do is to add another test for the module. Copy this text into a file, and save as Sample-Distro\t\01-add.t

use Test::More tests => 2;

my $sample = Sample::Distro->new();
isa_ok( $sample, 'Sample::Distro');
cmp_ok( $sample->add(2, 3), '==', 5, '2 plus 3 equals 5');
In the MANIFEST file add this line,
 t\01-add.t
In the Changes file add this text,
0.02    May 05, 2006 12:00:00
        - Added t\add.t to the tests to be run.
In Sample/Distro.pm module change your version to,
our $VERSION = '0.02';

Now you are ready to build a new distribution, type perl Build.PL
perl Build
perl Build test
perl Build dist

You should now see this,

Deleting META.yml
 Creating META.yml
 Creating Sample-Distro-0.02
 Creating Sample-Distro-0.02.tar.gz
 Deleting Sample-Distro-0.02

You have now created the next version of Sample::Distro. Everytime you are ready to distribute a new version of your software, repeat these steps.

  • Add tests to check changes in your code
  • Edit the MANIFEST file to include any news that are part of the distribution
  • Update the Changes file to add notes on what you added or fixed
  • Update the README file if there is something special that the user may need to know to install or use your distribution
  • Update the VERSION number in your module
  • Update the POD to reflect changes in your code

What have we Accomplished?

By bundling all of this software together we have,

  • A layout for where to expect to the module to be installed be (%PERLLIB%/Sample/Distro.pm).
  • A place for documentation for the module (A POD section of our module Distro.pm).
  • Any special notes that are needed for the module (README).
  • A location for tests for the module (t directory).
  • A place to keep track of updates and fixes and what version they are with (Changes file).
  • A way of keeping track of different versions of the module (In the Distro.pm and the compressed tarball).

-- Main.SteveKirkup - 18 May 2006

Parents: WebHome
This site is powered by FoswikiCopyright © by the contributing authors. All material on this collaboration platform is the property of the contributing authors.
Ideas, requests, problems regarding FiniWiki? Send feedback