modulorails 0.4.0 → 1.0.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: f695c4454203bb2d22353b7cff523da2315c7ce5472300208f1774d6aed2be5a
4
- data.tar.gz: f02062f1a5878154caa982fbf70dd5d584cdd1b07a90f5614aa4e01d27b79b20
3
+ metadata.gz: 945b70ac74dba5edd9a3e6df1aae0f0244d4a4704487a070c82d0b46580a2285
4
+ data.tar.gz: 850fcbbf27e12f2b777f0c72deb15a249d84a46fa9dc993fca359dbe79481efe
5
5
  SHA512:
6
- metadata.gz: 93943d5cd4726cce846e10c09149ff39b19adadbdf823a3ffc4032e524184ebd1fd50a83be07286ea50938062995df3a6166edd206461efeb400b85e00101d31
7
- data.tar.gz: 92b4689741e9468f395656200ff35096553e332e84958892adaedccfb6b14fb674f01078ae3a8588d104838d9e080422de7ae414224add37ed0c9a533aaf0508
6
+ metadata.gz: 43ef84405a627ebc3460428add66c7769b626a476c15b4e1e21234dc8ec3e4a03bade4d42bfea506965d1ee9192cfa12aa6b8271989005d0075c292faa951b25
7
+ data.tar.gz: b76c6a8fd2b32a745cac58298a751c4f120e7165ac3b5c13221dd11602475f4e3bf5aaa398106ef4f6a10e1c93c98e917373aea3c041114cf480820e91cae342
data/.rubocop.yml ADDED
@@ -0,0 +1,45 @@
1
+ # The behavior of RuboCop can be controlled via the .rubocop.yml
2
+ # configuration file. It makes it possible to enable/disable
3
+ # certain cops (checks) and to alter their behavior if they accept
4
+ # any parameters. The file can be placed either in your home
5
+ # directory or in some project directory.
6
+ #
7
+ # RuboCop will start looking for the configuration file in the directory
8
+ # where the inspected file is and continue its way up to the root directory.
9
+ #
10
+ # See https://docs.rubocop.org/rubocop/configuration
11
+
12
+ # Enabling Rails-specific cops.
13
+ require: rubocop-rails
14
+
15
+ AllCops:
16
+ # Disable all cops by default to ease the migration. This will probably be removed one day.
17
+ DisabledByDefault: true
18
+ # No suggestions since the gem is the sole truth for rubocop configuration.
19
+ SuggestExtensions: false
20
+
21
+ # Excluding most directories with generated files and directories with configuration files.
22
+ Exclude:
23
+ - 'vendor/**/*'
24
+ - 'db/**/*'
25
+ - 'tmp/**/*'
26
+ - 'bin/**/*'
27
+ - 'builds/**/*'
28
+ - 'Gemfile'
29
+ - 'config/environments/*'
30
+ - 'config/puma.rb'
31
+ - 'config/spring.rb'
32
+ - 'test/application_system_test_case.rb'
33
+ - 'test/test_helper.rb'
34
+ - 'config/initializers/*.rb'
35
+ - 'spec/spec_helper.rb'
36
+ - 'node_modules/**/*'
37
+ - 'spec/**/*'
38
+
39
+ # Instructing rubocop about all standard Modulotech environments.
40
+ Rails/UnknownEnv:
41
+ Environments:
42
+ - production
43
+ - development
44
+ - test
45
+ - staging
data/CHANGELOG.md CHANGED
@@ -2,6 +2,16 @@
2
2
 
3
3
  This file is used to list changes made in each version of the gem.
4
4
 
5
+ # 1.0.0
6
+
7
+ The Rubocop release.
8
+
9
+ - Add Modulorails helper `powered_by`.
10
+ - Add `Modulorails::BaseService`, `Modulorails::LogsForMethodService`,
11
+ `Modulorails::SuccessData` and `Modulorails::ErrorData`.
12
+ - Add Rubocop dependency with empty configuration.
13
+ - Ensure the compatibility of the gem with Ruby 3.0 and Ruby 3.1.
14
+
5
15
  # 0.4.0
6
16
 
