brut 0.17.0 → 0.18.0

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 (1104) hide show
  1. checksums.yaml +4 -4
  2. data/exe/brut +34 -0
  3. data/lib/brut/cli/apps/build_assets.rb +78 -48
  4. data/lib/brut/cli/apps/db.rb +168 -202
  5. data/lib/brut/cli/apps/deploy.rb +291 -0
  6. data/lib/brut/cli/apps/heroku_container_based_deploy.rb +6 -0
  7. data/{mkbrut/lib/mkbrut → lib/brut/cli/apps/new}/add_segment.rb +5 -5
  8. data/{mkbrut/lib/mkbrut → lib/brut/cli/apps/new}/add_segment_options.rb +1 -1
  9. data/lib/brut/cli/apps/new/app.rb +240 -0
  10. data/{mkbrut/lib/mkbrut → lib/brut/cli/apps/new}/app_id.rb +1 -1
  11. data/lib/brut/cli/apps/new/app_name.rb +29 -0
  12. data/{mkbrut/lib/mkbrut → lib/brut/cli/apps/new}/base.rb +9 -6
  13. data/lib/brut/cli/apps/new/erb_binding_delegate.rb +23 -0
  14. data/{mkbrut/lib/mkbrut → lib/brut/cli/apps/new}/internet_identifier.rb +5 -5
  15. data/{mkbrut/lib/mkbrut → lib/brut/cli/apps/new}/invalid_identifier.rb +1 -1
  16. data/{mkbrut/lib/mkbrut/app.rb → lib/brut/cli/apps/new/old_app.rb} +8 -11
  17. data/{mkbrut/lib/mkbrut → lib/brut/cli/apps/new}/ops/add_css_import.rb +1 -1
  18. data/{mkbrut/lib/mkbrut → lib/brut/cli/apps/new}/ops/add_i18n_message.rb +1 -1
  19. data/{mkbrut/lib/mkbrut → lib/brut/cli/apps/new}/ops/add_method.rb +1 -1
  20. data/{mkbrut/lib/mkbrut → lib/brut/cli/apps/new}/ops/append_to_file.rb +1 -1
  21. data/{mkbrut/lib/mkbrut → lib/brut/cli/apps/new}/ops/base_op.rb +3 -3
  22. data/{mkbrut/lib/mkbrut → lib/brut/cli/apps/new}/ops/copy_file.rb +1 -1
  23. data/{mkbrut/lib/mkbrut → lib/brut/cli/apps/new}/ops/insert_code_in_method.rb +1 -1
  24. data/{mkbrut/lib/mkbrut → lib/brut/cli/apps/new}/ops/insert_into_file.rb +1 -1
  25. data/{mkbrut/lib/mkbrut → lib/brut/cli/apps/new}/ops/insert_route.rb +1 -1
  26. data/{mkbrut/lib/mkbrut → lib/brut/cli/apps/new}/ops/mkdir.rb +1 -1
  27. data/{mkbrut/lib/mkbrut → lib/brut/cli/apps/new}/ops/prism_parsing_op.rb +1 -1
  28. data/{mkbrut/lib/mkbrut → lib/brut/cli/apps/new}/ops/render_template.rb +1 -1
  29. data/{mkbrut/lib/mkbrut → lib/brut/cli/apps/new}/ops/skip_file.rb +1 -1
  30. data/lib/brut/cli/apps/new/ops.rb +17 -0
  31. data/lib/brut/cli/apps/new/organization.rb +5 -0
  32. data/{mkbrut/lib/mkbrut → lib/brut/cli/apps/new}/prefix.rb +1 -1
  33. data/{mkbrut/lib/mkbrut → lib/brut/cli/apps/new}/segments/bare_bones.rb +12 -11
  34. data/{mkbrut/lib/mkbrut → lib/brut/cli/apps/new}/segments/demo.rb +16 -15
  35. data/{mkbrut/lib/mkbrut → lib/brut/cli/apps/new}/segments/heroku.rb +9 -5
  36. data/{mkbrut/lib/mkbrut → lib/brut/cli/apps/new}/segments/sidekiq.rb +44 -21
  37. data/lib/brut/cli/apps/new/segments.rb +8 -0
  38. data/lib/brut/cli/apps/new/version.rb +3 -0
  39. data/{mkbrut/lib/mkbrut → lib/brut/cli/apps/new}/versions.rb +2 -2
  40. data/lib/brut/cli/apps/new.rb +26 -0
  41. data/lib/brut/cli/apps/scaffold.rb +150 -141
  42. data/lib/brut/cli/apps/test.rb +92 -68
  43. data/lib/brut/cli/commands/base_command.rb +174 -0
  44. data/lib/brut/cli/commands/compound_command.rb +29 -0
  45. data/lib/brut/cli/commands/execution_context.rb +32 -0
  46. data/lib/brut/cli/commands/help.rb +26 -0
  47. data/lib/brut/cli/commands/output_error.rb +13 -0
  48. data/lib/brut/cli/commands/raise_error.rb +11 -0
  49. data/lib/brut/cli/commands.rb +8 -0
  50. data/lib/brut/cli/execute_result.rb +39 -0
  51. data/lib/brut/cli/executor.rb +9 -4
  52. data/lib/brut/cli/output.rb +13 -0
  53. data/lib/brut/cli/parsed_command_line.rb +143 -0
  54. data/lib/brut/cli/runner.rb +124 -0
  55. data/lib/brut/cli.rb +7 -29
  56. data/lib/brut/framework/container.rb +1 -1
  57. data/lib/brut/framework/mcp.rb +59 -13
  58. data/lib/brut/framework/project_environment.rb +3 -1
  59. data/lib/brut/junk_drawer.rb +3 -1
  60. data/lib/brut/spec_support/cli_command_support.rb +45 -0
  61. data/lib/brut/spec_support/e2e_test_server.rb +3 -0
  62. data/lib/brut/spec_support/general_support.rb +1 -1
  63. data/lib/brut/spec_support/matchers/have_executed.rb +35 -0
  64. data/lib/brut/spec_support/rspec_setup.rb +4 -8
  65. data/lib/brut/spec_support.rb +1 -0
  66. data/lib/brut/tui/markup_string.rb +2 -0
  67. data/lib/brut/tui/script/events/command_std_out.rb +3 -2
  68. data/lib/brut/tui/script/exec_step.rb +11 -4
  69. data/lib/brut/tui/script/puts_subscriber.rb +4 -4
  70. data/lib/brut/tui/script.rb +7 -3
  71. data/lib/brut/tui/terminal_theme.rb +15 -11
  72. data/lib/brut/version.rb +1 -1
  73. data/templates/Base/.env.development.local +2 -0
  74. data/templates/Base/bin/ci +42 -0
  75. data/{mkbrut/templates → templates}/Base/bin/release +2 -2
  76. data/templates/Base/bin/setup +174 -0
  77. data/{mkbrut/templates → templates}/Base/bin/watch-and-build-assets +1 -1
  78. data/{mkbrut/templates → templates}/Base/dx/docker-compose.env.erb +1 -1
  79. data/{mkbrut/templates → templates}/segments/Demo/app/src/front_end/css/fonts.css +1 -1
  80. data/{mkbrut/templates → templates}/segments/Heroku/deploy/Dockerfile +2 -2
  81. data/templates/segments/Heroku/deploy/docker_config.rb +30 -0
  82. metadata +191 -1055
  83. data/.gitignore +0 -61
  84. data/.projections.json +0 -10
  85. data/CHANGELOG.md +0 -172
  86. data/CODE_OF_CONDUCT.txt +0 -99
  87. data/Dockerfile.dx +0 -82
  88. data/Gemfile +0 -6
  89. data/Gemfile.lock +0 -246
  90. data/LICENSE.txt +0 -370
  91. data/README.md +0 -90
  92. data/Rakefile +0 -25
  93. data/assets/Logo-Square.pxd +0 -0
  94. data/assets/LogoPylon.pxd +0 -0
  95. data/assets/LogoStop.pxd +0 -0
  96. data/assets/LogoTall.pxd +0 -0
  97. data/assets/MetroIcon.graffle +0 -0
  98. data/assets/MetroLogo.graffle +0 -0
  99. data/assets/SocialImage.png +0 -0
  100. data/assets/SocialImage.pxd +0 -0
  101. data/assets/YouTubeThumb.pxd +0 -0
  102. data/bin/bin_kit.rb +0 -51
  103. data/bin/build +0 -86
  104. data/bin/ci +0 -40
  105. data/bin/dev +0 -20
  106. data/bin/docs +0 -86
  107. data/bin/generate-and-run-rubocop +0 -52
  108. data/bin/new-version +0 -8
  109. data/bin/publish +0 -61
  110. data/bin/rake +0 -27
  111. data/bin/rspec +0 -27
  112. data/bin/rubocop +0 -27
  113. data/bin/setup +0 -252
  114. data/bin/test +0 -18
  115. data/brut-css/.nvim.lua +0 -1
  116. data/brut-css/README.md +0 -28
  117. data/brut-css/bin/build +0 -50
  118. data/brut-css/bin/ci +0 -19
  119. data/brut-css/bin/dev +0 -1
  120. data/brut-css/bin/docs +0 -34
  121. data/brut-css/bin/publish +0 -21
  122. data/brut-css/bin/setup +0 -6
  123. data/brut-css/config/media-queries-all.css +0 -15
  124. data/brut-css/config/media-queries-minimal.css +0 -5
  125. data/brut-css/config/postcss.config.cjs +0 -7
  126. data/brut-css/config/pseudo-classes-all.css +0 -9
  127. data/brut-css/dx +0 -1
  128. data/brut-css/package-lock.json +0 -3165
  129. data/brut-css/package.json +0 -36
  130. data/brut-css/src/css/appearance.css +0 -145
  131. data/brut-css/src/css/border.css +0 -522
  132. data/brut-css/src/css/colors.css +0 -3502
  133. data/brut-css/src/css/dimensions.css +0 -548
  134. data/brut-css/src/css/flex.css +0 -179
  135. data/brut-css/src/css/index.css +0 -13
  136. data/brut-css/src/css/layout.css +0 -120
  137. data/brut-css/src/css/list.css +0 -41
  138. data/brut-css/src/css/positioning.css +0 -354
  139. data/brut-css/src/css/properties/colors.css +0 -455
  140. data/brut-css/src/css/properties/index.css +0 -3
  141. data/brut-css/src/css/properties/spacing.css +0 -140
  142. data/brut-css/src/css/properties/typography.css +0 -224
  143. data/brut-css/src/css/reset.css +0 -107
  144. data/brut-css/src/css/spacing.css +0 -585
  145. data/brut-css/src/css/typography.css +0 -519
  146. data/brut-css/src/css/utils.css +0 -104
  147. data/brut-css/src/docs/1_getting-started/1_overview.md +0 -46
  148. data/brut-css/src/docs/1_getting-started/2_installation.md +0 -25
  149. data/brut-css/src/docs/1_getting-started/3_core-concepts.md +0 -75
  150. data/brut-css/src/docs/1_getting-started/4_simple-example.md +0 -132
  151. data/brut-css/src/docs/1_getting-started/page.html.ejs +0 -10
  152. data/brut-css/src/docs/2_properties/page.html.ejs +0 -71
  153. data/brut-css/src/docs/3_classes/color-demo.html.ejs +0 -31
  154. data/brut-css/src/docs/3_classes/page.html.ejs +0 -87
  155. data/brut-css/src/docs/4_customization/1_design-system.md +0 -36
  156. data/brut-css/src/docs/4_customization/2_breakpoints.md +0 -75
  157. data/brut-css/src/docs/4_customization/3_pseudo-classes.md +0 -74
  158. data/brut-css/src/docs/4_customization/4_advanced-configuration.md +0 -40
  159. data/brut-css/src/docs/4_customization/page.html.ejs +0 -10
  160. data/brut-css/src/docs/docs.css +0 -98
  161. data/brut-css/src/docs/includes/body-and-header.html.ejs +0 -30
  162. data/brut-css/src/docs/includes/footer-and-rest.html.ejs +0 -9
  163. data/brut-css/src/docs/includes/head.html.ejs +0 -5
  164. data/brut-css/src/docs/includes/nav.html.ejs +0 -10
  165. data/brut-css/src/docs/index.html.ejs +0 -32
  166. data/brut-css/src/docs/prism-twilight.min.css +0 -1
  167. data/brut-css/src/js/Logger.js +0 -71
  168. data/brut-css/src/js/build.js +0 -111
  169. data/brut-css/src/js/cli/CLIArgError.js +0 -7
  170. data/brut-css/src/js/cli/Debug.js +0 -27
  171. data/brut-css/src/js/cli/DocsDir.js +0 -16
  172. data/brut-css/src/js/cli/DocsTemplateSourceDir.js +0 -16
  173. data/brut-css/src/js/cli/InputFile.js +0 -31
  174. data/brut-css/src/js/cli/MediaQueryConfigFile.js +0 -10
  175. data/brut-css/src/js/cli/OutputFile.js +0 -22
  176. data/brut-css/src/js/cli/ParsedArg.js +0 -17
  177. data/brut-css/src/js/cli/PathToBrutCSSRoot.js +0 -19
  178. data/brut-css/src/js/cli/PseudoClassConfigFile.js +0 -11
  179. data/brut-css/src/js/cli.js +0 -108
  180. data/brut-css/src/js/docGenerator.js +0 -467
  181. data/brut-css/src/js/mediaQueryConfigParser.js +0 -98
  182. data/brut-css/src/js/post-css-plugins/addMediaQueriesPlugin.js +0 -49
  183. data/brut-css/src/js/post-css-plugins/addPseudoClassesPlugin.js +0 -42
  184. data/brut-css/src/js/post-css-plugins/generateDocumentationPlugin/Category.js +0 -9
  185. data/brut-css/src/js/post-css-plugins/generateDocumentationPlugin/DocState.js +0 -185
  186. data/brut-css/src/js/post-css-plugins/generateDocumentationPlugin/Documentable.js +0 -8
  187. data/brut-css/src/js/post-css-plugins/generateDocumentationPlugin/Group.js +0 -7
  188. data/brut-css/src/js/post-css-plugins/generateDocumentationPlugin/ParsedComment.js +0 -73
  189. data/brut-css/src/js/post-css-plugins/generateDocumentationPlugin/Property.js +0 -9
  190. data/brut-css/src/js/post-css-plugins/generateDocumentationPlugin/PropertyCategory.js +0 -4
  191. data/brut-css/src/js/post-css-plugins/generateDocumentationPlugin/PropertyGroup.js +0 -8
  192. data/brut-css/src/js/post-css-plugins/generateDocumentationPlugin/Rule.js +0 -12
  193. data/brut-css/src/js/post-css-plugins/generateDocumentationPlugin/RuleCategory.js +0 -4
  194. data/brut-css/src/js/post-css-plugins/generateDocumentationPlugin/RuleGroup.js +0 -8
  195. data/brut-css/src/js/post-css-plugins/generateDocumentationPlugin/SeeRef.js +0 -5
  196. data/brut-css/src/js/post-css-plugins/generateDocumentationPlugin/SeeURL.js +0 -9
  197. data/brut-css/src/js/post-css-plugins/generateDocumentationPlugin.js +0 -49
  198. data/brut-css/src/js/post-css-plugins/generateRootCustomPropertiesPlugin.js +0 -45
  199. data/brut-css/src/js/pseudoClassConfigParser.js +0 -145
  200. data/brut-js/.projections.json +0 -10
  201. data/brut-js/README.md +0 -118
  202. data/brut-js/bin/build +0 -19
  203. data/brut-js/bin/ci +0 -5
  204. data/brut-js/bin/docs +0 -25
  205. data/brut-js/bin/publish +0 -21
  206. data/brut-js/bin/setup +0 -6
  207. data/brut-js/docs/README.md +0 -8
  208. data/brut-js/docs/jsdoc-plugins/customElementTag.js +0 -8
  209. data/brut-js/docs/jsdoc-theme/publish.js +0 -692
  210. data/brut-js/docs/jsdoc-theme/static/scripts/linenumber.js +0 -25
  211. data/brut-js/docs/jsdoc-theme/static/scripts/prettify/Apache-License-2.0.txt +0 -202
  212. data/brut-js/docs/jsdoc-theme/static/scripts/prettify/lang-css.js +0 -2
  213. data/brut-js/docs/jsdoc-theme/static/scripts/prettify/prettify.js +0 -28
  214. data/brut-js/docs/jsdoc-theme/static/styles/jsdoc-default.css +0 -327
  215. data/brut-js/docs/jsdoc-theme/static/styles/prettify-jsdoc.css +0 -111
  216. data/brut-js/docs/jsdoc-theme/static/styles/prettify-tomorrow.css +0 -132
  217. data/brut-js/docs/jsdoc-theme/tmpl/augments.tmpl +0 -10
  218. data/brut-js/docs/jsdoc-theme/tmpl/container.tmpl +0 -199
  219. data/brut-js/docs/jsdoc-theme/tmpl/details.tmpl +0 -143
  220. data/brut-js/docs/jsdoc-theme/tmpl/example.tmpl +0 -2
  221. data/brut-js/docs/jsdoc-theme/tmpl/examples.tmpl +0 -13
  222. data/brut-js/docs/jsdoc-theme/tmpl/exceptions.tmpl +0 -32
  223. data/brut-js/docs/jsdoc-theme/tmpl/layout.tmpl +0 -38
  224. data/brut-js/docs/jsdoc-theme/tmpl/mainpage.tmpl +0 -14
  225. data/brut-js/docs/jsdoc-theme/tmpl/members.tmpl +0 -38
  226. data/brut-js/docs/jsdoc-theme/tmpl/method.tmpl +0 -131
  227. data/brut-js/docs/jsdoc-theme/tmpl/modifies.tmpl +0 -14
  228. data/brut-js/docs/jsdoc-theme/tmpl/params.tmpl +0 -131
  229. data/brut-js/docs/jsdoc-theme/tmpl/properties.tmpl +0 -108
  230. data/brut-js/docs/jsdoc-theme/tmpl/returns.tmpl +0 -19
  231. data/brut-js/docs/jsdoc-theme/tmpl/source.tmpl +0 -8
  232. data/brut-js/docs/jsdoc-theme/tmpl/tutorial.tmpl +0 -19
  233. data/brut-js/docs/jsdoc-theme/tmpl/type.tmpl +0 -7
  234. data/brut-js/docs/jsdoc.config.json +0 -23
  235. data/brut-js/docs/package-lock.json +0 -343
  236. data/brut-js/docs/package.json +0 -7
  237. data/brut-js/dx +0 -1
  238. data/brut-js/package-lock.json +0 -2210
  239. data/brut-js/package.json +0 -36
  240. data/brut-js/specs/AjaxSubmit.spec.js +0 -453
  241. data/brut-js/specs/Autosubmit.spec.js +0 -127
  242. data/brut-js/specs/ConfirmSubmit.spec.js +0 -224
  243. data/brut-js/specs/ConstraintViolationMessage.spec.js +0 -33
  244. data/brut-js/specs/ConstraintViolationMessages.spec.js +0 -32
  245. data/brut-js/specs/CopyToClipboard.spec.js +0 -35
  246. data/brut-js/specs/Form.spec.js +0 -137
  247. data/brut-js/specs/I18nTranslation.spec.js +0 -19
  248. data/brut-js/specs/LocaleDetection.spec.js +0 -22
  249. data/brut-js/specs/Message.spec.js +0 -15
  250. data/brut-js/specs/SpecHelper.js +0 -23
  251. data/brut-js/specs/Tabs.spec.js +0 -41
  252. data/brut-js/specs/Toast.spec.js +0 -34
  253. data/brut-js/specs/config/asset_metadata.json +0 -7
  254. data/brut-js/src/AjaxSubmit.js +0 -499
  255. data/brut-js/src/Autosubmit.js +0 -63
  256. data/brut-js/src/BaseCustomElement.js +0 -261
  257. data/brut-js/src/ConfirmSubmit.js +0 -137
  258. data/brut-js/src/ConfirmationDialog.js +0 -143
  259. data/brut-js/src/ConstraintViolationMessage.js +0 -140
  260. data/brut-js/src/ConstraintViolationMessages.js +0 -98
  261. data/brut-js/src/CopyToClipboard.js +0 -96
  262. data/brut-js/src/Form.js +0 -147
  263. data/brut-js/src/I18nTranslation.js +0 -64
  264. data/brut-js/src/LocaleDetection.js +0 -117
  265. data/brut-js/src/Logger.js +0 -90
  266. data/brut-js/src/Message.js +0 -62
  267. data/brut-js/src/RichString.js +0 -116
  268. data/brut-js/src/Tabs.js +0 -168
  269. data/brut-js/src/Toast.js +0 -102
  270. data/brut-js/src/Tracing.js +0 -247
  271. data/brut-js/src/appForTestingOnly.js +0 -15
  272. data/brut-js/src/index.js +0 -133
  273. data/brut-js/src/testing/AssetMetadata.js +0 -35
  274. data/brut-js/src/testing/AssetMetadataLoader.js +0 -25
  275. data/brut-js/src/testing/CustomElementTest.js +0 -235
  276. data/brut-js/src/testing/DOMCreator.js +0 -45
  277. data/brut-js/src/testing/index.js +0 -48
  278. data/brut.gemspec +0 -73
  279. data/brutrb.com/.vitepress/config.mjs +0 -164
  280. data/brutrb.com/.vitepress/plugins/jsdocLinker.js +0 -34
  281. data/brutrb.com/.vitepress/plugins/rdocLinker.js +0 -18
  282. data/brutrb.com/.vitepress/theme/custom.css +0 -14
  283. data/brutrb.com/.vitepress/theme/index.js +0 -18
  284. data/brutrb.com/.vitepress/theme/style.css +0 -139
  285. data/brutrb.com/adrs.md +0 -16
  286. data/brutrb.com/ai.md +0 -68
  287. data/brutrb.com/assets.md +0 -131
  288. data/brutrb.com/bin/build +0 -5
  289. data/brutrb.com/bin/deploy +0 -7
  290. data/brutrb.com/bin/dev +0 -5
  291. data/brutrb.com/bin/setup +0 -6
  292. data/brutrb.com/brut-js.md +0 -128
  293. data/brutrb.com/business-logic.md +0 -55
  294. data/brutrb.com/cli.md +0 -274
  295. data/brutrb.com/components.md +0 -265
  296. data/brutrb.com/configuration.md +0 -256
  297. data/brutrb.com/css.md +0 -103
  298. data/brutrb.com/custom-element-tests.md +0 -148
  299. data/brutrb.com/database-access.md +0 -201
  300. data/brutrb.com/database-schema.md +0 -320
  301. data/brutrb.com/deployment.md +0 -158
  302. data/brutrb.com/dev-environment.md +0 -186
  303. data/brutrb.com/dir-structure.md +0 -120
  304. data/brutrb.com/doc-conventions.md +0 -41
  305. data/brutrb.com/dx +0 -1
  306. data/brutrb.com/end-to-end-tests.md +0 -176
  307. data/brutrb.com/features.md +0 -373
  308. data/brutrb.com/flash-and-session.md +0 -208
  309. data/brutrb.com/form-constraints.md +0 -266
  310. data/brutrb.com/forms.md +0 -238
  311. data/brutrb.com/getting-started.md +0 -142
  312. data/brutrb.com/handlers.md +0 -177
  313. data/brutrb.com/hooks.md +0 -176
  314. data/brutrb.com/i18n.md +0 -190
  315. data/brutrb.com/images/DevEnvironment.graffle +0 -0
  316. data/brutrb.com/images/DevEnvironment.png +0 -0
  317. data/brutrb.com/images/LogoSquare.png +0 -0
  318. data/brutrb.com/images/LogoStop.png +0 -0
  319. data/brutrb.com/images/LogoTall.png +0 -0
  320. data/brutrb.com/images/Makefile +0 -10
  321. data/brutrb.com/images/OverviewMetro.graffle +0 -0
  322. data/brutrb.com/images/OverviewMetro.png +0 -0
  323. data/brutrb.com/images/dev-env-overview.dot +0 -54
  324. data/brutrb.com/images/dev-env-overview.png +0 -0
  325. data/brutrb.com/images/dev-env-protocol.dot +0 -37
  326. data/brutrb.com/images/dev-env-protocol.png +0 -0
  327. data/brutrb.com/images/overview.graffle +0 -0
  328. data/brutrb.com/images/overview.png +0 -0
  329. data/brutrb.com/images/spa.dot +0 -19
  330. data/brutrb.com/images/spa.png +0 -0
  331. data/brutrb.com/images/tutorial/02-confirmation-dialog-browser-element-styled.png +0 -0
  332. data/brutrb.com/images/tutorial/02-confirmation-dialog-browser-element.png +0 -0
  333. data/brutrb.com/images/tutorial/02-confirmation-dialog-browser.png +0 -0
  334. data/brutrb.com/images/tutorial/02-confirmation-flow.graffle +0 -0
  335. data/brutrb.com/images/tutorial/02-confirmation-flow.png +0 -0
  336. data/brutrb.com/images/tutorial/basic-form-with-violations.png +0 -0
  337. data/brutrb.com/images/tutorial/basic-form.png +0 -0
  338. data/brutrb.com/images/tutorial/initial-home-page.png +0 -0
  339. data/brutrb.com/images/tutorial/new-post-editor.png +0 -0
  340. data/brutrb.com/images/tutorial/new-post-home-page.png +0 -0
  341. data/brutrb.com/images/tutorial/styled-form-with-server-side-violations.png +0 -0
  342. data/brutrb.com/images/tutorial/styled-form-with-violations.png +0 -0
  343. data/brutrb.com/images/tutorial/styled-home-page-with-posts.png +0 -0
  344. data/brutrb.com/images/tutorial/styled-home-page.png +0 -0
  345. data/brutrb.com/images/tutorial/welcome-to-brut.png +0 -0
  346. data/brutrb.com/images/workspace-protocol.dot +0 -44
  347. data/brutrb.com/images/workspace-protocol.png +0 -0
  348. data/brutrb.com/index.md +0 -34
  349. data/brutrb.com/instrumentation.md +0 -331
  350. data/brutrb.com/javascript.md +0 -122
  351. data/brutrb.com/jobs.md +0 -114
  352. data/brutrb.com/keyword-injection.md +0 -195
  353. data/brutrb.com/layouts.md +0 -156
  354. data/brutrb.com/lsp.md +0 -23
  355. data/brutrb.com/markdown-examples.md +0 -85
  356. data/brutrb.com/middleware.md +0 -80
  357. data/brutrb.com/overview.md +0 -68
  358. data/brutrb.com/package-lock.json +0 -2451
  359. data/brutrb.com/package.json +0 -11
  360. data/brutrb.com/pages.md +0 -290
  361. data/brutrb.com/public/SocialImage.png +0 -0
  362. data/brutrb.com/public/favicon.ico +0 -0
  363. data/brutrb.com/recipes/alternate-layouts.md +0 -32
  364. data/brutrb.com/recipes/authentication.md +0 -336
  365. data/brutrb.com/recipes/custom-flash.md +0 -51
  366. data/brutrb.com/recipes/dev-env-secrets.md +0 -87
  367. data/brutrb.com/recipes/form-errors.md +0 -148
  368. data/brutrb.com/recipes/indexed-forms.md +0 -149
  369. data/brutrb.com/recipes/migrations.md +0 -210
  370. data/brutrb.com/recipes/text-field-component.md +0 -182
  371. data/brutrb.com/roadmap.md +0 -52
  372. data/brutrb.com/routes.md +0 -189
  373. data/brutrb.com/security.md +0 -102
  374. data/brutrb.com/seed-data.md +0 -63
  375. data/brutrb.com/space-time-continuum.md +0 -81
  376. data/brutrb.com/tutorial.md +0 -138
  377. data/brutrb.com/tutorials/01-intro.md +0 -1654
  378. data/brutrb.com/tutorials/02-dialog.md +0 -569
  379. data/brutrb.com/unit-tests.md +0 -148
  380. data/brutrb.com/why.md +0 -19
  381. data/docker-compose.dx.yml +0 -25
  382. data/docs/404.html +0 -26
  383. data/docs/CNAME +0 -1
  384. data/docs/SocialImage.png +0 -0
  385. data/docs/adrs.html +0 -29
  386. data/docs/ai.html +0 -29
  387. data/docs/api/Brut/BackEnd/SeedData.html +0 -493
  388. data/docs/api/Brut/BackEnd/Sidekiq/Middlewares/Server/FlushSpans.html +0 -214
  389. data/docs/api/Brut/BackEnd/Sidekiq/Middlewares/Server.html +0 -125
  390. data/docs/api/Brut/BackEnd/Sidekiq/Middlewares.html +0 -125
  391. data/docs/api/Brut/BackEnd/Sidekiq.html +0 -125
  392. data/docs/api/Brut/BackEnd/Validators/FormValidator.html +0 -414
  393. data/docs/api/Brut/BackEnd/Validators.html +0 -128
  394. data/docs/api/Brut/BackEnd.html +0 -132
  395. data/docs/api/Brut/CLI/App.html +0 -1601
  396. data/docs/api/Brut/CLI/AppRunner.html +0 -491
  397. data/docs/api/Brut/CLI/Apps/BuildAssets/All.html +0 -264
  398. data/docs/api/Brut/CLI/Apps/BuildAssets/CSS.html +0 -306
  399. data/docs/api/Brut/CLI/Apps/BuildAssets/Images.html +0 -262
  400. data/docs/api/Brut/CLI/Apps/BuildAssets/JS.html +0 -314
  401. data/docs/api/Brut/CLI/Apps/BuildAssets.html +0 -183
  402. data/docs/api/Brut/CLI/Apps/DB/Create.html +0 -365
  403. data/docs/api/Brut/CLI/Apps/DB/Drop.html +0 -357
  404. data/docs/api/Brut/CLI/Apps/DB/Migrate.html +0 -389
  405. data/docs/api/Brut/CLI/Apps/DB/NewMigration.html +0 -339
  406. data/docs/api/Brut/CLI/Apps/DB/Rebuild.html +0 -329
  407. data/docs/api/Brut/CLI/Apps/DB/Seed.html +0 -347
  408. data/docs/api/Brut/CLI/Apps/DB/Status.html +0 -383
  409. data/docs/api/Brut/CLI/Apps/DB.html +0 -183
  410. data/docs/api/Brut/CLI/Apps/DeployBase/GitChecks.html +0 -270
  411. data/docs/api/Brut/CLI/Apps/DeployBase.html +0 -257
  412. data/docs/api/Brut/CLI/Apps/HerokuContainerBasedDeploy/Deploy.html +0 -587
  413. data/docs/api/Brut/CLI/Apps/HerokuContainerBasedDeploy.html +0 -196
  414. data/docs/api/Brut/CLI/Apps/Scaffold/Action/Route.html +0 -303
  415. data/docs/api/Brut/CLI/Apps/Scaffold/Action.html +0 -508
  416. data/docs/api/Brut/CLI/Apps/Scaffold/Component.html +0 -398
  417. data/docs/api/Brut/CLI/Apps/Scaffold/CustomElementTest.html +0 -374
  418. data/docs/api/Brut/CLI/Apps/Scaffold/DbModel.html +0 -384
  419. data/docs/api/Brut/CLI/Apps/Scaffold/E2ETest.html +0 -410
  420. data/docs/api/Brut/CLI/Apps/Scaffold/Form.html +0 -262
  421. data/docs/api/Brut/CLI/Apps/Scaffold/Page/Route.html +0 -303
  422. data/docs/api/Brut/CLI/Apps/Scaffold/Page.html +0 -480
  423. data/docs/api/Brut/CLI/Apps/Scaffold/RoutesEditor.html +0 -450
  424. data/docs/api/Brut/CLI/Apps/Scaffold/Test.html +0 -380
  425. data/docs/api/Brut/CLI/Apps/Scaffold.html +0 -253
  426. data/docs/api/Brut/CLI/Apps/Test/Audit.html +0 -474
  427. data/docs/api/Brut/CLI/Apps/Test/E2e.html +0 -407
  428. data/docs/api/Brut/CLI/Apps/Test/JS.html +0 -262
  429. data/docs/api/Brut/CLI/Apps/Test/Run.html +0 -578
  430. data/docs/api/Brut/CLI/Apps/Test.html +0 -253
  431. data/docs/api/Brut/CLI/Apps.html +0 -125
  432. data/docs/api/Brut/CLI/Command.html +0 -2425
  433. data/docs/api/Brut/CLI/Error.html +0 -139
  434. data/docs/api/Brut/CLI/ExecutionResults/Result.html +0 -664
  435. data/docs/api/Brut/CLI/ExecutionResults.html +0 -675
  436. data/docs/api/Brut/CLI/Executor.html +0 -561
  437. data/docs/api/Brut/CLI/InvalidOption.html +0 -245
  438. data/docs/api/Brut/CLI/Options.html +0 -880
  439. data/docs/api/Brut/CLI/Output.html +0 -699
  440. data/docs/api/Brut/CLI/SystemExecError.html +0 -451
  441. data/docs/api/Brut/CLI.html +0 -263
  442. data/docs/api/Brut/FactoryBot.html +0 -225
  443. data/docs/api/Brut/Framework/App.html +0 -1097
  444. data/docs/api/Brut/Framework/Config.html +0 -1071
  445. data/docs/api/Brut/Framework/Container.html +0 -1464
  446. data/docs/api/Brut/Framework/Error.html +0 -140
  447. data/docs/api/Brut/Framework/Errors/AbstractMethod.html +0 -232
  448. data/docs/api/Brut/Framework/Errors/Bug.html +0 -234
  449. data/docs/api/Brut/Framework/Errors/MissingConfiguration.html +0 -257
  450. data/docs/api/Brut/Framework/Errors/MissingParameter.html +0 -273
  451. data/docs/api/Brut/Framework/Errors/NoClassForPath.html +0 -471
  452. data/docs/api/Brut/Framework/Errors/NotFound.html +0 -308
  453. data/docs/api/Brut/Framework/Errors/NotImplemented.html +0 -234
  454. data/docs/api/Brut/Framework/Errors.html +0 -351
  455. data/docs/api/Brut/Framework/FussyTypeEnforcement.html +0 -392
  456. data/docs/api/Brut/Framework/MCP.html +0 -871
  457. data/docs/api/Brut/Framework/ProjectEnvironment.html +0 -648
  458. data/docs/api/Brut/Framework.html +0 -129
  459. data/docs/api/Brut/FrontEnd/AssetPathResolver.html +0 -317
  460. data/docs/api/Brut/FrontEnd/Component/Helpers.html +0 -420
  461. data/docs/api/Brut/FrontEnd/Component.html +0 -434
  462. data/docs/api/Brut/FrontEnd/Components/ConstraintViolations.html +0 -491
  463. data/docs/api/Brut/FrontEnd/Components/FormTag.html +0 -526
  464. data/docs/api/Brut/FrontEnd/Components/I18nTranslations.html +0 -313
  465. data/docs/api/Brut/FrontEnd/Components/Input.html +0 -195
  466. data/docs/api/Brut/FrontEnd/Components/Inputs/ButtonTag.html +0 -447
  467. data/docs/api/Brut/FrontEnd/Components/Inputs/CsrfToken.html +0 -339
  468. data/docs/api/Brut/FrontEnd/Components/Inputs/InputTag.html +0 -568
  469. data/docs/api/Brut/FrontEnd/Components/Inputs/RadioButton.html +0 -419
  470. data/docs/api/Brut/FrontEnd/Components/Inputs/SelectTagWithOptions.html +0 -610
  471. data/docs/api/Brut/FrontEnd/Components/Inputs/TextareaTag.html +0 -534
  472. data/docs/api/Brut/FrontEnd/Components/Inputs.html +0 -125
  473. data/docs/api/Brut/FrontEnd/Components/LocaleDetection.html +0 -367
  474. data/docs/api/Brut/FrontEnd/Components/PageIdentifier.html +0 -355
  475. data/docs/api/Brut/FrontEnd/Components/TimeTag.html +0 -655
  476. data/docs/api/Brut/FrontEnd/Components/Traceparent.html +0 -352
  477. data/docs/api/Brut/FrontEnd/Components.html +0 -156
  478. data/docs/api/Brut/FrontEnd/CsrfProtector.html +0 -250
  479. data/docs/api/Brut/FrontEnd/Download.html +0 -467
  480. data/docs/api/Brut/FrontEnd/Flash.html +0 -1150
  481. data/docs/api/Brut/FrontEnd/Form.html +0 -1227
  482. data/docs/api/Brut/FrontEnd/Forms/Button.html +0 -331
  483. data/docs/api/Brut/FrontEnd/Forms/ButtonInputDefinition.html +0 -537
  484. data/docs/api/Brut/FrontEnd/Forms/ConstraintViolation.html +0 -590
  485. data/docs/api/Brut/FrontEnd/Forms/Input/Color.html +0 -201
  486. data/docs/api/Brut/FrontEnd/Forms/Input/TimeOfDay.html +0 -535
  487. data/docs/api/Brut/FrontEnd/Forms/Input.html +0 -1567
  488. data/docs/api/Brut/FrontEnd/Forms/InputDeclarations.html +0 -635
  489. data/docs/api/Brut/FrontEnd/Forms/InputDefinition.html +0 -1336
  490. data/docs/api/Brut/FrontEnd/Forms/RadioButtonGroupInput.html +0 -730
  491. data/docs/api/Brut/FrontEnd/Forms/RadioButtonGroupInputDefinition.html +0 -587
  492. data/docs/api/Brut/FrontEnd/Forms/SelectInput.html +0 -734
  493. data/docs/api/Brut/FrontEnd/Forms/SelectInputDefinition.html +0 -582
  494. data/docs/api/Brut/FrontEnd/Forms/ValidityState.html +0 -659
  495. data/docs/api/Brut/FrontEnd/Forms.html +0 -127
  496. data/docs/api/Brut/FrontEnd/GenericResponse.html +0 -377
  497. data/docs/api/Brut/FrontEnd/Handler.html +0 -442
  498. data/docs/api/Brut/FrontEnd/Handlers/CspReportingHandler.html +0 -318
  499. data/docs/api/Brut/FrontEnd/Handlers/InstrumentationHandler/TraceParent.html +0 -336
  500. data/docs/api/Brut/FrontEnd/Handlers/InstrumentationHandler.html +0 -399
  501. data/docs/api/Brut/FrontEnd/Handlers/LocaleDetectionHandler.html +0 -354
  502. data/docs/api/Brut/FrontEnd/Handlers/MissingHandler/Form.html +0 -151
  503. data/docs/api/Brut/FrontEnd/Handlers/MissingHandler.html +0 -315
  504. data/docs/api/Brut/FrontEnd/Handlers.html +0 -125
  505. data/docs/api/Brut/FrontEnd/HandlingResults.html +0 -339
  506. data/docs/api/Brut/FrontEnd/HttpMethod.html +0 -661
  507. data/docs/api/Brut/FrontEnd/HttpStatus.html +0 -496
  508. data/docs/api/Brut/FrontEnd/InlineSvgLocator.html +0 -284
  509. data/docs/api/Brut/FrontEnd/Layout.html +0 -486
  510. data/docs/api/Brut/FrontEnd/Middleware.html +0 -135
  511. data/docs/api/Brut/FrontEnd/Middlewares/AnnotateBrutOwnedPaths.html +0 -288
  512. data/docs/api/Brut/FrontEnd/Middlewares/Favicon.html +0 -292
  513. data/docs/api/Brut/FrontEnd/Middlewares/OpenTelemetrySpan.html +0 -324
  514. data/docs/api/Brut/FrontEnd/Middlewares/ReloadApp.html +0 -376
  515. data/docs/api/Brut/FrontEnd/Middlewares.html +0 -125
  516. data/docs/api/Brut/FrontEnd/Page.html +0 -781
  517. data/docs/api/Brut/FrontEnd/Pages/MissingPage.html +0 -797
  518. data/docs/api/Brut/FrontEnd/Pages.html +0 -125
  519. data/docs/api/Brut/FrontEnd/RequestContext.html +0 -1312
  520. data/docs/api/Brut/FrontEnd/RouteHook.html +0 -424
  521. data/docs/api/Brut/FrontEnd/RouteHooks/AgeFlash.html +0 -242
  522. data/docs/api/Brut/FrontEnd/RouteHooks/CSPNoInlineScripts.html +0 -249
  523. data/docs/api/Brut/FrontEnd/RouteHooks/CSPNoInlineStylesOrScripts/ReportOnly.html +0 -264
  524. data/docs/api/Brut/FrontEnd/RouteHooks/CSPNoInlineStylesOrScripts.html +0 -261
  525. data/docs/api/Brut/FrontEnd/RouteHooks/LocaleDetection.html +0 -284
  526. data/docs/api/Brut/FrontEnd/RouteHooks/SetupRequestContext.html +0 -252
  527. data/docs/api/Brut/FrontEnd/RouteHooks.html +0 -115
  528. data/docs/api/Brut/FrontEnd/Routing/FormHandlerRoute.html +0 -227
  529. data/docs/api/Brut/FrontEnd/Routing/FormRoute.html +0 -305
  530. data/docs/api/Brut/FrontEnd/Routing/MissingForm.html +0 -324
  531. data/docs/api/Brut/FrontEnd/Routing/MissingHandler.html +0 -319
  532. data/docs/api/Brut/FrontEnd/Routing/MissingPage.html +0 -315
  533. data/docs/api/Brut/FrontEnd/Routing/MissingPath.html +0 -315
  534. data/docs/api/Brut/FrontEnd/Routing/PageRoute.html +0 -327
  535. data/docs/api/Brut/FrontEnd/Routing/Route.html +0 -761
  536. data/docs/api/Brut/FrontEnd/Routing.html +0 -927
  537. data/docs/api/Brut/FrontEnd/Session.html +0 -1195
  538. data/docs/api/Brut/FrontEnd.html +0 -134
  539. data/docs/api/Brut/I18n/BaseMethods.html +0 -931
  540. data/docs/api/Brut/I18n/ForBackEnd.html +0 -302
  541. data/docs/api/Brut/I18n/ForCLI.html +0 -302
  542. data/docs/api/Brut/I18n/ForHTML.html +0 -296
  543. data/docs/api/Brut/I18n/HTTPAcceptLanguage/AlwaysEnglish.html +0 -316
  544. data/docs/api/Brut/I18n/HTTPAcceptLanguage.html +0 -930
  545. data/docs/api/Brut/I18n.html +0 -127
  546. data/docs/api/Brut/Instrumentation/LoggerSpanExporter.html +0 -435
  547. data/docs/api/Brut/Instrumentation/Methods/ClassMethods.html +0 -596
  548. data/docs/api/Brut/Instrumentation/Methods.html +0 -173
  549. data/docs/api/Brut/Instrumentation/OpenTelemetry/NormalizedAttributes.html +0 -286
  550. data/docs/api/Brut/Instrumentation/OpenTelemetry/Span.html +0 -302
  551. data/docs/api/Brut/Instrumentation/OpenTelemetry.html +0 -866
  552. data/docs/api/Brut/Instrumentation.html +0 -128
  553. data/docs/api/Brut/RubocopConfig.html +0 -237
  554. data/docs/api/Brut/SinatraHelpers/ClassMethods.html +0 -534
  555. data/docs/api/Brut/SinatraHelpers.html +0 -281
  556. data/docs/api/Brut/SpecSupport/ClockSupport.html +0 -383
  557. data/docs/api/Brut/SpecSupport/ComponentSupport.html +0 -496
  558. data/docs/api/Brut/SpecSupport/E2ETestServer.html +0 -503
  559. data/docs/api/Brut/SpecSupport/E2eSupport.html +0 -142
  560. data/docs/api/Brut/SpecSupport/EnhancedNode.html +0 -403
  561. data/docs/api/Brut/SpecSupport/FlashSupport.html +0 -278
  562. data/docs/api/Brut/SpecSupport/GeneralSupport/ClassMethods.html +0 -401
  563. data/docs/api/Brut/SpecSupport/GeneralSupport.html +0 -195
  564. data/docs/api/Brut/SpecSupport/HandlerSupport.html +0 -160
  565. data/docs/api/Brut/SpecSupport/Matchers/BeABug.html +0 -142
  566. data/docs/api/Brut/SpecSupport/Matchers/BePageFor.html +0 -142
  567. data/docs/api/Brut/SpecSupport/Matchers/BeRoutingFor.html +0 -155
  568. data/docs/api/Brut/SpecSupport/Matchers/HaveConstraintViolation.html +0 -583
  569. data/docs/api/Brut/SpecSupport/Matchers/HaveGenerated.html +0 -149
  570. data/docs/api/Brut/SpecSupport/Matchers/HaveHTMLAttribute.html +0 -466
  571. data/docs/api/Brut/SpecSupport/Matchers/HaveI18nString.html +0 -149
  572. data/docs/api/Brut/SpecSupport/Matchers/HaveLinkTo.html +0 -149
  573. data/docs/api/Brut/SpecSupport/Matchers/HaveRedirectedTo.html +0 -165
  574. data/docs/api/Brut/SpecSupport/Matchers/HaveReturnedHttpStatus.html +0 -158
  575. data/docs/api/Brut/SpecSupport/Matchers/HaveReturnedRackResponse.html +0 -156
  576. data/docs/api/Brut/SpecSupport/Matchers.html +0 -125
  577. data/docs/api/Brut/SpecSupport/RSpecSetup/OptionalSidekiqSupport.html +0 -335
  578. data/docs/api/Brut/SpecSupport/RSpecSetup.html +0 -637
  579. data/docs/api/Brut/SpecSupport/SessionSupport.html +0 -196
  580. data/docs/api/Brut/SpecSupport.html +0 -129
  581. data/docs/api/Brut/TUI/AnsiEscapeCode/Mod.html +0 -409
  582. data/docs/api/Brut/TUI/AnsiEscapeCode.html +0 -426
  583. data/docs/api/Brut/TUI/EventLoop/Deque.html +0 -531
  584. data/docs/api/Brut/TUI/EventLoop.html +0 -676
  585. data/docs/api/Brut/TUI/Events/BaseEvent.html +0 -449
  586. data/docs/api/Brut/TUI/Events/EventBus.html +0 -485
  587. data/docs/api/Brut/TUI/Events/EventLoopStarted.html +0 -211
  588. data/docs/api/Brut/TUI/Events/Exception.html +0 -523
  589. data/docs/api/Brut/TUI/Events/Tick.html +0 -294
  590. data/docs/api/Brut/TUI/Events.html +0 -131
  591. data/docs/api/Brut/TUI/MarkupString.html +0 -537
  592. data/docs/api/Brut/TUI/Script/BlockStep.html +0 -300
  593. data/docs/api/Brut/TUI/Script/Events/CommandExecutionFailed.html +0 -252
  594. data/docs/api/Brut/TUI/Script/Events/CommandExecutionSucceeded.html +0 -163
  595. data/docs/api/Brut/TUI/Script/Events/CommandStdErr.html +0 -163
  596. data/docs/api/Brut/TUI/Script/Events/CommandStdOut.html +0 -300
  597. data/docs/api/Brut/TUI/Script/Events/ExecutingCommand.html +0 -298
  598. data/docs/api/Brut/TUI/Script/Events/Message.html +0 -345
  599. data/docs/api/Brut/TUI/Script/Events/PhaseCompleted.html +0 -229
  600. data/docs/api/Brut/TUI/Script/Events/PhaseStarted.html +0 -350
  601. data/docs/api/Brut/TUI/Script/Events/ScriptCompleted.html +0 -282
  602. data/docs/api/Brut/TUI/Script/Events/ScriptStarted.html +0 -343
  603. data/docs/api/Brut/TUI/Script/Events/StepCompleted.html +0 -163
  604. data/docs/api/Brut/TUI/Script/Events/StepStarted.html +0 -346
  605. data/docs/api/Brut/TUI/Script/Events.html +0 -115
  606. data/docs/api/Brut/TUI/Script/ExecStep/ProcessStatusFailed.html +0 -210
  607. data/docs/api/Brut/TUI/Script/ExecStep.html +0 -493
  608. data/docs/api/Brut/TUI/Script/LoggingSubscriber.html +0 -914
  609. data/docs/api/Brut/TUI/Script/PutsSubscriber.html +0 -783
  610. data/docs/api/Brut/TUI/Script/Step.html +0 -313
  611. data/docs/api/Brut/TUI/Script.html +0 -1250
  612. data/docs/api/Brut/TUI/Terminal.html +0 -593
  613. data/docs/api/Brut/TUI/TerminalTheme.html +0 -1403
  614. data/docs/api/Brut/TUI/Themes/Dark.html +0 -706
  615. data/docs/api/Brut/TUI/Themes/Light.html +0 -804
  616. data/docs/api/Brut/TUI/Themes/None.html +0 -218
  617. data/docs/api/Brut/TUI/Themes.html +0 -115
  618. data/docs/api/Brut/TUI.html +0 -129
  619. data/docs/api/Brut.html +0 -341
  620. data/docs/api/Clock.html +0 -603
  621. data/docs/api/ModuleName.html +0 -595
  622. data/docs/api/RichString.html +0 -775
  623. data/docs/api/SemanticLogger/Appender/Async.html +0 -219
  624. data/docs/api/Sequel/Extensions/BrutInstrumentation.html +0 -119
  625. data/docs/api/Sequel/Extensions/BrutMigrations.html +0 -541
  626. data/docs/api/Sequel/Extensions.html +0 -117
  627. data/docs/api/Sequel/Plugins/CreatedAt/InstanceMethods.html +0 -105
  628. data/docs/api/Sequel/Plugins/CreatedAt.html +0 -125
  629. data/docs/api/Sequel/Plugins/ExternalId/ClassMethods.html +0 -207
  630. data/docs/api/Sequel/Plugins/ExternalId/InstanceMethods.html +0 -186
  631. data/docs/api/Sequel/Plugins/ExternalId.html +0 -218
  632. data/docs/api/Sequel/Plugins/FindBang/ClassMethods.html +0 -202
  633. data/docs/api/Sequel/Plugins/FindBang.html +0 -125
  634. data/docs/api/Sequel/Plugins.html +0 -117
  635. data/docs/api/Sequel.html +0 -117
  636. data/docs/api/SpecSupport/Matchers/BeABug.html +0 -143
  637. data/docs/api/_index.html +0 -1964
  638. data/docs/api/class_list.html +0 -54
  639. data/docs/api/css/common.css +0 -1
  640. data/docs/api/css/full_list.css +0 -59
  641. data/docs/api/css/style.css +0 -504
  642. data/docs/api/file.README.html +0 -172
  643. data/docs/api/file_list.html +0 -59
  644. data/docs/api/frames.html +0 -22
  645. data/docs/api/index.html +0 -172
  646. data/docs/api/js/app.js +0 -344
  647. data/docs/api/js/full_list.js +0 -242
  648. data/docs/api/js/jquery.js +0 -4
  649. data/docs/api/method_list.html +0 -5542
  650. data/docs/api/top-level-namespace.html +0 -112
  651. data/docs/assets/02-confirmation-dialog-browser-element-styled.3NEGM20-.png +0 -0
  652. data/docs/assets/02-confirmation-dialog-browser-element.DPsf0xUW.png +0 -0
  653. data/docs/assets/02-confirmation-dialog-browser.DH8ALFO4.png +0 -0
  654. data/docs/assets/02-confirmation-flow.D9gZ0S5U.png +0 -0
  655. data/docs/assets/DevEnvironment.DaFcVfwP.png +0 -0
  656. data/docs/assets/LogoStop.Gb3tDhL1.png +0 -0
  657. data/docs/assets/OverviewMetro.DUS-5fUZ.png +0 -0
  658. data/docs/assets/adrs.md.YglbWtQe.js +0 -1
  659. data/docs/assets/adrs.md.YglbWtQe.lean.js +0 -1
  660. data/docs/assets/ai.md.ChLnvDAX.js +0 -1
  661. data/docs/assets/ai.md.ChLnvDAX.lean.js +0 -1
  662. data/docs/assets/app.B8jAEB7R.js +0 -1
  663. data/docs/assets/assets.md.BEF6Oz6K.js +0 -19
  664. data/docs/assets/assets.md.BEF6Oz6K.lean.js +0 -1
  665. data/docs/assets/basic-form-with-violations.Cv6Y9-Q_.png +0 -0
  666. data/docs/assets/basic-form.DbHnu0oW.png +0 -0
  667. data/docs/assets/brut-js.md.BMz0X1Rz.js +0 -12
  668. data/docs/assets/brut-js.md.BMz0X1Rz.lean.js +0 -1
  669. data/docs/assets/business-logic.md.DbuaOYGU.js +0 -1
  670. data/docs/assets/business-logic.md.DbuaOYGU.lean.js +0 -1
  671. data/docs/assets/chunks/@localSearchIndexroot.DJ8mocCj.js +0 -1
  672. data/docs/assets/chunks/VPLocalSearchBox.gF-Po_fz.js +0 -8
  673. data/docs/assets/chunks/framework.C4nOkCZI.js +0 -18
  674. data/docs/assets/chunks/theme.BjPAOJkz.js +0 -2
  675. data/docs/assets/cli.md.DDMar_51.js +0 -122
  676. data/docs/assets/cli.md.DDMar_51.lean.js +0 -1
  677. data/docs/assets/components.md.Ber8UBM0.js +0 -96
  678. data/docs/assets/components.md.Ber8UBM0.lean.js +0 -1
  679. data/docs/assets/configuration.md.DrJ6YVoZ.js +0 -78
  680. data/docs/assets/configuration.md.DrJ6YVoZ.lean.js +0 -1
  681. data/docs/assets/css.md.K5rOCOQY.js +0 -21
  682. data/docs/assets/css.md.K5rOCOQY.lean.js +0 -1
  683. data/docs/assets/custom-element-tests.md.DiLe-eFw.js +0 -69
  684. data/docs/assets/custom-element-tests.md.DiLe-eFw.lean.js +0 -1
  685. data/docs/assets/database-access.md.Dc8l2Plf.js +0 -63
  686. data/docs/assets/database-access.md.Dc8l2Plf.lean.js +0 -1
  687. data/docs/assets/database-schema.md.BJ_JhXmO.js +0 -70
  688. data/docs/assets/database-schema.md.BJ_JhXmO.lean.js +0 -1
  689. data/docs/assets/deployment.md.CHTx2eTR.js +0 -55
  690. data/docs/assets/deployment.md.CHTx2eTR.lean.js +0 -1
  691. data/docs/assets/dev-env-protocol.DysDAtnz.png +0 -0
  692. data/docs/assets/dev-environment.md.B1S9p5ZK.js +0 -16
  693. data/docs/assets/dev-environment.md.B1S9p5ZK.lean.js +0 -1
  694. data/docs/assets/dir-structure.md.D1T2kGwj.js +0 -46
  695. data/docs/assets/dir-structure.md.D1T2kGwj.lean.js +0 -1
  696. data/docs/assets/doc-conventions.md.CDnWaEFg.js +0 -1
  697. data/docs/assets/doc-conventions.md.CDnWaEFg.lean.js +0 -1
  698. data/docs/assets/end-to-end-tests.md.BJJdNDYL.js +0 -28
  699. data/docs/assets/end-to-end-tests.md.BJJdNDYL.lean.js +0 -1
  700. data/docs/assets/features.md.BDWxnyNO.js +0 -154
  701. data/docs/assets/features.md.BDWxnyNO.lean.js +0 -1
  702. data/docs/assets/flash-and-session.md.CUsMxoNl.js +0 -79
  703. data/docs/assets/flash-and-session.md.CUsMxoNl.lean.js +0 -1
  704. data/docs/assets/form-constraints.md.KlfXSKm2.js +0 -90
  705. data/docs/assets/form-constraints.md.KlfXSKm2.lean.js +0 -1
  706. data/docs/assets/forms.md.RK0zkhm0.js +0 -64
  707. data/docs/assets/forms.md.RK0zkhm0.lean.js +0 -1
  708. data/docs/assets/getting-started.md.CGJ44juQ.js +0 -31
  709. data/docs/assets/getting-started.md.CGJ44juQ.lean.js +0 -1
  710. data/docs/assets/handlers.md.C5tUwmmo.js +0 -54
  711. data/docs/assets/handlers.md.C5tUwmmo.lean.js +0 -1
  712. data/docs/assets/hooks.md.CoiYCKRc.js +0 -80
  713. data/docs/assets/hooks.md.CoiYCKRc.lean.js +0 -1
  714. data/docs/assets/i18n.md.DxkCKhUw.js +0 -23
  715. data/docs/assets/i18n.md.DxkCKhUw.lean.js +0 -1
  716. data/docs/assets/index.md.DnphWyQd.js +0 -1
  717. data/docs/assets/index.md.DnphWyQd.lean.js +0 -1
  718. data/docs/assets/initial-home-page.DNIaYmgP.png +0 -0
  719. data/docs/assets/instrumentation.md.BcxjC4jd.js +0 -90
  720. data/docs/assets/instrumentation.md.BcxjC4jd.lean.js +0 -1
  721. data/docs/assets/javascript.md.D6fxhaQb.js +0 -31
  722. data/docs/assets/javascript.md.D6fxhaQb.lean.js +0 -1
  723. data/docs/assets/jobs.md.Bi3qb3v6.js +0 -25
  724. data/docs/assets/jobs.md.Bi3qb3v6.lean.js +0 -1
  725. data/docs/assets/keyword-injection.md.CqLnnzIz.js +0 -21
  726. data/docs/assets/keyword-injection.md.CqLnnzIz.lean.js +0 -1
  727. data/docs/assets/layouts.md.HEbeK7Jr.js +0 -68
  728. data/docs/assets/layouts.md.HEbeK7Jr.lean.js +0 -1
  729. data/docs/assets/lsp.md.bE9dW8n9.js +0 -1
  730. data/docs/assets/lsp.md.bE9dW8n9.lean.js +0 -1
  731. data/docs/assets/markdown-examples.md.BPmtHlc-.js +0 -33
  732. data/docs/assets/markdown-examples.md.BPmtHlc-.lean.js +0 -1
  733. data/docs/assets/middleware.md.BhOIsg59.js +0 -20
  734. data/docs/assets/middleware.md.BhOIsg59.lean.js +0 -1
  735. data/docs/assets/new-post-editor.DrHr-5oh.png +0 -0
  736. data/docs/assets/new-post-home-page.Bm34lyMg.png +0 -0
  737. data/docs/assets/overview.md.BpWAgPFH.js +0 -1
  738. data/docs/assets/overview.md.BpWAgPFH.lean.js +0 -1
  739. data/docs/assets/pages.md.B3sQXpEd.js +0 -45
  740. data/docs/assets/pages.md.B3sQXpEd.lean.js +0 -1
  741. data/docs/assets/recipes_alternate-layouts.md.C1QzVkA7.js +0 -22
  742. data/docs/assets/recipes_alternate-layouts.md.C1QzVkA7.lean.js +0 -1
  743. data/docs/assets/recipes_authentication.md.CyvoIW82.js +0 -157
  744. data/docs/assets/recipes_authentication.md.CyvoIW82.lean.js +0 -1
  745. data/docs/assets/recipes_custom-flash.md.6gFqf2uL.js +0 -26
  746. data/docs/assets/recipes_custom-flash.md.6gFqf2uL.lean.js +0 -1
  747. data/docs/assets/recipes_dev-env-secrets.md.DC_jVY9U.js +0 -12
  748. data/docs/assets/recipes_dev-env-secrets.md.DC_jVY9U.lean.js +0 -1
  749. data/docs/assets/recipes_form-errors.md.B5ptSzMO.js +0 -66
  750. data/docs/assets/recipes_form-errors.md.B5ptSzMO.lean.js +0 -1
  751. data/docs/assets/recipes_indexed-forms.md.BYYQGW2C.js +0 -74
  752. data/docs/assets/recipes_indexed-forms.md.BYYQGW2C.lean.js +0 -1
  753. data/docs/assets/recipes_migrations.md.Cid7-3cu.js +0 -97
  754. data/docs/assets/recipes_migrations.md.Cid7-3cu.lean.js +0 -1
  755. data/docs/assets/recipes_text-field-component.md.VhOsCtKI.js +0 -101
  756. data/docs/assets/recipes_text-field-component.md.VhOsCtKI.lean.js +0 -1
  757. data/docs/assets/roadmap.md.DqC1Y7Zt.js +0 -1
  758. data/docs/assets/roadmap.md.DqC1Y7Zt.lean.js +0 -1
  759. data/docs/assets/routes.md.C1dgIBtD.js +0 -21
  760. data/docs/assets/routes.md.C1dgIBtD.lean.js +0 -1
  761. data/docs/assets/security.md.Jn4SY1uK.js +0 -1
  762. data/docs/assets/security.md.Jn4SY1uK.lean.js +0 -1
  763. data/docs/assets/seed-data.md.UZW0WxYN.js +0 -14
  764. data/docs/assets/seed-data.md.UZW0WxYN.lean.js +0 -1
  765. data/docs/assets/spa.qejUdp-5.png +0 -0
  766. data/docs/assets/space-time-continuum.md.D9rYGDFH.js +0 -1
  767. data/docs/assets/space-time-continuum.md.D9rYGDFH.lean.js +0 -1
  768. data/docs/assets/style.B1z60PPQ.css +0 -1
  769. data/docs/assets/styled-form-with-server-side-violations.Bjxd8Dpv.png +0 -0
  770. data/docs/assets/styled-form-with-violations.Bv_sa9tg.png +0 -0
  771. data/docs/assets/styled-home-page-with-posts.Dd4kG89D.png +0 -0
  772. data/docs/assets/styled-home-page.BzdI7dWz.png +0 -0
  773. data/docs/assets/tutorial.md.BX6f6l00.js +0 -27
  774. data/docs/assets/tutorial.md.BX6f6l00.lean.js +0 -1
  775. data/docs/assets/tutorials_01-intro.md.CzZ3kpF_.js +0 -708
  776. data/docs/assets/tutorials_01-intro.md.CzZ3kpF_.lean.js +0 -1
  777. data/docs/assets/tutorials_02-dialog.md.DE5WfCXI.js +0 -274
  778. data/docs/assets/tutorials_02-dialog.md.DE5WfCXI.lean.js +0 -1
  779. data/docs/assets/unit-tests.md.vDsdBbO_.js +0 -13
  780. data/docs/assets/unit-tests.md.vDsdBbO_.lean.js +0 -1
  781. data/docs/assets/welcome-to-brut.VSWzl17-.png +0 -0
  782. data/docs/assets/why.md.4WpxdrQ2.js +0 -1
  783. data/docs/assets/why.md.4WpxdrQ2.lean.js +0 -1
  784. data/docs/assets/workspace-protocol.C0gXsoDb.png +0 -0
  785. data/docs/assets.html +0 -47
  786. data/docs/brut-css/brut.css +0 -1
  787. data/docs/brut-css/brut.max.css +0 -22372
  788. data/docs/brut-css/classes/appearances.html +0 -783
  789. data/docs/brut-css/classes/background-colors.html +0 -3529
  790. data/docs/brut-css/classes/border-colors.html +0 -3529
  791. data/docs/brut-css/classes/borders.html +0 -2293
  792. data/docs/brut-css/classes/dimensions.html +0 -2581
  793. data/docs/brut-css/classes/flex.html +0 -917
  794. data/docs/brut-css/classes/foreground-colors.html +0 -3261
  795. data/docs/brut-css/classes/junk-drawer.html +0 -431
  796. data/docs/brut-css/classes/layout.html +0 -668
  797. data/docs/brut-css/classes/lists.html +0 -331
  798. data/docs/brut-css/classes/positioning.html +0 -1751
  799. data/docs/brut-css/classes/spacings.html +0 -2633
  800. data/docs/brut-css/classes/typography.html +0 -2206
  801. data/docs/brut-css/customization/advanced-configuration.html +0 -204
  802. data/docs/brut-css/customization/breakpoints.html +0 -227
  803. data/docs/brut-css/customization/design-system.html +0 -197
  804. data/docs/brut-css/customization/pseudo-classes.html +0 -228
  805. data/docs/brut-css/docs.css +0 -98
  806. data/docs/brut-css/getting-started/core-concepts.html +0 -234
  807. data/docs/brut-css/getting-started/installation.html +0 -190
  808. data/docs/brut-css/getting-started/overview.html +0 -210
  809. data/docs/brut-css/getting-started/simple-example.html +0 -285
  810. data/docs/brut-css/index.html +0 -193
  811. data/docs/brut-css/prism-twilight.min.css +0 -1
  812. data/docs/brut-css/properties/colors.html +0 -1548
  813. data/docs/brut-css/properties/spacings.html +0 -614
  814. data/docs/brut-css/properties/typography.html +0 -777
  815. data/docs/brut-js/api/AjaxSubmit.html +0 -452
  816. data/docs/brut-js/api/AjaxSubmit.js.html +0 -550
  817. data/docs/brut-js/api/Autosubmit.html +0 -192
  818. data/docs/brut-js/api/Autosubmit.js.html +0 -114
  819. data/docs/brut-js/api/BaseCustomElement.html +0 -1091
  820. data/docs/brut-js/api/BaseCustomElement.js.html +0 -312
  821. data/docs/brut-js/api/BrutCustomElements.html +0 -172
  822. data/docs/brut-js/api/BufferedLogger.html +0 -173
  823. data/docs/brut-js/api/ConfirmSubmit.html +0 -286
  824. data/docs/brut-js/api/ConfirmSubmit.js.html +0 -188
  825. data/docs/brut-js/api/ConfirmationDialog.html +0 -425
  826. data/docs/brut-js/api/ConfirmationDialog.js.html +0 -194
  827. data/docs/brut-js/api/ConstraintViolationMessage.html +0 -498
  828. data/docs/brut-js/api/ConstraintViolationMessage.js.html +0 -191
  829. data/docs/brut-js/api/ConstraintViolationMessages.html +0 -590
  830. data/docs/brut-js/api/ConstraintViolationMessages.js.html +0 -149
  831. data/docs/brut-js/api/CopyToClipboard.html +0 -345
  832. data/docs/brut-js/api/CopyToClipboard.js.html +0 -147
  833. data/docs/brut-js/api/Form.html +0 -291
  834. data/docs/brut-js/api/Form.js.html +0 -198
  835. data/docs/brut-js/api/I18nTranslation.html +0 -409
  836. data/docs/brut-js/api/I18nTranslation.js.html +0 -115
  837. data/docs/brut-js/api/LocaleDetection.html +0 -312
  838. data/docs/brut-js/api/LocaleDetection.js.html +0 -168
  839. data/docs/brut-js/api/Logger.html +0 -702
  840. data/docs/brut-js/api/Logger.js.html +0 -141
  841. data/docs/brut-js/api/Message.html +0 -238
  842. data/docs/brut-js/api/Message.js.html +0 -113
  843. data/docs/brut-js/api/PrefixedLogger.html +0 -369
  844. data/docs/brut-js/api/RichString.html +0 -1049
  845. data/docs/brut-js/api/RichString.js.html +0 -167
  846. data/docs/brut-js/api/Tabs.html +0 -295
  847. data/docs/brut-js/api/Tabs.js.html +0 -219
  848. data/docs/brut-js/api/Toast.html +0 -270
  849. data/docs/brut-js/api/Toast.js.html +0 -153
  850. data/docs/brut-js/api/Tracing.html +0 -277
  851. data/docs/brut-js/api/Tracing.js.html +0 -298
  852. data/docs/brut-js/api/external-CustomElementRegistry.html +0 -140
  853. data/docs/brut-js/api/external-Performance.html +0 -138
  854. data/docs/brut-js/api/external-Promise.html +0 -138
  855. data/docs/brut-js/api/external-ValidityState.html +0 -138
  856. data/docs/brut-js/api/external-Window.html +0 -233
  857. data/docs/brut-js/api/external-fetch.html +0 -138
  858. data/docs/brut-js/api/global.html +0 -400
  859. data/docs/brut-js/api/index.html +0 -168
  860. data/docs/brut-js/api/index.js.html +0 -184
  861. data/docs/brut-js/api/module-testing.html +0 -383
  862. data/docs/brut-js/api/scripts/linenumber.js +0 -25
  863. data/docs/brut-js/api/scripts/prettify/Apache-License-2.0.txt +0 -202
  864. data/docs/brut-js/api/scripts/prettify/lang-css.js +0 -2
  865. data/docs/brut-js/api/scripts/prettify/prettify.js +0 -28
  866. data/docs/brut-js/api/styles/jsdoc-default.css +0 -327
  867. data/docs/brut-js/api/styles/prettify-jsdoc.css +0 -111
  868. data/docs/brut-js/api/styles/prettify-tomorrow.css +0 -132
  869. data/docs/brut-js/api/testing.AssetMetadata.html +0 -172
  870. data/docs/brut-js/api/testing.AssetMetadataLoader.html +0 -171
  871. data/docs/brut-js/api/testing.CustomElementTest.html +0 -679
  872. data/docs/brut-js/api/testing.DOMCreator.html +0 -171
  873. data/docs/brut-js/api/testing_AssetMetadata.js.html +0 -86
  874. data/docs/brut-js/api/testing_AssetMetadataLoader.js.html +0 -76
  875. data/docs/brut-js/api/testing_CustomElementTest.js.html +0 -286
  876. data/docs/brut-js/api/testing_DOMCreator.js.html +0 -96
  877. data/docs/brut-js/api/testing_index.js.html +0 -99
  878. data/docs/brut-js.html +0 -40
  879. data/docs/business-logic.html +0 -29
  880. data/docs/cli.html +0 -150
  881. data/docs/components.html +0 -124
  882. data/docs/configuration.html +0 -106
  883. data/docs/css.html +0 -49
  884. data/docs/custom-element-tests.html +0 -97
  885. data/docs/database-access.html +0 -91
  886. data/docs/database-schema.html +0 -98
  887. data/docs/deployment.html +0 -83
  888. data/docs/dev-environment.html +0 -44
  889. data/docs/dir-structure.html +0 -74
  890. data/docs/doc-conventions.html +0 -29
  891. data/docs/end-to-end-tests.html +0 -56
  892. data/docs/favicon.ico +0 -0
  893. data/docs/features.html +0 -182
  894. data/docs/flash-and-session.html +0 -107
  895. data/docs/form-constraints.html +0 -118
  896. data/docs/forms.html +0 -92
  897. data/docs/getting-started.html +0 -59
  898. data/docs/handlers.html +0 -82
  899. data/docs/hashmap.json +0 -1
  900. data/docs/hooks.html +0 -108
  901. data/docs/i18n.html +0 -51
  902. data/docs/index.html +0 -29
  903. data/docs/instrumentation.html +0 -118
  904. data/docs/javascript.html +0 -59
  905. data/docs/jobs.html +0 -53
  906. data/docs/keyword-injection.html +0 -49
  907. data/docs/layouts.html +0 -96
  908. data/docs/lsp.html +0 -29
  909. data/docs/markdown-examples.html +0 -61
  910. data/docs/middleware.html +0 -48
  911. data/docs/overview.html +0 -29
  912. data/docs/pages.html +0 -73
  913. data/docs/recipes/alternate-layouts.html +0 -50
  914. data/docs/recipes/authentication.html +0 -185
  915. data/docs/recipes/custom-flash.html +0 -54
  916. data/docs/recipes/dev-env-secrets.html +0 -40
  917. data/docs/recipes/form-errors.html +0 -94
  918. data/docs/recipes/indexed-forms.html +0 -102
  919. data/docs/recipes/migrations.html +0 -125
  920. data/docs/recipes/text-field-component.html +0 -129
  921. data/docs/roadmap.html +0 -29
  922. data/docs/routes.html +0 -49
  923. data/docs/security.html +0 -29
  924. data/docs/seed-data.html +0 -42
  925. data/docs/space-time-continuum.html +0 -29
  926. data/docs/tutorial.html +0 -55
  927. data/docs/tutorials/01-intro.html +0 -736
  928. data/docs/tutorials/02-dialog.html +0 -302
  929. data/docs/unit-tests.html +0 -41
  930. data/docs/vp-icons.css +0 -1
  931. data/docs/why.html +0 -29
  932. data/docs-todo.md +0 -32
  933. data/dx/bash_customizations +0 -6
  934. data/dx/build +0 -73
  935. data/dx/build.pre +0 -15
  936. data/dx/docker-compose.env +0 -22
  937. data/dx/dx.sh.lib +0 -24
  938. data/dx/exec +0 -75
  939. data/dx/setupkit.sh.lib +0 -144
  940. data/dx/show-help-in-app-container-then-wait.sh +0 -38
  941. data/lib/brut/cli/app.rb +0 -238
  942. data/lib/brut/cli/app_runner.rb +0 -252
  943. data/lib/brut/cli/command.rb +0 -258
  944. data/lib/brut/cli/execution_results.rb +0 -119
  945. data/lib/brut/front_end/layouts/_internal.html.erb +0 -68
  946. data/lib/brut/front_end/pages/_missing_page.html.erb +0 -17
  947. data/mkbrut/.gitignore +0 -16
  948. data/mkbrut/CODE_OF_CONDUCT.txt +0 -100
  949. data/mkbrut/Gemfile +0 -3
  950. data/mkbrut/Gemfile.lock +0 -20
  951. data/mkbrut/LICENSE.txt +0 -370
  952. data/mkbrut/README.md +0 -145
  953. data/mkbrut/Rakefile +0 -2
  954. data/mkbrut/bin/build +0 -36
  955. data/mkbrut/bin/ci +0 -19
  956. data/mkbrut/bin/docs +0 -19
  957. data/mkbrut/bin/publish +0 -129
  958. data/mkbrut/bin/rake +0 -16
  959. data/mkbrut/bin/setup +0 -30
  960. data/mkbrut/brut-welcome.png +0 -0
  961. data/mkbrut/deploy/.dockerignore +0 -2
  962. data/mkbrut/deploy/Dockerfile +0 -25
  963. data/mkbrut/dx +0 -1
  964. data/mkbrut/exe/mkbrut +0 -5
  965. data/mkbrut/lib/mkbrut/app_name.rb +0 -29
  966. data/mkbrut/lib/mkbrut/app_options.rb +0 -36
  967. data/mkbrut/lib/mkbrut/cli.rb +0 -189
  968. data/mkbrut/lib/mkbrut/erb_binding_delegate.rb +0 -20
  969. data/mkbrut/lib/mkbrut/ops.rb +0 -17
  970. data/mkbrut/lib/mkbrut/organization.rb +0 -5
  971. data/mkbrut/lib/mkbrut/segments.rb +0 -8
  972. data/mkbrut/lib/mkbrut/version.rb +0 -3
  973. data/mkbrut/lib/mkbrut.rb +0 -20
  974. data/mkbrut/mkbrut.gemspec +0 -34
  975. data/mkbrut/templates/Base/app/src/front_end/images/LogoPylon.png +0 -0
  976. data/mkbrut/templates/Base/bin/build-assets +0 -7
  977. data/mkbrut/templates/Base/bin/ci +0 -39
  978. data/mkbrut/templates/Base/bin/db +0 -9
  979. data/mkbrut/templates/Base/bin/scaffold +0 -9
  980. data/mkbrut/templates/Base/bin/setup +0 -287
  981. data/mkbrut/templates/Base/bin/test +0 -9
  982. data/mkbrut/templates/Base/bin/test-server +0 -29
  983. data/mkbrut/templates/Base/dx/prune +0 -19
  984. data/mkbrut/templates/Base/dx/start +0 -30
  985. data/mkbrut/templates/Base/dx/stop +0 -23
  986. data/mkbrut/templates/segments/Heroku/deploy/heroku_config.rb +0 -27
  987. data/specs/brut/front_end/forms/input.spec.rb +0 -978
  988. data/specs/brut/front_end/forms/radio_button_group_input.spec.rb +0 -54
  989. data/specs/brut/front_end/forms/select_input.spec.rb +0 -54
  990. data/specs/brut/instrumentation/methods.spec.rb +0 -399
  991. data/specs/brut/junk_drawer.spec.rb +0 -79
  992. data/specs/brut/tui/ansi_escape_code.spec.rb +0 -30
  993. data/specs/brut/tui/event_loop.spec.rb +0 -70
  994. data/specs/brut/tui/events/base_event.spec.rb +0 -26
  995. data/specs/brut/tui/events/event_bus.spec.rb +0 -141
  996. data/specs/brut/tui/events/exception.spec.rb +0 -19
  997. data/specs/brut/tui/events/test_event.rb +0 -5
  998. data/specs/spec_helper.rb +0 -31
  999. data/specs/support/matchers/have_constraint_violation.rb +0 -23
  1000. data/specs/support/matchers.rb +0 -5
  1001. data/specs/support.rb +0 -3
  1002. /data/{mkbrut/lib/mkbrut → lib/brut/cli/apps/new}/prefixed_io.rb +0 -0
  1003. /data/{mkbrut/templates → templates}/Base/.dockerignore +0 -0
  1004. /data/{mkbrut/templates → templates}/Base/.env.development.erb +0 -0
  1005. /data/{mkbrut/templates → templates}/Base/.env.test.erb +0 -0
  1006. /data/{mkbrut/templates → templates}/Base/.gitignore +0 -0
  1007. /data/{mkbrut/templates → templates}/Base/.projections.json +0 -0
  1008. /data/{mkbrut/templates → templates}/Base/Dockerfile.dx +0 -0
  1009. /data/{mkbrut/templates → templates}/Base/Gemfile.erb +0 -0
  1010. /data/{mkbrut/templates → templates}/Base/Procfile.development +0 -0
  1011. /data/{mkbrut/templates → templates}/Base/Procfile.test +0 -0
  1012. /data/{mkbrut/templates → templates}/Base/README.md +0 -0
  1013. /data/{mkbrut/templates → templates}/Base/README.md.erb +0 -0
  1014. /data/{mkbrut/templates → templates}/Base/app/bootstrap.rb +0 -0
  1015. /data/{mkbrut/templates → templates}/Base/app/config/i18n/en/1_defaults.rb +0 -0
  1016. /data/{mkbrut/templates → templates}/Base/app/config/i18n/en/2_app.rb +0 -0
  1017. /data/{mkbrut/templates → templates}/Base/app/public/static/manifest.json.erb +0 -0
  1018. /data/{mkbrut/templates → templates}/Base/app/src/app.rb.erb +0 -0
  1019. /data/{mkbrut/templates → templates}/Base/app/src/back_end/data_models/app_data_model.rb +0 -0
  1020. /data/{mkbrut/templates → templates}/Base/app/src/back_end/data_models/db.rb +0 -0
  1021. /data/{mkbrut/templates → templates}/Base/app/src/back_end/data_models/migrations/20240101130000_citext.rb +0 -0
  1022. /data/{mkbrut/templates → templates}/Base/app/src/back_end/data_models/seed/seed_data.rb +0 -0
  1023. /data/{mkbrut/templates → templates}/Base/app/src/front_end/components/app_component.rb +0 -0
  1024. /data/{mkbrut/templates → templates}/Base/app/src/front_end/components/custom_element_registration.rb.erb +0 -0
  1025. /data/{mkbrut/templates → templates}/Base/app/src/front_end/css/index.css +0 -0
  1026. /data/{mkbrut/templates → templates}/Base/app/src/front_end/css/svgs.css +0 -0
  1027. /data/{mkbrut/templates → templates}/Base/app/src/front_end/forms/app_form.rb +0 -0
  1028. /data/{mkbrut/templates → templates}/Base/app/src/front_end/handlers/app_handler.rb +0 -0
  1029. /data/{brutrb.com → templates/Base/app/src/front_end}/images/LogoPylon.png +0 -0
  1030. /data/{mkbrut/templates → templates}/Base/app/src/front_end/images/LogoTransit.png +0 -0
  1031. /data/{mkbrut/templates → templates}/Base/app/src/front_end/images/apple-touch-icon-120x120.png +0 -0
  1032. /data/{mkbrut/templates → templates}/Base/app/src/front_end/images/apple-touch-icon-152x152.png +0 -0
  1033. /data/{mkbrut/templates → templates}/Base/app/src/front_end/images/apple-touch-icon-167x167.png +0 -0
  1034. /data/{mkbrut/templates → templates}/Base/app/src/front_end/images/apple-touch-icon-180x180.png +0 -0
  1035. /data/{mkbrut/templates → templates}/Base/app/src/front_end/images/favicon.ico +0 -0
  1036. /data/{mkbrut/templates → templates}/Base/app/src/front_end/images/icon.png +0 -0
  1037. /data/{mkbrut/templates → templates}/Base/app/src/front_end/images/mkicons.sh +0 -0
  1038. /data/{mkbrut/templates → templates}/Base/app/src/front_end/js/index.js +0 -0
  1039. /data/{mkbrut/templates → templates}/Base/app/src/front_end/layouts/blank_layout.rb +0 -0
  1040. /data/{mkbrut/templates → templates}/Base/app/src/front_end/layouts/default_layout.rb.erb +0 -0
  1041. /data/{mkbrut/templates → templates}/Base/app/src/front_end/pages/app_page.rb +0 -0
  1042. /data/{mkbrut/templates → templates}/Base/app/src/front_end/pages/home_page.rb +0 -0
  1043. /data/{mkbrut/templates → templates}/Base/app/src/front_end/support/app_session.rb +0 -0
  1044. /data/{mkbrut/templates → templates}/Base/app/src/front_end/svgs/README.md +0 -0
  1045. /data/{mkbrut/templates → templates}/Base/app/src/front_end/svgs/comment-button.svg +0 -0
  1046. /data/{mkbrut/templates → templates}/Base/bin/README.md.erb +0 -0
  1047. /data/{mkbrut/templates → templates}/Base/bin/console +0 -0
  1048. /data/{mkbrut/templates → templates}/Base/bin/dbconsole +0 -0
  1049. /data/{mkbrut/templates → templates}/Base/bin/dev +0 -0
  1050. /data/{mkbrut/templates → templates}/Base/bin/run +0 -0
  1051. /data/{mkbrut/templates → templates}/Base/bin/run.run +0 -0
  1052. /data/{mkbrut/templates → templates}/Base/bin/startup-message +0 -0
  1053. /data/{mkbrut/templates → templates}/Base/config.ru +0 -0
  1054. /data/{mkbrut/templates → templates}/Base/docker-compose.dx.yml +0 -0
  1055. /data/{mkbrut/templates → templates}/Base/dx/README.md +0 -0
  1056. /data/{mkbrut/templates → templates}/Base/dx/bash_customizations +0 -0
  1057. /data/{mkbrut/templates → templates}/Base/dx/bash_customizations.local +0 -0
  1058. /data/{mkbrut/templates → templates}/Base/dx/build +0 -0
  1059. /data/{mkbrut/templates → templates}/Base/dx/dx.sh.lib +0 -0
  1060. /data/{mkbrut/templates → templates}/Base/dx/exec +0 -0
  1061. /data/{dx → templates/Base/dx}/prune +0 -0
  1062. /data/{mkbrut/templates → templates}/Base/dx/show-help-in-app-container-then-wait.sh +0 -0
  1063. /data/{dx → templates/Base/dx}/start +0 -0
  1064. /data/{dx → templates/Base/dx}/stop +0 -0
  1065. /data/{mkbrut/templates → templates}/Base/package.json.erb +0 -0
  1066. /data/{mkbrut/templates → templates}/Base/puma.config.rb +0 -0
  1067. /data/{mkbrut/templates → templates}/Base/specs/e2e/home_page.spec.rb.erb +0 -0
  1068. /data/{mkbrut/templates → templates}/Base/specs/front_end/js/SpecHelper.js +0 -0
  1069. /data/{mkbrut/templates → templates}/Base/specs/front_end/pages/home_page.spec.rb +0 -0
  1070. /data/{mkbrut/templates → templates}/Base/specs/lint_factories.spec.rb +0 -0
  1071. /data/{mkbrut/templates → templates}/Base/specs/spec_helper.rb +0 -0
  1072. /data/{mkbrut/templates → templates}/Base/specs/support.rb +0 -0
  1073. /data/{mkbrut/templates → templates}/segments/BareBones/app/src/front_end/handlers/trigger_exception_handler.rb +0 -0
  1074. /data/{mkbrut/templates → templates}/segments/BareBones/app/src/front_end/js/Example.js.erb +0 -0
  1075. /data/{mkbrut/templates → templates}/segments/BareBones/specs/front_end/handlers/trigger_exception_handler.spec.rb +0 -0
  1076. /data/{mkbrut/templates → templates}/segments/BareBones/specs/front_end/js/Example.spec.js.erb +0 -0
  1077. /data/{mkbrut/templates → templates}/segments/Demo/app/src/back_end/data_models/db/guestbook_message.rb +0 -0
  1078. /data/{mkbrut/templates → templates}/segments/Demo/app/src/back_end/data_models/migrations/20250628194124_guestbook.rb +0 -0
  1079. /data/{mkbrut/templates → templates}/segments/Demo/app/src/front_end/components/flash_component.rb +0 -0
  1080. /data/{mkbrut/templates → templates}/segments/Demo/app/src/front_end/css/constraint-violations.css +0 -0
  1081. /data/{mkbrut/templates → templates}/segments/Demo/app/src/front_end/fonts/monaspace-xenon.ttf +0 -0
  1082. /data/{mkbrut/templates → templates}/segments/Demo/app/src/front_end/forms/guestbook_message_form.rb +0 -0
  1083. /data/{mkbrut/templates → templates}/segments/Demo/app/src/front_end/handlers/guestbook_message_handler.rb +0 -0
  1084. /data/{mkbrut/templates → templates}/segments/Demo/app/src/front_end/pages/guestbook_page/message_component.rb +0 -0
  1085. /data/{mkbrut/templates → templates}/segments/Demo/app/src/front_end/pages/guestbook_page.rb +0 -0
  1086. /data/{mkbrut/templates → templates}/segments/Demo/app/src/front_end/pages/new_guestbook_message_page.rb +0 -0
  1087. /data/{mkbrut/templates → templates}/segments/Demo/specs/back_end/data_models/db/guestbook_message.spec.rb +0 -0
  1088. /data/{mkbrut/templates → templates}/segments/Demo/specs/e2e/guest_message.spec.rb +0 -0
  1089. /data/{mkbrut/templates → templates}/segments/Demo/specs/factories/db/guestbook_message.factory.rb +0 -0
  1090. /data/{mkbrut/templates → templates}/segments/Demo/specs/front_end/components/flash_component.spec.rb +0 -0
  1091. /data/{mkbrut/templates → templates}/segments/Demo/specs/front_end/handlers/guestbook_message_handler.spec.rb +0 -0
  1092. /data/{mkbrut/templates → templates}/segments/Demo/specs/front_end/pages/guestbook_page/message_component.spec.rb +0 -0
  1093. /data/{mkbrut/templates → templates}/segments/Demo/specs/front_end/pages/guestbook_page.spec.rb +0 -0
  1094. /data/{mkbrut/templates → templates}/segments/Demo/specs/front_end/pages/new_guestbook_message_page.spec.rb +0 -0
  1095. /data/{mkbrut/templates → templates}/segments/Heroku/bin/deploy +0 -0
  1096. /data/{mkbrut/templates → templates}/segments/Heroku/deploy/docker-entrypoint +0 -0
  1097. /data/{mkbrut/templates → templates}/segments/Sidekiq/app/boot_sidekiq.rb +0 -0
  1098. /data/{mkbrut/templates → templates}/segments/Sidekiq/app/config/sidekiq.yml +0 -0
  1099. /data/{mkbrut/templates → templates}/segments/Sidekiq/app/src/back_end/jobs/app_job.rb +0 -0
  1100. /data/{mkbrut/templates → templates}/segments/Sidekiq/app/src/back_end/jobs/example_job.rb +0 -0
  1101. /data/{mkbrut/templates → templates}/segments/Sidekiq/app/src/back_end/segments/sidekiq_segment.rb +0 -0
  1102. /data/{mkbrut/templates → templates}/segments/Sidekiq/bin/run.sidekiq +0 -0
  1103. /data/{mkbrut/templates → templates}/segments/Sidekiq/specs/back_end/jobs/example_job.spec.rb +0 -0
  1104. /data/{mkbrut/templates → templates}/segments/Sidekiq/specs/integration/sidekiq_works.spec.rb +0 -0
