Выпуск 10. Декабрь 2013

Воркшоп Saint Perl 5 | Содержание | Обзор CPAN за ноябрь 2013 г.

Что такое cpanfile?

От создателя cpanminus и Plack, революционная инновация в процессе подготовки Perl-приложения для распространения — cpanfile. Начните использование сегодня, и установка ваших модулей будет мягкой и шелковистой даже из git.

cpanfile

cpanfile — это название файла, а также формата, который описывает CPAN-зависимости для Perl-приложений. Идея cpanfile пришла из мира Ruby, где для описания зависимостей используется Gemfile. На сам формат сильно повлиял DSL, используемый в системе сборки Module::Install, и, кстати, cpanfile обратно-совместим с ним. Кроме того, описание зависимостей использует терминологию спецификации META при описании зависимостей: те же типы и фазы зависимостей.

Рассмотрим пример:

# требуется Perl 5.8.5 или старше
requires 'perl', 5.008_005

# рекомендуется Foo::Bar версии 1.0 или старше
# но меньше версии 2.00
recommends 'Foo::Bar', '>= 1.0, < 2.00';

# Зависимости фазы тестирования
on test => sub {
    # Test::More версии 0.88 или старше
    requires 'Test::More', '0.88';
};

Зачем нужен cpanfile?

Все существующие системы сборки, такие как ExtUtils::MakeMaker, Module::Build, Module::Install и другие имеют средства для описания зависимостей.

use ExtUtils::MakeMaker;
WriteMakefile(
    NAME => "Foo::Bar",
    PREREQ_PM => {
        'JSON::XS' => '3.00'
    }
);

Как правило, утилиты для установки CPAN-модулей используют файл META.yml, который автоматически формируется средствами сборки и содержит информацию о зависимостях. Таким образом, типичный CPAN-модуль содержит всё необходимое для корректной сборки и установки в систему. Зачем нужно что-то ещё?

Прежде всего, cpanfile предлагает универсальный формат описания зависимостей, не перегруженный избыточным многословием, который может использоваться различными утилитами, начиная от инсталляторов, заканчивая статическими анализаторами или сервисами непрерывной интеграции.

На данный момент уже созданы плагины для многих систем сборок, которые позволяют использовать cpanfile для извлечения списка зависимостей. Например, для ExtUtils::MakeMaker есть модуль ExtUtils::MakeMaker::CPANfile, который позволяет переписать указанный выше пример так:

# Makefile.PL
use ExtUtils::MakeMaker::CPANfile;
WriteMakefile(
    NAME => "Foo::Bar",
);

# cpanfile
requires 'JSON::XS', '3.00

Для других систем сборки соответственно есть Module::Install::CPANfile, Dist::Zilla::Plugin::Prereqs::FromCPANfile, Module::Build::Pluggable::CPANfile. Таким образом, можно использовать cpanfile совместно с существующими системами сборки и избежать дублирования информации о зависимостях.

Кроме того, существует несколько ситуаций, когда применение cpanfile имеет явные преимущества. Рассмотрим такие примеры.

Веб-приложение или скрипт

Разрабатывается приложение, которое использует модули CPAN, но при этом нет задачи по выкладыванию самого приложения на CPAN. В этом случае для нормальной установки приложения требуется удобный способ описания зависимостей без необходимости создания полноценного CPAN-дистрибутива с Makefile.PL (выбора системы сборки и формальное следование всем её требованиям).

В такой ситуации после создания cpanfile все необходимые CPAN-модули можно установить с помощью команд:

$ carton install

или

$ cpanm --installdeps .

Установка модуля из git-репозитория

Всё больше авторов используют git в качестве системы контроля версий и github как публичный хостинг проектов. В этом отношении всё большее значение приобретает возможность брать и использовать код непосредственно из git (или любой другой VCS).

Как правило, при разработке модуля в git-репозитории отсутствуют автоматически генерируемые файлы. В случае использования Dist::Zilla это означает отсутствие Makefile.PL или Build.PL вообще, что требует от пользователя необходимость установки dzil и множества модулей этой среды разработки, которые не имеют никакого отношения к работе модуля, всё только ради возможности выяснить, какие он требует зависимости. В случае Module::Install потребуется знать, какие нужны модули в каталоге inc только для бутстрапа самого Makefile.PL.

