brew upgradeしたらopensslが1.1.1gになってしまいRailsが起動できなくなってしまったとき

# 参考
[Cannot install Ruby versions < 2.4 because of openssl@1.1 dependency](https://github.com/rbenv/ruby-build/issues/1353#issuecomment-573414540)

# 経緯
[問題](#問題)
[過程](#過程)
[解決](#解決)

# 問題
`ruby 2.0.0-p648`で動いているプロジェクトの修正をローカルで試すタイミングで動かないことに気づきました。

```bash
$ bundle exec rails s
Library not loaded: /usr/local/opt/openssl/lib/libssl.1.0.0.dylib (LoadError)
```

- brew upgradeでopensslが`1.1.1g`になってしまっていて、今までopenssl`1.0.0`で動かしていたプロジェクトが動かなくなってしまっていました。

# 過程
ちょっと試してこの時点では以下の2点を考えていました。
- `ruby 2.0.0-p648`を`openssl 1.1.1g`でどうにか再インストールできないか？
- `openssl 1.1.1g`を`openssl 1.0.0`にダウングレードできないか？

## 試したこと

[How to install openssl 1.0?](https://github.com/Homebrew/homebrew-core/issues/47348)

```bash:エラーで失敗
$ brew install https://raw.githubusercontent.com/Homebrew/homebrew-core/64555220bfbf4a25598523c2e4d3a232560eaad7/Formula/openssl.rb -f
```

[Homebrewで過去のバージョンを使いたい - 2017-01-08](https://christina04.hatenablog.com/entry/2017/01/08/120459)
これもダメでした…

# rubyの再インストール
rubyの再インストールでなんとかなるような記事もいくつかあったため試したが以下のエラーでインストールすらできない状態に…

```bash
The Ruby openssl extension was not compiled.
```

# 解決

この時点ではなんとか`openssl 1.1`で`ruby 2.0.0`をbuildできないか？と考え、
`openssl 1.1 ruby 2.0.0 build `でGoogle検索したところ以下の記事を発見し
[Cannot install Ruby versions < 2.4 because of openssl@1.1 dependency](https://github.com/rbenv/ruby-build/issues/1353#issuecomment-573414540)
結果的に、`openssl 1.0`をインストールすることで解決にたどり着きました。

## openssl1.0のインストール
`rbenv/tap`のリポジトリからopenssl1.0をインストールすることで解決しました。

```bash:openssl1.0のインストール
$ brew install rbenv/tap/openssl@1.0
Updating Homebrew...
==> Auto-updated Homebrew!
Updated 3 taps (homebrew/core, homebrew/cask and caskroom/cask).
==> Updated Formulae
Updated 13 formulae.
==> Updated Casks
inkscape                                                            inkscape

==> Tapping rbenv/tap
Cloning into '/usr/local/Homebrew/Library/Taps/rbenv/homebrew-tap'...
remote: Enumerating objects: 5, done.
remote: Counting objects: 100% (5/5), done.
remote: Compressing objects: 100% (4/4), done.
remote: Total 5 (delta 0), reused 5 (delta 0), pack-reused 0
Unpacking objects: 100% (5/5), done.
Tapped 1 formula (29 files, 28.6KB).
==> Installing openssl@1.0 from rbenv/tap
==> Downloading https://www.openssl.org/source/openssl-1.0.2t.tar.gz
Warning: Your Xcode (11.0) is outdated.
Please update to Xcode 11.3.1 (or delete it).
Xcode can be updated from the App Store.

==> perl ./Configure --prefix=/usr/local/Cellar/openssl@1.0/1.0.2t --openssldir=/usr/local/etc/openssl no-ssl2 no-ssl3 no-zlib shared e
==> make depend
==> make
==> make test
==> make install MANDIR=/usr/local/Cellar/openssl@1.0/1.0.2t/share/man MANSUFFIX=ssl
==> Caveats
A CA file has been bootstrapped using certificates from the SystemRoots
keychain. To add additional certificates (e.g. the certificates added in
the System keychain), place .pem files in
  /usr/local/etc/openssl/certs

and run
  /usr/local/opt/openssl@1.0/bin/c_rehash

openssl@1.0 is keg-only, which means it was not symlinked into /usr/local,
because Apple has deprecated use of OpenSSL in favor of its own TLS and crypto libraries.

If you need to have openssl@1.0 first in your PATH run:
  echo 'export PATH="/usr/local/opt/openssl@1.0/bin:$PATH"' >> ~/.bash_profile

For compilers to find openssl@1.0 you may need to set:
  export LDFLAGS="-L/usr/local/opt/openssl@1.0/lib"
  export CPPFLAGS="-I/usr/local/opt/openssl@1.0/include"

For pkg-config to find openssl@1.0 you may need to set:
  export PKG_CONFIG_PATH="/usr/local/opt/openssl@1.0/lib/pkgconfig"

==> Summary
🍺  /usr/local/Cellar/openssl@1.0/1.0.2t: 1,787 files, 12.0MB, built in 8 minutes 8 seconds
```


## 改めてrubyインストール

`openssl`のシンボリックリンクが`1.1.1g`を指しているので

```
openssl -> ../Cellar/openssl@1.1/1.1.1g
```
`RUBY_CONFIGURE_OPTS`で`openssl@1.0`に変更してインストール

```bash:
$ RUBY_CONFIGURE_OPTS="--with-openssl-dir=/usr/local/opt/openssl@1.0" rbenv install 2.0.0-p648 
Downloading ruby-2.0.0-p648.tar.bz2...
-> https://cache.ruby-lang.org/pub/ruby/2.0/ruby-2.0.0-p648.tar.bz2
Installing ruby-2.0.0-p648...

WARNING: ruby-2.0.0-p648 is past its end of life and is now unsupported.
It no longer receives bug fixes or critical security updates.

ruby-build: use readline from homebrew
Installed ruby-2.0.0-p648 to ~/.rbenv/versions/2.0.0-p648

rbenv: cannot rehash: ~/.rbenv/shims/.rbenv-shim exists
```

# そのあと
bundlerを追加したり…

```bash:ruby2.0.0-p648だと最新版はエラー
$ gem install bundler
Fetching: bundler-2.1.4.gem (100%)
ERROR:  Error installing bundler:
        bundler requires Ruby version >= 2.3.0.
```

```bash:バージョン指定してインストール
$ gem install bundler -v "1.17.2"
```

プロジェクトのgemを再インストールしたり…

```:opensslの参照が前のままなのが原因でエラー
$ bundle exec rails s
...
~/vendor/bundle/ruby/2.0.0/gems/activesupport-4.0.0/lib/active_support/dependencies.rb:228:in `require': dlopen(~/vendor/bundle/ruby/2.0.0/gems/mysql2-0.3.20/lib/mysql2/mysql2.bundle, 9): Library not loaded: /usr/local/opt/openssl/lib/libssl.1.0.0.dylib (LoadError)
...
```

```:.bundle/config
---
BUNDLE_PATH: "vendor/bundle"
BUNDLE_BUILD__LIBV8: "--with-system-v8"
BUNDLE_BUILD__THERUBYRACER: "--with-v8-dir=/usr/local/opt/v8@3.15"
- BUNDLE_BUILD__MYSQL2: "--with-ldflags=-L/usr/local/opt/openssl/lib"
+ BUNDLE_BUILD__MYSQL2: "--with-ldflags=-L/usr/local/opt/openssl@1.0/lib"
```

systemの`v8`とgemの`libv8`の互換性がなくてエラーが出たり…

```
However, your system version of v8 could not be located. 

Please make sure your system version of v8 that is compatible 
with 3.16.14.15 installed. You may need to use the 
--with-v8-dir option if it is installed in a non-standard location
        from ~/workspace/project/vendor/bundle/ruby/2.0.0/gems/libv8-3.16.14.15/lib/libv8.rb:7:in `configure_makefile'
        from extconf.rb:32:in `<main>'
```

```bash
$ bundle update libv8
...
Fetching libv8 3.16.14.19 (x86_64-darwin-18) (was 3.16.14.15)
Installing libv8 3.16.14.19 (x86_64-darwin-18) (was 3.16.14.15)
...
Fetching therubyracer 0.12.2
Installing therubyracer 0.12.2 with native extensions
...
Bundle updated!
```

しましたが無事動くようにできました。

# 反省と今後の課題

- `brew`の仕組みを理解していない
    - 公式以外のリポジトリからインストールなど理解していれば先に選択肢として考えられたはず
    - `yum`とかで使っているんだからわかる範囲のはずだったのに
- プログラミング言語（今回はインタプリタ型）のbuildの仕組みや動作を理解していない