akimo.dev

パッケージマネージャーのラッパーを作った

僕は現在Macを使っているので、Homebrewで入れられるものはHomebrewで入れることが多い。 しかし、何でもかんでもHomebrewで入れられるわけではないので、Go製ツールのインストールにgo installを使うこともあるし、npm系のツールをpnpmで入れたりもする。 複数のパッケージマネージャーを使うこと自体は別に構わないのだが、インストール関連ならまだしも、使用頻度の低いコマンドをパッケージマネージャーごとに覚えるのは難しい。 また、Goはパッケージマネージャーとして貧弱である。 こういった問題を解決するために、pacxというパッケージマネージャーのラッパーを作った。

akimon658/pacx: Wrapper for package managers, allowing you to define and configure your package managers in Lua
github.com

類似のツールはちょっと調べただけでもhkdb/apprami3l/pacaptrなどなどいくらでも出てくるが、ツール側でサポートされたパッケージマネージャーのみ使えるというものが主流で拡張性に欠ける。 そこでpacxでは、自分でパッケージマネージャーを定義し、その挙動をLuaで記述できるようにした。 例えば、

return {
  install = function(pkg)
    os.execute("brew install " .. pkg)
  end,
}

このコードを$XDG_CONFIG_HOME/pacx/brew.luaとして保存した状態でpacx install brew:ghを実行すると、brew install ghが実行される。

Luaなので、パッケージマネージャーにない機能も自分で実装すれば使えるようになる。 例えば、$XDG_CONFIG_HOME/pacx/go.lua

local function install(pkg)
  os.execute("go install -ldflags='-s -w' -trimpath " .. pkgName)
end

local function upgrade(pkg)
  local pkginfo = io.popen("go version -m $(go env GOPATH)/bin/" .. pkg)
  if not pkginfo then
    error("failed to execute go version -m " .. pkg)
  end

  _ = pkginfo:read()
  local pkgpath = string.match(pkginfo:read(), "path%s+(%S+)")
  install(pkgpath)
end

return {
  install = install,
  upgrade = upgrade,
}

と書いたとしよう。 この状態で何かインストールするときにはpacx install go:golang.org/x/tools/goplsのようにパッケージ名を指定する必要があるが、アップグレードはpacx upgrade go:goplsのようにバイナリ名だけで行えるようになる。

pacx側でサポートしているパッケージマネージャーなんてものはないので設定を書かなければ使えないが、その代わりLuaでできることは大体できる。 とはいえ、自力で0から設定を書かなければいけないのも面倒なので、wikiにはいくつかのパッケージマネージャーについて設定例を載せている。

今のところLuaで定義できる関数は僕が必要だと思ったものだけだが、要望があれば追加していく予定だ。