@@ -0,0 +1,143 @@
1
+ require "optparse"
2
+ require "brut/framework/project_environment"
3
+
4
+ # Parses the command line and makes everything parsed available as attributes.
5
+ class Brut::CLI::ParsedCommandLine
6
+
7
+ # The command that should be executed based on what was parsed from the command line
8
+ #
9
+ # @return [Brut::CLI::Commands::BaseCommand]
10
+ attr_reader :command
11
+
12
+ # The remaining unparsed command line arguments.
13
+ #
14
+ # @return [Array<String>]
15
+ attr_reader :argv
16
+
17
+ # The parsed command line switches and flags.
18
+ #
19
+ # @return [Brut::CLI::Options]
20
+ attr_reader :options
21
+
22
+ # The project enviornment, if specified
23
+ # @return [Brut::Framework::ProjectEnvironment]
24
+ attr_reader :project_environment
25
+
26
+ # Create the ParsedCommandLine based on a base command (which provides the initial set of
27
+ # command line options), the ARGV and the ENV when the command was invoked.
28
+ #
29
+ # This should always succeed, however depending on the contents of the parameters, the value
30
+ # for `#command` may be a command that outputs an error.
31
+ def initialize(app_command:, argv:, env:)
32
+ brut_provided_help_requested = false
33
+ app_option_parser = new_option_parser do |opts|
34
+ opts.banner = app_command.description
35
+ app_command.accepts.each_with_index { |class_or_class_and_proc,index| accept(opts,class_or_class_and_proc,index) }
36
+ app_command.opts.each do |option|
37
+ opts.on(*option)
38
+ end
39
+ opts.on("--help", "-h", "Show help") do
40
+ brut_provided_help_requested = true
41
+ end
42
+ end
43
+
44
+ options = {
45
+ 'log-level': "error",
46
+ }
47
+ remaining_argv = app_option_parser.order!(argv,into: options)
48
+
49
+ if remaining_argv[0] == "help"
50
+ brut_provided_help_requested = true
51
+ remaining_argv.shift
52
+ end
53
+
54
+ help_command = if brut_provided_help_requested
55
+ Brut::CLI::Commands::Help.new(app_command,app_option_parser)
56
+ end
57
+
58
+ command = app_command
59
+ loop do
60
+ arg = remaining_argv.shift
61
+ command_found = command.commands.detect { it.name == arg }
62
+ if command_found
63
+ command_found.parent_command = command
64
+ command = command_found
65
+ else
66
+ if arg
67
+ remaining_argv.unshift(arg)
68
+ end
69
+ break
70
+ end
71
+ end
72
+
73
+
74
+ if command != app_command
75
+ command_option_parser = new_option_parser do |opts|
76
+ opts.banner = command.description
77
+ app_command.accepts.each_with_index { |class_or_class_and_proc,index| accept(opts,class_or_class_and_proc,index) }
78
+ command.accepts.each_with_index { |class_or_class_and_proc,index| accept(opts,class_or_class_and_proc,index) }
79
+ opts.on("--help", "-h", "Show help") do
80
+ brut_provided_help_requested = true
81
+ end
82
+ app_command.opts.each { opts.on(*it) }
83
+ command.opts.each { opts.on(*it) }
84
+ end
85
+ remaining_argv = command_option_parser.parse!(remaining_argv, into: options)
86
+ if brut_provided_help_requested
87
+ help_command = Brut::CLI::Commands::Help.new(command,command_option_parser)
88
+ elsif help_command
89
+ help_command.option_parser = command_option_parser
90
+ end
91
+ end
92
+
93
+ if help_command
94
+ command = help_command
95
+ else
96
+ if remaining_argv.empty? && command.default_command
97
+ command = command.default_command
98
+ end
99
+ end
100
+
101
+ if options[:env]
102
+ @project_environment = options.delete(:env)
103
+ end
104
+
105
+ @command = command
106
+ @argv = remaining_argv
107
+ @options = Brut::CLI::Options.new(options)
108
+ rescue => ex
109
+ @command = if env["BRUT_DEBUG"] == "true"
110
+ Brut::CLI::Commands::RaiseError.new(ex)
111
+ else
112
+ Brut::CLI::Commands::OutputError.new(ex)
113
+ end
114
+ @argv = argv
115
+ @options = Brut::CLI::Options.new({})
116
+ end
117
+
118
+ private
119
+
120
+ def new_option_parser(&block)
121
+ OptionParser.new do |opts|
122
+ opts.accept(Brut::Framework::ProjectEnvironment) do |value|
123
+ Brut::Framework::ProjectEnvironment.new(value)
124
+ end
125
+ opts.on("--env=ENVIRONMENT", Brut::Framework::ProjectEnvironment,
126
+ "Project environment, e.g. test, development, production. Default depends on the command")
127
+ opts.on("--log-level=LOG_LEVEL", [ "debug", "info", "warn", "error", "fatal" ],
128
+ "Log level, which should be debug, info, warn, error, or fatal. Defaults to error")
129
+ block.(opts)
130
+ end
131
+ end
132
+
133
+ def accept(opts,class_or_class_and_proc,index)
134
+ klass,conversion_proc = if class_or_class_and_proc.kind_of?(Class)
135
+ [ class_or_class_and_proc, ->(arg) { class_or_class_and_proc.new(arg) } ]
136
+ elsif class_or_class_and_proc.kind_of?(Array) && class_or_class_and_proc.size == 2
137
+ class_or_class_and_proc
138
+ else
139
+ raise "def accepts must return an array whose elements are either a class or a 2-element array of a class and a conversion proc. Index #{index} had a #{class_or_class_and_proc.class}"
140
+ end
141
+ opts.accept(klass,&conversion_proc)
142
+ end
143
+ end
@@ -0,0 +1,124 @@
1
+ # Runs a CLI app/command. Handles all the logic of parsing command line arguments, locating
2
+ # the command object to process the execution, allow for help requests, and understanding the output.
3
+ class Brut::CLI::Runner
4
+
5
+ # Create the runner, which can be used to run `app_command` with whatever command line was provided.
6
+ #
7
+ # @param [Brut::CLI::Commands::BaseCommand] app_command The app that is being executed, in which all command line arguments
8
+ # should be interpreted.
9
+ # @param [IO] stdout the standard output, which will receive all output that isn't related to error messages.
10
+ # @param [IO] stderr the standard error, which will receive error messages
11
+ # @param [IO] stdin the standard input
12
+ # @param [Pathname] project_root root of the Brut project (i.e. where `Gemfile`, `app` et. al. are located)
13
+ def initialize(app_command, stdout:, stderr:,stdin:, project_root:)
14
+ prefix = if $0 =~ /\/brut$/
15
+ "brut"
16
+ else
17
+ $0
18
+ end
19
+ @app_command = app_command
20
+ @stdout = Brut::CLI::Output.new(io: stdout, prefix: "[ #{prefix} ] ")
21
+ @stderr = Brut::CLI::Output.new(io: stderr, prefix: "[ #{prefix} ] ")
22
+ @stdin = stdin
23
+ @project_root = project_root
24
+ end
25
+
26
+ # Run the commmand or subcommand based on the `app_command` given to the constructor and the command line
27
+ # provided in `argv`.
28
+ #
29
+ # @param [Array] argv The arguments provided to the command. Outside of tests, this is almost certainly `ARGV`.
30
+ # @param [ENV|Hash] env The UNIX environment available when the command was executed. This should be treated
31
+ # as if it's `ENV`, even though it may just be a hash.
32
+ # @return [Integer] the exit code to pass back to the shell that invoked the command, with 0 meaning the
33
+ # command succeeded and any other value meaning failure. Generally, this value should be between 0 and 255.
34
+ def run!(argv, env)
35
+
36
+ parsed_command_line = Brut::CLI::ParsedCommandLine.new(app_command: @app_command, argv:, env:)
37
+
38
+ load_unix_environment!(env, parsed_command_line)
39
+ setup_log_level(env, parsed_command_line)
40
+ bootstrap!(env, parsed_command_line)
41
+
42
+ execute_result = Brut::CLI::ExecuteResult.new do
43
+ execution_context = Brut::CLI::Commands::ExecutionContext.new(
44
+ argv: parsed_command_line.argv,
45
+ options: Brut::CLI::Options.new(parsed_command_line.options),
46
+ env:,
47
+ stdout: @stdout,
48
+ stderr: @stderr,
49
+ stdin: @stdin
50
+ )
51
+ parsed_command_line.command.execute(execution_context)
52
+ end
53
+ execute_result.exit_status do |error_message|
54
+ @stderr.puts error_message
55
+ end
56
+ end
57
+
58
+ private
59
+
60
+ def load_unix_environment!(env, parsed_command_line)
61
+ if env["RACK_ENV"]
62
+ if parsed_command_line.project_environment
63
+ @stderr.puts "RACK_ENV is set in the environment, which supercedes the command line, --env ignored"
64
+ end
65
+ else
66
+ env["RACK_ENV"] = if parsed_command_line.project_environment
67
+ parsed_command_line.project_environment.to_s
68
+ else
69
+ parsed_command_line.command.default_rack_env
70
+ end
71
+ end
72
+
73
+ rack_env = RichString.from_string(env["RACK_ENV"])
74
+
75
+ if !rack_env
76
+ return
77
+ end
78
+ require "bundler"
79
+ if rack_env == "production"
80
+ Bundler.require(:default)
81
+ return
82
+ end
83
+
84
+ Bundler.require(:default, rack_env.to_sym)
85
+
86
+ require "dotenv"
87
+
88
+ Dotenv.load(@project_root / ".env.#{rack_env}.local",
89
+ @project_root / ".env.#{rack_env}")
90
+
91
+ if env != ENV
92
+ # To prevent us from having to depend directly on ENV, we want everything
93
+ # to use env, however Dotenv doesn't allow this and just populates ENV,
94
+ # so we want to copy everything over.
95
+ ENV.each do |key, value|
96
+ # Do not allow Dotenv to ovrerwrite RACK_ENV, since that is what we used
97
+ # to load these files in the first place.
98
+ if key != "RACK_ENV"
99
+ env[key] = value
100
+ end
101
+ end
102
+ end
103
+ end
104
+
105
+ def setup_log_level(env, parsed_command_line)
106
+ if env["LOG_LEVEL"]
107
+ @stderr.puts "LOG_LEVEL is set in the environment, which supercedes the command line, --log-level ignored"
108
+ elsif parsed_command_line.options.log_level?
109
+ env["LOG_LEVEL"] = parsed_command_line.options.log_level
110
+ end
111
+ end
112
+
113
+ def bootstrap!(env, parsed_command_line)
114
+ if env["RACK_ENV"]
115
+ require "#{@project_root}/app/bootstrap"
116
+ bootstrap = Bootstrap.new
117
+ if parsed_command_line.command.bootstrap?
118
+ bootstrap.bootstrap!
119
+ else
120
+ bootstrap.configure_only!
121
+ end
122
+ end
123
+ end
124
+ end
data/lib/brut/cli.rb CHANGED
@@ -6,39 +6,17 @@ module Brut
6
6
  # that your CLI will respond to. See {Brut::CLI::app}.
