MENU

blog
スタッフブログ

dot
LaravelでServiceやRepositoryを生成するコマンドをパッケージ化してみた
技術

LaravelでServiceやRepositoryを生成するコマンドをパッケージ化してみた

こんにちは、クリエイティブSecの長谷川です。

以前「LaravelでServiceやRepositoryをartisanコマンドで生成できるようにする」という記事を書きました。
コマンドで簡単に生成できるようになったのは良いのですが、これをいろいろなプロジェクトで使おうと思うと
毎回ファイルを作成するのも面倒だなと思いました。

なので、今回はこの機能をパッケージ化して配布したことについて書いていきたいと思います。

作成したパッケージについて

今回作成したパッケージはこちらです。

lazgram/laravel-sr-command

基本的には、前の記事で書いた内容をそのままパッケージ化しました。

パッケージ化の方法

何気に困ったのが、そもそもLaravelのパッケージってどうやって作るんだろう?というところです。
公式ドキュメントが日本語訳された「Laravel 12.x パッケージ開発」を読んでも
各機能を作成するための説明は書かれているのですが、そもそもどういうファイル構成で作成するのかという点については
具体的に書かれておらず、苦戦しました。

作ったパッケージを動作検証するうえでは、下記のページが役に立ちました。
Laravelパッケージを作ろう!その壱

上記を参考にして、まず下記のようなフォルダ構成にしました。

[laravel]
├ app
├ bootstrap
├ ...
├ packages
│ └ [vendor_name] ← 配布する際の組織名
│   └ [package_name] ← 配布するパッケージ本体の名前
│     └ src
├ public
├ ...
└ ...

packagesというフォルダの名前については、必ずしもこの名前でないといけないというわけではありませんが
分かりやすく管理できるようにこの名前で作成をしました。

そして、その中に配布する際のベンダー名のフォルダを作り
さらにその中にパッケージ名のフォルダを作ります。

Laravelをcomposerでインストールする場合「laravel/laravel」とか「laravel/framework」なんていうパッケージをインストールしますが
スラッシュより前の部分がベンダー名、後の部分がパッケージ名ですね。

packageの初期化をする

フォルダを作ったら、次はプロジェクトとしての初期化を行います。
先程作った[package_name]のフォルダに移動して、下記コマンドを実行します。

composer init

コマンドを実行すると、対話式で色々と聞かれますので
初期情報を入力していきます。

$ composer init
This command will guide you through creating your composer.json config.

Package name (<vendor>/<name>) [xxxx/xxxx]: lazgram/laravel-sr-command ← ベンダー名/パッケージ名の形で入力
Description []: xxxxx ← パッケージの説明文を入力
Author [xxxxx <xxxx@xxxx.com>, n to skip]] xxxx <xxxxx.xxxxx.com> ← 作成者に関する情報を入力(名前 <メールアドレス>)
Minimum Stability []: ← パッケージの「安定性(開発段階)」を指定するが通常は空でOK
Package Type (e.g. library, project, metapackage, composer-plugin) []: library ← パッケージの種類
License []: MIT ← ライセンスの種類、通常はMITでOK

Define your dependencies.

Would you like to define your dependencies (require) interactively [yes]? ← 本番環境で必要なパッケージ
Search for a package: 
Would you like to define your dev dependencies (require-dev) interactively [yes]? ← 開発環境で必要なパッケージ
Search for a package: 
Add PSR-4 autoload mapping? Maps namespace "XXXXX\XXXXX" to the entered relative path. [src/, n to skip]: ← PSR-4オートロードの設定、通常はsrc/ディレクトリ指定

{
    "name": "lazgram/laravel-sr-command",
    "autoload": {
        "psr-4": {
            "lazgram\\laravel-sr-command\\": "src/"
        }
    },
    "authors": [
        {
            "name": "Shunsuke Hasegawa",
            "email": "xxxxx@xxxxx.com"
        }
    ],
    "require": {}
}

Do you confirm generation [yes]? yes ← yesで答えるとcomposer.jsonが生成される
Generating autoload files
Generated autoload files
PSR-4 autoloading configured. Use "namespace Hasegawa\Example;" in src/
Include the Composer autoloader with: require 'vendor/autoload.php';

なお、composer.jsonが作成された後は、ファイルを直接編集してもいいので
一部の項目はあとから入力するならスキップしてもいいです。

