Codependent testing with -Mylib

While working on Metabase recently,  I got annoyed running tests when the code under development depended on other distributions that I was editing simultaneously.  Unless all of them were in sync, the tests would fail.

For example, Metabase::Web depends on Metabase and Metabase::Fact and Metabase::Client::Simple.  They all live in separate git repositories like this:

~/git/metabase
~/git/metabase-fact
~/git/metabase-web
~/git/metabase-client-simple

When I changed how Metabase::Fact worked, I wanted tests for any of the other Metabase::* modules to see that change without a lot of extra work on my part.

There were  a couple obvious options, none of which I particularly liked.  One would have been just to regularly install the code under development (e.g. Metabase::Fact) so that it would be available when testing other modules.

Another option would have been to make all the */lib directories available via PERL5LIB.  But that requires either adding PERL5LIB to my .bashrc and having a global impact whenever I run Perl or else doing it manually within particular terminal sessions and potentially forgetting if I fire up a new terminal window.

Instead, I let my impatience, laziness and hubris spill forth and wrote the ylib module.  It looks for a .mylib file with a list of directories to include in @INC.  That way, each distribution directory contains a custom list of dependencies that are only applied when running Perl from that particular directory.

The only change required is adding '-Mylib' as an argument to Perl.  For  example, in the 'metabase-web' directory:

$ cat .mylib
../metabase/lib
../metabase-fact/lib
../metabase-client-simple/lib
../cpan-testers-report/lib

$ perl -Mylib -E 'say for @INC'
../cpan-testers-report/lib
../metabase-client-simple/lib
../metabase-fact/lib
../metabase/lib
/opt/perl/5.10.0/lib/5.10.0/x86_64-linux-ld
/opt/perl/5.10.0/lib/5.10.0
/opt/perl/5.10.0/lib/site_perl/5.10.0/x86_64-linux-ld
/opt/perl/5.10.0/lib/site_perl/5.10.0
.

That works well enough, but what about getting that to work with 'Build test' or 'make test' when the Perl I want to affect is a subprocess?

Fortunately, Build.PL will just DWIM since the Build program will remember anything added to @INC in Build.PL:

$ perl -Mylib Build.PL
$ Build test

With Makefile.PL, it's not so easy.  I found that for my testing, what worked was this:

$ perl Makefile.PL PERL="`which perl` -Mylib"

That's clunky, but I only have to re-run it when I need to rebuild the Makefile, which happens rarely. (Or I can just shorten it with an alias)

With 'prove', it's similarly clunky (and won't work if tainting is involved):

$ PERL5OPT="-Mylib" prove t/submit.t

Still, ylib has been a simple, little hack to make developing with co-dependencies less painful.  I hope others find it as useful as I do.

This entry was posted in cpan, perl programming and tagged . Bookmark the permalink. Both comments and trackbacks are currently closed.

One Comment

  1. Posted May 5, 2009 at 4:38 am | Permalink

    I've already fought this fight with local::lib - the answer is to just say sod it and generate a PERL5LIB env var. So if you were to make ylib.pm do something similar, you'd maybe have a usage of:


    eval $(perl -Mylib=export_perl5lib)
    make test

    or whatever. If it's in PERL5LIB it gets unrolled into -I switches by Test::Harness automatically which means apart from the very occasional buggy test that uses taint, re-executes $^X itself, -and- forgets to unroll PERL5LIB into -I switches. And we people using local::lib have been slowly shaking those out and getting them fixed anyway :)

© 2009-2014 David Golden All Rights Reserved