-
Notifications
You must be signed in to change notification settings - Fork 25
/
template.rb
188 lines (148 loc) · 5.39 KB
/
template.rb
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
# frozen_string_literal: true
require 'shellwords'
# Variables
APP_NAME = app_name
CONTAINERIZED_APP_NAME = app_name.tr('_', '-').downcase
# Transform the app name from slug to human-readable name e.g. nimble-web -> Nimble
APP_NAME_HUMANIZED = app_name.split(/[-_]/).map(&:capitalize).join(' ').gsub(/ Web$/, '')
DOCKER_REGISTRY_HOST = 'docker.io'
DOCKER_IMAGE = "nimblehq/#{CONTAINERIZED_APP_NAME}".freeze
RUBY_VERSION = '3.3.1'
POSTGRES_VERSION = '16.3'
REDIS_VERSION = '7.0.9'
# Variants
API_VARIANT = options[:api] || ENV['API'] == 'true'
WEB_VARIANT = !API_VARIANT
# Addons
DEFAULT_ADDONS = {
docker: 'Docker',
heroku: 'Heroku'
}.freeze
if WEB_VARIANT
NODE_VERSION = '22.1.0'
NODE_SOURCE_VERSION = '22' # Used in Dockerfile https://github.com/nodesource/distributions
end
def apply_template!(template_root)
use_source_path template_root
delete_test_folder
template 'Gemfile.tt', force: true
copy_file '.flayignore'
copy_file 'Dangerfile'
copy_file '.rubocop.yml'
copy_file '.reek.yml'
template '.ruby-gemset.tt'
template '.ruby-version.tt', force: true
template '.tool-versions.tt'
copy_file '.editorconfig'
copy_file 'Procfile'
copy_file 'Procfile.dev'
template 'Makefile.tt'
template 'README.md.tt', force: true
apply 'bin/template.rb'
apply 'config/template.rb'
apply '.gitignore.rb'
copy_file '.gitattributes', force: true
after_bundle do
use_source_path template_root
# Stop the spring before using the generators as it might hang for a long time
# Issue: https://github.com/rails/spring/issues/486
run 'spring stop'
apply 'spec/template.rb'
end
# Add-ons - [Default]
DEFAULT_ADDONS.each_key do |addon|
apply ".template/addons/#{addon}/template.rb"
end
post_default_addons_install
ask_for_optional_addons
apply_optional_addons
# Variants
apply '.template/variants/api/template.rb' if API_VARIANT
apply '.template/variants/web/template.rb' if WEB_VARIANT
# Custom Rubocop cops
apply '.template/addons/custom_cops/template.rb'
apply '.template/addons/crud/template.rb' if @install_crud
# A list necessary jobs that run before complete, ex: Fixing rubocop on Ruby files that generated by Rails
apply '.template/hooks/before_complete/fix_rubocop.rb'
apply '.template/hooks/before_complete/report.rb'
end
def ask_for_optional_addons
ask_for_all_variant_addons
ask_for_web_variant_addons if WEB_VARIANT
end
def ask_for_all_variant_addons
@install_github_action = yes?(install_addon_prompt('Github Action and Wiki'))
@install_openapi = API_VARIANT || yes?(install_addon_prompt('OpenAPI'))
@install_mock_server = @install_openapi && yes?(install_addon_prompt('Mock Server'))
@install_nginx = yes?(install_addon_prompt('Nginx'))
@install_phrase = yes?(install_addon_prompt('Phrase'))
@install_crud = WEB_VARIANT && yes?(install_addon_prompt('Crud (includes Devise, Bootstrap and Slim)'))
@install_devise = @install_crud || yes?(install_addon_prompt('Devise'))
end
def ask_for_web_variant_addons
@install_bootstrap = @install_crud || yes?(install_addon_prompt('Bootstrap'))
@install_slim = @install_crud || yes?(install_addon_prompt('Slim Template Engine'))
@install_hotwire = yes?(install_addon_prompt('Hotwire'))
@install_svgeez = yes?(install_addon_prompt('Svgeez'))
end
def apply_optional_addons
apply '.template/addons/github/template.rb' if @install_github_action
apply '.template/addons/openapi/template.rb' if @install_openapi
apply '.template/addons/nginx/template.rb' if @install_nginx
apply '.template/addons/phrase/template.rb' if @install_phrase
apply '.template/addons/devise/template.rb' if @install_devise
end
# Set Thor::Actions source path for looking up the files
def source_paths
@source_paths
end
# Prepend the required paths to the source paths to make the template files in those paths available
def use_source_path(source_path)
@source_paths.unshift(source_path)
end
def remote_repository
require 'tmpdir'
tempdir = Dir.mktmpdir('rails-templates')
at_exit { FileUtils.remove_entry(tempdir) }
git clone: [
'--quiet',
'https://github.com/nimblehq/rails-templates.git',
tempdir
].map(&:shellescape).join(' ')
if (branch = __FILE__[%r{rails-templates/(.+)/template.rb}, 1])
Dir.chdir(tempdir) { git checkout: branch }
end
tempdir
end
def delete_test_folder
FileUtils.rm_rf('test')
end
def install_addon_prompt(addon)
"Would you like to add the #{addon} addon? [yN]"
end
def post_default_addons_install
puts <<~INFO
These default addons were installed:
#{DEFAULT_ADDONS.values.map { |addon| "* #{addon}" }.join("\n")}
INFO
end
def get_content_between(content, string_start, string_end)
content[/#{Regexp.escape(string_start)}(.*)#{Regexp.escape(string_end)}/m, 1].strip
end
# Init the source path
@source_paths ||= []
# Setup the template root path
# If the template file is the url, clone the repo to the tmp directory
template_root = __FILE__.match?(%r{\Ahttps?://}) ? remote_repository : __dir__
use_source_path template_root
# Init the template helpers
require "#{template_root}/.template/lib/template"
@template_instructions = Template::Messages.new
@template_errors = Template::Errors.new
if ENV['ADDON']
addon_template_path = ".template/addons/#{ENV['ADDON']}/template.rb"
abort 'This addon is not supported' unless File.exist?(File.expand_path(addon_template_path, template_root))
apply addon_template_path
else
apply_template!(template_root)
end