modulorails 0.4.0 → 1.0.0

Sign up to get free protection for your applications and to get access to all the features.
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