自作ライブラリ作成の初心者がGitHubとComposerでソースをパッケージ化する

## はじめに

自作していたライブラリを

**”GitHubとComposerを使ってダウンロードできるようにしておけばカッコいいし便利そう”**

と思って

**”Composerって依存関係をJSONで書いておけば簡単にダウンロードできるんだったよねー”**

ってくらいの気持ちでComposerの初心者がやろうとした結果かなりハマってしまったので（色んな意味で）メモを残しておきます。
また、ハマりポイント（自分の場合ですが）を補足として入れておいたので参考になればと思います。

以下では **”ライブラリ公開側の設定”** と **”ライブラリ利用側の設定”** に分けて話を進めます。

:::note info
本記事ではPackagistへの登録をしなくても可能な方法をご紹介しています。
:::

## 環境

<dl>
    <dt>プラットフォーム</dt>
    <dd>Windows10</dd>
    <dt>Composer</dt>
    <dd>v2.6.5</dd>
    <dt>Git</dt>
    <dd>v2.31.1</dd>
</dl>

## 下準備

Composerを使う前にPHP環境を入れておく必要があります。
自分の場合はXamppを使っているので下記サイトを参考にしました。
Composerのインストール方法も掲載されています。

https://qiita.com/mitashun/items/ced252681edf2b01cd32/

クライアントサイドで使用するためのGitもインストールしておく必要があります。
個人的にはコマンド派なので下記のサイトを参考にしました。

https://sukkiri.jp/technologies/devtools/git/git_win.html

Gitが使えるようになったらGitHubにアカウント登録しておく必要があります。

https://docs.github.com/ja/get-started/start-your-journey/creating-an-account-on-github/

## ライブラリ公開側の設定

### composer.jsonを作る

ライブラリを置きたいフォルダ`dev-test（例）`に移動してからコマンドラインで初期設定を行います。
`composer init`を使えばjsonファイルをよしなに作ってくれます。

```
> composer init
```

> ［jsonファイルの作成開始］
> 実行するとLinuxアプリをインストールする時のように対話形式で聞いてきてくれます。

```
> Package name (<vendor>/<name>) [vendor-example/dev-test]:
```

> ［パッケージ名の設定］
> []内のデフォルトのままでいいのでそのままリターン。

:::note warn
ハマりポイント①
composerはパッケージ名を元に検索しているので、ここを間違えるとそもそも認識してくれません。使う側の事を意識してわかり易い名前にしておきましょう。
パッケージ名は`ベンダー名（=GitHubユーザー名）/リポジトリ名`の構成になります。
例えばGitHubユーザー名が`user`でリポジトリ名が`dev-repo`の場合は`user/dev-repo`と書き替えてください。
:::

```
> Description []:vendor-example sample
```

> ［パッケージ説明文の設定］
> 今回は`vendor-example sample`と入力。

```
> Author [vendor-example <vendor-example@example.com>, n to skip]:
```

> ［著者の情報設定］
> デフォルトのままでいいのでリターン。

```
> Minimum Stability []:dev
```

> ［安定性の設定］`dev`や`stable`等
開発中のライブラリなので`dev`と入力。

```
> Package Type (e.g. library, project, metapackage, composer-plugin) []:library
```

> ［パッケージタイプの設定］
ライブラリなので`library`と入力。

```
> License []:MIT
```

> ［ライセンスタイプの設定］
> 一番規制が緩そうな`MIT`を入力。

:::note info
`MIT`ライセンスについて詳しく知りたい方は下記ブログが参考になると思います。
:::

https://yamory.io/blog/about-mit-License/

```
> Would you like to define your dependencies (require) interactively [yes]?no
```

> ［依存モジュールの設定］
> 必要ないので`no`を入力。

```
> Would you like to define your dev dependencies (require-dev) interactively [yes]? no
```

> ［開発用の依存モジュールの設定］
> こちらも必要ないので`no`を入力。

