LoginSignup
3
0

More than 3 years have passed since last update.

Golangで作成されたVimプラグインの配布方法について調べた

Last updated at Posted at 2020-03-11

まえがき

Golangのクロスコンパイルは非常に魅力的だと思うのですが、Vimのプラグインとして配布する場合に少し悩んだので、調査した内容を残しておきます。

配布方法1: ユーザーにビルドしてもらうパターン

ユーザーにGoのビルドをしてもらうケース。

基本的にREADME.mdのInstallationの項目に

$ cd /ビルド可能なパス && go get -d && go build

と書いておけばすむので、用意する側はかなり気楽です。

ユーザーにgo buildしてもらえれば必ずその環境にあったバイナリが出来上がるのでこの点はメリットになりうるのですが、ユーザー側にGoの環境がなければいけないため、もしGoの環境がなければ使う側は少しハードルが高くなるかもしれません。

参考: Go で Vim プラグインを書く - http://haya14busa.com/vim-go-client/

配布方法2: バイナリを配布するパターン

バイナリ配布したいですよね。でも、インストール周りどうしましょう?

ここで個人的に大好きなfzf先生(Golang製)を参考にしてみました。
fzfにはインストールスクリプトがあり、shell scriptでアーキテクチャを判定してバイナリをダウンロードしているようです。

fzfのインストールスクリプトの実際のアーキテクチャを判定している箇所はこちらになります。

# Try to download binary executable
archi=$(uname -sm)
binary_available=1
binary_error=""
case "$archi" in
  Darwin\ *64)   download fzf-$version-darwin_${binary_arch:-amd64}.tgz  ;;
  Darwin\ *86)   download fzf-$version-darwin_${binary_arch:-386}.tgz    ;;
  Linux\ armv5*) download fzf-$version-linux_${binary_arch:-arm5}.tgz    ;;
  Linux\ armv6*) download fzf-$version-linux_${binary_arch:-arm6}.tgz    ;;
  Linux\ armv7*) download fzf-$version-linux_${binary_arch:-arm7}.tgz    ;;
  Linux\ armv8*) download fzf-$version-linux_${binary_arch:-arm8}.tgz    ;;
  Linux\ aarch64*) download fzf-$version-linux_${binary_arch:-arm8}.tgz  ;;
  Linux\ *64)    download fzf-$version-linux_${binary_arch:-amd64}.tgz   ;;
  Linux\ *86)    download fzf-$version-linux_${binary_arch:-386}.tgz     ;;
  FreeBSD\ *64)  download fzf-$version-freebsd_${binary_arch:-amd64}.tgz ;;
  FreeBSD\ *86)  download fzf-$version-freebsd_${binary_arch:-386}.tgz   ;;
  OpenBSD\ *64)  download fzf-$version-openbsd_${binary_arch:-amd64}.tgz ;;
  OpenBSD\ *86)  download fzf-$version-openbsd_${binary_arch:-386}.tgz   ;;
  CYGWIN*\ *64)  download fzf-$version-windows_${binary_arch:-amd64}.zip ;;
  MINGW*\ *86)   download fzf-$version-windows_${binary_arch:-386}.zip   ;;
  MINGW*\ *64)   download fzf-$version-windows_${binary_arch:-amd64}.zip ;;
  MSYS*\ *86)    download fzf-$version-windows_${binary_arch:-386}.zip   ;;
  MSYS*\ *64)    download fzf-$version-windows_${binary_arch:-amd64}.zip ;;
  Windows*\ *86) download fzf-$version-windows_${binary_arch:-386}.zip   ;;
  Windows*\ *64) download fzf-$version-windows_${binary_arch:-amd64}.zip ;;
  *)             binary_available=0 binary_error=1 ;;
esac

download fzf-$version ~~~となっている箇所はバイナリをダウンロードするスクリプト内の関数を呼び出しています。
こんなイメージで、初回起動時やプラグインマネージャでインストールスクリプトを叩いてあげれば、適切なバイナリを落としてくることができるようになりそうです。

配布方法3: 少し横着な方法

2つ目の方法で少し横着するとすれば、バイナリサイズが小さいうちはVimプラグインリポジトリにアーキテクチャごとのバイナリファイルをpushして、実行時に適切なバイナリが選ばれるようにすることもできるかと思います。
(無駄にファイルをダウンロードすることになるので怒られそうな気もしなくもないですが...)

Vim script側

let s:go_bin_path = v:null
let s:ext = ''

" windowsで極力外部コマンドを実行したくないのでここで判定できればここで
if has('win32')
    let s:go_bin_path = 'win-386'
    let s:ext = '.exe'
