hotoolong's blog

プログラムのことやエンジニアリングに関することを記事にしています。

ghq list の 代替案

イントロ

普段 ghqとfzfを使ってリポジトリの切り替えをしています。
とても便利なのですが、最近、かなりもっさりしてきて遅いので改善を考えてみました。

改善方法

ボトルネックとしてはghq listがとても遅くなっていました。

簡易改善

ghq root 配下のディレクトリがそこまで多くない場合 git だけを対象とした改善方法をよく見かけました。

ghq list --vcs=git

こちらで改善する場合はこれだけで良さそうです。

今回実施した改善

findに置き換えて改善している記事を見たいのですが、私の場合は動作がもっさりしたままでした。
そこでRUST製のfdを使いことにしました。
バージョン管理がすべてgitで管理してるのでgitの特性から.gitファイルを探すことにしました。

ghq list

fd --type d --min-depth 2 --max-depth 4 --hidden --search-path $i '.git$' | sed -e "s/\/.git\$//"

に変更しています。

このコマンドでは .gitディレクトリを探して .git を削り一覧化しています。
--min-depth 2 --max-depth 4 と しているのは
ghq root を複数設定していてローカルに作成してるリポジトリディレクトリ構造を考慮しています。
利用される方はお好みに合わせて変えるのが良いかと思います。

今回の変更のdiffは以下の様になっています.

gd configs/fish/config.fish
diff --git configs/fish/config.fish configs/fish/config.fish
index 9f2755c..5659e0c 100644
--- configs/fish/config.fish
+++ configs/fish/config.fish
@@ -210,15 +210,20 @@ function fzf_select_ghq_repository
     set fzf_query --query "$query"
   end

-  set -l out (ghq list --vcs=git | \
+  set -l out (
+    for i in (ghq root -all)
+      fd --type d --min-depth 2 --max-depth 4 --hidden --search-path $i '.git$' | \
+      sed -e "s/\/.git\$//"
+    end | \
     fzf $fzf_query \
       --prompt='Select Repository >' \
-      --preview="echo {} | cut -d'/' -f 2- | xargs -I{} gh repo view {} ")
+      --preview="echo {} | awk -F'/' '{ print \$(NF-1)\"/\"\$NF}' | \
+    xargs -I{} gh repo view {}"
+  )
   [ $status != 0 ] && commandline -f repaint && return

   if test -n $out
-    set -l dir_path (ghq list --vcs=git --full-path --exact $out)
-    commandline "cd $dir_path"
+    commandline "cd $out"
     commandline -f execute
   end
 end

これでかなり速度が改善されていて快適になりました。
もっといい方法がありそうなので、何かあればコメントないしはDMなどでご連絡いただけると嬉しいです。

参考URL

scrapbox.io

autopp-tech.hatenablog.com

rake release で エラーがでた

イントロ

以前の記事でembed_callbacksを作成したと取り上げたのですが、
その中でRubyGemsでユーザ登録に失敗してたのですが、
サポートの人に対応していただきメールアドレスを変更していただきました。

これでやっと登録できるなと思って登録してみたのですが少しトラブルにあったのでこちらに記載しておきます。
ちなみに登録したgemのアドレスは以下になります。
これでgem install とインストール可能になるのでとてもいい気分です。

rubygems.org

遭遇したエラー

rake releaseしたときに既存のブランチとupstream branchが違うよと指摘された内容になります。

$ rake release
embed_callbacks 0.1.0 built to pkg/embed_callbacks-0.1.0.gem.
Tagged v0.1.0.
Untagging v0.1.0 due to error.
rake aborted!
Couldn't git push. `git push ' failed with the following output:

fatal: The upstream branch of your current branch does not match
the name of your current branch.  To push to the upstream branch
on the remote, use

    git push origin HEAD:trunk

To push to the branch of the same name on the remote, use

    git push origin HEAD

To choose either option permanently, see push.default in 'git help config'.

/Users/hotoolong/.rbenv/versions/2.7.0/bin/bundle:23:in `load'
/Users/hotoolong/.rbenv/versions/2.7.0/bin/bundle:23:in `<main>'
Tasks: TOP => release => release:source_control_push
(See full trace by running task with --trace)

git init してはじめに変更したブランチがtrunkでした。
BLM運動がきっかけてmasterはどうなのかという話がありdefault branch名をどうするか決めかねていたときに以下のコマンドでtrunkにしました。