パッケージのメインとなるソースコードを追加していく

準備が出来たら、実際にLaravelで拡張したい機能のソースコードを追加していきます。

前回の記事で作っていたファイルを以下のように配置します。

[laravel]
├ ...
├ packages
│ └ [vendor_name]
│   └ [package_name]
│     ├ src ← Laravelのapp以下にあるべきファイルはsrc以下に追加
│     │ ├ Console
│     │ │ └ Commands
│     │ │   ├ RepositoryInterfaceMakeCommand.php
│     │ │   ├ RepositoryMakeCommand.php
│     │ │   └ ServiceMakeCommand.php
│     │ └ composer.json
│     └ stubs ← stubsフォルダを追加
│       ├ repository.interface.stub
│       ├ repository.stub
│       └ service.stub
└ ...

パッケージ内のsrcフォルダ以下のフォルダ構成は
Laravelのapp以下のフォルダ構成に合わせるような形で配置します。

一から作り込む場合はいいのですが、私の場合は前回の記事で書いたファイルをそのままコピーしたので
同じようにコピーして作った場合は、各ファイルのnamespaceはきちんと変えるようにしましょう。

ServiceProviderを追加する

このままではまだパッケージ化してcomposerでインストールしても動きません。
なので、ServiceProviderを追加して、Laravelに認識されるようにします。

<?php

namespace Lazgram\LaravelSrCommand;

use Illuminate\Support\ServiceProvider;

class SrCommandServiceProvider extends ServiceProvider
{
    /**
     * Register services.
     *
     * @return void
     */
    public function register()
    {
        $this->commands([
            Console\Commands\ServiceMakeCommand::class,
            Console\Commands\RepositoryInterfaceMakeCommand::class,
            Console\Commands\RepositoryMakeCommand::class,
        ]);
    }

    /**
     * Bootstrap services.
     *
     * @return void
     */
    public function boot()
    {
        $this->publishes([
            __DIR__ . '/../stubs' => base_path('stubs'),
        ], 'laravel-sr-command-stubs');
    }
}

今回はartisan用のコマンドの追加、およびスタブファイルをvendor:publishに対応させたかったので
上記のような形で記載しいました。

README.mdを記載する

地味に忘れてはいけないのは、README.mdの内容です。
README.mdに記載された内容はPackagistなどで公開した際に
パッケージのトップ画面に表示される内容でもあるため
利用者に対して、どのようなパッケージであるのかやインストール方法、使い方などを説明して上げる必要があります。
なので、なるべく丁寧に書きましょう。

GitHubにプッシュする

ここまでコードの準備は完了です。
次にGitHubにコードをプッシュする必要があるので
git initしてからGitHubでリポジトリを用意してプッシュします。

また、Composerパッケージとして公開するにはリリースバージョンも必要になってくるので
git tagコマンドを使ってバージョンの設定もしておきます。

$ git tag 1.0.0
$ git push origin --tag

いよいよ公開

まずはPackagistに登録する

すでにPackagistに登録したことがある方は不要ですが
まだの方はPackagistに登録をしましょう。

新規登録する際はGitHubアカウントでサインアップする方法がありますので
この方法だと、あとからGitHubにプッシュしたリポジトリを公開するのに連携が楽です。

パッケージを登録・公開する

Packagistの登録が完了したら、いよいよパッケージの公開です。
メニューに「Submit」という項目があるので、そのページを開きます。

開いたら、上記のようにRepository URLを入力する欄がありますので
パッケージのGitHubリポジトリのURLを入力してCheckボタンを押下します。

これで公開は完了です。

さっそくインストールしてみる

無事公開されていれば、他のLaravelのプロジェクトなどでcomposer経由でインストール可能となります。

$ composer require xxxx/xxxxx

念の為、ちゃんと動くかは確認しておいたほうが良いかもですね。

さいごに

いかがでしたでしょうか?
今回は自作したパッケージを公開する方法について書きましたが
社内プロジェクトなどで、中には公開したくはないけど、composerで管理できるようにしたいというケースもあるかと思います。
それについては、また別の機会に書ければと思いますが
パッケージ化することで面倒な手間を減らすことも出来ますので
みなさんも機会があれば、ぜひ活用してみてください。

それでは、今回はこのへんで。

dot
dot
PAGETOP