planter-cli 0.0.4 → 3.0.2

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 (115) hide show
  1. checksums.yaml +4 -4
  2. data/.gitignore +3 -0
  3. data/.gitmodules +3 -0
  4. data/.rubocop.yml +1 -1
  5. data/CHANGELOG.md +31 -0
  6. data/README.md +33 -4
  7. data/Rakefile +52 -16
  8. data/bin/plant +2 -2
  9. data/docker/Dockerfile +2 -4
  10. data/docker/Dockerfile-2.6 +4 -6
  11. data/docker/Dockerfile-2.7 +4 -6
  12. data/docker/Dockerfile-3.0 +4 -5
  13. data/docker/Dockerfile-3.3 +11 -0
  14. data/docker/sources.list +11 -0
  15. data/lib/planter/array.rb +17 -0
  16. data/lib/planter/fileentry.rb +5 -1
  17. data/lib/planter/filelist.rb +13 -4
  18. data/lib/planter/hash.rb +17 -1
  19. data/lib/planter/plant.rb +5 -3
  20. data/lib/planter/prompt.rb +5 -5
  21. data/lib/planter/string.rb +22 -0
  22. data/lib/planter/tag.rb +91 -0
  23. data/lib/planter/version.rb +1 -1
  24. data/lib/planter.rb +34 -18
  25. data/lib/tty-spinner/.editorconfig +9 -0
  26. data/lib/tty-spinner/.github/FUNDING.yml +1 -0
  27. data/lib/tty-spinner/.github/ISSUE_TEMPLATE/BUG_REPORT.md +31 -0
  28. data/lib/tty-spinner/.github/ISSUE_TEMPLATE/FEATURE_REQUEST.md +23 -0
  29. data/lib/tty-spinner/.github/ISSUE_TEMPLATE/config.yml +5 -0
  30. data/lib/tty-spinner/.github/PULL_REQUEST_TEMPLATE.md +19 -0
  31. data/lib/tty-spinner/.github/workflows/ci.yml +59 -0
  32. data/lib/tty-spinner/.gitignore +14 -0
  33. data/lib/tty-spinner/.rspec +2 -0
  34. data/lib/tty-spinner/.rubocop.yml +78 -0
  35. data/lib/tty-spinner/CHANGELOG.md +151 -0
  36. data/lib/tty-spinner/CODE_OF_CONDUCT.md +132 -0
  37. data/lib/tty-spinner/Gemfile +17 -0
  38. data/lib/tty-spinner/LICENSE.txt +22 -0
  39. data/lib/tty-spinner/README.md +581 -0
  40. data/lib/tty-spinner/Rakefile +10 -0
  41. data/lib/tty-spinner/appveyor.yml +33 -0
  42. data/lib/tty-spinner/bin/console +14 -0
  43. data/lib/tty-spinner/bin/setup +8 -0
  44. data/lib/tty-spinner/demo.gif +0 -0
  45. data/lib/tty-spinner/examples/auto_spin.rb +10 -0
  46. data/lib/tty-spinner/examples/basic.rb +10 -0
  47. data/lib/tty-spinner/examples/clear.rb +11 -0
  48. data/lib/tty-spinner/examples/color.rb +14 -0
  49. data/lib/tty-spinner/examples/error.rb +11 -0
  50. data/lib/tty-spinner/examples/formats.rb +13 -0
  51. data/lib/tty-spinner/examples/hide_cursor.rb +14 -0
  52. data/lib/tty-spinner/examples/log.rb +13 -0
  53. data/lib/tty-spinner/examples/multi/basic.rb +15 -0
  54. data/lib/tty-spinner/examples/multi/basic_top_level.rb +15 -0
  55. data/lib/tty-spinner/examples/multi/custom_style.rb +28 -0
  56. data/lib/tty-spinner/examples/multi/files.rb +16 -0
  57. data/lib/tty-spinner/examples/multi/jobs.rb +11 -0
  58. data/lib/tty-spinner/examples/multi/multi.rb +19 -0
  59. data/lib/tty-spinner/examples/multi/multi_top_level.rb +20 -0
  60. data/lib/tty-spinner/examples/multi/pause.rb +28 -0
  61. data/lib/tty-spinner/examples/multi/threaded.rb +30 -0
  62. data/lib/tty-spinner/examples/pause.rb +24 -0
  63. data/lib/tty-spinner/examples/run.rb +20 -0
  64. data/lib/tty-spinner/examples/success.rb +11 -0
  65. data/lib/tty-spinner/examples/threaded.rb +13 -0
  66. data/lib/tty-spinner/examples/update.rb +13 -0
  67. data/lib/tty-spinner/lib/tty/spinner/formats.rb +274 -0
  68. data/lib/tty-spinner/lib/tty/spinner/multi.rb +352 -0
  69. data/lib/tty-spinner/lib/tty/spinner/version.rb +7 -0
  70. data/lib/tty-spinner/lib/tty/spinner.rb +604 -0
  71. data/lib/tty-spinner/lib/tty-spinner.rb +2 -0
  72. data/lib/tty-spinner/spec/spec_helper.rb +52 -0
  73. data/lib/tty-spinner/spec/unit/auto_spin_spec.rb +25 -0
  74. data/lib/tty-spinner/spec/unit/clear_spec.rb +16 -0
  75. data/lib/tty-spinner/spec/unit/error_spec.rb +53 -0
  76. data/lib/tty-spinner/spec/unit/events_spec.rb +35 -0
  77. data/lib/tty-spinner/spec/unit/formats_spec.rb +9 -0
  78. data/lib/tty-spinner/spec/unit/frames_spec.rb +31 -0
  79. data/lib/tty-spinner/spec/unit/hide_cursor_spec.rb +51 -0
  80. data/lib/tty-spinner/spec/unit/job_spec.rb +12 -0
  81. data/lib/tty-spinner/spec/unit/join_spec.rb +10 -0
  82. data/lib/tty-spinner/spec/unit/log_spec.rb +60 -0
  83. data/lib/tty-spinner/spec/unit/multi/auto_spin_spec.rb +32 -0
  84. data/lib/tty-spinner/spec/unit/multi/error_spec.rb +107 -0
  85. data/lib/tty-spinner/spec/unit/multi/line_inset_spec.rb +57 -0
  86. data/lib/tty-spinner/spec/unit/multi/on_spec.rb +11 -0
  87. data/lib/tty-spinner/spec/unit/multi/register_spec.rb +46 -0
  88. data/lib/tty-spinner/spec/unit/multi/spin_spec.rb +101 -0
  89. data/lib/tty-spinner/spec/unit/multi/stop_spec.rb +95 -0
  90. data/lib/tty-spinner/spec/unit/multi/success_spec.rb +108 -0
  91. data/lib/tty-spinner/spec/unit/new_spec.rb +25 -0
  92. data/lib/tty-spinner/spec/unit/pause_spec.rb +43 -0
  93. data/lib/tty-spinner/spec/unit/reset_spec.rb +19 -0
  94. data/lib/tty-spinner/spec/unit/run_spec.rb +30 -0
  95. data/lib/tty-spinner/spec/unit/spin_spec.rb +117 -0
  96. data/lib/tty-spinner/spec/unit/stop_spec.rb +88 -0
  97. data/lib/tty-spinner/spec/unit/success_spec.rb +53 -0
  98. data/lib/tty-spinner/spec/unit/tty_spec.rb +8 -0
  99. data/lib/tty-spinner/spec/unit/update_spec.rb +85 -0
  100. data/lib/tty-spinner/tasks/console.rake +11 -0
  101. data/lib/tty-spinner/tasks/coverage.rake +11 -0
  102. data/lib/tty-spinner/tasks/spec.rake +29 -0
  103. data/lib/tty-spinner/tty-spinner.gemspec +36 -0
  104. data/planter-cli.gemspec +1 -0
  105. data/scripts/runtests.sh +1 -1
  106. data/spec/cli_spec.rb +27 -0
  107. data/spec/planter/hash_spec.rb +27 -0
  108. data/spec/planter_spec.rb +15 -0
  109. data/spec/spec_helper.rb +26 -0
  110. data/spec/templates/test/%%project:snake%%.rtf +10 -0
  111. data/spec/templates/test/Rakefile +6 -0
  112. data/spec/templates/test/_planter.yml +3 -6
  113. data/spec/templates/test/test.rb +5 -0
  114. data/src/_README.md +20 -3
  115. metadata +108 -3