git branch --set-upstream-to=origin/trunk

その後 github上でmainにしようという流れになっていた(以下のリンク)のでmainに変更していました。

GitHub - github/renaming: Guidance for changing the default branch name for GitHub repositories

git branch -m trunk main
git push -u origin main

ただ、upstreamの設定がそのままになっていたようです。

解決方法

git config -e

してtrunkをmainに置き換えてしまいました。 これで再度rake release するとうまくいきました。 よかったです。

embed_callbacksに機能追加した

概要

前回の記事embed_callbacksというgemを紹介しました。
こちらの機能を追加したので紹介していきます。

追加した機能

  • メソッドがエラーになったときに処理を呼び出せる
  • メソッドエラーになっても呼び出せる

rescue

これはその名の通りでrescueを設定するとエラー時に呼びされます。
コードを見てもらったほうがわかりやすいかと思うので下記にサンプルを記載しておきます。

require 'embed_callbacks'

class Sample
  include EmbedCallbacks
  set_callback :target, :rescue, :rescue_callback

  def target
    raise 'target'
  end

  def rescue_callback
    puts 'rescue_callback'
  end

end
sample = Sample.new
sample.target

#=> rescue_callback
#=> RuntimeError (target)

encure

こちらも同様にencureになります。
こちらはafterに近いかもしれないですが、
エラーが発生しても必ず呼び出されます。

require 'embed_callbacks'

class Sample
  include EmbedCallbacks
  set_callback :target, :ensure, :ensure_callback

  def target
    puts 'target'
  end

  def ensure_callback
    puts 'ensure_callback'
  end

end
sample = Sample.new
sample.target
#=> target
#=> ensure_callback

その他

RubyGemsへの登録

前回からの進捗はない状態ですが、
slackの#rubygemsで質問してみたところ、同様の問題質問があることを教えてもらいました。
Wrong emails when signup / Problems / Discussion Area - RubyGems.org Support
こちらを見ると SUPPORT STAFF で対応してもらい解決したようです。
一旦サポートにメールを送ってみました。
返信までは時間がかかるようなのでしばらく待ってみようと思います。

まとめ

callbackという感じではないですが、 rescue、ensureを後付で追加したいケースがあり作成してみました。
よかったらつかってみてください。

メソッドにcallbackを追加するgemをつくってみた

概要

以前からgemを作ってみたいと思いつつ作れてなかったので作成してみました。
methodにcallbackを追加するembed_callbacksというgemを作成しました。
探すと似たようなgemが出てくるので車輪の再発明的なものになりますが作成してみました.

gemの機能

まだそこまで機能はないのですが以下のようになります。

  • メソッドの前に処理を追加
  • メソッドの後に処理を追加
  • メソッドの前後に処理を追加

上記を簡単に呼び出せるようにしています。
今後更に機能は追加する予定です。詳細はGitHubを確認していただければと思います。

gemの作り方

参考記事

https://qiita.com/coe401_/items/8e90373a76f590ef0abe
しおいさんがQiitaで取り上げてくれた記事を参考にしました。
丁寧に説明してくれていてとてもいい記事ですね。

gemの命名

https://guides.rubygems.org/name-your-gem/
こちらの記事でどのような命名するとよいか記載されている内容を参考にしました。

gem searchコマンドもしくは https://rubygems.org/ から作成するgem名を検索しておき
同じ名前にならないようにしておくのがいいかと思います。
はじめに考えていた名前はすでに登録されていたので別名を考えていた今回の命名になりました。
命名は先行優位ですね。

困ったこと

RubyGemsへの登録

RubyGemsにユーザ登録時のメールアドレスを間違ってしまい、
確認メールをチェックできなくなってしまいました。
ログインはできるのですが確認メールをチェックしてください。というような文言で確認できない状況です。
メールアドレスは一度目の登録からは変更できないようなので、
とりあえずはRubyGemsには登録しないでしばらくGitHubだけで公開しておきます。
同様の問題で困っている人は少なそうですが、解決方法がわかる方いらっしゃいましたら情報いただければと思います。
どうしようもなくなったらhotoolong2みたいなのにして登録しようと思います。

gemの作成

参考記事にはbundle gem hogehoge などすると対話式にオプションを設定できるようなものもあったのですが、私の環境ではそうならなかったので引数などを設定しました。

