RuboCop RSpecでrake実行時にrake aborted! default.yml is out of syncが出たときの対応
はじめに
RuboCop RSpecプロジェクトで、コードを修正してrakeを走らせたときに少し詰まってしまったので、備忘録として残しておきます。
なお、この記録は2021/05/16時点の情報となります。
条件
- プロジェクト:
- 修正ファイル
- config/default.yml
- libフォルダ以下のファイル
- specフォルダ以下のファイル
- 修正ファイルはすべてunstageのまま
現象
bundle exec rake
を実行すると、rake aborted! default.yml is out of sync
となってしまいました。
$ bundle exec rake
・・・略・・・
You can opt out of this message by adding the following to your config (see https://docs.rubocop.org/rubocop/extensions.html#extension-suggestions for more options):
AllCops:
SuggestExtensions: false
rake aborted!
default.yml is out of sync:
diff --git a/config/default.yml b/config/default.yml
index 1b3b7d3..c4fb381 100644
--- a/config/default.yml
+++ b/config/default.yml
@@ -469,10 +469,12 @@ RSpec/MissingExampleGroupArgument:
StyleGuide: https://www.rubydoc.info/gems/rubocop-rspec/RuboCop/Cop/RSpec/MissingExampleGroupArgument
RSpec/MultipleDescribes:
- Description: Checks for multiple top-level example groups.
+ Description: Checks for multiple top-level example groups or nested example groups.
Enabled: true
VersionAdded: '1.0'
+ VersionChanged: '2.4'
StyleGuide: https://www.rubydoc.info/gems/rubocop-rspec/RuboCop/Cop/RSpec/MultipleDescribes
+ Splitting: false
RSpec/MultipleExpectations:
Description: Checks if examples contain too many `expect` calls.
Run bin/build_config
/Users/xxx/rubocop-rspec/Rakefile:45:in `block in <top (required)>'
/Users/xxx/rubocop-rspec/vendor/bundle/ruby/2.7.0/gems/rake-13.0.3/exe/rake:27:in `<top (required)>'
/Users/yyy/.rbenv/versions/2.7.0/bin/bundle:23:in `load'
/Users/yyy/.rbenv/versions/2.7.0/bin/bundle:23:in `<main>'
Tasks: TOP => default => confirm_config
(See full trace by running task with --trace)
$
原因
結論
gitでconfig/default.ymlをaddしていなかっただけです。
調査
エラーとして記載されているRakefileの該当箇所を見てみると、
desc 'Confirm config/default.yml is up to date'
task confirm_config: :build_config do
_, stdout, _, process =
Open3.popen3('git diff --exit-code config/default.yml')
raise <<~ERROR unless process.value.success?
default.yml is out of sync:
#{stdout.read}
Run bin/build_config
ERROR
end
とありました。
エラーメッセージが出る理由は、unless process.value.success?
がfalse
のためのようです。
では、なぜfalse
となるのか?
1つずつたどっていきます。
git diff --exit-code config/default.yml
のコマンドについて
git diff --exit-code
の説明を公式サイトで確認します。
Make the program exit with codes similar to diff(1). That is, it exits with 1 if there were differences and 0 means no differences.
この説明と、条件項目でconfig/default.ymlはunsatgeの状態であったことから、差分が残っているとなり、exit codeが1となります。
Open3.popen3
について
process
を返しているOpen3.popen3
を見てみます。
def popen3(*cmd, &block)
if Hash === cmd.last
opts = cmd.pop.dup
else
opts = {}
end
in_r, in_w = IO.pipe
opts[:in] = in_r
in_w.sync = true
out_r, out_w = IO.pipe
opts[:out] = out_w
err_r, err_w = IO.pipe
opts[:err] = err_w
popen_run(cmd, opts, [in_r, out_w, err_w], [in_w, out_r, err_r], &block)
end
popen3
メソッドではpopen_run
メソッドを呼び出しているので、そのコードを見てみます。
def popen_run(cmd, opts, child_io, parent_io) # :nodoc:
pid = spawn(*cmd, opts)
wait_thr = Process.detach(pid)
child_io.each(&:close)
result = [*parent_io, wait_thr]
if defined? yield
begin
return yield(*result)
ensure
parent_io.each(&:close)
wait_thr.join
end
end
result
end
spawn
で実行コマンドのプロセスIDを返し、Process.detach
で終了ステータスをProcess::Status
としてwait_thr
にセットし、返しているようです。
よってgit diff --exit-code
のコマンドの調査と組み合わせると、今回は終了コードが1だったので、successとならず、今回の現象が起きたと思われます。
対応
git addしてbundle exec rakeを再実行しました。
その結果、abortedすることなく完了しました。
$ bundle exec rake
・・・略・・・
You can opt out of this message by adding the following to your config (see https://docs.rubocop.org/rubocop/extensions.html#extension-suggestions for more options):
AllCops:
SuggestExtensions: false
Files: 92
Modules: 14 ( 6 undocumented)
Classes: 94 ( 0 undocumented)
Constants: 144 ( 143 undocumented)
Attributes: 1 ( 0 undocumented)
Methods: 277 ( 242 undocumented)
26.23% documented
* generated /Users/xxx/rubocop-rspec/docs/modules/ROOT/pages/cops_rspec.adoc
* generated /Users/xxx/rubocop-rspec/docs/modules/ROOT/pages/cops_rspec/capybara.adoc
* generated /Users/xxx/rubocop-rspec/docs/modules/ROOT/pages/cops_rspec/factorybot.adoc
* generated /Users/xxx/rubocop-rspec/docs/modules/ROOT/pages/cops_rspec/rails.adoc
$
終わりに
最初にエラーを見たときは、rake実行時のエラーなのになぜout of syncなのだろうと疑問に思っていました。
実際に蓋を開けてみたところ単純な原因でしたが、なぜエラーになるのかと1つずつ紐解いて経験を積むことができたので良かったと思います。
この記事が誰かのお役に立てれば幸いです。
Discussion