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,114 @@
1
+ require "pstore"
2
+ require "forwardable"
3
+
4
+ module FluidCLI
5
+ # Persists transient data like access tokens that may be cleared
6
+ # when user clears their session
7
+ #
8
+ # All of the instance methods documented here can be used as class methods. All class
9
+ # methods are forwarded to a new instance of the database, pointing at the default
10
+ # path.
11
+ class DB
12
+ extend SingleForwardable
13
+ def_delegators :new, :keys, :exists?, :set, :get, :del, :clear
14
+
15
+ attr_reader :db # :nodoc:
16
+
17
+ def initialize(path: File.join(FluidCLI.cache_dir, ".db.pstore")) # :nodoc:
18
+ @db = PStore.new(path)
19
+ end
20
+
21
+ # Get all keys that exist in the database.
22
+ #
23
+ # #### Returns
24
+ # - `keys`: an array of string or symbol keys that exist in the database
25
+ #
26
+ # #### Usage
27
+ #
28
+ # FluidCLI::DB.keys
29
+ #
30
+ def keys
31
+ db.transaction(true) { db.roots }
32
+ end
33
+
34
+ # Check to see if a key exists in the database, the key will only exist if it
35
+ # has a value so if the key exists then there is also a value.
36
+ #
37
+ # #### Parameters
38
+ # - `key`: a string or a symbol representation of a key that is stored in the DB
39
+ #
40
+ # #### Returns
41
+ # - `exists`: a boolean value if the key exists in the database
42
+ #
43
+ # #### Usage
44
+ #
45
+ # exists = FluidCLI::DB.exists?('fluid_exchange_token')
46
+ #
47
+ def exists?(key)
48
+ db.transaction(true) { db.root?(key) }
49
+ end
50
+
51
+ # Persist a value by key in the local storage
52
+ #
53
+ # #### Parameters
54
+ # - `**args`: a hash of keys and values to persist in the database
55
+ #
56
+ # #### Usage
57
+ #
58
+ # FluidCLI::DB.set(fluid_exchange_token: 'token', metric_consent: true)
59
+ #
60
+ def set(**args)
61
+ db.transaction do
62
+ args.each do |key, val|
63
+ if val.nil?
64
+ db.delete(key)
65
+ else
66
+ db[key] = val
67
+ end
68
+ end
69
+ end
70
+ end
71
+
72
+ # Gets a value from the DB that is associated with the supplied key
73
+ #
74
+ # #### Parameters
75
+ # - `key`: a string or a symbol representation of a key that is stored in the DB
76
+ #
77
+ # #### Returns
78
+ # - `value`: will be the previously saved value or nil if the key does not exist
79
+ # in the database.
80
+ #
81
+ # #### Usage
82
+ #
83
+ # FluidCLI::DB.get(:fluid_exchange_token)
84
+ #
85
+ def get(key)
86
+ val = db.transaction(true) { db[key] }
87
+ val = yield if val.nil? && block_given?
88
+ val
89
+ end
90
+
91
+ # Deletes a value from the local storage
92
+ #
93
+ # #### Parameters
94
+ # - `*args`: an array of strings or symbols that are keys to be removed from the database
95
+ #
96
+ # #### Usage
97
+ #
98
+ # FluidCLI::DB.del(:fluid_exchange_token)
99
+ #
100
+ def del(*args)
101
+ db.transaction { args.each { |key| db.delete(key) } }
102
+ end
103
+
104
+ # Drops all keys from the database.
105
+ #
106
+ # #### Usage
107
+ #
108
+ # FluidCLI::DB.clear
109
+ #
110
+ def clear
111
+ del(*keys)
112
+ end
113
+ end
114
+ end
@@ -0,0 +1,10 @@
1
+ require 'fluid_cli'
2
+
3
+ module FluidCLI
4
+ module EntryPoint
5
+ def self.call(args)
6
+ cmd, command_name, args = FluidCLI::Resolver.call(args)
7
+ FluidCLI::Executor.call(cmd, command_name, args)
8
+ end
9
+ end
10
+ end
@@ -0,0 +1,32 @@
1
+ module FluidCLI
2
+ # The environment module provides an interface to get information from
3
+ # the environment in which the CLI runs
4
+ module Environment
5
+ def self.ruby_version(context: Context.new)
6
+ output, status = context.capture2e("ruby", "--version")
7
+ raise FluidCLI::Abort, context.message("core.errors.missing_ruby") unless status.success?
8
+ version = output.match(/ruby (\d+\.\d+\.\d+)/)[1]
9
+ puts "Ruby version: #{version}"
10
+ end
11
+
12
+ def self.company(env_variables: ENV)
13
+ env_variables["FLUID_COMPANY"]
14
+ end
15
+
16
+ def self.auth_token(env_variables: ENV)
17
+ env_variables["FLUID_AUTH_TOKEN"]
18
+ end
19
+
20
+ def self.interactive=(interactive)
21
+ @interactive = interactive
22
+ end
23
+
24
+ def self.interactive?(env_variables: ENV)
25
+ if env_variables.key?("FLUID_CLI_TTY")
26
+ @interactive = env_variables["FLUID_CLI_TTY"] == "true"
27
+ else
28
+ @interactive ||= STDIN.tty?
29
+ end
30
+ end
31
+ end
32
+ end
@@ -0,0 +1,29 @@
1
+ # frozen_string_literal: true
2
+ require "listen"
3
+ require "observer"
4
+
5
+ module FluidCLI
6
+ class FileSystemListener
7
+ include Observable
8
+
9
+ def initialize(root:, force_poll:)
10
+ @root = root
11
+ @force_poll = force_poll
12
+
13
+ @listener = Listen.to(@root, force_polling: @force_poll) do |updated, added, removed|
14
+ changed
15
+ notify_observers(updated, added, removed)
16
+ end
17
+ end
18
+
19
+ def start
20
+ @listener.start
21
+ rescue ArgumentError
22
+ # Ignore errors during the transition of 'listen' events
23
+ end
24
+
25
+ def stop
26
+ @listener.stop
27
+ end
28
+ end
29
+ end
@@ -0,0 +1,42 @@
1
+ require "fluid_cli"
2
+
3
+ module FluidCLI
4
+ class Form
5
+ class << self
6
+ def ask(ctx, args, flags)
7
+ attrs = {}
8
+ (@positional_arguments || []).each { |name| attrs[name] = args.shift }
9
+ return nil if attrs.any? { |_k, v| v.nil? }
10
+ (@flag_arguments || []).each { |arg| attrs[arg] = flags[arg] }
11
+ form = new(ctx, args, attrs)
12
+ begin
13
+ form.ask
14
+ form
15
+ rescue CLI::Kit::Abort => err
16
+ ctx.puts(err.message)
17
+ nil
18
+ rescue CLI::Kit::AbortSilent
19
+ nil
20
+ end
21
+ end
22
+
23
+ def positional_arguments(*args)
24
+ @positional_arguments = args
25
+ attr_accessor(*args)
26
+ end
27
+
28
+ def flag_arguments(*args)
29
+ @flag_arguments = args
30
+ attr_accessor(*args)
31
+ end
32
+ end
33
+
34
+ attr_accessor :ctx, :xargs
35
+
36
+ def initialize(ctx, xargs, attributes)
37
+ @ctx = ctx
38
+ @xargs = xargs
39
+ attributes.each { |k, v| send("#{k}=", v) unless v.nil? }
40
+ end
41
+ end
42
+ end
@@ -0,0 +1,319 @@
1
+ module FluidCLI
2
+ ##
3
+ # FluidCLI::Git wraps git functionality to make it easier to integrate with git.
4
+ class Git
5
+ class << self
6
+ # Check if Git exists in the environment
7
+ def exists?(ctx)
8
+ _output, status = ctx.capture2e("git", "version")
9
+ status.success?
10
+ rescue Errno::ENOENT # git is not installed
11
+ false
12
+ end
13
+
14
+ # Check if the current working directory is a Git repository
15
+ def available?(ctx)
16
+ _output, status = ctx.capture2e("git", "status")
17
+ status.success?
18
+ rescue Errno::ENOENT # git is not installed
19
+ false
20
+ end
21
+
22
+ ##
23
+ # will return the current sha of the cli repo
24
+ #
25
+ # #### Parameters
26
+ #
27
+ # * `dir` - the directory of the git repo. This defaults to the cli repo
28
+ # * `ctx` - the current running context of your command
29
+ #
30
+ # #### Returns
31
+ #
32
+ # * `sha_string` - string of the sha of the most recent commit to the repo
33
+ #
34
+ # #### Example
35
+ #
36
+ # FluidCLI::Git.sha
37
+ #
38
+ # Some environments don't have git in PATH and this prevents
39
+ # the execution from raising an error
40
+ # https://app.bugsnag.com/shopify/shopify-cli/errors/615dd36365ce57000889d4c5
41
+ def sha(dir: Dir.pwd, ctx: Context.new)
42
+ if available?(ctx)
43
+ rev_parse("HEAD", dir: dir, ctx: ctx)
44
+ end
45
+ end
46
+
47
+ ##
48
+ # returns array with components of git clone command
49
+ #
50
+ # #### Parameters
51
+ #
52
+ # * `repo` - repo url without branch name
53
+ # * `dest` - a filepath to where the repo should be cloned to
54
+ # * `branch` - branch name when cloning
55
+ #
56
+ # #### Returns
57
+ #
58
+ # * array of strings
59
+ #
60
+ # #### Example
61
+ #
62
+ # ["clone", "--single-branch", "--branch", "test-branch", "test-app"]
63
+ #
64
+ def git_clone_command(repo, dest, branch)
65
+ if branch
66
+ ["clone", "--single-branch", "--branch", branch, repo, dest]
67
+ else
68
+ ["clone", "--single-branch", repo, dest]
69
+ end
70
+ end
71
+
72
+ ##
73
+ # calls git to clone a new repo into a supplied destination,
74
+ # it will also call a supplied block with the percentage of clone completion
75
+ #
76
+ # #### Parameters
77
+ #
78
+ # * `repo_with_branch` - a git url for git to clone the repo from
79
+ # * `dest` - a filepath to where the repo should be cloned to
80
+ # * `ctx` - the current running context of your command, defaults to a new context.
81
+ #
82
+ # #### Returns
83
+ #
84
+ # * `sha_string` - string of the sha of the most recent commit to the repo
85
+ #
86
+ # #### Example
87
+ #
88
+ # FluidCLI::Git.raw_clone('git@github.com:fluid-commerce/test.git', 'test-app')
89
+ #
90
+ def raw_clone(repo_with_branch, dest, ctx: Context.new)
91
+ if Dir.exist?(dest) && !Dir.empty?(dest)
92
+ ctx.abort(ctx.message("core.git.error.directory_exists"))
93
+ else
94
+ msg = []
95
+ # require at usage point to not slow down CLI startup
96
+ # https://github.com/Shopify/shopify-cli/pull/698#discussion_r444342445
97
+ require "open3"
98
+
99
+ repo, branch = repo_with_branch.split("#")
100
+ git_cmd = git_clone_command(repo, dest, branch)
101
+
102
+ success = Open3.popen3("git", *git_cmd, "--progress") do |_stdin, _stdout, stderr, thread|
103
+ msg = clone_progress(stderr, bar: nil)
104
+
105
+ thread.value
106
+ end.success?
107
+
108
+ ctx.abort((msg.join("\n"))) unless success
109
+ end
110
+ end
111
+
112
+ ##
113
+ # calls git to clone a new repo into a supplied destination,
114
+ # it will also output progress of the cloning process into a new progress bar
115
+ #
116
+ # #### Parameters
117
+ #
118
+ # * `repo_with_branch` - a git url for git to clone the repo from
119
+ # * `dest` - a filepath to where the repo should be cloned to
120
+ # * `ctx` - the current running context of your command, defaults to a new context.
121
+ #
122
+ # #### Returns
123
+ #
124
+ # * `sha_string` - string of the sha of the most recent commit to the repo
125
+ #
126
+ # #### Example
127
+ #
128
+ # FluidCLI::Git.clone('git@github.com:fluid-commerce/test.git', 'test-app')
129
+ #
130
+ def clone(repo_with_branch, dest, ctx: Context.new)
131
+ if Dir.exist?(dest) && !Dir.empty?(dest)
132
+ ctx.abort("Directory #{dest} already exists and is not empty.")
133
+ else
134
+ msg = []
135
+ # require at usage point to not slow down CLI startup
136
+ # https://github.com/Shopify/shopify-cli/pull/698#discussion_r444342445
137
+ require "open3"
138
+
139
+ repo, branch = repo_with_branch.split("#")
140
+ git_cmd = git_clone_command(repo, dest, branch)
141
+
142
+ success_message = "{{success:Cloned repository into #{dest}}}"
143
+
144
+ CLI::UI::Frame.open("Cloning #{repo} into #{dest}", success_text: success_message) do
145
+ CLI::UI::Progress.progress do |bar|
146
+ success = Open3.popen3("git", *git_cmd, "--progress") do |_stdin, _stdout, stderr, thread|
147
+ msg = clone_progress(stderr, bar: bar)
148
+
149
+ thread.value
150
+ end.success?
151
+
152
+ ctx.abort((msg.join("\n"))) unless success
153
+ bar.tick(set_percent: 1.0)
154
+ end
155
+ end
156
+ end
157
+ end
158
+
159
+ ##
160
+ # will fetch the repos list of branches.
161
+ #
162
+ # #### Parameters
163
+ #
164
+ # * `ctx` - the current running context of your command, defaults to a new context.
165
+ #
166
+ # #### Returns
167
+ #
168
+ # * `branches` - [String] an array of strings that are branch names
169
+ #
170
+ # #### Example
171
+ #
172
+ # branches = FluidCLI::Git.branches(@ctx)
173
+ #
174
+ def branches(ctx)
175
+ output, status = ctx.capture2e("git", "branch", "--list", "--format=%(refname:short)")
176
+ ctx.abort(ctx.message("core.git.error.no_branches_found")) unless status.success?
177
+
178
+ branches = if output == ""
179
+ ["master"]
180
+ else
181
+ output.split("\n")
182
+ end
183
+
184
+ branches
185
+ end
186
+
187
+ ##
188
+ # Run git three-way file merge (it doesn't require an initialized git repository)
189
+ #
190
+ # #### Parameters
191
+ #
192
+ # * `current_file - string path of the current file
193
+ # * `base_file` - string path of the base file
194
+ # * `other_file` - string path of the other file
195
+ # * `opts` - list of "git merge-file" options. Valid values:
196
+ # - "-q" - do not warn about conflicts
197
+ # - "--diff3" - show conflicts
198
+ # - "--ours" - resolve conflicts favoring lines from `current_file`
199
+ # - "--theirs" - resolve conflicts favoring lines from `other_file`
200
+ # - "--union" - resolve conflicts favoring lines from both files
201
+ # - "-p" - send results to standard output instead of
202
+ # overwriting the `current_file`
203
+ # * `ctx` - the current running context of your command, defaults to a new context
204
+ #
205
+ # #### Returns
206
+ #
207
+ # * standard output from git
208
+ #
209
+ # #### Example
210
+ #
211
+ # output = FluidCLI::Git.merge_file(current_file, base_file, other_file, opts, ctx: ctx)
212
+ #
213
+ def merge_file(current_file, base_file, other_file, opts = [], ctx: Context.new)
214
+ output, status = ctx.capture2e("git", "merge-file", current_file, base_file, other_file, *opts)
215
+
216
+ unless status.success?
217
+ ctx.abort(ctx.message("core.git.error.merge_failed"))
218
+ end
219
+
220
+ output
221
+ end
222
+
223
+ ##
224
+ # will initialize a new repo in the current directory. This will output
225
+ # if it was successful or not.
226
+ #
227
+ # #### Parameters
228
+ #
229
+ # * `ctx` - the current running context of your command, defaults to a new context.
230
+ #
231
+ # #### Example
232
+ #
233
+ # FluidCLI::Git.init(@ctx)
234
+ #
235
+ def init(ctx)
236
+ output, status = ctx.capture2e("git", "status")
237
+
238
+ unless status.success?
239
+ ctx.abort(ctx.message("core.git.error.repo_not_initiated"))
240
+ end
241
+
242
+ if output.include?("No commits yet")
243
+ ctx.abort(ctx.message("core.git.error.no_commits_made"))
244
+ end
245
+ end
246
+
247
+ def sparse_checkout(repo, set, branch, ctx)
248
+ _, status = ctx.capture2e("git init")
249
+ unless status.success?
250
+ ctx.abort(ctx.message("core.git.error.repo_not_initiated"))
251
+ end
252
+
253
+ _, status = ctx.capture2e("git remote add -f origin #{repo}")
254
+ unless status.success?
255
+ ctx.abort(ctx.message("core.git.error.remote_not_added"))
256
+ end
257
+
258
+ _, status = ctx.capture2e("git config core.sparsecheckout true")
259
+ unless status.success?
260
+ ctx.abort(ctx.message("core.git.error.sparse_checkout_not_enabled"))
261
+ end
262
+
263
+ _, status = ctx.capture2e("git sparse-checkout set #{set}")
264
+ unless status.success?
265
+ ctx.abort(ctx.message("core.git.error.sparse_checkout_not_set"))
266
+ end
267
+
268
+ resp, status = ctx.capture2e("git pull origin #{branch}")
269
+ unless status.success?
270
+ if resp.include?("fatal: couldn't find remote ref")
271
+ ctx.abort(ctx.message("core.git.error.pull_failed_bad_branch", branch))
272
+ end
273
+ ctx.abort(ctx.message("core.git.error.pull_failed"))
274
+ end
275
+ end
276
+
277
+ ##
278
+ # handles showing the progress of the git clone command.
279
+ # if block given, assumes passing percent to block, otherwise
280
+ # increments bar for progress bar
281
+ #
282
+ # #### Parameters
283
+ #
284
+ # * `stderr` - Open3.popen3 output stream
285
+ # * `bar` - progress bar object to set percent
286
+ #
287
+ def clone_progress(stderr, bar: nil)
288
+ msg = []
289
+
290
+ while (line = stderr.gets)
291
+ msg << line.chomp
292
+ next unless line.strip.start_with?("Receiving objects:")
293
+ percent = (line.match(/Receiving objects:\s+(\d+)/)[1].to_f / 100).round(2)
294
+
295
+ if block_given?
296
+ yield percent
297
+ elsif !bar.nil?
298
+ bar.tick(set_percent: percent)
299
+ end
300
+ end
301
+
302
+ msg
303
+ end
304
+
305
+ private
306
+
307
+ def exec(*args, dir: Dir.pwd, default: nil, ctx: Context.new)
308
+ args = %w(git) + ["--git-dir", File.join(dir, ".git")] + args
309
+ out, _, stat = ctx.capture3(*args)
310
+ return default unless stat.success?
311
+ out.chomp
312
+ end
313
+
314
+ def rev_parse(*args, dir: nil, ctx: Context.new)
315
+ exec("rev-parse", *args, dir: dir, ctx: ctx)
316
+ end
317
+ end
318
+ end
319
+ end
@@ -0,0 +1,54 @@
1
+ require "net/http"
2
+ require "openssl"
3
+ require 'net/http/post/multipart'
4
+
5
+ module FluidCLI
6
+ class HttpRequest
7
+ class << self
8
+ def post(uri, body, headers)
9
+ req = ::Net::HTTP::Post.new(uri.request_uri)
10
+ request(uri, body, headers, req)
11
+ end
12
+
13
+ def put(uri, body, headers)
14
+ req = ::Net::HTTP::Put.new(uri.request_uri)
15
+ request(uri, body, headers, req)
16
+ end
17
+
18
+ def get(uri, body, headers)
19
+ req = ::Net::HTTP::Get.new(uri.request_uri)
20
+ request(uri, body, headers, req)
21
+ end
22
+
23
+ def delete(uri, body, headers)
24
+ req = ::Net::HTTP::Delete.new(uri.request_uri)
25
+ request(uri, body, headers, req)
26
+ end
27
+
28
+ def multipart_put(uri, body, headers)
29
+ req = Net::HTTP::Put::Multipart.new(uri.request_uri, body)
30
+ request(uri, nil, headers, req)
31
+ end
32
+
33
+ def request(uri, body, headers, req)
34
+ cert_store = OpenSSL::X509::Store.new
35
+ cert_store.set_default_paths
36
+
37
+ http = ::Net::HTTP.new(uri.host, uri.port)
38
+ http.use_ssl = uri.scheme == "https"
39
+ http.cert_store = cert_store
40
+ http.verify_mode = OpenSSL::SSL::VERIFY_NONE if ENV["SSL_VERIFY_NONE"]
41
+
42
+ unless req.is_a?(Net::HTTP::Put::Multipart)
43
+ req.body = body unless body.nil?
44
+ req["Content-Type"] = "application/json"
45
+ headers.each { |header, value| req[header] = value }
46
+ else
47
+ headers.each { |header, value| req.add_field(header, value) }
48
+ end
49
+
50
+ http.request(req)
51
+ end
52
+ end
53
+ end
54
+ end
@@ -0,0 +1,39 @@
1
+ module FluidCLI
2
+ class IdentityAuth
3
+ class Servlet < WEBrick::HTTPServlet::AbstractServlet
4
+ ERB_FILENAME = File.join(FluidCLI::ROOT, "lib/fluid_cli/assets/post_auth_page/index.html.erb")
5
+ CSS_FILENAME = File.join(FluidCLI::ROOT, "lib/fluid_cli/assets/post_auth_page/style.css")
6
+
7
+ def initialize(server, identity_auth, token)
8
+ super
9
+ @server = server
10
+ @identity_auth = identity_auth
11
+ end
12
+
13
+ def do_GET(req, res) # rubocop:disable Naming/MethodName
14
+ if !req.query["error"].nil?
15
+ respond_with(
16
+ res,
17
+ 400,
18
+ req.query["error"],
19
+ )
20
+ else
21
+ respond_with(res, 200, "Authentication successful! You can close this window.")
22
+ end
23
+ @identity_auth.response_query = req.query
24
+ @server.shutdown
25
+ end
26
+
27
+ def respond_with(response, status, message)
28
+ successful = status == 200
29
+ locals = {
30
+ status: status,
31
+ message: message,
32
+ css: File.read(CSS_FILENAME),
33
+ }
34
+ response.status = status
35
+ response.body = ERB.new(File.read(ERB_FILENAME)).result(binding)
36
+ end
37
+ end
38
+ end
39
+ end