自作PythonCLIアプリケーションをHomebrewで公開する

# なんでか

**pipでインストールする時**

```shell
$ pyenv install 3.9.0
$ pyenv virtualenv 3.9.0 venv4myapp
$ pyenv activate venv4myapp
(venv4myapp) $ pip install myapp
(venv4myapp) $ myapp --option veryBadMan
(venv4myapp) $ deactivate
```

**Homebrewでインストールする場合**

```shell
$ brew tap SoHappyMan/myapp
$ brew install myapp
$ myapp --option veryHappyHeyMaaaaaan
```

依存ライブラリがある場合のPythonライブラリのHomebrewでの公開方法です。リンク集。

Homebrewでインストールするには、Formulaと呼ばれる「インストールまでの手順」を記載したRubyスクリプトを書く必要があります。
基本的にはその中で、依存ライブラリをインストールする必要があります。


## Pyinstallerを使う場合

Homebrewの依存ライブラリインストールはそれなりに面倒なので、もう単一ファイル化してしまいましょうよ、というパターン。簡単だけど、遅かった。これだと、依存ライブラリのインストールは不要。
こちらの記事が詳しいです。

[Python製自作ツールをHomebrewでインストール可能にする](https://qiita.com/Scstechr/items/db865d627272d873d9f0)

Formulaは、こんな感じ。

```ruby
class Mlkokuji < Formula
  desc "国交省のWebサイトから告示を検索し表示するコマンドラインスクリプト⛱⛱⛱"
  homepage "https://github.com/ryuhey0123/mlit-kokuji"
  url "https://github.com/ryuhey0123/mlit-kokuji/releases/download/v1.1/mlkokuji-v1.1.tar.gz"
  sha256 "78380cc079a812cd359dbfb27b7af40f15792d27b090858df21a71d95d9a09dd"
  license "MIT"

  def install
    bin.install 'mlkokuji'
  end

end
```

こんな感じ。上記の例だと、`mlkokuji`という単一ファイルを作っておいて、それを`bin`にインストールする、ということになります。

## Homebrew用の仮想環境に依存ライブラリをインストール

どうしてPythonがHomebrewで動くのか、依存ライブラリはどこにインストールしているのか不思議でしたが、Homebrewには専用の仮想環境があるようで、そこに依存ライブラリをインストールするようです。
こちらの記事が詳しいです。

[HomebrewでPythonアプリのFormulaを作る時に気をつけること](https://qiita.com/tomoyanonymous/items/7a1dd4f8eba809475a24)

Formulaは、こんな感じ。

```ruby
class Pdf2doc < Formula
  include Language::Python::Virtualenv

  desc "Add page number to some PDF files and merge it → PERFECT DOCUMENT! ⭐️"
  homepage "https://github.com/ryuhey0123/pdf2doc"
  url "https://github.com/ryuhey0123/pdf2doc/archive/v1.2.0.tar.gz"
  sha256 "6dc9f92b1a0b43d05957d8a8b6c59d52d22808029c826cf60ace20e06d991d52"
  license "MIT"

  depends_on "python@3.9"

  resource "click" do
    url "https://files.pythonhosted.org/packages/27/6f/be940c8b1f1d69daceeb0032fee6c34d7bd70e3e649ccac0951500b4720e/click-7.1.2.tar.gz"
    sha256 "d2b5255c7c6349bc1bd1e59e08cd12acbbd63ce649f2588755783aa94dfb6b1a"
  end

  resource "crayons" do
    url "https://files.pythonhosted.org/packages/b8/6b/12a1dea724c82f1c19f410365d3e25356625b48e8009a7c3c9ec4c42488d/crayons-0.4.0.tar.gz"
    sha256 "bd33b7547800f2cfbd26b38431f9e64b487a7de74a947b0fafc89b45a601813f"
  end

  resource "colorama" do
    url "https://files.pythonhosted.org/packages/1f/bb/5d3246097ab77fa083a61bd8d3d527b7ae063c7d8e8671b1cf8c4ec10cbe/colorama-0.4.4.tar.gz"
    sha256 "5941b2b48a20143d2267e95b1c2a7603ce057ee39fd88e7329b0c292aa16869b"
  end

  resource "fpdf" do
    url "https://files.pythonhosted.org/packages/37/c6/608a9e6c172bf9124aa687ec8b9f0e8e5d697d59a5f4fad0e2d5ec2a7556/fpdf-1.7.2.tar.gz"
    sha256 "125840783289e7d12552b1e86ab692c37322e7a65b96a99e0ea86cca041b6779"
  end

  resource "PyPDF2" do
    url "https://files.pythonhosted.org/packages/b4/01/68fcc0d43daf4c6bdbc6b33cc3f77bda531c86b174cac56ef0ffdb96faab/PyPDF2-1.26.0.tar.gz"
    sha256 "e28f902f2f0a1603ea95ebe21dff311ef09be3d0f0ef29a3e44a932729564385"
  end

  resource "Send2Trash" do
    url "https://files.pythonhosted.org/packages/13/2e/ea40de0304bb1dc4eb309de90aeec39871b9b7c4bd30f1a3cdcb3496f5c0/Send2Trash-1.5.0.tar.gz"
    sha256 "60001cc07d707fe247c94f74ca6ac0d3255aabcb930529690897ca2a39db28b2"
  end

  resource "yaspin" do
    url "https://files.pythonhosted.org/packages/f8/6d/7d5d081db3f399f5e345ad5107fa015f84a0c0dd62f1c9deb277ba83774e/yaspin-1.2.0.tar.gz"
    sha256 "72e9cdbc0e797ef886c373fef2bcd6526a704a470696f9d78d0bb27951fe659a"
  end

  def install
    virtualenv_install_with_resources
  end

end
```

注意点として、**依存ライブラリの依存ライブラリは自動でインストールしてくれない**ので、ここに書く必要があります。上記の例だと、CLIの出力に色をつけてくれるライブラリ`crayons`は、`colorama`というライブラリに依存しています。`pip install`だとこの辺はよしなにやってくれますが、ここは手動です。


`virtualenv_install_with_resources`は、`setup.py`を探して実行する関数を含んでいるので、pypiに公開しなくても**`setup.py`が必要！！**


## そもそもライブラリに他ライブラリを埋め込んでしまう

これは`pipenv`のリポジトリを見ながら気づきました。それなりに依存パッケージはあるはずなのに、Formulaがシンプルだった。バージョン依存がないようなライブラリは、リポジトリに組み込んでいるのかな？

Github: [pipenv/pipenv/vendor/](https://github.com/pypa/pipenv/tree/master/pipenv/vendor)


## 感想

PipFileから自動的にやってくれるヤツないかな〜〜
Pipenv最高なんだよな〜〜