Vim/Neovimのプラグインマネージャーを悪用してCLIの管理ツールとして使う
TL;DR
- CLI ツールを管理する方法として、Vim/Neovimのプラグインマネージャーを使うと意外と便利
はじめに
皆さんはCLI ツールをどのように管理していますか?
私はmacOSで使うツールの管理に以下のパッケージマネージャーたちを使っています。
- 汎用的なパッケージマネージャー
- 言語ごとのパッケージマネージャー
- ツールごとのパッケージマネージャー
結構多いですね。
ツールは多岐にわたるので、それぞれのツールに合ったパッケージマネージャーを使っています。
理想のパッケージマネージャー
私は複数マシンを使っているので、マシン間の設定をdotfilesとして管理しています。
自分がdotfilesで使用するパッケージマネージャーに求める条件は以下の通りです。
- パッケージマネージャーのインストール、アンインストールが簡単
- パッケージマネージャーの設定をDeclarativeに記述できる
- パッケージマネージャがー管理するツールの設定やバージョンをDeclarativeに記述できる
- Lockfileでバージョン、差分を管理できる
- パッケージマネージャーが管理するツールのバージョンを切り替えることができる/簡単に戻すことができる
- 設定量は多過ぎず少な過ぎず
- 暗黙の動作が少ない
これらを満たしていると、Github上で差分も簡単に確認でき、またマシン間でもgit pullして簡単なコマンドを打つだけで環境を再現できるので、とても便利です。
Aqua
これらを条件を考えた時に、汎用のパッケージマネージャーにおいては、Aquaが一番条件を満たしていると思います。
AquaはYAMLでDeclarativeにツールを管理でき、またRenovateを併用すれば最新版の確認、更新も簡単にできます。
また、設定もプリセットのものが多く、もし欲しいツールがなかった場合も本家のRegistryにPull Requestを送ることで追加できます。
そのため、自分の使用するCLI ツールは極力Aquaで管理したいと思っています。
しかし、AquaはGo言語以外のビルドをサポートしていないので、Go言語以外で書かれていて尚且つバイナリが提供されていないツールを管理することができません。
また、特定の場所にインストールが必要なもの(gh extension)も管理できません。
追記:
CargoによるInstallにも対応しているようです!
afx
自分は使用していないのですが、afxというパッケージマネージャーもあります。
このパッケージマネージャーはAquaと同じくYAMLでDeclarativeにツールを管理できます。
AquaのようなRegistryは存在しないので、自分でビルドスクリプトを書く必要がありますが、その分ビルドスクリプトを定義したり、gh extensionを管理したりと、より柔軟な管理ができます。
とても魅力的なパッケージマネージャーですが、以下の理由で自分は使用していません。
- 更新時、Releaseにあるものは最新版をチェックして落とすことができるが、例えばmain ブランチのHEADを落としてきてビルドするようなことはできない
- Lockfileを採用していないので、ツールのバージョン一覧を1箇所で確認することができない
- (これはAquaも同じであるが) YAMLで設定を記述するので、設定量が多いとYAMLの記述が煩雑になる
- (これはafxは何も悪くないのですが)これ以上パッケージマネージャーを増やしたくない
とても良いパッケージマネージャーではあるので、ぜひ皆さんチェックしてみてください。
解: lazy.nvimを悪用する
というわけで、自分が求める条件を満たすパッケージマネージャーがなかなか見つかりません。
これは自分で作るしかないのかなと思いつつ、なかなか手がつけられない中数ヶ月が経ちました。
そんな中、先日の駅伝でslinさんがvim/neovimのパッケージマネージャーであるdeinを悪用して、IMEの辞書を管理する方法を紹介していました。
またこれについて楽園で盛り上がっていたところ、CLI ツールを管理するのにも使えるんじゃないかという話になりました。
これについて考えてみると、vim/neovimのパッケージマネージャー、特に自分の使っているlazy.nvimは以下のような特徴があります。
- パッケージマネージャーのインストール、アンインストールが簡単 → vimの設定の一部なのですでにある
- パッケージマネージャーの設定をDeclarativeに記述できる → lua で記述できる
- パッケージマネージャーが管理するツールの設定やバージョンをDeclarativeに記述できる → lua で記述できる
- Lockfileでバージョン、差分を管理できる →
lazy-lock.json
が生成されるので、差分が取れる - 設定量は多過ぎず少な過ぎず → お作法に乗っ取れば、設定量は少ない。独自のビルドの設定も記述できる
というわけで、1からパッケージマネージャーを作るよりも、vim/neovimのパッケージマネージャーを悪用する方が簡単そうだなと思い、実際に設定を書いてみました。
以下に自分がAqua/Homebrew管理外だったツールをいかにして管理したかを書いていきます(da-ja-re)。
gh extensionの管理
gh extensionは、ghコマンドの拡張機能です。
自分もいくつか愛用しているものがあります。
これらのコマンドはghコマンドと一緒に使うことで、githubにまつわる便利な機能を提供してくれます。
しかし、これらのツールを管理するツールは(現時点ではafxをのぞいて)存在しません。
これをlazy.nvimで管理してみましょう。
この設定ファイルの中でやっていることは以下の通りです。
- 指定したレポジトリの最新版を落としてくる
- go build する
- ビルドされたバイナリをgh extensionのディレクトリ(macOSでは
~/.local/share/gh/extensions/
)に配置する
これで、gh extensionをlazy.nvimで管理することができました。
新しいgh extensionを追加したい場合は、この設定ファイルに追記するだけで、lazy.nvim
のアップデートをすると、自動的に最新版が落とされます。
別のマシンを使う時にも、dotfilesをpullしてNeovimを起動するだけで、最新版のgh extensionが自動的にインストールされます。
lazy-lock.json
にバージョンが記述されるので、差分も確認できて嬉しいですね。
追記:
gh extension install .
でローカルのレポジトリをインストールできることを知り、設定を簡素化しました。
zlsの管理
zlsはzigのLanguage Serverです。
自分はzigのHEADを使っているので、zlsを使用するにはmasterをcloneして最新版のzigでビルドする必要があります。
今までは毎日手動でzlsからgit pull、ビルドしていましたが、これもlazy.nvimで管理することにしました。
これもやっていることは簡単で、lazy.nvimでアップデートをすると、zlsのレポジトリをgit pullして勝手にビルドしてくれます。
あとはビルドされたバイナリをnvim-lspconfigで指定するだけで、zlsを使うことができます。
これで、zlsをlazy.nvimで管理することができました。
まとめ
この記事では、vim/neovimのプラグインマネージャーを悪用してCLI ツールを管理する方法、そしてlazy.nvimを使用した具体的な設定を紹介しました。
推奨されている方法ではないので、自己責任でお願いします。
これまで、Vimはエディタとして、単なる便利なCLI ツールの一つでしかありませんでした。
しかし、他のCLI ツールの管理をしたり、またGitを拡張するツールとしてVim使ったりしていると、VimがTerminalの環境を全て飲み込んでいくような、そんな感覚になります。
これからもVim/Neovimと仲良くしていきたいですね。
Discussion
go build
してlinkの流れ、出力されてほしいディレクトリを環境変数GOBIN
に放り込んだコンテキストでgo install
するのも悪くないかもしれないですね。私も使わせてもらいますこの手法aqua をご紹介いただきありがとうございます!
正確に言うと、 https://crates.io/ で公開されている Rust 製のツールのビルドにも対応しています。
cargo install
でビルドします。もっとも、 standard registry で対応しているツールの数はとても少ないですが(意外と需要がないのか知られてないのか、 Pull Request が来ません)。
ありがとうございます。
いつもお世話になっています。
以前記事でGo Buildに対応したことは存じていましたが、Cargoにもいつのまに対応されていたのですね!
今度PRします