rails_core_extensions 0.11.2 → 0.13.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: e58d4846243aed9d34acbc12219f9968d0794dac0c7663809293660306e7b76f
4
- data.tar.gz: a455c966efdfaa720de412cadb772fff9efc6dd9c5b1951cd012686bce40be52
3
+ metadata.gz: 2b1eb7cf498a2e96bf6b76cf957ae9f1e3a9bd98dfe3a295a993614b2d6c964b
4
+ data.tar.gz: 833f7a348a0df83860057188a63d7c8a0b7b41165e772440bdf806cfdd3ff244
5
5
  SHA512:
6
- metadata.gz: 2e742d0b0c274dce91c59cbc500cfa47a98abe66dc295b4ecec30fde12c01e9c503abeed9714c8c9a23f0de09d9dbc069a47fb3a19671a36a525a23242448a72
7
- data.tar.gz: 64624d95978eac776e0b68c416c496c375c1d35cee267f578cb888c9b0818e610dfdc980815745a96c6023566c762e3bf5eeebcdc39812f88b6d719e94f71244
6
+ metadata.gz: 220a9b391ae6601bd5e6b3163dba1c1ea3a93a80ec5790421777e0905ed2fffd0932f6f2f66fed51f4be93fe3882737494d55ca779e65de4149f1008b5651a80
7
+ data.tar.gz: 3f77384f933a2565f0e043fae0afc6444016f1468a7b53ad46de3e5c89d8d3620dd1273a3453ff3e21c43c7326ab10f50759bf4ea31d3610e57dd0295a78120c
@@ -5,8 +5,8 @@ jobs:
5
5
  strategy:
6
6
  fail-fast: false
7
7
  matrix:
8
- gemfile: [rails60, rails61]
9
- ruby: ["2.6", "2.7", "3.0"]
8
+ gemfile: [rails60, rails61, rails70]
9
+ ruby: ["2.7", "3.0", "3.1"]
10
10
  runs-on: ubuntu-latest
11
11
  env:
12
12
  BUNDLE_GEMFILE: gemfiles/${{ matrix.gemfile }}.gemfile
@@ -17,3 +17,8 @@ jobs:
17
17
  ruby-version: ${{ matrix.ruby }}
18
18
  bundler-cache: true
19
19
  - run: bundle exec rake
20
+ - name: Coveralls
21
+ uses: coverallsapp/github-action@master
22
+ with:
23
+ github-token: ${{ secrets.GITHUB_TOKEN }}
24
+ path-to-lcov: coverage/lcov.info
data/.ruby-version CHANGED
@@ -1 +1 @@
1
- 3.0.0
1
+ 3.1.0
data/CHANGELOG.md CHANGED
@@ -1,5 +1,17 @@
1
1
  # Changelog
2
2
 
3
+ ## 0.13.0
4
+
5
+ - [PLAT-378] Improve bundler startup time; Drop Concurrency
6
+
7
+ ## 0.12.0
8
+
9
+ - [PLAT-183] Ruby 3.1, Rails 7.0 and publish coverage with github action
10
+
11
+ ## 0.11.3
12
+
13
+ - [TT-8647] Fix issue with position_helpers_for active record change
14
+
3
15
  ## 0.11.2
4
16
 
5
17
  * [TT-8640] Add dependabot config
data/README.md CHANGED
@@ -1,6 +1,6 @@
1
1
  # Rails Core Extensions
2
2
 
