# mimemagicの最新動向
https://hackmd.io/@mametter/mimemagic-info-ja
この文書は[ruby-jp Slack](https://ruby-jp.github.io/)の`#rails`チャンネルの議論を有志を中心にまとめたものです。
## 起きたことの概要
Railsの一部であるactivestorageが依存しているmimemagic gemが、ライセンス関連の問題でrubygems.orgから取り下げられました。これにより、mimemagic <= 0.3.5に依存しているRailsアプリがbundle installに失敗するようになりました。
mimemagic <= 0.3.5に依存している場合のエラーの例:
> Your bundle is locked to mimemagic (0.3.5), but that version could not be found
shared-mime-infoがインストールされていない場合のエラーの例:
> Could not find MIME type database in the following locations:
> ["/usr/local/share/mime/packages/freedesktop.org.xml", "/opt/homebrew/share/mime/packages/freedesktop.org.xml",
"/usr/share/mime/packages/freedesktop.org.xml"]
## Railsユーザーはどうすればいい?
(2021/03/27現在)Rails 5.2.5 / 6.0.3.6 / 6.1.3.1 はmimemagicに依存しなくなりました。これらにバージョンアップしましょう。
https://weblog.rubyonrails.org/2021/3/26/marcel-upgrade-releases/
### 都合によりRailsをアップデートできない・したくない場合
アプリケーションを配布する際のライセンスがGPLになっても構わない、あるいは他者に配布しないのでGPLのライブラリがあっても問題ないのであれば、mimemagicをアップデートして対応することも可能です。
互換性を重視して0.3系を使う場合は以下のようにします。
0. `shared-mime-info` をインストールする
* macOS: `brew install shared-mime-info`
* Ubuntu, Debian: `apt-get install shared-mime-info`
* ruby:buster や cimg/ruby コンテナには元々入っているが、rubylang/ruby にはない
* Alpine Linux: `apk add shared-mime-info`
* ruby:alpine コンテナにはデフォルトでは入っていない
* Amazon Linux 2, Red Hat Enterprise Linux 8: (標準でインストール済みのため作業は不要)
* 詳しくは[mimemagicのドキュメント](https://github.com/mimemagicrb/mimemagic)を参照
1. Gemfileに `gem "mimemagic", "~> 0.3.10"` といった記述を追加する
2. ターミナルで`bundle update mimemagic` を実行する
### 他の方法
mimemagicに依存しているactivestorageが不要なら外す手もあります。
* (何らかの理由でRailsのバージョンを上げられない場合のみ?)
* https://gist.github.com/mensfeld/3437de2fae7fc58faccbf28c2e825443 のようにすればactivestorage gemをインストールせずにRailsを使える
* activestrorage以外に、paperclip~~やcarrierwave~~などもmimemagicに依存しています。そのため、それらのgemを使っている場合には単にactivestorageを外しただけではmimemagicの依存が外れないので注意が必要です。
## mimemagic 0.3系と0.4系の違い
- 0.4系はoverlay.rbが[削除されている](https://github.com/mimemagicrb/mimemagic/commit/0c9132141901ceaa298a563cdcd72896067f1dd6)
- `MimeMagic.add`の使用例みたいなもの
- デフォルトでは読み込まれない(`require "mimemagic/overlay"`)ので、これを使っていなければ0.4系で問題ないと思われる
- CarrierWave(2.2.0以下)では依存指定が `"mimemagic", ">= 0.3.0"` になっているため、このgemを使用している状態で `bundle update mimemagic` すると0.4系の最新版が入る場合がある。**ただしCarrierWaveには現時点で0.4系では削除されているoverlay.rbに依存しているコードがあるため、強制的に0.3系を指定する必要がある。**
- 具体的には、Gemfileに `gem 'mimemagic', '~> 0.3.0'` を追加して、0.3.x系を要求する。Railsと同じくCarrierWaveの次期バージョンでmimemagicへの依存が取り外されたら、この指定も削除してmimemagicをインストールしないようにすると良い。
## mimemagicに依存しているRails以外のgem
* [CarrierWave](https://github.com/carrierwaveuploader/carrierwave)
* ファイルアップロード用のメジャーな老舗gem。方式は違うがActiveStorageのような存在。
* ~~[こちらのissue](https://github.com/carrierwaveuploader/carrierwave/issues/2548)で有志が議論、対応中。 一部フォーク先で修正対応も?メンテナは静観中か。gemとしての公式対応は今のところなし。content typeを取得するためにmimemagicを使っているが、併用しているminimimeに一本化などは可能かも。~~
* ~~**上の「mimemagicを最新版に上げる」を行うと0.4.x系最新版が入ってしまうため、0.3.x系を強制する必要がある(上記のGemfileでの指定を参照)**~~
* ~~Railsに合わせてmimemagic依存をmarcelに切り替えるプルリクエストが出ている。マージされればRailsの対応バージョン以降では特別な対応が必要なくなりそう マージされました。次バージョンリリース待ち。~~
* 2.2.1がリリースされ、Rails同様にmarcelを使用することでmimemagicに依存しなくなりました。
* 2.2.0以下を使用する場合はmimemagicに依存するため、mimemagic 0.3.x系を強制する措置をとってください。
* [Carrierwave::Base64](https://github.com/y9v/carrierwave-base64)
* CarrierWaveと一緒に使用し、ファイルをBase64で扱うためのgem。
* [こちらのissue](https://github.com/y9v/carrierwave-base64/issues/84)がmimemagic関連。gemとしての公式対応は今のところなし。 内部的にファイルのバイナリからファイルタイプを判定するためにCarrierWaveの実装に追加してmimemagicを使用しているので、他のgemに変更などはできなさそう。
* 上の「mimemagicを最新版に上げる」を行うことで現時点では解消できる(CarrierWave単独使用時のmimemagicのバージョン問題は発生しない)
* v2.9.0がリリースされ、CarrierWaveと同じくmimemagicの代わりにmarcelを使うように。なお、CarrierWaveの2.2.1も必要になる。
* [Paperclip](https://github.com/thoughtbot/paperclip)
* ファイルアップロード用のメジャーな老舗gemで、CarrierWaveと人気を二分していた。ActiveStorageの登場でDeprecatedとなり、移行を推奨されている。
* [こちらのissue](https://github.com/thoughtbot/paperclip/issues/2678)で議論中。
* Deprecatedになった本家の[フォーク先](https://github.com/kreeti/kt-paperclip)では非公式にメンテナンス継続中で、[mimemagicを削除するPR](https://github.com/kreeti/kt-paperclip/pull/52)が立っている。
* フォーク先ではCarrierWaveと同じく、mimemagicをmarcelに切り替えるプルリクエストが出ている。
* 本家にも同様のプルリクエストが出ていたが、mimemagicがすでにMITライセンスであること、本家自体がDeprecatedであることから却下されている。。
## かんたんな経緯
1. mimemagic 0.3.5以前が、MITライセンスで配布されていたが、GPLのファイル(freedesktop.org.xml)に依存していた
2. 0.3.5までのすべてのgemがrubygems.orgからyank(削除)され、0.3.6がGPLとして公開された
3. 0.3.6が再度yankされ、システムにインストールされたfreedesktop.org.xmlを使うように変わった0.3.7がMITライセンスで再度リリースされた
* そのため、brew install shared-mime-infoなどでシステムにfreedesktop.org.xmlをインストールする必要が生じた
4. Railsがmimemagicへの依存を取り除いたバージョンをリリースした
* freedesktop.org.xmlの代わりに、[Apache Tika](https://tika.apache.org/)の情報(Apacheライセンス)を利用するようになった。[PR](https://github.com/rails/marcel/pull/30)
## GPL2.0ライセンスを利用すると、ソースコードを要求されたら開示しないといけないの?
https://www.gnu.org/licenses/old-licenses/gpl-2.0-faq.ja.html#GPLRequireSourcePostedPublic より引用
> GPLでは、あなたが改変した版をリリースすることは要求してはいません。改変を加えて、リリースせずに個人的に使うのはあなたの自由です。これは組織(企業を含む)でも同様で、ある組織は、改変した版を用意してそれを組織外にリリースすることなく内部的に利用することができます。
> しかし、もしあなたが改変された版を何らかの形で公にするならば、GPLはあなたが改変したソースコードをユーザがGPLのもとで入手できるようにすることを要求します。
>
> すなわち、GPLは改変されたプログラムを特定のやり方でリリースする許可を与えていますが、別の形でのリリースは許可していないのです。しかし、リリースするかどうかはあなた次第です。
## (おまけ)mimemagicバージョン一覧
https://rubygems.org/gems/mimemagic/versions
- ~0.3.5[yanked] MITライセンス 今回の件で取り下げられた。
- 0.3.6[yanked] ライセンスだけGPLv2に直したもの
- 0.4.0[yanked]
- 0.3.7 freedesktop.org.xmlを同梱しないようになり、代わりにユーザが自前で用意する形にすることでMITライセンスに戻った
- 0.3.8
- 0.3.9
- 0.3.10
- 0.4.1
- 0.4.2
- 0.4.3
参考
- https://github.com/mimemagicrb/mimemagic/blob/master/CHANGELOG.md
- https://github.com/mimemagicrb/mimemagic/commits/master
## (おまけ2) marcelの挙動変更について
marcelのmime type判定の挙動が一部変わっているので注意
https://sasa5740.hatenablog.com/entry/2021/03/29/223635
marcelでissueが上がっており、marcelのmimemagic外しの対応を行ったメンテナが反応しているのでそのうち修正されるかも。
https://github.com/rails/marcel/issues/35
## (おまけ3) rails 5.2.5 と 6.1.x 以外の rails を組み合わせて使っている人向けの注意点
> mimemagic に依存しなくなった rails 5.2.5 に CSRF トークンのフォーマットが Urlsafe Base64 になる変更が(意図せず?)入っているようで 5.2.5 で生成されたセッションが 5.2.4.x 以下 or 6.0.x で読めなくなってしまっているようなので rails 5.2.5 と 6.1.x 以外の rails を組み合わせて使っている人は要注意です。
https://github.com/rails/rails/issues/41783