Авторинг Perl модулів

При розробці перл-модулів доводиться робити багато роботи, яка практично не пов'язана із завданнями та код модуля — починаючи від створення десятка типових файлів/каталогів і закінчуючи виконанням десятка однакових операцій необхідних для випуску нової версії.

Крім того, що це нудно, ліниво, і часто призводить до помилок (з-за необхідності оновлювати мета-інформацію — зразок номера версії — в декількох файлах або ненавмисного пропуску команд при релізі) всі додатково ускладнюється перловским TIMTOWTDI — існує декілька різних систем складання, у всіх є свої достоїнства і недоліки (але ні простий таблички з їх перерахуванням), і жодна з них не є рекомендованої ні офіційно ні спільнотою.

Крім того, багато хто з нас пишуть на перлі дуже багато років, і останній раз читали perlnewmod коли вивчали перл. В результаті, коли створюються нові модулі це нерідко робиться  стилі 15-ти річної давності, причому система складання вибирається практично випадковим чином — небудь древній, але знайомий і точно вміє що завгодно EUMM, або одна з інших (не тому, що потрібна саме вона, а просто в надії що вона виявиться простіше і зручніше EUMM, не створивши при цьому нових проблем… які вона все-таки з часом створює).

Далі коротко описані наявні на початок 2015 року кошти, які можуть полегшити процес розробки перл-модулів, зробити ваші модулі більше сучасними, і спростити іншим розробникам доопрацювання ваших модулів. Я постарався перерахувати їх основні плюси і мінуси, але оскільки сам не користувався всіма буду доповнювати/виправляти цей список у відповідності з вашими коментарями.

Завдання
Отже, давайте складемо список завдань, які зазвичай входять у процес авторинга Perl модулів.

Завдання при створенні нового модуля:
  1. задати ім'я/email автора
  2. визначити ліцензію
  3. вибрати систему збирання
  4. вибрати додаткові особливості:
    • підтримка XS
    • базовий набір тестів (перевірка документації, правопису, якості  коду, залежностей, файлів системи збирання, etc.)

    • автоматична генерація ВІДОМОСТЕЙ з документації модуля
    • використання VCS
    • інтеграція з GitHub, Travis CI
  5. створити скелет модуля — каталог з купкою файлів необхідних для його  розробки і релізу:
    • скелет самого модуля і документації
    • базовий набір тестів

    • Changes
    • README
    • LICENSE
    • файли системи збирання
    • список залежностей (іноді входить у файли системи збирання)
    • при використанні VCS: репозиторій і його налаштування
Завдання при реліз нової версії:
  1. оновити список залежностей
  2. зібрати модуль
  3. запустити тести
  4. вибрати новий номер версії і змінити її в декількох файлах (в  деяких файли в декількох місцях)
  5. описати зміни в Changes
  6. додати в Changes поточну дату і версію релізу
  7. оновити README
  8. при використанні VCS:
    1. commit змін версії, Changes, і всіх інших змінених файлів
    2. додати tag для нової версії

    3. при використанні центрального репо (GitHub) — відправити у нього  зміни
  9. створити архів з модулем
  10. залити його на CPAN
В ідеалі, всі необхідні рішення при створенні нового модуля (крім потреби в XS) потрібно прийняти один раз, і надалі створювати нові модулі однією командою. А при релізі, в ідеалі, одна команда повинна виконати всі кроки крім вибору нового номера версії і опису змін в Changes.

$VERSION
In a perfect world, I would never blog about version numbers in Perl.
 «Version numbers should be boring» — David Golden
Перед тим як перейти до суті питання, необхідно описати одну проблему: вибір формату для версії модуля. Хоча це і не пов'язано безпосередньо з темою статті, цей вибір необхідно робити в процесі створення, і він не так простий, як може здатися.

Є дуже багато способів неправильно оголосити версію свого модуля, тому я перерахую тільки правильні — їх набагато менше.

