Skip to content

Commit

Permalink
Merge pull request #502 from nimblehq/release/5.12.0
Browse files Browse the repository at this point in the history
Release - 5.12.0
  • Loading branch information
malparty authored Jan 12, 2024
2 parents a6dcfe7 + e62b869 commit c676ca2
Show file tree
Hide file tree
Showing 9 changed files with 190 additions and 2 deletions.
10 changes: 10 additions & 0 deletions .rubocop.yml
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ require:
- rubocop-rails
- rubocop-rspec
- rubocop-performance
- ./rubocop/custom_cops/required_inverse_of_relations.rb

AllCops:
Exclude:
Expand All @@ -21,6 +22,9 @@ AllCops:
Style/Documentation:
Enabled: false

Style/DocumentationMethod:
Enabled: true

Layout/LineLength:
Max: 130
Exclude:
Expand Down Expand Up @@ -50,3 +54,9 @@ RSpec/NestedGroups:

RSpec/MultipleExpectations:
Max: 10

CustomCops/RequiredInverseOfRelations:
Enabled: true
Include:
# Only Rails model files
- !ruby/regexp /models\//
5 changes: 5 additions & 0 deletions .template/addons/custom_cops/template.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
# frozen_string_literal: true

require 'fileutils'

copy_file 'rubocop/custom_cops/required_inverse_of_relations.rb', mode: :preserve
4 changes: 2 additions & 2 deletions .template/addons/github/.github/workflows/test.yml.tt
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ jobs:
password: ${{ env.DOCKER_REGISTRY_TOKEN }}

- name: Pull Docker image
if: ${{ env.BRANCH_TAG != 'latest' && env.BRANCH_TAG != 'development' }}
if: ${{ env.BRANCH_TAG != 'latest' && env.BRANCH_TAG != 'develop' }}
run: docker-compose pull test || true

- name: Build Docker image
Expand All @@ -63,7 +63,7 @@ jobs:
- uses: actions/checkout@v3

- name: Set env BRANCH_TAG
uses: nimblehq/branch-tag-action@v1.2
uses: nimblehq/branch-tag-action@1

- name: Login to Docker registry
uses: docker/login-action@v2
Expand Down
4 changes: 4 additions & 0 deletions .template/addons/svgeez/helpers/svg_helper.rb
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,10 @@ module SvgHelper
height: '16'
}.freeze

# @param [Hash<String: String>] html
# @param [String] icon_id
#
# @return [String]
def svg_tag(html: {}, icon_id: '')
svg_attributes = DEFAULT_SVG_ATTRIBUTES.merge(html)

Expand Down
6 changes: 6 additions & 0 deletions rubocop/Gemfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
# frozen_string_literal: true

source 'https://rubygems.org'

gem 'rspec'
gem 'rubocop'
53 changes: 53 additions & 0 deletions rubocop/Gemfile.lock
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
GEM
remote: https://rubygems.org/
specs:
ast (2.4.2)
diff-lcs (1.5.0)
json (2.7.1)
language_server-protocol (3.17.0.3)
parallel (1.24.0)
parser (3.2.2.4)
ast (~> 2.4.1)
racc
racc (1.7.3)
rainbow (3.1.1)
regexp_parser (2.8.3)
rexml (3.2.6)
rspec (3.12.0)
rspec-core (~> 3.12.0)
rspec-expectations (~> 3.12.0)
rspec-mocks (~> 3.12.0)
rspec-core (3.12.2)
rspec-support (~> 3.12.0)
rspec-expectations (3.12.3)
diff-lcs (>= 1.2.0, < 2.0)
rspec-support (~> 3.12.0)
rspec-mocks (3.12.6)
diff-lcs (>= 1.2.0, < 2.0)
rspec-support (~> 3.12.0)
rspec-support (3.12.1)
rubocop (1.59.0)
json (~> 2.3)
language_server-protocol (>= 3.17.0)
parallel (~> 1.10)
parser (>= 3.2.2.4)
rainbow (>= 2.2.2, < 4.0)
regexp_parser (>= 1.8, < 3.0)
rexml (>= 3.2.5, < 4.0)
rubocop-ast (>= 1.30.0, < 2.0)
ruby-progressbar (~> 1.7)
unicode-display_width (>= 2.4.0, < 3.0)
rubocop-ast (1.30.0)
parser (>= 3.2.1.0)
ruby-progressbar (1.13.0)
unicode-display_width (2.5.0)