7
17
  Fixes, updates and health_check release.
@@ -0,0 +1,21 @@
1
+ /**
2
+ ** Modulorails style
3
+ **/
4
+ .modulolink {
5
+ text-decoration: none;
6
+ font-weight: 500;
7
+ color: #202D4C;
8
+ }
9
+
10
+ .modulolink span {
11
+ color: #FFCE19;
12
+ }
13
+
14
+ .modulolink:hover {
15
+ color: #374D82;
16
+ text-decoration: none;
17
+ }
18
+
19
+ .modulolink:hover span {
20
+ color: #FFCB0C;
21
+ }
@@ -0,0 +1,8 @@
1
+ # @author Matthieu CIAPPARA <ciappa_m@modulotech.fr>
2
+ module Modulorails::ApplicationHelper
3
+ def powered_by
4
+ link_to('https://www.modulotech.fr/', target: '_blank', class: 'modulolink') do
5
+ raw("Powered by modulo<span>Tech</span>")
6
+ end
7
+ end
8
+ end
@@ -14,3 +14,6 @@ en:
14
14
  configurable_password: Password is not configurable for test environment
15
15
  configurable_database: Database name is not configurable for test environment
16
16
  configurable_port: Port is not configurable for test environment
17
+ errors:
18
+ invalid_format: Invalid format for field %{field}
19
+ invalid_value: Invalid value for field %{field}
@@ -0,0 +1,47 @@
1
+ version: '3.7'
2
+
3
+ services:
4
+ ruby25:
5
+ image: modulotechgroup/modulorails:testruby25
6
+ volumes:
7
+ - .:/app
8
+ build:
9
+ context: .
10
+ dockerfile: Dockerfile.ruby25
11
+ command: ./entrypoints/appraisal_test.sh
12
+
13
+ ruby26:
14
+ image: modulotechgroup/modulorails:testruby26
15
+ volumes:
16
+ - .:/app
17
+ build:
18
+ context: .
19
+ dockerfile: Dockerfile.ruby26
20
+ command: ./entrypoints/appraisal_test.sh
21
+
22
+ ruby27:
23
+ image: modulotechgroup/modulorails:testruby27
24
+ volumes:
25
+ - .:/app
26
+ build:
27
+ context: .
28
+ dockerfile: Dockerfile.ruby27
29
+ command: ./entrypoints/appraisal_test.sh
30
+
31
+ ruby30:
32
+ image: modulotechgroup/modulorails:testruby30
33
+ volumes:
34
+ - .:/app
35
+ build:
36
+ context: .
37
+ dockerfile: Dockerfile.ruby30
38
+ command: ./entrypoints/appraisal_test.sh
39
+
40
+ ruby31:
41
+ image: modulotechgroup/modulorails:testruby31
42
+ volumes:
43
+ - .:/app
44
+ build:
45
+ context: .
46
+ dockerfile: Dockerfile.ruby31
47
+ command: ./entrypoints/appraisal_test.sh
@@ -0,0 +1,24 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'rails/generators'
4
+
5
+ class Modulorails::RubocopGenerator < Rails::Generators::Base
6
+ source_root File.expand_path('templates', __dir__)
7
+ desc 'This generator creates a configuration for Rubocop'
8
+
9
+ def create_config_files
10
+ rubocop_config_path = Rails.root.join('.rubocop.yml')
11
+ gitlab_config_path = Rails.root.join('.gitlab-ci.yml')
12
+
13
+ template "rubocop.yml", rubocop_config_path, force: true
14
+
15
+ unless File.read(gitlab_config_path).match?(/\s+extends:\s+.lint\s*$/)
16
+ append_file gitlab_config_path do
17
+ <<~YAML
18
+ rubocop:
19
+ extends: .lint
20
+ YAML
21
+ end
22
+ end
23
+ end
24
+ end
@@ -0,0 +1,18 @@
1
+ # The behavior of RuboCop can be controlled via the .rubocop.yml
2
+ # configuration file. It makes it possible to enable/disable
3
+ # certain cops (checks) and to alter their behavior if they accept
4
+ # any parameters. The file can be placed either in your home
5
+ # directory or in some project directory.
6
+ #
7
+ # RuboCop will start looking for the configuration file in the directory
8
+ # where the inspected file is and continue its way up to the root directory.
9
+ #
10
+ # See https://docs.rubocop.org/rubocop/configuration
11
+
12
+ inherit_gem:
13
+ modulorails: .rubocop.yml
14
+
15
+ # Take into account the exclude list from the gem
16
+ inherit_mode:
17
+ merge:
18
+ - Exclude
@@ -0,0 +1,13 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'rails/generators'
4
+
5
+ class Modulorails::ServiceGenerator < Rails::Generators::NamedBase
6
+ source_root File.expand_path('templates', __dir__)
7
+ desc 'This generator creates a service inheriting Modulorails::BaseService'
8
+ argument :arguments, type: :array, default: [], banner: 'argument argument'
9
+
10
+ def create_service_files
11
+ template "service.rb", File.join("app/services", class_path, "#{file_name}_service.rb")
12
+ end
13
+ end
@@ -0,0 +1,28 @@
1
+ <% module_namespacing do -%>
2
+ # @author <INSERT YOUR NAME HERE>
3
+ # <DESCRIBE YOUR CLASS HERE>
4
+ <%- if arguments.size >= 1 -%>
5
+ #
6
+ <%- arguments.each do |argument| -%>
7
+ # @!attribute <%= argument %>
8
+ # @return <DESCRIBE YOUR ARGUMENT HERE>
9
+ <%- end -%>
10
+ <%- end -%>
11
+ class <%= class_name %>Service < ::ApplicationService
12
+ <%- if arguments.size >= 1 -%>
13
+
14
+ def initialize(<%= arguments.join(', ') %>)
15
+ super()
16
+
17
+ <%- arguments.each do |argument| -%>
18
+ <%= "@#{argument} = #{argument}" %>
19
+ <%- end -%>
20
+ end
21
+ <%- end -%>
22
+
23
+ def call
24
+ # TODO
25
+ end
26
+
27
+ end
28
+ <% end -%>
@@ -0,0 +1,21 @@
1
+ # @author Matthieu Ciappara <ciappa_m@modulotech>
2
+ # An error encountered during an operation with additional data.
3
+ class Modulorails::ErrorData
4
+ # @!attribute r errors
5
+ # An error message or an array of error messages (those will be joined by a coma and a space).
6
+ # @!attribute r exception
7
+ # The exception that caused the error. Defaults to nil.
8
+ attr_reader :errors, :exception
9
+
10
+ # @param errors [String,Array<String>] An error message or an array of error messages
11
+ # @param exception [Exception,nil] The exception that caused the error.
12
+ def initialize(errors, exception: nil)
13
+ @errors = errors.respond_to?(:join) ? errors.join(', ') : errors.to_s
14
+ @exception = exception
15
+ end
16
+
17
+ # @return [false] An error always means the operation was not a success.
18
+ def success?
19
+ false
20
+ end
21
+ end
@@ -0,0 +1,4 @@
1
+ # @author Matthieu CIAPPARA <ciappa_m@modulotech.fr>
2
+ # The base class for modulorails exceptions.
3
+ class Modulorails::BaseError < RuntimeError
4
+ end
@@ -0,0 +1,3 @@
1
+ require_relative 'base_error'
2
+ require_relative 'invalid_format_error'
3
+ require_relative 'invalid_value_error'
@@ -0,0 +1,14 @@
1
+ # @author Matthieu CIAPPARA <ciappa_m@modulotech.fr>
2
+ # An exception representing an invalid format for a given field.
3
+ class Modulorails::InvalidFormatError < Modulorails::BaseError
4
+ # @!attribute r field
5
+ # The name of the field that had a wrong format.
6
+ attr_reader :field
7
+
8
+ # @param field [String]
9
+ def initialize(field)
10
+ super(I18n.t('modulorails.errors.invalid_format', field: field))
11
+
12
+ @field = field
13
+ end
14
+ end
@@ -0,0 +1,14 @@
1
+ # @author Matthieu CIAPPARA <ciappa_m@modulotech.fr>
2
+ # An exception representing an invalid value for a given field.
3
+ class Modulorails::InvalidValueError < Modulorails::BaseError
4
+ # @!attribute r field
5
+ # The name of the field that had a wrong value.
6
+ attr_reader :field
7
+
8
+ # @param field [String]
9
+ def initialize(field)
10
+ super(I18n.t('modulorails.errors.invalid_value', field: field))
11
+
12
+ @field = field
13
+ end
14
+ end
@@ -1,3 +1,5 @@
1
+ require_relative '../../app/helpers/modulorails/application_helper'
2
+
1
3
  module Modulorails
