🐍

【Rust】Pythonライブラリを超簡単に作れるツールを作った

2024/09/20に公開1

はじめに

最近になってRustを勉強し始めて、何か作ってみようということでpyinitを開発しました。この記事では開発の背景や手こずった点を紹介していこうと思います。

https://github.com/t3tra-dev/pyinit

ツール自体のインストール方法や使い方についてはGitHubリポジトリのREADME.ja.mdを参照してください。

開発背景

Pythonのライブラリ開発において、プロジェクトの初期セットアップには多くの手順が伴います。README.mdsetup.py__init__.py、ライセンスファイルなど、プロジェクトごとにこれらのファイルを毎回作成するのは煩わしいです。

「このセットアップを自動化できないか?」という発想から、プロジェクトのテンプレートを自動生成できるCLIツール pyinit を開発することにしました。これにより、Pythonライブラリの開発がより迅速に、そして効率的に行えるようになります。

ちなみに名前のpyinitはお察しの通りPython + initです、安直ですね。

使用技術

Rust

CLIそのものの開発言語にはRustを使用しています。Rustを選んだ理由は、コンパイルされたCLIバイナリを生成でき、またクロスプラットフォーム対応が容易であることです。

GitHub Actions

継続的インテグレーション(CI)と継続的デリバリー(CD)のためのものです。v*.*.*の形のタグがプッシュされると自動的にLinux、macOS、Windows用のバイナリをビルドし、GitHubのリリースページにアップロードするようになっています。

使用したクレート

他の言語で言うライブラリとかフレームワークみたいなやつです。

CLIの構築

主にclapdialoguerを使ってインタラクティブなCLIを構築しました。これにより、ユーザーが対話形式でプロジェクト名や説明、ライセンスなどを指定できるようにしました。

  • clap: コマンドライン引数のパースとオプションの処理に使用
  • dialoguer: プロジェクトの詳細を対話形式で入力できるプロンプトを実装

内部処理

主にregexreqwestを使って内部の処理を実装しました。これにより、入力のバリデーションなどを行っています。

  • regex: 正規表現によるバリデーションで、プロジェクト名や作者名のフォーマットチェックに使用
  • reqwest: PyPIのAPIにアクセスし、ライブラリ名の使用可否を確認するためのHTTPリクエストに使用

問題と解決

実行権限の問題

最初に生成されたLinuxとmacOSのバイナリで、permission deniedが発生しました。この問題は、ビルド後に実行権限が付与されていなかったことが原因です。GitHub Actionsの中でchmod +xコマンドを追加し、バイナリに実行権限を付与することで解決しました。

圧縮方法の問題

ビルドプロセスの自動化には、GitHub Actionsを使用しました。Windows、Linux、macOSの3つの環境で同時にビルドを行い、リリースページにバイナリをアップロードするまでは上手く行ったのですが、Linux/macOSで利用可能なzipコマンドがWindowsで使えなかったため${{ matrix.os == 'windows-latest' }}を用いて場合分けを行い、Windows環境ではCompress-Archiveを使うようにすることで解決しました。

まとめ

Rustを初めて触ったにしては結構頑張った方なんじゃないでしょうか...ツール自体も結構便利だと思うのでGitHubリポジトリにstarなど頂けると励みになります。

https://github.com/t3tra-dev/pyinit

プルリクエストも大歓迎です!ただ私自身がRust初心者なのでお手柔らかに...

バグなどありましたらissuesセクションからお願いします。

終わりに

最後まで読んで頂きありがとうございます。不備があれば是非コメントで指摘して下さい。

Zennでの投稿は初めてで、この記事は私のQiitaの記事をコピーしたものになります。色々と至らぬ点があると思いますがご容赦ください...

Discussion

kanaruskanarus

気づいたら原型が全くないレベルでリファクタリングしてしまい、プルリク出すのもためらわれる感じになってしまったので、ひとつの参考として供養がてらここに置いておきます。。。

https://github.com/kanarus/pyinit/tree/main/src