snafu has asked for the wisdom of the Perl Monks concerning the following question:

I have a script that I want to migrate over to another box for testing from my development box. Eventually, this script will be used by people everywhere and I would prefer to make it very user friendly when they want to install it. This script, like most other scripts, uses CPAN modules. It just happens that the test box I want to move my script over to does not have all of the modules I need. This is what got me to thinking. Would it be or is it possible to create a bundle somehow from some perl command or some other module that actually looks in my script at the modules I am using and bundles those modules with my script into a tarball. This way my script can be distributed to anybody with all of the stuff required to make it work right there.

Is there something like this out there already? If so, what is it and how can I use it? tilly suggested I can make a bundle but just have no idea how to do that quickly and benignly.

----------
- Jim

  • Comment on How can I create a Bundle quickly and easily?

Replies are listed 'Best First'.
Re: How can I create a Bundle quickly and easily?
by bikeNomad (Priest) on Jul 26, 2001 at 08:51 UTC
    I don't know about making a Bundle, but you can put prerequisites in the PREREQ_PM section of Makefile.PL and CPAN will load them as needed:

    WriteMakefile( NAME => 'MyBundle', PREREQ_PM => { 'Compress::Zlib' => 1.06, 'SomeModule' => 0, 'SomeOtherModule' => 1.00, 'File::Find' => 0, 'File::Basename' => 0, }, );
Re: How can I create a Bundle quickly and easily?
by jepri (Parson) on Jul 26, 2001 at 08:34 UTC
    The autobundle command should create a module that 'requires' every module currently on your system. You can then copy this module to your new machine and try to install it, which will cause CPAN to download all the modules again.

    I don't know if you can request just some of the modules, but you could either edit the bundle, or set CPAN to 'ask' instead of 'follow' module dependencies and then personally approve every one.

    Update: Ooops, answered the wrong question. See the answers below.

    ____________________
    Jeremy
    I didn't believe in evil until I dated it.

Re: How can I create a Bundle quickly and easily?
by clemburg (Curate) on Jul 26, 2001 at 13:45 UTC

    In general, this will be hard, since you would have to parse Perl to recognize all the statements where additional code is included (do, require, use, even open file and string eval are possible). ActiveState's PerlApp application has the same problem, and they need an "add this module" switch for you to add modules manually in the more pathological cases (dynamic require, e.g., in Tk).

    It is hard to tell if you could do a quick-and-dirty hack for just your purposes. Depends both on your coding conventions, and on the install procedure you prefer (from CPAN automatically via CPAN shell, or from downloaded tarballs by a procedure that you wrote yourself (warning: there can be dependencies between modules, and you will have to handle them yourself)).

    I would probably create a checklist of modules from the code relying on conventions (just use "use", etc.), build a CPAN bundle by first using autobundle and then tuning that by hand, create a checklist from that bundle, too, and diff both checklists. If there is something new, I will know and can handle it manually (just add to the bundle).

    Christian Lemburg
    Brainbench MVP for Perl
    http://www.brainbench.com

      I am not familiar with autobundle. Where can I read about that? Are there any words of wisdom you can give me on it?

      ----------
      - Jim

        From perldoc CPAN (read it):

        autobundle `autobundle' writes a bundle file into the `$CPAN::Config- >{cpan_home}/Bundle' directory. The file contains a list of all modules that are both available from CPAN and currently installed within @INC. The name of the bundle file is based on the current date and a counter.

        You can invoke it by saying:

        >perl -MCPAN -e autobundle

        It then starts to print out all the modules on your system, and put them into a bundle file:

        CPAN: LWP::UserAgent loaded ok [... bla bla bla ...] Package namespace installed latest in CPAN file AnyDBM_File undef undef G/GS/GSAR/perl-5.6.1.ta +r.gz [... many such lines ...] uri 1.04 undef L/LD/LDACHARY/URIC-2.02 +.tar.gz vars undef undef G/GS/GSAR/perl-5.6.1.ta +r.gz Wrote bundle file D:\home\.cpan\Bundle\Snapshot_2001_07_30_00.pm

        Now you have a bundle file that you can edit to your needs. Note that the order of appearance of modules matters, so you might need to tune your bundle file to your needs. That's how the bundle file autobundle created looks like:

        package Bundle::Snapshot_2001_07_30_00; $VERSION = '0.01'; 1; __END__ =head1 NAME Bundle::Snapshot_2001_07_30_00 - Snapshot of installation on on Mon J +ul 30 10:11:15 2001 =head1 SYNOPSIS perl -MCPAN -e 'install Bundle::Snapshot_2001_07_30_00' =head1 CONTENTS AnyDBM_File undef AppConfig 1.52 [... many such lines ...] [... NOTE: these are the lines you want to edit ...] subs undef uri 1.04 vars undef =head1 CONFIGURATION [... bla bla bla ...] =head1 AUTHOR This Bundle has been generated automatically by the autobundle routine + in CPAN.pm.

        Christian Lemburg
        Brainbench MVP for Perl
        http://www.brainbench.com

