LoginSignup
1
0

More than 1 year has passed since last update.

semgrepでbelongs_toにoptional: trueを一括で追加した

Last updated at Posted at 2022-12-10

Rails のバージョンを上げて belongs_to_required_by_default を変更したり、 load_defaults を指定するときに、 belongs_tooptional: true をつけるか、古いバージョンでの required: true 相当でも動くようになっている必要があります。

その書き換えに semgrep を使ってみるとうまくいったので、その紹介です。

動作確認バージョン

  • Ruby 2.7.6
  • Rails 6.0.6
  • semgrep 0.122.0

belongs_to_required_by_default の例

# 古い挙動に戻す
# config.load_defaults 5.0以上の直後に追加
config.active_record.belongs_to_required_by_default = false

# 新しい挙動にする(config.load_defaults 5.0以上と同じ)
# https://github.com/rails/rails/blob/v7.0.4/railties/lib/rails/application/configuration.rb#L100
# config/initializers/new_framework_defaults_*.rb ならこの書き方になっている
Rails.application.config.active_record.belongs_to_required_by_default = true

semgrep での置き換え

試行錯誤して以下の内容のファイルを用意しました。

belongs_to.yaml
rules:
  - id: belongs_to_optional
    message: 'Add "optional: true" to belongs_to.'
    patterns:
    - pattern-not: 'belongs_to(..., optional: $V, ...)'
    - pattern-not: 'belongs_to(..., required: $V, ...)'
    - pattern: 'belongs_to(...)'
    fix-regex:
      regex: '^([\s\S]+)(\)?)$'
      replacement: '\1, optional: true\2'
    languages: [ruby]
    severity: WARNING

対象の Rails アプリのディレクトリでこのファイルを -f で指定して semgrep --autofix を実行すると belongs_tooptional: true を追加できました。

$ semgrep -f .../belongs_to.yaml --autofix

苦労した点

  • 最初にsynvertを試そうとしたら、https://synvert.net/ は javascript 用がメインになっているらしく、ruby 用は synvert-ruby になっていました。
  • synvert-ruby も試しましたが、 belongs_to の引数の途中に改行が入っているときに synvert-ruby がエラーで落ちてしまうことがあって、使いにくかったので他の方法を試しました。
  • rubocop での auto correct も検討しましたが、検出がメインなので、 synvert-ruby 以上に書き換えの書き方が難しそうだったので、調査は後回しにしました。
  • semgrepで最初はfix-regex.regex^ をつけていなかったら、なぜか , optional: true, optional: true と2回追加されていました。

まとめ

semgrep はパターンの書き方が独特でとっつきにくいですが、パターンを重ねていけるので、 grep をパイプでつないでいくように簡単なパターンの組み合わせで絞り込めるので、慣れれば使いやすそうです。

文脈を意識した検索や置換が必要なときに候補のひとつとして覚えておくと良さそうです。

1
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
0