views:

359

answers:

6

Is there anything equivalent or close in terms of functionality to Python's virtualenv, but for Perl?

I've done some development in Python and a possibility of having non-system versions of modules installed in a separate environment without creating any mess is a huge advantage. Now I have to work on a new project in Perl, and I'm looking for something like virtualenv, but for Perl. Can you suggest any Perl equivalent or replacement for python's virtualenv?

I'm trying to setup X different sets of non-system Perl packages for Y different applications to be deployed. Even worse, these applications may require different versions of the same package, so each of them may require to be installed in a separate module/library environment. You may want to do this manually for X < Y < 3. But you should not do this manually for 10 > Y > X.

Ideally what I'm looking should work like this:

perl virtualenv.pl my_environment
. my_environment/bin/activate
wget http://.../foo-0.1.tar.gz
tar -xzf foo-0.1.tar.gz ; cd foo-0.1
perl Makefile.pl
make install # <-- package foo-0.1 gets installed inside my_environment
perl -MCPAN -e 'install Bar' # <-- now package Bar with all its deps gets installed inside my_environment
+1  A: 

Programs can modify what directories they check for libraries uwith use lib. This lib directory can be relative to the current directory. Libraries from these directories will be used before system libraries, as they are placed at the beginning of the @INC array.

I believe cpan can also install libraries to specific directories. Granted, cpan draws from the CPAN site in order to install things, so this may not be the best option.

R. Bemrose
`@LIB` doesn't do anything. ITYM `@INC`
hillu
I know about these options. Yes, I know, I can write some simple scripts to initialize environment and directory structure, I can even convince CPAN to use that directory structure, and I can do many other interesting things. But I need to do this manually. One of the key features of virtualenv is that 'without creating any mess' part. It hides all these low-level setup steps away and greatly simplifies using such environments. I'm looking for something similar for Perl. I simply can't believe it does not exist.
abbot
@hillu: er... whoops, braino on my part.
R. Bemrose
+1  A: 

I am not sure whether this is the same as that virtualenv thing you are talking about, but have a look for the @INC special variable in the perlvar manpage.

hillu
+14  A: 

There's a tool called local::lib that wraps up all of the work for you, much like virtualenv. It will:

  • Set up @INC in the process where it's used.
  • Set PERL5LIB and other such things for child processes.
  • Set the right variables to convince CPAN, MakeMaker, Module::Build, etc. to install libraries and store configuration in a local directory.
  • Set PATH so that installed binaries can be found.
  • Print environment variables to stdout when used from the commandline so that you can put eval $(perl -Mlocal::lib) in your .profile and then mostly forget about it.
hobbs
A: 

What I do is start the CPAN shell (cpan) and install my own Perl 5.10 from it (I believe the command is install perl-5.10). This will ask for various configuration settings; I make sure to make it point to paths under /usr/local (or some other installation location other than the default).

Then I put its resulting location in my executable $PATH before the standard perl, and use its CPAN shell to install the modules I need (usually, a lot). My Perl scripts all start with the line

#!/usr/bin/env perl

Never had a problem with this approach.

reinierpost
Installing your own Perl is not in option if you need 5-10 different environments.
abbot
You mean it isn't fully automated? Yes, that's a drawback. I'm sure it would be easy to automate (just a matter of figuring out how to provide config choices to the Perl installation), but I never did that.
reinierpost
BTW I always install software in a version-specific subdirectory, then use something like stow to symlink one version into a location that's in my path. That way I can still use specific versions when needed.
reinierpost
I mean that it does not work fine when you want to stay with system perl, while using customized non-system set of modules. You will need this when you are deploying an application.
abbot
True: not staying with the system's perl doesn't work if you want to stay with the system's perl. There may be legitimate reasons why you'd want to do that; my point is that I haven't met any in practice, and I use Perl quite a lot.
reinierpost
A: 

I've used schroot for this purpose. It is a bit heavier than virtualenv but you can be sure that nothing will leak in that shouldn't.

Schroot manages a chroot environment for you, but mounts your home directory in the chroot so it appears like a normal shell session, just using the binaries and libraries in the chroot.

I think it may be debian/ubuntu only though.

After setting up the schroot, your script above would look like

schroot -c my_perl_dev
wget ...

See http://www.debian-administration.org/articles/566 for an interesting article about it

Nick Craig-Wood
A: 

It looks like you just need to use the INSTALL_BASE configuration for Makefile.PL (or the --install_base option for Build.PL)? What exactly do you need the solution to do for you? It sounds like you just need to get the installed module in the right place. You've presented your problem as an XY Problem by specifying what you think is the solution is rather than letting us help you with your task.

See How do I keep my own module/library directory? in perlfaq8, for instance.

If you are downloading modules from CPAN, the latest cpan command (in App::Cpan) has a -j switch to allow you to choose alternate CPAN.pm configuration files. In those configuration files you can set the CPAN.pm options to install wherever you like.

Based on your clarification, it sounds like local::lib might work for you in single, simple cases, but I do this for industrial strength deployments where I set up custom, private CPANs per application, and install directly from those custom CPANs. See my MyCPAN::App::DPAN module, for instance. From that, I use custom CPAN.pm configs that analyze their environment and set the proper values to each application can install everything in a directory just for that application.

You might also consider distributing your application as a Task::. You install it like any other Perl module, but dependencies share that same setup (i.e. INSTALL_BASE).

brian d foy
I know about all this stuff, but it is quite low-level. I wanted a tool which can quickly make all these low-level setup/configuration steps for me with just a simple command. I know that I've presented this as an XY Problem, but if you check the accepted answer then you will find that it works almost exactly as I've described. You should try that solution yourself if you haven't done yet.
abbot
I don't see how it works for you if you want to install more than 10 different setups on the same machine, as you say in the comment to your own question.
brian d foy