brut 0.18.2 → 0.19.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.
@@ -1,12 +1,42 @@
1
1
  require "fileutils"
2
2
  require "erb"
3
3
  require "ostruct"
4
+ require "lipgloss"
4
5
 
5
6
  class Brut::CLI::Apps::New::App < Brut::CLI::Commands::BaseCommand
6
7
  def name = "new"
7
8
  def description = "Create a Brut App or modify an existing one with new segments"
8
9
  def args_description = "app_name"
9
10
 
11
+ LOGO_WIDE = %{
12
+ ################# #### ################# ################
13
+ ################## #### ################## #################
14
+ ##### ##### #### ##### ###### ##### #####
15
+ ##### ##### #### #### #### #### ########## ##### ##### ##### #####
16
+ ##### ###### ########## #### #### ########## ##### ##### ##### ######
17
+ ################ ###### #### #### #### ################# ################
18
+ ##### ###### ##### #### #### #### ################# ##### ######
19
+ ##### ##### #### #### #### #### ##### ##### ##### #####
20
+ ##### ##### #### #### #### #### ##### ##### ##### #####
21
+ ##### ###### #### ##### ##### #### ##### #### ##### ######
22
+ ################## #### ############## ####### ##### #### #################
23
+ ############### #### ####### #### ###### ##### ##### ##############
24
+ }.strip
25
+ LOGO_NARROW = %{
26
+ ################# ####
27
+ ################## ####
28
+ ##### ##### ####
29
+ ##### ##### #### #### #### #### ##########
30
+ ##### ###### ########## #### #### ##########
31
+ ################ ###### #### #### ####
32
+ ##### ###### ##### #### #### ####
33
+ ##### ##### #### #### #### ####
34
+ ##### ##### #### #### #### ####
35
+ ##### ###### #### ##### ##### ####
36
+ ################## #### ############## #######
37
+ ############### #### ####### #### ######
38
+ }.strip
39
+
10
40
  def accepts = [
11
41
  Brut::CLI::Apps::New::Prefix,
12
42
  Brut::CLI::Apps::New::AppId,
@@ -25,16 +55,15 @@ class Brut::CLI::Apps::New::App < Brut::CLI::Commands::BaseCommand
25
55
  Brut::CLI::Apps::New::AppId,
26
56
  "App identifier, which must be able to be used as a hostname or other Internet identifier. Derived from your app name, if omitted"
27
57
  ],
28
- [
29
- "--[no-]interactive",
30
- "Don't ask for user input, just assume default answers",
31
- ],
32
58
  [
33
59
  "--organization=ORG",
34
60
  Brut::CLI::Apps::New::Organization,
35
61
  "Organization name, e.g. what you'd use for GitHub. Defaults to the app-id value"
36
62
  ],