2
4
  # Bind in the Rails lifecycle
3
5
  class Railtie < ::Rails::Railtie
@@ -15,6 +17,18 @@ module Modulorails
15
17
  require 'health_check'
16
18
  end
17
19
 
20
+ initializer 'modulorails.action_view' do
21
+ ActiveSupport.on_load :action_view do
22
+ include Modulorails::ApplicationHelper
23
+ end
24
+ end
25
+
26
+ initializer 'modulorails.assets' do |app|
27
+ %w[stylesheets javascripts].each do |subdirectory|
28
+ app.config.assets.paths << File.expand_path("../../../app/assets/#{subdirectory}", __FILE__)
29
+ end
30
+ end
31
+
18
32
  # Sending data after the initialization ensures we can access
19
33
  # all gems, constants and configurations we might need.
20
34
  config.after_initialize do
@@ -32,6 +46,9 @@ module Modulorails
32
46
  # Check database configuration
33
47
  Modulorails.check_database_config
34
48
 
49
+ # Add/update Rubocop config
50
+ Modulorails.generate_rubocop_template
51
+
35
52
  # Gem's self-update if a new version was released
36
53
  Modulorails.self_update
37
54
  end
@@ -0,0 +1,203 @@
1
+ # @author Matthieu CIAPPARA <ciappa_m@modulotech.fr>
2
+ # The base class for services. Should be implemented by ApplicationService following the model of
3
+ # ActiveRecord::Base and ApplicationRecord.
4
+ class Modulorails::BaseService
5
+ # Allow to instantiate the service and call the service in one go.
6
+ if Modulorails::COMPARABLE_RUBY_VERSION < Gem::Version.new('3.0')
7
+ def self.call(*args, &block)
8
+ new(*args, &block).call
9
+ end
10
+ else
11
+ def self.call(*args, **kwargs, &block)
12
+ new(*args, **kwargs, &block).call
13
+ end
14
+ end
15
+
16
+ # @abstract The main method to implement for your service to do something
17
+ def call
18
+ raise NotImplementedError.new('Implement method call on sub-class')
19
+ end
20
+
21
+ def to_s
22
+ self.class.to_s
23
+ end
24
+
25
+ # The method used by Modulorails::LogsForMethodService to log the service name
26
+ def to_tag
27
+ self.class.to_s
28
+ end
29
+
30
+ # Shamelessly copied from text_helper
31
+ def self.pluralize(count, singular, plural_arg = nil, plural: plural_arg, locale: I18n.locale)
32
+ word = if count == 1 || count =~ /^1(\.0+)?$/
33
+ singular
34
+ else
35
+ plural || singular.pluralize(locale)
36
+ end
37
+
38
+ "#{count || 0} #{word}"
39
+ end
40
+
41
+ protected
42
+
43
+ # Wrapper to Modulorails::LogsForMethodService
44
+ # @param method [#to_s] The method calling `#log`
45
+ # @param message [Hash,#to_s] The message to log; Hash will be logged after a #to_json call
46
+ def log(method, message)
47
+ Modulorails::LogsForMethodService.call(method: method, message: message, tags: [self])
48
+ end
49
+
50
+ # @yield Wrap the given block in an ActiveRecord transaction.
51
+ # @yieldreturn [Object] Will be available as data of the `SuccessData` returned by the method
52
+ # @return [SuccessData] If the transaction was not rollbacked; give access to the block's return.
53
+ # @return [ErrorData] If the transaction was rollbacked; give access to the rollbacking exception.
54
+ def with_transaction
55
+ data = nil
56
+
57
+ ActiveRecord::Base.transaction do
58
+ data = yield
59
+ end
60
+
61
+ SuccessData.new(data)
62
+ rescue ActiveRecord::RecordInvalid => e
63
+ # Known error, no need for a log, it just needs to be returned
64
+ ErrorData.new(e.message, exception: e)
65
+ rescue StandardError => e
66
+ # Unknown error, log the error
67
+ Rails.logger.error("#{self}: #{e.message}")
68
+ Rails.logger.error("Local variables: #{local_variables.map! { |v| { v => eval(v.to_s, binding) } }}")
69
+ Rails.logger.error(e.backtrace&.join("\n"))
70
+
71
+ # Return the error
72
+ ErrorData.new(e.message, exception: e)
73
+ end
74
+
75
+ # Cast the date/datetime parameters to time with zones.
76
+ # @param from [String,ActiveSupport::TimeWithZone] the minimum date
77
+ # @param to [String,ActiveSupport::TimeWithZone] the maximum date
78
+ # @return [[ActiveSupport::TimeWithZone, ActiveSupport::TimeWithZone]] The given dates casted.
79
+ def params_to_time(from, to = nil)
80
+ from = from.is_a?(String) && from.present? ? from.to_time_with_zone : from
81
+ to = if to.is_a?(String) && to.present?
82
+ to = to.to_time_with_zone
83
+
84
+ # If the right bound is exactly the same as the left one, we add 1 day to the right
85
+ # one by default.
86
+ to.present? && to == from ? to + 1.day : to
87
+ else
88
+ to
89
+ end
90
+
91
+ [from, to]
92
+ end
93
+
94
+ # Shamelessly copied from text_helper
95
+ def pluralize(count, singular, plural_arg = nil, plural: plural_arg, locale: I18n.locale)
96
+ self.class.pluralize(count, singular, plural_arg, plural: plural, locale: locale)
97
+ end
98
+
99
+ # Take a series of keys, dig them into the given params and ensure the found value is a date.
100
+ # @param keys [Array<Symbol>] The keys to find in the parameters.
101
+ # @param params [#dig] The parameters to dig in.
102
+ # @return [ActiveSupport::TimeWithZone] If it is found, the value casted as a datetime.
103
+ # @return [nil] If the parameter was not found.
104
+ def parse_date_field(*keys, params:)
105
+ value = params.dig(*keys)
106
+
107
+ return nil unless value
108
+
109
+ begin
110
+ Time.zone.parse(value)
111
+ rescue ArgumentError
112
+ raise InvalidFormatError.new(keys.join('/'))
113
+ end
114
+ end
115
+
116
+ # Take a series of keys, dig them into the given params and ensure the found value is a date.
117
+ # @param keys [Array<Symbol>] The keys to find in the parameters.
118
+ # @param params [#dig] The parameters to dig in.
119
+ # @return [ActiveSupport::TimeWithZone] If it is found, the value casted as a datetime.
120
+ # @return [nil] If the parameter was not found.
121
+ def parse_iso8601_field(*keys, params: {})
122
+ value = params.dig(*keys)
123
+
124
+ return nil unless value
125
+
126
+ begin
127
+ Time.zone.iso8601(value)
128
+ rescue ArgumentError
129
+ raise InvalidFormatError.new(keys.join('/'))
130
+ end
131
+ end
132
+
133
+ # Take a series of keys, dig them into the given params and ensure the found value is valid.
134
+ # @param allowed_values [#include?] Allowed values
135
+ # @param keys [Array<Symbol>] The keys to find in the parameters.
136
+ # @param params [#dig] The parameters to dig in.
137
+ # @param allow_nil [Boolean] Do not raise if value is nil.
138
+ # @return [ActiveSupport::TimeWithZone] If it is found, the value casted as a datetime.
139
+ # @return [nil] If the parameter was not found.
140
+ def parse_enumerated_field(allowed_values, keys, params: {}, allow_nil: true)
141
+ value = params.dig(*keys)
142
+
143
+ if value.respond_to?(:each)
144
+ raise InvalidValueError.new(keys.join('/')) unless value.all? { |v| allowed_values.include?(v) }
145
+ else
146
+ return nil if !value && allow_nil
147
+
148
+ raise InvalidValueError.new(keys.join('/')) unless allowed_values.include?(value)
149
+ end
150
+
151
+ value
152
+ end
153
+
154
+ # @param model [#find_by] The model to search in
155
+ # @param field [Symbol] The field to filter on
156
+ # @param keys [Array<Symbol>] The keys to search in the params
157
+ # @param params [#dig] The params to search in
158
+ # @param allow_nil [Boolean] Raise if the keys are not found; default true
159
+ # @return [#id, nil] The record corresponding to given field and values (through keys)
160
+ # @raise [InvalidValueError] When there is no record for given field and values
161
+ def parse_referential_value(model, field, *keys, params: {}, allow_nil: true)
162
+ value = params.dig(*keys)
163
+
164
+ unless value
165
+ if allow_nil
166
+ return nil
167
+ else
168
+ raise InvalidValueError.new(keys.join('/'))
169
+ end
170
+ end
171
+
172
+ result = model.find_by(field => value)
173
+
174
+ raise InvalidValueError.new(keys.join('/')) if result.nil?
175
+
176
+ result
177
+ end
178
+
179
+ # @param model [#where] The model to search in
180
+ # @param field [Symbol] The field to filter on
181
+ # @param keys [Array<Symbol>] The keys to search in the params
182
+ # @param params [#dig] The parmas to search in
183
+ # @param allow_nil [Boolean] Raise if the keys are not found; default true
184
+ # @return [#ids, nil] The record corresponding to given field and values (through keys)
185
+ # @raise [InvalidValueError] When there is no record for given field and values
186
+ def parse_referential_values(model, field, *keys, params: {}, allow_nil: true)
187
+ values = params.dig(*keys)
188
+
189
+ if values.blank?
190
+ if allow_nil
191
+ return nil
192
+ else
193
+ raise InvalidValueError.new(keys.join('/'))
194
+ end
195
+ end
196
+
197
+ results = model.where(field => values)
198
+
199
+ raise InvalidValueError.new(keys.join('/')) if results.blank?
200
+
201
+ results
202
+ end
203
+ end
@@ -0,0 +1,42 @@
1
+ # @author Matthieu CIAPPARA <ciappa_m@modulotech.fr>
2
+ # A service to write formatted debug logs from a method.
3
+ class Modulorails::LogsForMethodService < Modulorails::BaseService
4
+
5
+ # @param method [String] The name of the calling method
6
+ # @param message [String,#to_json] The body of the log.
7
+ # @param tags [Array<String,#to_tag>] A list of tags to prefix the log.
8
+ def initialize(method:, message:, tags: [])
9
+ super()
10
+ @method = method
11
+ @message = message
12
+ @tags = tags
13
+ end
14
+
15
+ # Write a formatted debug log using given initialization parameters
16
+ def call
17
+ # Map the tags (either objects responding to #to_tag or strings) to prefix the log body
18
+ tag_strings = @tags.map do |tag|
19
+ tag.respond_to?(:to_tag) ? "[#{tag.to_tag}]" : "[#{tag}]"
20
+ end
21
+
22
+ # If the message respond_to #to_json (and is not a String), use it.
23
+ @message = jsonify if !@message.is_a?(String) && @message.respond_to?(:to_json)
24
+
25
+ # Join the tags
26
+ tag_string = tag_strings.join
27
+
28
+ # Split on newlines to avoid a log of a thousand columns and for each line, prefix the tags
29
+ # and log it as debug.
30
+ @message.split("\n").each do |line|
31
+ msg = "#{tag_string}[#{@method}] #{line}"
32
+
33
+ Rails.logger.debug(msg)
34
+ end
35
+ end
36
+
37
+ private
38
+
39
+ def jsonify
40
+ @message.to_json
41
+ end
42
+ end
@@ -0,0 +1,2 @@
1
+ require_relative 'base_service'
2
+ require_relative 'logs_for_method_service'
@@ -0,0 +1,17 @@
1
+ # @author Matthieu Ciappara <ciappa_m@modulotech>
2
+ # A success resulting from an operation with optional additional data.
3
+ class Modulorails::SuccessData
4
+ # @!attribute r data
5
+ # An object to transport some data (for instance the result of the operation). Defaults to nil.
6
+ attr_reader :data
7
+
8
+ # @param data [Object] An object to transport some data (for instance the result of the operation)
9
+ def initialize(data=nil)
10
+ @data = data
11
+ end
12
+
13
+ # @return [true] A success always means the operation was a success. ;)
14
+ def success?
15
+ true
16
+ end
17
+ end
@@ -52,13 +52,19 @@ module Modulorails
52
52
 