$ bundle gem embed_callbacks --test=rspec --coc --mit
Creating gem 'embed_callbacks'...
MIT License enabled in config
Code of conduct enabled in config
      create  embed_callbacks/Gemfile
      create  embed_callbacks/lib/embed_callbacks.rb
      create  embed_callbacks/lib/embed_callbacks/version.rb
      create  embed_callbacks/embed_callbacks.gemspec
      create  embed_callbacks/Rakefile
      create  embed_callbacks/README.md
      create  embed_callbacks/bin/console
      create  embed_callbacks/bin/setup
      create  embed_callbacks/.gitignore
      create  embed_callbacks/.travis.yml
      create  embed_callbacks/.rspec
      create  embed_callbacks/spec/spec_helper.rb
      create  embed_callbacks/spec/embed_callbacks_spec.rb
      create  embed_callbacks/LICENSE.txt
      create  embed_callbacks/CODE_OF_CONDUCT.md
Initializing git repo in /Users/hotoolong/repositories/embed_callbacks
Gem 'embed_callbacks' was successfully created. For more information on making a RubyGem visit https://bundler.io/guides/creating_gem.html

まとめ

比較的簡単に作成まではいけそうなので、他にもgemにしていなかったものや放置してるものを徐々にupしていければいいかなと思っています。 なにか助言やPRなど私の困ったことへの解決の糸口になるものなどアドバイスいただければとてもありがたいです。

参考にした記事

はじめての自作gem 「Hello, Tama!」を出力してみる - Qiita
RubyGemはめっちゃ簡単に作れる! | 酒と涙とRubyとRailsと
https://qiita.com/yu-croco/items/a93693d02ca39ac38f78
RubyGemsの作り方 - Qiita
Bundler: How to create a Ruby gem with Bundler
Name your gem - RubyGems Guides
GitHubリポジトリのREADMEの良さそうな書き方・テンプレート - karaage. [からあげ]
個人gemのCIをほぼ全部Travis CIからGitHub Actionsに移行した - くりにっき
GitHub Actions がローンチされたのでマイグレートしてる - HsbtDiary(2019-08-11)
GitHub - actions/setup-ruby: Set up your GitHub Actions workflow with a specific version of Ruby
今の時代だからこそオススメする車輪の再発明|erukiti

fzfをつかってRailsのmigrationを実行しやすくする

イントロ

Railsのmigationを実行する機会はそこまで多くはないと思うのですが、
generateしてつくったあとにVERSIONの選択が意外と面倒だったりします。

以前の記事

hotoolong.hatenablog.com

でgit statusをfzfのpreviewやbindを使って操作しやすくしましたが、

railsのmigration管理もpreviewとbindと親和性が高いなと思い作ってみました。

fish shell の function

以下のようなfish の function を作成しています。

function migrate
  if test ! -d 'db/migrate'
    echo 'Go to Rails Root'
    return
  end

  set -l out (ls -1 db/migrate | grep -v -e '^\.' | \
    fzf --exit-0 \
      --preview="bat --color=always db/migrate/{}" \
      --expect=ctrl-u,ctrl-d,ctrl-r,ctrl-m \
      --header='C-u: up, C-d: down, C-r: redo, C-m(Enter): edit' \
  )
  [ $status != 0 ]; and commandline -f repaint; and return

  if string length -q -- $out
    set -l key $out[1]
    set -l time (echo $out[2] | awk -F '_' '{ print $1 }')
    echo $key
    if test $key = 'ctrl-u'
      commandline "./bin/rails db:migrate:up VERSION=$time"
    else if test $key = 'ctrl-d'
      commandline "./bin/rails db:migrate:down VERSION=$time"
    else if test $key = 'ctrl-r'
      commandline "./bin/rails db:migrate:redo VERSION=$time"
    else if test $key = 'ctrl-m'
      commandline "$EDITOR db/migrate/$out[2]"
    end
    commandline -f execute
  end
end

操作方法

functionを登録してコマンドを実行するとfzf が起動します。

$ migrate

f:id:hotoolong:20200420002914g:plain
migration

migrate:up migrate:down migrate:redo を key bind しているので
バージョンを指定してアクションを決めて実行することができます。

これで少し便利になりました。

previewにはbatコマンドを使っていますが、headなどでもいいかと思います。

よかったら使ってみてください。

brewのformulaアップグレード時の依存関係のアップグレードによる弊害に対応する

イントロ

googlerをアップグレードしたところopensslのバージョンがあがって
他のツールが壊れてしまったのを戻す作業をした履歴です。
困ってる人の役に当てればと思います。

