DenoとTypeScriptで自作CLIツールのghfを移植してみた(動機編)

by

以前、ghコマンドを曖昧検索で便利にするghfコマンドを作りました。

GitHub CLI(gh)に曖昧検索の力を加えるghfコマンドを作ってzshプラグイン化した

このツールは基本的にはbashで書いており、手動で導入すればzshがなくても動きます。

私のLinux環境では快適に使えていますが、2つの理由から別言語への移植を健闘していました。

  1. ポータビリティ
  2. 保守性
  3. 機能拡張のしやすさ

本稿ではこのあたりを考えた理由について記録しておきます。次回は感想戦かな。

依存が増えるのはデメリットではありますが、趣味のプロジェクトですし、自分の環境にはDenoを当然のように入れてるので悪くない選択肢だと思います。

もっとも、本家ghコマンドの実装を資産として活用できるGo言語を使った方がいいのでは、とDenoに移植してから気付いてしまったので、近くGoでも書き直すと思います。

ポータビリティ

戦術の通り、ghfコマンドはbashで書かれています。

しかしWindowsで動かすにはbashなどの導入が面倒です。

また、内部ではsedgrepを使っていますが、これらのコマンドは実装によって挙動が違います。私はLinuxユーザーなのでGNU版を使って開発をしていますが、macOSにはBSD版が入っているのでまともに動作するか不明です。

便利なのでせっかくならもっと多くの人に手軽に使ってもらえる形にしたいと思いました。

Denoへの依存こそ発生しますが、きっとWindowsにbashを入れるよりは簡単でしょう。 macOSやLinuxならhomebrewなりなんなりを使えば簡単に導入できます。

また、Denoさえ入れてしまえば、あとは以下のコマンドで簡単にインストールできるようになります。パスを通す必要はありますが、その旨はコマンド実行時に表示される手順に従えばよいようです。

deno install --allow-run --allow-env --allow-read --force --name ghf \
    https://raw.githubusercontent.com/atusy/ghf.ts/main/ghf.ts

保守性

見通しの良いコードを書くには、関数の切り分けが大事です。そして関数の扱いやすさも大事です。

しかしシェルスクリプトの関数は、n番目の引数を使って……みたいな書き方になるのでどうにも使い勝手が悪いです。加えて型付けができません。これでは引数を増やしたり順番を変えたりした時に、うっかり想定外の値を引数に渡すおそれがあります。

静的型付けな言語ならこの問題を回避できるでしょう。

機能拡張のしやすさ

ghfコマンドはghコマンドを通じてGitHubのAPIを叩いています。そのため、issueやレポジトリの一覧取得や、README.mdなどの概要の取得にどうしても多少の時間がかかります。このレスポンスを改善するため、キャッシュや非同期なプリフェッチを行いたいと考えています。

こういった複雑なことをしたければやはり非同期プログラミングが容易な言語を採用した方がいいでしょう。また、拡張すればする程、ポータビリティや保守性は重荷になるわけで、シェルスクリプト脱却が楽かなと思いました。