53
53
  def check_standard_config_file_location
54
54
  # Load the configuration
55
- config = Psych.load_file(Rails.root.join('config/database.yml'))
55
+ config = if Modulorails::COMPARABLE_RUBY_VERSION >= Gem::Version.new('3.1')
56
+ # Ruby 3.1 uses Psych4 which changes the default way of handling aliases in
57
+ # `load_file`.
58
+ Psych.load_file(Rails.root.join('config/database.yml'), aliases: true)
59
+ else
60
+ Psych.load_file(Rails.root.join('config/database.yml'))
61
+ end
56
62
 
57
63
  # If no exception was raised, then the database configuration file is at standard location
58
64
  @rules[:standard_config_file_location] = true
59
65
 
60
66
  config
61
- rescue StandardError =>e
67
+ rescue StandardError => e
62
68
  # An exception was raised, either the file is not a the standard location, either it just
63
69
  # cannot be read. Either way, we consider the config as invalid
64
70
  @rules[:standard_config_file_location] = false
@@ -1,3 +1,6 @@
1
1
  module Modulorails
2
- VERSION = '0.4.0'
2
+ VERSION = '1.0.0'
3
+
4
+ # Useful to compare the current Ruby version
5
+ COMPARABLE_RUBY_VERSION = Gem::Version.new(RUBY_VERSION)
3
6
  end
