PHP: создание и публикация пакета composer

С пакетами и библиотеками жизнь разработчика упрощается. Пакет  —  это часть кода многократного использования, добавляемая в любое приложение и применяемая без каких-либо изменений для расширения функционала этого кода.

Создадим и опубликуем пакет composer на PHP.

Что понадобится

  • Composer.
  • Код пакета проекта.
  • Учетная запись на Github и в Packagist.

Что такое composer?

  • Это диспетчер зависимостей для пакетов или библиотек PHP.
  • Создан по примеру npm (Node.js) и bundler (Ruby).
  • Работает с пакетами официального репозитория packagist.org: так известно местонахождение кода пакета  —  обычно это публичный репозиторий на Github.

Готовим пакет

Вот структура проекта:

sfmok ~/my-package> tree
.
├── src
│ └── HelloWorld.php
└── tests
└── HelloWorldTest.php

Сделаем ее в виде пакета: поделиться им можно точно так же, каким бы ни был пакет и/или его размер.

Начнем с генерирования в composer конфигурационного файла composer.json, переходим к пути пакета проекта в терминале и запускаем:

composer init

Здесь нужно внимательно рассмотреть вопросы:

Инициализируем конфигурацию пакета
  1. Проверяем соответствие пакета способу именования <vendor>/<name>, где:
  • <vendor>  —  это имя автора, и оно должно быть уникальным, например имя пользователя на Github sfmok;
  • <name>  —  это название самого пакета, например hello-world.

2. Тип пакета:

  • library: по умолчанию. Файлы им скопируются в vendor.
  • project: так обозначается проект, а не библиотека. Например, оболочки приложений, такие как стандартная версия Symfony; системы управления содержимым, такие как установщик SilverStripe; полноценные приложения, распространяемые в виде пакетов. Это применяется в интегрированных средах разработки, где предоставляются листинги проектов для инициализации при создании новой рабочей области.
  • metapackage: пустой пакет с требованиями, которым запускается их установка; но файлов в нем нет, и в файловую систему ничего не записывается. Поэтому для его установки ключ dist или source не требуется.
  • composer-plugin: в таком пакете может быть установщик других пакетов пользовательского типа. Подробнее здесь.
  • symfony-bundle: применяется в бандлах фреймворков Symfony для автоматического  —  с помощью Flex  —  включения бандла при его установке.

3. Зависимости require и require-dev: в composer сообщается, от каких пакетов зависит проект, например php для всех сред, а phpunit для среды разработки.

4. Сопоставление при автозагрузке PSR-4: пространство имен пакета сопоставляется с корневым пакетом src. По умолчанию совпадает с названием пакета.

После подтверждения генерирования в пакет проекта добавлен файл composer.json:

sfmok ~/my-package> tree
.
├── composer.json
├── src
│ └── HelloWord.php
└── tests
└── HelloWordTest.php

Командой composer init не поддерживаются следующие параметры конфигурации.

  • PSR-4 autoload-dev для указания другого пространства имен путей test/dev.
  • Config.
  • Скрипты.

Они добавляются в файл composer.json вручную. Например, добавим в пакет пространство имен PSR-4 autoload-dev:

{
"name": "sfmok/hello-world",
"description": "A hello world example package.",
"type": "library",
"require": {
"php": "^8.0"
},
"require-dev": {
"phpunit/phpunit": "^9.0"
},
"license": "MIT",
"autoload": {
"psr-4": {
"Sfmok\\HelloWorld\\": "src/"
}
},
"autoload-dev": {
"psr-4": {
"Sfmok\\HelloWorld\\Tests\\": "tests/"
}
},
"authors": [
{
"name": "Mokhtar Tlili",
"email": "[email protected]"
}
]
}

Тесты должны быть зелеными. Дальше добавляем:

  • файл README с описанием пакета и особенностей его использования;
  • файл .gitignore, чтобы исключить отслеживание лишних файлов и каталогов, например папку vendor для пакетов зависимостей, папку IDE (часто скрытую) и т. д.;
  • файл .gitattributes (необязательно) для игнорирования экспорта конкретных файлов и каталогов, когда в composer архивируется пакет; его содержимое  —  относительные пути с последующим атрибутом, например /tests export-ignore.

Публикуем

Пакет публикуется официально в два этапа.

  1. Размещается в публичном репозитории, например на Github.
  2. Регистрируется в Packagist.

Размещаем на Github

Создаем новый репозиторий hello-world: название то же, что у пакета.

Репозиторий на GitHub

Версионируем пакет, инициализируя локальный репозиторий, затем отслеживаем и фиксируем изменения во всем проекте:

sfmok ~/my-package> git init --initial-branch=main
Initialized empty Git repository in /Users/sfmok/projects/my-package/.git/
sfmok ~/my-package (main)> git add .
sfmok ~/my-package (main)> git commit -m "first commit"
[main (root-commit) 25b914a] first commit
6 files changed, 68 insertions(+)
create mode 100644 .gitattributes
create mode 100644 .gitignore
create mode 100644 README.md
create mode 100644 composer.json
create mode 100644 src/HelloWorld.php
create mode 100644 tests/HelloWorldTest.php

Публикуем пакет, добавляя главную ветку в публичный репозиторий на Github:

sfmok ~/my-package (main)> git remote add origin https://github.com/sfmok/hello-world.git
sfmok ~/my-package (main)> git push -u origin main
Enumerating objects: 10, done.
Counting objects: 100% (10/10), done.
Delta compression using up to 8 threads
Compressing objects: 100% (7/7), done.
Writing objects: 100% (10/10), 1.29 KiB | 661.00 KiB/s, done.
Total 10 (delta 0), reused 0 (delta 0), pack-reused 0
To https://github.com/sfmok/hello-world.git
* [new branch] main -> main
Branch 'main' set up to track remote branch 'main' from 'origin'.

Репозиторий выглядит так:

Пакет репозитория на Github

Чтобы сделать версию v1.0.0 первого релиза, нажимаем на Releases и создаем для него тег:

Пакет релизов на Github

Заполняем форму релиза и публикуем:

Пакет релизов на Github

Регистрируем в Packagist

Входим через учетную запись Github и отправляем пакет:

Отправка пакета в Packagist

Нажимаем кнопку check  —  проверится уникальность названия пакета.

В случае успеха появится кнопка отправки:

Отправка пакета в Packagist

Отправленный пакет несколько минут обрабатывается, затем публикуется:

Просмотр пакета в Packagist

Теперь пакет официально опубликован и готов к использованию в любом проекте на PHP, например в composer require sfmok/hello-world:

Установка пакета HelloWorld

В composer обнаружен первый релиз v1.0.0:

<?php
// src/Test.php

require_once __DIR__ . '/../vendor/autoload.php';

use Sfmok\HelloWorld\HelloWorld;

$greeting = new HelloWorld();

echo $greeting->hello();
Тестовый пакет HelloWorld

Читайте также:

Читайте нас в TelegramVK и Дзен


Перевод статьи Mokhtar Tlili: Create and publish a PHP composer package

Предыдущая статья7 полезных репозиториев GitHub для JS-программистов
Следующая статьяКак создать эффективную систему логирования с использованием Aspect и Spring Cloud Sleuth