В подобных ситуациях наличие cpanfile позволяет быстро и просто установить необходимые зависимости с помощью cpanm или carton, что существенно повышает доступность кода для использования непосредственно из git-репозитория.

Фиксация зависимостей

Существующие средства описания зависимостей фиксируют саму зависимость и минимальную необходимую версию. Таким образом, не исключена возможность установки более новой версии зависимого модуля, с которой работа приложения не тестировалась. С помощью cpanfile существует возможность точно указать требуемые версии модулей или диапазоны таких версий, а также явно указывать версии, которые использовать нельзя. Например,

# зафиксировать версию
requires 'JSON::XS', '== 3.01'

# диапазон версий с исключениями
requires 'Plack',
  '> 1.0000, != 1.0020, != 1.0021, <= 1.0030'

Это позволяет получать предсказуемые результаты установки и работоспособность программы.

Формат cpanfile

Рассмотрим пример cpanfile:

requires 'Catalyst', '5.8000';
requires 'Catalyst::View::JSON', '>= 0.30, < 0.40';

recommends 'JSON::XS', '2.0';
conflicts 'JSON', '< 1.0';

on 'test' => sub {
  requires 'Test::More', '>= 0.96, < 2.0';
  recommends 'Test::TCP', '1.12';
};

on 'develop' => sub {
  recommends 'Devel::NYTProf';
};

feature 'sqlite', 'SQLite support' => sub {
  recommends 'DBD::SQLite';
};

Ключевые слова requires, recommends, conflicts, а также suggests описывают зависимости модуля соответственно как обязательные, рекомендуемые, конфликтующие и опциональные. После ключевого слова идёт название модуля, затем через запятую указывается строка с диапазоном версий, формат которой соответствует спецификации CPAN::Meta::Spec Version Range:

  • undef, '', 0 — любая версия
  • '1.00' или '>= 1.00' — минимальная версия (1.00 или старше)
  • '> 1.00' — любая версия старше 1.00
  • '<= 1.00' — версия 1.00 или младше
  • '< 1.00' — строго младше версии 1.00
  • '!= 1.00' — любая версия, кроме 1.00
  • '== 1.00' — только версия 1.00

С помощью ключевого слова on можно определять, к какой именно фазе относятся указанные зависимости:

  1. develop — зависимости, необходимые для разработки модуля
  2. configure — зависимости этапа конфигурации, т.е. необходимые для успешного запуска perl Makefile.PL
  3. build — зависимости этапа сборки (make)
  4. test — зависимости этапа тестирования (make test)
  5. runtime — основные зависимости приложения, необходимые для выполнения приложения

Для совместимости с Module::Install requires-зависимости, указанные в перечисленных фазах, можно указывать с помощью соответствующих ключевых слов: author_requires, configure_requires, build_requires, test_requires.

После определения фазы идёт тело функции с описанием зависимостей фазы.

Ключевое слово feature описывает зависимости той или иной опциональной функциональности приложения, которая может быть подключена или отключена. Вслед за ключевым словом идёт идентификатор функционала, через запятую следует строка его описания, которая может быть опущена. Последним параметром идёт функция, описывающая зависимости функционала.

Идеи развития cpanfile

Одно из интересных направлений развития cpanfile — это поддержка не только CPAN-модулей, но и произвольных репозиториев кода.

Например, на данный момент cpanminus поддерживает установку модулей непосредственно из git, например:

cpanm git://github.com/plack/Plack.git@1.0000 # тег
cpanm git://github.com/plack/Plack.git@devel  # бранч

Кажется разумным, чтобы и cpanfile поддерживал подобную возможность, например:

requires 'Plack', '1.001', at => 'git://github.com/tokuhirom/Plack.git'

Также открыт вопрос с тестированием git-репозиториев. На сегодняшний момент многие используют сервис Travis CI. Для этого в репозиторий помещают файл .travis.yml для описаний зависимостей и способа их установки. К сожалению, данный метод специфичен для данного сервиса. Кажется интересным идея о добавлении ключевого слова или команды в cpanfile, которая бы задавала способ подготовки кода к стандартному виду CPAN-дистрибутива.

Владимир Леттиев


Воркшоп Saint Perl 5 | Содержание | Обзор CPAN за ноябрь 2013 г.
Нас уже 1393. Больше подписчиков — лучше выпуски!

Комментарии к статье