エラーと調査

ことの始まりは

$ brew upgrade googler

googlerの新しいバージョンがでてるからupgradeしました。

==> Upgrading 1 outdated package:
googler 3.7.1 -> 4.0_1
==> Upgrading googler 3.7.1 -> 4.0_1
==> Installing dependencies for googler: openssl@1.1, xz and python@3.8
==> Installing googler dependency: openssl@1.1
==> Downloading https://homebrew.bintray.com/bottles/openssl@1.1-1.1.1f.mojave.bottle.tar.gz
==> Downloading from https://akamai.bintray.com/25/25ab844d2f14fc85c7f52958b4b89bdd2965bbd9c557445829eff6473f238744?__gda__=exp=1586836802~hmac=b9c5e50d09
6a9d953daac8c75
######################################################################## 100.0%
==> Pouring openssl@1.1-1.1.1f.mojave.bottle.tar.gz
==> Caveats
A CA file has been bootstrapped using certificates from the system
keychain. To add additional certificates, place .pem files in
  /usr/local/etc/openssl@1.1/certs

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

openssl@1.1 is keg-only, which means it was not symlinked into /usr/local,
because macOS provides LibreSSL.

If you need to have openssl@1.1 first in your PATH run:
  echo 'set -g fish_user_paths "/usr/local/opt/openssl@1.1/bin" $fish_user_paths' >> ~/.config/fish/config.fish

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

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

==> Summary
🍺  /usr/local/Cellar/openssl@1.1/1.1.1f: 8,057 files, 18MB
==> Installing googler dependency: xz
==> Downloading https://homebrew.bintray.com/bottles/xz-5.2.5.mojave.bottle.tar.gz
==> Downloading from https://akamai.bintray.com/44/44483961b5d2b535b0ece1936c9d40b4bc7d9c7281646cca0fb476291ab9d4dc?__gda__=exp=1586836818~hmac=45f8f52462
3d23ee5d13f2dad
######################################################################## 100.0%
==> Pouring xz-5.2.5.mojave.bottle.tar.gz
🍺  /usr/local/Cellar/xz/5.2.5: 92 files, 1.1MB
==> Installing googler dependency: python@3.8
==> Downloading https://homebrew.bintray.com/bottles/python@3.8-3.8.2.mojave.bottle.tar.gz
==> Downloading from https://akamai.bintray.com/51/511b4f2c3993f000516938ed0700936c8a7d8c054b5171fa733ac7d344291c30?__gda__=exp=1586836821~hmac=0271b874c6
5db4ee2c7f66f1d
######################################################################## 100.0%
==> Pouring python@3.8-3.8.2.mojave.bottle.tar.gz
==> /usr/local/Cellar/python@3.8/3.8.2/bin/python3 -s setup.py --no-user-cfg install --force --verbose --install-scripts=/usr/local/Cellar/python@3.8/3.8.
2/bin --install
==> /usr/local/Cellar/python@3.8/3.8.2/bin/python3 -s setup.py --no-user-cfg install --force --verbose --install-scripts=/usr/local/Cellar/python@3.8/3.8.
2/bin --install
==> /usr/local/Cellar/python@3.8/3.8.2/bin/python3 -s setup.py --no-user-cfg install --force --verbose --install-scripts=/usr/local/Cellar/python@3.8/3.8.
2/bin --install
==> Caveats
Python has been installed as
  /usr/local/opt/python@3.8/bin/python3

You can install Python packages with
  /usr/local/opt/python@3.8/bin/pip3 install <package>
They will install into the site-package directory
  /usr/local/opt/python@3.8/Frameworks/Python.framework/Versions/3.8/lib/python3.8/site-packages

brew upgrade すると
dependencyになっている formula がアップグレードされます。
openssl も バージョンアップされてしまいます。
以前もこの問題で python がアップグレードしてパスが変更されてしまいいろいろ動作できないソフトがあって困ったことがありました。

今回も気づかず
暫くして
rails cをしてみたところ以下のようなエラーに

