RuboCopを使用したRubyコードのリンティングと自動フォーマット
リンティングは、プログラムおよびスタイルのエラーについてソースコードを自動チェックすることです。このチェックは、リンターと呼ばれる静的コード分析ツールによって実行されます。ただし、コードフォーマッタは、事前に構成された一連のルールに厳密に準拠するようにソースコードをフォーマットするためのツールです。リンターは通常違反を報告しますが、問題を修正するのは通常プログラマー次第ですが、コードフォーマッターはそのルールをソースコードに直接適用する傾向があるため、フォーマットの間違いを自動的に修正します。
プロジェクトでより一貫性のあるコードスタイルを作成するタスクでは、通常、個別のリンティングツールとフォーマットツールを導入する必要がありますが、場合によっては、1つのツールで両方の問題に対処できます。後者の良い例はRuboCopです。これは、この記事で詳しく検討するツールです。 Rubyプロジェクトでセットアップし、出力が期待どおりになるように構成オプションを調整する方法を学習します。ローカル開発プロセスに統合するだけでなく、継続的インテグレーションワークフローの一部にする方法も学習します。
RuboCopのインストール
RuboCopのインストールはRubyGemsを介して簡単です:
$ gem install rubocop
インストールされたバージョンを確認してください:
$ rubocop --version
1.18.3
Bundlerを使用する場合は、以下のスニペットをGemfile
に配置してください。 次に、bundle install
を実行します 。 require: false
一部はBundler.require
に通知します コマンドラインからのみ使用されるため、コードでその特定のgemを必要としないでください。
gem 'rubocop', require: false
インストールされたバージョンを確認してください:
$ bundle exec rubocop --version
1.18.3
RuboCopの実行
rubocop
と入力すると、プロジェクトのデフォルト設定を使用してRuboCopを実行できます。 (またはbundle exec rubocop
Bundlerと一緒にインストールされている場合)。コマンドに引数を渡さない場合、現在のディレクトリ内のすべてのRubyソースファイルとすべてのサブディレクトリがチェックされます。または、分析する必要のあるファイルとディレクトリのリストを渡すこともできます。
$ bundle exec rubocop
$ bundle exec rubocop src/lib
構成がない場合、RuboCopは、コミュニティ主導のRubyスタイルガイドで概説されているガイドラインの多くを適用します。コマンドを実行した後、いくつかのエラー(違反)が発生する場合があります。報告された各違反には、違反の説明、発生したファイルと行番号など、問題を解決するために必要なすべての情報が記載されています。
レポートの下部に、検査されたファイルの数、違反の総数、および自動的に修正できる違反の数を説明する行が表示されます。 -a
を追加した場合 または--auto-correct
引数として、RuboCopは、ソースファイル(接頭辞[Correctable]
が付いている問題)で見つかった問題を自動的に修正しようとします。 。
$ bundle exec rubocop -a
修正された各オフェンスのプレフィックスが[Corrected]
になっていることに注目してください。 。修正された違反の数の要約もレポートの下部に表示されます。上記の例では、-a
を追加した後でも、自動修正されなかった別の修正可能な違反があります。 国旗。これは、一部の自動修正によってコードのセマンティクスがわずかに変更される可能性があるため、RuboCopはそれを安全でないと見なしているためです。これらの違反も自動修正する場合は、-A
を使用してください または--auto-correct-all
フラグ。
$ bundle exec rubocop -A
従うべき経験則は、オートコレクト機能を使用した後にテストスイートを実行して、コードの動作が予期せず変更されていないことを確認することです。
RuboCopの構成
RuboCopは、.rubocop.yml
を介して構成できます プロジェクトのルートに配置されたファイル。すべてのプロジェクトに同じチェックを使用する場合は、グローバル構成ファイルをホームディレクトリ(~/.rubocop.yml
)に配置できます。 )またはXDG構成ディレクトリ(~/.config/rubocop/config.yml
)。このグローバル構成ファイルは、ローカルスコープのプロジェクト構成ファイルが現在のディレクトリまたは後続の親ディレクトリに見つからない場合に使用されます。
RuboCopのデフォルト構成は、その構成ホームディレクトリ(~/.config/rubocop/default.yml
)に配置されます。 )、および他のすべての構成ファイルはそれを継承します。これは、プロジェクト構成をセットアップするときに、デフォルトとは異なる変更を加えるだけでよいことを意味します。これは、特定のチェックを有効または無効にしたり、パラメータを受け入れる場合はその動作を変更したりすることを意味する場合があります。
RuboCopは、個々のチェックを警官と呼び、それぞれが特定の違反を検出する責任があります。利用可能な警官も次の部門にグループ化されています:
- スタイル警官は主に前述のRubyスタイルガイドに基づいており、コードの整合性をチェックします。
- レイアウト警官は、空白の使用など、フォーマットに関連する問題をキャッチします。
- Lint警官は、
ruby -w
と同様に、コードで発生する可能性のあるエラーを検出します 、ただし、追加のチェックが多数あります。 - メートル法の警官は、クラスの長さやメソッドの長さなど、ソースコードの測定に関連する問題を扱います。
- ネーミング警官はネーミング規則に関係しています。
- セキュリティ警官は、潜在的なセキュリティ問題を見つけるのに役立ちます。
- Bundlerの警官は、Bundlerファイル(
Gemfile
など)の不正行為をチェックします 。 - Gemspecの警官は
.gemspec
で悪い習慣をチェックします ファイル。
追加のリンターとフォーマッターを介してRuboCopを拡張することも可能です。独自の拡張機能を構築することも、プロジェクトに関連する場合は既存の拡張機能を利用することもできます。たとえば、Rails拡張機能は、Railsのベストプラクティスとコーディング規則を適用する目的で使用できます。
初めて構成ファイルを作成すると、追加されたが構成されていない新しい警官の存在を警告する多数のメッセージが表示されます。これは、RuboCopがリリースごとに新しい警官を追加し、ユーザー設定で明示的に有効または無効になるまで、これらが特別な保留状態に設定されるためです。メッセージにリストされている各警官を個別に有効または無効にするか、以下のスニペットを使用してすべての新しい警官を有効にすることができます(推奨)。その後、メッセージは抑制されます。
# .rubocop.yml
AllCops:
NewCops: enable
構成ファイルやRuboCopが提供する豊富なオプションをいじりたくない場合は、Standardプロジェクトを検討することを検討してください。これは主に、RuboCopの事前構成されたバージョンであり、ルールをカスタマイズすることなく、Rubyプロジェクトに一貫したスタイルを適用することを目的としています。最初に発表されたライトニングトークでは、その起源と動機について詳しく説明しています。
Gemfile
に次の行を追加することでインストールできます 次に、bundle install
を実行します 。
# Gemfile
gem "standard", group: [:development, :test]
その後、次のようにコマンドラインからStandardを実行できます。
$ bundle exec standardrb
ほとんどのRubyistには、グリーンフィールドプロジェクトに取り組む余裕がありません。私たちの開発時間の多くは、すぐに対処できない圧倒的な量のリンティングオフェンスを生み出す可能性のあるレガシーコードベースに費やされています。幸い、RuboCopには、既存の違反の許可リストを生成する便利な機能があり、時間の経過とともにゆっくりと対処できます。利点は、管理不能なリンティングエラーの山に襲われることなく、既存のプロジェクトにリンティングを導入できると同時に、今後の新しい違反にフラグを立てることができることです。
$ bundle exec rubocop
523 files inspected, 1018 offenses detected
許可リスト構成ファイルの作成は、以下のコマンドを使用して実行できます。
$ bundle exec rubocop --auto-gen-config
Added inheritance from `.rubocop_todo.yml` in `.rubocop.yml`.
Created .rubocop_todo.yml.
--auto-gen-config
オプションは、すべての違反とそのカウントを収集し、.rubocop_todo.yml
を生成します 現在のすべての違反が無視される現在のディレクトリ内のファイル。最後に、.rubocop.yml
が発生します .rubocop_todo.yml
から継承します コードベースでRuboCopをもう一度実行しても、問題が発生しないようにファイルを作成してください。
$ bundle exec rubocop
523 files inspected, no offenses detected
許可リストファイルの生成中に、違反の数が特定のしきい値(デフォルトでは15)を超えると、RuboCopは警官を完全にオフにします。これは、既存の違反の数が原因で新しいコードがその警官に対してチェックされるのを防ぐため、通常は希望するものではありません。幸い、違反の数が多い場合でも警官が無効にならないように、しきい値を上げることができます。
$ bundle exec rubocop --auto-gen-config --auto-gen-only-exclude --exclude-limit 10000
--auto-gen-only-exclude
オプションは、許可リスト内の各警官がExclude
を持つことを保証します Max
ではなく、違反が発生したすべてのファイルを一覧表示するブロック 、警官の除外ファイルの最大数を設定します。 --exclude-limit
の設定 Exclude
に追加できるファイルの最大数も変更します 各警官のブロック。調査対象のファイルの総数よりも大きい任意の数を指定すると、警官が完全に無効になることはなく、既存または新しいファイルに追加された新しいコードはそれに応じてチェックされます。
.rubocop_todo.yml
を生成した後 ファイルでは、既存の違反を忘れないで、次々とゆっくりと対処することが重要です。これを行うには、Exclude
からファイルを削除します 警官をブロックし、報告された違反を修正し、バグの導入を回避するためにテストスイートを実行し、コミットします。警官からすべてのファイルを削除したら、ファイルから警官を手動で削除するか、許可リストファイルをもう一度再生成できます。 --auto-correct
を利用することを忘れないでください 可能な場合は、プロセスをはるかに高速化するオプション。
RuboCopは非常に構成可能であるため、あらゆるタイプのプロジェクトで実行可能です。ただし、特にデフォルトのルールの多くに同意しない場合は、要件に合わせてルールを構成するのに長い時間がかかる場合があります。このような状況では、既存のスタイルガイドを採用することが有益な場合があります。 ShopifyやAirbnbなど、いくつかの企業がすでにRubyスタイルガイドを公開しています。 RuboCopで好みのスタイルガイドを利用するには、関連するgemをGemfile
に追加します。 :
# Gemfile
gem "rubocop-shopify", require: false
次に、プロジェクト構成でそれを要求します:
# .rubocop.yml
inherit_gem:
rubocop-shopify: rubocop.yml
RuboCopは優れたツールですが、誤検知が発生したり、プログラマーの意図に反する方法でコードを修正することを提案したりする可能性があります。このような状況が発生した場合は、ソースコードにコメントを付けて違反を無視できます。以下に示すように、無効にする個々の警官または部門について言及することができます。
# rubocop:disable Layout/LineLength, Style
[..]
# rubocop:enable Layout/LineLength, Style
または、コードのセクションのすべての警官を一挙に無効にすることができます:
# rubocop:disable all
[..]
# rubocop:enable all
行末コメントを使用すると、指定された警官はその行だけで無効になります。
for x in (0..10) # rubocop:disable Style/For
毎回コマンドラインからチェックを実行する代わりに、エディターにコードを入力するときにRuboCopによって生成される警告とエラーを表示すると便利です。ありがたいことに、RuboCop統合は、ほとんどの一般的なコードエディターとIDEで、主にサードパーティのプラグインを介して利用できます。 Visual Studio Codeでは、このRuby拡張機能をインストールし、ユーザーのsettings.json
に以下を配置するだけです。 ファイル:
{
"ruby.lint": {
"rubocop": true
}
}
VimまたはNeovimを使用している場合は、coc.nvimを介してRuboCopの診断を表示できます。 Solargraph言語サーバーをインストールする必要があります(gem install solargraph
)、続いてcoc-solargraph拡張機能(:CocInstall coc-solargraph
)。その後、coc-settings.json
を構成します 以下に示すようなファイル:
{
"coc.preferences.formatOnSaveFiletypes": ["ruby"],
"solargraph.autoformat": true,
"solargraph.diagnostics": true,
"solargraph.formatting": true
}
プロジェクト内のすべてのRubyコードが、ソース管理にチェックインされる前に適切にリントおよびフォーマットされていることを確認する優れた方法は、ステージングされた各ファイルでRuboCopを実行するGitpre-commitフックを設定することです。この記事では、Gitの事前コミットフックを管理および構成するためのツールであるOvercommitを使用してセットアップする方法を説明しますが、既存の事前コミットワークフローがある場合は、RuboCopを他のツールと統合することもできます。
まず、RubyGemsを介してOvercommitをインストールしてから、プロジェクトにインストールします。
$ gem install overcommit
$ overcommit --install # at the root of your project
上記の2番目のコマンドは、リポジトリ固有の設定ファイル(.overcommit.yml
)を作成します )現在のディレクトリにあり、既存のフックをバックアップします。このファイルはデフォルト構成を拡張するため、デフォルトに関して構成を指定するだけで済みます。たとえば、次のスニペットを使用してRuboCoppre-commitフックを有効にすることができます。
# .overcommit.yml
PreCommit:
RuboCop:
enabled: true
on_warn: fail
problem_on_unmodified_line: ignore
command: ['bundle', 'exec', 'rubocop']
on_warn: fail
設定すると、Overcommitは警告を失敗として扱いますが、problem_on_unmodified_line: ignore
ステージングされなかった行の警告とエラーが無視される原因になります。プロジェクトのGitHubページで、使用可能なすべてのフックオプションとそれらの許容値の範囲を参照できます。 overcommit --sign
を実行する必要がある場合があります 構成ファイルを変更して変更を有効にした後。
場合によっては、すべてのチェックに合格しないファイル(進行中の作業など)をコミットする場合は、ケースバイケースで個々のチェックをスキップできます。
$ SKIP=RuboCop git commit -m "WIP: Unfinished work"
RuboCopをCIワークフローに追加する
プルリクエストごとにRuboCopチェックを実行することは、不適切な形式のコードがプロジェクトにマージされるのを防ぐもう1つの方法です。どのCIツールでも設定できますが、この記事では、GitHubアクションを介してRuboCopを実行する方法についてのみ説明します。
最初のステップは、.github/workflows
を作成することです プロジェクトのルートにあるディレクトリとrubocop.yml
新しいディレクトリ内のファイル。エディターでファイルを開き、次のように更新します。
# .github/workflows/rubocop.yml
name: Lint code with RuboCop
on: [push, pull_request]
jobs:
build:
runs-on: ${{ matrix.os }}
strategy:
matrix:
os: [macos-latest, ubuntu-latest, windows-latest]
steps:
- uses: actions/checkout@v2
- name: Setup Ruby
uses: ruby/setup-ruby@v1
with:
ruby-version: '3.0'
bundler-cache: true
- name: Run RuboCop
run: bundle exec rubocop
上記のワークフローファイルは、コードがGitHubにプッシュされたとき、または任意のブランチに対してプルリクエストが行われたときに実行される単一のジョブを記述しています。 job
順番に実行される一連のステップです。この特定のジョブは、GitHub Actionsによって提供される最新のUbuntu、MacOS、およびWindowsバージョン(runs-on
で定義)で1回実行されます。 およびstrategy.matrix
)。最初のステップはリポジトリ内のコードをチェックアウトし、次のステップはRubyツールチェーンと依存関係を設定し、最後のステップはRuboCopを実行します。
ファイルの編集が完了したら、ファイルを保存してコミットし、GitHubにプッシュします。その後、後続のチェックインとプルリクエストで報告された問題がインラインで表示されます。
RuboCopは包括的な自動フォーマット機能を提供しますが、ニーズを十分に満たしていない場合に備えて、代替ツールに注意することも重要です。
Prettierは、JavaScriptの独創的なコードフォーマッターとしてスタートしましたが、現在はRubyを含む他の多くの言語をサポートしています。 Rubyプラグインのインストールは簡単です。prettier
を追加してください Gemfile
へのgem 次に、bundle
を実行します 。
# Gemfile
gem 'prettier'
この時点で、次のコマンドを使用してRubyコードをPrettierでフォーマットできます。
$ bundle exec rbprettier --write '**/*.rb'
Prettierのルールの一部はRuboCopのルールと競合するため、Prettierに干渉しないように、後者のフォーマットチェックを無効にする必要があります。幸い、Prettierと競合する、または不要なRuboCopチェックをオフにするのは簡単です。プロジェクトの.rubocop.yml
の上部にあるPrettierのRuboCop構成を継承するだけです。 ファイル:
# .rubocop.yml
inherit_gem:
prettier: rubocop.yml
RuboCopを実行する場合(bundle exec rubocop
)今後、レイアウトに関連する違反は報告されず、Prettierが独自のルールに従ってそれらを修正するための道が開かれます。 Prettierの出力は、同じプロジェクト内のJavaScriptコードとRubyコードの間で共有できる構成ファイルを介して構成することもできます。
RubyFmt
RubyFmtは、Rustで記述され、現在活発に開発されている新しいコードフォーマッターです。 Prettierと同様に、コード分析ツールではなく、フォーマッターとして使用することを目的としています。まだ安定したリリースが見られていないので、今は採用を控えるべきでしょうが、それは間違いなく注目すべきものです。
コードのリンティングと自動フォーマットは、特に開発者のチームのコンテキストでは、コードベースに非常に多くの利点をもたらします。コードのフォーマット方法を教えられたくない場合でも、リンティングは自分だけのものではないことを覚えておく必要があります。また、共同作業を行う他の人々も同じ規則に従うことができるため、同じプロジェクトで複数のコーディングスタイルを扱うことの欠点がなくなります。
リンターの出力を福音として扱わないことも重要です。そのため、主な目的を損なうことなく、最もメリットが得られるように構成するようにしてください。 RuboCopの広範な構成設定により、これは問題にはなりません。ただし、RuboCopの構成に時間がかかりすぎる場合は、前述のように事前定義されたスタイルガイドを使用するか、詳細を気にすることなく誰もが使用できる構成なしの代替手段としてStandardを採用できます。 。
読んでくれてありがとう、そして幸せなコーディング!
-
Rubyでの静的分析
ソースコードを解析して、すべてのメソッド、それらが定義されている場所、およびそれらが取る引数を見つけたいとします。 どうすればこれができますか? あなたの最初のアイデアはそれのために正規表現を書くことかもしれません… しかし、もっと良い方法はありますか? はい! 静的分析 は、ソースコード自体から情報を抽出する必要がある場合に使用できる手法です。 これは、ソースコードをトークンに変換する(解析する)ことによって行われます。 さっそく始めましょう! パーサージェムの使用 Rubyには標準ライブラリで利用可能なパーサーがあります。名前はRipperです。出力を操作するのは難し
-
iPad と iPhone で QR コードをスキャンする方法
2018 年の初めに、技術大手の Apple が展開した驚くべき機能は iOS 12 です。iPad と電話で QR コードをスキャンすることは、Apple のユーザー エクスペリエンスを次のレベルに引き上げるために追加された機能の 1 つです。この機能は、生活を楽にするだけでなく、チケット、クーポン、製品の成分などに関する情報を取得するのにも役立ちます。さらに、スマートフォンの助けを借りて QR コードをスキャンできる固有の QR コード認識が付属しています。無意味にカメラ。 QR コードをスキャンすることで、購入前に商品に関する情報を数秒以内に収集できます。 この投稿では、iPad