7
7
  module CLI
8
8
 
9
- # Execute your CLI based on its command line invocation. You would call this method inside the
10
- # executable file placed in `bin/` in your project.
11
- # For example, if you have `YourApp::CLI::CleanOldFiles` and you wish to execute
12
- # it via `bin/clean-files`, you'd create `bin/clean-files` like so:
13
- #
14
- # ```
15
- # #!/usr/bin/env ruby
16
- #
17
- # require "bundler"
18
- # Bundler.require
19
- # require "pathname"
20
- # require "brut/cli/apps/db"
21
- #
22
- # exit Brut::CLI.app(YourApp::CLI::CleanOldFiles,
23
- # project_root: Pathname($0).dirname / "..")
24
- # ```
25
- #
26
- # @param app_klass [Class] your CLI app's class.
27
- # @param project_root [Pathname] the path to the root of your project. This is needed before the Brut framework is initialized so
28
- # it must be specified explicitly.
29
- def self.app(app_klass, project_root:)
30
- Brut::CLI::AppRunner.new(app_klass:,project_root:).run!
31
- end
32
- autoload(:App, "brut/cli/app")
33
- autoload(:Command, "brut/cli/command")
9
+ autoload(:Commands, "brut/cli/commands")
34
10
  autoload(:Error, "brut/cli/error")
