+1

RUBOCOP

RUBOCOP

Rubocop là một công cụ để kiểm tra code style dựa trên ruby-style-guide, xây dựng lên để phục vụ cho developers. Việc sử dụng Rubocop trong dự án sẽ giúp bạn tiết kiệm rất nhiều thời gian cho việc review coding convention, đảm bảo code không bị mắc phải những lỗi cơ bản.

Rubocop sử dụng các quy tắc được định sẵn, và so sánh chúng với code của bạn để đưa ra các thông báo lỗi. Dễ dàng nhận thấy các lợi ích khi sử dụng rubocop đó là:

  • Dễ dàng kiểm tra các lỗi cơ bản về coding convention, tiết kiệm thời gian cho dự án.
  • Tạo ra sự đồng bộ về source code cho dự án.
  • Dễ dàng nắm bắt, thống kê soure code của dự án (độ dài tối đa của lines, method, class, module …. các lỗi còn tồn tại …)
  • Các quy tắc dễ dàng tùy chỉnh để phù hợp với từng quy tắc của riêng mỗi dự án.

rubocop-logo.png

Cài đặt

Cách 1 : cài đặt gem cho phiên bản ruby mà bạn đang sử dụng.

Rvm use 2.1.5  //my ruby version
gem install rubocop

Cách 2 : Cho vào Gemfile và bundle install

gem 'rubocop'

Cách dùng

// Chạy tất cả thư mục
rubocop

//hạy riêng 1 thư mục
rubocop app/

//Chạy riêng 1 file
rubocop app/controllers/test_controller.rb

//hoặc bạn có thể chạy đồng thời các thư mục và các file khác nhau
rubocop app/controllers/test_controller.rb app/models/ app/views/test/index.rb

Output

Ví dụ với một đoạn code ngắn sau

class TestController < ActionController::Base
  def method_name name
    if condition
    error = "invalid method name"
      end
    end
end

chạy rubocop với

rubocop app/controllers/test_controller.rb

và kết quả là

warning: please see https://github.com/whitequark/parser#compatibility-with-ruby-mri.
Inspecting 1 file
W

Offenses:

app/controllers/test_controller.rb:2:19: W: Unused method argument - name. If it's necessary, use _ or _name as an argument name to indicate that it won't be used. You can also write as method_name(*) if you want the method to accept any arguments but don't care about them.
  def method_name name
                  ^^^^
app/controllers/test_controller.rb:5:7: W: end at 5, 6 is not aligned with if at 3, 4.
      end
      ^^^
app/controllers/test_controller.rb:6:5: W: end at 6, 4 is not aligned with def at 2, 2.
    end
    ^^^

1 file inspected, 3 offenses detected

Như trên thì rubocop đang thông báo 3 Warning

  • Warning 1 : Đối số của phương thức là “name” không được sử dụng ởi bên trong, bạn nên dùng _ hoặc _name để thay thế cho tên đối số, và cũng nên thêm _ vào phần đầu tên của các đối số không sử dụng.
  • Warning 2 : vị trí của end ở dòng 5 không cùng lề với if ở dòng 3
  • Warning 3 : vị trí của end ở dòng 6 không cùng lề với def ở dòng 2

Với thông báo như vậy bạn sẽ dễ dàng phát hiện và sửa chữa lỗi ngay lập tức. Và sau đây là danh sách các kí hiệu thông báo khi chạy của rubocop

|Symbol|Description | ||| |.|File không có lỗi rubocop| |C|Có lỗi liên quan đến convention| |E|Có lỗi liên quan đến logic| |F|Có một fatal error| |W|Có một cảnh báo|

Cops

Trong rubocop, các quy tắc kiểm tra được gọi là cops. Các cops được chia thành các loại như sau

  • Style

Hầu hết các cops ở trong rubocop là thuộc dạng style, dùng để check các vấn đề về phong cách code của bạn.Và hầu hết chúng đều dựa trên Ruby Style Guide. Nhiều style cops có các lựa chọn cài đặt để hỗ trợ những coding convention khác nhau.

  • Lint

Lint cop để check các lỗi có thể xảy ra, các phần thực hiện có thể gây ra lỗi trong code của bạn. Bạn có thể chỉ chạy lint cop với lệnh $ rubocop -l lựa chọn -l/--lint có thể được sử dụng cùng với --only để chạy tất cả các lint cops được enable thêm với một phần của cops khác. Việc disable bất kì lint cop nào đó là một ý tưởng tồi, vì lint cop rất quang trọng, nó có thể gây ra các lỗi nghiêm trọng cho hệ thống.

  • Metrics

Đây là cops dùng để thống kê, đo lường code của bạn. Chẳng hạn như chiều dài của dòng, chiều dài của phương thức, chiều dài của lớp, module …. Và nó sẽ có một tham số là max, và khi chạy rubocop thì tham số này sẽ được thiết lập là giá trị cao nhất cho cop đó.

  • Rails