@@ -0,0 +1,352 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "monitor"
4
+ require "forwardable"
5
+
6
+ require_relative "../spinner"
7
+
8
+ module TTY
9
+ class Spinner
10
+ # Used for managing multiple terminal spinners
11
+ #
12
+ # @api public
13
+ class Multi
14
+ include Enumerable
15
+ include MonitorMixin
16
+
17
+ extend Forwardable
18
+
19
+ def_delegators :@spinners, :each, :empty?, :length
20
+
21
+ DEFAULT_INSET = {
22
+ top: Gem.win_platform? ? "+ " : "\u250c ",
23
+ middle: Gem.win_platform? ? "|-- " : "\u251c\u2500\u2500 ",
24
+ bottom: Gem.win_platform? ? "|__ " : "\u2514\u2500\u2500 "
25
+ }.freeze
26
+
27
+ # The current count of all rendered rows
28
+ #
29
+ # @api public
30
+ attr_reader :rows
31
+
32
+ # Initialize a multispinner
33
+ #
34
+ # @example
35
+ # spinner = TTY::Spinner::Multi.new
36
+ #
37
+ # @param [String] message
38
+ # the optional message to print in front of the top level spinner
39
+ #
40
+ # @param [Hash] options
41
+ # @option options [Hash] :style
42
+ # keys :top :middle and :bottom can contain Strings that are used to
43
+ # indent the spinners. Ignored if message is blank
44
+ # @option options [Object] :output
45
+ # the object that responds to print call defaulting to stderr
46
+ # @option options [Boolean] :hide_cursor
47
+ # display or hide cursor
48
+ # @option options [Boolean] :clear
49
+ # clear ouptut when finished
50
+ # @option options [Float] :interval
51
+ # the interval for auto spinning
52
+ #
53
+ # @api public
54
+ def initialize(*args)
55
+ super()
56
+ @options = args.last.is_a?(::Hash) ? args.pop : {}
57
+ message = args.empty? ? nil : args.pop
58
+ @inset_opts = @options.delete(:style) { DEFAULT_INSET }
59
+ @rows = 0
60
+ @spinners = []
61
+ @spinners_count = 0
62
+ @top_spinner = nil
63
+ @last_spin_at = nil
64
+ unless message.nil?
65
+ @top_spinner = register(message, observable: false, row: next_row)
66
+ end
67
+
68
+ @callbacks = {
69
+ success: [],
70
+ error: [],
71
+ done: [],
72
+ spin: []
73
+ }
74
+ end
75
+
76
+ # Register a new spinner
77
+ #
78
+ # @param [String, TTY::Spinner] pattern_or_spinner
79
+ # the pattern used for creating spinner, or a spinner instance
80
+ #
81
+ # @api public
82
+ def register(pattern_or_spinner, **options, &job)
83
+ observable = options.delete(:observable) { true }
84
+ spinner = nil
85
+
86
+ synchronize do
87
+ spinner = create_spinner(pattern_or_spinner, options)
88
+ spinner.attach_to(self)
89
+ spinner.job(&job) if block_given?
90
+ observe(spinner) if observable
91
+ @spinners << spinner
92
+ @spinners_count += 1
93
+ if @top_spinner
94
+ @spinners.each { |sp| sp.redraw_indent if sp.spinning? || sp.done? }
95
+ end
96
+ end
97
+
98
+ spinner
99
+ end
100
+
101
+ # Create a spinner instance
102
+ #
103
+ # @api private
104
+ def create_spinner(pattern_or_spinner, options)
105
+ case pattern_or_spinner
106
+ when ::String
107
+ TTY::Spinner.new(
108
+ pattern_or_spinner,
109
+ @options.merge(options)
110
+ )
111
+ when ::TTY::Spinner
112
+ pattern_or_spinner
113
+ else
114
+ raise ArgumentError, "Expected a pattern or spinner, " \
115
+ "got: #{pattern_or_spinner.class}"
116
+ end
117
+ end
118
+
119
+ # Increase a row count
120
+ #
121
+ # @api public
122
+ def next_row
123
+ synchronize do
124
+ @rows += 1
125
+ end
126
+ end
127
+
128
+ # Get the top level spinner if it exists
129
+ #
130
+ # @return [TTY::Spinner] the top level spinner
131
+ #
132
+ # @api public
133
+ def top_spinner
134
+ raise "No top level spinner" if @top_spinner.nil?
135
+
136
+ @top_spinner
137
+ end
138
+
139
+ # Auto spin the top level spinner & all child spinners
140
+ # that have scheduled jobs
141
+ #
142
+ # @api public
143
+ def auto_spin
144
+ raise "No top level spinner" if @top_spinner.nil?
145
+
146
+ jobs = []
147
+ @spinners.each do |spinner|
148
+ if spinner.job?
149
+ spinner.auto_spin
150
+ jobs << Thread.new { spinner.execute_job }
151
+ end
152
+ end
153
+ jobs.each(&:join)
154
+ end
155
+
156
+ # Perform a single spin animation
157
+ #
158
+ # @api public
159
+ def spin
160
+ raise "No top level spinner" if @top_spinner.nil?
161
+
162
+ synchronize do
163
+ throttle { @top_spinner.spin }
164
+ end
165
+ end
166
+
167
+ # Pause all spinners
168
+ #
169
+ # @api public
170
+ def pause
171
+ @spinners.dup.each(&:pause)
172
+ end
173
+
174
+ # Resume all spinners
175
+ #
176
+ # @api public
177
+ def resume
178
+ @spinners.dup.each(&:resume)
179
+ end
180
+
181
+ # Find the number of characters to move into the line
182
+ # before printing the spinner
183
+ #
184
+ # @param [Integer] line_no
185
+ # the current spinner line number for which line inset is calculated
186
+ #
187
+ # @return [String]
188
+ # the inset
189
+ #
190
+ # @api public
191
+ def line_inset(line_no)
192
+ return "" if @top_spinner.nil?
193
+
194
+ if line_no == 1
195
+ @inset_opts[:top]
196
+ elsif line_no == @spinners_count
197
+ @inset_opts[:bottom]
198
+ else
199
+ @inset_opts[:middle]
200
+ end
201
+ end
202
+
203
+ # Check if all spinners are done
204
+ #
205
+ # @return [Boolean]
206
+ #
207
+ # @api public
208
+ def done?
209
+ synchronize do
210
+ (@spinners - [@top_spinner]).all?(&:done?)
211
+ end
212
+ end
213
+
214
+ # Check if all spinners succeeded
215
+ #
216
+ # @return [Boolean]
217
+ #
218
+ # @api public
219
+ def success?
220
+ synchronize do
221
+ (@spinners - [@top_spinner]).all?(&:success?)
222
+ end
223
+ end
224
+
225
+ # Check if any spinner errored
226
+ #
227
+ # @return [Boolean]
228
+ #
229
+ # @api public
230
+ def error?
231
+ synchronize do
232
+ (@spinners - [@top_spinner]).any?(&:error?)
233
+ end
234
+ end
235
+
236
+ # Stop all spinners
237
+ #
238
+ # @api public
239
+ def stop
240
+ @spinners.dup.each(&:stop)
241
+ end
242
+
243
+ # Stop all spinners with success status
244
+ #
245
+ # @api public
246
+ def success
247
+ @spinners.dup.each(&:success)
248
+ end
249
+
250
+ # Stop all spinners with error status
251
+ #
252
+ # @api public
253
+ def error
254
+ @spinners.dup.each(&:error)
255
+ end
256
+
257
+ # Listen on event
258
+ #
259
+ # @api public
260
+ def on(key, &callback)
261
+ unless @callbacks.key?(key)
262
+ raise ArgumentError, "The event #{key} does not exist. " \
263
+ " Use :spin, :success, :error, or :done instead"
264
+ end
265
+ @callbacks[key] << callback
266
+ self
267
+ end
268
+
269
+ private
270
+
271
+ # Check if this spinner should revolve to keep constant speed
272
+ # matching top spinner interval
273
+ #
274
+ # @api private
275
+ def throttle
276
+ sleep_time = 1.0 / @top_spinner.interval
277
+ return if @last_spin_at && Time.now - @last_spin_at < sleep_time
278
+
279
+ yield if block_given?
280
+ @last_spin_at = Time.now
281
+ end
282
+
283
+ # Fire an event
284
+ #
285
+ # @api private
286
+ def emit(key, *args)
287
+ @callbacks[key].each do |block|
288
+ block.call(*args)
289
+ end
290
+ end
291
+
292
+ # Observe spinner for events to notify top spinner of current state
293
+ #
294
+ # @param [TTY::Spinner] spinner
295
+ # the spinner to listen to for events
296
+ #
297
+ # @api private
298
+ def observe(spinner)
299
+ spinner.on(:spin, &spin_handler)
300
+ .on(:success, &success_handler)
301
+ .on(:error, &error_handler)
302
+ .on(:done, &done_handler)
303
+ end
304
+
305
+ # Handle spin event
306
+ #
307
+ # @api private
308
+ def spin_handler
309
+ proc do
310
+ spin if @top_spinner
311
+ emit(:spin)
312
+ end
313
+ end
314
+
315
+ # Handle the success state
316
+ #
317
+ # @api private
318
+ def success_handler
319
+ proc do
320
+ if success?
321
+ @top_spinner.success if @top_spinner
322
+ emit(:success)
323
+ end
324
+ end
325
+ end
326
+
327
+ # Handle the error state
328
+ #
329
+ # @api private
330
+ def error_handler
331
+ proc do
332
+ if error?
333
+ @top_spinner.error if @top_spinner
334
+ @fired ||= emit(:error) # fire once
335
+ end
336
+ end
337
+ end
338
+
339
+ # Handle the done state
340
+ #
341
+ # @api private
342
+ def done_handler
343
+ proc do
344
+ if done?
345
+ @top_spinner.stop if @top_spinner && !error? && !success?
346
+ emit(:done)
347
+ end
348
+ end
349
+ end
350
+ end # MultiSpinner
351
+ end # Spinner
352
+ end # TTY
@@ -0,0 +1,7 @@
1
+ # frozen_string_literal: true
2
+
3
+ module TTY
4
+ class Spinner
5
+ VERSION = "0.9.3"
6
+ end # Spinner
7
+ end # TTY