wassup 0.1.2 → 0.3.1

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.
Files changed (55) hide show
  1. checksums.yaml +4 -4
  2. data/.gitignore +4 -0
  3. data/Gemfile.lock +19 -1
  4. data/README.md +19 -13
  5. data/bin/wassup +6 -1
  6. data/docs/.gitignore +20 -0
  7. data/docs/README.md +41 -0
  8. data/docs/babel.config.js +3 -0
  9. data/docs/blog/2021-12-09-welcome/index.md +8 -0
  10. data/docs/blog/authors.yml +5 -0
  11. data/docs/docs/Supfile-basics/_category_.json +4 -0
  12. data/docs/docs/Supfile-basics/understanding-the-supfile.md +50 -0
  13. data/docs/docs/intro.md +54 -0
  14. data/docs/docusaurus.config.js +110 -0
  15. data/docs/package-lock.json +21196 -0
  16. data/docs/package.json +43 -0
  17. data/docs/sidebars.js +31 -0
  18. data/docs/src/components/HomepageFeatures.module.css +10 -0
  19. data/docs/src/components/HomepageFeatures.tsx +60 -0
  20. data/docs/src/css/custom.css +28 -0
  21. data/docs/src/pages/index.module.css +36 -0
  22. data/docs/src/pages/index.tsx +39 -0
  23. data/docs/src/pages/markdown-page.md +7 -0
  24. data/docs/static/.nojekyll +0 -0
  25. data/docs/static/img/demo-supfile.png +0 -0
  26. data/docs/static/img/favicon.ico +0 -0
  27. data/docs/static/img/logo.svg +27 -0
  28. data/docs/static/img/tutorial/docsVersionDropdown.png +0 -0
  29. data/docs/static/img/tutorial/localeDropdown.png +0 -0
  30. data/docs/static/img/tutorial-intro-starter-screenshot.png +0 -0
  31. data/docs/static/img/undraw_docusaurus_mountain.svg +170 -0
  32. data/docs/static/img/undraw_docusaurus_react.svg +169 -0
  33. data/docs/static/img/undraw_docusaurus_tree.svg +1 -0
  34. data/docs/static/img/wassup-long.png +0 -0
  35. data/docs/static/img/wassup-screenshot.png +0 -0
  36. data/docs/static/img/wassup.png +0 -0
  37. data/docs/static/video/wassup-demo.mov +0 -0
  38. data/docs/tsconfig.json +7 -0
  39. data/examples/basic/Supfile +183 -16
  40. data/examples/debug/Supfile +90 -13
  41. data/examples/josh-fastlane/Supfile +61 -117
  42. data/examples/simple/Supfile +17 -0
  43. data/examples/starter/Supfile +44 -0
  44. data/lib/wassup/app.rb +167 -6
  45. data/lib/wassup/color.rb +5 -0
  46. data/lib/wassup/helpers/circleci.rb +75 -0
  47. data/lib/wassup/helpers/github.rb +137 -0
  48. data/lib/wassup/helpers/netlify.rb +70 -0
  49. data/lib/wassup/helpers/shortcut.rb +114 -0
  50. data/lib/wassup/pane.rb +244 -134
  51. data/lib/wassup/pane_builder.rb +60 -1
  52. data/lib/wassup/version.rb +1 -1
  53. data/lib/wassup.rb +5 -0
  54. data/wassup.gemspec +1 -0
  55. metadata +55 -2
data/lib/wassup/pane.rb CHANGED
@@ -6,11 +6,12 @@ module Wassup
6
6
  class Pane
7
7
  attr_accessor :win
8
8
  attr_accessor :subwin
9
- attr_accessor :data_lines
10
- attr_accessor :data_objects
11
9
  attr_accessor :top
12
10
 
11
+ attr_accessor :contents
12
+
13
13
  attr_accessor :title
14
+ attr_accessor :description
14
15
 
15
16
  attr_accessor :focused
16
17
  attr_accessor :focus_number
@@ -28,22 +29,52 @@ module Wassup
28
29
  attr_accessor :last_refreshed
29
30
  attr_accessor :content_block
30
31
  attr_accessor :selection_blocks
32
+ attr_accessor :selection_blocks_description
33
+
34
+ attr_accessor :caught_error
31
35
 
32
36
  attr_accessor :content_thread
37
+ attr_accessor :show_refresh
33
38
 
34
39
  attr_accessor :selected_view_index