3
- [![Build Status](https://github.com/sealink/rails_core_extensions/workflows/Build/badge.svg?branch=master)](https://github.com/sealink/rails_core_extensions/actions)
3
+ [![Build Status](https://github.com/sealink/rails_core_extensions/workflows/Build%20and%20Test/badge.svg?branch=master)](https://github.com/sealink/rails_core_extensions/actions)
4
4
  [![Coverage Status](https://coveralls.io/repos/sealink/rails_core_extensions/badge.png)](https://coveralls.io/r/sealink/rails_core_extensions)
5
5
  [![Code Climate](https://codeclimate.com/github/sealink/rails_core_extensions.png)](https://codeclimate.com/github/sealink/rails_core_extensions)
6
6
 
@@ -62,10 +62,10 @@ along with type_body[]=7.. for all the types in category 6
62
62
 
63
63
  To publish a new version of this gem the following steps must be taken.
64
64
 
65
- * Update the version in the following files
65
+ - Update the version in the following files
66
66
  ```
67
67
  CHANGELOG.md
68
68
  lib/rails_core_extensions/version.rb
69
- ````
70
- * Create a tag using the format v0.1.0
71
- * Follow build progress in GitHub actions
69
+ ```
70
+ - Create a tag using the format v0.1.0
71
+ - Follow build progress in GitHub actions
@@ -0,0 +1,6 @@
1
+ source 'https://rubygems.org'
2
+ gemspec :path => '../'
3
+
4
+ group :development, :test do
5
+ gem 'activerecord', '~> 7.0'
6
+ end
@@ -1,8 +1,6 @@
1
1
  module RailsCoreExtensions
2
2
  module ActionControllerSortable
3
- def self.included(base)
4
- base.extend ClassMethods
5
- end
3
+ extend ActiveSupport::Concern
6
4
 
7
5
  module ClassMethods
8
6
  def sortable
@@ -28,5 +28,7 @@ module RailsCoreExtensions
28
28
  end
29
29
  end
30
30
 
31
- ActionView::Base.send(:include, RailsCoreExtensions::HasManyExtensions::Tags) if defined?(ActionView::Base)
32
- ActionView::Helpers::FormBuilder.send(:include, RailsCoreExtensions::HasManyExtensions::FormBuilder) if defined?(ActionView::Base)
31
+ ActiveSupport.on_load :action_view do
32
+ ActionView::Base.send(:include, RailsCoreExtensions::HasManyExtensions::Tags)
33
+ ActionView::Helpers::FormBuilder.send(:include, RailsCoreExtensions::HasManyExtensions::FormBuilder)
34
+ end
@@ -1,8 +1,6 @@
1
1
  module ActiveModelExtensions
2
2
  module Validations
3
- def self.included(base)
4
- base.extend ClassMethods
5
- end
3
+ extend ActiveSupport::Concern
6
4
 
7
5
  # Validates the presence of the required fields identified in a rule-string.
8
6
  #
@@ -1,7 +1,5 @@
1
1
  module ActiveRecordCloning
2
- def self.included(base)
3
- base.extend(ClassMethods)
4
- end
2
+ extend ActiveSupport::Concern
5
3
 
6
4
  module ClassMethods
7
5
 
@@ -1,7 +1,5 @@
1
1
  module ActiveRecordExtensions
2
- def self.included(base)
3
- base.extend ClassMethods
4
- end
2
+ extend ActiveSupport::Concern
5
3
 
6
4
  module ClassMethods
7
5
  # Like establish_connection but postfixes the key with the rails environment
@@ -70,7 +68,7 @@ module ActiveRecordExtensions
70
68
  reload
71
69
  #{collection}.sort_by(&:position).each_with_index do |o, index|
72
70
  if o.position != (index + 1)
73
- o.update(:position, index + 1)
71
+ o.update_attribute(:position, index + 1)
74
72
  end
75
73
  end
76
74
  end
@@ -1,8 +1,6 @@
1
1
  module RailsCoreExtensions
2
2
  module ActiveRecordLiquidExtensions
3
- def self.included(base)
4
- base.extend ClassMethods
5
- end
3
+ extend ActiveSupport::Concern
6
4
  end
7
5
 
8
6
  module ClassMethods
@@ -1,8 +1,6 @@
1
1
  module RailsCoreExtensions
2
2
  module Translations
3
- def self.included(base)
4
- base.extend ClassMethods
5
- end
3
+ extend ActiveSupport::Concern
6
4
 
7
5
  module ClassMethods
8
6
  def translate(key, options = {})
@@ -1,3 +1,3 @@
1
1
  module RailsCoreExtensions
2
- VERSION = '0.11.2'
2
+ VERSION = '0.13.0'
3
3
  end
@@ -3,8 +3,6 @@ module RailsCoreExtensions
3
3
  require 'rails_core_extensions/position_initializer'
4
4
  require 'rails_core_extensions/time_with_zone'
5
5
  require 'rails_core_extensions/transfer_records'
6
- require 'rails_core_extensions/active_support_concern'
7
- require 'rails_core_extensions/concurrency'
8
6
 
9
7
  require 'rails_core_extensions/railtie' if defined?(Rails)
10
8
 
@@ -12,15 +10,19 @@ module RailsCoreExtensions
12
10
  require 'rails_core_extensions/activatable'
13
11
  require 'rails_core_extensions/action_controller_sortable'
14
12
 
15
- ActionController::Base.send(:include, Activatable)
16
- ActionController::Base.send(:include, ActionControllerSortable)
13
+ ActiveSupport.on_load(:action_controller) do
14
+ ActionController::Base.send(:include, Activatable)
15
+ ActionController::Base.send(:include, ActionControllerSortable)
16
+ end
17
17
  end
18
18
 
19
19
  if defined? ActionView
20
20
  require 'rails_core_extensions/action_view_extensions'
21
21
  require 'rails_core_extensions/action_view_has_many_extensions'
22
22
 
23
- ActionView::Base.send(:include, RailsCoreExtensions::ActionViewExtensions)
23
+ ActiveSupport.on_load(:active_view) do
24
+ ActionView::Base.send(:include, RailsCoreExtensions::ActionViewExtensions)
25
+ end
24
26
  end
25
27
 
26
28
  if defined? ActiveRecord
@@ -30,11 +32,13 @@ module RailsCoreExtensions
30
32
  require 'rails_core_extensions/translations'
31
33
  require 'rails_core_extensions/active_model_extensions'
32
34
 
33
- ActiveRecord::Base.send(:include, ActiveRecordCloning)
34
- ActiveRecord::Base.send(:include, ActiveRecordExtensions)
35
- ActiveRecord::Base.send(:include, RailsCoreExtensions::ActiveRecordLiquidExtensions)
36
- ActiveRecord::Base.send(:include, ActiveRecordExtensions::InstanceMethods)
37
- ActiveRecord::Base.send(:include, RailsCoreExtensions::Translations)
38
- ActiveRecord::Base.send(:include, ActiveModelExtensions::Validations)
35
+ ActiveSupport.on_load(:active_record) do
36
+ ActiveRecord::Base.send(:include, ActiveRecordCloning)
37
+ ActiveRecord::Base.send(:include, ActiveRecordExtensions)
38
+ ActiveRecord::Base.send(:include, RailsCoreExtensions::ActiveRecordLiquidExtensions)
39
+ ActiveRecord::Base.send(:include, ActiveRecordExtensions::InstanceMethods)
40
+ ActiveRecord::Base.send(:include, RailsCoreExtensions::Translations)
41
+ ActiveRecord::Base.send(:include, ActiveModelExtensions::Validations)
42
+ end
39
43
  end
40
44
  end
@@ -18,7 +18,7 @@ Gem::Specification.new do |spec|
18
18
  spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
19
19
  spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
20
20
  spec.require_paths = ['lib']
21
- spec.required_ruby_version = '>= 2.6'
21
+ spec.required_ruby_version = '>= 2.7'
22
22
 
23
23
  spec.add_dependency 'activerecord', ['>= 6.0.0']
24
24
  spec.add_dependency 'actionpack', ['>= 6.0.0']
@@ -28,8 +28,6 @@ Gem::Specification.new do |spec|
28
28
  spec.add_development_dependency 'rspec'
29
29
  spec.add_development_dependency 'activerecord-nulldb-adapter'
30
30
  spec.add_development_dependency 'coverage-kit'
31
- spec.add_development_dependency 'simplecov-rcov'
32
- spec.add_development_dependency 'coveralls'
33
31
  spec.add_development_dependency 'rubocop'
34
32
  spec.add_development_dependency 'sqlite3'
35
33
  end
@@ -1,5 +1,3 @@
1
- require 'simplecov-rcov'
2
- require 'coveralls'
3
1
  require 'coverage/kit'
4
2
 
5
- Coverage::Kit.setup(minimum_coverage: 86.7)
3
+ Coverage::Kit.setup(minimum_coverage: 84.1)
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: rails_core_extensions
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.11.2
4
+ version: 0.13.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Michael Noack
@@ -9,7 +9,7 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2021-01-06 00:00:00.000000000 Z
12
+ date: 2022-07-02 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: activerecord
@@ -109,34 +109,6 @@ dependencies:
109
109
  - - ">="
110
110
  - !ruby/object:Gem::Version
111
111
  version: '0'
112
- - !ruby/object:Gem::Dependency
113
- name: simplecov-rcov
114
- requirement: !ruby/object:Gem::Requirement
115
- requirements:
116
- - - ">="
117
- - !ruby/object:Gem::Version
118
- version: '0'
119
- type: :development
120
- prerelease: false
121
- version_requirements: !ruby/object:Gem::Requirement
122
- requirements:
123
- - - ">="
124
- - !ruby/object:Gem::Version
125
- version: '0'
126
- - !ruby/object:Gem::Dependency
127
- name: coveralls
128
- requirement: !ruby/object:Gem::Requirement
129
- requirements:
130
- - - ">="
131
- - !ruby/object:Gem::Version
132
- version: '0'
133
- type: :development
134
- prerelease: false
135
- version_requirements: !ruby/object:Gem::Requirement
136
- requirements:
137
- - - ">="
138
- - !ruby/object:Gem::Version
139
- version: '0'
140
112
  - !ruby/object:Gem::Dependency
141
113
  name: rubocop
142
114
  requirement: !ruby/object:Gem::Requirement
@@ -176,9 +148,7 @@ files:
176
148
  - ".github/workflows/release.yml"
177
149
  - ".github/workflows/ruby.yml"
178
150
  - ".gitignore"
179
- - ".hound.yml"
180
151
  - ".rspec"
181
- - ".ruby-style.yml"
182
152
  - ".ruby-version"
183
153
  - CHANGELOG.md
184
154
  - Gemfile
@@ -187,6 +157,7 @@ files:
187
157
  - Rakefile
188
158
  - gemfiles/rails60.gemfile
189
159
  - gemfiles/rails61.gemfile
160
+ - gemfiles/rails70.gemfile
190
161
  - lib/rails_core_extensions.rb
191
162
  - lib/rails_core_extensions/action_controller_sortable.rb
192
163
  - lib/rails_core_extensions/action_view_extensions.rb
@@ -196,8 +167,6 @@ files:
196
167
  - lib/rails_core_extensions/active_record_cloning.rb
197
168
  - lib/rails_core_extensions/active_record_extensions.rb
198
169
  - lib/rails_core_extensions/active_record_liquid_extensions.rb
199
- - lib/rails_core_extensions/active_support_concern.rb
200
- - lib/rails_core_extensions/concurrency.rb
201
170
  - lib/rails_core_extensions/position_initializer.rb
202
171
  - lib/rails_core_extensions/railtie.rb
203
172
  - lib/rails_core_extensions/sortable.rb
@@ -212,7 +181,6 @@ files:
212
181
  - spec/active_model_extensions_spec.rb
213
182
  - spec/active_record_cloning_spec.rb
214
183
  - spec/active_record_extensions_spec.rb
215
- - spec/concurrency_spec.rb
216
184
  - spec/en.yml
217
185
  - spec/position_initializer_spec.rb
218
186
  - spec/schema.rb
@@ -233,14 +201,14 @@ required_ruby_version: !ruby/object:Gem::Requirement
233
201
  requirements:
234
202
  - - ">="
235
203
  - !ruby/object:Gem::Version
236
- version: '2.6'
204
+ version: '2.7'
237
205
  required_rubygems_version: !ruby/object:Gem::Requirement
238
206
  requirements:
239
207
  - - ">="
240
208
  - !ruby/object:Gem::Version
241
209
  version: '0'
242
210
  requirements: []
243
- rubygems_version: 3.2.3
211
+ rubygems_version: 3.3.3
244
212
  signing_key:
245
213
  specification_version: 4
246
214
  summary: Set of extensions to core rails libraries.
@@ -250,7 +218,6 @@ test_files:
250
218
  - spec/active_model_extensions_spec.rb
251
219
  - spec/active_record_cloning_spec.rb
252
220
  - spec/active_record_extensions_spec.rb
253
- - spec/concurrency_spec.rb
254
221
  - spec/en.yml
255
222
  - spec/position_initializer_spec.rb
256
223
  - spec/schema.rb
data/.hound.yml DELETED
@@ -1,2 +0,0 @@
1
- ruby:
2
- config_file: .ruby-style.yml
data/.ruby-style.yml DELETED
@@ -1,217 +0,0 @@
1
- AllCops:
2
- Exclude:
3
- - "vendor/**/*"
4
- - "db/schema.rb"
5
- UseCache: false
6
- Style/CollectionMethods:
7
- Description: Preferred collection methods.
8
- StyleGuide: https://github.com/bbatsov/ruby-style-guide#map-find-select-reduce-size
9
- Enabled: true
10
- PreferredMethods:
11
- collect: map
12
- collect!: map!
13
- find: detect
14
- find_all: select
15
- reduce: inject
16
- Layout/DotPosition:
17
- Description: Checks the position of the dot in multi-line method calls.
18
- StyleGuide: https://github.com/bbatsov/ruby-style-guide#consistent-multi-line-chains
19
- Enabled: true
20
- EnforcedStyle: trailing
21
- SupportedStyles:
22
- - leading
23
- - trailing
24
- Naming/FileName:
25
- Description: Use snake_case for source file names.
26
- StyleGuide: https://github.com/bbatsov/ruby-style-guide#snake-case-files
27
- Enabled: false
28
- Exclude: []
29
- Style/GuardClause:
30
- Description: Check for conditionals that can be replaced with guard clauses
31
- StyleGuide: https://github.com/bbatsov/ruby-style-guide#no-nested-conditionals
32
- Enabled: false
33
- MinBodyLength: 1
34
- Style/IfUnlessModifier:
35
- Description: Favor modifier if/unless usage when you have a single-line body.
36
- StyleGuide: https://github.com/bbatsov/ruby-style-guide#if-as-a-modifier
37
- Enabled: false
38
- Style/OptionHash:
39
- Description: Don't use option hashes when you can use keyword arguments.
40
- Enabled: false
41
- Style/PercentLiteralDelimiters:
42
- Description: Use `%`-literal delimiters consistently
43
- StyleGuide: https://github.com/bbatsov/ruby-style-guide#percent-literal-braces
44
- Enabled: false
45
- PreferredDelimiters:
46
- "%": "()"
47
- "%i": "()"
48
- "%q": "()"
49
- "%Q": "()"
50
- "%r": "{}"
51
- "%s": "()"
52
- "%w": "()"
53
- "%W": "()"
54
- "%x": "()"
55
- Naming/PredicateName:
56
- Description: Check the names of predicate methods.
57
- StyleGuide: https://github.com/bbatsov/ruby-style-guide#bool-methods-qmark
58
- Enabled: true
59
- NamePrefix:
60
- - is_
61
- - has_
62
- - have_
63
- NamePrefixBlacklist:
64
- - is_
65
- Exclude:
66
- - spec/**/*
67
- Style/RaiseArgs:
68
- Description: Checks the arguments passed to raise/fail.
69
- StyleGuide: https://github.com/bbatsov/ruby-style-guide#exception-class-messages
70
- Enabled: false
71
- EnforcedStyle: exploded
72
- SupportedStyles:
73
- - compact
74
- - exploded
75
- Style/SignalException:
76
- Description: Checks for proper usage of fail and raise.
77
- StyleGuide: https://github.com/bbatsov/ruby-style-guide#fail-method
78
- Enabled: false
79
- EnforcedStyle: semantic
80
- SupportedStyles:
81
- - only_raise
82
- - only_fail
83
- - semantic
84
- Style/SingleLineBlockParams:
85
- Description: Enforces the names of some block params.
86
- StyleGuide: https://github.com/bbatsov/ruby-style-guide#reduce-blocks
87
- Enabled: false
88
- Methods:
89
- - reduce:
90
- - a
91
- - e
92
- - inject:
93
- - a
94
- - e
95
- Style/SingleLineMethods:
96
- Description: Avoid single-line methods.
97
- StyleGuide: https://github.com/bbatsov/ruby-style-guide#no-single-line-methods
98
- Enabled: false
99
- AllowIfMethodIsEmpty: true
100
- Style/TrailingCommaInArguments:
101
- Description: Checks for trailing comma in argument lists.
102
- StyleGuide: https://github.com/bbatsov/ruby-style-guide#no-trailing-array-commas
103
- EnforcedStyleForMultiline: comma
104
- Enabled: true
105
- Style/TrailingCommaInArrayLiteral:
106
- Description: Checks for trailing comma in array and hash literals.
107
- StyleGuide: https://github.com/bbatsov/ruby-style-guide#no-trailing-array-commas
108
- EnforcedStyleForMultiline: comma
109
- Enabled: true
110
- Metrics/AbcSize:
111
- Description: A calculated magnitude based on number of assignments, branches, and
112
- conditions.
113
- Enabled: false
114
- Max: 15
115
- Metrics/ClassLength:
116
- Description: Avoid classes longer than 100 lines of code.
117
- Enabled: false
118
- CountComments: false
119
- Max: 100
120
- Metrics/ModuleLength:
121
- CountComments: false
122
- Max: 100
123
- Description: Avoid modules longer than 100 lines of code.
124
- Enabled: false
125
- Metrics/CyclomaticComplexity:
126
- Description: A complexity metric that is strongly correlated to the number of test
127
- cases needed to validate a method.
128
- Enabled: false
129
- Max: 6
130
- Metrics/MethodLength:
131
- Description: Avoid methods longer than 10 lines of code.
132
- StyleGuide: https://github.com/bbatsov/ruby-style-guide#short-methods
133
- Enabled: false
134
- CountComments: false
135
- Max: 10
136
- Metrics/ParameterLists:
137
- Description: Avoid parameter lists longer than three or four parameters.
138
- StyleGuide: https://github.com/bbatsov/ruby-style-guide#too-many-params
139
- Enabled: false
140
- Max: 5
141
- CountKeywordArgs: true
142
- Metrics/PerceivedComplexity:
143
- Description: A complexity metric geared towards measuring complexity for a human
144
- reader.
145
- Enabled: false
146
- Max: 7
147
- Lint/AssignmentInCondition:
148
- Description: Don't use assignment in conditions.
149
- StyleGuide: https://github.com/bbatsov/ruby-style-guide#safe-assignment-in-condition
150
- Enabled: false
151
- AllowSafeAssignment: true
152
- Style/InlineComment:
153
- Description: Avoid inline comments.
154
- Enabled: false
155
- Naming/AccessorMethodName:
156
- Description: Check the naming of accessor methods for get_/set_.
157
- Enabled: false
158
- Style/Alias:
159
- Description: Use alias_method instead of alias.
160
- StyleGuide: https://github.com/bbatsov/ruby-style-guide#alias-method
161
- Enabled: false
162
- Style/Documentation:
163
- Description: Document classes and non-namespace modules.
164
- Enabled: false
165
- Style/DoubleNegation:
166
- Description: Checks for uses of double negation (!!).
167
- StyleGuide: https://github.com/bbatsov/ruby-style-guide#no-bang-bang
168
- Enabled: false
169
- Style/EachWithObject:
170
- Description: Prefer `each_with_object` over `inject` or `reduce`.
171
- Enabled: false
172
- Style/EmptyLiteral:
173
- Description: Prefer literals to Array.new/Hash.new/String.new.
174
- StyleGuide: https://github.com/bbatsov/ruby-style-guide#literal-array-hash
175
- Enabled: false
176
- Style/ModuleFunction:
177
- Description: Checks for usage of `extend self` in modules.
178
- StyleGuide: https://github.com/bbatsov/ruby-style-guide#module-function
179
- Enabled: false
180
- Style/OneLineConditional:
181
- Description: Favor the ternary operator(?:) over if/then/else/end constructs.
182
- StyleGuide: https://github.com/bbatsov/ruby-style-guide#ternary-operator
183
- Enabled: false
184
- Style/PerlBackrefs:
185
- Description: Avoid Perl-style regex back references.
186
- StyleGuide: https://github.com/bbatsov/ruby-style-guide#no-perl-regexp-last-matchers
187
- Enabled: false
188
- Style/Send:
189
- Description: Prefer `Object#__send__` or `Object#public_send` to `send`, as `send`
190
- may overlap with existing methods.
191
- StyleGuide: https://github.com/bbatsov/ruby-style-guide#prefer-public-send
192
- Enabled: false
193
- Style/SpecialGlobalVars:
194
- Description: Avoid Perl-style global variables.
195
- StyleGuide: https://github.com/bbatsov/ruby-style-guide#no-cryptic-perlisms
196
- Enabled: false
197
- Style/VariableInterpolation:
198
- Description: Don't interpolate global, instance and class variables directly in
199
- strings.
200
- StyleGuide: https://github.com/bbatsov/ruby-style-guide#curlies-interpolate
201
- Enabled: false
202
- Style/WhenThen:
203
- Description: Use when x then ... for one-line cases.
204
- StyleGuide: https://github.com/bbatsov/ruby-style-guide#one-line-cases
205
- Enabled: false
206
- Lint/EachWithObjectArgument:
207
- Description: Check for immutable argument given to each_with_object.
208
- Enabled: true
209
- Lint/HandleExceptions:
210
- Description: Don't suppress exception.
211
- StyleGuide: https://github.com/bbatsov/ruby-style-guide#dont-hide-exceptions
212
- Enabled: false
213
- Lint/LiteralInInterpolation:
214
- Description: Checks for literals used in interpolation.
215
- Enabled: false
216
- Style/FrozenStringLiteralComment:
217
- Enabled: false
@@ -1,134 +0,0 @@
1
- module ActiveSupport
2
- # A typical module looks like this:
3
- #
4
- # module M
5
- # def self.included(base)
6
- # base.extend ClassMethods
7
- # base.send(:include, InstanceMethods)
8
- # scope :disabled, where(:disabled => true)
9
- # end
10
- #
11
- # module ClassMethods
12
- # ...
13
- # end
14
- #
15
- # module InstanceMethods
16
- # ...
17
- # end
18
- # end
19
- #
20
- # By using <tt>ActiveSupport::Concern</tt> the above module could instead be written as:
21
- #
22
- # require 'active_support/concern'
23
- #
24
- # module M
25
- # extend ActiveSupport::Concern
26
- #
27
- # included do
28
- # scope :disabled, where(:disabled => true)
29
- # end
30
- #
31
- # module ClassMethods
32
- # ...
33
- # end
34
- #
35
- # module InstanceMethods
36
- # ...
37
- # end
38
- # end
39
- #
40
- # Moreover, it gracefully handles module dependencies. Given a +Foo+ module and a +Bar+
41
- # module which depends on the former, we would typically write the following:
42
- #
43
- # module Foo
44
- # def self.included(base)
45
- # base.class_eval do
46
- # def self.method_injected_by_foo
47
- # ...
48
- # end
49
- # end
50
- # end
51
- # end
52
- #
53
- # module Bar
54
- # def self.included(base)
55
- # base.method_injected_by_foo
56
- # end
57
- # end
58
- #
59
- # class Host
60
- # include Foo # We need to include this dependency for Bar
61
- # include Bar # Bar is the module that Host really needs
62
- # end
63
- #
64
- # But why should +Host+ care about +Bar+'s dependencies, namely +Foo+? We could try to hide
65
- # these from +Host+ directly including +Foo+ in +Bar+:
66
- #
67
- # module Bar
68
- # include Foo
69
- # def self.included(base)
70
- # base.method_injected_by_foo
71
- # end
72
- # end
73
- #
74
- # class Host
75
- # include Bar
76
- # end
77
- #
78
- # Unfortunately this won't work, since when +Foo+ is included, its <tt>base</tt> is the +Bar+ module,
79
- # not the +Host+ class. With <tt>ActiveSupport::Concern</tt>, module dependencies are properly resolved:
80
- #
81
- # require 'active_support/concern'
82
- #
83
- # module Foo
84
- # extend ActiveSupport::Concern
85
- # included do
86
- # class_eval do
87
- # def self.method_injected_by_foo
88
- # ...
89
- # end
90
- # end
91
- # end
92
- # end
93
- #
94
- # module Bar
95
- # extend ActiveSupport::Concern
96
- # include Foo
97
- #
98
- # included do
99
- # self.method_injected_by_foo
100
- # end
101
- # end
102
- #
103
- # class Host
104
- # include Bar # works, Bar takes care now of its dependencies
105
- # end
106
- #
107
- module Concern
108
- def self.extended(base)
109
- base.instance_variable_set("@_dependencies", [])
110
- end
111
-
112
- def append_features(base)
113
- if base.instance_variable_defined?("@_dependencies")
114
- base.instance_variable_get("@_dependencies") << self
115
- return false
116
- else
117
- return false if base < self
118
- @_dependencies.each { |dep| base.send(:include, dep) }
119
- super
120
- base.extend const_get("ClassMethods") if const_defined?("ClassMethods")
121
- base.send :include, const_get("InstanceMethods") if const_defined?("InstanceMethods")
122
- base.class_eval(&@_included_block) if instance_variable_defined?("@_included_block")
123
- end
124
- end
125
-
126
- def included(base = nil, &block)
127
- if base.nil?
128
- @_included_block = block
129
- else
130
- super
131
- end
132
- end
133
- end
134
- end
@@ -1,152 +0,0 @@
1
- module Concurrency
2
- extend ActiveSupport::Concern
3
-
4
- module ClassMethods
5
-
6
- def concurrency_safe(*methods)
7
- options = methods.extract_options!
8
- methods.each do |method|
9
- add_concurrency_check(method, options)
10
- end
11
- end
12
-
13
-
14
- def concurrency_safe_method_locked?(method)
15
- concurrency_cache.read(concurrency_safe_method_cache_name(method)) == 'locked'
16
- end
17
-
18
-
19
- def concurrency_cache
20
- @concurrency_cache ||= ::Rails.cache
21
- end
22
-
23
-
24
- def concurrency_cache=(cache)
25
- [:read,:write,:delete].each do |method|
26
- raise ConcurrencyCacheException, "#{cache} does not implement #{method}" unless cache.respond_to?(method)
27
- end
28
- @concurrency_cache = cache
29
- end
30
-
31
-
32
- private
33
-
34
- def add_concurrency_check(method, options = {})
35
- method_definition = <<-DEFINITION
36
- def #{method}_with_concurrency_lock(*args)
37
- if concurrency_safe_method_locked?(:#{method})
38
- raise ConcurrentCallException.new(self,:#{method}), "#{self.name}.#{method} is already running"
39
- end
40
- lock_concurrency_safe_method(:#{method})
41
- return_value = nil
42
- begin
43
- return_value = #{method}_without_concurrency_lock(*args)
44
- ensure
45
- unlock_concurrency_safe_method(:#{method})
46
- end
47
- return_value
48
- end
49
- alias_method :#{method}_without_concurrency_lock, :#{method}
50
- alias_method :#{method}, :#{method}_with_concurrency_lock
51
- DEFINITION
52
-
53
- if method_type(method, options[:type]) == 'class'
54
- method_definition = <<-DEFINITION
55
- class << self
56
- #{method_definition}
57
- end
58
- DEFINITION
59
- end
60
-
61
- module_eval method_definition
62
- end
63
-
64
-
65
- def lock_concurrency_safe_method(method)
66
- concurrency_cache.write(concurrency_safe_method_cache_name(method), 'locked')
67
- end
68
-
69
-
70
- def unlock_concurrency_safe_method(method)
71
- concurrency_cache.delete(concurrency_safe_method_cache_name(method))
72
- end
73
-
74
-
75
- def concurrency_safe_method_cache_name(method)
76
- "#{self.name.underscore}_concurrency_safe_class_method_#{method}"
77
- end
78
-
79
-
80
- def method_type(method, type = nil)
81
- types = method_types(method, type)
82
- raise AmbiguousMethodException.new(self, method), "#{method} for #{self.name} is ambiguous. Please specify the type (instance/class) option" if types.count == 2
83
- raise NoMethodException.new(self, method), "#{method} is not not a valid method for #{self.name}." if types.blank?
84
- types.first
85
- end
86
-
87
-
88
- def method_types(method, type = nil)
89
- ['class', 'instance'].select do |mt|
90
- (type.blank? || type.to_s == mt) && self.send("#{mt}_method?", method)
91
- end
92
- end
93
-
94
-
95
- def class_method?(method)
96
- self.respond_to?(method, true)
97
- end
98
-
99
-
100
- def instance_method?(method)
101
- (self.instance_methods + self.private_instance_methods).map(&:to_s).include?(method.to_s)
102
- end
103
-
104
- end
105
-
106
-
107
- module InstanceMethods
108
-
109
- def concurrency_cache
110
- self.class.concurrency_cache
111
- end
112
-
113
-
114
- def concurrency_safe_method_locked?(method)
115
- concurrency_cache.read(concurrency_safe_method_cache_name(method)) == 'locked'
116
- end
117
-
118
-
119
- private
120
-
121
- def lock_concurrency_safe_method(method)
122
- concurrency_cache.write(concurrency_safe_method_cache_name(method), 'locked')
123
- end
124
-
125
-
126
- def unlock_concurrency_safe_method(method)
127
- concurrency_cache.delete(concurrency_safe_method_cache_name(method))
128
- end
129
-
130
-
131
- def concurrency_safe_method_cache_name(method)
132
- "#{self.class.name.underscore}_concurrency_safe_instance_method_#{method}"
133
- end
134
-
135
- end
136
-
137
-
138
- class ConcurrencyException < ::Exception; end
139
- class ConcurrencyCacheException < ConcurrencyException; end
140
- class MethodException < ConcurrencyException
141
- attr_reader :object, :method
142
-
143
- def initialize(object, method)
144
- @object = object
145
- @method = method
146
- end
147
- end
148
- class ConcurrentCallException < MethodException; end
149
- class NoMethodException < MethodException; end
150
- class AmbiguousMethodException < MethodException; end
151
-
152
- end
@@ -1,110 +0,0 @@
1
- require 'spec_helper'
2
-
3
- class TestConcurrencyCache
4
- @@cache = {}
5
-
6
- def self.read(key)
7
- @@cache[key]
8
- end
9
-
10
- def self.write(key, value)
11
- @@cache[key] = value
12
- end
13
-
14
- def self.delete(key)
15
- @@cache.delete(key)
16
- end
17
-
18
- def self.clear
19
- @@cache = {}
20
- end
21
- end
22
-
23
- describe Concurrency do
24
- before :each do
25
- TestConcurrencyCache.clear
26
-
27
- class ConcurrencyTest
28
- include Concurrency
29
-
30
- self.concurrency_cache = TestConcurrencyCache
31
-
32
- def self.class_test_method
33
- sleep(1)
34
- end
35
-
36
- def instance_test_method
37
- sleep(1)
38
- end
39
-
40
- def self.both_instance_and_class_test_method; end
41
- def both_instance_and_class_test_method; end
42
- end
43
- end
44
-
45
- after :each do
46
- Object.send(:remove_const, :ConcurrencyTest)
47
- end
48
-
49
- it "should allow specifying which methods should implement the concurrency check" do
50
- expect { ConcurrencyTest.send(:concurrency_safe, :instance_test_method) }
51
- .to_not raise_error
52
- expect { ConcurrencyTest.send(:concurrency_safe, :class_test_method) }
53
- .to_not raise_error
54
- expect { ConcurrencyTest.send(:concurrency_safe, :both_instance_and_class_test_method) }
55
- .to raise_error(Concurrency::AmbiguousMethodException)
56
- expect { ConcurrencyTest.send(:concurrency_safe, :both_instance_and_class_test_method, type: :instance) }
57
- .to_not raise_error
58
- expect { ConcurrencyTest.send(:concurrency_safe, :both_instance_and_class_test_method, type: :class) }
59
- .to_not raise_error
60
- expect { ConcurrencyTest.send(:concurrency_safe, :unknown_method) }
61
- .to raise_error(Concurrency::NoMethodException)
62
- end
63
-
64
- it "should allow identyfying the type of a method" do
65
- expect(ConcurrencyTest.send(:method_types, :class_test_method)).to eq ['class']
66
- expect(ConcurrencyTest.send(:method_types, :instance_test_method)).to eq ['instance']
67
- expect(ConcurrencyTest.send(:method_types, :both_instance_and_class_test_method)).to eq ['class','instance']
68
- expect(ConcurrencyTest.send(:method_types, :unknown_method)).to be_blank
69
- expect(ConcurrencyTest.send(:method_type, :class_test_method)).to eq 'class'
70
- expect(ConcurrencyTest.send(:method_type, :instance_test_method)).to eq 'instance'
71
- expect { ConcurrencyTest.send(:method_type, :both_instance_and_class_test_method) }
72
- .to raise_error(Concurrency::AmbiguousMethodException)
73
- expect { ConcurrencyTest.send(:method_type, :unknown_method) }
74
- .to raise_error(Concurrency::NoMethodException)
75
- end
76
-
77
- it "should allow checking the concurrency lock for specified class methods" do
78
- ConcurrencyTest.send(:concurrency_safe, :class_test_method)
79
- started = false
80
- expect(ConcurrencyTest.concurrency_safe_method_locked?(:class_test_method)).to be false
81
- thread = Thread.new { ConcurrencyTest.send(:class_test_method); started = true }
82
- thread.join
83
- expect(ConcurrencyTest.concurrency_safe_method_locked?(:class_test_method)).to be true until started
84
- end
85
-
86
- it "should allow checking the concurrency lock for specified instance methods" do
87
- ConcurrencyTest.send(:concurrency_safe, :class_test_method)
88
- instance = ConcurrencyTest.new
89
- started = false
90
- expect(instance.concurrency_safe_method_locked?(:instance_test_method)).to be false
91
- thread = Thread.new { instance.send(:instance_test_method); started = true }
92
- thread.join
93
- expect(instance.concurrency_safe_method_locked?(:instance_test_method)).to be true until started
94
- end
95
-
96
- it "should implement the concurrency check for specified class methods" do
97
- ConcurrencyTest.send(:concurrency_safe, :class_test_method)
98
- threads = 2.times.map { Thread.new { ConcurrencyTest.send(:class_test_method) } }
99
- expect { threads.each(&:join) }
100
- .to raise_error(Concurrency::ConcurrentCallException)
101
- end
102
-
103
- it "should implement the concurrency check for specified instance methods" do
104
- ConcurrencyTest.send(:concurrency_safe, :instance_test_method)
105
- instance = ConcurrencyTest.new
106
- threads = 2.times.map { Thread.new { instance.send(:instance_test_method) } }
107
- expect { threads.each(&:join) }
108
- .to raise_error(Concurrency::ConcurrentCallException)
109
- end
110
- end