35
- autoload(:SystemExecError, "brut/cli/error")
11
+ autoload(:ExecuteResult, "brut/cli/execute_result")
12
+ autoload(:Executor, "brut/cli/executor")
36
13
  autoload(:InvalidOption, "brut/cli/error")
37
- autoload(:ExecutionResults, "brut/cli/execution_results")
38
14
  autoload(:Options, "brut/cli/options")
39
15
  autoload(:Output, "brut/cli/output")
40
- autoload(:Executor, "brut/cli/executor")
41
- autoload(:AppRunner, "brut/cli/app_runner")
16
+ autoload(:ParsedCommandLine, "brut/cli/parsed_command_line")
17
+ autoload(:Runner, "brut/cli/runner")
18
+ autoload(:SystemExecError, "brut/cli/error")
19
+
42
20
  # Holds Brut-provided CLI apps that are set up in your project.
43
21
  module Apps
44
22
  autoload(:DB,"brut/cli/apps/db")
@@ -1,4 +1,4 @@
1
- require "fileutils"
1
+ autoload :FileUtils, "fileutils"
2
2
 
3
3
  module Brut
4
4
  # Provides access to the singelton container that contains all of Brut's current configuration.
@@ -1,24 +1,57 @@
1
- require_relative "container"
2
- require_relative "config"
3
- require_relative "../junk_drawer"
4
- require_relative "app"
1
+ def time_it(label,&block)
2
+ start_time = Time.now
3
+ result = block.call
4
+ end_time = Time.now
5
+ duration = end_time - start_time
6
+ #printf "%30s - %.4f\n",label,duration
7
+ result
8
+ end
9
+
10
+ time_it "container" do
11
+ require_relative "container"
12
+ end
13
+ time_it "config" do
14
+ require_relative "config"
15
+ end
16
+ time_it "../junk_drawer" do
17
+ require_relative "../junk_drawer"
18
+ end
19
+ time_it "app" do
20
+ require_relative "app"
21
+ end
5
22
 