35
- attr_accessor :all_view_data_objects
36
40
 
37
41
  attr_accessor :win_height, :win_width, :win_top, :win_left
38
42
 
39
- def initialize(height, width, top, left, title: nil, highlight: true, focus_number: nil, interval:, content_block:, selection_blocks:)
40
- self.win_height = Curses.lines * height
41
- self.win_width = Curses.cols * width
42
- self.win_top = Curses.lines * top
43
- self.win_left = Curses.cols * left
43
+ class Content
44
+ class Row
45
+ attr_accessor :display
46
+ attr_accessor :object
44
47
 
45
- self.win = Curses::Window.new(self.win_height, self.win_width, self.win_top, self.win_left)
46
- self.setup_subwin()
48
+ def initialize(display, object)
49
+ @display = display
50
+ @object = object || display
51
+ end
52
+ end
53
+
54
+ attr_accessor :title
55
+ attr_accessor :data
56
+
57
+ def initialize(title = nil)
58
+ @title = title
59
+ @data = []
60
+ end
61
+
62
+ def add_row(display, object = nil)
63
+ @data << Row.new(display, object)
64
+ end
65
+ end
66
+
67
+ def initialize(height, width, top, left, title: nil, description: nil, highlight: true, focus_number: nil, interval:, show_refresh:, content_block:, selection_blocks:, selection_blocks_description:, debug: false)
68
+
69
+ if !debug
70
+ self.win_height = Curses.lines * height
71
+ self.win_width = Curses.cols * width
72
+ self.win_top = Curses.lines * top
73
+ self.win_left = Curses.cols * left
74
+
75
+ self.win = Curses::Window.new(self.win_height, self.win_width, self.win_top, self.win_left)
76
+ self.setup_subwin()
77
+ end
47
78
 
48
79
  self.focused = false
49
80
  self.focus_number = focus_number
@@ -52,20 +83,24 @@ module Wassup
52
83
  self.virtual_scroll = true
53
84
 
54
85
  self.top = 0
55
- self.data_lines = []
56
- self.data_objects = []
86
+
87
+ self.contents = []
88
+ self.show_refresh = show_refresh
57
89
 
58
90
  self.selected_view_index = 0
59
- self.all_view_data_objects = [] # Array of array
60
91
 
61
- self.win.refresh
62
- self.subwin.refresh
92
+ if !debug
93
+ self.win.refresh
94
+ self.subwin.refresh
95
+ end
63
96
 
64
97
  self.title = title
98
+ self.description = description
65
99
 
66
100
  self.interval = interval
67
101
  self.content_block = content_block
68
102
  self.selection_blocks = selection_blocks || {}
103
+ self.selection_blocks_description = selection_blocks_description || {}
69
104
  end
70
105
 
71
106
  def setup_subwin
@@ -77,16 +112,16 @@ module Wassup
77
112
  self.subwin = nil
78
113
  end
79
114
 
80
- if (@all_view_data_objects || []).size > 1
115
+ if (self.contents || []).size > 1
81
116
  top_bump = 4
82
117
 
83
- view_title = (self.all_view_data_objects[self.selected_view_index] || {})[:title]
118
+ view_title = self.contents[self.selected_view_index].title || "<No Title>"
84
119
  view_title += " " * 100
85
120
 
86
121
  self.win.setpos(2, 2)
87
122
  self.win.addstr(view_title[0...self.win.maxx()-3])
88
123
 
89
- subtitle = "(#{self.selected_view_index + 1} out of #{self.all_view_data_objects.size})"
124
+ subtitle = "(#{self.selected_view_index + 1} out of #{self.contents.size})"
90
125
  subtitle += " " * 100
91
126
  self.win.setpos(3, 2)
92
127
  self.win.addstr(subtitle[0...self.win.maxx()-3])
@@ -106,6 +141,16 @@ module Wassup
106
141
  self.subwin.scrollok(true)
107
142
  end
108
143
 
144
+ def close
145
+ unless self.subwin.nil?
146
+ self.subwin.clear
147
+ self.subwin.close
148
+ end
149
+
150
+ self.win.clear
151
+ self.win.close
152
+ end
153
+
109
154
  def needs_refresh?
110
155
  return false if self.content_block.nil?
111
156
  return false if self.interval.nil?
@@ -120,28 +165,72 @@ module Wassup
120
165
  end
121
166
  end
122
167
 