Стара десяткова / Old-style decimal
Стабільні релізи (дві/три цифри, кому як подобається):

our $VERSION = '0.08';
our $VERSION = '0.008';
package MyModule 0.08; # need perl-5.12
package MyModule 0.008; # need perl-5.12

Альфа-версії для тестування CPAN Testers перед випуском
0.09
/
0.009
:

our $VERSION = '0.08_01';
our $VERSION = '0.008_001';

Або, враховуючи, що альфа-версії користувачі все-одно не побачать, ви можете використовувати дві незалежні послідовності для стабільних і нестабільних релізів: приклад.

Точково-числова / Dotted-decimal
Стабільні релізи (можна використовувати 3 і більше чисел у версії):

use version; our $VERSION = 'v0.8.0'; # need perl-5.8.1
our $VERSION = 'v0.8.0'; # need perl-5.10
package MyModule v0.8.0; # need perl-5.12

Альфа-версії для тестування CPAN Testers перед випуском
v0.8.1
:

use version; our $VERSION = 'v0.8.0_1'; # need perl-5.8.1
our $VERSION = 'v0.8.0_1'; # need perl-5.10

Хоча
"v0.8_1"
також можна використовувати як альфа-версію між стабільними 
"v0.8.0"
та
"v0.8.1"
але така версія може бути тільки одна — якщо знадобиться випустити кілька альфа-версій те випустити стабільну з номером
"v0.8.1"
вже не вийде.

Семантична / Semantic
На даний момент немає можливості повністю відповідати спецификации семантичного версионирования - pre-release версії визначені як
"1.2.3-alpha1"
застосувати до перл-модулів не можна. Самим близьким варіантом буде вказана 3-х елементна точково-числова версія — ви можете слідувати правилам визначення наступної стабільної версії специфікації, а замість текстових pre-release версій випускати числові альфа-версії.

TRIAL
Ви вже помітили, що альфа версії це, як кажуть наші зарубіжні колеги, «біль в дупі». Фактично ж мова йде не про справжніх «альфа» — справжні альфа, бета і інші pre-release версії описані в специфікації семантичного версионирования і не підтримуються перлом. Мова йде про те, щоб дати CPAN команду «не індексувати» дану версію. Таким чином ми змішуємо в однієї змінної два типи даних (номер версії і прапор для CPAN), що є поганим стилем, потворно виглядає, заплутує (що вибрати перед випуском
"v0.8.1"
"v0.8_1"
 
"v0.8.0_1"
?) і створює інші проблеми: альфа версії можна задати в package, в деяких старих (до 5.8.1) версії perl вони працюють не коректно.

Не так давно на CPAN додали новий спосіб дати команду «не індексувати» цю версію, якщо в імені архіву з модулем є слово
"TRIAL"
. Таким чином, ви можете більше не використовувати «альфа» версії. Деякі утиліти (Dist::Zilla shipit, ...) підтримують параметр для додавання до імені архіву з модулем
"-TRIAL"
перед заливанням на CPAN. Врахуйте, що
"v1.2.3-TRIAL"
(на відміну від
"v1.2_3"
) це звичайна версія 
"v1.2.3"
, так що наступна після неї повинна бути
"v1.2.4"
 
"v1.2.4-TRIAL"
.

Скелет модуля / Boilerplate
Ці утиліти створюють каталог з новим модулем, наповнюючи його базовим набором необхідних файлів з якогось шаблону. Це самий старий, і, до сих пір, основний спосіб створити новий модуль. Проблема цього підходу в тому, що значну частину цих файлів мало просто одноразово створити, їх потрібно постійно оновлювати при випуску нових версій модуля. Тому багато поступово починають використовувати замість цих утиліт більш комплексні рішення (зазвичай на базі Dist::Zilla).

h2xs, Module::Starter
Використання цих модулів описано в perlnewmod, але суть в тому, що вони дуже застаріли, практично не підтримуються, занадто складні і при цьому недостатньо гнучкі.