data/lib/modulorails.rb CHANGED
@@ -6,7 +6,12 @@ require 'modulorails/railtie' if defined?(Rails::Railtie)
6
6
  require 'generators/modulorails/gitlabci/gitlabci_generator'
7
7
  require 'generators/modulorails/healthcheck/health_check_generator'
8
8
  require 'generators/modulorails/self_update/self_update_generator'
9
+ require 'generators/modulorails/rubocop/rubocop_generator'
9
10
  require 'httparty'
11
+ require 'modulorails/error_data'
12
+ require 'modulorails/success_data'
13
+ require 'modulorails/errors/errors'
14
+ require 'modulorails/services/services'
10
15
 
11
16
  # Author: Matthieu 'ciappa_m' Ciappara
12
17
  # The entry point of the gem. It exposes the configurator, the gathered data and the method to
@@ -147,5 +152,12 @@ module Modulorails
147
152
 
148
153
  Modulorails::HealthCheckGenerator.new([], {}, {}).invoke_all
149
154
  end
155
+
156
+ # @author Matthieu 'ciappa_m' Ciappara
157
+ #
158
+ # Generate a rubocop configuration.
159
+ def generate_rubocop_template
160
+ Modulorails::RubocopGenerator.new([], {}, {}).invoke_all
161
+ end
150
162
  end
