Windows に Gollum をインストール

WindowsにGollumを入れて実行できるようにしました。WSLとかCygwinは甘えと断じ使いませんでした。

以下の２つ（または３つ）の困難がありました。

1. Ryzen系のCPUでMSYSインストーラが正常動作しない
2. libicuのファイル名がmsysではデフォルトと違う
3. gitlab-gritがWindowsに対応していない

以上の問題の解決法を書いた、gollumインストールの備忘録です。

# 環境を用意

https://rubyinstaller.org/downloads/

ここから、Ruby+Devkit の一番新しいやつを落としてきます。
2019/12/10 のときの最新版(2.6.5-1)でやりました。

そしてインストーラをダブルクリックしてインストール。Pathは特にどこでもいいと思いますが、環境変数に追加したほうがいいかなと思います。

で、最後のMSYSセットアップ起動にチェックを入れて、MSYSのインストールに移ります。で、MSYSをインストールします。


# PATHを通す

* Rubyのbin
* MSYSの/usr/bin
* MSYSの/mingw64/bin
* 一応gitのバイナリがあるところ

Windowsキー＋Pause/breakキーのショートカットを使うと幸せになれるかもしれません。

# Gollum のインストール

## charlock_holmes のビルド

適当な端末を立ち上げ、以下のコマンドを実行。

```
gem install gollum
```

するとたぶん `charlock_holmes` のインストールで止まり、`mkmf.log` を見ろとか言われると思います。いわれた通りファイル内容を確認すると、

```
C:/msys64/..(中略)../x86_64-w64-mingw32/bin/ld.exe: cannot find -licui18n
collect2.exe: error: ld returned 1 exit statu
```

とあり、 libicuがないことがわかります。

## icuインストール

ということで追加します。
https://github.com/brianmario/charlock_holmes/issues/84
を参考にしながら、msysの端末（もしかしたらWindowsのcmdでもいいかもしれない）を立ち上げ、

```
pacman -S mingw64/mingw-w64-x86_64-icu
# pacman -S icu-devel はなくてもいいかも
```

と必要なライブラリをインストールします。そのまま `gem install charlock_holmes` ・・・と行きたいところですが、このままではまた止まります。
MSYSのライブラリ内を見てみるとわかりますが、`libicui18n.a` というファイルがありません。pacmanインストールが失敗した？と思いましたが、どうもファイル名が違うだけのようです。ということでそれをオプションで教えてやります。

```
gem install charlock_holmes -- --with-icui18nlib=icuin --with-icudatalib=icudt
```

これでcharlock_holmesがインストールできました。

## gollumインストール

最後に、

```
gem install gollum
```

とします。これで僕は問題なくインストールできました。

# Gollumの実行

## アクセス時にエラー

しかしこのまま適当なgitリポジトリを用意して `gollum` を実行し、localhost:4567にアクセスしても、

```
TypeError at /Home
no implicit conversion of nil into String
```

なるエラーが出ました。いろいろググったところ、それっぽい情報が見つからなかったので、Fortranで培った地獄のPrintデバッグをやってみました。

BackTraceによると

```
Ruby26-x64/lib/ruby/gems/2.6.0/gems/gitlab-grit-2.8.2/lib/grit/git.rb
```

の350行目近く

```ruby
        Child.new(env, *(argv + [{
```

を経由するのですが、この`argv`の中身を見てみると、

```ruby
      # build up the git process argv
      argv = []
      argv << Git.git_binary
      argv << "--git-dir=#{git_dir}" if base
      argv << "--work-tree=#{work_tree}" if work_tree
      argv << cmd.to_s.tr('_', '-')
      argv.concat(options_to_argv(options))
      argv.concat(args)
```

としていますが、なんと `Git.git_binary`が空文字だったことがわかりました。

## 原因

さてこの`git_binary` ですが、いつ決定されるかというと、`git.rb` の81行目からを見てみると

```ruby
      def git_binary
        @git_binary ||=
          ENV['PATH'].split(':').
            map  { |p| File.join(p, 'git') }.
            find { |p| File.exist?(p) }
      end
```

となっていますが、ここにはWindows環境において動かなくなる2つの間違いがあります。

1. 環境変数`PATH`のセパレータはWindowsにおいては `;`
2. Windowsでは `git.exe` でないと実行ファイルにヒットしない

ということで `find` でヒットしなくなってしまいます。

