modulorails 1.5.2.pre.2 → 1.7.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/.claude/skills/release-modulorails/SKILL.md +150 -0
- data/.rubocop.yml +2 -1
- data/CHANGELOG.md +55 -8
- data/Gemfile.lock +75 -26
- data/README.md +69 -9
- data/lib/generators/modulorails/claude_code/claude_code_generator.rb +64 -0
- data/lib/generators/modulorails/claude_code/templates/.gitlab-ci.yml.tt +120 -0
- data/lib/generators/modulorails/claude_code/templates/.modulorails-gitlab-ci +6 -0
- data/lib/generators/modulorails/claude_code/templates/bin/init-firewall.sh.tt +118 -0
- data/lib/generators/modulorails/docker/compose/compose_generator.rb +7 -6
- data/lib/generators/modulorails/docker/config/config_generator.rb +11 -5
- data/lib/generators/modulorails/docker/config/templates/config/database.yml.tt +7 -2
- data/lib/generators/modulorails/docker/devcontainer/devcontainer_generator.rb +52 -0
- data/lib/generators/modulorails/docker/devcontainer/templates/devcontainer/Dockerfile.tt +53 -0
- data/lib/generators/modulorails/docker/devcontainer/templates/devcontainer/compose.yml.tt +97 -0
- data/lib/generators/modulorails/docker/devcontainer/templates/devcontainer/devcontainer.json.tt +80 -0
- data/lib/generators/modulorails/docker/docker_generator.rb +7 -0
- data/lib/generators/modulorails/docker/dockerfile/dockerfile_generator.rb +15 -11
- data/lib/generators/modulorails/docker/dockerfile/templates/dockerfiles/{rails/Dockerfile.prod.tt → Dockerfile.prod.tt} +31 -12
- data/lib/generators/modulorails/docker/dockerfile/templates/dockerfiles/dockerignore.tt +120 -0
- data/lib/generators/modulorails/docker/entrypoint/entrypoint_generator.rb +11 -5
- data/lib/generators/modulorails/docker/entrypoint/templates/entrypoints/docker-entrypoint.sh.tt +5 -0
- data/lib/generators/modulorails/githooks/githooks_generator.rb +5 -3
- data/lib/generators/modulorails/githooks/templates/dc.sh +30 -0
- data/lib/generators/modulorails/githooks/templates/dcr.sh +47 -0
- data/lib/generators/modulorails/githooks/templates/post-rewrite.sh +1 -1
- data/lib/generators/modulorails/githooks/templates/pre-merge-commit.sh +1 -1
- data/lib/generators/modulorails/githooks/templates/refresh_generations.sh +17 -9
- data/lib/generators/modulorails/gitlabci/gitlabci_generator.rb +7 -1
- data/lib/generators/modulorails/gitlabci/templates/.gitlab-ci.yml.tt +15 -13
- data/lib/generators/modulorails/gitlabci/templates/bin/test.sh.tt +36 -0
- data/lib/generators/modulorails/gitlabci/templates/config/deploy/production.yaml.tt +4 -4
- data/lib/generators/modulorails/gitlabci/templates/config/deploy/review.yaml.tt +4 -4
- data/lib/generators/modulorails/gitlabci/templates/config/deploy/staging.yaml.tt +7 -7
- data/lib/generators/modulorails/moduloproject/moduloproject_generator.rb +8 -3
- data/lib/generators/modulorails/moduloproject/templates/config/environments/production.rb.tt +21 -51
- data/lib/generators/modulorails/rubocop/rubocop_generator.rb +8 -3
- data/lib/generators/modulorails/rubocop/templates/rubocop.yml.tt +7 -1
- data/lib/generators/modulorails/self_update/self_update_generator.rb +4 -0
- data/lib/generators/modulorails/sidekiq/sidekiq_generator.rb +95 -38
- data/lib/generators/modulorails/sidekiq/templates/config/initializers/sidekiq.rb.tt +4 -4
- data/lib/modulorails/configuration.rb +17 -7
- data/lib/modulorails/data.rb +41 -12
- data/lib/modulorails/generators/base.rb +1 -1
- data/lib/modulorails/railtie.rb +4 -1
- data/lib/modulorails/version.rb +1 -1
- data/lib/modulorails.rb +15 -5
- metadata +17 -10
- data/lib/generators/modulorails/docker/compose/templates/docker-compose.yml.tt +0 -81
- data/lib/generators/modulorails/docker/dockerfile/templates/dockerfiles/modulotech/Dockerfile.prod.tt +0 -66
- data/lib/generators/modulorails/docker/dockerfile/templates/dockerfiles/modulotech/Dockerfile.tt +0 -30
- data/lib/generators/modulorails/docker/entrypoint/templates/entrypoints/webpack-entrypoint.sh.tt +0 -7
- data/lib/generators/modulorails/githooks/templates/dockeruby.rb +0 -124
- data/lib/generators/modulorails/sidekiq/templates/entrypoints/sidekiq-entrypoint.sh.tt +0 -7
|
@@ -1,18 +1,23 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
|
-
require '
|
|
3
|
+
require 'modulorails/generators/base'
|
|
4
4
|
|
|
5
|
-
class Modulorails::RubocopGenerator <
|
|
5
|
+
class Modulorails::RubocopGenerator < Modulorails::Generators::Base
|
|
6
|
+
|
|
7
|
+
VERSION = 1
|
|
6
8
|
|
|
7
9
|
source_root File.expand_path('templates', __dir__)
|
|
8
10
|
desc 'This generator creates a configuration for Rubocop'
|
|
9
11
|
|
|
10
|
-
|
|
12
|
+
protected
|
|
13
|
+
|
|
14
|
+
def create_config
|
|
11
15
|
rubocop_config_path = Rails.root.join('.rubocop.yml')
|
|
12
16
|
gitlab_config_path = Rails.root.join('.gitlab-ci.yml')
|
|
13
17
|
|
|
14
18
|
template 'rubocop.yml', rubocop_config_path, force: true
|
|
15
19
|
|
|
20
|
+
return unless File.exist?(gitlab_config_path)
|
|
16
21
|
return if File.read(gitlab_config_path).match?(/\s+extends:\s+.lint\s*$/)
|
|
17
22
|
|
|
18
23
|
append_file gitlab_config_path do
|
|
@@ -10,7 +10,8 @@
|
|
|
10
10
|
# See https://docs.rubocop.org/rubocop/configuration
|
|
11
11
|
|
|
12
12
|
# Enabling Rails-specific cops.
|
|
13
|
-
|
|
13
|
+
plugins:
|
|
14
|
+
- rubocop-rails
|
|
14
15
|
|
|
15
16
|
inherit_mode:
|
|
16
17
|
merge:
|
|
@@ -102,6 +103,7 @@ Metrics/CyclomaticComplexity:
|
|
|
102
103
|
# Commonly used screens these days easily fit more than 80 characters.
|
|
103
104
|
Layout/LineLength:
|
|
104
105
|
Max: 120
|
|
106
|
+
AllowedPatterns: ['\A\s*#']
|
|
105
107
|
|
|
106
108
|
# Too short methods lead to extraction of single-use methods, which can make
|
|
107
109
|
# the code easier to read (by naming things), but can also clutter the class
|
|
@@ -235,6 +237,10 @@ Metrics/BlockLength:
|
|
|
235
237
|
Exclude:
|
|
236
238
|
- 'app/admin/**/*'
|
|
237
239
|
- 'lib/tasks/**/*'
|
|
240
|
+
# Allow big blocks for Concerns
|
|
241
|
+
AllowedMethods:
|
|
242
|
+
- class_methods
|
|
243
|
+
- included
|
|
238
244
|
|
|
239
245
|
# Checks if empty lines around the bodies of classes match the configuration.
|
|
240
246
|
Layout/EmptyLinesAroundClassBody:
|
|
@@ -12,6 +12,10 @@ class Modulorails::SelfUpdateGenerator < Rails::Generators::Base
|
|
|
12
12
|
LATEST_VERSION_URL = 'https://rubygems.org/api/v1/versions/modulorails.json'
|
|
13
13
|
|
|
14
14
|
def create_config_file
|
|
15
|
+
Modulorails.deprecator.warn(<<~MESSAGE)
|
|
16
|
+
Modulorails::SelfUpdateGenerator is deprecated and will be removed in version 2.0.
|
|
17
|
+
MESSAGE
|
|
18
|
+
|
|
15
19
|
# Get the last published version
|
|
16
20
|
versions = HTTParty.get(LATEST_VERSION_URL).parsed_response
|
|
17
21
|
last_published_version = versions&.reject { |version| Gem::Version.new(version['number']).prerelease? }&.first
|
|
@@ -8,12 +8,15 @@ class Modulorails::SidekiqGenerator < Rails::Generators::Base
|
|
|
8
8
|
|
|
9
9
|
desc 'This generator adds Sidekiq to the project'
|
|
10
10
|
|
|
11
|
+
def deprecation_warning
|
|
12
|
+
Modulorails.deprecator.warn(<<~MESSAGE)
|
|
13
|
+
Modulorails::SidekiqGenerator is deprecated and will be removed in version 2.0.
|
|
14
|
+
Use Moduloproject 3.0 (available later) to initialize new projects with Sidekiq configuration.
|
|
15
|
+
MESSAGE
|
|
16
|
+
end
|
|
17
|
+
|
|
11
18
|
def add_to_docker_compose
|
|
12
|
-
|
|
13
|
-
add_to_docker_compose_yml_file(Rails.root.join('compose.yml'))
|
|
14
|
-
elsif Rails.root.join('docker-compose.yml').exist?
|
|
15
|
-
add_to_docker_compose_yml_file(Rails.root.join('docker-compose.yml'))
|
|
16
|
-
end
|
|
19
|
+
add_to_docker_compose_yml_file(Rails.root.join('.devcontainer/compose.yml'))
|
|
17
20
|
end
|
|
18
21
|
|
|
19
22
|
def add_to_deploy_files
|
|
@@ -26,12 +29,15 @@ class Modulorails::SidekiqGenerator < Rails::Generators::Base
|
|
|
26
29
|
gemfile_path = Rails.root.join('Gemfile')
|
|
27
30
|
|
|
28
31
|
# Add gem redis unless already present
|
|
29
|
-
append_to_file(gemfile_path, "
|
|
32
|
+
append_to_file(gemfile_path, "\ngem 'redis'\n") unless File.read(gemfile_path).match?(/^\s*gem ['"]redis['"]/)
|
|
30
33
|
|
|
31
34
|
# Add gem sidekiq unless already present
|
|
32
|
-
|
|
35
|
+
append_to_file(gemfile_path, "\ngem 'sidekiq'\n") unless File.read(gemfile_path).match?(/^\s*gem ['"]sidekiq['"]/)
|
|
36
|
+
|
|
37
|
+
# Add gem sidekiq-datadog-error-tracking unless already present
|
|
38
|
+
return if File.read(gemfile_path).match?(/^\s*gem ['"]sidekiq-datadog-error-tracking['"]/)
|
|
33
39
|
|
|
34
|
-
append_to_file(gemfile_path, "
|
|
40
|
+
append_to_file(gemfile_path, "\ngem 'sidekiq-datadog-error-tracking'\n")
|
|
35
41
|
end
|
|
36
42
|
|
|
37
43
|
def add_to_config
|
|
@@ -46,20 +52,19 @@ class Modulorails::SidekiqGenerator < Rails::Generators::Base
|
|
|
46
52
|
|
|
47
53
|
def add_routes
|
|
48
54
|
routes_path = Rails.root.join('config/routes.rb')
|
|
49
|
-
|
|
50
55
|
return if File.read(routes_path).match?(%r{require ['"]sidekiq/web["']})
|
|
51
56
|
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
RUBY
|
|
57
|
+
authentication_type = Modulorails.data.authentication_type
|
|
58
|
+
if respond_to?("add_#{authentication_type}_authenticated_route")
|
|
59
|
+
send("add_#{authentication_type}_authenticated_route", routes_path)
|
|
60
|
+
else
|
|
61
|
+
add_unauthenticated_route(routes_path)
|
|
58
62
|
end
|
|
59
63
|
end
|
|
60
64
|
|
|
61
65
|
def add_health_check
|
|
62
66
|
file_path = Rails.root.join('config/initializers/health_check.rb')
|
|
67
|
+
return unless File.exist?(file_path)
|
|
63
68
|
|
|
64
69
|
return if File.read(file_path).match?(/add_custom_check\s*\(?\s*['"]sidekiq-queues['"]\s*\)?/)
|
|
65
70
|
|
|
@@ -73,10 +78,10 @@ class Modulorails::SidekiqGenerator < Rails::Generators::Base
|
|
|
73
78
|
# No queues, means no jobs, ok!
|
|
74
79
|
next '' if queues.empty?
|
|
75
80
|
|
|
76
|
-
|
|
81
|
+
global_latency = queues.each.map { |queue| queue.latency }.sum
|
|
77
82
|
|
|
78
|
-
#
|
|
79
|
-
|
|
83
|
+
# Global latency is less than 5 minutes, ok!
|
|
84
|
+
global_latency < 5.minutes ? '' : "Global latency (\#{global_latency}) is too high."
|
|
80
85
|
end
|
|
81
86
|
|
|
82
87
|
# Add one or more custom checks that return a blank string if ok, or an error message if there is an error
|
|
@@ -90,9 +95,9 @@ class Modulorails::SidekiqGenerator < Rails::Generators::Base
|
|
|
90
95
|
end
|
|
91
96
|
end
|
|
92
97
|
|
|
93
|
-
def
|
|
94
|
-
|
|
95
|
-
|
|
98
|
+
def remove_entrypoint
|
|
99
|
+
remove_file 'entrypoints/sidekiq-entrypoint.sh'
|
|
100
|
+
remove_file 'bin/sidekiq-entrypoint'
|
|
96
101
|
end
|
|
97
102
|
|
|
98
103
|
private
|
|
@@ -100,31 +105,43 @@ class Modulorails::SidekiqGenerator < Rails::Generators::Base
|
|
|
100
105
|
def add_to_docker_compose_yml_file(file_path)
|
|
101
106
|
@image_name ||= Modulorails.data.name.parameterize
|
|
102
107
|
|
|
103
|
-
|
|
104
|
-
|
|
108
|
+
unless File.exist?(file_path)
|
|
109
|
+
puts("Compose file not found at #{file_path}. Ignoring.")
|
|
110
|
+
return
|
|
111
|
+
end
|
|
105
112
|
|
|
106
|
-
|
|
113
|
+
# Update existing Sidekiq service
|
|
114
|
+
if File.read(file_path).match?(/^ {2}sidekiq:$/)
|
|
115
|
+
pattern = /^(\s*)entrypoint:(\s*).\/(bin\/sidekiq-entrypoint|entrypoints\/sidekiq-entrypoint\.sh)/
|
|
116
|
+
gsub_file file_path, pattern, '\1command:\2./bin/bundle exec sidekiq'
|
|
117
|
+
return
|
|
118
|
+
end
|
|
107
119
|
|
|
120
|
+
add_sidekiq_service(file_path)
|
|
121
|
+
end
|
|
122
|
+
|
|
123
|
+
def add_sidekiq_service(file_path)
|
|
108
124
|
insert_into_file file_path, after: /^services:/ do
|
|
125
|
+
# Using `<<-` Heredoc syntax to preserve YAML indentation
|
|
109
126
|
<<-YAML
|
|
110
127
|
|
|
111
128
|
sidekiq:
|
|
112
129
|
image: modulotechgroup/#{@image_name}:dev
|
|
113
130
|
build:
|
|
114
|
-
context:
|
|
115
|
-
dockerfile: Dockerfile
|
|
131
|
+
context: ..
|
|
132
|
+
dockerfile: .devcontainer/Dockerfile
|
|
116
133
|
depends_on:
|
|
117
134
|
- database
|
|
118
135
|
- redis
|
|
119
136
|
volumes:
|
|
120
|
-
-
|
|
137
|
+
- ..:/rails
|
|
121
138
|
environment:
|
|
122
139
|
RAILS_ENV: development
|
|
123
140
|
URL: http://app:3000
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
141
|
+
env_file:
|
|
142
|
+
- path: .env
|
|
143
|
+
required: false
|
|
144
|
+
command: ./bin/bundle exec sidekiq
|
|
128
145
|
stdin_open: true
|
|
129
146
|
tty: true
|
|
130
147
|
YAML
|
|
@@ -146,8 +163,9 @@ class Modulorails::SidekiqGenerator < Rails::Generators::Base
|
|
|
146
163
|
end
|
|
147
164
|
|
|
148
165
|
def add_to_deploy_file(file_path)
|
|
149
|
-
# Do nothing if file does not
|
|
150
|
-
return
|
|
166
|
+
# Do nothing if file does not exist or Sidekiq is already enabled
|
|
167
|
+
return unless File.exist?(file_path)
|
|
168
|
+
return if File.read(file_path).match?(/^sidekiq:\n {2}enabled: true$/m)
|
|
151
169
|
|
|
152
170
|
# Add sidekiq to deploy file
|
|
153
171
|
insert_into_file file_path do
|
|
@@ -158,17 +176,56 @@ class Modulorails::SidekiqGenerator < Rails::Generators::Base
|
|
|
158
176
|
resources:
|
|
159
177
|
requests:
|
|
160
178
|
cpu: 100m
|
|
161
|
-
memory:
|
|
179
|
+
memory: 1024Mi
|
|
162
180
|
limits:
|
|
163
|
-
|
|
164
|
-
memory: 512Mi
|
|
181
|
+
memory: 1024Mi
|
|
165
182
|
autoscaling:
|
|
166
183
|
enabled: true
|
|
167
|
-
minReplicas: 1
|
|
168
|
-
maxReplicas: 10
|
|
184
|
+
minReplicas: #{file_path.to_s.match?('production.y') ? 2 : 1}
|
|
185
|
+
maxReplicas: #{file_path.to_s.match?('production.y') ? 10 : 2}
|
|
169
186
|
targetCPUUtilizationPercentage: 80
|
|
187
|
+
command: ["./bin/bundle", "exec", "sidekiq"]
|
|
170
188
|
YAML
|
|
171
189
|
end
|
|
172
190
|
end
|
|
173
191
|
|
|
192
|
+
RAILS_AUTHENTICATION_TEMPLATE = <<~RUBY.freeze
|
|
193
|
+
require 'sidekiq/web'
|
|
194
|
+
constraints lambda { |request| Session.find_by(id: request.cookie_jar.signed[:session_id])&.user&.role == 'admin' } do
|
|
195
|
+
mount Sidekiq::Web => '/admin/sidekiq'
|
|
196
|
+
end
|
|
197
|
+
|
|
198
|
+
|
|
199
|
+
RUBY
|
|
200
|
+
|
|
201
|
+
def add_devise_authenticated_route(routes_path)
|
|
202
|
+
template = <<~RUBY
|
|
203
|
+
require 'sidekiq/web'
|
|
204
|
+
authenticate :user, lambda { |u| u.respond_to?('role') && u.role == 'admin' } do
|
|
205
|
+
mount Sidekiq::Web => '/admin/sidekiq'
|
|
206
|
+
end
|
|
207
|
+
|
|
208
|
+
RUBY
|
|
209
|
+
puts("Injecting #{template} into #{routes_path}: update the authentication block.")
|
|
210
|
+
inject_into_file routes_path, template, after: "Rails.application.routes.draw do\n"
|
|
211
|
+
end
|
|
212
|
+
|
|
213
|
+
def add_rails_authenticated_route(routes_path)
|
|
214
|
+
template = RAILS_AUTHENTICATION_TEMPLATE
|
|
215
|
+
puts("Injecting #{template} into #{routes_path}: update the authentication block.")
|
|
216
|
+
inject_into_file routes_path, template, after: "Rails.application.routes.draw do\n"
|
|
217
|
+
end
|
|
218
|
+
|
|
219
|
+
def add_unauthenticated_route(routes_path)
|
|
220
|
+
template = <<~RUBY
|
|
221
|
+
require 'sidekiq/web'
|
|
222
|
+
mount Sidekiq::Web => '/admin/sidekiq'
|
|
223
|
+
|
|
224
|
+
RUBY
|
|
225
|
+
puts("Injecting #{template} into #{routes_path}: you should add authentication to the route.")
|
|
226
|
+
puts("If you do not have authentication, execute `rails generate authentication` and replace \
|
|
227
|
+
the route by #{RAILS_AUTHENTICATION_TEMPLATE}.")
|
|
228
|
+
inject_into_file routes_path, template, after: "Rails.application.routes.draw do\n"
|
|
229
|
+
end
|
|
230
|
+
|
|
174
231
|
end
|
|
@@ -1,9 +1,9 @@
|
|
|
1
|
-
redis_url = Rails.application.config_for('cable')['url']
|
|
2
|
-
|
|
3
1
|
Sidekiq.configure_server do |config|
|
|
4
|
-
config.redis = { url:
|
|
2
|
+
config.redis = { url: REDIS_URL }
|
|
3
|
+
config.logger.formatter = Sidekiq::Logger::Formatters::Datadog.new
|
|
4
|
+
config.error_handlers << Sidekiq::Datadog::Error::Tracking
|
|
5
5
|
end
|
|
6
6
|
|
|
7
7
|
Sidekiq.configure_client do |config|
|
|
8
|
-
config.redis = { url:
|
|
8
|
+
config.redis = { url: REDIS_URL }
|
|
9
9
|
end
|
|
@@ -16,14 +16,8 @@ module Modulorails
|
|
|
16
16
|
# config.project_manager 'pm@modulotech.fr'
|
|
17
17
|
# config.endpoint "intranet's endpoint"
|
|
18
18
|
# config.api_key "intranet's api key"
|
|
19
|
-
# config.production_url "production.app.com"
|
|
20
|
-
# config.staging_url "staging.app.com"
|
|
21
|
-
# config.review_base_url "review.app.com"
|
|
22
19
|
# end
|
|
23
|
-
%i[
|
|
24
|
-
name main_developer project_manager endpoint api_key no_auto_update production_url staging_url
|
|
25
|
-
review_base_url
|
|
26
|
-
].each do |field|
|
|
20
|
+
%i[name main_developer project_manager endpoint api_key].each do |field|
|
|
27
21
|
define_method(field) do |value=nil|
|
|
28
22
|
# No value means we want to get the field
|
|
29
23
|
return send("_#{field}") unless value
|
|
@@ -33,6 +27,22 @@ module Modulorails
|
|
|
33
27
|
end
|
|
34
28
|
end
|
|
35
29
|
|
|
30
|
+
# Deprecated configuration options - will be removed in 2.0
|
|
31
|
+
%i[no_auto_update production_url staging_url review_base_url].each do |field|
|
|
32
|
+
define_method(field) do |value=nil|
|
|
33
|
+
# No value means we want to get the field
|
|
34
|
+
return send("_#{field}") unless value
|
|
35
|
+
|
|
36
|
+
# Warn only when setting the value (i.e., in the initializer)
|
|
37
|
+
Modulorails.deprecator.warn(
|
|
38
|
+
"Modulorails configuration `#{field}` is deprecated and will be removed in version 2.0."
|
|
39
|
+
)
|
|
40
|
+
|
|
41
|
+
# Else we want to set the field
|
|
42
|
+
send("_#{field}=", value)
|
|
43
|
+
end
|
|
44
|
+
end
|
|
45
|
+
|
|
36
46
|
end
|
|
37
47
|
|
|
38
48
|
end
|
data/lib/modulorails/data.rb
CHANGED
|
@@ -13,7 +13,7 @@ module Modulorails
|
|
|
13
13
|
ATTRIBUTE_KEYS = %i[
|
|
14
14
|
name main_developer project_manager repository type rails_name ruby_version rails_version
|
|
15
15
|
bundler_version modulorails_version adapter db_version adapter_version webpacker_version
|
|
16
|
-
importmap_version
|
|
16
|
+
importmap_version js_engine
|
|
17
17
|
production_url staging_url review_base_url
|
|
18
18
|
environment_name
|
|
19
19
|
].freeze
|
|
@@ -48,6 +48,10 @@ module Modulorails
|
|
|
48
48
|
}
|
|
49
49
|
end
|
|
50
50
|
|
|
51
|
+
def authentication_type
|
|
52
|
+
@authentication_type ||= authentication_data
|
|
53
|
+
end
|
|
54
|
+
|
|
51
55
|
private
|
|
52
56
|
|
|
53
57
|
def initialize_from_constants
|
|
@@ -104,20 +108,16 @@ module Modulorails
|
|
|
104
108
|
|
|
105
109
|
def initialize_from_database
|
|
106
110
|
# Get the database connection to identify the database used by the application
|
|
107
|
-
|
|
108
|
-
db_connection = begin
|
|
109
|
-
ActiveRecord::Base.connection
|
|
110
|
-
rescue ActiveRecord::NoDatabaseError, ActiveRecord::ConnectionNotEstablished => e
|
|
111
|
-
warn("[Modulorails] Error: #{e.message}")
|
|
112
|
-
nil
|
|
113
|
-
end
|
|
111
|
+
db_connection = ActiveRecord::Base.connection || return
|
|
114
112
|
|
|
115
113
|
# The name of the ActiveRecord adapter; it gives the name of the database system too
|
|
116
|
-
@adapter = db_connection
|
|
114
|
+
@adapter = db_connection.adapter_name.downcase
|
|
117
115
|
|
|
118
116
|
# The version of the database engine; this request works only on MySQL and PostgreSQL
|
|
119
117
|
# It should not be a problem since those are the sole database engines used at Modulotech
|
|
120
|
-
@db_version = db_connection
|
|
118
|
+
@db_version = db_connection.select_value('SELECT version()')
|
|
119
|
+
rescue ActiveRecord::NoDatabaseError, ActiveRecord::ConnectionNotEstablished => e
|
|
120
|
+
warn("[Modulorails] Error: #{e.message}")
|
|
121
121
|
end
|
|
122
122
|
|
|
123
123
|
def initialize_from_gem_specs
|
|
@@ -134,14 +134,28 @@ module Modulorails
|
|
|
134
134
|
# The version of the ActiveRecord adapter
|
|
135
135
|
@adapter_version = gem_version(loaded_specs[@adapter])
|
|
136
136
|
|
|
137
|
+
initialize_from_js_specs(loaded_specs)
|
|
138
|
+
end
|
|
139
|
+
|
|
140
|
+
def initialize_from_js_specs(loaded_specs)
|
|
137
141
|
# The version of the webpacker gem - might be nil
|
|
138
142
|
@webpacker_version = gem_version(loaded_specs['webpacker'])
|
|
139
143
|
|
|
140
144
|
# The version of the importmap-rails gem - might be nil
|
|
141
145
|
@importmap_version = gem_version(loaded_specs['importmap-rails'])
|
|
142
146
|
|
|
143
|
-
|
|
144
|
-
|
|
147
|
+
@js_engine =
|
|
148
|
+
if @webpacker_version
|
|
149
|
+
:webpacker
|
|
150
|
+
elsif @importmap_version
|
|
151
|
+
:importmap
|
|
152
|
+
else
|
|
153
|
+
find_js_engine
|
|
154
|
+
end
|
|
155
|
+
end
|
|
156
|
+
|
|
157
|
+
def find_js_engine
|
|
158
|
+
File.exist?(Rails.root.join('bun.config.js')) ? :bun : :unknown
|
|
145
159
|
end
|
|
146
160
|
|
|
147
161
|
def gem_version(spec)
|
|
@@ -152,6 +166,8 @@ module Modulorails
|
|
|
152
166
|
# Theorically, origin is the main repository of the project and git is the sole VCS we use
|
|
153
167
|
# at Modulotech
|
|
154
168
|
@repository = Git.open(::Rails.root).config('remote.origin.url')
|
|
169
|
+
rescue ArgumentError, Git::GitExecuteError => e
|
|
170
|
+
warn("[Modulorails] Error: #{e.message}")
|
|
155
171
|
end
|
|
156
172
|
|
|
157
173
|
def to_project_data_params
|
|
@@ -182,6 +198,19 @@ module Modulorails
|
|
|
182
198
|
}
|
|
183
199
|
end
|
|
184
200
|
|
|
201
|
+
def authentication_data
|
|
202
|
+
loaded_specs = Gem.loaded_specs
|
|
203
|
+
|
|
204
|
+
# The version of the devise gem - might be nil
|
|
205
|
+
devise_version = gem_version(loaded_specs['devise'])
|
|
206
|
+
|
|
207
|
+
if devise_version
|
|
208
|
+
:devise
|
|
209
|
+
elsif File.exist?(Rails.root.join('app/controllers/concerns/authentication.rb'))
|
|
210
|
+
:rails
|
|
211
|
+
end
|
|
212
|
+
end
|
|
213
|
+
|
|
185
214
|
end
|
|
186
215
|
|
|
187
216
|
end
|
data/lib/modulorails/railtie.rb
CHANGED
|
@@ -32,7 +32,7 @@ module Modulorails
|
|
|
32
32
|
end
|
|
33
33
|
|
|
34
34
|
initializer "modulorails.deprecator" do |app|
|
|
35
|
-
app.deprecators[:modulorails] = Modulorails.deprecator
|
|
35
|
+
app.deprecators[:modulorails] = Modulorails.deprecator if app.respond_to?(:deprecators)
|
|
36
36
|
end
|
|
37
37
|
|
|
38
38
|
# Sending data after the initialization ensures we can access
|
|
@@ -62,6 +62,9 @@ module Modulorails
|
|
|
62
62
|
# Add/update Bundler-audit config
|
|
63
63
|
Modulorails.generate_bundleraudit_template
|
|
64
64
|
|
|
65
|
+
# Add/update Claude Code config
|
|
66
|
+
Modulorails.configure_claude_code
|
|
67
|
+
|
|
65
68
|
# Gem's self-update if a new version was released
|
|
66
69
|
Modulorails.self_update
|
|
67
70
|
end
|
data/lib/modulorails/version.rb
CHANGED
data/lib/modulorails.rb
CHANGED
|
@@ -9,6 +9,7 @@ require 'generators/modulorails/self_update/self_update_generator'
|
|
|
9
9
|
require 'generators/modulorails/rubocop/rubocop_generator'
|
|
10
10
|
require 'generators/modulorails/bundleraudit/bundleraudit_generator'
|
|
11
11
|
require 'generators/modulorails/githooks/githooks_generator'
|
|
12
|
+
require 'generators/modulorails/claude_code/claude_code_generator'
|
|
12
13
|
require 'httparty'
|
|
13
14
|
require 'modulorails/error_data'
|
|
14
15
|
require 'modulorails/success_data'
|
|
@@ -97,14 +98,14 @@ module Modulorails
|
|
|
97
98
|
# went wrong with an `errors` field. We do not want to raise since the gem's user is not
|
|
98
99
|
# (necessarily) responsible for the error but we still need to display it somewhere to warn
|
|
99
100
|
# the user something went wrong.
|
|
100
|
-
Rails.logger
|
|
101
|
+
Rails.logger&.debug { "[Modulorails] Error: #{response['errors'].join(', ')}" } if response.code == 400
|
|
101
102
|
|
|
102
103
|
# Return the response to allow users to do some more
|
|
103
104
|
response
|
|
104
105
|
rescue StandardError => e
|
|
105
106
|
# Still need to notify the user
|
|
106
|
-
Rails.logger
|
|
107
|
-
Rails.logger
|
|
107
|
+
Rails.logger&.debug { "[Modulorails] Error: Could not post to #{configuration.endpoint}" }
|
|
108
|
+
Rails.logger&.debug e.message
|
|
108
109
|
nil
|
|
109
110
|
end
|
|
110
111
|
end
|
|
@@ -134,7 +135,7 @@ module Modulorails
|
|
|
134
135
|
|
|
135
136
|
Modulorails::SelfUpdateGenerator.new([], {}, {}).invoke_all
|
|
136
137
|
rescue StandardError => e
|
|
137
|
-
Rails.logger
|
|
138
|
+
Rails.logger&.debug { "[Modulorails] An error occured: #{e.class} - #{e.message}" }
|
|
138
139
|
end
|
|
139
140
|
|
|
140
141
|
# @author Matthieu 'ciappa_m' Ciappara
|
|
@@ -147,7 +148,8 @@ module Modulorails
|
|
|
147
148
|
|
|
148
149
|
# @author Matthieu 'ciappa_m' Ciappara
|
|
149
150
|
#
|
|
150
|
-
# Generate a rubocop configuration.
|
|
151
|
+
# Generate a rubocop configuration unless it was already done.
|
|
152
|
+
# The check is done using a 'keepfile'.
|
|
151
153
|
def generate_rubocop_template
|
|
152
154
|
Modulorails::RubocopGenerator.new([], {}, {}).invoke_all
|
|
153
155
|
end
|
|
@@ -166,6 +168,14 @@ module Modulorails
|
|
|
166
168
|
Modulorails::GithooksGenerator.new([], {}, {}).invoke_all
|
|
167
169
|
end
|
|
168
170
|
|
|
171
|
+
# @author Matthieu 'ciappa_m' Ciappara
|
|
172
|
+
#
|
|
173
|
+
# Configure devcontainer for Claude code unless it was already done.
|
|
174
|
+
# The check is done using a 'keepfile'.
|
|
175
|
+
def configure_claude_code
|
|
176
|
+
Modulorails::ClaudeCodeGenerator.new([], {}, {}).invoke_all
|
|
177
|
+
end
|
|
178
|
+
|
|
169
179
|
def deprecator
|
|
170
180
|
@deprecator ||= ActiveSupport::Deprecation.new('2.0', 'Modulorails')
|
|
171
181
|
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: 1.
|
|
4
|
+
version: 1.7.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:
|
|
11
|
+
date: 2026-04-28 00:00:00.000000000 Z
|
|
12
12
|
dependencies:
|
|
13
13
|
- !ruby/object:Gem::Dependency
|
|
14
14
|
name: bundler-audit
|
|
@@ -140,6 +140,7 @@ executables: []
|
|
|
140
140
|
extensions: []
|
|
141
141
|
extra_rdoc_files: []
|
|
142
142
|
files:
|
|
143
|
+
- ".claude/skills/release-modulorails/SKILL.md"
|
|
143
144
|
- ".dockerignore"
|
|
144
145
|
- ".gitignore"
|
|
145
146
|
- ".rspec"
|
|
@@ -171,29 +172,36 @@ files:
|
|
|
171
172
|
- gemfiles/rails_61.gemfile
|
|
172
173
|
- gemfiles/rails_70.gemfile
|
|
173
174
|
- lib/generators/modulorails/bundleraudit/bundleraudit_generator.rb
|
|
175
|
+
- lib/generators/modulorails/claude_code/claude_code_generator.rb
|
|
176
|
+
- lib/generators/modulorails/claude_code/templates/.gitlab-ci.yml.tt
|
|
177
|
+
- lib/generators/modulorails/claude_code/templates/.modulorails-gitlab-ci
|
|
178
|
+
- lib/generators/modulorails/claude_code/templates/bin/init-firewall.sh.tt
|
|
174
179
|
- lib/generators/modulorails/docker/compose/compose_generator.rb
|
|
175
|
-
- lib/generators/modulorails/docker/compose/templates/docker-compose.yml.tt
|
|
176
180
|
- lib/generators/modulorails/docker/config/config_generator.rb
|
|
177
181
|
- lib/generators/modulorails/docker/config/templates/config/cable.yml.tt
|
|
178
182
|
- lib/generators/modulorails/docker/config/templates/config/database.yml.tt
|
|
179
183
|
- lib/generators/modulorails/docker/config/templates/config/initializers/0_redis.rb
|
|
180
184
|
- lib/generators/modulorails/docker/config/templates/config/puma.rb
|
|
185
|
+
- lib/generators/modulorails/docker/devcontainer/devcontainer_generator.rb
|
|
186
|
+
- lib/generators/modulorails/docker/devcontainer/templates/devcontainer/Dockerfile.tt
|
|
187
|
+
- lib/generators/modulorails/docker/devcontainer/templates/devcontainer/compose.yml.tt
|
|
188
|
+
- lib/generators/modulorails/docker/devcontainer/templates/devcontainer/devcontainer.json.tt
|
|
181
189
|
- lib/generators/modulorails/docker/docker_generator.rb
|
|
182
190
|
- lib/generators/modulorails/docker/dockerfile/dockerfile_generator.rb
|
|
183
|
-
- lib/generators/modulorails/docker/dockerfile/templates/dockerfiles/
|
|
184
|
-
- lib/generators/modulorails/docker/dockerfile/templates/dockerfiles/
|
|
185
|
-
- lib/generators/modulorails/docker/dockerfile/templates/dockerfiles/rails/Dockerfile.prod.tt
|
|
191
|
+
- lib/generators/modulorails/docker/dockerfile/templates/dockerfiles/Dockerfile.prod.tt
|
|
192
|
+
- lib/generators/modulorails/docker/dockerfile/templates/dockerfiles/dockerignore.tt
|
|
186
193
|
- lib/generators/modulorails/docker/entrypoint/entrypoint_generator.rb
|
|
187
194
|
- lib/generators/modulorails/docker/entrypoint/templates/entrypoints/docker-entrypoint.sh.tt
|
|
188
|
-
- lib/generators/modulorails/docker/entrypoint/templates/entrypoints/webpack-entrypoint.sh.tt
|
|
189
195
|
- lib/generators/modulorails/githooks/githooks_generator.rb
|
|
190
|
-
- lib/generators/modulorails/githooks/templates/
|
|
196
|
+
- lib/generators/modulorails/githooks/templates/dc.sh
|
|
197
|
+
- lib/generators/modulorails/githooks/templates/dcr.sh
|
|
191
198
|
- lib/generators/modulorails/githooks/templates/post-rewrite.sh
|
|
192
199
|
- lib/generators/modulorails/githooks/templates/pre-merge-commit.sh
|
|
193
200
|
- lib/generators/modulorails/githooks/templates/refresh_generations.sh
|
|
194
201
|
- lib/generators/modulorails/gitlabci/gitlabci_generator.rb
|
|
195
202
|
- lib/generators/modulorails/gitlabci/templates/.gitlab-ci.yml.tt
|
|
196
203
|
- lib/generators/modulorails/gitlabci/templates/.modulorails-gitlab-ci
|
|
204
|
+
- lib/generators/modulorails/gitlabci/templates/bin/test.sh.tt
|
|
197
205
|
- lib/generators/modulorails/gitlabci/templates/config/deploy/production.yaml.tt
|
|
198
206
|
- lib/generators/modulorails/gitlabci/templates/config/deploy/review.yaml.tt
|
|
199
207
|
- lib/generators/modulorails/gitlabci/templates/config/deploy/staging.yaml.tt
|
|
@@ -210,7 +218,6 @@ files:
|
|
|
210
218
|
- lib/generators/modulorails/service/templates/service.rb.tt
|
|
211
219
|
- lib/generators/modulorails/sidekiq/sidekiq_generator.rb
|
|
212
220
|
- lib/generators/modulorails/sidekiq/templates/config/initializers/sidekiq.rb.tt
|
|
213
|
-
- lib/generators/modulorails/sidekiq/templates/entrypoints/sidekiq-entrypoint.sh.tt
|
|
214
221
|
- lib/modulorails.rb
|
|
215
222
|
- lib/modulorails/configuration.rb
|
|
216
223
|
- lib/modulorails/data.rb
|
|
@@ -251,7 +258,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
|
251
258
|
- !ruby/object:Gem::Version
|
|
252
259
|
version: '0'
|
|
253
260
|
requirements: []
|
|
254
|
-
rubygems_version: 3.
|
|
261
|
+
rubygems_version: 3.4.19
|
|
255
262
|
signing_key:
|
|
256
263
|
specification_version: 4
|
|
257
264
|
summary: Common base for Ruby on Rails projects at Modulotech
|