168
+ def data_lines
169
+ return [] if self.selected_view_index.nil?
170
+ content = (self.contents || [])[self.selected_view_index]
171
+
172
+ if content.nil?
173
+ return []
174
+ else
175
+ content.data.map(&:display)
176
+ end
177
+ end
178
+
179
+ def refreshing?
180
+ return !self.content_thread.nil?
181
+ end
182
+
183
+ def redraw
184
+ self.update_box
185
+ self.update_title
186
+ self.load_current_view()
187
+ end
188
+
123
189
  def refresh(force: false)
124
- return if !needs_refresh? && !force
190
+ if force
191
+ self.last_refreshed = nil
192
+ end
193
+
194
+ if !needs_refresh?
195
+ return
196
+ end
125
197
 
126
198
  thread = self.content_thread
127
199
  if !thread.nil?
128
200
  if thread.status == "sleep" || thread.status == "run" || thread.status == "aborting"
201
+ self.update_refresh
129
202
  return
130
203
  elsif thread.status == nil
131
- self.add_line("thread status is nil")
132
204
  return
133
205
  elsif thread.status == false
134
- content = thread.value
135
- if content.is_a?(Ope)
136
- self.refresh_content([
137
- "[fg=red]Error during refersh[fg=white]",
138
- "[fg=red]at #{Time.now}[fg=while]",
139
- "",
140
- "[fg=yellow]Will try again next interval[fg=white]"
141
- ])
142
- else
143
- self.refresh_content(content)
206
+ rtn = thread.value
207
+ if rtn.is_a?(Ope)
208
+ self.caught_error = rtn.error
209
+ content = Wassup::Pane::Content.new("Overview")
210
+ content.add_row("[fg=red]Error during refersh[fg=white]")
211
+ content.add_row("[fg=red]at #{Time.now}[fg=while]")
212
+ content.add_row("")
213
+ content.add_row("[fg=yellow]Will try again next interval[fg=white]")
214
+
215
+ content_directions = Wassup::Pane::Content.new("Directions")
216
+ content_directions.add_row("1. Press 'c' to copy the stacktrace")
217
+ content_directions.add_row("2. Debug pane content block with:")
218
+ content_directions.add_row(" $: wassup --debug")
219
+ content_directions.add_row("3. Stacktrace viewable in next page")
220
+
221
+ content_stacktrace = Wassup::Pane::Content.new("Stacktrace")
222
+ rtn.error.backtrace.each do |line|
223
+ content_stacktrace.add_row(line)
224
+ end
225
+
226
+ self.refresh_content([content, content_directions, content_stacktrace])
227
+ elsif rtn.is_a?(Wassup::PaneBuilder::ContentBuilder)
228
+ self.caught_error = nil
229
+ self.refresh_content(rtn.contents)
144
230
  end
231
+
232
+ self.update_box
233
+ self.update_title
145
234
  else
146
235
  # This shouldn't happen
147
236
  # TODO: also fix this
@@ -151,25 +240,21 @@ module Wassup
151
240
  the_block = self.content_block
152
241
  self.content_thread = Thread.new {
153
242
  begin
154
- content = the_block.call()
243
+ builder = Wassup::PaneBuilder::ContentBuilder.new(self.contents)
244
+ content = the_block.call(builder)
245
+
246
+ builder
155
247
  rescue => ex
156
248
  next Ope.new(ex)
157
249
  end
158
250
  }
251
+ self.update_box
252
+ self.update_title
159
253
  end
160
254
  end
161
255
 
162
- def refresh_content(content)
163
- return unless content.is_a?(Array)
164
- return if content.first.nil?
165
-
166
- if content.first.is_a?(Hash)
167
- self.all_view_data_objects = content
168
- else
169
- self.all_view_data_objects = [
170
- content
171
- ]
172
- end
256
+ def refresh_content(contents)
257
+ self.contents = contents
173
258
 
174
259
  self.load_current_view()
175
260
  self.last_refreshed = Time.now
@@ -179,40 +264,73 @@ module Wassup
179
264
 
180
265
  def load_current_view
181
266
  self.setup_subwin()
182
- view_content = self.all_view_data_objects[self.selected_view_index]
183
267
 
184
268
  # this might be bad
185
269
  self.highlighted_line = nil
270
+ self.virtual_reload()
271
+ end
272
+
273
+ def title=(title)
274
+ @title = title
275
+ self.update_box()
276
+ self.update_title()
277
+ end
186
278
 