## gitlab_grit 微修正

どうせ僕はrubyをこの用事でしか使わないので、これを微修正することにしました。
以下の2通りが考えられます。

このどちらの方法でもgollumが実行できるようになったことを確認しました。

### 実行バイナリ検索をちゃんとする

`:` を `;` に、`git` を `git.exe` に変えてやります。

```ruby
      def git_binary
        @git_binary ||=
          ENV['PATH'].split(';').
            map  { |p| File.join(p, 'git.exe') }.
            find { |p| File.exist?(p) }
      end
```

### spawnの引数を正確に

実行バイナリの検索はあきらめ、正しい引数を決め打ちしてしまいます。

```ruby
      # build up the git process argv
      argv = []
      # argv << Git.git_binary
      argv << "C:/Program Files/Git/bin/git.exe"
      argv << "--git-dir=#{git_dir}" if base
      argv << "--work-tree=#{work_tree}" if work_tree
      argv << cmd.to_s.tr('_', '-')
      argv.concat(options_to_argv(options))
      argv.concat(args)
```
# 導入かくにん！よかった。

とりあえずWindows上で閲覧・ページ作成・編集ができるようになりました。

```
gollum --mathjax
```

で数式も問題なくレンダリングできました。

# 余談１ RyzenマシンでMSYSをインストールする

MSYSのインストーラですが、Ryzen系CPUだと普通のMSYSインストーラが使えません。
終盤あたりで「書き込み用のファイル""を開けません」みたいなエラーメッセージが出て中断すると思います。

参考：https://github.com/msys2/MSYS2-packages/issues/1532

こういう時は、このissueにあるように、tar.xzを落としてきて手動で解凍、インストールしたいフォルダに置いてPATHを通します。

https://sourceforge.net/projects/msys2/files/Base/x86_64/

そして `msys64` フォルダ中の `msys2.exe` を一度起動して端末を立ち上げますと何か処理が始まります。終わったらいったん終了して再起動します。この状態だと gcc など重要なビルドツールがありませんのでインストールしてやります。

```bash
pacman --needed -Sy bash pacman pacman-mirrors msys2-runtime
pacman -Syu
pacman -S mingw-w64-x86_64-toolchain
pacman -S make
```

 なお3つ目ですが、C, Fortran, Adaなど言語パッケージを選択します。今回は趣味のFortranと必須のCを選択した` 1 2 3 5 6 7 9 10 11 12 13 14 15 16 17` を選択しました。

参考：https://qiita.com/spiegel-im-spiegel/items/ba4e8d2418bdfe0c8049

## 追記 2019/12/30

ふとissueを見ていると、インストーラに使っているqtの問題ではという話がありました。

https://github.com/msys2/MSYS2-packages/issues/1532#issuecomment-535949200
https://bugreports.qt.io/browse/QTBUG-77375

これの回避にはBIOSのアップデートだとあります。ちょっと今忙しいのでできないですが、そのうちやってみようと思います。ひとまず追記だけしておきます。


# 余談２　なぜGollum

なんかプライベートで勉強したこととかをまとめたナレッジベースが欲しくなったのですが、このとき以下の条件を考えていました。

* 文法

markdownもしくはwikiで、mathjaxなどによるlatex風文法での数式レンダリングがあること。

* ポータビリティ

 データのコピーとか移動がPC上の操作で楽なものが欲しかった。MySQLとかデータベースを使うものはちょっと。Gollumは普通のGitリポジトリなので、普通のファイル的に持ち運んでもよし、githubなどを使うもよし。

* 実行環境の軽さ

TomcatとかApache、またはほかのサービスを前提としたものは環境構築だけでも一苦労です。

* ローカル環境

今回はインターネットに公開するつもりはないので、特に認証システムとかCSSのカスタマイズ性とかは求めませんでした。必要な時にプロセスを立ち上げるコマンドを実行して http://localhost:4567 といった感じでアクセスすれば十分かなと。

だいたいこんな感じのことを考えながら探していて、ふとGollumを見つけました。そしてGollumで気づいた利点です。

* 汎用性

蓄えたデータはそのまま普通のmarkdownファイルとしてみることができます。Gollumを使わなくてもリポジトリが生きてさえいれば活用できます。Qiitaの下書きとしてもいいかもしれない。

ということでしばらくGollumwo使ってみようかなと。

# 余談３

僕は今回初めてRubyに触りました。