PLATFORMS
arm64-darwin-22

DEPENDENCIES
rspec
rubocop

BUNDLED WITH
2.4.17
36 changes: 36 additions & 0 deletions rubocop/custom_cops/required_inverse_of_relations.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
# frozen_string_literal: true

module CustomCops
class RequiredInverseOfRelations < RuboCop::Cop::Base
MSG = 'Use inverse_of option when defining associations to prevent avoidable SQL queries and keep models in sync.'

# Optimization: don't call `on_send` unless the method name is in this list
RESTRICT_ON_SEND = %i[has_many belongs_to].freeze
ASSOCIATION_METHODS = RESTRICT_ON_SEND.to_set

def_node_matcher :association_expression_no_arguments?, <<~PATTERN
(send nil? ASSOCIATION_METHODS (sym _))
PATTERN

def_node_matcher :association_expression_with_arguments?, <<~PATTERN
(send nil? ASSOCIATION_METHODS (sym _) (hash $...))
PATTERN

# See https://docs.rubocop.org/rubocop/development.html#writing-node-pattern-rules
def on_send(node)
return add_offense(node) if association_expression_no_arguments?(node)

hash_pairs = association_expression_with_arguments?(node)

add_offense(node) if hash_pairs && !contain_inverse_of?(hash_pairs)
end

private

def contain_inverse_of?(nodes)
pattern = RuboCop::NodePattern.new('(pair (sym :inverse_of) _)')

nodes.any? { pattern.match(_1) }
end
end
end
71 changes: 71 additions & 0 deletions rubocop/spec/required_inverse_of_relations_spec.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
# frozen_string_literal: true

require 'rubocop'
require 'rubocop/rspec/support'
require_relative '../cops/required_inverse_of_relations'

RSpec.configure do |config|
config.include RuboCop::RSpec::ExpectOffense
end

describe CustomCops::RequiredInverseOfRelations, :config do
context 'given an association expression without :inverse_of option' do
it 'registers an offense' do
expect_offense(<<~RUBY)
class Test
has_many :books
^^^^^^^^^^^^^^^ Use inverse_of option when defining associations to prevent avoidable SQL queries and keep models in sync.
end
RUBY

expect_offense(<<~RUBY)
class Test
belongs_to :books
^^^^^^^^^^^^^^^^^ Use inverse_of option when defining associations to prevent avoidable SQL queries and keep models in sync.
end
RUBY
end
end

context 'given an association expression with :inverse_of option' do
it 'registers NO offenses' do
expect_no_offenses(<<~RUBY)
class Test
has_many :books, inverse_of: :author
end
RUBY

expect_no_offenses(<<~RUBY)
class Test
belongs_to :author, inverse_of: :books
end
RUBY
end
end

context 'given a method which have the same name with one of Rails association helpers' do
context 'given the method invocation has explicit module/class' do
it 'registers NO offenses' do
expect_no_offenses(<<~RUBY)
class Test
def test
Module.has_many :books
end
end
RUBY
end
end

context 'given the method invocation has explicit receiver' do
it 'registers NO offenses' do
expect_no_offenses(<<~RUBY)
class Test
def test
self.has_many :books
end
end
RUBY
end
end
end
end
3 changes: 3 additions & 0 deletions template.rb
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,9 @@ def apply_template!(template_root)
apply '.template/variants/api/template.rb' if API_VARIANT
apply '.template/variants/web/template.rb' if WEB_VARIANT

# Custom Rubocop cops
apply '.template/addons/custom_cops/template.rb'

# A list necessary jobs that run before complete, ex: Fixing rubocop on Ruby files that generated by Rails
apply '.template/hooks/before_complete/fix_rubocop.rb'
apply '.template/hooks/before_complete/report.rb'
Expand Down

0 comments on commit c676ca2

Please sign in to comment.