Выпуск 20. Октябрь 2014
← Событийно-ориентированное программирование. Введение | Содержание | Работа с API GitHub в Perl →Локальная установка и использование Perl-модулей
Рассмотрены способы установки Perl-модулей в локальную директории с помощью cpanm
, использование local::lib
для работы с ними, и carton
для автоматизации процесса.
Часто требуется изолировать установленные модули для каждого проекта отдельно. Это может быть связано с разными версиями, необходимостью локализации или, например, с нежеланием устанавливать модули в систему, если вы просто тестируете какое-то новое Perl-приложение. Для примера возьмем простейшую серверную программу на Plack
, которая при наличии параметра name
приветствует посетителя:
#!/usr/bin/env perl
use strict;
use warnings;
use Plack::Request;
sub {
my $env = shift;
my $req = Plack::Request->new($env);
my $name = $req->param('name') || 'anonymous';
return [200, [], [qq{Hello, $name!}]];
}
Наш проект на текущий момент имеет следующую структуру:
app.psgi
cpanm
Далее с помощью cpanfile
(подробнее о формате cpanfile
читайте в статьей Что такое cpanfile?) укажем зависимости:
requires 'Plack';
Теперь наш проект выглядит так:
app.psgi
cpanfile
Установим зависимости в локальную директорию. Пусть, например, это будет third-party
. Для того, чтобы все модули устанавливались несмотря на их присутствие в локальной системе, воспользуемся ключом -L
у cpanm
:
$ cpanm -L third-party --installdeps .
Установка займет некоторое время и на выходе мы получим следующую структуру:
app.psgi
cpanfile
third-party/
bin/
...
plackup
lib/
perl5/
x86_64-linux-gnu-thread-multi
...
man/
...
Как видно, модули установились в third-party/lib/perl5
, исполняемые файлы в third-party/bin
и man
-страницы в third-party/man
. В директории perl5
присутствует также x86_64-linux-gnu-thread-multi
, куда обычно устанавливаются модули, требующие компиляции. К сожалению, до сих пор Plack
требует компилятор для установки, однако ведутся работы по разделению дистрибутива на несколько пакетов, где необходимые модули для запуска приложения не будут требовать компиляции.
Работа cpanm
на этом закончена. Мы установили необходимые модули в локальную директорию. Теперь необходимо запустить наше приложение.
local::lib
Если мы попробуем запустить следующим образом:
$ perl third-party/bin/plackup app.psgi
То получим вполне ожидаемую ошибку:
Can't locate Plack/Runner.pm in @INC
Мы, конечно, можем указать perl
с помощью ключа -I
где искать модули, однако это довольно утомительно. Более того, часто можно забыть подключить директорию с компилированными модулями, и это не так просто автоматизировать, потому как название директории меняется в зависимости от операционной системы. Именно для подключения локальных модулей нам поможет local::lib
.
$ perl -Mlocal::lib=third-party third-party/bin/plackup app.psgi
HTTP::Server::PSGI: Accepting connections at http://0:5000/
Ключ -M
интерпретатора подключает модули до запуска скрипта. А с помощью =
можно передать модулю параметры. local::lib
получает их в методе import
и подключает необходимую директорию.
Использование cpanm
и local::lib
таким образом позволяет быстро установить модули рядом с проектом и запустить его. Однако, для больших приложений, которые часто приходится устанавливать и запускать на разных системах, это не слишком удобно.
Carton
Carton
объединяет в себе возможности cpanm
и local::lib
(на самом деле, внутри он использует эти два модуля), а также избавляет от необходимости ручного указания путей, позволяет контролировать зависимости и упрощает процесс поставки приложения.
Для работы carton
достаточно cpanfile
, который у нас уже есть. Вернемся к структуре проекта до установки зависимостей и инициализируем carton
:
$ carton install
Installing modules using cpanfile
Successfully installed ...
23 distributions installed
Complete! Modules were installed into local
Модули установились в директорию local
, но это не так важно, потому как carton
сам позаботится о добавлении нужных путей для запуска perl
. Кроме того, carton
создал файл cpanfile.snapshot
, где указаны установленные зависимости с их версиями. Это файл стоит добавить в систему контроля версий. При запуске carton install --deployment
и при наличии cpanfile.snapshot
будут установлены указанные там версии. Таким образом, на машине другого разработчика или сервере будет такое же окружение.
Запускаем приложение:
$ carton exec -- plackup app.psgi
HTTP::Server::PSGI: Accepting connections at http://0:5000/
carton exec
запускает приложение в виртуальном окружении, где все модули подгружаются из директории local
. Так, например, можно проверять все ли модули указаны как зависимости.
carton
также позволяет собирать дистрибутив с зависимостями:
$ carton bundle
Bundling modules using cpanfile
Copying K/KA/KAZEBURO/Apache-LogFormat-Compiler-0.32.tar.gz
Copying ...
/tmp/h3lGuLzMVc/carton.pre.pl syntax OK
Bundling vendor/bin/carton
Complete! Modules were bundled into vendor/cache
Теперь в директории vendor/cache
находятся тарболы модулей. Просто скопировав их на другую машину и запустив там:
$ carton install --cached
модули будут устанавливаться из тарболов без обращения к CPAN. Так можно разворачивать приложения на серверах без доступа к внешним сетям.
Другие решения
Другим подходом для контроля зависимостей является создание своего приватного CPAN. Это позволяют сделать модули CPAN::Mini
и подобные ему. Отдельно стоит приложение Pinto
(читайте подробнее в статье Pinto — собственный CPAN из коробки), которое автоматизирует процесс установки, контроля и фиксирования модулей.
← Событийно-ориентированное программирование. Введение | Содержание | Работа с API GitHub в Perl →