187
- require 'pp'
188
- if view_content.is_a?(Hash) && view_content[:content]
189
- view_content = view_content[:content]
279
+ def highlight
280
+ if self.caught_error
281
+ return true
282
+ end
283
+ return @highlight
284
+ end
285
+
286
+ attr_accessor :refresh_char_count
287
+ def refresh_char
288
+ return "" unless self.show_refresh
289
+
290
+ if self.refresh_char_count.nil?
291
+ self.refresh_char_count = 0
190
292
  end
191
293
 
192
- @data_lines = []
193
- @data_objects = []
194
- view_content.each do |item|
195
- if item.is_a?(String)
196
- @data_objects << item
197
- self.add_line(item)
198
- elsif item.is_a?(Array)
199
- @data_objects << item[1]
200
- self.add_line(item[0])
294
+ if self.refreshing?
295
+ array = ['\\', '|', '/', '|']
296
+ rtn = array[self.refresh_char_count]
297
+
298
+ self.refresh_char_count += 1
299
+ if self.refresh_char_count >= array.size
300
+ self.refresh_char_count = 0
201
301
  end
302
+
303
+ return rtn
304
+ else
305
+ return ""
202
306
  end
203
307
  end
204
308
 
205
- def title=(title)
206
- @title = title
207
- self.update_box()
208
- self.update_title()
309
+ attr_accessor :last_refresh_char_at
310
+ def update_refresh
311
+ return unless self.should_box
312
+
313
+ self.last_refresh_char_at ||= Time.now
314
+
315
+ if Time.now - self.last_refresh_char_at >= 0.15
316
+ self.win.setpos(0, 1)
317
+ self.win.addstr(self.refresh_char)
318
+ self.win.refresh
319
+
320
+ self.last_refresh_char_at = Time.now
321
+ end
209
322
  end
210
323
 
211
324
  def update_title
212
325
  return unless self.should_box
213
326
 
214
327
  title = self.title || "<No Title>"
215
- full_title = "#{self.focus_number} - #{title}"
328
+
329
+ if self.focus_number.nil?
330
+ full_title = title
331
+ else
332
+ full_title = "#{self.focus_number} - #{title}"
333
+ end
216
334
 
217
335
  self.win.setpos(0, 3)
218
336
  self.win.addstr(full_title)
@@ -229,23 +347,19 @@ module Wassup
229
347
  def update_box
230
348
  return unless self.should_box
231
349
 
232
- self.win.attrset(self.focused ? Curses.color_pair(Wassup::Color::Pair::BORDER_FOCUS) : Curses.color_pair(Wassup::Color::Pair::BORDER))
350
+ show_focused = self.focused
351
+
352
+ if self.focus_number.nil?
353
+ show_focused = true
354
+ end
355
+
356
+ self.win.attrset(show_focused ? Curses.color_pair(Wassup::Color::Pair::BORDER_FOCUS) : Curses.color_pair(Wassup::Color::Pair::BORDER))
233
357
  self.win.box()
234
358
  self.win.attrset(Curses.color_pair(Wassup::Color::Pair::NORMAL))
235
359
 
236
360
  self.win.refresh
237
361
  end
238
362
 
239
- def add_line(text)
240
- data_lines << text
241
-
242
- if self.virtual_scroll
243
- self.virtual_reload
244
- else
245
- self.load_thing
246
- end
247
- end
248
-
249
363
  # Load the file into memory and
250
364
  # put the first part on the curses display.
251
365
  def load_thing
@@ -258,8 +372,9 @@ module Wassup
258
372
  end
259
373
 
260
374
  def virtual_reload
261
- return if self.data_lines.nil?
375
+ return if self.data_lines.nil? || self.data_lines.empty?
262
376
 
377
+ # TODO: This errored out but might be because thread stuff???
263
378
  self.data_lines[self.top..(self.top+self.subwin.maxy-1)].each_with_index do |line, idx|
264
379
 
265
380
  write_full_line = false
@@ -267,65 +382,49 @@ module Wassup
267
382
 
268
383
  max_char = self.subwin.maxx()-3
269
384
 