151
163
  end
data/modulorails.gemspec CHANGED
@@ -34,7 +34,9 @@ Gem::Specification.new do |spec|
34
34
  spec.add_runtime_dependency 'httparty'
35
35
  spec.add_runtime_dependency 'i18n'
36
36
  spec.add_runtime_dependency 'health_check', '~> 3.1'
37
+ spec.add_runtime_dependency 'rubocop', '= 1.25.1'
38
+ spec.add_runtime_dependency 'rubocop-rails', '= 2.13.2'
37
39
 
38
40
  spec.add_development_dependency 'activerecord', '>= 4.2.0'
39
- spec.add_development_dependency "appraisal"
41
+ spec.add_development_dependency 'appraisal'
40
42
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: modulorails
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.4.0
4
+ version: 1.0.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Matthieu Ciappara
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2022-01-20 00:00:00.000000000 Z
11
+ date: 2022-02-10 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: railties
@@ -86,6 +86,34 @@ dependencies:
86
86
  - - "~>"
87
87
  - !ruby/object:Gem::Version
88
88
  version: '3.1'
89
+ - !ruby/object:Gem::Dependency
90
+ name: rubocop
91
+ requirement: !ruby/object:Gem::Requirement
92
+ requirements:
93
+ - - '='
94
+ - !ruby/object:Gem::Version
95
+ version: 1.25.1
96
+ type: :runtime
97
+ prerelease: false
98
+ version_requirements: !ruby/object:Gem::Requirement
99
+ requirements:
100
+ - - '='
101
+ - !ruby/object:Gem::Version
102
+ version: 1.25.1
103
+ - !ruby/object:Gem::Dependency
104
+ name: rubocop-rails
105
+ requirement: !ruby/object:Gem::Requirement
106
+ requirements:
107
+ - - '='
108
+ - !ruby/object:Gem::Version
109
+ version: 2.13.2
110
+ type: :runtime
111
+ prerelease: false
112
+ version_requirements: !ruby/object:Gem::Requirement
113
+ requirements:
114
+ - - '='
115
+ - !ruby/object:Gem::Version
116
+ version: 2.13.2
89
117
  - !ruby/object:Gem::Dependency