Rails cops là đặc trưng riêng cho Ruby on Rails framwork. Không giống như style và line cops, nó không được sử dụng mặc định mà bạn cần phải yêu cầu một cách cụ thể.

$ rubocop -R

Hoặc thêm yêu cầu sau vào trong file .rubocop.yml của bạn.

AllCops:
  RunRailsCops: true

Config

Tùy từng dự án, từng công ty mà các quy tắc khi code cũng sẽ khác nhau, chính vì thế rubocop không cố định hoàn toàn các quy tắc lỗi. Bạn hoàn toàn có thể chỉnh sửa config để rubocop bắt lỗi theo đúng những gì mà bạn muốn. Bạn có thể sửa trong file .rubocop.yml, lúc này nó sẽ overwrite lên các cops mặc định tương ứng của nó.

Cú pháp ở trong này như sau

rule_name:
  Description: 'a description of a rule'
  Enabled : (true or false)
  Key: Value

Trong đó

  • rule_name là tên của một cop
  • Description : mô tả cop
  • Enable : cho phép cop có được thực hiện hay không, thông thường theo mặc định sẽ là true.
  • Key và Value : dùng để thêm thông tin cho một cop nào đó, ví dụ như các giá trị Max cho độ dài của dòng, của phương thức, của class ….

Ví dụ một file .rubocop.yml

inherit_from: ../.rubocop.yml
Style/Encoding:
  Enabled: false
Metrics/LineLength:
  Max: 99

Inheritance

Rubocop hỗ trợ kế thừa các config từ một hoặc nhiều tập tin config khác trong thời gian chạy

  • Bạn có thể kế thừa từ một file config của một project khác

Tùy chọn inherit_from có thể được sử dụng để include config từ một hoặc nhiều file. Điều khiến cho nó có thể có những setting chung giữa các project trong một file .rubocop.yml gốc nào đó, và sau đó có thể tùy chỉnh ở các file, các thư mục con.

inherit_from:
  - ../.rubocop.yml
  - ../conf/.rubocop.yml
  • Bạn có thể kế thừa từ một URL

Tùy chọn inherit_from cũng có thể chưa một địa chỉ đầy đủ đến một tệp tin từ xa. Điều này khiến cho nó có thể lưu trữ một setting chung cho các project tại một địa chỉ http và chia sẻ giữa nhiều project. Bạn có thể đồng thời kế thừa từ cả ở URL và cả file cục bộ. Các quy tắc chung được kết thừa ở cả các URL và file cục bộ đều hoạt động theo quy tắc là : Các file (các cops) được include đầu tiên sẽ có độ ưu tiên thấp nhất, và các file (các cops) được include sau sẽ có độ ưu tiên cao nhất.

inherit_from:
  - http://www.example.com/rubocop.yml
  - ../.rubocop.yml
  • Hoặc bạn cũng có thể kế thừa từ một gem
inherit_gem:
  my-shared-gem: .rubocop.yml
  cucumber: conf/rubocop.yml

Tuy nhiên nếu như gem phụ thuộc đó phải sử dụng bundle install thì khi chạy rubocop cũng phải sử dụng bundle để tìm đường dẫn của gem phụ thuộc đó.

$ bundle exec rubocop <options...>

Including/Excluding files

Rubocop kiểm tra tất cả các tập tin được tìm thấy bằng một tìm kiếm đệ quy bắt đầu từ chính thư mục cha nó và chạy vào bên trong hoặc các thư mục được đưa ra bởi dòng lệnh. Tuy nhiên nó chỉ nhận ra các tập tin .rb hoặc các extension với liệt kê #!.* như là một file ruby. Các thư mục ẩn sẽ không được tìm kiếm bằng mặc định. Nếu bạn muốn kiểm tra các file không được bao gồm trong mặc định thì bạn cần bỏ qua nó hoặc thêm nó dưới AllCops/Include. Và các tệp tin hay thư mục cũng có thể bị loại trừ thông qua AllCops/Exclude.

Ví dụ

AllCops:
  Include:
    - '**/Rakefile'
    - '**/config.ru'
  Exclude:
    - 'db/**/*'
    - 'config/**/*'
    - 'script/**/*'
    - !ruby/regexp /old_and_unused\.rb$/

# other configuration
# ...

Vậy là các bạn đã hiểu và có thể dùng rubocop, ở blog tiếp mình sẽ liệt kê danh sách các lỗi rubocop mà mình đã làm việc. P/S : hãy dùng rubocop ngay hôm nay để code của bạn sẽ đẹp hơn.


All rights reserved

Viblo
Hãy đăng ký một tài khoản Viblo để nhận được nhiều bài viết thú vị hơn.
Đăng kí