形態素解析器 kagome を brew tap でインストールできるようにした

7 min read読了の目安(約6300字

概要

形態素解析器、mecab もあるし、Go を利用しないのに kagome をインストールする人もいないかなと思って go get でのインストールしか考えてませんでした。今回 Homebrew に対応したらどうかという issue を頂いたので思い切って対応してみました。すこし戸惑うところがあったので手順をメモします。

brew tap の仕組み

brew tap というのは Homebrew で公式以外のライブラリを登録する仕組みで、自分で作ったライブラリも Homebrew を通して公開することが出来ます。この仕組みを利用するために以下の2点をクリアしなくてはなりません:

  1. 自分のリポジトリに brew 用の Formula(インストール用のスクリプト一式)を用意する
  2. リリースする(コンパイル済みの)バイナリを用意する

リポジトリを用意する

kagome は github に上がっているので、github に brew 用のリポジトリを用意します。brew 用のリポジトリは形式が決まっていて、次の形式が想定されています:

github.com/<user>/homebrew-<パッケージ名>

なので、kagome では、github.com/ikawaha/homebrew-kagome としました。

配布用のバイナリと brew 用の Formula を用意する

上で作成した brew 用のリポジトリ(ikawaha/homebrew-kagome) にはバイナリを含めず、Formula のみを置きたいと思います。バイナリ自体は kagome にタグが振られたときに作成して kagome のリポジトリにリリースしたいと思います。

この両方を Github Actions を利用して自動化していくわけですが、GoReleaserという便利なツールがあるのでこれを使って構築していきます(というか GoReleaser を使うだけでほぼ完了です)。

GoReleaser の設定

GoReleaser 用の設定を YAML 形式のファイルで用意します。ファイル名はなんでもいいですが、ここでは .goreleaser.yml とします。やりたいことは以下の2点です:

  1. バイナリのビルド (OS と ARCH のクロスで用意したい)
  2. brew 用の Formula の生成

バイナリのビルド

クロスビルドしていきます。brew は macOS(か linux)でしか動かないので windows のバイナリ作る必要はないんですが、せっかくなので一緒に作ることにしました。ARCH も amd64 だけ入っていれば問題ないですが、折角(ry

組み合わせで不適合なものは作られません。この設定でバージョンやコミット番号などの情報もバイナリに埋め込みます。GoReleaser は CGO には対応できないとのことなのでご注意ください。

.goreleaser.yml
builds:
  - env:
      - CGO_ENABLED=0
    goos:
      - linux
      - darwin
      - windows
    goarch:
      - 386
      - amd64
      - arm
      - arm64
    mod_timestamp: '{{ .CommitTimestamp }}'
    flags:
      - -trimpath
    ldflags:
      - -s -w -X main.version={{.Version}} -X main.commit={{.Commit}} -X main.date={{ .CommitDate }} -X main.builtBy=goreleaser

最終的に、生成されるバイナリはリリースページからダウンロードできるようになります。

https://github.com/ikawaha/kagome/releases

Formula 用の設定

必要な情報は以下です。

brews:
   - github:    # この設定は古いようだ

と書いてあるものもあるみたいですが、これは github -> tap に変更されたようです[1]

項目 説明
tap>owner ikawaha github.com/ikawaha/homebrew-kagome のユーザー名部分
tap>name homebrew-kagome github.com/ikawaha/homebrew-kagome のリポジトリ名部分
commit_author>name goreleaserbot Formulaをコミットするコミットユーザー名
commit_author>email goreleaser@carlosbecker.com コミットユーザーのemailアドレス
description --- パッケージの説明
homepage https://github.com/ikawaha/kagome パッケージの説明が読めるホームページ
foler Formula パッケージのFormulaを配置するリポジトリのディレクトリ
install>bin.install kagome 実行ファイルを指定すればよさそう
test brew test で実行されるコマンドを指定
.goreleaser.yml
brews:
  - tap:
      owner: ikawaha
      name: homebrew-kagome
    commit_author:
      name: goreleaserbot
      email: goreleaser@carlosbecker.com
    description: "Self-contained Japanese Morphological Analyzer written in pure Go."
    homepage: "https://github.com/ikawaha/kagome"
    folder: Formula
    install: |
      bin.install "kagome"
    test: |
      system "#{bin}/kagome version"

GoReleaser 設定まとめ

まとめると設定は以下になります。

.goreleaser.yml
env:
  - GO111MODULE=on
before:
  hooks:
    - go mod download
builds:
  - env:
      - CGO_ENABLED=0
    goos:
      - linux
      - darwin
      - windows
    goarch:
      - amd64
      - arm
      - arm64
    mod_timestamp: '{{ .CommitTimestamp }}'
    flags:
      - -trimpath
    ldflags:
      - -s -w -X main.version={{.Version}} -X main.commit={{.Commit}} -X main.date={{ .CommitDate }} -X main.builtBy=goreleaser
brews:
  - tap:
      owner: ikawaha
      name: homebrew-kagome
    commit_author:
      name: goreleaserbot
      email: goreleaser@carlosbecker.com
    description: "Self-contained Japanese Morphological Analyzer written in pure Go."
    homepage: "https://github.com/ikawaha/kagome"
    folder: Formula
    install: |
      bin.install "kagome"
    test: |
      system "#{bin}/kagome version"

goreleaser は手元でも動作できるので build オプションで起動して確かめることが出来ます。このオプションではビルドだけしてリリースはされません。ただし、リポジトリの状態がコミットしてない差分などがある状態であったりすると止まってしまったりするのでそういうときは -snapshot オプションを足してください。

$ goreleaser build --config ./.goreleaser.yml --rm-dist --snapshot

GitHub Actions を設定する

GitHub でタグを打ったときに brew tap にもリリースするように設定していきます。goreleaser-action があるのでこれを使うだけです。args に goreleaser の実行時の引数をそのまま書けばいいです。設定ファイルの位置はリポジトリトップからの相対位置です。

権限について気をつける点があって、GITHUB_TOKENsecrets.GITHUB_TOKEN を利用すると、ビルドした成果物を同リポジトリのリリースの Assets に貼り付けるには問題ないのですが、別リポジトリ(この場合は github.com/ikawaha/homebrew-kagome) に書き込む権限がなくて失敗します。https://github.com/settings/tokenspublic_repo を有効にしたアクセストークンを作り、ビルドを動かすリポジトリの secrets に加えて設定してください。

token

name: Release

on:
  workflow_dispatch:
  push:
    tags:
      - 'v*'

jobs:
  goreleaser:
    runs-on: ubuntu-latest
    steps:
      - name: Checkout
        uses: actions/checkout@v2
        with:
          fetch-depth: 0
      - name: Set up Go
        uses: actions/setup-go@v2
        with:
          go-version: '1.15.x'
      - name: Run GoReleaser
        uses: goreleaser/goreleaser-action@v2
        with:
          version: latest
          args: release --rm-dist --config .goreleaser.yml
        env:
          GITHUB_TOKEN: ${{ secrets.GO_RELEASER_TOKEN }}

これでタグを打つとリリースされます。タグを打ったあと何か commit した状態で手動で動かしても(workflow_dispatchを設定している) homebrew-kagome リポジトリにはリリースされません。snapshot 扱いになります。

試す

Formula の置いてあるリポジトリが github.com/<user>/homebrew-<repo> のとき、brew install <user>/<repo>/<package> でインストールできます。kagome の場合は ikawaha/kagome/kagome でインストールされます。

$ brew install ikawaha/kagome/kagome

$ kagome version
2.3.2

$ echo 'すもももももももものうち' | kagome
すもも	名詞,一般,*,*,*,*,すもも,スモモ,スモモ
も	助詞,係助詞,*,*,*,*,も,モ,モ
もも	名詞,一般,*,*,*,*,もも,モモ,モモ
も	助詞,係助詞,*,*,*,*,も,モ,モ
もも	名詞,一般,*,*,*,*,もも,モモ,モモ
の	助詞,連体化,*,*,*,*,の,ノ,ノ
うち	名詞,非自立,副詞可能,*,*,*,うち,ウチ,ウチ
EOS

これで Go が環境にないときもインストールが簡単になりました(簡単とは・・・)。

Happy hacking!

脚注
  1. https://goreleaser.com/deprecations/ ↩︎