90
118
  name: activerecord
91
119
  requirement: !ruby/object:Gem::Requirement
@@ -129,6 +157,7 @@ files:
129
157
  - ".dockerignore"
130
158
  - ".gitignore"
131
159
  - ".rspec"
160
+ - ".rubocop.yml"
132
161
  - ".travis.yml"
133
162
  - Appraisals
134
163
  - CHANGELOG.md
@@ -143,9 +172,12 @@ files:
143
172
  - LICENSE.txt
144
173
  - README.md
145
174
  - Rakefile
175
+ - app/assets/stylesheets/modulorails.css
176
+ - app/helpers/modulorails/application_helper.rb
146
177
  - bin/console
147
178
  - bin/setup
148
179
  - config/locales/en.yml
180
+ - docker-compose.debug.yml
149
181
  - docker-compose.yml
150
182
  - entrypoints/appraisal_test.sh
151
183
  - gemfiles/rails_52.gemfile
@@ -167,11 +199,24 @@ files:
167
199
  - lib/generators/modulorails/healthcheck/health_check_generator.rb
168
200
  - lib/generators/modulorails/healthcheck/templates/.modulorails-health_check
169
201
  - lib/generators/modulorails/healthcheck/templates/config/initializers/health_check.rb.tt
202
+ - lib/generators/modulorails/rubocop/rubocop_generator.rb
203
+ - lib/generators/modulorails/rubocop/templates/rubocop.yml.tt
170
204
  - lib/generators/modulorails/self_update/self_update_generator.rb
205
+ - lib/generators/modulorails/service/service_generator.rb
206
+ - lib/generators/modulorails/service/templates/service.rb.tt
171
207
  - lib/modulorails.rb
172
208
  - lib/modulorails/configuration.rb
173
209
  - lib/modulorails/data.rb
210
+ - lib/modulorails/error_data.rb
211
+ - lib/modulorails/errors/base_error.rb
212
+ - lib/modulorails/errors/errors.rb
213
+ - lib/modulorails/errors/invalid_format_error.rb
214
+ - lib/modulorails/errors/invalid_value_error.rb
174
215
  - lib/modulorails/railtie.rb
216
+ - lib/modulorails/services/base_service.rb
217
+ - lib/modulorails/services/logs_for_method_service.rb
218
+ - lib/modulorails/services/services.rb
219
+ - lib/modulorails/success_data.rb
175
220
  - lib/modulorails/validators/database_configuration.rb
176
221
  - lib/modulorails/version.rb
177
222
  - modulorails.gemspec