| pip documentation | Contained in the pip distribution. |
pip - The Perl Installation Program, for scripted and third-party distribution installation.
pip script.p5i pip script.p5z pip Distribution-1.23.tgz pip Distribution-1.23.tar.gz pip Distribution-1.23-MSWin32-5.8.0.par pip http://server/Distribution-1.23.tar.gz pip http://github.com/gitpan/Distribution/tarball/1.23
The pip ("Perl Installation Program") console application is used to install Perl distributions in a wide variety of formats, both from CPAN and from external third-party locations, while supporting module dependencies that go across the boundary from third-party to CPAN.
Using pip you can install CPAN modules, arbitrary tarballs from both the local file-system or across the internet from arbitrary URIs.
You can use pip to ensure that specific versions of CPAN modules are installed instead of the most current version.
And beyond just single installations, you script script a series of these installations by creating a "P5I" (Perl 5 Installation) file.
A Perl 5 Installation (P5I) file is a small script-like file that describes a set of distributions to install, and integrates the installation of these distributions with the CPAN installer.
The primary use of P5I files are for installing proprietary or non-CPAN software that may still require the installation of a number of CPAN dependencies in order to function.
P5I files are also extensible, with the first line of the file specifying the name of the Perl class that implements the plan.
For the moment, the class described at the top of the P5I file must be installed.
The simple Module::Plan::Lite plan class is bundled with the main distribution, and additional types can be installed if needed.
Also on the development schedule for pip is the creation and installation of distributions via "P5Z" files, which are tarballs containing a P5I file, as well as all the distribution tarballs referenced by the P5I file.
It is also anticipated that pip will gain support for PAR binary packages and potentially also for ActivePerl PPM files.
The primary use of pip is to install from a P5I script, with the canonical use case as follows:
pip directory/myplan.p5i
This command will load the plan file directory/myplan.p5i, create the plan, and then execute it.
If only a directory name is given, pip will look for a default.p5i plan in the directory. Thus, all of the following are equivalent
pip directory pip directory/ pip directory/default.p5i
If no target is provided at all, then the current directory will be used. Thus, the following are equivalent
pip pip . pip default.p5i pip ./default.p5i
Initially, the only plan is available is the Module::Plan::Lite (MPL) plan.
A typical MPL plan will look like the following
# myplan.p5i Module::Plan::Lite Process-0.17.tar.gz YAML-Tiny-0.10.tar.gz
With the functionality available in pip, you can find that sometimes you don't even want to make a file at all, you just want to install a single tarball.
The -i option lets you pass the name of a single file and it will treat
it as an installer for that single file. Further, if the extension of the
tarball is .tar.gz, the -i option is implied.
For example, the following are equivalent.
# Installing with the -i|--install option > pip Process-0.17.tar.gz > pip -i Process-0.17.tar.gz > pip --install Process-0.17.tar.gz # Installing from the file as normal > pip ./default.p5i # myplan.p5i Module::Plan::Lite Process-0.17.tar.gz
The -i option can be used with any single value supported by
Module::Plan::Lite (see above).
This means you can also use pip to install a distribution from any arbitrary URI, including installing direct from a subversion repository.
> pip http://svn.ali.as/cpan/release/Process-0.17.tar.gz
This module is stored in an Open Repository at the following address.
http://svn.ali.as/cpan/trunk/pip
Write access to the repository is made available automatically to any published CPAN author, and to most other volunteers on request.
If you are able to submit your bug report in the form of new (failing) unit tests, or can apply your fix directly instead of submitting a patch, you are strongly encouraged to do so. The author currently maintains over 100 modules and it may take some time to deal with non-Critical bug reports or patches.
This will guarentee that your issue will be addressed in the next release of the module.
If you cannot provide a direct test or fix, or don't have time to do so, then regular bug reports are still accepted and appreciated via the CPAN bug tracker.
http://rt.cpan.org/NoAuth/ReportBug.html?Queue=pip
For other issues, for commercial enhancement and support, or to have your write access enabled for the repository, contact the author at the email address above.
Adam Kennedy <adamk@cpan.org>
Module::Plan::Base, Module::Plan::Lite, Module::Plan
Copyright 2006 - 2010 Adam Kennedy.
This program is free software; you can redistribute it and/or modify it under the same terms as Perl itself.
The full text of the license can be found in the LICENSE file included with this module.
| pip documentation | Contained in the pip distribution. |
package pip; use 5.006; use strict; use File::Spec (); use File::Temp (); use File::Which (); use Getopt::Long (); use URI::file (); use Module::Plan::Base (); use vars qw{$VERSION}; BEGIN { $VERSION = '1.19'; } ##################################################################### # Main Function # Save a copy of @ARGV for error messages my $install = 0; Getopt::Long::GetOptions( install => \$install, ); sub main { unless ( @ARGV ) { error("Did not provide a command"); } # If the first argument is a file, install it if ( $ARGV[0] =~ /^(https?|ftp)\:\/\// ) { # resolving redirects to get the real URI, handy for handling # e.g. github URLs like http://github.com/john/repo-name/tarball/master require LWP::Simple; my $h = LWP::Simple::head($ARGV[0]); error("Probably non existing URI '$ARGV[0]'") unless defined($h); return fetch_any($h->request->uri || $ARGV[0]); } if ( -f $ARGV[0] ) { return install_any($ARGV[0]); } error("Unknown or unsupported command '$ARGV[0]'"); } sub fetch_any { my $uri = $_[0]; # Handle tarballs via a custom Module::Plan::Lite object. # Also handle PAR archives if ( $uri =~ /\.(?:par|zip|tar\.gz)$/ ) { require Module::Plan::Lite; my $plan = Module::Plan::Lite->new( p5i => 'default.p5i', lines => [ '', $uri ], ); $plan->run; return 1; } # P5I files can have a plan created for the remote URI if ( $uri =~ /\.p5i$/ ) { require Module::Plan::Lite; my $plan = Module::Plan::Lite->new( p5i => $uri, ); $plan->run; return 1; } # We don't yet support remote p5z files if ( $uri =~ /\.p5z$/ ) { error("Remote p5z installation is not yet supported"); } error("Unknown or unsupported uri '$uri'"); } sub install_any { # Load the plan my $plan = read_any(@_); # Run it $plan->run; return 1; } sub read_any { my $param = $_[0]; # If the first argument is a tar.gz file, hand off to install if ( $param =~ /\.(?:zip|tar\.gz|tgz)$/ ) { return read_archive(@_); } # If the first argument is a par file, hand off to install if ( $param =~ /\.par$/ ) { return read_archive(@_); } # If the first argument is a p5i file, hand off to read if ( $param =~ /\.p5i$/ ) { return read_p5i(@_); } # If the first argument is a p5z file, hand off to instal if ( $param =~ /\.p5z$/ ) { return read_p5z(@_); } error("Unknown or unsupported file '$param'"); } # Create the plan object from a file sub read_p5i { my $pip = @_ ? shift : File::Spec->curdir; if ( -d $pip ) { $pip = File::Spec->catfile( $pip, 'default.p5i' ); } $pip = File::Spec->rel2abs( $pip ); unless ( -f $pip ) { error( "The plan file $pip does not exist" ); } # Create the plan object my $plan = eval { Module::Plan::Base->read( $pip ); }; if ( $@ ) { unless ( $@ =~ /The sources directory is not owned by the current user/ ) { # Rethrow the error die $@; } # Generate an appropriate error my @msg = ( "The current user does not control the default CPAN client", ); if ( File::Which::which('sudo') ) { my $cmd = join(' ', 'sudo', '-H', $0, @_); push @msg, "You may need to try again with the following command:"; push @msg, ""; push @msg, " $cmd"; } error( @msg ); } return $plan; } sub read_archive { my $archive = File::Spec->rel2abs(shift); unless ( -f $archive ) { error("Filed does no exist: $archive"); } require Module::Plan::Lite; Module::Plan::Lite->new( p5i => 'default.p5i', lines => [ '', URI::file->new($archive)->as_string ], ); } sub read_p5z { my $p5z = File::Spec->rel2abs(shift); unless ( -f $p5z ) { error("File does not exist: $p5z"); } # Create the temp directory my $dir = File::Temp::tempdir( CLEANUP => 1 ); my $pushd = File::pushd::pushd( $dir ); # Extract the tarball require Archive::Tar; my @files = Archive::Tar->extract_archive( $p5z, 1 ); unless ( @files ) { error( "Failed to extract P5Z file: " . Archive::Tar->error ); } # Find the plan my $path = File::Spec->catfile( $dir, 'default.p5i' ); unless ( -f $path ) { error("P5Z file did not contain a default.p5i"); } # Load the plan return read_p5i( $path ); } ##################################################################### # Support Functions sub error { print "\n"; print map { $_ . "\n" } @_; exit(255); } 1;