$ rails c 
/rails_project/vendor/bundle/ruby/2.7.0/gems/bootsnap-1.4.6/lib/bootsnap/load_path_cache/core_ext/kernel_require.rb:23:in `requir
e': dlopen(/rails_project/vendor/bundle/ruby/2.7.0/gems/mysql2-0.5.3/lib/mysql2/mysql2.bundle, 9): Library not loaded: /usr/local
/opt/openssl/lib/libssl.1.0.0.dylib (LoadError)
  Referenced from: /rails_project/vendor/bundle/ruby/2.7.0/gems/mysql2-0.5.3/lib/mysql2/mysql2.bundle
  Reason: image not found - /rails_project/vendor/bundle/ruby/2.7.0/gems/mysql2-0.5.3/lib/mysql2/mysql2.bundle

あれ?
起動しない

LoadErrorになっている。
opensslのライブラリが参照できなくなっている

opensslのバージョンが上がっていることに気づく

エラー内容をGoogleで調べているとライブラリを読み込ませると動く模様

mysql2をインストールしたときに参照しているopensslを参照できないようなので

一旦mysql2は削除して入れ直すことに

$ brew info openssl

を確認すると

  set -gx LDFLAGS "-L/usr/local/opt/openssl@1.1/lib"
  set -gx CPPFLAGS "-I/usr/local/opt/openssl@1.1/include"

とあり、ライブラリのパスが確認できます。

bindle 時に利用できるように以下のように config に設定します。

$ bundle config --local build.mysql2 "--with-ldflags=-L/usr/local/opt/openssl@1.1/lib"

mysql2を入れ直すためアンインストールします。

$ bundle exec gem uninstall mysql2

再度インストール

$ bundle install

起動してみます。

$ rails c

インストール時にはライブラリを参照してくれてそうだけどエラーは解消しませんでした。

/rails_project/vendor/bundle/ruby/2.7.0/gems/bootsnap-1.4.6/lib/bootsnap/load_path_cache/core_ext/kernel_require.rb:23:in `requir
e': dlopen(/rails_project/vendor/bundle/ruby/2.7.0/gems/mysql2-0.5.3/lib/mysql2/mysql2.bundle, 9): Library not loaded: /usr/local/opt/openssl/lib/libssl.1.0.0.dylib (LoadError)
  Referenced from: /usr/local/opt/mysql/lib/libmysqlclient.20.dylib
  Reason: image not found - /rails_project/vendor/bundle/ruby/2.7.0/gems/mysql2-0.5.3/lib/mysql2/mysql2.bundle

rails cでライブラリの古い方を見てしまうようです。
PATHなどを確認して古いopensslのライブラリを参照しないようにしてますが
いろいろ調べてるがこれ以上はわからない状態でした。

opensslのインストール先を確認

$ brew --prefix openssl
/usr/local/opt/openssl@1.1

PATHに古いopensslが残っていて古いバージョンを参照していました。

$ which openssl
/usr/local/opt/openssl/bin/openssl

PATHの設定を見直して新しいバージョンを参照させて、再度bundleしなおしても駄目でした。

お手上げ感があったのですが、
mysql2.bundleがイマイチよくわかっておらず調べていると

qastack.jp

どうもmysql自体のインストール時に参照するライブラリを決め打ちしてそうということがわかり

一旦mysqlを停止してみました。

$ sudo mysql.server stop
Password:
dyld: Library not loaded: /usr/local/opt/openssl/lib/libssl.1.0.0.dylib
  Referenced from: /usr/local/Cellar/mysql/5.7.17/bin/my_print_defaults
  Reason: image not found
Shutting down MySQL
... SUCCESS!

あら、rails c したときと同じようなエラーが、、、

起動もできなくなったので、
opensslのバージョンを戻すことに

brew で uninstall すると 依存関係のあるformulaが多いので怒られるが
--ignore-dependenciesをつけるとアンインストールできます。

$ brew uninstall --ignore-dependencies openssl
Uninstalling /usr/local/Cellar/openssl@1.1/1.1.1f... (8,057 files, 18MB)

古いopensslのライブラリをインストールする

$ brew install https://github.com/tebelorg/Tump/releases/download/v1.0.0/openssl.rb
Updating Homebrew...

これで1.0.2tがインストールされた。
(他のやりかたでインストールできるかもしれないが調べきれてない。)

mysqlを起動してみる

$ sudo mysql.server start 

Starting MySQL
.. SUCCESS!

起動できた!

bundle configの内容をバージョンダウンしたopensslに合わせる(戻す)

$ bundle config --local build.mysql2 "--with-ldflags=-L/usr/local/opt/openssl/lib"

再度mysql2を入れ直す

$ bundle exec gem uninstall mysql2
$ bundle install

まとめ

