Pythonで作ったCLIツールは
PyPI
を通して配布することが出来ますが
必要なPythonのバージョンがあったり、依存パッケージを色々インストールしないといけないとなると
pip
でグローバルな環境に入れるのもちょっと微妙。
仮想環境を作ってそこで管理すれば他のライブラリ等を気にせず使えますが、 Homebrewを使うとその辺が簡単に出来ます。
HomebrewでのPythonツール用のFormulaの作成
以下にPythonのFormulaに関するドキュメントがあります。
ここだと色々と思想的なものが書かれているのとちょっと古い?方法が書かれていますが、
以下ではPyPIで配布されているパッケージのFormulaを作る際に実際にやりやすい手順を紹介。
brew create
まず、テンプレートを作るため、brew create
コマンドを使います。
ただ、これ今ちょっと使いづらくなっています。 デフォルトではHomebrew-coreのTapの中に作る設定になっていますが 最近API経由のインストールがHomebrewのデフォルトになっているので そのTapが存在しないため
1
|
|
といったエラーが出てしまいます。
なので適当なTapを用意して上げる必要があります。 homebrew-core を入れるでも良いのですが重いので適当な別のものを入れたほうが楽です。
もし適当なものがなければhomebrew-testtapという名前の空レポジトリをGitHubに作って
1
|
|
とかで入れればOK 1。
rcmdnk/homebrew-testtap が空Tapなので、これを使っても良いです。
ローカルなtapを持ったらbrew create
を実行します。
1
|
|
brew create
は--python
, --ruby
, --go
など各言語の独自環境やビルド用の
templateを作るためのオプションが用意されているのでこれを使います。
python用FormulaではURL
にはPyPIでのSourceの圧縮ファイルを指定します。
以下では cocoro というCLIツールで作ってみます。
PyPIのcocoroのファイルをダウンロード のページに有る最新のtar.gzのファイルのURLを取得。
これを使って以下のようなコマンドを実行。
--set-name
オプションはつけない場合はデフォルトの値がcocoro-0.1.4
とバージョンの付いた名前になって、
これを変更するかどうか聞かれるプロンプトが出ます。
バージョンは外さないと行けないので最初から--set-name
で指定しています。
--set-license
でのライセンス指定などは後からエディタで変更してもOK。
1
|
|
これで以下のようなファイルができ、それをエディタで開いた状態になります。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 |
|
ファイルはtapの中の/opt/homebrew/Library/Taps/rcmdnk/homebrew-testtap/cocoro.rb (環境によって違う、$(brew --repo rcmdnk/testtap)/cocoro.rb
)にあります。
このファイルは$ brew edit cocoro
とすることでもエディタで開くことが出来ます。
URL
で指定したものがurl
に入り、そのsha256
の値は自動的に取得されています。
依存するHomebrewのパッケージとしてはpythonがあります。
もし(Homebrewで入れられる)特定のPythonのバージョンを使いたい場合は
[email protected]
などに変更します。
Homebrew-coreに入れる場合など、test
をきちんと定義したい場合はpython
というエイリアスだと
1 2 |
|
といったエラーになってしまうので[email protected]
などきちんとバージョン含めたパッケージ名にする必要があります。
pyproject.tomlやsetup.pyに書かれた依存関係のあるパッケージに関してはすべて
resource
として追加されています。
きちんと定義されたパッケージであればもうこれでOKで、後は
desc
に適当な紹介文を、homepage
にPyPIのパッケージのページかGitHubのページ、
もしくはちゃんとしたHomepageがあればそれを記入しておけばとりあえず完成です。
もし依存関係の記述が不十分で他に必要なパッケージがある場合には
自分でそのパッケージのURLとハッシュ値を調べてresource
に追加する必要があります。
Formulaが出来たら
1
|
|
としてインストールできます。
インストールされたもの
1 2 |
|
こんな感じでコマンドがHomebrewのbinディレクトリにインストールされています(これ自体はシンボリックリンク)。
(opt~の部分は環境によって違う、$(brew --prefix)/bin/cocoro
)
中身は
1 2 3 4 5 6 7 8 |
|
となっていて、これは通常通りpip install
で入れた場合と内容は基本的に同じです。
ただ、Shebangを見てみると
1
|
|
となっていて、このpythonは /opt/homebrew/Cellar/cocoro/0.1.4/libexec/に作られたPythonの仮想環境のものになっています。
この仮想環境を直接使うことは通常はないかと思いますが、
1
|
|
で入ることも出来ます。
こんな感じで各Fomrula毎に仮想環境を用意してその中に必要なパッケージを入れて実行しているので 他のPython環境と競合せずに管理できます。
ちょっと注意が必要なのはHomebrewでインストールしたPythonのpip
コマンドを使って同じツールをインストールすると
同じく/opt/homebrew/bin/cocoroとしてインストールされるので
競合してしまいます。
後からbrew
で入れると
1
|
|
みたいに出てbinへの実行ファイルのリンクが作れません。
仮想環境やリンク元のファイルは出来ているので、pip uninstall cocoro
としてからbrew link cocoro
するか
brew link --overwrite cocoro
で矯正上書きしてしまうかで置き直せます。
インストール時間
上のcocoroはそれほど依存パッケージを持っていませんが、
それでもbrew install
で入れると普通にpip install
するよりも結構時間がかかりました。
pip
なら1,2秒のところ(空の仮想環境に入れてみるテスト)、
brew install
だと5分位かかりました。
1
|
|
の部分がやけに時間かかったみたいで、--no-binary
でビルドするようになってるのでパッケージによっては時間がかかるものが出てきます。
他のものはそこまで時間はかかってないので殆どの場合ではbrew
でも数秒から数十秒程度で終わると思います。
(仮想環境作ったりパッケージビルドしたりするので多少は時間がかかる。)
単純に仮想環境でpip install <package>==<version
>で依存関係も含めて全部入れてくれるような
オプションもあっても良いな、とは思います。
それだとインストールが速いのと、Formulaもurl
の代わりにcocoro
などを指定するpackage
、
それとバージョン指定のversion
を書くだけでシンプルになってresorce
も要らなく出来ます。
ただ、Python for Formula Authors — Homebrew Documentation を見るとそういうのは思想に反する感じではありますが。
パッケージのアップデート
上にあるように各パッケージはすべてバージョン指定された形でそのソースファイルのURLとハッシュが指定されていますが、 これを手でアップデートするのはかなり大変です。
そんなときのためのコマンドがbrew update-python-resources
。
これ使うにあたって
pipgrip
というツールが必要なのでこれを別途
1
|
|
としてインストールしておく必要があります。
これで
1
|
|
とすると各パッケージのバージョンの再確認を行ってくれます。
このツールを使うに、
これはHomebrewのTapの中にないものでも直接適用することが出来て、 カレントディレクトリにcocoro.rbがあれば
1
|
|
とすればそのファイルをアップデートしてくれます。
これを使えば、
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 |
|
みたいな感じの最小限のformulaを書いてbrew update-python-resources
を適用することでもFormulaを完成させられます。
もとの cocoro-0.1.4.tar.gzのハッシュ値は自分で求めないといけませんが、個人的には 以下のようなスクリプトを使ってURL先のハッシュ値を取得できるようにしています。
配布
出来たら
$(brew --repo rcmdnk/testtap)/cocoro.rb
をコピーして、配布用のhomebrew-mypackages
みたいなtapレポジトリに追加してGitHubに上げれば
1
|
|
でインストールできるようになります。
まとめ
pip
だけで配布できるものをわざわざHomebrewを使って、
ということで配布側にはちょっと手間がかかりますが、
ユーザー側としてはHomebrewさえ使っていれば
既存のPython環境を汚さずに、また、Pythonのバージョンの指定も含めて
インストールするように出来るのは結構便利ではないかな、と。
特にアップデートがあった際にpip
だと直接そのパッケージをアップデートするコマンドを打たないといけませんが、
Homebrewであれば定期的にbrew update && brew upgrade
とかしておけば
他のパッケージ含めてアップデートしてくれるので楽です。
また、PyPIに公開されているPythonのコマンドラインツールであればどれでも同じことが出来るので、 自分のパッケージでなくても自分の管理用にFormulaを作ってHomebrewで管理できるようにする、という手段もありかと思います。
-
warning: You appear to have cloned an empty repository.
という注意が出ますがbrew create
でファイルを追加テストする分には 問題なく動きます。 ↩