theme-juice 0.5.0 → 0.6.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.
@@ -0,0 +1,17 @@
1
+ # encoding: UTF-8
2
+
3
+ module ThemeJuice
4
+ class Command::Create < ::ThemeJuice::Command
5
+
6
+ #
7
+ # @param {Hash} opts
8
+ #
9
+ # @return {Void}
10
+ #
11
+ def initialize(opts = {})
12
+ super
13
+
14
+ ::ThemeJuice::Service::CreateSite.new(@opts).create
15
+ end
16
+ end
17
+ end
@@ -0,0 +1,17 @@
1
+ # encoding: UTF-8
2
+
3
+ module ThemeJuice
4
+ class Command::Delete < ::ThemeJuice::Command
5
+
6
+ #
7
+ # @param {Hash} opts
8
+ #
9
+ # @return {Void}
10
+ #
11
+ def initialize(opts = {})
12
+ super
13
+
14
+ ::ThemeJuice::Service::DeleteSite.new(@opts).delete
15
+ end
16
+ end
17
+ end
@@ -0,0 +1,17 @@
1
+ # encoding: UTF-8
2
+
3
+ module ThemeJuice
4
+ class Command::Install < ::ThemeJuice::Command
5
+
6
+ #
7
+ # @param {Hash} opts
8
+ #
9
+ # @return {Void}
10
+ #
11
+ def initialize(opts = {})
12
+ super
13
+
14
+ ::ThemeJuice::Service::ConfigFile.new.install
15
+ end
16
+ end
17
+ end
@@ -0,0 +1,17 @@
1
+ # encoding: UTF-8
2
+
3
+ module ThemeJuice
4
+ class Command::List < ::ThemeJuice::Command
5
+
6
+ #
7
+ # @param {Hash} opts
8
+ #
9
+ # @return {Void}
10
+ #
11
+ def initialize(opts = {})
12
+ super
13
+
14
+ ::ThemeJuice::Service::ListSites.new.list
15
+ end
16
+ end
17
+ end
@@ -0,0 +1,17 @@
1
+ # encoding: UTF-8
2
+
3
+ module ThemeJuice
4
+ class Command::Subcommand < ::ThemeJuice::Command
5
+
6
+ #
7
+ # @param {Hash} opts
8
+ #
9
+ # @return {Void}
10
+ #
11
+ def initialize(opts = {})
12
+ super
13
+
14
+ ::ThemeJuice::Service::ConfigFile.new.subcommand @opts[:subcommand], @opts[:commands]
15
+ end
16
+ end
17
+ end
@@ -0,0 +1,14 @@
1
+ # encoding: UTF-8
2
+
3
+ module ThemeJuice
4
+ module Environment
5
+ class << self
6
+ attr_accessor :vvv_path
7
+ attr_accessor :no_unicode
8
+ attr_accessor :no_colors
9
+ attr_accessor :no_animations
10
+ attr_accessor :boring
11
+ attr_accessor :yolo
12
+ end
13
+ end
14
+ end
@@ -0,0 +1,446 @@
1
+ # encoding: UTF-8
2
+
3
+ module ThemeJuice
4
+ module Interaction
5
+
6
+ # Icons
7
+ ICONS = {
8
+
9
+ # Unicode
10
+ :success => "\u2713",
11
+ :error => "\u2191",
12
+ :notice => "\u2192",
13
+ :question => "\u2022",
14
+ :general => "\u2022",
15
+ :log => "\u2026",
16
+ :restart => "\u21AA",
17
+ :selected => "\u2022",
18
+ :unselected => "\u25CB",
19
+
20
+ # Fallback
21
+ :nu_success => "+",
22
+ :nu_error => "!",
23
+ :nu_notice => "-",
24
+ :nu_question => "?",
25
+ :nu_general => "-",
26
+ :nu_log => "...",
27
+ :nu_restart => "!",
28
+ :nu_selected => "[x]",
29
+ :nu_unselected => "[ ]"
30
+ }
31
+
32
+ # Escape sequences
33
+ KEYS = {
34
+ "\e[A" => "up",
35
+ "\e[B" => "down",
36
+ "\e[C" => "right",
37
+ "\e[D" => "left",
38
+ "\003" => "ctrl+c",
39
+ "\004" => "ctrl+d",
40
+ "\e" => "escape",
41
+ "\n" => "linefeed",
42
+ "\r" => "return",
43
+ " " => "space"
44
+ }
45
+
46
+ # Get the environment
47
+ @environment = ::ThemeJuice::Environment
48
+
49
+ class << self
50
+ include ::Thor::Actions
51
+ include ::Thor::Shell
52
+
53
+ #
54
+ # Output formatted message
55
+ #
56
+ # @param {String} message
57
+ # @param {Hash} opts
58
+ #
59
+ # @return {Void}
60
+ #
61
+ def speak(message, opts = {})
62
+ format_message message, opts
63
+ output_message
64
+ end
65
+
66
+ #
67
+ # Ask a question
68
+ #
69
+ # @param {String} question
70
+ # @param {Hash} opts
71
+ #
72
+ # @return {Void}
73
+ #
74
+ def prompt(question, *opts)
75
+ format_message question, {
76
+ :color => :blue,
77
+ :icon => :question
78
+ }
79
+
80
+ opts.each do |opt|
81
+
82
+ # if opt[:default]
83
+ # opt[:default] = set_color(opt[:default], :black, :bold) unless @environment.no_colors
84
+ # end
85
+
86
+ if opt[:indent]
87
+ set(question) { |str| (" " * opt[:indent]) << str }
88
+ end
89
+
90
+ break
91
+ end
92
+
93
+ ask("#{question} :", *opts).gsub /\e\[\d+m/, ""
94
+ end
95
+
96
+ #
97
+ # Ask a yes or no question
98
+ #
99
+ # @param {String} question
100
+ # @param {Hash} opts
101
+ #
102
+ # @return {Bool}
103
+ #
104
+ def agree?(question, opts = {})
105
+
106
+ format_message question, {
107
+ :color => opts[:color] || :blue,
108
+ :icon => :question
109
+ }
110
+
111
+ if opts[:simple]
112
+ yes? " :", if opts[:color] then opts[:color] end
113
+ else
114
+ yes? "#{question} (y/N) :"
115
+ end
116
+ end
117
+
118
+ #
119
+ # Output log message
120
+ #
121
+ # @param {String} message
122
+ #
123
+ # @return {Void}
124
+ #
125
+ def log(message)
126
+ speak message, {
127
+ :color => :yellow,
128
+ :icon => :log
129
+ }
130
+ end
131
+
132
+ #
133
+ # Output success message
134
+ #
135
+ # @param {String} message
136
+ #
137
+ # @return {Void}
138
+ #
139
+ def success(message)
140
+ speak message, {
141
+ :color => [:black, :on_green, :bold],
142
+ :icon => :success,
143
+ :row => true
144
+ }
145
+ end
146
+
147
+ #
148
+ # Output notice message
149
+ #
150
+ # @param {String} message
151
+ #
152
+ # @return {Void}
153
+ #
154
+ def notice(message)
155
+ speak message, {
156
+ :color => [:black, :on_yellow],
157
+ :icon => :notice,
158
+ :row => true
159
+ }
160
+ end
161
+
162
+ #
163
+ # Output error message and exit. Allows a block to be passed
164
+ # as well, which will be executed before exiting
165
+ #
166
+ # @param {String} message
167
+ #
168
+ # @return {Void}
169
+ #
170
+ def error(message)
171
+ speak message, {
172
+ :color => [:white, :on_red],
173
+ :icon => :error,
174
+ :row => true
175
+ }
176
+
177
+ yield if block_given?
178
+
179
+ exit 1
180
+ end
181
+
182
+ #
183
+ # Output greeting
184
+ #
185
+ # @param {Hash} opts ({})
186
+ #
187
+ # @return {Void}
188
+ #
189
+ def hello(opts = {})
190
+ speak "Welcome to Theme Juice!", {
191
+ :color => [:black, :on_green, :bold],
192
+ :row => true
193
+ }.merge(opts)
194
+ end
195
+
196
+ #
197
+ # Output goodbye and exit with interupt code
198
+ #
199
+ # @param {Hash} opts ({})
200
+ #
201
+ # @return {Void}
202
+ #
203
+ def goodbye(opts = {})
204
+ speak "Bye bye!", {
205
+ :color => :yellow,
206
+ :icon => :general,
207
+ :newline => true
208
+ }.merge(opts)
209
+
210
+ exit 130
211
+ end
212
+
213
+ #
214
+ # Output a list of messages
215
+ #
216
+ # @param {String} header
217
+ # @param {Symbol} color
218
+ # @param {Array} list
219
+ #
220
+ # @return {Void}
221
+ #
222
+ def list(header, color, list)
223
+ speak header, {
224
+ :color => [:black, :"on_#{color}"],
225
+ :icon => :notice,
226
+ :row => true
227
+ }
228
+
229
+ list.each do |item|
230
+ speak item, {
231
+ :color => :"#{color}",
232
+ :icon => :general
233
+ }
234
+ end
235
+ end
236
+
237
+ #
238
+ # Create a shell select menu
239
+ #
240
+ # @param {String} header
241
+ # @param {Symbol} color
242
+ # @param {Array} list
243
+ #
244
+ # @return {String}
245
+ #
246
+ def choose(header, color, list)
247
+ speak "#{header} (use arrow keys and press enter)", {
248
+ :color => :"#{color}",
249
+ :icon => :question
250
+ }
251
+
252
+ print "\n" * list.size
253
+
254
+ selected = 0
255
+ update_list_selection(list, color, selected)
256
+
257
+ loop do
258
+ case key = read_key
259
+ when "up"
260
+ selected -= 1
261
+ selected = list.size - 1 if selected < 0
262
+ update_list_selection(list, color, selected)
263
+ when "down"
264
+ selected += 1
265
+ selected = 0 if selected > list.size - 1
266
+ update_list_selection(list, color, selected)
267
+ when "return", "linefeed", "space"
268
+ return list[selected]
269
+ when "esc", "ctrl+c"
270
+ goodbye(newline: false)
271
+ # else
272
+ # speak "You pressed: #{chr.inspect}", { color: :yellow }
273
+ end
274
+ end
275
+ end
276
+
277
+ private
278
+
279
+ #
280
+ # Destructively format message
281
+ #
282
+ # @param {String} message
283
+ # @param {Hash} opts
284
+ #
285
+ # @return {String}
286
+ #
287
+ def format_message(message, opts = {})
288
+ @message, @opts = message, opts
289
+
290
+ format_message_icon
291
+ format_message_newline
292
+ format_message_row
293
+ format_message_width
294
+ format_message_color
295
+ format_message_indent
296
+
297
+ @message
298
+ end
299
+
300
+ #
301
+ # Run destructive block against string
302
+ #
303
+ # @param {String} string
304
+ #
305
+ # @return {String}
306
+ #
307
+ def set(string)
308
+ str = yield(string); string.clear; string << str
309
+ end
310
+
311
+ #
312
+ # Force message to use icon (if environment allows)
313
+ #
314
+ # @return {String}
315
+ #
316
+ def format_message_icon
317
+ icon = if @environment.no_unicode then "nu_#{@opts[:icon]}" else "#{@opts[:icon]}" end
318
+
319
+ if @opts[:icon]
320
+ set(@message) { |msg| " #{ICONS[:"#{icon}"]}" << if @opts[:empty] then nil else " #{msg}" end }
321
+ else
322
+ set(@message) { |msg| " " << msg }
323
+ end
324
+ end
325
+
326
+ #
327
+ # Force message on newline, unless already on newline
328
+ #
329
+ # @return {String}
330
+ #
331
+ def format_message_newline
332
+ set(@message) { |msg| "\n" << msg } if @opts[:newline]
333
+ end
334
+
335
+ #
336
+ # Force message to use colors (if environment allows)
337
+ #
338
+ # @return {String}
339
+ #
340
+ def format_message_color
341
+ unless @environment.no_colors
342
+ set(@message) { |msg| set_color(msg, *@opts[:color]) } if @opts[:color]
343
+ end
344
+ end
345
+
346
+ #
347
+ # Force message to take up width of terminal window
348
+ #
349
+ # @return {String}
350
+ #
351
+ def format_message_row
352
+ set(@message) { |msg| msg.ljust(terminal_width) } if @opts[:row]
353
+ end
354
+
355
+ #
356
+ # Force message width
357
+ #
358
+ # @return {String}
359
+ #
360
+ def format_message_width
361
+ set(@message) { |msg| msg.ljust(@opts[:width]) } if @opts[:width]
362
+ end
363
+
364
+ #
365
+ # Force message indentation
366
+ #
367
+ # @return {String}
368
+ #
369
+ def format_message_indent
370
+ set(@message) { |str| (" " * @opts[:indent]) << str } if @opts[:indent]
371
+ end
372
+
373
+ #
374
+ # Output message to terminal, unless quiet
375
+ #
376
+ # @return {String|Void}
377
+ #
378
+ def output_message
379
+ if @opts[:quiet] then @message else say @message end
380
+ end
381
+
382
+ #
383
+ # Output list with updated selection
384
+ #
385
+ # @return {Void}
386
+ #
387
+ def update_list_selection(list, color, selected = 0)
388
+ print "\e[#{list.size}A"
389
+
390
+ list.each_with_index do |item, i|
391
+ icon = if i == selected then "selected" else "unselected" end
392
+ speak "#{item}", {
393
+ :color => :"#{color}",
394
+ :icon => :"#{icon}",
395
+ :indent => 2
396
+ }
397
+ end
398
+ end
399
+
400
+ #
401
+ # Read input
402
+ #
403
+ # @see http://www.alecjacobson.com/weblog/?p=75
404
+ #
405
+ # @return {String}
406
+ #
407
+ def read_key
408
+ save_state
409
+ raw_no_echo_mode
410
+
411
+ key = STDIN.getc.chr
412
+
413
+ if key == "\e"
414
+ thread = Thread.new { key += STDIN.getc.chr + STDIN.getc.chr }
415
+ thread.join(0.001)
416
+ thread.kill
417
+ end
418
+
419
+ KEYS[key] || key
420
+ ensure
421
+ restore_state
422
+ end
423
+
424
+ #
425
+ # Get the current state of stty
426
+ #
427
+ def save_state
428
+ @state = %x(stty -g)
429
+ end
430
+
431
+ #
432
+ # Disable echoing and enable raw mode
433
+ #
434
+ def raw_no_echo_mode
435
+ %x(stty raw -echo)
436
+ end
437
+
438
+ #
439
+ # Restore state of stty
440
+ #
441
+ def restore_state
442
+ %x(stty #{@state})
443
+ end
444
+ end
445
+ end
446
+ end