PipenvからPoetryへのお引越しツール作った
動機
1/13にPoetry 0.12.11 がリリースされました。
それに伴い、poetry init
で会話形式でいろいろ設定していく際に依存パッケージを事前に検索して記述する機能のバグが修正されました。
$ poetry init This command will guide you through creating your pyproject.toml config. Package name [foo]: Version [0.1.0]: Description []: Author [kk6 <hiro.ashiya@gmail.com>, n to skip]: License []: Compatible Python versions [^3.7]: Would you like to define your dependencies (require) interactively? (yes/no) [yes] yes Search for package:
ここのことです。
前のバージョンだと検索するとLegacyRipositoryなんちゃらってエラーで落ちてたので使わずスキップするしかなかったんですが、直ったとのことなのでさっそく試してみると…
Search for package: django Found 100 packages matching django Enter package # to add, or the complete package name if it is not listed: [ 0] django-bagou [ 1] django-maro [ 2] django-ide [ 3] django-hooked [ 4] django-six [ 5] django-umanage (中略) [95] django-bittersweet [96] django-perm [97] django-simplemde [98] django-rosetta [99] django-pjax >
ああ、うん…。そっか、そういうやつなんだ…。
引っ越しツール
これだとPipfile見ながらひとつひとつ poetry add django
とかしていくのとそんな大差ない気がするのでPipfileパースしていい感じに poetry init
を実行してくれるツール作りました。
たぶんMac以外だと全然動かなかったりしそうなのでPyPIには登録してません。名前もイマイチ思いつかなかくて長ったらしいしかえるかもしれない(変えた*1)ので、ひとまず個人的に使うだけのつもりですが、それでも試したい人いたらどうぞ。
PyPI に登録しました。Mac以外だとまともに動かない気がするのには変わりないのであくまでアルファ版ということで。
概要
poetry init
コマンドは --dependency
と--dev-dependency
オプションにパッケージ名を与えることで、pyproject.toml
の [tool.poetry.dependencies]
および [tool.poetry.dev-dependencies]
セクションにいい感じに依存バージョン解決して書き込んでくれるという機能があります。
今回作ったツールはPipfileをパースしてこの--dependency/--dev-dependency
オプションの文字列を組み立ててくれるツールになってます。
インストール
READMEに二通りのインストール方法書いてますけど、今回はこっちの $HOME/.local/bin
以下にインストールする方法にしてみます。リポジトリに setup.py
がないので pip install --user git+https://github.com/kk6/poetrify.git
ではインストールできません。ごめんなさい。
PyPIに登録したのでpipでインストールできます。
$ pip install poetrify
引数無しで実行して以下のように出力されていればインストールできてます。
$ poetrify Poetrify version 0.2.0 USAGE poetrify [-h] [-q] [-v [<...>]] [-V] [--ansi] [--no-ansi] [-n] <command> [<arg1>] ... [<argN>] ARGUMENTS <command> The command to execute <arg> The arguments of the command GLOBAL OPTIONS -h (--help) Display this help message -q (--quiet) Do not output any message -v (--verbose) Increase the verbosity of messages: "-v" for normal output, "-vv" for more verbose output and "-vvv" for debug -V (--version) Display this application version --ansi Force ANSI output --no-ansi Disable ANSI output -n (--no-interaction) Do not ask any interactive question AVAILABLE COMMANDS completions Generate completion scripts for your shell. generate Generate pyproject.toml from Pipfile help Display the manual of a command
使い方
こんな感じのリポジトリがあるとします。実際は他にもソースコード等あると思いますけど。
$ tree . ├── LICENSE └── Pipfile 0 directories, 2 files
Pipfileの中身はこんな感じだとします。
[[source]] url = "https://pypi.python.org/simple" verify_ssl = true name = "pypi" [dev-packages] pytest = "*" pytest-cov = "*" "pytest-flake8" = "*" responses = "*" pytest-runner = "*" [packages] rauth = "*" requests = "*" requests-cache = "*" furl = "*" arrow = "*" pytest = "*" responses = "*" [requires] python_version = "3.7"
ツールの generate
コマンドを実行します。
$ poetrify generate Generated init command: poetry init --dependency=rauth --dependency=requests --dependency=requests-cache --dependency=furl --dependency=arrow --dependency=pytest --dependency=responses --dev-dependency=pytest --dev-dependency=pytest-cov --dev-dependency=pytest-flake8 --dev-dependency=responses --dev-dependency=pytest-runner --license=MIT Execute the above command. Also, the following output is due to Poetry. This command will guide you through creating your pyproject.toml config. Package name [foo]:
LICENSEファイルもパースしてライセンスを自動判定させてるので、これもちゃんと判定できてれば会話モードで License [MIT]:
みたいな感じでデフォルト値としてパースされたライセンス名が入ってるはずです。
init
コマンドを組み立てたらあとは雑に subprocess.run()
に投げてるだけです…。
あとは普通に poetry init
の会話モードでの入力となります。
Package name [foo]: Version [0.1.0]: Description []: Author [kk6 <hiro.ashiya@gmail.com>, n to skip]: License [MIT]: Compatible Python versions [^3.7]: Would you like to define your dependencies (require) interactively? (yes/no) [yes] Using version ^0.7.3 for rauth Using version ^2.21 for requests Using version ^0.4.13 for requests-cache Using version ^2.0 for furl Using version ^0.13.0 for arrow Using version ^4.1 for pytest Using version ^0.10.5 for responses Would you like to define your dev dependencies (require-dev) interactively (yes/no) [yes] Using version ^4.1 for pytest Using version ^2.6 for pytest-cov Using version ^1.0 for pytest-flake8 Using version ^0.10.5 for responses Using version ^4.2 for pytest-runner Generated file [tool.poetry] name = "foo" version = "0.1.0" description = "" authors = ["kk6 <hiro.ashiya@gmail.com>"] license = "MIT" [tool.poetry.dependencies] python = "^3.7" rauth = "^0.7.3" requests = "^2.21" requests-cache = "^0.4.13" furl = "^2.0" arrow = "^0.13.0" pytest = "^4.1" responses = "^0.10.5" [tool.poetry.dev-dependencies] pytest = "^4.1" pytest-cov = "^2.6" pytest-flake8 = "^1.0" responses = "^0.10.5" pytest-runner = "^4.2" [build-system] requires = ["poetry>=0.12"] build-backend = "poetry.masonry.api" Do you confirm generation? (yes/no) [yes]
基本的にgenerate
コマンド叩いた後はEnter押しっぱなしでいい感じにpyproject.toml
が生成されると思います。
既知の不具合
poetry init
自体がエラーで落ちるようなパッケージ名を与えると当然このツールも落ちます。
$ poetry init --dependency black This command will guide you through creating your pyproject.toml config. Package name [foo]: Version [0.1.0]: Description []: Author [kk6 <hiro.ashiya@gmail.com>, n to skip]: License []: Compatible Python versions [^3.7]: Would you like to define your dependencies (require) interactively? (yes/no) [yes] [ValueError] Could not find a matching version of package black init [--name NAME] [--description DESCRIPTION] [--author AUTHOR] [--dependency DEPENDENCY] [--dev-dependency DEV-DEPENDENCY] [-l|--license LICENSE]
たぶんpipenvで allow_prereleases = true
に設定してないとインストールできないようなパッケージはこうなります。
--dev-dependency=black:18.9b0
みたいにプレリリースなバージョン番号を指定できればちゃんとインストールできるんですけど、pipenvって pipenv install black --pre
とインストールしてもPipfileには black = "*"
って何でもかんでもアスタリスクにしてしまうのでバージョン番号がわからないんですよね…。Pipfile.lockのほうに書いてあるけど、こっちパースするの面倒くさそうなので気が向いたらやるかもって感じです。
なのでとりあえずPipfileから該当パッケージ行を削除してやり直して、うまくpyproject.tomlが生成できたら、あとから手動で poetry add --allow-prereleases black
みたいな感じで --allow-prereleases
オプション付きでインストールしてください。
*1:pipenv2poetry → poetrify