6
- require "sequel"
23
+ time_it "sequel" do
24
+ autoload :Sequel, "sequel"
25
+ end
7
26
 
8
- require "semantic_logger"
9
- require_relative "patch_semantic_logger"
27
+ time_it "semantic_logger" do
28
+ autoload :SemanticLogger, "semantic_logger"
29
+ end
10
30
 
11
- require "i18n"
12
- require "zeitwerk"
13
- require "opentelemetry/sdk"
14
- require "opentelemetry/exporter/otlp"
31
+ time_it "i18n" do
32
+ autoload :I18n, "i18n"
33
+ end
34
+ time_it "zeitwerk" do
35
+ require "zeitwerk"
36
+ end
37
+ time_it "opentelemetry/sdk" do
38
+ require "opentelemetry/sdk"
39
+ end
40
+ time_it "opentelemetry/exporter/otlp" do
41
+ require "opentelemetry/exporter/otlp"
42
+ end
43
+ time_it "concurrent-ruby" do
44
+ require "concurrent"
45
+ end
15
46
 
16
47
  # The Master Control Program of Brut. This handles all the bootstrapping and setup of your app. You are not
17
48
  # intended to use or interact with this class at all. End of line.
18
49
  class Brut::Framework::MCP
19
50
 
20
- @otel_shutdown = Concurrent::AtomicBoolean.new(false)
21
- def self.otel_shutdown = @otel_shutdown
51
+ @otel_shutdown = nil
52
+ def self.otel_shutdown
53
+ @otel_shutdown ||= Concurrent::AtomicBoolean.new(false)
54
+ end
22
55
 
