bundler
新人プログラマ応援
Pipenv

pipenvとかBundler以前に知っておいて欲しいこと

  • gembundle ってどっちを使えばいいんですか?
  • pipenv!? Pythonには何種類のパッケージングツールがあるんですか!!
  • Gemfile.lock ってコミットしないんですよね!?偉い人がそう言ってました!!

落ち着いてください。個別ツールの話をする前に、まずこれを覚えておいてください。

ライブラリアプリケーション かで、依存ライブラリの管理の仕方・バージョンの指定方法が違う

これを理解すれば、自然とツールの使い方も解るはずです。

「プロジェクト」には2種類ある。依存ライブラリにも2種類ある

RubyやPython(や他の言語)のプロジェクトは、大きく2種類に分けられます。

  • ライブラリ
    • 他のライブラリやアプリケーションに組み込まれて使うもの
  • アプリケーション
    • 直接使うことができるもの。他のプロジェクトに組み込まれることは基本的に無い

また、プロジェクトが依存しているライブラリも2種類に分けられます。

  • 直接依存
    • プロジェクトで利用しているライブラリのこと
  • 間接依存
    • 直接依存のライブラリが利用している別のライブラリのこと

※「直接依存」「間接依存」は一般的な用語ではありません(通じなくはないと思いますが)。

ライブラリのバージョン指定戦略

ライブラリでは、できるだけ緩くバージョンを指定します。

「このライブラリは、pandas 0.22.0 をインストールした環境でしか動作しません」
なんて厳しい制約があるライブラリは使ってもらえません。

なので、ライブラリでは「直接依存」についてのみバージョンを指定し、間接依存については指定しません。

また直接依存についても、バージョンは特定の1バージョンではなく、範囲で指定します(pandas >= 0.22.0, < 1のように)。

バージョンの下限はテストして動作が確認された最低バージョンを指定します。

一方、最大バージョンは微妙な問題があります。というのは、

バージョンアップで互換性が壊すライブラリが、たまにあるからです。動作を保証したいなら、上限も指定しなければなりませんが、厳格すぎる指定をすると利用側に無用な制約を与えてしまいます。本来マイナーバージョン間で互換性は保たれるはずなので、numpy ">= 1.14.3", "==1.*" のように、メジャーバージョンレベルで指定するのが穏当でしょう。

アプリケーションのバージョン指定戦略

アプリケーションでは、どの環境でも同じバージョンが使われるようにしたいはずです。さもないと・・・

「開発環境では動くのに、本番環境では動かない」
「俺のマシンでは動くのに、あいつのマシンでは動かない」
ということになります。

そのため、直接依存も間接依存も全て指定します。また、バージョンも厳密に(== x.y.z の形で)指定します。

とはいえ、全部のバージョンを書き下して管理するのは大変なので、RubyやPythonでは2ファイルに分けて管理しています。

  • 直接依存しているライブラリを指定するファイル
    • 手動で管理する
    • Gemfile や Pipfile
  • 全部のバージョン
    • 自動で更新できる。手動編集は基本的にしない
    • Gemfile.lockやPipfile.lock

「プロジェクトには2種類ある」と言ったな、あれは嘘だ

なお、困ったことにライブラリともアプリケーションとも言い切れないプロジェクトがあります。

例えば、curl の代替コマンドのHTTPie は、使い方の観点では明らかにアプリケーションです。しかし、ライブラリであるかのように配布されているので(PyPIで配布され、pip install httpie でインストールできる1)、依存ライブラリは、setup.py に指定しています。

困ったもんです。

おそらく、HTTPieの場合は、そもそも配布方法が間違いなのです。pip install httpie でインストールするとシステムのPythonを変更することになるので2、他のアプリケーションに影響を与える恐れがあります。

a. システムのPythonとは別にPythonインタープリタをビルドし、そこにインストールする
b. 依存ライブラリも全て含んだ、単一のバイナリとして配布する(Go等では可能。Pythonでもツールを使えばできるかも)

本来、このような方法をとるべきなのでしょう。

参考


  1. HTTPieはbrewやaptでもインストールすることができ、その場合は厳密にバージョン指定された依存ライブラリがインストールされます(「アプリケーション」的な戦略)。なので、ここで「困った」例に httpie を挙げるのは濡れ衣です。 

  2. pyenv などで複数のPythonがインストールされている場合は、システムのPythonとは限りませんが。