theme-juice 0.5.0 → 0.6.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -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