gem install bundleの罠
TL;DR
ネタ記事です。Aliasのためだけに存在しているgemがあるというお話を少し掘り下げています。
はじめに
Rubyを使って開発していると、ふいにbundle install
が使えず、慌ててgem install bundle
と打ってしまうってことありませんか?
(ちなみに、最近のRubyではbundlerがデフォルトで入っているので、bundle install
が通らないなんてことはかなり減りましたが、、)
正しくは、gem install bundler
です。
そんなことはしないよと思った方、ぜひgem list | grep bundle
を実行してみてください。
bundle (0.0.1) bundler (x.x.x)
と表示される方は意外と多いのではないでしょうか?気づかぬうちにbundleというgemがインストールされていませんか?
gem install bundle
とすると何が起こるのでしょう。bundleを調べると、このgem自体は空で、依存関係にbundlerが設定されていることがわかります。
つまり、gem install bundleによってbundlerもインストールされるので、全く問題なく動きます。
実害はちょっとだけ環境を汚されてしまうことだけです。 (もしこのgemの作者が悪意を持っていたら結構怖い事になると思いますが、完全に善意のようですね。)
驚くことに、このgemは約478万回(2020/01/02時点)もダウンロードされており、例えばpuma_worker_killer(約481万ダウンロード)と同程度にダウンロードされています!
うまくAliasを貼っただけのgemを作れば、これだけのダウンロード数のgem作者になれるわけです!
他にもこういったgemはありそうなので調べてみました。
gemのlistを集める
robots.txtを見るとスクレイピングは禁止っぽいです。
どうしようと思ったらちゃんとデータが配布されているので、こちらからダウンロードします。
bundlerに似たgemを集める
雑にbundlerとのレーベンシュタイン距離が1のgemを探します。levenshtein-ffiというgemを使って計算しました。
require 'levenshtein' gems = File.read('gem_list.txt').split similar_gems = gems.select do |gem| Levenshtein.distance('bundler', gem) == 1 end puts similar_gems
bindler bndler bundle bundlr bungler bunlder byndler fundler jbundler rundler vundler
なんかたくさんある!この中からAliasじゃないgemを除きます。
bundle 約478万ダウンロード bunlder 約38000ダウンロード bundlr 約5500ダウンロード byndler 約4000ダウンロード bndler 約3000ダウンロード
結局見つかったのはこの5つでした、そして、ダウンロード数はbundleが圧倒的でした。
考察
bundlerはよく使うコマンドがbundle
だったため、bundleという間違えが多い。これはtypoというよりは勘違いに起因している気がしました。
bunlderに関してはtypoだが、ダウンロード数はそれほど多くないようです。
また、同種の間違いをしているgem、例えばraisl
などは、比率で考えても更に少ないダウンロード数でした。
Gemfile経由でダウンロードする際には間違えにくいような気がします。
「コマンドとgem名が違う」「Gemfile経由でダウンロードすることが少ない」などの好条件を満たさないと、bundleほどのダウンロード数を作れなさそうです。
おわりに
1年半くらい前に自分のgem listを見て気づいたネタをやっと供養できました。