На CPAN можна знайти ще деяку кількість аналогічних модулів, але все, що бачив я, були заточені під потреби їх авторів і не дуже гнучко налаштовувалися — по суті, завдання генерації каталогу з новим модулем шаблоном настільки проста, що майже кожний пише свій велосипед (мій — це скрипт на 20 рядків
~/bin/
, теж абсолютно не настроюється).

Збірка / Build
З 95% модулів містять кілька pm-файлів, тести і стандартно збирається невеликий шматок XS — впорається будь-яка система складання.

Починаючи з 5.10.1 з'явилася підтримка configure_requires — тобто тепер можна в
META.{json,yml}
вказати які модулі повинні бути встановлені запуску
perl Makefile.PL
або
perl Build.PL
. Іншими словами тепер не важливо, встановлений у користувача, наприклад, Module::Build::Tiny — ви можете використовувати його для складання свого модуля. А можете написати свою систему збирання для своїх модулів.

ExtUtils::MakeMaker (a.k.a. EUMM)
Особливості:
  • вимагає наявності
    make
  • є підтримка графа залежностей (завдяки використанню
    make
    )
Недоліки:
  • для зміни процесу складання зазвичай доводиться міняти
    Makefile
    (або  дописуючи до нього шматок, або як його перетворюючи; більш того, це  необхідно робити портабельно як в плані формату
    Makefile
    так і у  плані використовуваних в ньому шелл-команд) — що дуже сильно все ускладнює
    • при внесенні змін потрібно писати портабельный код
  • занадто великий і складний,  ніхто не хоче його підтримувати  і розвивати
  • до нього складно писати плагіни і складно підключати одночасно декілька  плагінів
Переваги:
  • самий гнучкий з усіх альтернатив, тому в складних випадках доводиться  використовувати виключно EUMM
Module::Build (a.k.a. MB)
Особливості:
  • для роботи досить perl, не потрібен ні
    make
    ні знання як писати  портабельный
    Makefile
  • немає підтримки графа залежностей (що від чого залежить при збірці)
  • прибирають з core (модулів поширюваних разом з perl) — що ні на що  не вплине (спасибі configure_requires), але викликало хвилю  FUD; насправді жодних нових  причин його уникати не з'явилося, і якщо старі причини вас не  зупиняли — то продовжуйте спокійно їм користуватися і далі
