fluid_cli 0.1.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 (329) hide show
  1. checksums.yaml +7 -0
  2. data/README.md +1 -0
  3. data/dev.yml +5 -0
  4. data/exe/fluid +24 -0
  5. data/lib/fluid_cli/api.rb +135 -0
  6. data/lib/fluid_cli/assets/post_auth_page/index.html.erb +34 -0
  7. data/lib/fluid_cli/assets/post_auth_page/style.css +58 -0
  8. data/lib/fluid_cli/command.rb +55 -0
  9. data/lib/fluid_cli/commands/help.rb +21 -0
  10. data/lib/fluid_cli/commands/login.rb +30 -0
  11. data/lib/fluid_cli/commands/logout.rb +38 -0
  12. data/lib/fluid_cli/commands/switch.rb +23 -0
  13. data/lib/fluid_cli/commands/theme/common/company_helper.rb +15 -0
  14. data/lib/fluid_cli/commands/theme/common/root_helper.rb +95 -0
  15. data/lib/fluid_cli/commands/theme/dev.rb +61 -0
  16. data/lib/fluid_cli/commands/theme/help.rb +21 -0
  17. data/lib/fluid_cli/commands/theme/init.rb +46 -0
  18. data/lib/fluid_cli/commands/theme/pull.rb +68 -0
  19. data/lib/fluid_cli/commands/theme/push.rb +132 -0
  20. data/lib/fluid_cli/commands/theme.rb +23 -0
  21. data/lib/fluid_cli/commands/whoami.rb +23 -0
  22. data/lib/fluid_cli/commands.rb +19 -0
  23. data/lib/fluid_cli/company_switcher.rb +69 -0
  24. data/lib/fluid_cli/context.rb +691 -0
  25. data/lib/fluid_cli/db.rb +114 -0
  26. data/lib/fluid_cli/entry_point.rb +10 -0
  27. data/lib/fluid_cli/environment.rb +32 -0
  28. data/lib/fluid_cli/file_system_listener.rb +29 -0
  29. data/lib/fluid_cli/form.rb +42 -0
  30. data/lib/fluid_cli/git.rb +319 -0
  31. data/lib/fluid_cli/http_request.rb +54 -0
  32. data/lib/fluid_cli/identity_auth/servlet.rb +39 -0
  33. data/lib/fluid_cli/identity_auth.rb +126 -0
  34. data/lib/fluid_cli/options.rb +38 -0
  35. data/lib/fluid_cli/theme/dev_server/certificate_manager.rb +79 -0
  36. data/lib/fluid_cli/theme/dev_server/errors.rb +9 -0
  37. data/lib/fluid_cli/theme/dev_server/header_hash.rb +98 -0
  38. data/lib/fluid_cli/theme/dev_server/hooks/file_change_hook.rb +39 -0
  39. data/lib/fluid_cli/theme/dev_server/hot_reload/resources/hot-reload-no-script.html +27 -0
  40. data/lib/fluid_cli/theme/dev_server/hot_reload/resources/hot_reload.js +28 -0
  41. data/lib/fluid_cli/theme/dev_server/hot_reload/resources/sse_client.js +43 -0
  42. data/lib/fluid_cli/theme/dev_server/hot_reload/resources/theme.js +16 -0
  43. data/lib/fluid_cli/theme/dev_server/hot_reload/script_injector.rb +54 -0
  44. data/lib/fluid_cli/theme/dev_server/hot_reload.rb +75 -0
  45. data/lib/fluid_cli/theme/dev_server/local_assets.rb +92 -0
  46. data/lib/fluid_cli/theme/dev_server/proxy.rb +235 -0
  47. data/lib/fluid_cli/theme/dev_server/proxy_param_builder.rb +82 -0
  48. data/lib/fluid_cli/theme/dev_server/reload_mode.rb +34 -0
  49. data/lib/fluid_cli/theme/dev_server/sse.rb +75 -0
  50. data/lib/fluid_cli/theme/dev_server/watcher.rb +57 -0
  51. data/lib/fluid_cli/theme/dev_server/web_server.rb +140 -0
  52. data/lib/fluid_cli/theme/dev_server.rb +289 -0
  53. data/lib/fluid_cli/theme/development_theme.rb +101 -0
  54. data/lib/fluid_cli/theme/file.rb +105 -0
  55. data/lib/fluid_cli/theme/forms/select.rb +33 -0
  56. data/lib/fluid_cli/theme/mime_type.rb +34 -0
  57. data/lib/fluid_cli/theme/presenters/theme_presenter.rb +49 -0
  58. data/lib/fluid_cli/theme/presenters/themes_presenter.rb +31 -0
  59. data/lib/fluid_cli/theme/root.rb +62 -0
  60. data/lib/fluid_cli/theme/syncer/checksums.rb +66 -0
  61. data/lib/fluid_cli/theme/syncer/downloader.rb +54 -0
  62. data/lib/fluid_cli/theme/syncer/error_reporter.rb +45 -0
  63. data/lib/fluid_cli/theme/syncer/merger.rb +53 -0
  64. data/lib/fluid_cli/theme/syncer/operation.rb +58 -0
  65. data/lib/fluid_cli/theme/syncer/standard_reporter.rb +32 -0
  66. data/lib/fluid_cli/theme/syncer/unsupported_script_warning.rb +90 -0
  67. data/lib/fluid_cli/theme/syncer/uploader/forms/apply_to_all.rb +41 -0
  68. data/lib/fluid_cli/theme/syncer/uploader/forms/apply_to_all_form.rb +37 -0
  69. data/lib/fluid_cli/theme/syncer/uploader/forms/base_strategy_form.rb +64 -0
  70. data/lib/fluid_cli/theme/syncer/uploader/forms/select_delete_strategy.rb +29 -0
  71. data/lib/fluid_cli/theme/syncer/uploader/forms/select_update_strategy.rb +30 -0
  72. data/lib/fluid_cli/theme/syncer/uploader/json_delete_handler.rb +49 -0
  73. data/lib/fluid_cli/theme/syncer/uploader/json_update_handler.rb +71 -0
  74. data/lib/fluid_cli/theme/syncer/uploader.rb +105 -0
  75. data/lib/fluid_cli/theme/syncer.rb +412 -0
  76. data/lib/fluid_cli/theme/theme.rb +186 -0
  77. data/lib/fluid_cli/theme/ui/sync_progress_bar.rb +22 -0
  78. data/lib/fluid_cli/thread_pool/job.rb +35 -0
  79. data/lib/fluid_cli/thread_pool.rb +49 -0
  80. data/lib/fluid_cli/version.rb +3 -0
  81. data/lib/fluid_cli.rb +59 -0
  82. data/vendor/deps/base64/.document +5 -0
  83. data/vendor/deps/base64/.gitignore +9 -0
  84. data/vendor/deps/base64/BSDL +22 -0
  85. data/vendor/deps/base64/COPYING +56 -0
  86. data/vendor/deps/base64/Gemfile +9 -0
  87. data/vendor/deps/base64/LEGAL +60 -0
  88. data/vendor/deps/base64/README.md +48 -0
  89. data/vendor/deps/base64/Rakefile +31 -0
  90. data/vendor/deps/base64/base64.gemspec +28 -0
  91. data/vendor/deps/base64/bin/console +14 -0
  92. data/vendor/deps/base64/bin/setup +8 -0
  93. data/vendor/deps/base64/lib/base64.rb +382 -0
  94. data/vendor/deps/base64/sig/base64.rbs +358 -0
  95. data/vendor/deps/base64/test/base64/test_base64.rb +115 -0
  96. data/vendor/deps/base64/test_sig/test_base64.rb +44 -0
  97. data/vendor/deps/cli-kit/REVISION +1 -0
  98. data/vendor/deps/cli-kit/lib/cli/kit/args/definition.rb +286 -0
  99. data/vendor/deps/cli-kit/lib/cli/kit/args/evaluation.rb +215 -0
  100. data/vendor/deps/cli-kit/lib/cli/kit/args/parser/node.rb +128 -0
  101. data/vendor/deps/cli-kit/lib/cli/kit/args/parser.rb +125 -0
  102. data/vendor/deps/cli-kit/lib/cli/kit/args/tokenizer.rb +130 -0
  103. data/vendor/deps/cli-kit/lib/cli/kit/args.rb +16 -0
  104. data/vendor/deps/cli-kit/lib/cli/kit/base_command.rb +30 -0
  105. data/vendor/deps/cli-kit/lib/cli/kit/command_help.rb +268 -0
  106. data/vendor/deps/cli-kit/lib/cli/kit/command_registry.rb +150 -0
  107. data/vendor/deps/cli-kit/lib/cli/kit/config.rb +137 -0
  108. data/vendor/deps/cli-kit/lib/cli/kit/core_ext.rb +28 -0
  109. data/vendor/deps/cli-kit/lib/cli/kit/error_handler.rb +166 -0
  110. data/vendor/deps/cli-kit/lib/cli/kit/executor.rb +92 -0
  111. data/vendor/deps/cli-kit/lib/cli/kit/ini.rb +91 -0
  112. data/vendor/deps/cli-kit/lib/cli/kit/levenshtein.rb +92 -0
  113. data/vendor/deps/cli-kit/lib/cli/kit/logger.rb +94 -0
  114. data/vendor/deps/cli-kit/lib/cli/kit/opts.rb +248 -0
  115. data/vendor/deps/cli-kit/lib/cli/kit/parse_args.rb +55 -0
  116. data/vendor/deps/cli-kit/lib/cli/kit/resolver.rb +66 -0
  117. data/vendor/deps/cli-kit/lib/cli/kit/support/test_helper.rb +260 -0
  118. data/vendor/deps/cli-kit/lib/cli/kit/support.rb +11 -0
  119. data/vendor/deps/cli-kit/lib/cli/kit/system.rb +290 -0
  120. data/vendor/deps/cli-kit/lib/cli/kit/util.rb +118 -0
  121. data/vendor/deps/cli-kit/lib/cli/kit/version.rb +7 -0
  122. data/vendor/deps/cli-kit/lib/cli/kit.rb +139 -0
  123. data/vendor/deps/cli-ui/REVISION +1 -0
  124. data/vendor/deps/cli-ui/lib/cli/ui/ansi.rb +218 -0
  125. data/vendor/deps/cli-ui/lib/cli/ui/color.rb +101 -0
  126. data/vendor/deps/cli-ui/lib/cli/ui/formatter.rb +219 -0
  127. data/vendor/deps/cli-ui/lib/cli/ui/frame/frame_stack.rb +67 -0
  128. data/vendor/deps/cli-ui/lib/cli/ui/frame/frame_style/box.rb +179 -0
  129. data/vendor/deps/cli-ui/lib/cli/ui/frame/frame_style/bracket.rb +152 -0
  130. data/vendor/deps/cli-ui/lib/cli/ui/frame/frame_style.rb +127 -0
  131. data/vendor/deps/cli-ui/lib/cli/ui/frame.rb +286 -0
  132. data/vendor/deps/cli-ui/lib/cli/ui/glyph.rb +92 -0
  133. data/vendor/deps/cli-ui/lib/cli/ui/os.rb +63 -0
  134. data/vendor/deps/cli-ui/lib/cli/ui/printer.rb +64 -0
  135. data/vendor/deps/cli-ui/lib/cli/ui/progress.rb +132 -0
  136. data/vendor/deps/cli-ui/lib/cli/ui/progress_reporter.rb +209 -0
  137. data/vendor/deps/cli-ui/lib/cli/ui/prompt/interactive_options.rb +583 -0
  138. data/vendor/deps/cli-ui/lib/cli/ui/prompt/options_handler.rb +36 -0
  139. data/vendor/deps/cli-ui/lib/cli/ui/prompt.rb +381 -0
  140. data/vendor/deps/cli-ui/lib/cli/ui/spinner/async.rb +48 -0
  141. data/vendor/deps/cli-ui/lib/cli/ui/spinner/spin_group.rb +602 -0
  142. data/vendor/deps/cli-ui/lib/cli/ui/spinner.rb +79 -0
  143. data/vendor/deps/cli-ui/lib/cli/ui/stdout_router.rb +399 -0
  144. data/vendor/deps/cli-ui/lib/cli/ui/table.rb +83 -0
  145. data/vendor/deps/cli-ui/lib/cli/ui/terminal.rb +55 -0
  146. data/vendor/deps/cli-ui/lib/cli/ui/truncater.rb +106 -0
  147. data/vendor/deps/cli-ui/lib/cli/ui/version.rb +8 -0
  148. data/vendor/deps/cli-ui/lib/cli/ui/widgets/base.rb +46 -0
  149. data/vendor/deps/cli-ui/lib/cli/ui/widgets/status.rb +79 -0
  150. data/vendor/deps/cli-ui/lib/cli/ui/widgets.rb +89 -0
  151. data/vendor/deps/cli-ui/lib/cli/ui/work_queue.rb +142 -0
  152. data/vendor/deps/cli-ui/lib/cli/ui/wrap.rb +61 -0
  153. data/vendor/deps/cli-ui/lib/cli/ui.rb +359 -0
  154. data/vendor/deps/cli-ui/vendor/reentrant_mutex.rb +78 -0
  155. data/vendor/deps/debug/CONTRIBUTING.md +573 -0
  156. data/vendor/deps/debug/Gemfile +10 -0
  157. data/vendor/deps/debug/LICENSE.txt +22 -0
  158. data/vendor/deps/debug/README.md +996 -0
  159. data/vendor/deps/debug/Rakefile +57 -0
  160. data/vendor/deps/debug/TODO.md +23 -0
  161. data/vendor/deps/debug/debug.gemspec +33 -0
  162. data/vendor/deps/debug/exe/rdbg +53 -0
  163. data/vendor/deps/debug/ext/debug/Makefile +273 -0
  164. data/vendor/deps/debug/ext/debug/debug.c +228 -0
  165. data/vendor/deps/debug/ext/debug/debug_version.h +1 -0
  166. data/vendor/deps/debug/ext/debug/extconf.rb +27 -0
  167. data/vendor/deps/debug/ext/debug/iseq_collector.c +93 -0
  168. data/vendor/deps/debug/lib/debug/abbrev_command.rb +77 -0
  169. data/vendor/deps/debug/lib/debug/breakpoint.rb +556 -0
  170. data/vendor/deps/debug/lib/debug/client.rb +263 -0
  171. data/vendor/deps/debug/lib/debug/color.rb +123 -0
  172. data/vendor/deps/debug/lib/debug/config.rb +592 -0
  173. data/vendor/deps/debug/lib/debug/console.rb +224 -0
  174. data/vendor/deps/debug/lib/debug/dap_custom/traceInspector.rb +336 -0
  175. data/vendor/deps/debug/lib/debug/debug.bundle +0 -0
  176. data/vendor/deps/debug/lib/debug/frame_info.rb +190 -0
  177. data/vendor/deps/debug/lib/debug/irb_integration.rb +37 -0
  178. data/vendor/deps/debug/lib/debug/local.rb +115 -0
  179. data/vendor/deps/debug/lib/debug/open.rb +13 -0
  180. data/vendor/deps/debug/lib/debug/open_nonstop.rb +15 -0
  181. data/vendor/deps/debug/lib/debug/prelude.rb +50 -0
  182. data/vendor/deps/debug/lib/debug/server.rb +534 -0
  183. data/vendor/deps/debug/lib/debug/server_cdp.rb +1348 -0
  184. data/vendor/deps/debug/lib/debug/server_dap.rb +1108 -0
  185. data/vendor/deps/debug/lib/debug/session.rb +2667 -0
  186. data/vendor/deps/debug/lib/debug/source_repository.rb +150 -0
  187. data/vendor/deps/debug/lib/debug/start.rb +5 -0
  188. data/vendor/deps/debug/lib/debug/thread_client.rb +1457 -0
  189. data/vendor/deps/debug/lib/debug/tracer.rb +241 -0
  190. data/vendor/deps/debug/lib/debug/version.rb +5 -0
  191. data/vendor/deps/debug/lib/debug.rb +9 -0
  192. data/vendor/deps/debug/misc/README.md.erb +660 -0
  193. data/vendor/deps/listen/.github/release-drafter.yml +17 -0
  194. data/vendor/deps/listen/.github/workflows/development.yml +67 -0
  195. data/vendor/deps/listen/.github/workflows/push.yml +12 -0
  196. data/vendor/deps/listen/.gitignore +28 -0
  197. data/vendor/deps/listen/.rspec +3 -0
  198. data/vendor/deps/listen/.rubocop.yml +283 -0
  199. data/vendor/deps/listen/.yardopts +11 -0
  200. data/vendor/deps/listen/CHANGELOG.md +1 -0
  201. data/vendor/deps/listen/CONTRIBUTING.md +45 -0
  202. data/vendor/deps/listen/Gemfile +33 -0
  203. data/vendor/deps/listen/Guardfile +26 -0
  204. data/vendor/deps/listen/LICENSE.txt +22 -0
  205. data/vendor/deps/listen/README.md +490 -0
  206. data/vendor/deps/listen/Rakefile +154 -0
  207. data/vendor/deps/listen/bin/listen +11 -0
  208. data/vendor/deps/listen/lib/listen/adapter/base.rb +129 -0
  209. data/vendor/deps/listen/lib/listen/adapter/bsd.rb +104 -0
  210. data/vendor/deps/listen/lib/listen/adapter/config.rb +31 -0
  211. data/vendor/deps/listen/lib/listen/adapter/darwin.rb +77 -0
  212. data/vendor/deps/listen/lib/listen/adapter/linux.rb +108 -0
  213. data/vendor/deps/listen/lib/listen/adapter/polling.rb +40 -0
  214. data/vendor/deps/listen/lib/listen/adapter/windows.rb +96 -0
  215. data/vendor/deps/listen/lib/listen/adapter.rb +43 -0
  216. data/vendor/deps/listen/lib/listen/backend.rb +40 -0
  217. data/vendor/deps/listen/lib/listen/change.rb +69 -0
  218. data/vendor/deps/listen/lib/listen/cli.rb +65 -0
  219. data/vendor/deps/listen/lib/listen/directory.rb +93 -0
  220. data/vendor/deps/listen/lib/listen/error.rb +11 -0
  221. data/vendor/deps/listen/lib/listen/event/config.rb +39 -0
  222. data/vendor/deps/listen/lib/listen/event/loop.rb +92 -0
  223. data/vendor/deps/listen/lib/listen/event/processor.rb +128 -0
  224. data/vendor/deps/listen/lib/listen/event/queue.rb +52 -0
  225. data/vendor/deps/listen/lib/listen/file.rb +95 -0
  226. data/vendor/deps/listen/lib/listen/fsm.rb +131 -0
  227. data/vendor/deps/listen/lib/listen/listener/config.rb +41 -0
  228. data/vendor/deps/listen/lib/listen/listener.rb +136 -0
  229. data/vendor/deps/listen/lib/listen/logger.rb +65 -0
  230. data/vendor/deps/listen/lib/listen/monotonic_time.rb +27 -0
  231. data/vendor/deps/listen/lib/listen/options.rb +24 -0
  232. data/vendor/deps/listen/lib/listen/queue_optimizer.rb +129 -0
  233. data/vendor/deps/listen/lib/listen/record/entry.rb +66 -0
  234. data/vendor/deps/listen/lib/listen/record/symlink_detector.rb +47 -0
  235. data/vendor/deps/listen/lib/listen/record.rb +122 -0
  236. data/vendor/deps/listen/lib/listen/silencer/controller.rb +50 -0
  237. data/vendor/deps/listen/lib/listen/silencer.rb +106 -0
  238. data/vendor/deps/listen/lib/listen/thread.rb +54 -0
  239. data/vendor/deps/listen/lib/listen/version.rb +5 -0
  240. data/vendor/deps/listen/lib/listen.rb +47 -0
  241. data/vendor/deps/listen/listen.gemspec +40 -0
  242. data/vendor/deps/listen/spec/acceptance/listen_spec.rb +320 -0
  243. data/vendor/deps/listen/spec/lib/listen/adapter/base_spec.rb +101 -0
  244. data/vendor/deps/listen/spec/lib/listen/adapter/bsd_spec.rb +13 -0
  245. data/vendor/deps/listen/spec/lib/listen/adapter/config_spec.rb +122 -0
  246. data/vendor/deps/listen/spec/lib/listen/adapter/darwin_spec.rb +82 -0
  247. data/vendor/deps/listen/spec/lib/listen/adapter/linux_spec.rb +199 -0
  248. data/vendor/deps/listen/spec/lib/listen/adapter/polling_spec.rb +83 -0
  249. data/vendor/deps/listen/spec/lib/listen/adapter/windows_spec.rb +13 -0
  250. data/vendor/deps/listen/spec/lib/listen/adapter_spec.rb +69 -0
  251. data/vendor/deps/listen/spec/lib/listen/backend_spec.rb +82 -0
  252. data/vendor/deps/listen/spec/lib/listen/change_spec.rb +102 -0
  253. data/vendor/deps/listen/spec/lib/listen/cli_spec.rb +116 -0
  254. data/vendor/deps/listen/spec/lib/listen/directory_spec.rb +284 -0
  255. data/vendor/deps/listen/spec/lib/listen/event/config_spec.rb +33 -0
  256. data/vendor/deps/listen/spec/lib/listen/event/loop_spec.rb +118 -0
  257. data/vendor/deps/listen/spec/lib/listen/event/processor_spec.rb +250 -0
  258. data/vendor/deps/listen/spec/lib/listen/event/queue_spec.rb +118 -0
  259. data/vendor/deps/listen/spec/lib/listen/file_spec.rb +254 -0
  260. data/vendor/deps/listen/spec/lib/listen/fsm_spec.rb +147 -0
  261. data/vendor/deps/listen/spec/lib/listen/listener/config_spec.rb +29 -0
  262. data/vendor/deps/listen/spec/lib/listen/listener_spec.rb +321 -0
  263. data/vendor/deps/listen/spec/lib/listen/logger_spec.rb +212 -0
  264. data/vendor/deps/listen/spec/lib/listen/monotonic_time_spec.rb +58 -0
  265. data/vendor/deps/listen/spec/lib/listen/queue_optimizer_spec.rb +111 -0
  266. data/vendor/deps/listen/spec/lib/listen/record_spec.rb +424 -0
  267. data/vendor/deps/listen/spec/lib/listen/silencer/controller_spec.rb +97 -0
  268. data/vendor/deps/listen/spec/lib/listen/silencer_spec.rb +109 -0
  269. data/vendor/deps/listen/spec/lib/listen/thread_spec.rb +133 -0
  270. data/vendor/deps/listen/spec/lib/listen_spec.rb +25 -0
  271. data/vendor/deps/listen/spec/spec_helper.rb +49 -0
  272. data/vendor/deps/listen/spec/support/acceptance_helper.rb +260 -0
  273. data/vendor/deps/listen/spec/support/fixtures_helper.rb +32 -0
  274. data/vendor/deps/listen/spec/support/platform_helper.rb +17 -0
  275. data/vendor/deps/observer/.github/dependabot.yml +6 -0
  276. data/vendor/deps/observer/.github/workflows/test.yml +33 -0
  277. data/vendor/deps/observer/.gitignore +8 -0
  278. data/vendor/deps/observer/BSDL +22 -0
  279. data/vendor/deps/observer/COPYING +56 -0
  280. data/vendor/deps/observer/Gemfile +9 -0
  281. data/vendor/deps/observer/README.md +139 -0
  282. data/vendor/deps/observer/Rakefile +10 -0
  283. data/vendor/deps/observer/bin/console +14 -0
  284. data/vendor/deps/observer/bin/setup +8 -0
  285. data/vendor/deps/observer/lib/observer.rb +229 -0
  286. data/vendor/deps/observer/observer.gemspec +32 -0
  287. data/vendor/deps/observer/test/test_observer.rb +66 -0
  288. data/vendor/deps/webrick/.gitignore +9 -0
  289. data/vendor/deps/webrick/Gemfile +3 -0
  290. data/vendor/deps/webrick/LICENSE.txt +22 -0
  291. data/vendor/deps/webrick/README.md +61 -0
  292. data/vendor/deps/webrick/Rakefile +10 -0
  293. data/vendor/deps/webrick/lib/webrick/accesslog.rb +157 -0
  294. data/vendor/deps/webrick/lib/webrick/cgi.rb +313 -0
  295. data/vendor/deps/webrick/lib/webrick/compat.rb +36 -0
  296. data/vendor/deps/webrick/lib/webrick/config.rb +158 -0
  297. data/vendor/deps/webrick/lib/webrick/cookie.rb +172 -0
  298. data/vendor/deps/webrick/lib/webrick/htmlutils.rb +30 -0
  299. data/vendor/deps/webrick/lib/webrick/httpauth/authenticator.rb +117 -0
  300. data/vendor/deps/webrick/lib/webrick/httpauth/basicauth.rb +116 -0
  301. data/vendor/deps/webrick/lib/webrick/httpauth/digestauth.rb +395 -0
  302. data/vendor/deps/webrick/lib/webrick/httpauth/htdigest.rb +132 -0
  303. data/vendor/deps/webrick/lib/webrick/httpauth/htgroup.rb +97 -0
  304. data/vendor/deps/webrick/lib/webrick/httpauth/htpasswd.rb +158 -0
  305. data/vendor/deps/webrick/lib/webrick/httpauth/userdb.rb +53 -0
  306. data/vendor/deps/webrick/lib/webrick/httpauth.rb +96 -0
  307. data/vendor/deps/webrick/lib/webrick/httpproxy.rb +354 -0
  308. data/vendor/deps/webrick/lib/webrick/httprequest.rb +636 -0
  309. data/vendor/deps/webrick/lib/webrick/httpresponse.rb +564 -0
  310. data/vendor/deps/webrick/lib/webrick/https.rb +152 -0
  311. data/vendor/deps/webrick/lib/webrick/httpserver.rb +294 -0
  312. data/vendor/deps/webrick/lib/webrick/httpservlet/abstract.rb +152 -0
  313. data/vendor/deps/webrick/lib/webrick/httpservlet/cgi_runner.rb +47 -0
  314. data/vendor/deps/webrick/lib/webrick/httpservlet/cgihandler.rb +126 -0
  315. data/vendor/deps/webrick/lib/webrick/httpservlet/erbhandler.rb +88 -0
  316. data/vendor/deps/webrick/lib/webrick/httpservlet/filehandler.rb +552 -0
  317. data/vendor/deps/webrick/lib/webrick/httpservlet/prochandler.rb +47 -0
  318. data/vendor/deps/webrick/lib/webrick/httpservlet.rb +23 -0
  319. data/vendor/deps/webrick/lib/webrick/httpstatus.rb +194 -0
  320. data/vendor/deps/webrick/lib/webrick/httputils.rb +512 -0
  321. data/vendor/deps/webrick/lib/webrick/httpversion.rb +76 -0
  322. data/vendor/deps/webrick/lib/webrick/log.rb +156 -0
  323. data/vendor/deps/webrick/lib/webrick/server.rb +381 -0
  324. data/vendor/deps/webrick/lib/webrick/ssl.rb +215 -0
  325. data/vendor/deps/webrick/lib/webrick/utils.rb +265 -0
  326. data/vendor/deps/webrick/lib/webrick/version.rb +18 -0
  327. data/vendor/deps/webrick/lib/webrick.rb +232 -0
  328. data/vendor/deps/webrick/webrick.gemspec +74 -0
  329. metadata +412 -0