23
56
  # Create and configure the MCP. The app will not work until {#boot!} has been called, however most of the core configuration
24
57
  # will be available via `Brut.container`.
@@ -64,6 +97,18 @@ class Brut::Framework::MCP
64
97
  "Prefix for all OTel attributes set by the app",
65
98
  otel_prefix
66
99
  )
100
+ Brut.container.store(
101
+ "app_id",
102
+ "String",
103
+ "Identifier for this app, useful in external contexts like deployment",
104
+ @app.id
105
+ )
106
+ Brut.container.store(
107
+ "app_organization",
108
+ "String",
109
+ "Organization identifier for this app, useful in external contexts like deployment",
110
+ @app.organization
111
+ )
67
112
  end
68
113
 
69
114
  # Starts up the internals of Brut and that app so that it can receive requests from
@@ -301,6 +346,7 @@ class Brut::Framework::MCP
301
346
  private
302
347
 
303
348
  def setup_logging
349
+ require_relative "patch_semantic_logger"
304
350
  SemanticLogger.default_level = Brut.container.log_level
305
351
  semantic_logger_appenders = Brut.container.semantic_logger_appenders
306
352
  if semantic_logger_appenders.kind_of?(Hash)
@@ -11,8 +11,10 @@ class Brut::Framework::ProjectEnvironment
11
11
  when "development" then "development"
