はじめに
Gitの仕組みに興味があり、学習目的も兼ねて簡易的なRCS(Revision Control System)をPHPで実装してみました。
最終的には、
– Composer package化
– GitHub Actions
– Packagist公開
まで行ったので、その流れをまとめます。今回、Packagistに登録したリポジトリはこちらです。
GitHub - yu-corder/php-rcs: A pure PHP implementation of a Revision Control System (RCS) for file versioning.A pure PHP implementation of a Revision Control System (RCS) for file versioning. - yu-corder/php-rcs
ディレクトリ構成はこちらになります。
php-rcs(ドキュメントルート)
|------- .github/workflows/test.yml (自動テスト)
|------- src/RcsManager.php (packageのコアロジック/API)
|------- bin/rcs (CLI)
|------- tests/(テストコード)
|------- composer.json (Packagist公開にあたって必要です。)

composer package化
composer.json を作成し、パッケージ名(yu-corder/php-rcs)、オートロード設定(PSR-4)、および依存関係(”php”: “^8.2″)を定義しました。重要なのが、PSR-4 autoload の部分になります。
YuCorder 名前空間のクラスは src/ 以下から自動ロードしてくれます。
</>json
{
"require": {
"php": "^8.2"
},
"require-dev": {
"friendsofphp/php-cs-fixer": "^3.0",
"phpunit/phpunit": "^10.5"
},
"autoload": {
"psr-4": {
"YuCorder\\": "src/"
}
},
"autoload-dev": {
"psr-4": {
"YuCorder\\Tests\\": "tests/"
}
}
}
//expample.php
use YuCorder\RcsManager;
use 宣言したときに Composer が src/RcsManager.php を自動で探してくれるようになります。
PSR-4 についてもっと詳しく知りたい方はこちらの公式ドキュメントを参照してください。
PSR-4: Autoloader - PHP-FIGWe're a group of established PHP projects whose goal is to talk about commonalities between our projects and find ways w...
ライブラリ設計(関心の分離)
- src/RcsManager.php
- bin/rcs
今回は CLI ツールとして利用できるようにしていますが、実際の処理は RcsManager に集約し、CLI 側は薄いラッパーとして実装しました。これにより、
– CLI
– 他のPHPアプリケーション
– 将来的なWeb API
などから同じロジックを再利用できる構成にしています。
GitHub Actions
今回は自動テストはGitHub-hosted runner で 設定しました。Self-hosted runner 設定も別記事で紹介しているので、気になる方はこちらもどうぞ。
今回私が実装したpackageがPHP8.2以上 を前提としているので、自動テストでは8.2 からサポートするように記述します。
name: Test Suite
on:
push:
branches: [ main, master ]
pull_request:
branches: [ main, master ]
permissions:
contents: read
jobs:
phpunit:
name: PHPUnit (PHP ${{ matrix.php-versions }})
runs-on: ubuntu-latest
strategy:
fail-fast: false
matrix:
php-versions: ['8.2', '8.3', '8.4', '8.5']
....省略
テストコードや細かい設定については省略しますが、パッケージを動かすための前提環境は最低限保証できるようにします。
Packagist公開
Packagist.orgThe PHP Package Repository
こちらが Packagist になります。Packagistに登録しないと、composer で追加することができません。
composer require yu-corder/php-rcs

Packagist にログイン(githubのアカウントでログインできます。)するとヘッダーに submit があるので、そちらに遷移します。GitHubのリポジトリURLを入力して、Checkを押します。問題なければ、公開されます。※リポジトリにREADME.md がないと公開できません。READMEは必須ではありませんが、表示品質や使いやすさのため強く推奨します。

yu-corder/php-rcs - Packagist.orgA pure PHP implementation of a Revision Control System (RCS) for file versioning.
公開したら、git tag でバージョンを打ちます。初めて git tag 使いました。
git tag を打つことで、その時点の commit を特定バージョンとして固定できます。私の場合は、v0.1.0 にしました。これから、さらに色々な機能を追加する予定なので、プロトタイプということで、v1.0ではなく、v0.1.0です。タグを打った後に改修などでmain ブランチにpush やマージするかと思いますが、タグを再度作成するまでは、Packagist 上では dev-main として扱われます。
git tag v0.1.0
git push origin v0.1.0
最後に別プロジェクトで実際にパッケージを追加して、動かしてみます。
composer require yu-corder/php-rcs
/var/www# ./vendor/bin/rcs
Warning: require_once(/var/www/vendor/yu-corder/php-rcs/bin/../vendor/autoload.php): Failed to open stream: No such file or directory in /var/www/vendor/yu-corder/php-rcs/bin/rcs on line 4
Fatal error: Uncaught Error: Failed opening required '/var/www/vendor/yu-corder/php-rcs/bin/../vendor/autoload.php' (include_path='.:/usr/local/lib/php') in /var/www/vendor/yu-corder/php-rcs/bin/rcs:4
Stack trace:
#0 /var/www/vendor/bin/rcs(119): include()
#1 {main}
thrown in /var/www/vendor/yu-corder/php-rcs/bin/rcs on line 4
エラーになりましたね。。。別のプロジェクトでインストールされると、ディレクトリ構造が変わってしまうため、エラーになります。
if (file_exists(__DIR__ . '/../../../autoload.php')) {
require_once __DIR__ . '/../../../autoload.php';
} else {
require_once __DIR__ . '/../vendor/autoload.php';
}
修正をして、再度タグを打ちます。
git tag v0.1.1
git push origin v0.1.1
プロジェクト内のパッケージをupdateします。そして、再度 rcsを呼んでみます。
composer update yu-corder/php-rcs
/var/www# ./vendor/bin/rcs checkin .env
✓ Successfully checked in.
無事使うことができました。
以上が基本的なパッケージ開発のサイクルになるかと思います。
最後に
今回初めて Packagist にパッケージを公開しましたが、Composer や PSR-4 autoload、Git tag の理解も深まり、非常に良い学習経験になりました。
実際に別プロジェクトへ導入してみることで、autoload 周りの問題にも気づくことができ、
「ライブラリとして使われる」視点の大切さも学べました。
これからも機能追加や改善を続けていこうと思います。



コメント