modulorails 1.0.2 → 1.1.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 +4 -4
- data/.rubocop.yml +222 -17
- data/Appraisals +6 -6
- data/CHANGELOG.md +9 -0
- data/app/helpers/modulorails/application_helper.rb +4 -2
- data/gemfiles/rails_52.gemfile +5 -5
- data/gemfiles/rails_60.gemfile +5 -5
- data/gemfiles/rails_61.gemfile +5 -5
- data/gemfiles/rails_70.gemfile +5 -5
- data/lib/generators/modulorails/docker/docker_generator.rb +10 -1
- data/lib/generators/modulorails/docker/templates/Dockerfile.prod.tt +4 -0
- data/lib/generators/modulorails/docker/templates/Dockerfile.tt +3 -0
- data/lib/generators/modulorails/docker/templates/config/database.yml.tt +1 -1
- data/lib/generators/modulorails/docker/templates/docker-compose.yml.tt +6 -1
- data/lib/generators/modulorails/docker/templates/entrypoints/docker-entrypoint.sh.tt +2 -2
- data/lib/generators/modulorails/gitlabci/gitlabci_generator.rb +4 -2
- data/lib/generators/modulorails/healthcheck/health_check_generator.rb +8 -5
- data/lib/generators/modulorails/rubocop/rubocop_generator.rb +8 -6
- data/lib/generators/modulorails/self_update/self_update_generator.rb +6 -3
- data/lib/generators/modulorails/service/service_generator.rb +3 -1
- data/lib/modulorails/configuration.rb +4 -0
- data/lib/modulorails/data.rb +113 -62
- data/lib/modulorails/error_data.rb +2 -0
- data/lib/modulorails/errors/invalid_format_error.rb +2 -0
- data/lib/modulorails/errors/invalid_value_error.rb +2 -0
- data/lib/modulorails/railtie.rb +5 -1
- data/lib/modulorails/services/base_service.rb +17 -15
- data/lib/modulorails/services/logs_for_method_service.rb +1 -0
- data/lib/modulorails/success_data.rb +2 -0
- data/lib/modulorails/validators/database_configuration.rb +19 -9
- data/lib/modulorails/version.rb +3 -1
- data/lib/modulorails.rb +40 -33
- data/modulorails.gemspec +8 -7
- metadata +31 -32
- data/lib/generators/modulorails/gitlabci/templates/config/database-ci.yml.tt +0 -8
data/lib/modulorails/data.rb
CHANGED
|
@@ -3,47 +3,90 @@ require 'active_record'
|
|
|
3
3
|
require 'git'
|
|
4
4
|
|
|
5
5
|
module Modulorails
|
|
6
|
+
|
|
6
7
|
# Author: Matthieu 'ciappa_m' Ciappara
|
|
7
8
|
# This holds the data gathered by the gem. Some come from the configuration by the gem's user.
|
|
8
9
|
# Some are fetched dynamically.
|
|
9
10
|
class Data
|
|
11
|
+
|
|
10
12
|
# All the data handled by this class
|
|
11
13
|
ATTRIBUTE_KEYS = %i[
|
|
12
14
|
name main_developer project_manager repository type rails_name ruby_version rails_version
|
|
13
|
-
bundler_version modulorails_version adapter db_version adapter_version
|
|
14
|
-
|
|
15
|
+
bundler_version modulorails_version adapter db_version adapter_version webpacker_version
|
|
16
|
+
importmap_version jsbundling_version
|
|
17
|
+
production_url staging_url review_base_url
|
|
15
18
|
].freeze
|
|
16
19
|
|
|
17
20
|
# Useful if the gem's user need to read one of the data
|
|
18
|
-
attr_reader
|
|
21
|
+
attr_reader(*ATTRIBUTE_KEYS)
|
|
19
22
|
|
|
20
23
|
def initialize
|
|
24
|
+
initialize_from_constants
|
|
25
|
+
initialize_from_configuration
|
|
26
|
+
initialize_from_database
|
|
27
|
+
initialize_from_gem_specs
|
|
28
|
+
initialize_from_git
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
# @author Matthieu 'ciappa_m' Ciappara
|
|
32
|
+
# @return [String] Text version of the data
|
|
33
|
+
def to_s
|
|
34
|
+
ATTRIBUTE_KEYS.map { |key| "#{key}: #{send(key)}" }.join(', ')
|
|
35
|
+
end
|
|
36
|
+
|
|
37
|
+
# @author Matthieu 'ciappa_m' Ciappara
|
|
38
|
+
# @return [Hash] The payload for the request to the intranet
|
|
39
|
+
def to_params
|
|
40
|
+
{
|
|
41
|
+
'name' => @name,
|
|
42
|
+
'main_developer' => @main_developer,
|
|
43
|
+
'project_manager' => @project_manager,
|
|
44
|
+
'repository' => @repository,
|
|
45
|
+
'app_type' => @type,
|
|
46
|
+
'project_data' => to_project_data_params
|
|
47
|
+
}
|
|
48
|
+
end
|
|
49
|
+
|
|
50
|
+
private
|
|
51
|
+
|
|
52
|
+
def initialize_from_constants
|
|
53
|
+
# The API can handle more project types but this gem is (obviously) intended for Rails
|
|
54
|
+
# projects only
|
|
55
|
+
@type = 'rails'
|
|
56
|
+
|
|
57
|
+
# The name defined for the Rails application; it can be completely different from the usual
|
|
58
|
+
# name or can be the same
|
|
59
|
+
@rails_name = ::Rails.application.class.name&.split('::')&.first
|
|
60
|
+
|
|
61
|
+
# The Ruby version used by the application
|
|
62
|
+
@ruby_version = RUBY_VERSION
|
|
63
|
+
|
|
64
|
+
# The version of the gem
|
|
65
|
+
@modulorails_version = Modulorails::VERSION
|
|
66
|
+
end
|
|
67
|
+
|
|
68
|
+
def initialize_from_configuration
|
|
21
69
|
# Get the gem's configuration to get the application's usual name, main dev and PM
|
|
22
70
|
configuration = Modulorails.configuration
|
|
23
|
-
# Get the database connection to identify the database used by the application
|
|
24
|
-
# or return nil if the database does not exist
|
|
25
|
-
db_connection = begin
|
|
26
|
-
ActiveRecord::Base.connection
|
|
27
|
-
rescue ActiveRecord::NoDatabaseError => e
|
|
28
|
-
$stderr.puts("[Modulorails] Error: #{e.message}")
|
|
29
|
-
nil
|
|
30
|
-
end
|
|
31
|
-
# Get the gem's specifications to fetch the versions of critical gems
|
|
32
|
-
loaded_specs = Gem.loaded_specs
|
|
33
71
|
|
|
34
72
|
# The data written by the user in the configuration
|
|
35
73
|
# The name is the usual name of the project, the one used in conversations at Modulotech
|
|
36
74
|
@name = configuration.name
|
|
75
|
+
|
|
37
76
|
# The main developer, the lead developer, in short the developer to call when something's
|
|
38
77
|
# wrong with the application ;)
|
|
39
78
|
@main_developer = configuration.main_developer
|
|
79
|
+
|
|
40
80
|
# The project manager of the application; the other person to call when something's wrong with
|
|
41
81
|
# the application ;)
|
|
42
82
|
@project_manager = configuration.project_manager
|
|
83
|
+
|
|
43
84
|
# The URL of the production environment for the application
|
|
44
85
|
@production_url = configuration.production_url
|
|
86
|
+
|
|
45
87
|
# The URL of the staging environment for the application
|
|
46
88
|
@staging_url = configuration.staging_url
|
|
89
|
+
|
|
47
90
|
# The base URL of the review environment for the application.
|
|
48
91
|
# A real review URL is built like this at Modulotech:
|
|
49
92
|
# https://review-#{shortened_branch_name}-#{ci_slug}.#{review_base_url}
|
|
@@ -53,21 +96,29 @@ module Modulorails
|
|
|
53
96
|
# ci_slug: jzzham
|
|
54
97
|
# |-> https://review-786-a_sup-jzzham.dev.app.com/
|
|
55
98
|
@review_base_url = configuration.review_base_url
|
|
99
|
+
end
|
|
56
100
|
|
|
57
|
-
|
|
58
|
-
#
|
|
59
|
-
|
|
101
|
+
def initialize_from_database
|
|
102
|
+
# Get the database connection to identify the database used by the application
|
|
103
|
+
# or return nil if the database does not exist
|
|
104
|
+
db_connection = begin
|
|
105
|
+
ActiveRecord::Base.connection
|
|
106
|
+
rescue ActiveRecord::NoDatabaseError, ActiveRecord::ConnectionNotEstablished => e
|
|
107
|
+
warn("[Modulorails] Error: #{e.message}")
|
|
108
|
+
nil
|
|
109
|
+
end
|
|
60
110
|
|
|
61
|
-
# The
|
|
62
|
-
|
|
63
|
-
@type = 'rails'
|
|
111
|
+
# The name of the ActiveRecord adapter; it gives the name of the database system too
|
|
112
|
+
@adapter = db_connection&.adapter_name&.downcase
|
|
64
113
|
|
|
65
|
-
# The
|
|
66
|
-
#
|
|
67
|
-
@
|
|
114
|
+
# The version of the database engine; this request works only on MySQL and PostgreSQL
|
|
115
|
+
# It should not be a problem since those are the sole database engines used at Modulotech
|
|
116
|
+
@db_version = db_connection&.select_value('SELECT version()')
|
|
117
|
+
end
|
|
68
118
|
|
|
69
|
-
|
|
70
|
-
|
|
119
|
+
def initialize_from_gem_specs
|
|
120
|
+
# Get the gem's specifications to fetch the versions of critical gems
|
|
121
|
+
loaded_specs = Gem.loaded_specs
|
|
71
122
|
|
|
72
123
|
# The Rails version used by the application
|
|
73
124
|
@rails_version = loaded_specs['rails'].version.version
|
|
@@ -76,53 +127,53 @@ module Modulorails
|
|
|
76
127
|
# Bundler 1 are not compatible)
|
|
77
128
|
@bundler_version = loaded_specs['bundler'].version.version
|
|
78
129
|
|
|
79
|
-
# The version of the
|
|
80
|
-
@
|
|
130
|
+
# The version of the ActiveRecord adapter
|
|
131
|
+
@adapter_version = loaded_specs[@adapter]&.version&.version
|
|
81
132
|
|
|
82
|
-
# The
|
|
83
|
-
@
|
|
133
|
+
# The version of the webpacker gem - might be nil
|
|
134
|
+
@webpacker_version = loaded_specs['webpacker']&.version&.version
|
|
84
135
|
|
|
85
|
-
# The version of the
|
|
86
|
-
|
|
87
|
-
@db_version = db_connection&.select_value('SELECT version()')
|
|
136
|
+
# The version of the importmap-rails gem - might be nil
|
|
137
|
+
@importmap_version = loaded_specs['importmap-rails']&.version&.version
|
|
88
138
|
|
|
89
|
-
# The version of the
|
|
90
|
-
@
|
|
139
|
+
# The version of the jsbundling-rails gem - might be nil
|
|
140
|
+
@jsbundling_version = loaded_specs['jsbundling-rails']&.version&.version
|
|
91
141
|
end
|
|
92
142
|
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
143
|
+
def initialize_from_git
|
|
144
|
+
# Theorically, origin is the main repository of the project and git is the sole VCS we use
|
|
145
|
+
# at Modulotech
|
|
146
|
+
@repository = Git.open(::Rails.root).config('remote.origin.url')
|
|
97
147
|
end
|
|
98
148
|
|
|
99
|
-
|
|
100
|
-
# @return [Hash] The payload for the request to the intranet
|
|
101
|
-
def to_params
|
|
149
|
+
def to_project_data_params
|
|
102
150
|
{
|
|
103
|
-
'name'
|
|
104
|
-
'
|
|
105
|
-
'
|
|
106
|
-
'
|
|
107
|
-
'
|
|
108
|
-
'
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
},
|
|
119
|
-
'urls' => {
|
|
120
|
-
'production' => @production_url,
|
|
121
|
-
'staging' => @staging_url,
|
|
122
|
-
'review_base' => @review_base_url
|
|
123
|
-
}
|
|
124
|
-
}
|
|
151
|
+
'name' => @rails_name,
|
|
152
|
+
'ruby_version' => @ruby_version,
|
|
153
|
+
'rails_version' => @rails_version,
|
|
154
|
+
'bundler_version' => @bundler_version,
|
|
155
|
+
'modulorails_version' => @modulorails_version,
|
|
156
|
+
'database' => to_database_params,
|
|
157
|
+
'urls' => to_urls_params
|
|
158
|
+
}
|
|
159
|
+
end
|
|
160
|
+
|
|
161
|
+
def to_database_params
|
|
162
|
+
{
|
|
163
|
+
'adapter' => @adapter,
|
|
164
|
+
'db_version' => @db_version,
|
|
165
|
+
'gem_version' => @adapter_version
|
|
125
166
|
}
|
|
126
167
|
end
|
|
168
|
+
|
|
169
|
+
def to_urls_params
|
|
170
|
+
{
|
|
171
|
+
'production' => @production_url,
|
|
172
|
+
'staging' => @staging_url,
|
|
173
|
+
'review_base' => @review_base_url
|
|
174
|
+
}
|
|
175
|
+
end
|
|
176
|
+
|
|
127
177
|
end
|
|
178
|
+
|
|
128
179
|
end
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
# @author Matthieu Ciappara <ciappa_m@modulotech>
|
|
2
2
|
# An error encountered during an operation with additional data.
|
|
3
3
|
class Modulorails::ErrorData
|
|
4
|
+
|
|
4
5
|
# @!attribute r errors
|
|
5
6
|
# An error message or an array of error messages (those will be joined by a coma and a space).
|
|
6
7
|
# @!attribute r exception
|
|
@@ -18,4 +19,5 @@ class Modulorails::ErrorData
|
|
|
18
19
|
def success?
|
|
19
20
|
false
|
|
20
21
|
end
|
|
22
|
+
|
|
21
23
|
end
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
# @author Matthieu CIAPPARA <ciappa_m@modulotech.fr>
|
|
2
2
|
# An exception representing an invalid format for a given field.
|
|
3
3
|
class Modulorails::InvalidFormatError < Modulorails::BaseError
|
|
4
|
+
|
|
4
5
|
# @!attribute r field
|
|
5
6
|
# The name of the field that had a wrong format.
|
|
6
7
|
attr_reader :field
|
|
@@ -11,4 +12,5 @@ class Modulorails::InvalidFormatError < Modulorails::BaseError
|
|
|
11
12
|
|
|
12
13
|
@field = field
|
|
13
14
|
end
|
|
15
|
+
|
|
14
16
|
end
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
# @author Matthieu CIAPPARA <ciappa_m@modulotech.fr>
|
|
2
2
|
# An exception representing an invalid value for a given field.
|
|
3
3
|
class Modulorails::InvalidValueError < Modulorails::BaseError
|
|
4
|
+
|
|
4
5
|
# @!attribute r field
|
|
5
6
|
# The name of the field that had a wrong value.
|
|
6
7
|
attr_reader :field
|
|
@@ -11,4 +12,5 @@ class Modulorails::InvalidValueError < Modulorails::BaseError
|
|
|
11
12
|
|
|
12
13
|
@field = field
|
|
13
14
|
end
|
|
15
|
+
|
|
14
16
|
end
|
data/lib/modulorails/railtie.rb
CHANGED
|
@@ -1,8 +1,10 @@
|
|
|
1
1
|
require_relative '../../app/helpers/modulorails/application_helper'
|
|
2
2
|
|
|
3
3
|
module Modulorails
|
|
4
|
+
|
|
4
5
|
# Bind in the Rails lifecycle
|
|
5
6
|
class Railtie < ::Rails::Railtie
|
|
7
|
+
|
|
6
8
|
# Update and add gems before we load the configuration
|
|
7
9
|
config.before_configuration do
|
|
8
10
|
# Currently, we limit everything to the development environment
|
|
@@ -35,7 +37,7 @@ module Modulorails
|
|
|
35
37
|
# Currently, we limit everything to the development environment
|
|
36
38
|
if Rails.env.development?
|
|
37
39
|
# Load translations
|
|
38
|
-
I18n.load_path += [File.expand_path('
|
|
40
|
+
I18n.load_path += [File.expand_path('../../config/locales/en.yml', __dir__)]
|
|
39
41
|
|
|
40
42
|
# Effectively send the data to the intranet
|
|
41
43
|
Modulorails.send_data
|
|
@@ -53,5 +55,7 @@ module Modulorails
|
|
|
53
55
|
Modulorails.self_update
|
|
54
56
|
end
|
|
55
57
|
end
|
|
58
|
+
|
|
56
59
|
end
|
|
60
|
+
|
|
57
61
|
end
|
|
@@ -2,6 +2,7 @@
|
|
|
2
2
|
# The base class for services. Should be implemented by ApplicationService following the model of
|
|
3
3
|
# ActiveRecord::Base and ApplicationRecord.
|
|
4
4
|
class Modulorails::BaseService
|
|
5
|
+
|
|
5
6
|
# Allow to instantiate the service and call the service in one go.
|
|
6
7
|
if Modulorails::COMPARABLE_RUBY_VERSION < Gem::Version.new('3.0')
|
|
7
8
|
def self.call(*args, &block)
|
|
@@ -28,7 +29,7 @@ class Modulorails::BaseService
|
|
|
28
29
|
end
|
|
29
30
|
|
|
30
31
|
# Shamelessly copied from text_helper
|
|
31
|
-
def self.pluralize(count, singular, plural_arg
|
|
32
|
+
def self.pluralize(count, singular, plural_arg=nil, plural: plural_arg, locale: I18n.locale)
|
|
32
33
|
word = if count == 1 || count =~ /^1(\.0+)?$/
|
|
33
34
|
singular
|
|
34
35
|
else
|
|
@@ -65,7 +66,9 @@ class Modulorails::BaseService
|
|
|
65
66
|
rescue StandardError => e
|
|
66
67
|
# Unknown error, log the error
|
|
67
68
|
Rails.logger.error("#{self}: #{e.message}")
|
|
68
|
-
Rails.logger.error("Local variables: #{local_variables.map! { |v|
|
|
69
|
+
Rails.logger.error("Local variables: #{local_variables.map! { |v|
|
|
70
|
+
{ v => binding.local_variable_get(v) }
|
|
71
|
+
} }")
|
|
69
72
|
Rails.logger.error(e.backtrace&.join("\n"))
|
|
70
73
|
|
|
71
74
|
# Return the error
|
|
@@ -76,7 +79,7 @@ class Modulorails::BaseService
|
|
|
76
79
|
# @param from [String,ActiveSupport::TimeWithZone] the minimum date
|
|
77
80
|
# @param to [String,ActiveSupport::TimeWithZone] the maximum date
|
|
78
81
|
# @return [[ActiveSupport::TimeWithZone, ActiveSupport::TimeWithZone]] The given dates casted.
|
|
79
|
-
def params_to_time(from, to
|
|
82
|
+
def params_to_time(from, to=nil)
|
|
80
83
|
from = from.is_a?(String) && from.present? ? from.to_time_with_zone : from
|
|
81
84
|
to = if to.is_a?(String) && to.present?
|
|
82
85
|
to = to.to_time_with_zone
|
|
@@ -92,7 +95,7 @@ class Modulorails::BaseService
|
|
|
92
95
|
end
|
|
93
96
|
|
|
94
97
|
# Shamelessly copied from text_helper
|
|
95
|
-
def pluralize(count, singular, plural_arg
|
|
98
|
+
def pluralize(count, singular, plural_arg=nil, plural: plural_arg, locale: I18n.locale)
|
|
96
99
|
self.class.pluralize(count, singular, plural_arg, plural: plural, locale: locale)
|
|
97
100
|
end
|
|
98
101
|
|
|
@@ -141,7 +144,9 @@ class Modulorails::BaseService
|
|
|
141
144
|
value = params.dig(*keys)
|
|
142
145
|
|
|
143
146
|
if value.respond_to?(:each)
|
|
144
|
-
raise InvalidValueError.new(keys.join('/')) unless value.all? { |v|
|
|
147
|
+
raise InvalidValueError.new(keys.join('/')) unless value.all? { |v|
|
|
148
|
+
allowed_values.include?(v)
|
|
149
|
+
}
|
|
145
150
|
else
|
|
146
151
|
return nil if !value && allow_nil
|
|
147
152
|
|
|
@@ -162,11 +167,9 @@ class Modulorails::BaseService
|
|
|
162
167
|
value = params.dig(*keys)
|
|
163
168
|
|
|
164
169
|
unless value
|
|
165
|
-
if allow_nil
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
raise InvalidValueError.new(keys.join('/'))
|
|
169
|
-
end
|
|
170
|
+
return nil if allow_nil
|
|
171
|
+
|
|
172
|
+
raise InvalidValueError.new(keys.join('/'))
|
|
170
173
|
end
|
|
171
174
|
|
|
172
175
|
result = model.find_by(field => value)
|
|
@@ -187,11 +190,9 @@ class Modulorails::BaseService
|
|
|
187
190
|
values = params.dig(*keys)
|
|
188
191
|
|
|
189
192
|
if values.blank?
|
|
190
|
-
if allow_nil
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
raise InvalidValueError.new(keys.join('/'))
|
|
194
|
-
end
|
|
193
|
+
return nil if allow_nil
|
|
194
|
+
|
|
195
|
+
raise InvalidValueError.new(keys.join('/'))
|
|
195
196
|
end
|
|
196
197
|
|
|
197
198
|
results = model.where(field => values)
|
|
@@ -200,4 +201,5 @@ class Modulorails::BaseService
|
|
|
200
201
|
|
|
201
202
|
results
|
|
202
203
|
end
|
|
204
|
+
|
|
203
205
|
end
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
# @author Matthieu Ciappara <ciappa_m@modulotech>
|
|
2
2
|
# A success resulting from an operation with optional additional data.
|
|
3
3
|
class Modulorails::SuccessData
|
|
4
|
+
|
|
4
5
|
# @!attribute r data
|
|
5
6
|
# An object to transport some data (for instance the result of the operation). Defaults to nil.
|
|
6
7
|
attr_reader :data
|
|
@@ -14,4 +15,5 @@ class Modulorails::SuccessData
|
|
|
14
15
|
def success?
|
|
15
16
|
true
|
|
16
17
|
end
|
|
18
|
+
|
|
17
19
|
end
|
|
@@ -1,8 +1,11 @@
|
|
|
1
1
|
module Modulorails
|
|
2
|
+
|
|
2
3
|
module Validators
|
|
4
|
+
|
|
3
5
|
# Author: Matthieu 'ciappa_m' Ciappara
|
|
4
6
|
# This holds the rules to configure the database by respecting Modulotech's norms.
|
|
5
7
|
class DatabaseConfiguration
|
|
8
|
+
|
|
6
9
|
def initialize
|
|
7
10
|
# All rules are invalid by default
|
|
8
11
|
@rules = {
|
|
@@ -37,19 +40,23 @@ module Modulorails
|
|
|
37
40
|
check_rules_for_environment(database_configuration, :development)
|
|
38
41
|
check_rules_for_environment(database_configuration, :test)
|
|
39
42
|
|
|
40
|
-
|
|
43
|
+
fetch_invalid_rules
|
|
41
44
|
end
|
|
42
45
|
|
|
43
46
|
private
|
|
44
47
|
|
|
45
|
-
def
|
|
46
|
-
dev = @rules[:development].
|
|
47
|
-
test = @rules[:test].
|
|
48
|
-
general = @rules
|
|
48
|
+
def fetch_invalid_rules
|
|
49
|
+
dev = select_invalid_keys(@rules[:development]).map { |k| "development.#{k}" }
|
|
50
|
+
test = select_invalid_keys(@rules[:test]).map { |k| "test.#{k}" }
|
|
51
|
+
general = select_invalid_keys(@rules)
|
|
49
52
|
|
|
50
53
|
general + dev + test
|
|
51
54
|
end
|
|
52
55
|
|
|
56
|
+
def select_invalid_keys(hash)
|
|
57
|
+
hash.select { |_k, v| v == false }.keys
|
|
58
|
+
end
|
|
59
|
+
|
|
53
60
|
def check_standard_config_file_location
|
|
54
61
|
# Load the configuration
|
|
55
62
|
config = if Modulorails::COMPARABLE_RUBY_VERSION >= Gem::Version.new('3.1')
|
|
@@ -64,7 +71,7 @@ module Modulorails
|
|
|
64
71
|
@rules[:standard_config_file_location] = true
|
|
65
72
|
|
|
66
73
|
config
|
|
67
|
-
rescue StandardError
|
|
74
|
+
rescue StandardError
|
|
68
75
|
# An exception was raised, either the file is not a the standard location, either it just
|
|
69
76
|
# cannot be read. Either way, we consider the config as invalid
|
|
70
77
|
@rules[:standard_config_file_location] = false
|
|
@@ -74,13 +81,13 @@ module Modulorails
|
|
|
74
81
|
# The database for tests MUST NOT be the same as the development database since the test
|
|
75
82
|
# database is rewritten each time the tests are launched
|
|
76
83
|
def check_test_database_not_equals_dev_database(config)
|
|
77
|
-
|
|
78
|
-
|
|
84
|
+
@rules[:test_database_not_equals_dev_database] =
|
|
85
|
+
config['test']['database'] != config['development']['database']
|
|
79
86
|
end
|
|
80
87
|
|
|
81
88
|
# Check all rules for an environment
|
|
82
89
|
def check_rules_for_environment(config, env)
|
|
83
|
-
@rules[env].
|
|
90
|
+
@rules[env].each_key do |rule|
|
|
84
91
|
key = rule.to_s.gsub(/configurable_/, '')
|
|
85
92
|
check_configurable_key_for_environment(config, env, key)
|
|
86
93
|
end
|
|
@@ -94,6 +101,9 @@ module Modulorails
|
|
|
94
101
|
# Use of `!!` to convert `nil` to `false` and `0` to `true`
|
|
95
102
|
@rules[env][:"configurable_#{key}"] = !!valid_rule
|
|
96
103
|
end
|
|
104
|
+
|
|
97
105
|
end
|
|
106
|
+
|
|
98
107
|
end
|
|
108
|
+
|
|
99
109
|
end
|
data/lib/modulorails/version.rb
CHANGED
data/lib/modulorails.rb
CHANGED
|
@@ -17,11 +17,13 @@ require 'modulorails/services/services'
|
|
|
17
17
|
# The entry point of the gem. It exposes the configurator, the gathered data and the method to
|
|
18
18
|
# send those data to the intranet.
|
|
19
19
|
module Modulorails
|
|
20
|
+
|
|
20
21
|
# Author: Matthieu 'ciappa_m' Ciappara
|
|
21
22
|
# The error class of the gem. Allow to identify all functional errors raised by the gem.
|
|
22
23
|
class Error < StandardError; end
|
|
23
24
|
|
|
24
25
|
class << self
|
|
26
|
+
|
|
25
27
|
# Useful to update the configuration
|
|
26
28
|
attr_writer :configuration
|
|
27
29
|
|
|
@@ -73,38 +75,38 @@ module Modulorails
|
|
|
73
75
|
# If no endpoint and/or no API key is configured, it is impossible to send the data to the
|
|
74
76
|
# intranet and thus we raise an error: it is the only error we want to raise since it goes
|
|
75
77
|
# against one of the main goals of the gem and the gem's user is responsible.
|
|
76
|
-
|
|
77
|
-
# Define the headers of the request ; sending JSON and API key to authenticate the gem on
|
|
78
|
-
# the intranet
|
|
79
|
-
headers = {
|
|
80
|
-
'Content-Type' => 'application/json', 'X-MODULORAILS-TOKEN' => configuration.api_key
|
|
81
|
-
}
|
|
82
|
-
|
|
83
|
-
# Define the JSON body of the request
|
|
84
|
-
body = data.to_params.to_json
|
|
85
|
-
|
|
86
|
-
# Prevent HTTParty to raise error and crash the server in dev
|
|
87
|
-
begin
|
|
88
|
-
# Post to the configured endpoint on the Intranet
|
|
89
|
-
response = HTTParty.post(configuration.endpoint, headers: headers, body: body)
|
|
90
|
-
|
|
91
|
-
# According to the API specification, on a "Bad request" response, the server explicits what
|
|
92
|
-
# went wrong with an `errors` field. We do not want to raise since the gem's user is not
|
|
93
|
-
# (necessarily) responsible for the error but we still need to display it somewhere to warn
|
|
94
|
-
# the user something went wrong.
|
|
95
|
-
puts("[Modulorails] Error: #{response['errors'].join(', ')}") if response.code == 400
|
|
96
|
-
|
|
97
|
-
# Return the response to allow users to do some more
|
|
98
|
-
response
|
|
99
|
-
rescue StandardError => e
|
|
100
|
-
# Still need to notify the user
|
|
101
|
-
puts("[Modulorails] Error: Could not post to #{configuration.endpoint}")
|
|
102
|
-
puts e.message
|
|
103
|
-
nil
|
|
104
|
-
end
|
|
105
|
-
else
|
|
78
|
+
unless configuration.endpoint && configuration.api_key
|
|
106
79
|
raise Error.new('No endpoint or api key')
|
|
107
80
|
end
|
|
81
|
+
|
|
82
|
+
# Define the headers of the request ; sending JSON and API key to authenticate the gem on
|
|
83
|
+
# the intranet
|
|
84
|
+
headers = {
|
|
85
|
+
'Content-Type' => 'application/json', 'X-MODULORAILS-TOKEN' => configuration.api_key
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
# Define the JSON body of the request
|
|
89
|
+
body = data.to_params.to_json
|
|
90
|
+
|
|
91
|
+
# Prevent HTTParty to raise error and crash the server in dev
|
|
92
|
+
begin
|
|
93
|
+
# Post to the configured endpoint on the Intranet
|
|
94
|
+
response = HTTParty.post(configuration.endpoint, headers: headers, body: body)
|
|
95
|
+
|
|
96
|
+
# According to the API specification, on a "Bad request" response, the server explicits what
|
|
97
|
+
# went wrong with an `errors` field. We do not want to raise since the gem's user is not
|
|
98
|
+
# (necessarily) responsible for the error but we still need to display it somewhere to warn
|
|
99
|
+
# the user something went wrong.
|
|
100
|
+
puts("[Modulorails] Error: #{response['errors'].join(', ')}") if response.code == 400
|
|
101
|
+
|
|
102
|
+
# Return the response to allow users to do some more
|
|
103
|
+
response
|
|
104
|
+
rescue StandardError => e
|
|
105
|
+
# Still need to notify the user
|
|
106
|
+
puts("[Modulorails] Error: Could not post to #{configuration.endpoint}")
|
|
107
|
+
puts e.message
|
|
108
|
+
nil
|
|
109
|
+
end
|
|
108
110
|
end
|
|
109
111
|
|
|
110
112
|
# @author Matthieu 'ciappa_m' Ciappara
|
|
@@ -112,7 +114,7 @@ module Modulorails
|
|
|
112
114
|
# Generate a CI/CD template unless it was already done.
|
|
113
115
|
# The check is done using a 'keepfile'.
|
|
114
116
|
def generate_ci_template
|
|
115
|
-
return if File.
|
|
117
|
+
return if File.exist?(Rails.root.join('.modulorails-gitlab-ci'))
|
|
116
118
|
|
|
117
119
|
Modulorails::GitlabciGenerator.new([], {}, {}).invoke_all
|
|
118
120
|
end
|
|
@@ -138,7 +140,10 @@ module Modulorails
|
|
|
138
140
|
# Check the last version of Modulorails available on rubygems and update if there was a
|
|
139
141
|
# publication
|
|
140
142
|
def self_update
|
|
141
|
-
|
|
143
|
+
unless configuration.no_auto_update
|
|
144
|
+
Modulorails::SelfUpdateGenerator.new([], {},
|
|
145
|
+
{}).invoke_all
|
|
146
|
+
end
|
|
142
147
|
rescue StandardError => e
|
|
143
148
|
puts("[Modulorails] An error occured: #{e.class} - #{e.message}")
|
|
144
149
|
end
|
|
@@ -148,7 +153,7 @@ module Modulorails
|
|
|
148
153
|
# Generate a health_check configuration unless it was already done.
|
|
149
154
|
# The check is done using a 'keepfile'.
|
|
150
155
|
def generate_healthcheck_template
|
|
151
|
-
return if File.
|
|
156
|
+
return if File.exist?(Rails.root.join('.modulorails-health_check'))
|
|
152
157
|
|
|
153
158
|
Modulorails::HealthCheckGenerator.new([], {}, {}).invoke_all
|
|
154
159
|
end
|
|
@@ -159,5 +164,7 @@ module Modulorails
|
|
|
159
164
|
def generate_rubocop_template
|
|
160
165
|
Modulorails::RubocopGenerator.new([], {}, {}).invoke_all
|
|
161
166
|
end
|
|
167
|
+
|
|
162
168
|
end
|
|
169
|
+
|
|
163
170
|
end
|
data/modulorails.gemspec
CHANGED
|
@@ -7,7 +7,7 @@ Gem::Specification.new do |spec|
|
|
|
7
7
|
spec.email = ['ciappa_m@modulotech.fr']
|
|
8
8
|
|
|
9
9
|
spec.summary = 'Common base for Ruby on Rails projects at Modulotech'
|
|
10
|
-
spec.description
|
|
10
|
+
spec.description = <<~END_OF_TEXT
|
|
11
11
|
Modulorails is the common base for the Ruby on Rails project at Modulotech
|
|
12
12
|
(https://www.modulotech.fr/).
|
|
13
13
|
|
|
@@ -24,19 +24,20 @@ Gem::Specification.new do |spec|
|
|
|
24
24
|
|
|
25
25
|
# Specify which files should be added to the gem when it is released.
|
|
26
26
|
# The `git ls-files -z` loads the files in the RubyGem that have been added into git.
|
|
27
|
-
spec.files
|
|
27
|
+
spec.files = Dir.chdir(File.expand_path(__dir__)) do
|
|
28
28
|
`git ls-files -z`.split("\x0").reject { |f| f.match(%r{^(test|spec|features)/}) }
|
|
29
29
|
end
|
|
30
30
|
spec.require_paths = ['lib']
|
|
31
31
|
|
|
32
|
-
spec.add_runtime_dependency 'railties', '>= 4.2.0'
|
|
33
32
|
spec.add_runtime_dependency 'git', '~> 1.7', '>= 1.7.0'
|
|
34
|
-
spec.add_runtime_dependency 'httparty'
|
|
35
|
-
spec.add_runtime_dependency 'i18n'
|
|
36
33
|
spec.add_runtime_dependency 'health_check', '~> 3.1'
|
|
37
|
-
spec.add_runtime_dependency '
|
|
38
|
-
spec.add_runtime_dependency '
|
|
34
|
+
spec.add_runtime_dependency 'httparty', '>= 0.13.3'
|
|
35
|
+
spec.add_runtime_dependency 'i18n', '>= 0.9.5'
|
|
36
|
+
spec.add_runtime_dependency 'railties', '>= 4.2.0'
|
|
37
|
+
spec.add_runtime_dependency 'rubocop', '>= 1.28.2'
|
|
38
|
+
spec.add_runtime_dependency 'rubocop-rails', '>= 2.14.2'
|
|
39
39
|
|
|
40
40
|
spec.add_development_dependency 'activerecord', '>= 4.2.0'
|
|
41
41
|
spec.add_development_dependency 'appraisal'
|
|
42
|
+
# spec.metadata['rubygems_mfa_required'] = 'true'
|
|
42
43
|
end
|