37
-
63
+ [
64
+ "--[no-]interactive",
65
+ "Set if you want to be prompted before the app is actually created",
66
+ ],
38
67
  [
39
68
  "--prefix=PREFIX",
40
69
  Brut::CLI::Apps::New::Prefix,
@@ -60,16 +89,28 @@ class Brut::CLI::Apps::New::App < Brut::CLI::Commands::BaseCommand
60
89
  app_name = argv[0]
61
90
 
62
91
  if !app_name
63
- stderr.puts "app_name is required"
92
+ error "app_name is required"
64
93
  return 1
65
94
  end
66
95
 
96
+ if terminal.cols >= LOGO_WIDE.lines[0].length
97
+ puts theme.title.render("WELCOME TO")
98
+ puts
99
+ puts theme.title.render(LOGO_WIDE)
100
+ elsif terminal.cols >= LOGO_NARROW.lines[0].length
101
+ puts theme.title.render("WELCOME TO")
102
+ puts
103
+ puts theme.title.render(LOGO_NARROW)
104
+ else
105
+ puts theme.title.render("WELCOME TO BRUT")
106
+ end
107
+
67
108
  options.set_default(:app_id, Brut::CLI::Apps::New::AppId.from_app_name(app_name))
68
109
  options.set_default(:prefix, Brut::CLI::Apps::New::Prefix.from_app_id(options.app_id))
69
110
  options.set_default(:organization, Brut::CLI::Apps::New::Prefix.from_app_id(options.app_id))
70
111
  options.set_default(:demo, true)
71
- options.set_default(:interactive, true)
72
112
  options.set_default(:dir,Pathname.pwd)
113
+ options.set_default(:interactive, true)
73
114
 
74
115
  segment_names = Set.new(options.segments)
75
116
  if options.demo?
@@ -128,45 +169,90 @@ class Brut::CLI::Apps::New::App < Brut::CLI::Commands::BaseCommand
128
169
  end
129
170
  segments.sort!
130
171
 
131
- stdout.puts "Creating a new Brut app with these options:\n"
132
- stdout.puts "App Name : #{app_name}"
133
- stdout.puts "Path to New App : #{current_dir / app_name}"
134
- stdout.puts "App Id : #{options.app_id}"
135
- stdout.puts "Prefix : #{options.prefix}"
136
- stdout.puts "Organization : #{options.organization}"
137
- stdout.puts "Segments : #{segments.map(&:class).map(&:segment_name).join(", ")}"
138
- stdout.puts
139
-
140
- if options.dry_run?
141
- stdout.puts "Dry Run only"
142
- Brut::CLI::Apps::New::Ops::BaseOp.dry_run = true
172
+ info "Creating a new Brut app with these options:"
173
+ rows = [
174
+ ["App Name", app_name],
175
+ ["Path to New App", current_dir / app_name],
176
+ ["App Id", options.app_id ],
177
+ ["Prefix", options.prefix ],
178
+ ["Organization", options.organization ],
179
+ ["Segments", segments.map(&:class).map(&:segment_name).join(", ") ],
180
+ ]
181
+ rows.each do |(attr,val)|
182
+ info " #{attr}: #{val}"
143
183
  end
144
-
145
184
  if options.interactive?
146
- stdout.puts "Proceed? (Y/N)"
147
- answer = stdin.gets
148
- if answer.downcase.strip.chomp != "y"
149
- stdout.puts "Aborting...."
150
- exit
185
+ puts
186
+ puts theme.subheader.render("Options for your new app:")
187
+ table = Lipgloss::Table.new.headers(["Attribute", "Value"]).
188
+ rows(rows).
189
+ border(:rounded).
190
+ style_func(rows: rows.size, columns: 2) do |row,column|
191
+ if row == Lipgloss::Table::HEADER_ROW
192
+ if column == 0
193
+ Lipgloss::Style.new.inherit(theme.header).align_horizontal(:right).padding_right(1).padding_left(1)
194
+ else
195
+ Lipgloss::Style.new.inherit(theme.header).align_horizontal(:left).padding_right(1).padding_left(1)
196
+ end
197
+ elsif column == 0
198
+ Lipgloss::Style.new.inherit(theme.subheader).align_horizontal(:right).padding_right(1).padding_left(1)
199
+ else
200
+ Lipgloss::Style.new.inherit(theme.none).align_horizontal(:left).padding_right(1).padding_left(1)
201
+ end
202
+ end
203
+
204
+ puts table.render
205
+
206
+ puts "Proceed? (y/n): "
207
+ answer = stdin.gets.strip.downcase
208
+ if answer != "y"
209
+ puts theme.warning.render("Aborting app creation")
210
+ return 0
151
211
  end
152
212
  end
153
213
 
154
- stdout.puts "Creating Base app"
214
+ if options.dry_run?
215
+ info "Dry Run only"
216
+ Brut::CLI::Apps::New::Ops::BaseOp.dry_run = true
217
+ end
218
+
219
+ info "Creating Base app"
155
220
  base.create!
156
221
  segments.each do |segment|
157
- stdout.puts "Creating segment: #{segment.class.friendly_name}"
222
+ info "Creating segment: #{segment.class.friendly_name}"
158
223
  segment.add!
159
224
  end
160
- stdout.puts "#{options.app_name} was created\n\n"
161
- stdout.puts "Time to get building:"
162
- stdout.puts "1. cd #{current_dir / app_name}"
163
- stdout.puts "2. dx/build"
164
- stdout.puts "3. dx/start"
165
- stdout.puts "4. [ in another terminal ] dx/exec bash"
166
- stdout.puts "5. [ inside the Docker container ] bin/setup"
167
- stdout.puts "6. [ inside the Docker container ] bin/dev"
168
- stdout.puts "7. Visit http://localhost:6502 in your browser"
169
- stdout.puts "8. [ inside the Docker container ] bin/setup help # to see more commands"
225
+
226
+ puts
227
+ print theme.header.render("Your app ")
228
+ print theme.subheader.render(app_name)
229
+ print theme.header.render(" was created - time to get building!")
230
+ puts
231
+ puts
232
+
233
+ in_computer = Lipgloss::List.new.items(
234
+ [
235
+ theme.code.render("cd #{current_dir / app_name}"),
236
+ theme.code.render("dx/build"),
237
+ theme.code.render("dx/start"),
238
+ "#{theme.weak.render("(in another terminal)")} #{theme.code.render('dx/exec bash')}",
239
+ ]
240
+ ).enumerator(:arabic).enumerator_style(theme.bullet(1))
241
+ in_docker = Lipgloss::List.new.items(
242
+ [
243
+ theme.code.render("bin/setup"),
244
+ theme.code.render("bin/dev"),
245
+ ]
246
+ ).enumerator(:arabic).enumerator_style(theme.bullet(1))
247
+ list = Lipgloss::List.new.items([
248
+ "On your computer:\n#{in_computer.render}",
249
+ "Inside the Docker container:\n#{in_docker.render}",
250
+ "Navigate to #{theme.url.render('http://localhost:6502')} to see your app",
251
+ "Inside the Docker container, try #{theme.code.render('bin/setup')} help to find more commands",
252
+ ]).enumerator(:arabic).
253
+ enumerator_style(theme.bullet(0))
254
+ puts list.render
255
+ puts
170
256
  end
171
257
 
172
258
  class Segment < Brut::CLI::Commands::BaseCommand
@@ -195,7 +281,7 @@ class Brut::CLI::Apps::New::App < Brut::CLI::Commands::BaseCommand
195
281
 
196
282
  segment_name = argv[0]
197
283
  if !segment_name
198
- stderr.puts "segment_name is required"
284
+ error "segment_name is required"
199
285
  return 1
200
286
  end
201
287
  if options.demo?
@@ -207,7 +293,7 @@ class Brut::CLI::Apps::New::App < Brut::CLI::Commands::BaseCommand
207
293
 
208
294
 
209
295
  if options.dry_run?
210
- stdout.puts "Dry Run"
296
+ puts "Dry Run"
211
297
  Brut::CLI::Apps::New::Ops::BaseOp.dry_run = true
212
298
  end
213
299
 
@@ -227,11 +313,11 @@ class Brut::CLI::Apps::New::App < Brut::CLI::Commands::BaseCommand
227
313
  )
228
314
  end
229
315
  if !segment
230
- stderr.puts "'#{segment_name}' is not a segment. Allowed values: sidekiq, heroku"
316
+ error "'#{segment_name}' is not a segment. Allowed values: sidekiq, heroku"
231
317
  return 1
232
318
  end
233
319
 
234
- stdout.puts "Adding #{segment_name} to this app"
320
+ puts "Adding #{segment_name} to this app"
235
321
  segment.add!
236
322
  segment.output_post_add_messaging(stdout:)
237
323
  0