12
12
  when "test" then "test"
13
13
  when "production" then "production"
14
- else
14
+ when String
15
15
  raise ArgumentError.new("'#{string_value}' is not a valid project environment")
16
+ else
17
+ raise ArgumentError.new("'#{string_value.class}' cannot be used as a project environment")
16
18
  end
17
19
  end
18
20
 
@@ -1,4 +1,5 @@
1
- require "tzinfo"
1
+ autoload :TZInfo, "tzinfo"
2
+ #require "tzinfo"
2
3
  # Models a clock, which is a time in the context of a time zone. This theoretically makes it easier to get the time and date at the time zone of the user.
3
4
  class Clock
4
5
  attr_reader :timezone
@@ -142,6 +143,7 @@ class RichString
142
143
  def to_s = @string
143
144
  def to_str = self.to_s
144
145
  def length = to_s.length
146
+ def to_sym = to_s.to_sym
145
147
 
146
148
  def to_s_or_nil = @string.to_s.strip.empty? ? nil : self.to_s
147
149
 
@@ -0,0 +1,45 @@
1
+ require "stringio"
2
+ require "brut/cli"
3
+ require_relative "matchers/have_executed"
4
+
5
+ # Convienience methods included in tests for CLI commands
6
+ module Brut::SpecSupport::CLICommandSupport
7
+ # A subclass of {Brut::CLI::Executor} that remembers the commands it was asked to execute, instead of
8
+ # actually executing them. This allows inspection later to see if expected commands had been run.
9
+ #
10
+ # This is used by the `have_executed` matcher.
11
+ class CapturingExecutor < Brut::CLI::Executor
12
+ attr_reader :commands_executed
13
+ def system!(*args)
14
+ @commands_executed ||= []
15
+ if args.length == 1
16
+ @commands_executed << args[0]
17
+ else
18
+ @commands_executed << args
19
+ end
20
+ nil
21
+ end
22
+ end
23
+ # Create an ExecutionContext suitable for any command, but which allows
24
+ # manipulating the data as needed for your test, or to access the various IO streams
25
+ # used by the command.
26
+ def test_execution_context(
27
+ argv: [],
28
+ options: {},
29
+ env: {},
30
+ stdin: StringIO.new,
31
+ stdout: StringIO.new,
32
+ stderr: StringIO.new,
33
+ executor: :default
34
+ )
35
+ Brut::CLI::Commands::ExecutionContext.new(
36
+ argv:,
37
+ options: Brut::CLI::Options.new({ "log-level": "error" }.merge(options)),
38
+ env:,
39
+ stdin:,
40
+ stdout:,
41
+ stderr:,
42
+ executor: executor == :default ? CapturingExecutor.new(out: stdout, err: stderr) : executor,
43
+ )
44
+ end
45
+ end
@@ -1,6 +1,9 @@
1
1
  require "socket"