270
- # if false && write_full_line || should_highlight
271
- # if should_highlight
272
- # self.subwin.attrset(Curses.color_pair(Wassup::Color::Pair::HIGHLIGHT))
273
- # else
274
- # self.subwin.attrset(Curses.color_pair(Wassup::Color::Pair::NORMAL))
275
- # end
276
- #
277
- # short_line = line[0...max_char]
278
- #
279
- # self.subwin.setpos(idx, 0)
280
- # self.subwin.addstr(short_line)
281
- # self.subwin.clrtoeol()
282
- #
283
- # self.subwin.attrset(Curses.color_pair(Wassup::Color::Pair::NORMAL))
284
- # else
285
- self.subwin.attrset(Curses.color_pair(Wassup::Color::Pair::NORMAL))
286
-
287
- splits = line.split(/\[.*?\]/) # returns ["hey something", "other thing", "okay"]
288
- scans = line.scan(/\[.*?\]/) #returns ["red", "white"]
289
- scans = scans.map do |str|
290
- if str.start_with?('[fg=')
291
- str = str.gsub('[fg=', '').gsub(']','')
292
- Wassup::Color.new(str)
293
- else
294
- str
295
- end
296
- end
297
-
298
- all_parts = splits.zip(scans).flatten.compact
299
-
300
- char_count = 0
301
-
302
- if should_highlight
303
- self.subwin.attrset(Curses.color_pair(Wassup::Color::Pair::HIGHLIGHT))
304
- end
305
-
306
- all_parts.each do |part|
307
- if part.is_a?(Wassup::Color)
308
- #color = Curses.color_pair([1,2,3,4].sample)
309
- if !should_highlight
310
- self.subwin.attrset(Curses.color_pair(part.color_pair))
311
- end
312
- else
313
- new_char_count = char_count + part.size
314
- if new_char_count >= max_char
315
- part = part[0...(max_char - char_count)]
316
- end
317
-
318
- self.subwin.setpos(idx, char_count)
319
- self.subwin.addstr(part)
320
-
321
- char_count += part.size
322
- end
323
-
324
- end
325
-
326
- self.subwin.attrset(Curses.color_pair(Wassup::Color::Pair::NORMAL))
327
- self.subwin.clrtoeol()
328
- #end
385
+ self.subwin.attrset(Curses.color_pair(Wassup::Color::Pair::NORMAL))
386
+
387
+ splits = line.split(/\[.*?\]/) # returns ["hey something", "other thing", "okay"]
388
+ scans = line.scan(/\[.*?\]/) #returns ["red", "white"]
389
+ scans = scans.map do |str|
390
+ if str.start_with?('[fg=')
391
+ str = str.gsub('[fg=', '').gsub(']','')
392
+ Wassup::Color.new(str)
393
+ else
394
+ str
395
+ end
396
+ end
397
+
398
+ all_parts = splits.zip(scans).flatten.compact
399
+
400
+ char_count = 0
401
+
402
+ if should_highlight
403
+ self.subwin.attrset(Curses.color_pair(Wassup::Color::Pair::HIGHLIGHT))
404
+ end
405
+
406
+ all_parts.each do |part|
407
+ if part.is_a?(Wassup::Color)
408
+ #color = Curses.color_pair([1,2,3,4].sample)
409
+ if !should_highlight
410
+ self.subwin.attrset(Curses.color_pair(part.color_pair))
411
+ end
412
+ else
413
+ new_char_count = char_count + part.size
414
+ if new_char_count >= max_char
415
+ part = part[0...(max_char - char_count)]
416
+ end
417
+
418
+ self.subwin.setpos(idx, char_count)
419
+ self.subwin.addstr(part)
420
+
421
+ char_count += part.size
422
+ end
423
+
424
+ end
425
+
426
+ self.subwin.attrset(Curses.color_pair(Wassup::Color::Pair::NORMAL))
427
+ self.subwin.clrtoeol()
329
428
  end
330
429
  self.subwin.refresh
331
430
  end
@@ -387,7 +486,7 @@ module Wassup
387
486
  def scroll_left
388
487
  self.selected_view_index -= 1
389
488
  if self.selected_view_index < 0
390
- self.selected_view_index = self.all_view_data_objects.size - 1
489
+ self.selected_view_index = self.contents.size - 1
391
490
  end
392
491
 
393
492
  self.load_current_view
@@ -395,7 +494,7 @@ module Wassup
395
494
 
396
495
  def scroll_right
397
496
  self.selected_view_index += 1
398
- if self.selected_view_index >= self.all_view_data_objects.size
497
+ if self.selected_view_index >= self.contents.size
399
498
  self.selected_view_index = 0
400
499
  end
401
500
 
@@ -462,10 +561,21 @@ module Wassup
462
561
  self.scroll_right
463
562
  elsif input == "r"