```
> Add PSR-4 autoload mapping? Maps namespace "VendorExample\DevTest" to the entered relative path. [src/, n to skip]:
```

> ［ソース配置の相対位置の設定］（今回は`VendorExample\DevTest`からの相対位置）
> デフォルトのままでいいのでそのままリターン。

```
{
    "name": "vendor-example/dev-test",
    "description": "vendor-example sample",
    "type": "library",
    "license": "MIT",
    "autoload": {
        "psr-4": {
            "VendorExample\\DevTest\\": "src/"
        }
    },
    "authors": [
        {
            "name": "author-example",
            "email": "author-example@example.jp"
        }
    ],
    "minimum-stability": "dev",
    "require": {}
}

> Do you confirm generation [yes]?
```

> ［最終確認］
> そのままで問題ないのでリターン。

同フォルダに上記で入力した内容が`composer.json`に生成されているはずです。
そして下記の`src`フォルダと`vendor`フォルダも同時に生成されます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3619905/60be2fd6-cf57-2886-ee59-b66d5f773862.png)

以上で初回の`composer.json`の作成は完了です。


### GitHubのリポジトリを初期化する

下記日本語サイトでリポジトリを作成する手順が書かれています。

https://docs.github.com/ja/repositories/creating-and-managing-repositories/quickstart-for-repositories/

:::note info
リポジトリ作成時にオプションを選択すればREADMEやLICENSEのファイルも作成してくれるので作っておいた方がいいでしょう。
READMEの内容は何でも構いませんがLICENSEファイルは選択したライセンスの種類によって内容を書き替えてくれるので便利です。
:::
リポジトリの作成が終わったら下記コマンドを実行してGitを使えるようにします。


```
> git init
```

> gitを初期化してコマンドが使えるようにします。

```
> git config --local user.name vendor-example
```

> gitのユーザー名を設定する。

```
> git config --local user.email vendor-example@example.com
```

> ユーザーのEMailを設定する。

:::note info
`git config`系のコマンドは設定しなくても動作しますが、大人数による開発ではコミット時の履歴に設定したユーザー名がちゃんと残るので、後になって修正した内容を誰に聞けばいいのかわからないといった状況は防げるでしょう。
:::

```
> git branch -M main
```

> メインブランチを`main`にします。

```
> git remote add origin https://github.com/vendor-example/dev-test.git
```

> リモートリポジトリを設定します。
（URLはGitHubのリポジトリのページからコピーできます）

```
> git pull origin main
```

> リモートリポジトリから最新のソースをプルします。

```
> git add composer.json
```

> 先ほど作成したcomposer.jsonをcommitエントリに加えます。

```
> git commit -m "first commit"
```

> `first commit`というコメントで最初のコミットを実行します。

```
> git push -u origin main
```

> リモートリポジトリへコミットをプッシュします。

これで **”ライブラリ公開側の設定”** は完了です。

## ライブラリ利用側の設定

### composer.jsonを作る

ライブラリを利用したいフォルダ`use-test（例）`に移動してからコマンドラインで初期設定を行います。

```
> composer init
```

> **”ライブラリ公開側の設定”** で行った操作と同じ要領で進めます。

```
> Package name (<vendor>/<name>) [use-example/use-test]:
> Description []:use library
> Author [use-example <use-example@example.com>, n to skip]:
> Minimum Stability []:dev
> Package Type (e.g. library, project, metapackage, composer-plugin) []:project
> License []:MIT
> Would you like to define your dependencies (require) interactively [yes]?no
> Would you like to define your dev dependencies (require-dev) interactively [yes]? no
> Add PSR-4 autoload mapping? Maps namespace "UseExample\UseTest" to the entered relative path. [src/, n to skip]:
```

> 対話形式の設問に全て答えてcomposer.jsonを作成します。


```
> composer config repositories.vendor-example/dev-test vcs https://github.com/vendor-example/dev-test.git
```

