package App::Virtualenv; =head1 NAME App::Virtualenv - Perl virtual environment =head1 VERSION version 1.11 =head1 SYNOPSIS Perl virtual environment =head1 DESCRIPTION App::Virtualenv is a Perl package to create isolated Perl virtual environments, like Python virtual environment. =head1 USAGE =head2 virtualenv.pl creates new Perl virtual environment =over B<virtualenv.pl> [I<environment_path>] =back =head2 activate activates Perl virtual environment =over source I<environment_path>/bin/B<activate> =back =head2 deactivate deactivates activated Perl virtual environment =over B<deactivate> =back =head2 sh.pl runs Unix shell under Perl virtual environment =over [I<environment_path>/bin/]B<sh.pl> [I<argument>]... =back =head2 perl.pl runs Perl language interpreter under Perl virtual environment =over [I<environment_path>/bin/]B<perl.pl> [I<argument>]... =back =head2 piv.pl Perl in Virtual environment =over [I<environment_path>/bin/]B<piv.pl> [-I<argument>]... [--I<argument> I<value>]... I<command> [I<parameter>]... =back =head3 Commands =head4 piv virtualenv creates new Perl virtual environment =over B<piv virtualenv> [-e] [I<environment_path>] =over B<-e> Empty virtual environment =back =back =head4 piv sh runs Unix shell under Perl virtual environment =over [I<environment_path>/bin/]B<piv sh> [I<argument>]... =back =head4 piv perl runs Perl language interpreter under Perl virtual environment =over [I<environment_path>/bin/]B<piv perl> [I<argument>]... =back =head4 piv list lists installed packages under Perl virtual environment =over [I<environment_path>/bin/]B<piv list> [-1] =over B<-1> One column list =back =back =head4 piv install installs or upgrades packages under Perl virtual environment =over [I<environment_path>/bin/]B<piv install> [-f] [-t] [-s] [-v] I<package>... =over B<-f> Force B<-t> Run tests B<-s> Soft install without installing prerequisites B<-v> Verbose =back =back =head4 piv remove removes packages under Perl virtual environment =over [I<environment_path>/bin/]B<piv remove> [-f] [-v] I<package>... =over B<-f> Force B<-v> Verbose =back =back =head1 INSTALLATION To install this module type the following perl Makefile.PL make make test make install from CPAN cpan -i App::Virtualenv =head1 DEPENDENCIES This module requires these other modules and libraries: =over =item * local::lib =item * Switch =item * FindBin =item * Cwd =item * File::Basename =item * ExtUtils::Installed =item * CPAN =item * CPANPLUS =back =cut use strict; use warnings; no warnings qw(qw utf8); use v5.14; use utf8; use Config; use FindBin; use Cwd; use File::Basename; use App::Virtualenv::Utils; BEGIN { require Exporter; # set the version for version checking our $VERSION = '1.11'; # Inherit from Exporter to export functions and variables our @ISA = qw(Exporter); # Functions and variables which are exported by default our @EXPORT = qw(); # Functions and variables which can be optionally exported our @EXPORT_OK = qw(); } sub activate { my ($virtualenvPath) = @_; $virtualenvPath = getVirtualenvPath() if not defined $virtualenvPath; $virtualenvPath = binVirtualenvPath() if not defined $virtualenvPath; $virtualenvPath = Cwd::realpath($virtualenvPath); return if not validVirtualenvPath($virtualenvPath); deactivate(1); $ENV{_OLD_PERL_VIRTUAL_ENV} = $ENV{PERL_VIRTUAL_ENV}; $ENV{PERL_VIRTUAL_ENV} = $virtualenvPath; $ENV{_OLD_PERL_VIRTUAL_PATH} = $ENV{PATH}; $ENV{PATH} = "$virtualenvPath/bin".((defined $ENV{PATH})? ":${ENV{PATH}}": ""); $ENV{_OLD_PERL_VIRTUAL_PERL5LIB} = $ENV{PERL5LIB}; $ENV{PERL5LIB} = "$virtualenvPath/lib/perl5".((defined $ENV{PERL5LIB})? ":${ENV{PERL5LIB}}": ""); $ENV{_OLD_PERL_VIRTUAL_PERL_LOCAL_LIB_ROOT} = $ENV{PERL_LOCAL_LIB_ROOT}; $ENV{PERL_LOCAL_LIB_ROOT} = "$virtualenvPath"; $ENV{_OLD_PERL_VIRTUAL_PERL_MB_OPT} = $ENV{PERL_MB_OPT}; $ENV{PERL_MB_OPT} = "--install_base \"$virtualenvPath\""; $ENV{_OLD_PERL_VIRTUAL_PERL_MM_OPT} = $ENV{PERL_MM_OPT}; $ENV{PERL_MM_OPT} = "INSTALL_BASE=$virtualenvPath"; $ENV{_OLD_PERL_VIRTUAL_PS1} = $ENV{PS1}; $ENV{PS1} = "(".basename($virtualenvPath).") ".((defined $ENV{PS1})? $ENV{PS1}: ""); return $virtualenvPath; } sub activate2 { my $oldVirtualenvPath = getVirtualenvPath(); my $virtualenvPath = activate(); if (defined $virtualenvPath) { say STDERR "Perl virtual environment path: $virtualenvPath" if not defined $oldVirtualenvPath or $oldVirtualenvPath ne $virtualenvPath; } else { say STDERR "Perl virtual environment is not activated"; } return $virtualenvPath; } sub deactivate { my ($nondestructive) = @_; $nondestructive = not defined($ENV{PERL_VIRTUAL_ENV}) if not defined($nondestructive); $ENV{PERL_VIRTUAL_ENV} = $ENV{_OLD_PERL_VIRTUAL_ENV} if defined($ENV{_OLD_PERL_VIRTUAL_ENV}) or not $nondestructive; undef $ENV{_OLD_PERL_VIRTUAL_ENV}; $ENV{PATH} = $ENV{_OLD_PERL_VIRTUAL_PATH} if defined($ENV{_OLD_PERL_VIRTUAL_PATH}) or not $nondestructive; undef $ENV{_OLD_PERL_VIRTUAL_PATH}; $ENV{PERL5LIB} = $ENV{_OLD_PERL_VIRTUAL_PERL5LIB} if defined($ENV{_OLD_PERL_VIRTUAL_PERL5LIB}) or not $nondestructive; undef $ENV{_OLD_PERL_VIRTUAL_PERL5LIB}; $ENV{PERL_LOCAL_LIB_ROOT} = $ENV{_OLD_PERL_VIRTUAL_PERL_LOCAL_LIB_ROOT} if defined($ENV{_OLD_PERL_VIRTUAL_PERL_LOCAL_LIB_ROOT}) or not $nondestructive; undef $ENV{_OLD_PERL_VIRTUAL_PERL_LOCAL_LIB_ROOT}; $ENV{PERL_MB_OPT} = $ENV{_OLD_PERL_VIRTUAL_PERL_MB_OPT} if defined($ENV{_OLD_PERL_VIRTUAL_PERL_MB_OPT}) or not $nondestructive; undef $ENV{_OLD_PERL_VIRTUAL_PERL_MB_OPT}; $ENV{PERL_MM_OPT} = $ENV{_OLD_PERL_VIRTUAL_PERL_MM_OPT} if defined($ENV{_OLD_PERL_VIRTUAL_PERL_MM_OPT}) or not $nondestructive; undef $ENV{_OLD_PERL_VIRTUAL_PERL_MM_OPT}; $ENV{PS1} = $ENV{_OLD_PERL_VIRTUAL_PS1} if defined($ENV{_OLD_PERL_VIRTUAL_PS1}) or not $nondestructive; undef $ENV{_OLD_PERL_VIRTUAL_PS1}; return; } sub getVirtualenvPath { return (defined $ENV{PERL_VIRTUAL_ENV})? Cwd::realpath($ENV{PERL_VIRTUAL_ENV}): undef; } sub binVirtualenvPath { return Cwd::realpath("${FindBin::Bin}/.."); } sub validVirtualenvPath { my ($virtualenvPath) = @_; return 0 if not defined $virtualenvPath; $virtualenvPath = Cwd::realpath($virtualenvPath); return -d "$virtualenvPath/lib/perl5"; } sub create { my ($virtualenvPath, $empty) = @_; $virtualenvPath = Cwd::realpath((defined $virtualenvPath)? $virtualenvPath: "."); say "Creating Perl virtual environment: $virtualenvPath"; deactivate(); require local::lib; local::lib->import($virtualenvPath); activate($virtualenvPath); perl("-MApp::Virtualenv::Module", "-e exit not App::Virtualenv::Module::install(force => 1, test => 0, modules => ['LWP', 'CPAN', 'CPANPLUS']);") unless $empty; my $pkgPath = dirname(__FILE__); _system("cp -v $pkgPath/Virtualenv/activate $virtualenvPath/bin/activate && chmod 644 $virtualenvPath/bin/activate"); _system("cp -v $pkgPath/Virtualenv/sh.pl $virtualenvPath/bin/sh.pl && chmod 755 $virtualenvPath/bin/sh.pl"); _system("cp -v $pkgPath/Virtualenv/perl.pl $virtualenvPath/bin/perl.pl && chmod 755 $virtualenvPath/bin/perl.pl"); _system("ln -v -s -f perl.pl $virtualenvPath/bin/perl"); _system("cp -v $pkgPath/Virtualenv/piv.pl $virtualenvPath/bin/piv.pl && chmod 755 $virtualenvPath/bin/piv.pl"); _system("ln -v -s -f piv.pl $virtualenvPath/bin/piv"); return 1; } sub sh { my (@args) = @_; return _system((defined $ENV{SHELL})? $ENV{SHELL}: "/bin/sh", @args); } sub perl { my (@args) = @_; return _system($Config{perlpath}, @args); } 1; __END__ =head1 AUTHOR Orkun Karaduman <orkunkaraduman@gmail.com> =head1 COPYRIGHT AND LICENSE Copyright (C) 2016 Orkun Karaduman <orkunkaraduman@gmail.com> This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see <http://www.gnu.org/licenses/>. =cut