464
563
  self.refresh(force: true)
564
+ elsif input == "c"
565
+ if !self.caught_error.nil?
566
+ text = self.caught_error.backtrace.join("\n")
567
+ if RUBY_PLATFORM.downcase =~ /win32/
568
+ IO.popen('clip', 'w') { |pipe| pipe.puts text }
569
+ else
570
+ IO.popen('pbcopy', 'w') { |pipe| pipe.puts text }
571
+ end
572
+ end
465
573
  else
466
574
  selection_block = self.selection_blocks[input]
467
575
  if !selection_block.nil? && !self.highlighted_line.nil?
468
- data = @data_objects[self.highlighted_line]
576
+ content = self.contents[self.selected_view_index]
577
+ row = content.data[self.highlighted_line]
578
+ data = row.object || row.display
469
579
  selection_block.call(data)
470
580
  end
471
581
  end
@@ -9,10 +9,58 @@ module Wassup
9
9
  attr_accessor :highlight
10
10
 
11
11
  attr_accessor :title
12
+ attr_accessor :description
13
+
14
+ attr_accessor :show_refresh
12
15
 
13
16
  attr_accessor :interval
14
17
  attr_accessor :content_block
15
18
  attr_accessor :selection_blocks
19
+ attr_accessor :selection_blocks_description
20
+
21
+ class ContentBuilder
22
+ attr_accessor :contents
23
+
24
+ def initialize(contents)
25
+ @contents = contents
26
+ @need_to_clear = true
27
+ @show_refresh = true
28
+ end
29
+
30
+ def clear=(clear)
31
+ @need_to_clear = clear
32
+ end
33
+
34
+ def add_row(display, object=nil, page:nil)
35
+ if @need_to_clear
36
+ @need_to_clear = false
37
+ self.contents = []
38
+ end
39
+
40
+ content = nil
41
+
42
+ # Create contents if none
43
+ if page.nil?
44
+ if self.contents.empty?
45
+ content = Pane::Content.new
46
+ self.contents << content
47
+ else
48
+ content = self.contents.first
49
+ end
50
+ elsif page.is_a?(String)
51
+ content = self.contents.find do |content|
52
+ content.title == page
53
+ end
54
+
55
+ if content.nil?
56
+ content = Pane::Content.new(page)
57
+ self.contents << content
58
+ end
59
+ end
60
+
61
+ content.add_row(display, object)
62
+ end
63
+ end
16
64
 
17
65
  def initialize()
18
66
  @height = 1
@@ -24,13 +72,24 @@ module Wassup
24
72
  @interval = 60 * 5
25
73
 
26
74
  @selection_blocks = {}
75
+ @selection_blocks_description = {}
27
76
  end
28
77
 
29
78
  def content(&block)
30
79
  self.content_block = block
31
80
  end
32
- def selection(input=10, &block)
81
+ def selection(input=10, description=nil, &block)
82
+ if input.to_s.downcase == "enter"
83
+ input = 10
84
+ end
85
+
86
+ description_input = input
87
+ if input.to_s == "10"
88
+ description_input = "enter"
89
+ end
90
+
33
91
  self.selection_blocks[input] = block
92
+ self.selection_blocks_description[description_input] = description
34
93
  end
35
94
  end
36
95
  end
@@ -1,3 +1,3 @@
1
1
  module Wassup
2
- VERSION = "0.1.2"
2
+ VERSION = "0.3.1"
3
3
  end
data/lib/wassup.rb CHANGED
@@ -4,6 +4,11 @@ require "wassup/color"
4
4
  require "wassup/pane"
5
5
  require "wassup/pane_builder"
6
6
 
7
+ require "wassup/helpers/circleci"
8
+ require "wassup/helpers/github"
9
+ require "wassup/helpers/netlify"
10
+ require "wassup/helpers/shortcut"
11
+
7
12
  module Wassup
8
13
  class Error < StandardError; end
9
14
  # Your code goes here...
data/wassup.gemspec CHANGED
@@ -16,6 +16,7 @@ Gem::Specification.new do |spec|
16
16
  spec.metadata["source_code_uri"] = "https://github.com/joshdholtz/wassup"
17
17
 
18
18
  spec.add_runtime_dependency 'curses'
19
+ spec.add_runtime_dependency 'rest-client'
19
20
 
20
21
  # Specify which files should be added to the gem when it is released.
21
22
  # The `git ls-files -z` loads the files in the RubyGem that have been added into git.