結局opensslのバージョンを一旦戻すことにした。
おそくらbrew upgrade で影響のある formula を上げていけばいいのだが、
上げたくないものもあるので、悩ましいところ。

brew で formula の依存関係を確認することができる。
brew deps コマンドが使える
今回のgooglerの場合だと以下の通り

$ brew deps --tree googler
googler
└── python@3.8
    ├── gdbm
    ├── openssl@1.1
    ├── readline
    ├── sqlite
    │   └── readline
    └── xz

ということで python経由でopensslのバージョンアップがされてしまったと気付ける。

逆にopensslがどのformulaが利用してるかというと以下のように uses オプションが使える。

$ brew uses --installed  openssl
asdf                  glib                  imagemagick           mysql                 python@3.8            shared-mime-info      vim
docutils              gnupg                 libevent              poco                  rbenv                 tmux
erlang                gnutls                libheif               python                ruby                  unbound

またautoupgradeさせない方法もあった。

$ brew pin openssl

というようにするとバージョンが固定されるようです。 解除するには

$ brew unpin openssl

とすると解除できます。
積極的に活用しようと思います。

RailsのRubyバージョンを2.7.0から2.7.1に上げる

いつものようにRailsRubyバージョンを上げていこうかと思います。

まずはruby-buildの最新化します。

$ brew upgrade ruby-build

rubyをrbenvで管理しているのでrbenvで2.7.1をビルドします。

$ rbenv install 2.7.1

Rails root の.ruby-version を 2.7.1 に変更

$ ruby -v
ruby 2.7.1p83 (2020-03-31 revision a0c7c23c9c) [x86_64-darwin18]
$ bundle --version
Bundler version 2.1.4

Gemfileのrubyのバージョンを変更

ruby '2.7.1'

.ruby-versionとGemfileのバージョンをあわせてbundle installします。

$ bundle install

rails c を起動するとエラーが表示されました。

Traceback (most recent call last):
        15: from bin/rails:3:in `<main>'
        14: from bin/rails:3:in `require_relative'
        13: from /rails_project/config/boot.rb:4:in `<top (required)>'
        12: from /rails_project/config/boot.rb:4:in `require'
        11: from /rails_project/vendor/bundle/ruby/2.7.0/gems/bootsnap-1.4.6/lib/bootsnap/setup.rb:2:in `<top (required)>'
        10: from /rails_project/vendor/bundle/ruby/2.7.0/gems/bootsnap-1.4.6/lib/bootsnap/setup.rb:2:in `require_relative'
         9: from /rails_project/vendor/bundle/ruby/2.7.0/gems/bootsnap-1.4.6/lib/bootsnap.rb:4:in `<top (required)>'
         8: from /rails_project/vendor/bundle/ruby/2.7.0/gems/bootsnap-1.4.6/lib/bootsnap.rb:4:in `require_relative'
         7: from /rails_project/vendor/bundle/ruby/2.7.0/gems/bootsnap-1.4.6/lib/bootsnap/load_path_cache.rb:74:in `<top (required)>'
         6: from /rails_project/vendor/bundle/ruby/2.7.0/gems/bootsnap-1.4.6/lib/bootsnap/load_path_cache.rb:74:in `require_relative'
         5: from /rails_project/vendor/bundle/ruby/2.7.0/gems/bootsnap-1.4.6/lib/bootsnap/load_path_cache/store.rb:4:in `<top (required)>'
         4: from /rails_project/vendor/bundle/ruby/2.7.0/gems/bootsnap-1.4.6/lib/bootsnap/explicit_require.rb:41:in `with_gems'
         3: from /rails_project/vendor/bundle/ruby/2.7.0/gems/bootsnap-1.4.6/lib/bootsnap/load_path_cache/store.rb:4:in `block in <top (required)>'
         2: from /rails_project/vendor/bundle/ruby/2.7.0/gems/bootsnap-1.4.6/lib/bootsnap/load_path_cache/store.rb:4:in `require'
         1: from /rails_project/vendor/bundle/ruby/2.7.0/gems/msgpack-1.3.3/lib/msgpack.rb:9:in `<top (required)>'
/rails_project/vendor/bundle/ruby/2.7.0/gems/msgpack-1.3.3/lib/msgpack.rb:9:in `require': cannot load such file -- msgpack/2.7/msgpack (LoadError)
        16: from bin/rails:3:in `<main>'
        15: from bin/rails:3:in `require_relative'
        14: from /rails_project/config/boot.rb:4:in `<top (required)>'
        13: from /rails_project/config/boot.rb:4:in `require'
        12: from /rails_project/vendor/bundle/ruby/2.7.0/gems/bootsnap-1.4.6/lib/bootsnap/setup.rb:2:in `<top (required)>'
        11: from /rails_project/vendor/bundle/ruby/2.7.0/gems/bootsnap-1.4.6/lib/bootsnap/setup.rb:2:in `require_relative'
        10: from /rails_project/vendor/bundle/ruby/2.7.0/gems/bootsnap-1.4.6/lib/bootsnap.rb:4:in `<top (required)>'
         9: from /rails_project/vendor/bundle/ruby/2.7.0/gems/bootsnap-1.4.6/lib/bootsnap.rb:4:in `require_relative'
         8: from /rails_project/vendor/bundle/ruby/2.7.0/gems/bootsnap-1.4.6/lib/bootsnap/load_path_cache.rb:74:in `<top (required)>'
         7: from /rails_project/vendor/bundle/ruby/2.7.0/gems/bootsnap-1.4.6/lib/bootsnap/load_path_cache.rb:74:in `require_relative'
         6: from /rails_project/vendor/bundle/ruby/2.7.0/gems/bootsnap-1.4.6/lib/bootsnap/load_path_cache/store.rb:4:in `<top (required)>'
         5: from /rails_project/vendor/bundle/ruby/2.7.0/gems/bootsnap-1.4.6/lib/bootsnap/explicit_require.rb:41:in `with_gems'
         4: from /rails_project/vendor/bundle/ruby/2.7.0/gems/bootsnap-1.4.6/lib/bootsnap/load_path_cache/store.rb:4:in `block in <top (required)>'
         3: from /rails_project/vendor/bundle/ruby/2.7.0/gems/bootsnap-1.4.6/lib/bootsnap/load_path_cache/store.rb:4:in `require'
         2: from /rails_project/vendor/bundle/ruby/2.7.0/gems/msgpack-1.3.3/lib/msgpack.rb:8:in `<top (required)>'
         1: from /rails_project/vendor/bundle/ruby/2.7.0/gems/msgpack-1.3.3/lib/msgpack.rb:11:in `rescue in <top (required)>'