@@ -0,0 +1,602 @@
1
+ # typed: true
2
+ # frozen_string_literal: true
3
+
4
+ require_relative '../work_queue'
5
+
6
+ module CLI
7
+ module UI
8
+ module Spinner
9
+ class SpinGroup
10
+ DEFAULT_FINAL_GLYPH = ->(success) { success ? CLI::UI::Glyph::CHECK : CLI::UI::Glyph::X }
11
+
12
+ class << self
13
+ #: Mutex
14
+ attr_reader :pause_mutex
15
+
16
+ #: -> bool
17
+ def paused?
18
+ @paused
19
+ end
20
+
21
+ #: [T] { -> T } -> T
22
+ def pause_spinners(&block)
23
+ previous_paused = nil #: bool?
24
+ @pause_mutex.synchronize do
25
+ previous_paused = @paused
26
+ @paused = true
27
+ end
28
+ block.call
29
+ ensure
30
+ @pause_mutex.synchronize do
31
+ @paused = previous_paused
32
+ end
33
+ end
34
+ end
35
+
36
+ @pause_mutex = Mutex.new
37
+ @paused = false
38
+
39
+ # Initializes a new spin group
40
+ # This lets you add +Task+ objects to the group to multi-thread work
41
+ #
42
+ # ==== Options
43
+ #
44
+ # * +:auto_debrief+ - Automatically debrief exceptions or through success_debrief? Default to true
45
+ # * +:interrupt_debrief+ - Automatically debrief on interrupt. Default to false
46
+ # * +:max_concurrent+ - Maximum number of concurrent tasks. Default is 0 (effectively unlimited)
47
+ # * +:work_queue+ - Custom WorkQueue instance. If not provided, a new one will be created
48
+ # * +:to+ - Target stream, like $stdout or $stderr. Can be anything with print and puts methods,
49
+ # or under Sorbet, IO or StringIO. Defaults to $stdout
50
+ #
51
+ # ==== Example Usage
52
+ #
53
+ # CLI::UI::SpinGroup.new do |spin_group|
54
+ # spin_group.add('Title') { |spinner| sleep 3.0 }
55
+ # spin_group.add('Title 2') { |spinner| sleep 3.0; spinner.update_title('New Title'); sleep 3.0 }
56
+ # end
57
+ #
58
+ # Output:
59
+ #
60
+ # https://user-images.githubusercontent.com/3074765/33798558-c452fa26-dce8-11e7-9e90-b4b34df21a46.gif
61
+ #
62
+ #: (?auto_debrief: bool, ?interrupt_debrief: bool, ?max_concurrent: Integer, ?work_queue: WorkQueue?, ?to: io_like) -> void
63
+ def initialize(auto_debrief: true, interrupt_debrief: false, max_concurrent: 0, work_queue: nil, to: $stdout)
64
+ @m = Mutex.new
65
+ @tasks = []
66
+ @puts_above = []
67
+ @auto_debrief = auto_debrief
68
+ @interrupt_debrief = interrupt_debrief
69
+ @start = Time.new
70
+ @stopped = false
71
+ @internal_work_queue = work_queue.nil?
72
+ @work_queue = work_queue || WorkQueue.new(max_concurrent.zero? ? 1024 : max_concurrent) #: WorkQueue
73
+ if block_given?
74
+ yield self
75
+ wait(to: to)
76
+ end
77
+ end
78
+
79
+ class Task
80
+ #: String
81
+ attr_reader :title, :stdout, :stderr
82
+
83
+ #: bool
84
+ attr_reader :success
85
+
86
+ #: bool
87
+ attr_reader :done
88
+
89
+ #: Exception?
90
+ attr_reader :exception
91
+
92
+ #: Integer?
93
+ attr_reader :progress_percentage
94
+
95
+ # Initializes a new Task
96
+ # This is managed entirely internally by +SpinGroup+
97
+ #
98
+ # ==== Attributes
99
+ #
100
+ # * +title+ - Title of the task
101
+ # * +block+ - Block for the task, will be provided with an instance of the spinner
102
+ #
103
+ #: (String title, final_glyph: ^(bool success) -> (Glyph | String), merged_output: bool, duplicate_output_to: IO, work_queue: WorkQueue) { (Task task) -> untyped } -> void
104
+ def initialize(title, final_glyph:, merged_output:, duplicate_output_to:, work_queue:, &block)
105
+ @title = title
106
+ @final_glyph = final_glyph
107
+ @always_full_render = title =~ Formatter::SCAN_WIDGET
108
+ @future = work_queue.enqueue do
109
+ cap = CLI::UI::StdoutRouter::Capture.new(
110
+ merged_output: merged_output, duplicate_output_to: duplicate_output_to,
111
+ ) { block.call(self) }
112
+ begin
113
+ cap.run
114
+ ensure
115
+ @stdout = cap.stdout
116
+ @stderr = cap.stderr
117
+ end
118
+ end
119
+
120
+ @m = Mutex.new
121
+ @force_full_render = false
122
+ @done = false
123
+ @exception = nil
124
+ @success = false
125
+ @progress_percentage = nil
126
+ @wants_progress_mode = false
127
+ end
128
+
129
+ #: { (Task task) -> void } -> void
130
+ def on_done(&block)
131
+ @on_done = block
132
+ end
133
+
134
+ # Checks if a task is finished
135
+ #
136
+ #: -> bool
137
+ def check
138
+ return true if @done
139
+ return false unless @future.completed?
140
+
141
+ @done = true
142
+ begin
143
+ result = @future.value
144
+ @success = true
145
+ @success = false if result == TASK_FAILED
146
+ rescue => exc
147
+ @exception = exc
148
+ @success = false
149
+ end
150
+
151
+ @on_done&.call(self)
152
+
153
+ @done
154
+ end
155
+
156
+ # Re-renders the task if required:
157
+ #
158
+ # We try to be as lazy as possible in re-rendering the full line. The
159
+ # spinner rune will change on each render for the most part, but the
160
+ # body text will rarely have changed. If the body text *has* changed,
161
+ # we set @force_full_render.
162
+ #
163
+ # Further, if the title string includes any CLI::UI::Widgets, we
164
+ # assume that it may change from render to render, since those
165
+ # evaluate more dynamically than the rest of our format codes, which
166
+ # are just text formatters. This is controlled by @always_full_render.
167
+ #
168
+ # ==== Attributes
169
+ #
170
+ # * +index+ - index of the task
171
+ # * +force+ - force rerender of the task
172
+ # * +width+ - current terminal width to format for
173
+ #
174
+ #: (Integer index, ?bool force, ?width: Integer) -> String
175
+ def render(index, force = true, width: CLI::UI::Terminal.width)
176
+ @m.synchronize do
177
+ if !CLI::UI.enable_cursor? || force || @always_full_render || @force_full_render
178
+ full_render(index, width)
179
+ else
180
+ partial_render(index)
181
+ end
182
+ ensure
183
+ @force_full_render = false
184
+ end
185
+ end
186
+
187
+ # Update the spinner title
188
+ #
189
+ # ==== Attributes
190
+ #
191
+ # * +title+ - title to change the spinner to
192
+ #
193
+ #: (String new_title) -> void
194
+ def update_title(new_title)
195
+ @m.synchronize do
196
+ @always_full_render = new_title =~ Formatter::SCAN_WIDGET
197
+ @title = new_title
198
+ @force_full_render = true
199
+ end
200
+ end
201
+
202
+ # Set progress percentage (0-100) and switch to progress mode
203
+ #: (Integer percentage) -> void
204
+ def set_progress(percentage) # rubocop:disable Naming/AccessorMethodName
205
+ @m.synchronize do
206
+ @progress_percentage = percentage.clamp(0, 100)
207
+ @wants_progress_mode = true
208
+ end
209
+ end
210
+
211
+ # Switch back to indeterminate mode
212
+ #: -> void
213
+ def clear_progress
214
+ @m.synchronize do
215
+ @progress_percentage = nil
216
+ @wants_progress_mode = false
217
+ end
218
+ end
219
+
220
+ # Check if this task wants progress mode
221
+ #: -> bool
222
+ def wants_progress_mode?
223
+ @m.synchronize { @wants_progress_mode }
224
+ end
225
+
226
+ # Get current progress percentage
227
+ #: -> Integer?
228
+ def current_progress
229
+ @m.synchronize { @progress_percentage }
230
+ end
231
+
232
+ private
233
+
234
+ #: (Integer index, Integer terminal_width) -> String
235
+ def full_render(index, terminal_width)
236
+ o = +''
237
+
238
+ o << inset
239
+ o << glyph(index)
240
+ o << ' '
241
+
242
+ truncation_width = terminal_width - CLI::UI::ANSI.printing_width(o)
243
+
244
+ o << CLI::UI.resolve_text(title, truncate_to: truncation_width)
245
+ o << ANSI.clear_to_end_of_line if CLI::UI.enable_cursor?
246
+
247
+ o
248
+ end
249
+
250
+ #: (Integer index) -> String
251
+ def partial_render(index)
252
+ o = +''
253
+
254
+ o << CLI::UI::ANSI.cursor_forward(inset_width)
255
+ o << glyph(index)
256
+
257
+ o
258
+ end
259
+
260
+ #: (Integer index) -> String
261
+ def glyph(index)
262
+ if @done
263
+ final_glyph = @final_glyph.call(@success)
264
+ if final_glyph.is_a?(Glyph)
265
+ CLI::UI.enable_color? ? final_glyph.to_s : final_glyph.char
266
+ else
267
+ final_glyph
268
+ end
269
+ elsif CLI::UI.enable_cursor?
270
+ if !@future.started?
271
+ CLI::UI.enable_color? ? Glyph::HOURGLASS.to_s : Glyph::HOURGLASS.char
272
+ else
273
+ CLI::UI.enable_color? ? GLYPHS[index] : RUNES[index]
274
+ end
275
+ else
276
+ Glyph::HOURGLASS.char
277
+ end
278
+ end
279
+
280
+ #: -> String
281
+ def inset
282
+ @inset ||= CLI::UI::Frame.prefix
283
+ end
284
+
285
+ #: -> Integer
286
+ def inset_width
287
+ @inset_width ||= CLI::UI::ANSI.printing_width(inset)
288
+ end
289
+ end
290
+
291
+ # Add a new task
292
+ #
293
+ # ==== Attributes
294
+ #
295
+ # * +title+ - Title of the task
296
+ # * +block+ - Block for the task, will be provided with an instance of the spinner
297
+ #
298
+ # ==== Example Usage:
299
+ # spin_group = CLI::UI::SpinGroup.new
300
+ # spin_group.add('Title') { |spinner| sleep 1.0 }
301
+ # spin_group.wait
302
+ #
303
+ #: (String title, ?final_glyph: ^(bool success) -> (Glyph | String), ?merged_output: bool, ?duplicate_output_to: IO) { (Task task) -> void } -> void
304
+ def add(
305
+ title,
306
+ final_glyph: DEFAULT_FINAL_GLYPH,
307
+ merged_output: false,
308
+ duplicate_output_to: File.new(File::NULL, 'w'),
309
+ &block
310
+ )
311
+ @m.synchronize do
312
+ @tasks << Task.new(
313
+ title,
314
+ final_glyph: final_glyph,
315
+ merged_output: merged_output,
316
+ duplicate_output_to: duplicate_output_to,
317
+ work_queue: @work_queue,
318
+ &block
319
+ )
320
+ end
321
+ end
322
+
323
+ #: -> void
324
+ def stop
325
+ # If we already own the mutex (called from within another synchronized block),
326
+ # set stopped directly to avoid deadlock
327
+ if @m.owned?
328
+ return if @stopped
329
+
330
+ @stopped = true
331
+ else
332
+ @m.synchronize do
333
+ return if @stopped
334
+
335
+ @stopped = true
336
+ end
337
+ end
338
+ # Interrupt is thread-safe on its own, so we can call it outside the mutex
339
+ @work_queue.interrupt
340
+ end
341
+
342
+ #: -> bool
343
+ def stopped?
344
+ if @m.owned?
345
+ @stopped
346
+ else
347
+ @m.synchronize { @stopped }
348
+ end
349
+ end
350
+
351
+ # Tells the group you're done adding tasks and to wait for all of them to finish
352
+ #
353
+ # ==== Options
354
+ #
355
+ # * +:to+ - Target stream, like $stdout or $stderr. Can be anything with print and puts methods,
356
+ # or under Sorbet, IO or StringIO. Defaults to $stdout
357
+ #
358
+ # ==== Example Usage:
359
+ # spin_group = CLI::UI::SpinGroup.new
360
+ # spin_group.add('Title') { |spinner| sleep 1.0 }
361
+ # spin_group.wait
362
+ #
363
+ #: (?to: io_like) -> bool
364
+ def wait(to: $stdout)
365
+ result = false #: bool
366
+
367
+ CLI::UI::ProgressReporter.with_progress(mode: :indeterminate, to: to, delay_start: true) do |reporter|
368
+ idx = 0
369
+ consumed_lines = 0
370
+
371
+ @work_queue.close if @internal_work_queue
372
+
373
+ tasks_seen = @tasks.map { false }
374
+ tasks_seen_done = @tasks.map { false }
375
+
376
+ current_mode = :indeterminate #: Symbol
377
+ first_render = true #: bool
378
+
379
+ loop do
380
+ break if stopped?
381
+
382
+ done_count = 0
383
+ width = CLI::UI::Terminal.width
384
+
385
+ # Update progress mode based on task states
386
+ current_mode = update_progress_mode(reporter, current_mode, first_render)
387
+
388
+ self.class.pause_mutex.synchronize do
389
+ next if self.class.paused?
390
+
391
+ @m.synchronize do
392
+ CLI::UI.raw do
393
+ # Render any messages above the spinner
394
+ force_full_render = render_puts_above(to, consumed_lines)
395
+
396
+ # Render all tasks
397
+ done_count, consumed_lines = render_tasks(
398
+ to: to,
399
+ tasks_seen: tasks_seen,
400
+ tasks_seen_done: tasks_seen_done,
401
+ consumed_lines: consumed_lines,
402
+ idx: idx,
403
+ force_full_render: force_full_render,
404
+ width: width,
405
+ )
406
+ end
407
+ end
408
+ end
409
+
410
+ break if done_count == @tasks.size
411
+
412
+ # After first render, start the progress reporter in indeterminate mode
413
+ if first_render
414
+ reporter.force_set_indeterminate
415
+ first_render = false
416
+ end
417
+
418
+ idx = (idx + 1) % GLYPHS.size
419
+ Spinner.index = idx
420
+ sleep(PERIOD)
421
+ end
422
+
423
+ # Show error state briefly if tasks failed
424
+ success = all_succeeded?
425
+ unless success
426
+ reporter.set_error
427
+ sleep(0.5)
428
+ end
429
+
430
+ result = if @auto_debrief
431
+ debrief(to: to)
432
+ else
433
+ all_succeeded?
434
+ end
435
+ end
436
+
437
+ result
438
+ rescue Interrupt
439
+ @work_queue.interrupt
440
+ debrief(to: to) if @interrupt_debrief
441
+ stopped? ? false : raise
442
+ end
443
+
444
+ #: (String message) -> void
445
+ def puts_above(message)
446
+ @m.synchronize do
447
+ @puts_above << message
448
+ end
449
+ end
450
+
451
+ # Provide an alternative debriefing for failed tasks
452
+ #: { (String title, Exception? exception, String out, String err) -> void } -> void
453
+ def failure_debrief(&block)
454
+ @failure_debrief = block
455
+ end
456
+
457
+ # Provide a debriefing for successful tasks
458
+ #: { (String title, String out, String err) -> void } -> void
459
+ def success_debrief(&block)
460
+ @success_debrief = block
461
+ end
462
+
463
+ #: -> bool
464
+ def all_succeeded?
465
+ @m.synchronize do
466
+ @tasks.all?(&:success)
467
+ end
468
+ end
469
+
470
+ private
471
+
472
+ # Update progress reporter mode based on task progress states
473
+ #: (CLI::UI::ProgressReporter::Reporter reporter, Symbol current_mode, bool first_render) -> Symbol
474
+ def update_progress_mode(reporter, current_mode, first_render)
475
+ # Don't emit OSC on first iteration
476
+ return current_mode if first_render
477
+
478
+ # Check if any task wants progress mode
479
+ task_with_progress = @tasks.find(&:wants_progress_mode?)
480
+
481
+ if task_with_progress
482
+ progress = task_with_progress.current_progress
483
+ if progress
484
+ reporter.force_set_progress(progress)
485
+ if current_mode != :progress
486
+ # Switch to progress mode
487
+ :progress
488
+ else
489
+ # Update progress
490
+ current_mode
491
+ end
492
+ else
493
+ current_mode
494
+ end
495
+ elsif current_mode != :indeterminate
496
+ # No task wants progress, switch back to indeterminate
497
+ reporter.force_set_indeterminate
498
+ :indeterminate
499
+ else
500
+ current_mode
501
+ end
502
+ end
503
+
504
+ # Render messages that should appear above the spinner
505
+ #: (io_like to, Integer consumed_lines) -> bool
506
+ def render_puts_above(to, consumed_lines)
507
+ return false if @puts_above.empty?
508
+
509
+ to.print(CLI::UI::ANSI.cursor_up(consumed_lines)) if CLI::UI.enable_cursor?
510
+ while (message = @puts_above.shift)
511
+ to.print(CLI::UI::ANSI.insert_lines(message.lines.count)) if CLI::UI.enable_cursor?
512
+ message.lines.each do |line|
513
+ to.print(CLI::UI::Frame.prefix + CLI::UI.fmt(line))
514
+ end
515
+ to.print("\n")
516
+ end
517
+ # we descend with newlines rather than ANSI.cursor_down as the inserted lines may've
518
+ # pushed the spinner off the front of the buffer, so we can't move back down below it
519
+ to.print("\n" * consumed_lines) if CLI::UI.enable_cursor?
520
+
521
+ true # force full render needed
522
+ end
523
+
524
+ # Render all tasks
525
+ #: (to: io_like, tasks_seen: Array[bool], tasks_seen_done: Array[bool], consumed_lines: Integer, idx: Integer, force_full_render: bool, width: Integer) -> [Integer, Integer]
526
+ def render_tasks(to:, tasks_seen:, tasks_seen_done:, consumed_lines:, idx:, force_full_render:, width:)
527
+ done_count = 0
528
+
529
+ @tasks.each.with_index do |task, int_index|
530
+ nat_index = int_index + 1
531
+ task_done = task.check
532
+ done_count += 1 if task_done
533
+
534
+ if CLI::UI.enable_cursor?
535
+ if nat_index > consumed_lines
536
+ to.print(task.render(idx, true, width: width) + "\n")
537
+ consumed_lines += 1
538
+ else
539
+ offset = consumed_lines - int_index
540
+ move_to = CLI::UI::ANSI.cursor_up(offset) + "\r"
541
+ move_from = "\r" + CLI::UI::ANSI.cursor_down(offset)
542
+
543
+ to.print(move_to + task.render(idx, idx.zero? || force_full_render, width: width) + move_from)
544
+ end
545
+ elsif !tasks_seen[int_index] || (task_done && !tasks_seen_done[int_index])
546
+ to.print(task.render(idx, true, width: width) + "\n")
547
+ end
548
+
549
+ tasks_seen[int_index] = true
550
+ tasks_seen_done[int_index] ||= task_done
551
+ end
552
+
553
+ [done_count, consumed_lines]
554
+ end
555
+
556
+ # Debriefs failed tasks is +auto_debrief+ is true
557
+ #
558
+ # ==== Options
559
+ #
560
+ # * +:to+ - Target stream, like $stdout or $stderr. Can be anything with print and puts methods,
561
+ # or under Sorbet, IO or StringIO. Defaults to $stdout
562
+ #
563
+ #: (?to: io_like) -> bool
564
+ def debrief(to: $stdout)
565
+ @m.synchronize do
566
+ @tasks.each do |task|
567
+ next unless task.done
568
+
569
+ title = task.title
570
+ out = task.stdout
571
+ err = task.stderr
572
+
573
+ if task.success
574
+ next @success_debrief&.call(title, out, err)
575
+ end
576
+
577
+ # exception will not be set if the wait loop is stopped before the task is checked
578
+ e = task.exception
579
+ next @failure_debrief.call(title, e, out, err) if @failure_debrief
580
+
581
+ CLI::UI::Frame.open('Task Failed: ' + title, color: :red, timing: Time.new - @start) do
582
+ if e
583
+ to.puts("#{e.class}: #{e.message}")
584
+ to.puts("\tfrom #{e.backtrace.join("\n\tfrom ")}")
585
+ end
586
+
587
+ CLI::UI::Frame.divider('STDOUT')
588
+ out = '(empty)' if out.nil? || out.strip.empty?
589
+ to.puts(out)
590
+
591
+ CLI::UI::Frame.divider('STDERR')
592
+ err = '(empty)' if err.nil? || err.strip.empty?
593
+ to.puts(err)
594
+ end
595
+ end
596
+ @tasks.all?(&:success)
597
+ end
598
+ end
599
+ end
600
+ end
601
+ end
602
+ end
@@ -0,0 +1,79 @@
1
+ # typed: true
2
+ # frozen_string_literal: true
3
+
4
+ require 'cli/ui'
5
+
6
+ module CLI
7
+ module UI
8
+ module Spinner
9
+ autoload :Async, 'cli/ui/spinner/async'
10
+ autoload :SpinGroup, 'cli/ui/spinner/spin_group'
11
+
12
+ PERIOD = 0.1 # seconds
13
+ TASK_FAILED = :task_failed
14
+
15
+ RUNES = if CLI::UI::OS.current.use_emoji?
16
+ ['⠋', '⠙', '⠹', '⠸', '⠼', '⠴', '⠦', '⠧', '⠇', '⠏'].freeze
17
+ else
18
+ ['\\', '|', '/', '-', '\\', '|', '/', '-'].freeze
19
+ end
20
+
21
+ colors = [CLI::UI::Color::CYAN.code] * (RUNES.size / 2).ceil +
22
+ [CLI::UI::Color::MAGENTA.code] * (RUNES.size / 2).to_i
23
+ GLYPHS = colors.zip(RUNES).map { |c, r| c + r + CLI::UI::Color::RESET.code }.freeze
24
+
25
+ class << self
26
+ #: Integer?
27
+ attr_accessor(:index)
28
+
29
+ # We use this from CLI::UI::Widgets::Status to render an additional
30
+ # spinner next to the "working" element. While this global state looks
31
+ # a bit repulsive at first, it's worth realizing that:
32
+ #
33
+ # * It's managed by the SpinGroup#wait method, not individual tasks; and
34
+ # * It would be complete insanity to run two separate but concurrent SpinGroups.
35
+ #
36
+ # While it would be possible to stitch through some connection between
37
+ # the SpinGroup and the Widgets included in its title, this is simpler
38
+ # in practice and seems unlikely to cause issues in practice.
39
+ #: -> String
40
+ def current_rune
41
+ RUNES[index || 0]
42
+ end
43
+ end
44
+
45
+ class << self
46
+ # Adds a single spinner
47
+ # Uses an interactive session to allow the user to pick an answer
48
+ # Can use arrows, y/n, numbers (1/2), and vim bindings to control
49
+ #
50
+ # https://user-images.githubusercontent.com/3074765/33798295-d94fd822-dce3-11e7-819b-43e5502d490e.gif
51
+ #
52
+ # ==== Attributes
53
+ #
54
+ # * +title+ - Title of the spinner to use
55
+ #
56
+ # ==== Options
57
+ #
58
+ # * +:auto_debrief+ - Automatically debrief exceptions or through success_debrief? Default to true
59
+ # * +:to+ - Target stream, like $stdout or $stderr. Can be anything with print and puts methods,
60
+ # or under Sorbet, IO or StringIO. Defaults to $stdout.
61
+ #
62
+ # ==== Block
63
+ #
64
+ # * *spinner+ - Instance of the spinner. Can call +update_title+ to update the user of changes
65
+ #
66
+ # ==== Example Usage:
67
+ #
68
+ # CLI::UI::Spinner.spin('Title') { sleep 1.0 }
69
+ #
70
+ #: (String title, ?auto_debrief: bool, ?to: io_like) { (SpinGroup::Task task) -> void } -> bool
71
+ def spin(title, auto_debrief: true, to: $stdout, &block)
72
+ sg = SpinGroup.new(auto_debrief: auto_debrief)
73
+ sg.add(title, &block)
74
+ sg.wait(to: to)
75
+ end
76
+ end
77
+ end
78
+ end
79
+ end