> ダウンロードしたいパッケージのリポジトリを設定します。
> `repositories`の後ろの`vendor-example/dev-test`はパッケージ名になります。

:::note warn
ハマりポイント②
この時パッケージ名`vendor-example/dev-test`の部分を間違えないようにしないと認識してくれませんので注意が必要です。
:::

```
> composer require vendor-example/dev-test:dev-main
```

> パッケージをダウンロード（`composer install`でも可能です）。
> `vendor-example/dev-test`の部分はcomposer.json内`repositories`項目のパッケージ名になります。
> `dev-main`はmainブランチの事を表していて同ブランチ内の最新をとってきてくれます。

ここまで実行すると下記のようなファイルが出来上がります。

```composer.json
{
    "name": "use-example/use-test",
    "description": "use library",
    "type": "project",
    "license": "MIT",
    "autoload": {
        "psr-4": {
            "UseExample\\UseTest\\": "src/"
        }
    },
    "authors": [
        {
            "name": "use-example",
            "email": "use-example@example.com"
        }
    ],
    "minimum-stability": "dev",
    "require": {
        "vendor-example/dev-test": "dev-main"
    },
    "repositories": {
        "vendor-example/dev-test": {
            "type": "vcs",
            "url": "https://github.com/vendor-example/dev-test.git"
        }
    }
}
```

`composer config`を実行するためにはあらかじめcomposer.jsonを作っておく必要があるので、今回は`composer init`でファイルを１から作りましたが他のファイルを複製して持ってきても構いません。
極端に言えば必要な部分は`repositories`の項目だけなので他の項目はなくても動作します。

ダウンロードが完了すれば下記のように`vendor/vendor-example/dev-test/src`配下（`vendor/パッケージ名/src`の形式）にライブラリが設置されます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3619905/fb045fd1-f32f-54a7-15b8-18b348f827e2.png)

あとはライブラリ修正⇒コミット⇒プッシュするたびに、使う側で

```
> composer require vendor-example/dev-test:dev-main
```

を実行すると最新のソースがダウンロードされます。

## バージョンを発行する

`v1.0.0`などの形式でバージョンを指定してダウンロードする方法です。
ライブラリ公開側で最新のソースをプッシュした後はGitHub上でバージョンをつけましょう。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3619905/1de372e4-ab9a-982d-7401-c2dfe534e73a.png)

> `Create a new release`というリンクをクリック

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3619905/7f1a5304-da4c-7247-6d38-7eecd836c3a2.png)

> リリース内容の編集画面が開きます

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3619905/2c8ed0fe-98ed-53ef-2857-0605fac49130.png)

> `Choose a tag`というプルダウンをクリックしてバージョンを入力してから`+ Create new tag`をクリック

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3619905/3c568989-e022-56da-f14c-7eb7c8abafda.png)

> タイトルと説明文を入力してから`Publish release`ボタンをクリック

あとは下記のように`v0.0.0`というバージョンを指定してコマンドを実行するとバージョンに対応した内容がダウンロードできます。

```
> composer require vendor-example/dev-test:v0.0.0
```

下記のようにgitコマンドでタグを付けてからバージョン名でプッシュする方法もあります。

```
> git tag v0.0.0
> git push origin v0.0.0
```

:::note info
この場合は別のブランチ名でプッシュする事になるので`dev-main`でダウンロードしようとしても最新のソースは取得できなくなるので注意が必要です。
:::

## まとめ

素人考えですがComposerの存在は知っていたけど公開側にもcomposer.jsonが必要だという事を知らなかったので最初はかなり苦労しました。
調べていくうちにGitHubにも多くの機能やサービスの提供がある事にも改めて驚かされました。

というわけで今回のまとめは次の通り。

・composer.jsonはソースの公開者側にも利用者側にも必要だよ
・バージョン管理（v1.0.0などの指定でダウンロード可能）も容易にできるよ
・Packagistへ登録しなくても使えるよ