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,260 @@
1
+ require 'cli/kit'
2
+
3
+ module CLI
4
+ module Kit
5
+ module Support
6
+ module TestHelper
7
+ def setup
8
+ super
9
+ CLI::Kit::System.reset!
10
+ end
11
+
12
+ def assert_all_commands_run(should_raise: true)
13
+ errors = CLI::Kit::System.error_message
14
+ CLI::Kit::System.reset!
15
+ # this is in minitest, but sorbet doesn't know that. probably we
16
+ # could structure this better.
17
+ uself = self #: as untyped
18
+ uself.assert(false, errors) if should_raise && !errors.nil?
19
+ errors
20
+ end
21
+
22
+ def teardown
23
+ super
24
+ assert_all_commands_run
25
+ rescue Errno::EACCES
26
+ # this sometimes happens on windows builds - let's ignore it
27
+ end
28
+
29
+ module FakeConfig
30
+ require 'tmpdir'
31
+ require 'fileutils'
32
+
33
+ def setup
34
+ super
35
+ @tmpdir = Dir.mktmpdir
36
+ @prev_xdg = ENV['XDG_CONFIG_HOME']
37
+ ENV['XDG_CONFIG_HOME'] = @tmpdir
38
+ end
39
+
40
+ def teardown
41
+ FileUtils.rm_rf(@tmpdir)
42
+ ENV['XDG_CONFIG_HOME'] = @prev_xdg
43
+ super
44
+ end
45
+ end
46
+
47
+ class FakeSuccess
48
+ def initialize(success)
49
+ @success = success
50
+ end
51
+
52
+ def success?
53
+ @success
54
+ end
55
+ end
56
+
57
+ module ::CLI
58
+ module Kit
59
+ module System
60
+ class << self
61
+ alias_method :original_system, :system
62
+ def system(cmd, *a, sudo: false, env: {}, stdin: nil, **kwargs)
63
+ a.unshift(cmd)
64
+ expected_command = expected_command(a, sudo: sudo, env: env)
65
+
66
+ # In the case of an unexpected command, expected_command will be nil
67
+ return FakeSuccess.new(false) if expected_command.nil?
68
+
69
+ # Otherwise handle the command
70
+ if expected_command[:allow]
71
+ uself = self #: as untyped
72
+ uself.original_system(*a, sudo: sudo, env: env, **kwargs)
73
+ else
74
+ FakeSuccess.new(expected_command[:success])
75
+ end
76
+ end
77
+
78
+ alias_method :original_capture2, :capture2
79
+ def capture2(cmd, *a, sudo: false, env: {}, **kwargs)
80
+ a.unshift(cmd)
81
+ expected_command = expected_command(a, sudo: sudo, env: env)
82
+
83
+ # In the case of an unexpected command, expected_command will be nil
84
+ return [nil, FakeSuccess.new(false)] if expected_command.nil?
85
+
86
+ # Otherwise handle the command
87
+ if expected_command[:allow]
88
+ uself = self #: as untyped
89
+ uself.original_capture2(*a, sudo: sudo, env: env, **kwargs)
90
+ else
91
+ [
92
+ expected_command[:stdout],
93
+ FakeSuccess.new(expected_command[:success]),
94
+ ]
95
+ end
96
+ end
97
+
98
+ alias_method :original_capture2e, :capture2e
99
+ def capture2e(cmd, *a, sudo: false, env: {}, **kwargs)
100
+ a.unshift(cmd)
101
+ expected_command = expected_command(a, sudo: sudo, env: env)
102
+
103
+ # In the case of an unexpected command, expected_command will be nil
104
+ return [nil, FakeSuccess.new(false)] if expected_command.nil?
105
+
106
+ # Otherwise handle the command
107
+ if expected_command[:allow]
108
+ uself = self #: as untyped
109
+ uself.original_capture2e(*a, sudo: sudo, env: env, **kwargs)
110
+ else
111
+ [
112
+ expected_command[:stdout],
113
+ FakeSuccess.new(expected_command[:success]),
114
+ ]
115
+ end
116
+ end
117
+
118
+ alias_method :original_capture3, :capture3
119
+ def capture3(cmd, *a, sudo: false, env: {}, **kwargs)
120
+ a.unshift(cmd)
121
+ expected_command = expected_command(a, sudo: sudo, env: env)
122
+
123
+ # In the case of an unexpected command, expected_command will be nil
124
+ return [nil, nil, FakeSuccess.new(false)] if expected_command.nil?
125
+
126
+ # Otherwise handle the command
127
+ if expected_command[:allow]
128
+ uself = self #: as untyped
129
+ uself.original_capture3(*a, sudo: sudo, env: env, **kwargs)
130
+ else
131
+ [
132
+ expected_command[:stdout],
133
+ expected_command[:stderr],
134
+ FakeSuccess.new(expected_command[:success]),
135
+ ]
136
+ end
137
+ end
138
+
139
+ # Sets up an expectation for a command and stubs out the call (unless allow is true)
140
+ #
141
+ # #### Parameters
142
+ # `*a` : the command, represented as a splat
143
+ # `stdout` : stdout to stub the command with (defaults to empty string)
144
+ # `stderr` : stderr to stub the command with (defaults to empty string)
145
+ # `allow` : allow determines if the command will be actually run, or stubbed. Defaults to nil (stub)
146
+ # `success` : success status to stub the command with (Defaults to nil)
147
+ # `sudo` : expectation of sudo being set or not (defaults to false)
148
+ # `env` : expectation of env being set or not (defaults to {})
149
+ #
150
+ # Note: Must set allow or success
151
+ #
152
+ def fake(*a, stdout: '', stderr: '', allow: nil, success: nil, sudo: false, env: {})
153
+ raise ArgumentError, 'success or allow must be set' if success.nil? && allow.nil?
154
+
155
+ @delegate_open3 ||= {}
156
+ @delegate_open3[a.join(' ')] = {
157
+ expected: {
158
+ sudo: sudo,
159
+ env: env,
160
+ },
161
+ actual: {
162
+ sudo: nil,
163
+ env: nil,
164
+ },
165
+ stdout: stdout,
166
+ stderr: stderr,
167
+ allow: allow,
168
+ success: success,
169
+ run: false,
170
+ }
171
+ end
172
+
173
+ # Resets the faked commands
174
+ #
175
+ def reset!
176
+ @delegate_open3 = {}
177
+ end
178
+
179
+ # Returns the errors associated to a test run
180
+ #
181
+ # #### Returns
182
+ # `errors` (String) a string representing errors found on this run, nil if none
183
+ def error_message
184
+ errors = {
185
+ unexpected: [],
186
+ not_run: [],
187
+ other: {},
188
+ }
189
+
190
+ @delegate_open3.each do |cmd, opts|
191
+ if opts[:unexpected]
192
+ errors[:unexpected] << cmd
193
+ elsif opts[:run]
194
+ error = []
195
+
196
+ if opts[:expected][:sudo] != opts[:actual][:sudo]
197
+ error << "- sudo was supposed to be #{opts[:expected][:sudo]} but was #{opts[:actual][:sudo]}"
198
+ end
199
+
200
+ if opts[:expected][:env] != opts[:actual][:env]
201
+ error << "- env was supposed to be #{opts[:expected][:env]} but was #{opts[:actual][:env]}"
202
+ end
203
+
204
+ errors[:other][cmd] = error.join("\n") unless error.empty?
205
+ else
206
+ errors[:not_run] << cmd
207
+ end
208
+ end
209
+
210
+ final_error = []
211
+
212
+ unless errors[:unexpected].empty?
213
+ final_error << CLI::UI.fmt(<<~EOF)
214
+ {{bold:Unexpected command invocations:}}
215
+ {{command:#{errors[:unexpected].join("\n")}}}
216
+ EOF
217
+ end
218
+
219
+ unless errors[:not_run].empty?
220
+ final_error << CLI::UI.fmt(<<~EOF)
221
+ {{bold:Expected commands were not run:}}
222
+ {{command:#{errors[:not_run].join("\n")}}}
223
+ EOF
224
+ end
225
+
226
+ unless errors[:other].empty?
227
+ final_error << CLI::UI.fmt(<<~EOF)
228
+ {{bold:Commands were not run as expected:}}
229
+ #{errors[:other].map { |cmd, msg| "{{command:#{cmd}}}\n#{msg}" }.join("\n\n")}
230
+ EOF
231
+ end
232
+
233
+ return if final_error.empty?
234
+
235
+ "\n" + final_error.join("\n") # Initial new line for formatting reasons
236
+ end
237
+
238
+ private
239
+
240
+ def expected_command(a, sudo: raise, env: raise)
241
+ expected_cmd = @delegate_open3[a.join(' ')]
242
+
243
+ if expected_cmd.nil?
244
+ @delegate_open3[a.join(' ')] = { unexpected: true }
245
+ return
246
+ end
247
+
248
+ expected_cmd[:run] = true
249
+ expected_cmd[:actual][:sudo] = sudo
250
+ expected_cmd[:actual][:env] = env
251
+ expected_cmd
252
+ end
253
+ end
254
+ end
255
+ end
256
+ end
257
+ end
258
+ end
259
+ end
260
+ end
@@ -0,0 +1,11 @@
1
+ # typed: true
2
+
3
+ require 'cli/kit'
4
+
5
+ module CLI
6
+ module Kit
7
+ module Support
8
+ autoload :TestHelper, 'cli/kit/support/test_helper'
9
+ end
10
+ end
11
+ end
@@ -0,0 +1,290 @@
1
+ # typed: true
2
+
3
+ require 'cli/kit'
4
+ require 'open3'
5
+ require 'English'
6
+
7
+ module CLI
8
+ module Kit
9
+ module System
10
+ SUDO_PROMPT = CLI::UI.fmt('{{info:(sudo)}} Password: ')
11
+ class << self
12
+ # Ask for sudo access with a message explaning the need for it
13
+ # Will make subsequent commands capable of running with sudo for a period of time
14
+ #
15
+ # #### Parameters
16
+ # - `msg`: A message telling the user why sudo is needed
17
+ #
18
+ # #### Usage
19
+ # `ctx.sudo_reason("We need to do a thing")`
20
+ #
21
+ #: (String msg) -> void
22
+ def sudo_reason(msg)
23
+ # See if sudo has a cached password
24
+ %x(env SUDO_ASKPASS=/usr/bin/false sudo -A true > /dev/null 2>&1)
25
+ return if $CHILD_STATUS.success?
26
+
27
+ CLI::UI.with_frame_color(:blue) do
28
+ puts(CLI::UI.fmt("{{i}} #{msg}"))
29
+ end
30
+ end
31
+
32
+ # Execute a command in the user's environment
33
+ # This is meant to be largely equivalent to backticks, only with the env passed in.
34
+ # Captures the results of the command without output to the console
35
+ #
36
+ # #### Parameters
37
+ # - `*a`: A splat of arguments evaluated as a command. (e.g. `'rm', folder` is equivalent to `rm #{folder}`)
38
+ # - `sudo`: If truthy, run this command with sudo. If String, pass to `sudo_reason`
39
+ # - `env`: process environment with which to execute this command
40
+ # - `**kwargs`: additional arguments to pass to Open3.capture2
41
+ #
42
+ # #### Returns
43
+ # - `output`: output (STDOUT) of the command execution
44
+ # - `status`: boolean success status of the command execution
45
+ #
46
+ # #### Usage
47
+ # `out, stat = CLI::Kit::System.capture2('ls', 'a_folder')`
48
+ #
49
+ #: (String cmd, *String args, ?sudo: (String | bool), ?env: Hash[String, String?], **untyped kwargs) -> [String, Process::Status]
50
+ def capture2(cmd, *args, sudo: false, env: ENV.to_h, **kwargs)
51
+ delegate_open3(cmd, args, kwargs, sudo: sudo, env: env, method: :capture2)
52
+ end
53
+
54
+ # Execute a command in the user's environment
55
+ # This is meant to be largely equivalent to backticks, only with the env passed in.
56
+ # Captures the results of the command without output to the console
57
+ #
58
+ # #### Parameters
59
+ # - `*a`: A splat of arguments evaluated as a command. (e.g. `'rm', folder` is equivalent to `rm #{folder}`)
60
+ # - `sudo`: If truthy, run this command with sudo. If String, pass to `sudo_reason`
61
+ # - `env`: process environment with which to execute this command
62
+ # - `**kwargs`: additional arguments to pass to Open3.capture2e
63
+ #
64
+ # #### Returns
65
+ # - `output`: output (STDOUT merged with STDERR) of the command execution
66
+ # - `status`: boolean success status of the command execution
67
+ #
68
+ # #### Usage
69
+ # `out_and_err, stat = CLI::Kit::System.capture2e('ls', 'a_folder')`
70
+ #
71
+ #: (String cmd, *String args, ?sudo: (String | bool), ?env: Hash[String, String?], **untyped kwargs) -> [String, Process::Status]
72
+ def capture2e(cmd, *args, sudo: false, env: ENV.to_h, **kwargs)
73
+ delegate_open3(cmd, args, kwargs, sudo: sudo, env: env, method: :capture2e)
74
+ end
75
+
76
+ # Execute a command in the user's environment
77
+ # This is meant to be largely equivalent to backticks, only with the env passed in.
78
+ # Captures the results of the command without output to the console
79
+ #
80
+ # #### Parameters
81
+ # - `*a`: A splat of arguments evaluated as a command. (e.g. `'rm', folder` is equivalent to `rm #{folder}`)
82
+ # - `sudo`: If truthy, run this command with sudo. If String, pass to `sudo_reason`
83
+ # - `env`: process environment with which to execute this command
84
+ # - `**kwargs`: additional arguments to pass to Open3.capture3
85
+ #
86
+ # #### Returns
87
+ # - `output`: STDOUT of the command execution
88
+ # - `error`: STDERR of the command execution
89
+ # - `status`: boolean success status of the command execution
90
+ #
91
+ # #### Usage
92
+ # `out, err, stat = CLI::Kit::System.capture3('ls', 'a_folder')`
93
+ #
94
+ #: (String cmd, *String args, ?sudo: (String | bool), ?env: Hash[String, String?], **untyped kwargs) -> [String, String, Process::Status]
95
+ def capture3(cmd, *args, sudo: false, env: ENV.to_h, **kwargs)
96
+ delegate_open3(cmd, args, kwargs, sudo: sudo, env: env, method: :capture3)
97
+ end
98
+
99
+ #: (String cmd, *String args, ?sudo: (String | bool), ?env: Hash[String, String?], **untyped kwargs) ?{ (IO stdin, IO stdout, Process::Waiter wait_thr) -> [IO, IO, Process::Waiter] } -> [IO, IO, Process::Waiter]
100
+ def popen2(cmd, *args, sudo: false, env: ENV.to_h, **kwargs, &block)
101
+ delegate_open3(cmd, args, kwargs, sudo: sudo, env: env, method: :popen2, &block)
102
+ end
103
+
104
+ #: (String cmd, *String args, ?sudo: (String | bool), ?env: Hash[String, String?], **untyped kwargs) ?{ (IO stdin, IO stdout, Process::Waiter wait_thr) -> [IO, IO, Process::Waiter] } -> [IO, IO, Process::Waiter]
105
+ def popen2e(cmd, *args, sudo: false, env: ENV.to_h, **kwargs, &block)
106
+ delegate_open3(cmd, args, kwargs, sudo: sudo, env: env, method: :popen2e, &block)
107
+ end
108
+
109
+ #: (String cmd, *String args, ?sudo: (String | bool), ?env: Hash[String, String?], **untyped kwargs) ?{ (IO stdin, IO stdout, IO stderr, Process::Waiter wait_thr) -> [IO, IO, IO, Process::Waiter] } -> [IO, IO, IO, Process::Waiter]
110
+ def popen3(cmd, *args, sudo: false, env: ENV.to_h, **kwargs, &block)
111
+ delegate_open3(cmd, args, kwargs, sudo: sudo, env: env, method: :popen3, &block)
112
+ end
113
+
114
+ # Execute a command in the user's environment
115
+ # Outputs result of the command without capturing it
116
+ #
117
+ # #### Parameters
118
+ # - `*a`: A splat of arguments evaluated as a command. (e.g. `'rm', folder` is equivalent to `rm #{folder}`)
119
+ # - `sudo`: If truthy, run this command with sudo. If String, pass to `sudo_reason`
120
+ # - `env`: process environment with which to execute this command
121
+ # - `**kwargs`: additional keyword arguments to pass to Process.spawn
122
+ #
123
+ # #### Returns
124
+ # - `status`: The `Process:Status` result for the command execution
125
+ #
126
+ # #### Usage
127
+ # `stat = CLI::Kit::System.system('ls', 'a_folder')`
128
+ #
129
+ #: (String cmd, *String args, ?sudo: (String | bool), ?env: Hash[String, String?], ?stdin: (IO | String | Integer | Symbol)?, **untyped kwargs) ?{ (String out, String err) -> void } -> Process::Status
130
+ def system(cmd, *args, sudo: false, env: ENV.to_h, stdin: nil, **kwargs, &block)
131
+ cmd, args = apply_sudo(cmd, args, sudo)
132
+
133
+ out_r, out_w = IO.pipe
134
+ err_r, err_w = IO.pipe
135
+ in_stream = if stdin
136
+ stdin
137
+ elsif STDIN.closed?
138
+ :close
139
+ else
140
+ STDIN
141
+ end
142
+ cmd, args = resolve_path(cmd, args, env)
143
+ process = Process #: as untyped
144
+ pid = process.spawn(env, cmd, *args, 0 => in_stream, :out => out_w, :err => err_w, **kwargs)
145
+ out_w.close
146
+ err_w.close
147
+
148
+ handlers = if block_given?
149
+ {
150
+ out_r => ->(data) { yield(data.force_encoding(Encoding::UTF_8), '') },
151
+ err_r => ->(data) { yield('', data.force_encoding(Encoding::UTF_8)) },
152
+ }
153
+ else
154
+ {
155
+ out_r => ->(data) { STDOUT.write(data) },
156
+ err_r => ->(data) { STDOUT.write(data) },
157
+ }
158
+ end
159
+
160
+ previous_trailing = Hash.new('')
161
+ loop do
162
+ break if Process.wait(pid, Process::WNOHANG)
163
+
164
+ ios = [err_r, out_r].reject(&:closed?)
165
+ next if ios.empty?
166
+
167
+ readers, = IO.select(ios, [], [], 1)
168
+ next if readers.nil? # If IO.select times out we iterate again so we can check if the process has exited
169
+
170
+ readers.each do |io|
171
+ data, trailing = split_partial_characters(io.readpartial(4096))
172
+ handlers[io].call(previous_trailing[io] + data)
173
+ previous_trailing[io] = trailing
174
+ rescue IOError
175
+ io.close
176
+ end
177
+ end
178
+
179
+ $CHILD_STATUS
180
+ end
181
+
182
+ # Split off trailing partial UTF-8 Characters. UTF-8 Multibyte characters start with a 11xxxxxx byte that tells
183
+ # how many following bytes are part of this character, followed by some number of 10xxxxxx bytes. This simple
184
+ # algorithm will split off a whole trailing multi-byte character.
185
+ #: (String data) -> [String, String]
186
+ def split_partial_characters(data)
187
+ last_byte = data.getbyte(-1) #: as !nil
188
+ return [data, ''] if (last_byte & 0b1000_0000).zero?
189
+
190
+ # UTF-8 is up to 4 characters per rune, so we could never want to trim more than that, and we want to avoid
191
+ # allocating an array for the whole of data with bytes
192
+ min_bound = -[4, data.bytesize].min
193
+ fb = data.byteslice(min_bound..-1) #: as !nil
194
+ final_bytes = fb.bytes
195
+ partial_character_sub_index = final_bytes.rindex { |byte| byte & 0b1100_0000 == 0b1100_0000 }
196
+
197
+ # Bail out for non UTF-8
198
+ return [data, ''] unless partial_character_sub_index
199
+
200
+ start_byte = final_bytes[partial_character_sub_index]
201
+ full_size = if start_byte & 0b1111_1000 == 0b1111_0000
202
+ 4
203
+ elsif start_byte & 0b1111_0000 == 0b1110_0000
204
+ 3
205
+ elsif start_byte & 0b1110_0000 == 0b110_00000
206
+ 2
207
+ else
208
+ nil # Not a valid UTF-8 character
209
+ end
210
+ return [data, ''] if full_size.nil? # Bail out for non UTF-8
211
+
212
+ if final_bytes.size - partial_character_sub_index == full_size
213
+ # We have a full UTF-8 character, so we can just return the data
214
+ return [data, '']
215
+ end
216
+
217
+ partial_character_index = min_bound + partial_character_sub_index
218
+
219
+ [
220
+ data.byteslice(0...partial_character_index), #: as !nil
221
+ data.byteslice(partial_character_index..-1), #: as !nil
222
+ ]
223
+ end
224
+
225
+ #: -> Symbol
226
+ def os
227
+ return :mac if /darwin/.match(RUBY_PLATFORM)
228
+ return :linux if /linux/.match(RUBY_PLATFORM)
229
+ return :windows if /mingw/.match(RUBY_PLATFORM)
230
+
231
+ raise "Could not determine OS from platform #{RUBY_PLATFORM}"
232
+ end
233
+
234
+ #: (String cmd, Hash[String, String?] env) -> String?
235
+ def which(cmd, env)
236
+ exts = os == :windows ? (env['PATHEXT'] || 'exe').split(';') : ['']
237
+ (env['PATH'] || '').split(File::PATH_SEPARATOR).each do |path|
238
+ exts.each do |ext|
239
+ exe = File.join(path, "#{cmd}#{ext}")
240
+ return exe if File.executable?(exe) && !File.directory?(exe)
241
+ end
242
+ end
243
+
244
+ nil
245
+ end
246
+
247
+ private
248
+
249
+ #: (String cmd, Array[String] args, (String | bool) sudo) -> [String, Array[String]]
250
+ def apply_sudo(cmd, args, sudo)
251
+ return [cmd, args] if !sudo || Process.uid.zero?
252
+
253
+ sudo_reason(sudo) if sudo.is_a?(String)
254
+ ['sudo', args.unshift('-E', '-S', '-p', SUDO_PROMPT, '--', cmd)]
255
+ end
256
+
257
+ #: (String cmd, Array[String] args, Hash[Symbol, untyped] kwargs, ?sudo: (String | bool), ?env: Hash[String, String?], ?method: Symbol) ?{ (?) -> untyped } -> untyped
258
+ def delegate_open3(cmd, args, kwargs, sudo: raise, env: raise, method: raise, &block)
259
+ cmd, args = apply_sudo(cmd, args, sudo)
260
+ cmd, args = resolve_path(cmd, args, env)
261
+ open3 = Open3 #: as untyped
262
+ open3.send(method, env, cmd, *args, **kwargs, &block)
263
+ rescue Errno::EINTR
264
+ raise(Errno::EINTR, "command interrupted: #{cmd} #{args.join(" ")}")
265
+ end
266
+
267
+ # Ruby resolves the program to execute using its own PATH, but we want it to
268
+ # use the provided one, so we ensure ruby chooses to spawn a shell, which will
269
+ # parse our command and properly spawn our target using the provided environment.
270
+ #
271
+ # This is important because dev clobbers its own environment such that ruby
272
+ # means /usr/bin/ruby, but we want it to select the ruby targeted by the active
273
+ # project.
274
+ #
275
+ # See https://github.com/Shopify/dev/pull/625 for more details.
276
+ #: (String cmd, Array[String] args, Hash[String, String?] env) -> [String, Array[String]]
277
+ def resolve_path(cmd, args, env)
278
+ # If only one argument was provided, make sure it's interpreted by a shell.
279
+ if args.empty?
280
+ prefix = os == :windows ? 'break && ' : 'true ; '
281
+ return [prefix + cmd, []]
282
+ end
283
+ return [cmd, args] if cmd.include?('/')
284
+
285
+ [which(cmd, env) || cmd, args]
286
+ end
287
+ end
288
+ end
289
+ end
290
+ end
@@ -0,0 +1,118 @@
1
+ # typed: true
2
+
3
+ require 'cli/kit'
4
+
5
+ module CLI
6
+ module Kit
7
+ module Util
8
+ class << self
9
+ #
10
+ # Converts an integer representing bytes into a human readable format
11
+ #
12
+ #: (Integer bytes, ?precision: Integer, ?space: bool) -> String
13
+ def to_filesize(bytes, precision: 2, space: false)
14
+ to_si_scale(bytes, 'B', precision: precision, space: space, factor: 1024)
15
+ end
16
+
17
+ # Converts a number to a human readable format on the SI scale
18
+ #
19
+ #: (Numeric number, ?String unit, ?factor: Integer, ?precision: Integer, ?space: bool) -> String
20
+ def to_si_scale(number, unit = '', factor: 1000, precision: 2, space: false)
21
+ raise ArgumentError, 'factor should only be 1000 or 1024' unless [1000, 1024].include?(factor)
22
+
23
+ small_scale = ['m', 'µ', 'n', 'p', 'f', 'a', 'z', 'y']
24
+ big_scale = ['k', 'M', 'G', 'T', 'P', 'E', 'Z', 'Y']
25
+ negative = number < 0
26
+ number = number.abs.to_f
27
+
28
+ if number == 0.0 || number.between?(1, factor)
29
+ prefix = ''
30
+ scale = 0
31
+ else
32
+ scale = Math.log(number, factor).floor
33
+ if number < 1
34
+ index = [-scale - 1, small_scale.length].min
35
+ scale = -(index + 1)
36
+ prefix = small_scale[index] #: as !nil
37
+ else
38
+ index = [scale - 1, big_scale.length].min
39
+ scale = index + 1
40
+ prefix = big_scale[index] #: as !nil
41
+ end
42
+ end
43
+
44
+ divider = (factor**scale)
45
+ fnum = (number / divider.to_f).round(precision)
46
+
47
+ # Trim useless decimal
48
+ fnum = fnum.to_i if (fnum.to_i.to_f * divider.to_f) == number
49
+
50
+ fnum = -fnum if negative
51
+ if space
52
+ prefix = ' ' + prefix
53
+ end
54
+
55
+ "#{fnum}#{prefix}#{unit}"
56
+ end
57
+
58
+ # Dir.chdir, when invoked in block form, complains when we call chdir
59
+ # again recursively. There's no apparent good reason for this, so we
60
+ # simply implement our own block form of Dir.chdir here.
61
+ #: [T] (String dir) { -> T } -> T
62
+ def with_dir(dir, &block)
63
+ prev = Dir.pwd
64
+ begin
65
+ Dir.chdir(dir)
66
+ yield
67
+ ensure
68
+ Dir.chdir(prev)
69
+ end
70
+ end
71
+
72
+ # Must call retry_after on the result in order to execute the block
73
+ #
74
+ # Example usage:
75
+ #
76
+ # CLI::Kit::Util.begin do
77
+ # might_raise_if_costly_prep_not_done()
78
+ # end.retry_after(ExpectedError) do
79
+ # costly_prep()
80
+ # end
81
+ #: [T] { -> T } -> Retrier[T]
82
+ def begin(&block_that_might_raise)
83
+ Retrier.new(block_that_might_raise)
84
+ end
85
+ end
86
+
87
+ #: [BlockReturnType]
88
+ class Retrier
89
+ #: (^-> BlockReturnType block_that_might_raise) -> void
90
+ def initialize(block_that_might_raise)
91
+ @block_that_might_raise = block_that_might_raise
92
+ end
93
+
94
+ #: (?singleton(Exception) exception, ?retries: Integer) ?{ (Exception e) -> void } -> BlockReturnType
95
+ def retry_after(exception = StandardError, retries: 1, &before_retry)
96
+ @block_that_might_raise.call
97
+ rescue exception => e
98
+ raise if (retries -= 1) < 0
99
+
100
+ if before_retry
101
+ # rubocop:disable Style/IdenticalConditionalBranches
102
+ if before_retry.arity == 0
103
+ prc = before_retry #: as ^() -> void
104
+ prc.call
105
+ else
106
+ prc = before_retry #: as ^(Exception) -> void
107
+ prc.call(e)
108
+ end
109
+ # rubocop:enable Style/IdenticalConditionalBranches
110
+ end
111
+ retry
112
+ end
113
+ end
114
+
115
+ private_constant :Retrier
116
+ end
117
+ end
118
+ end
@@ -0,0 +1,7 @@
1
+ # typed: true
2
+
3
+ module CLI
4
+ module Kit
5
+ VERSION = '5.2.0'
6
+ end
7
+ end