elseif has('win64')
    let s:go_bin_path = 'win-amd64'
    let s:ext = '.exe'
else
    " 正しいパスが得られているかチェックはしたほうが良いかも
    let s:go_bin_path = trim(system('path/to/archi_info.sh'))
endif

if l:go_bin_path != v:null
    let s:result = system('"path/to/plugin/' . s:go_bin_path . '/goで実行するバイナリファイル"' . s:ext . '')
endif

アーキテクチャ判定スクリプト

archi_info.sh
#!/usr/bin/env bash

set -u

# Echo binary path executable to stdout.
archi=$(uname -sm)
case "$archi" in
  Darwin\ *64)     echo darwin-amd64  ;;
  Darwin\ *86)     echo darwin-386    ;;
  Linux\ armv5*)   echo linux-arm5    ;;
  Linux\ armv6*)   echo linux-arm6    ;;
  Linux\ armv7*)   echo linux-arm7    ;;
  Linux\ armv8*)   echo linux-amd64   ;;
  Linux\ aarch64*) echo linux-amd64   ;;
  Linux\ *64)      echo linux-amd64   ;;
  Linux\ *86)      echo linux-386     ;;
  FreeBSD\ *64)    echo freebsd-amd64 ;;
  FreeBSD\ *86)    echo freebsd-386   ;;
  OpenBSD\ *64)    echo openbsd-amd64 ;;
  OpenBSD\ *86)    echo openbsd-386   ;;
  CYGWIN*\ *64)    echo windows-amd64 ;;
  MINGW*\ *86)     echo windows-386   ;;
  MINGW*\ *64)     echo windows-amd64 ;;
  MSYS*\ *86)      echo windows-386   ;;
  MSYS*\ *64)      echo windows-amd64 ;;
  Windows*\ *86)   echo windows-386   ;;
  Windows*\ *64)   echo windows-amd64 ;;
  *)               ;;
esac

Vim scriptからアーキテクチャ判定用のshell scriptを実行し、結果をもとにVim scriptから適切なGoのバイナリを実行します。

各アーキテクチャ用のビルドは、下記のような内容をMakefileに書いてmake allでコマンドで一気に作成されるようにします。
(パスは適宜読み替えてください)

mac:
    GOOS=darwin GOARCH=amd64 go build -o ../bin/darwin-amd64/go_bin ./go_file.go
    GOOS=darwin GOARCH=386 go build -o ../bin/darwin-386/go_bin ./go_file.go
all:
    GOOS=linux GOARCH=arm GOARM=5 go build -o ../bin/linux-arm5/go_bin ./go_file.go
    GOOS=linux GOARCH=arm GOARM=6 go build -o ../bin/linux-arm6/go_bin ./go_file.go
    GOOS=linux GOARCH=arm GOARM=7 go build -o ../bin/linux-arm7/go_bin ./go_file.go
    GOOS=linux GOARCH=amd64 go build -o ../bin/linux-amd64/go_bin ./go_file.go
    GOOS=linux GOARCH=386 go build -o ../bin/linux-386/go_bin ./go_file.go

    GOOS=freebsd GOARCH=amd64 go build -o ../bin/freebsd-amd64/go_bin ./go_file.go
    GOOS=freebsd GOARCH=386 go build -o ../bin/freebsd-386/go_bin ./go_file.go

    GOOS=openbsd GOARCH=amd64 go build -o ../bin/openbsd-amd64/go_bin ./go_file.go
    GOOS=openbsd GOARCH=386 go build -o ../bin/openbsd-386/go_bin ./go_file.go

    GOOS=windows GOARCH=amd64 go build -o ../bin/win-amd64/go_bin.exe ./go_file.go
    GOOS=windows GOARCH=386 go build -o ../bin/win-386/go_bin.exe ./go_file.go
    make mac

3つ目の方法のメリットとしてはVimプラグインのバージョンに対して正しいバイナリが落とされているか気にする必要がないため、用意する側も少し気が楽になりそうです。

まとめ

Golangで作成されたVim プラグインの配布方法の3つをまとめました。

実際に自分もVimプラグインでGoのバイナリを配布する必要があったのですが、現在は3つ目の方法で暫定的に用意しています。

ちなみに、今回作ったプラグインはこちらです。
Qiita: Neovimでpopup-menuを実装できるプラグイン
Github: https://github.com/kamykn/popup-menu.nvim
(もしも、需要が高まれば2つ目の方の方法に移行する、というのも考えられるかと思います。)

色々方法はありましたが、そのプロジェクトに応じて適切な方法を選択できればいいかなと思いました👍

3
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
3
0