Недоліки:
  • занадто великий і складний, ніхто не хоче його підтримувати та розвивати
  • архітектури схожою з EUMM (для розширення потрібно писати код,  який буде використовуватися для генерації іншого коду, який вже  буде виконуватися) у нього та ж проблема — складно писати плагіни і  складно підключати одночасно кілька плагінів (нещодавно з'явився  Module::Build::Pluggable,  який намагається вирішити другу половину цієї проблеми)
Переваги:
  • використовувати і в невеликих обсягах, розширювати значно простіше, ніж  EUMM
Module::Install (a.k.a. MI)
Особливості:
  • обгортка над EUMM
Недоліки:
  • намагався вирішити проблему відсутності в той час configure_requires копіюючи  себе та всі необхідні йому для складання поточного модуля плагіни
    inc/
    -  що, в свою чергу, створило нові проблеми (а зараз і зовсім втратила  сенс) — від необхідності перевипускати свій модуль для виправлення бага  що йде в комплекті з ним версії MI до незручностей при використанні VCS  з-за того, що в репозиторії постійно оновлюється код відноситься до MI
Переваги:
  • простий і наочний інтерфейс
Незважаючи на одностайну нелюбов спільноти до EUMM і Module::Build, у мене склалося враження що Module::Install останнім часом взагалі перестали сприймати всерйоз — створювані їм час від часу проблеми переважили його гідності.

Module::Build::Tiny (a.k.a. MBT)
Особливості:
  • експеримент, який показав що можна зробити систему збирання на перлі  достатню для більшості модулів всього в 120 рядках коду
Ваш
Build.PL
виглядає так:

use 5.008001; # only if you need it
use Module::Build::Tiny;
Build_PL();

Як не дивно, але цим навіть можна користуватися — використовуючи файл cpanfile для управління залежностями і допоміжну утиліту mbtiny створення (генерації
Build.PL
,
MANIFEST
та
META.{json,yml}
, підготовки архіву з модулем — того, що робив Module::Build і що не відноситься до процесу складання модуля). Або використовувати Dist::Zilla замість
mbtiny
(до речі, Dist::Milla  Minilla використовують MBT — для таких наворочених систем як раз дуже зручно, коли система збирання робить тільки свою справу і не бере на себе «зайві» задачі).

Управління залежностями / Dependencies
cpanfile
Це підхід, при якому залежності вказуються окремо від системи складання, в файлі
cpanfile
. Є кілька причин це робити:

  • Якщо ви використовуєте різні системи складання в різних модулях, то  використання cpanfile дозволить забути про відмінності синтаксису (і  обмеження — EUMM і Module::Install поки не повністю підтримують  CPAN::Meta::Spec 2.0) різних  систем збирання і використовувати один формат для всіх (до речі,  сумісний з форматом Module::Install).
  • Цим же способом можна задавати залежності не тільки для перл-модулів,  але і для звичайних додатків (у яких зазвичай немає
    Makefile.PL
     
    Build.PL
    і залежно вказувати просто ніде) — власне, саме  заради цієї можливості cpanfile і був розроблений. Причому можна задати для  окремої залежності альтернативний джерело, звідки її брати —   приватного CPAN mirror, з git, etc.
  • Можна встановлювати всі залежно через
    cpanm --installdeps .
      carton
    META.{json,yml}
    файлів.
  • При використанні Module::Install можна не тримати в репозиторії
    inc/
     
    META.{json,yml}
    і коректно вказувати залежність від Module::Install  як «develop» (author_requires) а не «configure» (configure_requires).  При цьому інші розробники, у яких не встановлений Module::Install,  зможуть встановити його через
    cpanm --with-develop --installdeps .
     
    carton
    .
Керування версіями / VCS
У разі перл-модулів потрібно мати на увазі, що в репозиторії потрібно, з одного сторони, зберігати всі необхідні для складання модуля файли (щоб його можна було встановлювати прямо з репозиторію через
cpanm
і щоб після форк інші розробники отримали робочу версію проекту), а з інший уникнути засмічення його зайвими авто-генеруються файлами (наприклад, файлами Module::Install
inc/
— вам адже їх commit-ить постійно, плюс вони будуть засмічувати diff, etc. Особливо це стосується користувачів Dist::Zilla — якщо ви хочете отримувати pull-request-и то не варто вимагати, щоб бажаючі пофіксити вам якусь дрібницю були змушені встановлювати 150-200 додаткових модулів для запуску збірки проекту.

GitHub
При використанні GitHub вам швидше за все доведеться або писати додатковий опис модуля
README.md
, або налаштувати автоматичну генерацію цього файлу з POD-документації модуля. І у другому випадку може знадобитися додавати додаткові елементи - наприклад, статус складання проекту в Travis CI.

Безперервна інтеграція / CI
CPAN Testers
До квітня 2013 CPAN Testers не підтримував окреме зазначення test_requires (залежностей необхідних тільки для запуску тестів). При цьому системи складання вже давно давали можливість вказувати їх… але це не працювало. У результаті деякі розробники модулів сильно засмучувалися, випускали нову версію без всяких розумних test_requires і забували про цю фічу. Так ось, вжеПодробиці підтримки test_requires різними версіями систем збирання.

В принципі, сервіс CPAN Testers покриває основні потреби, але у нього є один недолік: тестування відбувається вже після релізу. Щоб прогнати модуль через CPAN Testers до релізу потрібно випускати спеціальні alpha-версії — і все-одно це реліз, так і працює CPAN Testers не так вже швидко.

GitHub + Travis CI
Підключивши до дерева з модулем на GitHub Travis CI можна автоматизувати тестування поточної версії модуля до релізу  кількох версіях perl (хоч це і не так круто в плані різних платформ як CPAN Тестерів, але все-таки краще, ніж запускати тести тільки у себе на машині).

Випуск / Release
App::scan_prereqs_cpanfile
Надає команду scan-prereqs-cpanfile для аналізу залежностей модуля і генерування
cpanfile
або виведення відмінностей від поточного
cpanfile
(якщо він модифікувався вручну і просто створити його заново це не найкраща ідея).

Perl::Version
Надає команду perl-reversion для зміни номера версії (майже) всіх файлів модуля.

Підтримує
README
, а не
README.md
.

CPAN::Uploader
Надає команду cpan-upload для заливання модулів на CPAN з командного рядка. Конфіг-файл
~/.pause
 з логіном/паролем для PAUSE може бути зашифрований GnuPG.

GitHub
На жаль, GitHub поки не вміє автоматично заливати перл-модулі на CPAN (хоча, напевно, технічно правильніше буде сказати, що це CPAN не вміє викачувати модулі з GitHub додавання тега для нової версії (як це відбувається, наприклад, з плагінами для jQuery). Але я все-одно залишу цей пункт тут, раптом його побачать потрібні люди і додадуть фічу. ☺

Підтримка / Support
CPAN RT
Баг-трекер CPAN багато років був єдиним доступним варіантом. Враховуючи його незручний інтерфейс це було дуже сумно. З іншого боку, їм можна користуватися навіть якщо ви не використовуєте VCS при розробці модуля.

На щастя, зараз є можливість вказати в
META.{json,yml}
(не ручками, звичайно, а через використовувану систему складання) альтернативний баг-трекер (наприклад на GitHub). На жаль, хоча при цьому зміняться посилання на баг-трекер на сайтах CPAN і MetaCPAN, це не відключить можливість додавати тікети для вашого модуля на CPAN RT (але там показується повідомлення, що бажаний баг-трекер в іншому місці). Зрозуміло, після зміни баг-трекер поточні баги залишаються в RT.

GitHub
Не буду описувати переваги та зручність підтримки проектів на GitHub (особливо впадають в очі порівняно з CPAN RT). Тим більше, що навіть якщо не подобається Git, то можна без проблем локально працювати з Mercurial і все-одно тримати проект на GitHub (через плагін hg-git).

Якщо ви захочете перемістити поточні тікети з CPAN RT в GitHub Issues - можете спробувати скористатися rt-to-github.pl або модифікацією його старої версії.

Авторинг / Authoring
В цьому розділі будуть описані утиліти повністю беруть на себе процес створення модулів, часто використовуючи при цьому вищеописані утиліти вирішують окремі підзадачі авторинга.

У мене є два сервера, один тільки що встановлений, там всього 27 CPAN-модулів, на другому багато років розробляється багато перл-проектів, там встановлено 248 CPAN-модулів. Я підрахував, скільки доводиться встановити додаткових CPAN-модулів на кожному з серверів для описаних у цьому розділі утиліт:

  • Dist::Zilla (без додаткових плагінів) вимагає 162 модуля на першому і  83 на другому сервері.
  • Dist::Milla (фактично, добірка плагінів для Dist::Zilla) вимагає 257  і 166 модулів.
  • Minilla (яка декларує мінімум залежностей як одне з основних  переваг) — 126 41 модуль.
  • ShipIt — 1 і 1.
  • App::ModuleBuildTiny — 8 і 6.
Dist::Zilla
Це справжній монстр. Він робить все! На CPAN зараз близько 900 модулів входять до 480 дистрибутивів розширюють можливості Dist::Zilla. З цих 480 дистрибутивів 315 це плагіни (Dist::Zilla::Plugin::*), і ще 100 - різні збірки цих плагінів (Dist::Zilla::PluginBundle::*).

Є тільки дві проблеми: скільки днів потрібно витратити, щоб він почав робити те, що потрібно особисто вам, і кількість модулів, які потрібно встановити щоб ним скористатися.

Щодо першої проблеми — нічого не можу сказати. Я не ризикнув зв'язуватися і намагатися його налаштувати під себе. Хто це зробив — поділіться враженнями в коментарях.

Друга проблема теж досить важлива — якщо ви хочете отримувати патчі і pull-request-и до свого модулю, необхідно, щоб бажаючі внести в нього зміни могли зробити це досить просто. Якщо їм для виправлення пари рядків потрібно буде встановити половину CPAN (автор стверджує, що  половину, а всього 0.6%) і розбиратися з нестандартним процесом складання - патч ви не дочекаєтеся.

Dist::Milla
Особливості:
  • просто добірка плагінів для Dist::Zilla і утиліта-обгортка
  • використовується ліцензія Perl, для зміни замінити її іншою в POD
  • немає автоматичного визначення та оновлення залежностей, їх потрібно  описувати вручну
    cpanfile
    • можна скористатися
      scan-prereqs-cpanfile --diff=cpanfile
      щоб  швидко знайти всі нові підключені модулі, які ще не додано до 
      cpanfile
  • можна вибрати яка система зборки буде використовуватися:  Module::Build::Tiny (за замовчуванням), Module::Build або EUMM, але я не  впевнений, що можна скористатися всіма можливостями обраної системи  складання —
    Build.PL
    редагувати сенсу немає, він при кожній збірці  генерується заново
Недоліки (порівняно з Dist::Zilla):
  • ще більшу кількість залежностей, які потрібно встановити… але це, в  значною мірою компенсується тим, що можна заощадити кілька  днів на складання своєї збірки плагінів, яка ще не факт що  опинилася б менше
    • втім, як тільки захочеться додати нову фічу, наприклад висновок  badge із звітом Travis CI в README.md — все-одно потрібно буде шукати і  підключати  додатковий  плагін Dist::Zilla

  • начебто XS-модулі не підтримуються (ймовірно, потрібно буде підключати  додатковий плагін)
Переваги:
  • багато популярні плагіни Dist::Zilla модифікують код і/або  документацію модуля (або залежать від плагінів, які це роблять),  змушуючи вас змінювати свій робочий процес — таких плагінів в  Dist::Milla принципово немає: ваш код і документацію змінюєте тільки  ви самі (виключаючи оновлення
    $VERSION
    при релізі)
    • замість того, щоб змінювати код/документацію на підставі заданих  мета-даних, Dist::Milla працює в зворотному напрямку, обчислюючи  мета-дані на підставі коду, документації та репозиторію — як це  завжди робили системи збирання начебто Module::Install або Module::Build
  • на відміну від більшості модулів використовують Dist::Zilla, в розробці  модулів використовують Dist::Milla можуть легко брати участь сторонні  розробники — їм не потрібно встановлювати собі Dist::Zilla або  розбиратися з нестандартним процесом складання, ваш модуль виглядає,  збирається, тестується і встановлюється як всі звичайні модулі
    • зокрема, ваш модуль можна встановлювати прямо з GitHub
  • немає необхідності витрачати кілька днів на підбір і налаштування свого  набору плагінів для Dist::Zilla, можна почати відразу використовувати  досить непоганий стартовий набір, і в подальшому його модифікувати  по мірі необхідності
  • підтримка міграції існуючого модуля використовує іншу систему  складання або авторинга на Dist::Milla
Minilla
Особливості:
  • працює практично ідентично Dist::Milla з налаштуваннями за замовчуванням
Недоліки:
  • практично не налаштовується
Переваги:
  • сумісний зі стандартним процесом складання/установки модуля
  • не використовує Dist::Zilla
  • значно менше залежностей, ніж у Dist::Milla
  • підтримує XS
  • підтримка міграції існуючого модуля використовує іншу систему  складання або авторинга на Minilla
Якщо ви робите авторинг практично так само, як Tokuhiro Matsuno (автор Minilla), або якщо вам все-одно як саме робиться авторинг, головне щоб все працювало саме з коробки досить сучасним чином (тобто з використанням git і GitHub) і не вимагало установки дикого кількості модулів — Minilla вам ідеально підійде. Якщо ж потрібно щось робити інакше — доведеться шукати йому заміну (найімовірніше їй виявиться Dist::Milla).

ShipIt
Дозволяє однією командою
shipit
виконати більшість операцій, необхідних при випуску нової версії.

В каталозі модуля створюється файл
.shipit
, приблизно такий:

steps = FindVersion, ChangeVersion, CheckChangeLog, DistTest, Commit, Tag, MakeDist, UploadCPAN
і тепер при запуску
shipit
будуть виконані зазначені в
.shipit
 операції:

  1. у вас запитають номер нової версії
  2. нова версія пропишеться в коді модуля
  3. перевірить наявність запису в
    Changes
    і запропонує її додати
  4. запустить тести (підтримує
    Makefile.PL
    та
    Build.PL
    )
  5. зробить commit (підтримує Git/Mercurial/SVN)
  6. додасть tag для нової версії
  7. підготує архів з модулем
  8. заллє архів на CPAN
Всі доступні операції оформлені у вигляді плагінів, так що на CPAN повно додаткових модулів (генерація
README
з POD, оновлення версії POD, прописування нової версією в коді кожного модуля, анонси в соц.мережі, ...).

Не зрозуміло, чи буде ShipIt підтримуватися — він вже пару років не оновлювався, а його автор зараз активно працює над Dist::Milla і описує міграцію з ShipIt на Dist::Milla. На мій погляд ShipIt робить практично все необхідне, і при цьому він дуже маленький, простий, розширюваний і без залежностей. Не знаю, що в ньому не влаштувало автора, і чому він вирішив робити обгортку для Dist::Zilla замість дописування відсутньої функціональності плагінами для ShipIt. &Nbsp;думку автора Dist::Zilla (який активно використовував ShipIt до того як розробити Dist::Zilla) основна проблема ShipIt — складність і недостатня гнучкість розширення його плагінами. Треба визнати, цю проблему Dist::Zilla дійсно вирішив більш ніж грунтовно.

App::ModuleBuildTiny
Довго думав, чи варто взагалі включати його в статтю. Функціональність у нього рудиментарна, поточна версія 0.005, рік його ніхто не оновлював… але буквально днями автор їм активно зайнявся, і крім того, він необхідний для використання Module::Build::Tiny безпосередньо, не через Dist::Zilla або Minilla.

Це не схоже на утиліту для авторинга, принаймні якщо порівняти його можливості з вищеописаними утилітами. Але автор назвав його «A standalone authoring tool», значить будемо розглядати її в цьому розділі. З урахуванням його вкрай обмежених можливостей спробуємо використовувати разом з ним інші дрібні утиліти (описані в наступних розділах) у спробі отримати повну функціональність авторинга без Dist::Zilla.

Для початку — самий мінімалістичний спосіб створити модуль для CPAN:

mkdir-p Example-MBtiny/lib/Example/
cd Example-MBtiny
vi lib/Example/MBtiny.pm
mbtiny dist

В результаті отримуємо
Example-MBtiny-$VERSION.tar.gz
, який можна заливати на CPAN. Ніяких інших файлів в каталозі з модулем більше немає - тільки створений нами
lib/Example/MBtiny.pm
і цей архів.

Тепер створимо (або згенеруємо якою-небудь утилітою) всі стандартні файли, які зазвичай присутні в кожному сучасному модулі викладеному на GitHub:
README.md
,
LICENSE
,
Changes
,
t/*
,
.gitignore
 
.travis.yml
а так само створимо репозиторій, додамо туди всі ці файли і заллємо на GitHub.

Наступне питання — у якому стилі використовувати
mbtiny
:

  • Якщо викликати тільки
    mbtiny test
    та
    mbtiny dist
    , необхідні для  складання, тестування та встановлення файли
    Build.PL
    ,
    MANIFEST
    та 
    META.{json,yml}
    будуть генеруватися на льоту і віддалятися по завершенню  операції. Безумовно, вони будуть присутні у створеному архіві для  заливання на CPAN, але їх не буде в репозиторії — що зробить  неможливим встановлення модуля через
    cpanm
    прямо з репозиторію і може  спантеличити сторонніх розробників, які хотіли б щось змінити і  надіслати pull-request.
  • Альтернативний варіант — викликати
    mbtiny regenerate
    для створення 
    Build.PL
    ,
    MANIFEST
    та
    META.{json,yml}
    і додати їх у сховище.  При зміні версії модуля, додавання нових файлів, або зміні  залежностей — буде необхідно знову викликати цю команду.
При використанні GitHub потрібно додати в проект
metamerge.json
, його вміст буде враховуватися при генерації
META.{json,yml}
:

{
"resources" : {
"bugtracker" : {
"web" : "https://github.com/powerman/Example-MBtiny/issues"
},
"homepage" : "https://github.com/powerman/Example-MBtiny",
"repository" : {
"type" : "git",
"url" : "git://github.com/powerman/Example-MBtiny.git",
"web" : "https://github.com/powerman/Example-MBtiny"
}
}
}

При реліз нової версії знадобляться додаткові утиліти:

# update dependencies
scan-prereqs-cpanfile >cpanfile
# ... update META.* from cpanfile if you added META.* into the repo
mbtiny regenerate
# build & test
mbtiny test
# version update everywhere
ver=1.2.3
perl-reversion-set $ver
# don't forget to version update & date
vi Changes
# regenerate README.md with badges
cp BADGES.md README.md
pod2markdown lib/Example/MBtiny.pm >> README.md
# release
git commit-a-m "release $ver"
git tag $ver
git push
mbtiny dist
cpan-upload Example-MBtiny-$ver.tar.gz

Як бачите, виконувати все це кожен раз вручну — не найкраща ідея, щось забудеш, десь помилишся. Але оформити це скриптом не складно. Двох таких простих скриптів (цього, і створює кістяк нового модуля за шаблоном) цілком достатньо для створення сучасних модулів без Dist::Zilla.

Резюме
  • якщо немає гострої необхідності підтримувати старі версії перла, на мій  погляд, в модулях стоїть за замовчуванням використовувати
    use 5.010001;
  • версію задавати використовуючи формат
    our $VERSION="v1.2.3";
    • відповідати специфікації семантичного версионирования настільки,  наскільки можливо в перлі
    • для альфа-версій додавати після версії в імені архіву з модулем 
      "-TRIAL"
      замість використання підкреслень у номері версії
  • в якості системи збирання використовувати Module::Build::Tiny або  Module::Build (тільки якщо не вистачає можливостей MBT)
  • для управління залежностями використовувати
    cpanfile
  • тримати модуль на GitHub, вказати посилання на GitHub
    META.json
    • використовувати Travis CI
Що ж стосується вибору утиліти для авторинга — тут складно дати однозначну рекомендацію. Якщо вибирати серед занедбаних:

  • Minilla, якщо робота за замовчуванням влаштовує і немає потреби якось  його налаштовувати
  • Dist::Milla, якщо подобається Minilla але хочеться щось налаштувати, або  хочеться почати використовувати Dist::Zilla з досить адекватною і  документованої збірки плагінів
  • App::ModuleBuildTiny, якщо хочеться швидко зробити свій велосипед,  простий і досить гнучко настроюється
Різні корисності для авторів модулів
______________________
Текст конвертований використовуючи habrahabr backend AsciiDoc.


Джерело: Хабрахабр

0 коментарів

Тільки зареєстровані та авторизовані користувачі можуть залишати коментарі.