Re: How can I create a Bundle quickly and easily?
by John M. Dlugosz (Monsignor) on Jul 26, 2001 at 08:34 UTC
    ActiveState's bundler does that, but generates something that's extracted into the temp directory and then run there. Presumably the same technology could be used to generate an installer, too.

    Here is a quick idea: unshift a sub onto @INC that logs the filename being searched for and returns the value meaning "not here", so it keeps looking normally. After running the script, everything that was actually used should be noted, even when lazily required.

    —John

Re: How can I create a Bundle quickly and easily?
by bikeNomad (Priest) on Jul 26, 2001 at 19:41 UTC
    It's easy to monitor the behavior of require/use in your script. For instance, this script will run another Perl program and print out whatever files it's loading to STDERR:

    #!/usr/bin/perl -w my $db = <<'EOF'; sub DB::postponed { my $glob = shift; $glob =~ s/.*::_<//; print STDERR "loading $glob\n"; } sub DB::DB { } EOF ($ENV{PERL5DB} = $db) =~ tr/\n/ /; system($^X, '-d', @ARGV);

    Just run it on another program like this:
    perl watchRequire.pl myProgram.pl arg1 arg2 2>required

    update: hmm... seems useful, so I put it into Code.

      Annoying note - reminder that if you use settings that perl can't interpet (eg odbc calls on windows machines to databases which are different / don't exist , expecting certain directories which doesn't exist on target machine, etc) you will have to hand jab those settings onto the production machine.

      ----
      Zak
Re: How can I create a Bundle quickly and easily?
by markjugg (Curate) on Jul 26, 2001 at 22:10 UTC
    Did you try downloading a bundle from CPAN and seeing how it's put together? (IE, just unpacking and looking at the source, rather than installing it through CPAN.pm)

    -mark

Re: How can I create a Bundle quickly and easily?
by runrig (Abbot) on Jul 31, 2001 at 01:23 UTC
    bikeNomad mentioned PREREQ_PM, but nobody else mentioned h2xs, so I will. Read the perdocs on h2xs, create a skelton module with h2xs (probably with the -A and -X options), and edit it accordingly, like the PREREQ_PM in Makefile.PL. Also look at the perldocs at ExtUtils::MakeMaker (the EXE_FILES arrayref argument is probably what you want). Then look at what other people do in their modules. If the WriteMakefile in Makefile.PL fails, you could kick off the CPAN module to install the necessary modules.

    Update: Hmm, WriteMakefile() warns you if modules in PREREQ_PM are not present, but it doesn't set any flag or return failure or anything. There's some commented out code in MakeMaker.pm that seems like there was some attempt to autoinstall via the CPAN module any missing modules, but I wonder why its not implemented. It would have been a nice option. You could still try to roll your own in the Makefile.PL, though.