2
2
  require "timeout"
3
3
 
4
+ module Brut::SpecSupport # This file is designed to be required without the parent namespace
5
+ end
6
+
4
7
  # Manages running the app in test mode for the purposes of running End-to-End tests against it.
5
8
  class Brut::SpecSupport::E2ETestServer
6
9
  include SemanticLogger::Loggable
@@ -18,7 +18,7 @@ module Brut::SpecSupport::GeneralSupport
18
18
  expect(Time.now < check_again_at).to eq(true),"It's after #{check_again_at}. Implementation is needed"
19
19
  end
20
20
  end
21
- # To pass bin/test audit with a class whose implementation is trivial, call this inside the RSpec `describe` block. This is better
21
+ # To pass brut test audit with a class whose implementation is trivial, call this inside the RSpec `describe` block. This is better
22
22
  # than an empty test as it makes it more explicit that you believe the implementation is trivial enough to not require a test. You
23
23
  # can also set an expiration for this thinking.
24
24
  #
@@ -0,0 +1,35 @@
1
+ RSpec::Matchers.define :have_executed do |commands|
2
+ match do |execution_context|
3
+ commands.all? { |command|
4
+ if command.kind_of?(Regexp)
5
+ execution_context.executor.commands_executed.any? { it.kind_of?(String) && it.match(command) }
6
+ else
7
+ execution_context.executor.commands_executed.include?(command)
8
+ end
9
+ }
10
+ end
11
+
12
+ failure_message do |execution_context|
13
+ not_executed = commands.reject { |command|
14
+ if command.kind_of?(Regexp)
15
+ execution_context.executor.commands_executed.any? { it.kind_of?(String) && it.match(command) }
16
+ else
17
+ execution_context.executor.commands_executed.include?(command)
18
+ end
19
+ }
20
+
21
+ "Expected these commands to be executed, but they were not:\n#{format_system_args(not_executed)}\nAll executed commands:\n#{format_system_args(execution_context.executor.commands_executed)}"
22
+ end
23
+ def format_system_args(args)
24
+ args.map { |arg|
25
+ if arg.kind_of?(String)
26
+ arg.to_s
27
+ elsif arg.kind_of?(Regexp)
28
+ "Matching /#{arg.source}/"
29
+ else
30
+ "[" + arg.map(&:inspect).join(", ") + "]"
31
+ end
32
+ }.join("\n")
33
+ end
34
+
35
+ end
@@ -21,7 +21,6 @@
21
21
  # the thread local storage. This allows any component that is injected with data from the `RequestContext` to access it as it would
22
22
  # normally. You can also seed this with data that a component may need.
23
23
  # * Handles all infrastructure for end-to-end tests:
24
- # - starting a test server using {Brut::SpecSupport::E2ETestServer}
25
24
  # - launching Chromium via Playwright
26
25
  # * If using Sidekiq:
27
26
  # - Jobs are cleared before each test
@@ -45,7 +44,7 @@ class Brut::SpecSupport::RSpecSetup
45
44
  # @param [RSpec::Core::Configuration] rspec_config yielded from `RSpec.configure`
46
45
  # @param [boolean] monkey_patch_summary_notification if true (the default),
47
46
  # RSpec's Notifications::SumaryNotification will be monkey-patched to show
48
- # `bin/test` in the summary instead of `./rspec`, as that is how you would
47
+ # `brut test` in the summary instead of `./rspec`, as that is how you would
49
48
  # re-run a test. But, it's still monkey-patching.
50
49
  def initialize(rspec_config:,
51
50
  monkey_patch_summary_notification: true)
@@ -86,6 +85,7 @@ class Brut::SpecSupport::RSpecSetup
86
85
  end
87
86
  end
88
87
  @config.include Brut::SpecSupport::GeneralSupport
88
+ @config.include Brut::SpecSupport::CLICommandSupport, cli_command: true
89
89
  @config.include Brut::SpecSupport::ComponentSupport, component: true
90
90
  @config.include Brut::SpecSupport::HandlerSupport, handler: true
91
91
  @config.include Brut::SpecSupport::E2eSupport, e2e: true
@@ -127,7 +127,6 @@ class Brut::SpecSupport::RSpecSetup
127
127
  if example.metadata[:e2e]
128
128
  e2e_timeout = (ENV["E2E_TIMEOUT_MS"] || example.metadata[:e2e_timeout] || 5_000).to_i
129
129
  optional_sidekiq_support.disable_sidekiq_testing do
130
- Brut::SpecSupport::E2ETestServer.instance.start
131
130
  Playwright.create(playwright_cli_executable_path: "./node_modules/.bin/playwright") do |playwright|
132
131
  launch_args = {
133
132
  headless: true,
@@ -160,9 +159,6 @@ class Brut::SpecSupport::RSpecSetup
160
159
  end
161
160
  end
162
161
  end
163
- @config.after(:suite) do
164
- Brut::SpecSupport::E2ETestServer.instance.stop
165
- end
166
162
  if @monkey_patch_summary_notification
167
163
  monkey_patch_summary_notification!
168
164
  end
@@ -200,13 +196,13 @@ private
200
196
  if !klass.instance_variable_get("@_brut_has_monkeypatched")
201
197
  klass.class_eval do
202
198
  # Slightly reformatted, but the only line that's different
203
- # is the one that said to use './rspec'. Now it says 'bin/test run'
199
+ # is the one that said to use './rspec'. Now it says 'brut test run'
204
200
  def colorized_rerun_commands(colorizer=::RSpec::Core::Formatters::ConsoleCodes)
205
201
  "\nFailed examples:\n\n" +
206
202
  failed_examples.map do |example|
207
203
  rerun_argument = rerun_argument_for(example)
208
204
  colorizer.wrap(
209
- "bin/test run #{rerun_argument}", # <--- this is the only difference
205
+ "brut test run #{rerun_argument}", # <--- this is the only difference
210
206
  RSpec.configuration.failure_color
211
207
  ) +
212
208
  " " +
@@ -10,6 +10,7 @@ require_relative "spec_support/e2e_support"
10
10
  require_relative "spec_support/e2e_test_server"
11
11
  require_relative "spec_support/general_support"
12
12
  require_relative "spec_support/handler_support"
13
+ require_relative "spec_support/cli_command_support"
13
14
  require_relative "spec_support/matcher"
14
15
  require_relative "spec_support/rspec_setup"
15
16
  require_relative "factory_bot"
@@ -20,6 +20,8 @@ class Brut::TUI::MarkupString
20
20
  "~" => :strike,
21
21
  }.freeze
22
22
 
23
+ def to_s = @string
24
+
23
25
  # Parse the string for known markup, yielding at key parsing events.
24
26
  #
25
27
  # @yield [directive, value] called for each parsing event, where value depends on directive. The block
@@ -1,13 +1,14 @@
1
1
  # Fired when a command has provided at least some output on its standard output.
2
2
  class Brut::TUI::Script::Events::CommandStdOut < Brut::TUI::Events::BaseEvent
3
- def initialize(step:, output:)
3
+ def initialize(step:, output:, show: false)
4
4
  @step = step
5
5
  @output = output
6
+ @show = show
6
7
  end
7
8
 
8
9
  # Adds `description`, `command` and `output` to the event keywords. `output` is a string
9
10
  # containing whatever output was available. This is likely not terminated with a newline.
10
11
  def deconstruct_keys(keys=nil)
11
- super.merge({ description: @step.description, command: @step.command, output: @output })
12
+ super.merge({ description: @step.description, command: @step.command, output: @output, show: @show })
12
13
  end
13
14
  end