/rails_project/vendor/bundle/ruby/2.7.0/gems/msgpack-1.3.3/lib/msgpack.rb:11:in `require': incompatible library version - /rails_project/vendor/bundle/ruby/2.7.0/gems/msgpack-1.3.3/lib/msgpack/msgpack.bundle (LoadError)
        16: from bin/rails:3:in `<main>'
        15: from bin/rails:3:in `require_relative'
        14: from /rails_project/config/boot.rb:4:in `<top (required)>'
        13: from /rails_project/config/boot.rb:4:in `require'
        12: from /rails_project/vendor/bundle/ruby/2.7.0/gems/bootsnap-1.4.6/lib/bootsnap/setup.rb:2:in `<top (required)>'
        11: from /rails_project/vendor/bundle/ruby/2.7.0/gems/bootsnap-1.4.6/lib/bootsnap/setup.rb:2:in `require_relative'
        10: from /rails_project/vendor/bundle/ruby/2.7.0/gems/bootsnap-1.4.6/lib/bootsnap.rb:4:in `<top (required)>'
         9: from /rails_project/vendor/bundle/ruby/2.7.0/gems/bootsnap-1.4.6/lib/bootsnap.rb:4:in `require_relative'
         8: from /rails_project/vendor/bundle/ruby/2.7.0/gems/bootsnap-1.4.6/lib/bootsnap/load_path_cache.rb:74:in `<top (required)>'
         7: from /rails_project/vendor/bundle/ruby/2.7.0/gems/bootsnap-1.4.6/lib/bootsnap/load_path_cache.rb:74:in `require_relative'
         6: from /rails_project/vendor/bundle/ruby/2.7.0/gems/bootsnap-1.4.6/lib/bootsnap/load_path_cache/store.rb:4:in `<top (required)>'
         5: from /rails_project/vendor/bundle/ruby/2.7.0/gems/bootsnap-1.4.6/lib/bootsnap/explicit_require.rb:40:in `with_gems'
         4: from /rails_project/vendor/bundle/ruby/2.7.0/gems/bootsnap-1.4.6/lib/bootsnap/explicit_require.rb:44:in `rescue in with_gems'
         3: from /rails_project/vendor/bundle/ruby/2.7.0/gems/bootsnap-1.4.6/lib/bootsnap/load_path_cache/store.rb:4:in `block in <top (required)>'
         2: from /rails_project/vendor/bundle/ruby/2.7.0/gems/bootsnap-1.4.6/lib/bootsnap/load_path_cache/store.rb:4:in `require'
         1: from /rails_project/vendor/bundle/ruby/2.7.0/gems/msgpack-1.3.3/lib/msgpack.rb:9:in `<top (required)>'
/rails_project/vendor/bundle/ruby/2.7.0/gems/msgpack-1.3.3/lib/msgpack.rb:9:in `require': cannot load such file -- msgpack/2.7/msgpack (LoadError) 17: from bin/rails:3:in `<main>'
        16: from bin/rails:3:in `require_relative'
        15: from /rails_project/config/boot.rb:4:in `<top (required)>'
        14: from /rails_project/config/boot.rb:4:in `require'
        13: from /rails_project/vendor/bundle/ruby/2.7.0/gems/bootsnap-1.4.6/lib/bootsnap/setup.rb:2:in `<top (required)>'
        12: from /rails_project/vendor/bundle/ruby/2.7.0/gems/bootsnap-1.4.6/lib/bootsnap/setup.rb:2:in `require_relative'
        11: from /rails_project/vendor/bundle/ruby/2.7.0/gems/bootsnap-1.4.6/lib/bootsnap.rb:4:in `<top (required)>'
        10: from /rails_project/vendor/bundle/ruby/2.7.0/gems/bootsnap-1.4.6/lib/bootsnap.rb:4:in `require_relative'
         9: from /rails_project/vendor/bundle/ruby/2.7.0/gems/bootsnap-1.4.6/lib/bootsnap/load_path_cache.rb:74:in `<top (required)>'
         8: from /rails_project/vendor/bundle/ruby/2.7.0/gems/bootsnap-1.4.6/lib/bootsnap/load_path_cache.rb:74:in `require_relative'
         7: from /rails_project/vendor/bundle/ruby/2.7.0/gems/bootsnap-1.4.6/lib/bootsnap/load_path_cache/store.rb:4:in `<top (required)>'
         6: from /rails_project/vendor/bundle/ruby/2.7.0/gems/bootsnap-1.4.6/lib/bootsnap/explicit_require.rb:40:in `with_gems'
         5: from /rails_project/vendor/bundle/ruby/2.7.0/gems/bootsnap-1.4.6/lib/bootsnap/explicit_require.rb:44:in `rescue in with_gems'
         4: from /rails_project/vendor/bundle/ruby/2.7.0/gems/bootsnap-1.4.6/lib/bootsnap/load_path_cache/store.rb:4:in `block in <top (required)>'
         3: from /rails_project/vendor/bundle/ruby/2.7.0/gems/bootsnap-1.4.6/lib/bootsnap/load_path_cache/store.rb:4:in `require'
         2: from /rails_project/vendor/bundle/ruby/2.7.0/gems/msgpack-1.3.3/lib/msgpack.rb:8:in `<top (required)>'
         1: from /rails_project/vendor/bundle/ruby/2.7.0/gems/msgpack-1.3.3/lib/msgpack.rb:11:in `rescue in <top (required)>'
/rails_project/vendor/bundle/ruby/2.7.0/gems/msgpack-1.3.3/lib/msgpack.rb:11:in `require': incompatible library version - /rails_project/vendor/bundle/ruby/2.7.0/gems/msgpack-1.3.3/lib/msgpack/msgpack.bundle (LoadError)

msgpackの参照してるライブラリで参照エラーになってしまうようです。

私の場合はbundle install の際に path を vendor/bundle に設定しているので、
vendor/bundle/ruby/2.7.0 配下を削除して bundle install しなおします。
今回の2.7.1の場合, patchバージョン変更のため2.7.0のディレクトリがそのまま使われるようです。

Dockerなどでvendor配下を共有している場合も同様の事象に遭遇する可能性があるので
一旦削除して再インストールすると良いかもしれなれないです。

bundle upgrade の helpをみてみると options --ruby の項目があり

  --ruby Update the locked version of Ruby to the current version of Ruby.

と記載されていたので、 試してみたのですが 同様のエラーになって動作しなかったので使い方が違いそうです。

テストがある方は rails testなどでテストして動作確認してください。

$ rails test