55require "open3"
66require "tmpdir"
77require "tty-prompt"
8+ require "rainbow"
89require "nextgen/ext/prompt/list"
910require "nextgen/ext/prompt/multilist"
1011
@@ -26,9 +27,9 @@ def run # rubocop:disable Metrics/MethodLength, Metrics/PerceivedComplexity
2627 say <<~BANNER
2728 Welcome to nextgen, the interactive Rails app generator!
2829
29- You are about to create a Rails app named "#{ app_name } " in the following directory:
30+ You are about to create a Rails app named "#{ cyan ( app_name ) } " in the following directory:
3031
31- #{ app_path }
32+ #{ cyan ( app_path ) }
3233
3334 You'll be asked ~10 questions about database, test framework, and other options.
3435 The standard Rails "omakase" experience will be selected by default.
@@ -83,9 +84,9 @@ def run # rubocop:disable Metrics/MethodLength, Metrics/PerceivedComplexity
8384 say <<~DONE . gsub ( /^/ , " " )
8485
8586
86- #{ set_color ( "Done!" , :green ) }
87+ #{ green ( "Done!" ) }
8788
88- A Rails #{ rails_version } app was generated in #{ set_color ( app_path , :cyan ) } .
89+ A Rails #{ rails_version } app was generated in #{ cyan ( app_path ) } .
8990 Run #{ set_color ( "bin/setup" , :yellow ) } in that directory to get started.
9091
9192
@@ -99,7 +100,7 @@ def run # rubocop:disable Metrics/MethodLength, Metrics/PerceivedComplexity
99100 def_delegators :shell , :say , :set_color
100101
101102 def continue_if ( question )
102- if prompt . yes? ( question )
103+ if prompt . yes? ( " #{ question } ↵" )
103104 say
104105 else
105106 say "Canceled" , :red
@@ -121,32 +122,29 @@ def rails_version
121122
122123 def ask_rails_version
123124 selected = prompt . select (
124- "What version of Rails will you use?" ,
125+ "What #{ underline ( " version" ) } of Rails will you use?" ,
125126 Rails . version => :current ,
126127 "edge (#{ Rails . edge_branch } branch)" => :edge
127128 )
128129 rails_opts . edge! if selected == :edge
129130 end
130131
131132 def ask_database
132- common_databases = {
133+ databases = {
133134 "SQLite3 (default)" => "sqlite3" ,
134135 "PostgreSQL (recommended)" => "postgresql" ,
135- "MySQL" => "mysql"
136- }
137- all_databases = common_databases . merge (
138- %w[ MySQL Trilogy Oracle SQLServer JDBCMySQL JDBCSQLite3 JDBCPostgreSQL JDBC ] . to_h do |name |
136+ **%w[ MySQL Trilogy Oracle SQLServer JDBCMySQL JDBCSQLite3 JDBCPostgreSQL JDBC ] . to_h do |name |
139137 [ name , name . downcase ]
140138 end ,
141139 "None (disable Active Record)" => nil
140+ }
141+ rails_opts . database = prompt_select (
142+ "Which #{ underline ( "database" ) } ?" , databases
142143 )
143- rails_opts . database =
144- prompt . select ( "Which database?" , common_databases . merge ( "More options..." => false ) ) ||
145- prompt . select ( "Which database?" , all_databases )
146144 end
147145
148146 def ask_full_stack_or_api
149- api = prompt . select (
147+ api = prompt_select (
150148 "What style of Rails app do you need?" ,
151149 "Standard, full-stack Rails (default)" => false ,
152150 "API only" => true
@@ -155,12 +153,13 @@ def ask_full_stack_or_api
155153 end
156154
157155 def ask_frontend_management
158- frontend = prompt . select (
159- "How will you manage frontend assets?" ,
156+ frontend = prompt_select (
157+ "How will you manage frontend #{ underline ( " assets" ) } ?" ,
160158 "Sprockets (default)" => "sprockets" ,
161159 "Propshaft" => "propshaft" ,
162160 "Vite" => :vite
163161 )
162+
164163 if frontend == :vite
165164 rails_opts . asset_pipeline = nil
166165 rails_opts . javascript = "vite"
@@ -170,8 +169,8 @@ def ask_frontend_management
170169 end
171170
172171 def ask_css
173- rails_opts . css = prompt . select (
174- "Which CSS framework will you use with the asset pipeline?" ,
172+ rails_opts . css = prompt_select (
173+ "Which #{ underline ( " CSS" ) } framework will you use with the asset pipeline?" ,
175174 "None (default)" => nil ,
176175 "Bootstrap" => "bootstrap" ,
177176 "Bulma" => "bulma" ,
@@ -182,8 +181,8 @@ def ask_css
182181 end
183182
184183 def ask_javascript
185- rails_opts . javascript = prompt . select (
186- "Which JavaScript bundler will you use with the asset pipeline?" ,
184+ rails_opts . javascript = prompt_select (
185+ "Which #{ underline ( " JavaScript" ) } bundler will you use with the asset pipeline?" ,
187186 "Importmap (default)" => "importmap" ,
188187 "Bun" => "bun" ,
189188 "ESBuild" => "esbuild" ,
@@ -214,7 +213,7 @@ def ask_rails_frameworks
214213 end
215214
216215 answers = prompt . multi_select (
217- "Which optional Rails frameworks do you need?" ,
216+ "Which optional Rails #{ underline ( " frameworks" ) } do you need?" ,
218217 frameworks ,
219218 default : frameworks . keys . reverse
220219 )
@@ -223,17 +222,17 @@ def ask_rails_frameworks
223222 end
224223
225224 def ask_test_framework
226- rails_opts . test_framework = prompt . select (
227- "Which test framework will you use?" ,
225+ rails_opts . test_framework = prompt_select (
226+ "Which #{ underline ( " test" ) } framework will you use?" ,
228227 "Minitest (default)" => "minitest" ,
229228 "RSpec" => "rspec" ,
230229 "None" => nil
231230 )
232231 end
233232
234233 def ask_system_testing
235- system_testing = prompt . select (
236- "Include system testing (capybara)?" ,
234+ system_testing = prompt_select (
235+ "Include #{ underline ( " system testing" ) } (capybara)?" ,
237236 "Yes (default)" => true ,
238237 "No" => false
239238 )
@@ -309,5 +308,10 @@ def prompt
309308 def shell
310309 @shell ||= Thor ::Base . shell . new
311310 end
311+
312+ def green ( string ) = set_color ( string , :green )
313+ def cyan ( string ) = set_color ( string , :cyan )
314+ def underline ( string ) = Rainbow ( string ) . underline
315+ def prompt_select ( question , choices ) = prompt . select ( question , choices , enum : "." , cycle : true )
312316 end
313317end
0 commit comments