brut 0.0.27 → 0.0.28

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 (359) hide show
  1. checksums.yaml +4 -4
  2. data/Gemfile.lock +1 -1
  3. data/brutrb.com/.vitepress/config.mjs +1 -0
  4. data/brutrb.com/dev-environment.md +6 -5
  5. data/brutrb.com/doc-conventions.md +1 -1
  6. data/brutrb.com/getting-started.md +64 -28
  7. data/brutrb.com/instrumentation.md +12 -0
  8. data/brutrb.com/layouts.md +130 -0
  9. data/docs/404.html +2 -2
  10. data/docs/ai.html +5 -5
  11. data/docs/api/Brut/BackEnd/SeedData.html +1 -1
  12. data/docs/api/Brut/BackEnd/Sidekiq/Middlewares/Server/FlushSpans.html +1 -1
  13. data/docs/api/Brut/BackEnd/Sidekiq/Middlewares/Server.html +1 -1
  14. data/docs/api/Brut/BackEnd/Sidekiq/Middlewares.html +1 -1
  15. data/docs/api/Brut/BackEnd/Sidekiq.html +1 -1
  16. data/docs/api/Brut/BackEnd/Validators/FormValidator.html +1 -1
  17. data/docs/api/Brut/BackEnd/Validators.html +1 -1
  18. data/docs/api/Brut/BackEnd.html +1 -1
  19. data/docs/api/Brut/CLI/App.html +38 -13
  20. data/docs/api/Brut/CLI/AppRunner.html +1 -1
  21. data/docs/api/Brut/CLI/Apps/BuildAssets/All.html +2 -2
  22. data/docs/api/Brut/CLI/Apps/BuildAssets/CSS.html +2 -2
  23. data/docs/api/Brut/CLI/Apps/BuildAssets/Images.html +2 -2
  24. data/docs/api/Brut/CLI/Apps/BuildAssets/JS.html +2 -2
  25. data/docs/api/Brut/CLI/Apps/BuildAssets.html +1 -1
  26. data/docs/api/Brut/CLI/Apps/DB/Create.html +2 -2
  27. data/docs/api/Brut/CLI/Apps/DB/Drop.html +2 -2
  28. data/docs/api/Brut/CLI/Apps/DB/Migrate.html +9 -3
  29. data/docs/api/Brut/CLI/Apps/DB/NewMigration.html +11 -11
  30. data/docs/api/Brut/CLI/Apps/DB/Rebuild.html +2 -2
  31. data/docs/api/Brut/CLI/Apps/DB/Seed.html +2 -2
  32. data/docs/api/Brut/CLI/Apps/DB/Status.html +12 -12
  33. data/docs/api/Brut/CLI/Apps/DB.html +1 -1
  34. data/docs/api/Brut/CLI/Apps/DeployBase/GitChecks.html +270 -0
  35. data/docs/api/Brut/CLI/Apps/DeployBase.html +257 -0
  36. data/docs/api/Brut/CLI/Apps/HerokuContainerBasedDeploy/Deploy.html +585 -0
  37. data/docs/api/Brut/CLI/Apps/HerokuContainerBasedDeploy.html +196 -0
  38. data/docs/api/Brut/CLI/Apps/Scaffold/Action/Route.html +1 -1
  39. data/docs/api/Brut/CLI/Apps/Scaffold/Action.html +2 -2
  40. data/docs/api/Brut/CLI/Apps/Scaffold/Component.html +2 -2
  41. data/docs/api/Brut/CLI/Apps/Scaffold/CustomElementTest.html +2 -2
  42. data/docs/api/Brut/CLI/Apps/Scaffold/E2ETest.html +2 -2
  43. data/docs/api/Brut/CLI/Apps/Scaffold/Form.html +2 -2
  44. data/docs/api/Brut/CLI/Apps/Scaffold/Page/Route.html +1 -1
  45. data/docs/api/Brut/CLI/Apps/Scaffold/Page.html +2 -2
  46. data/docs/api/Brut/CLI/Apps/Scaffold/RoutesEditor.html +1 -1
  47. data/docs/api/Brut/CLI/Apps/Scaffold/Test.html +2 -2
  48. data/docs/api/Brut/CLI/Apps/Scaffold.html +1 -1
  49. data/docs/api/Brut/CLI/Apps/Test/Audit.html +12 -10
  50. data/docs/api/Brut/CLI/Apps/Test/E2e.html +8 -8
  51. data/docs/api/Brut/CLI/Apps/Test/JS.html +9 -9
  52. data/docs/api/Brut/CLI/Apps/Test/Run.html +18 -18
  53. data/docs/api/Brut/CLI/Apps/Test.html +1 -1
  54. data/docs/api/Brut/CLI/Apps.html +2 -2
  55. data/docs/api/Brut/CLI/Command.html +113 -28
  56. data/docs/api/Brut/CLI/Error.html +1 -1
  57. data/docs/api/Brut/CLI/ExecutionResults/Result.html +1 -1
  58. data/docs/api/Brut/CLI/ExecutionResults.html +1 -1
  59. data/docs/api/Brut/CLI/Executor.html +169 -38
  60. data/docs/api/Brut/CLI/InvalidOption.html +1 -1
  61. data/docs/api/Brut/CLI/Options.html +68 -19
  62. data/docs/api/Brut/CLI/Output.html +1 -1
  63. data/docs/api/Brut/CLI/SystemExecError.html +1 -1
  64. data/docs/api/Brut/CLI.html +1 -1
  65. data/docs/api/Brut/FactoryBot.html +1 -1
  66. data/docs/api/Brut/Framework/App.html +1 -1
  67. data/docs/api/Brut/Framework/Config.html +1 -1
  68. data/docs/api/Brut/Framework/Container.html +110 -29
  69. data/docs/api/Brut/Framework/Error.html +1 -1
  70. data/docs/api/Brut/Framework/Errors/AbstractMethod.html +89 -1
  71. data/docs/api/Brut/Framework/Errors/Bug.html +1 -1
  72. data/docs/api/Brut/Framework/Errors/MissingConfiguration.html +1 -1
  73. data/docs/api/Brut/Framework/Errors/MissingParameter.html +1 -1
  74. data/docs/api/Brut/Framework/Errors/NoClassForPath.html +1 -1
  75. data/docs/api/Brut/Framework/Errors/NotFound.html +1 -1
  76. data/docs/api/Brut/Framework/Errors/NotImplemented.html +1 -1
  77. data/docs/api/Brut/Framework/Errors.html +31 -8
  78. data/docs/api/Brut/Framework/FussyTypeEnforcement.html +1 -1
  79. data/docs/api/Brut/Framework/MCP.html +1 -1
  80. data/docs/api/Brut/Framework/ProjectEnvironment.html +1 -1
  81. data/docs/api/Brut/Framework.html +1 -1
  82. data/docs/api/Brut/FrontEnd/AssetPathResolver.html +1 -1
  83. data/docs/api/Brut/FrontEnd/Component/Helpers.html +36 -26
  84. data/docs/api/Brut/FrontEnd/Component.html +7 -7
  85. data/docs/api/Brut/FrontEnd/Components/ConstraintViolations.html +1 -1
  86. data/docs/api/Brut/FrontEnd/Components/FormTag.html +37 -29
  87. data/docs/api/Brut/FrontEnd/Components/I18nTranslations.html +1 -1
  88. data/docs/api/Brut/FrontEnd/Components/Input.html +1 -1
  89. data/docs/api/Brut/FrontEnd/Components/Inputs/CsrfToken.html +1 -1
  90. data/docs/api/Brut/FrontEnd/Components/Inputs/InputTag.html +20 -117
  91. data/docs/api/Brut/FrontEnd/Components/Inputs/RadioButton.html +25 -23
  92. data/docs/api/Brut/FrontEnd/Components/Inputs/SelectTagWithOptions.html +73 -380
  93. data/docs/api/Brut/FrontEnd/Components/Inputs/TextareaTag.html +22 -138
  94. data/docs/api/Brut/FrontEnd/Components/Inputs.html +1 -1
  95. data/docs/api/Brut/FrontEnd/Components/LocaleDetection.html +1 -1
  96. data/docs/api/Brut/FrontEnd/Components/PageIdentifier.html +1 -1
  97. data/docs/api/Brut/FrontEnd/Components/TimeTag.html +1 -1
  98. data/docs/api/Brut/FrontEnd/Components/Traceparent.html +1 -1
  99. data/docs/api/Brut/FrontEnd/Components.html +23 -2
  100. data/docs/api/Brut/FrontEnd/Download.html +1 -1
  101. data/docs/api/Brut/FrontEnd/Flash.html +1 -1
  102. data/docs/api/Brut/FrontEnd/Form.html +1 -1
  103. data/docs/api/Brut/FrontEnd/Forms/ConstraintViolation.html +24 -68
  104. data/docs/api/Brut/FrontEnd/Forms/Input.html +1 -1
  105. data/docs/api/Brut/FrontEnd/Forms/InputDeclarations.html +4 -4
  106. data/docs/api/Brut/FrontEnd/Forms/InputDefinition.html +1 -1
  107. data/docs/api/Brut/FrontEnd/Forms/RadioButtonGroupInput.html +1 -1
  108. data/docs/api/Brut/FrontEnd/Forms/RadioButtonGroupInputDefinition.html +1 -1
  109. data/docs/api/Brut/FrontEnd/Forms/SelectInput.html +1 -1
  110. data/docs/api/Brut/FrontEnd/Forms/SelectInputDefinition.html +1 -1
  111. data/docs/api/Brut/FrontEnd/Forms/ValidityState.html +72 -22
  112. data/docs/api/Brut/FrontEnd/Forms.html +1 -1
  113. data/docs/api/Brut/FrontEnd/GenericResponse.html +1 -1
  114. data/docs/api/Brut/FrontEnd/Handler.html +1 -1
  115. data/docs/api/Brut/FrontEnd/Handlers/CspReportingHandler.html +1 -1
  116. data/docs/api/Brut/FrontEnd/Handlers/InstrumentationHandler/TraceParent.html +1 -1
  117. data/docs/api/Brut/FrontEnd/Handlers/InstrumentationHandler.html +1 -1
  118. data/docs/api/Brut/FrontEnd/Handlers/LocaleDetectionHandler.html +1 -1
  119. data/docs/api/Brut/FrontEnd/Handlers/MissingHandler/Form.html +1 -1
  120. data/docs/api/Brut/FrontEnd/Handlers/MissingHandler.html +1 -1
  121. data/docs/api/Brut/FrontEnd/Handlers.html +1 -1
  122. data/docs/api/Brut/FrontEnd/HandlingResults.html +1 -1
  123. data/docs/api/Brut/FrontEnd/HttpMethod.html +1 -1
  124. data/docs/api/Brut/FrontEnd/HttpStatus.html +1 -1
  125. data/docs/api/Brut/FrontEnd/InlineSvgLocator.html +1 -1
  126. data/docs/api/Brut/FrontEnd/Layout.html +1 -1
  127. data/docs/api/Brut/FrontEnd/Middleware.html +1 -1
  128. data/docs/api/Brut/FrontEnd/Middlewares/AnnotateBrutOwnedPaths.html +1 -1
  129. data/docs/api/Brut/FrontEnd/Middlewares/Favicon.html +1 -1
  130. data/docs/api/Brut/FrontEnd/Middlewares/OpenTelemetrySpan.html +1 -1
  131. data/docs/api/Brut/FrontEnd/Middlewares/ReloadApp.html +6 -2
  132. data/docs/api/Brut/FrontEnd/Middlewares.html +1 -1
  133. data/docs/api/Brut/FrontEnd/Page.html +1 -1
  134. data/docs/api/Brut/FrontEnd/Pages/MissingPage.html +1 -1
  135. data/docs/api/Brut/FrontEnd/Pages.html +1 -1
  136. data/docs/api/Brut/FrontEnd/RequestContext.html +1 -1
  137. data/docs/api/Brut/FrontEnd/RouteHook.html +1 -1
  138. data/docs/api/Brut/FrontEnd/RouteHooks/AgeFlash.html +1 -1
  139. data/docs/api/Brut/FrontEnd/RouteHooks/CSPNoInlineScripts.html +1 -1
  140. data/docs/api/Brut/FrontEnd/RouteHooks/CSPNoInlineStylesOrScripts/ReportOnly.html +1 -1
  141. data/docs/api/Brut/FrontEnd/RouteHooks/CSPNoInlineStylesOrScripts.html +1 -1
  142. data/docs/api/Brut/FrontEnd/RouteHooks/LocaleDetection.html +1 -1
  143. data/docs/api/Brut/FrontEnd/RouteHooks/SetupRequestContext.html +1 -1
  144. data/docs/api/Brut/FrontEnd/RouteHooks.html +1 -1
  145. data/docs/api/Brut/FrontEnd/Routing/FormHandlerRoute.html +1 -1
  146. data/docs/api/Brut/FrontEnd/Routing/FormRoute.html +1 -1
  147. data/docs/api/Brut/FrontEnd/Routing/MissingForm.html +1 -1
  148. data/docs/api/Brut/FrontEnd/Routing/MissingHandler.html +1 -1
  149. data/docs/api/Brut/FrontEnd/Routing/MissingPage.html +1 -1
  150. data/docs/api/Brut/FrontEnd/Routing/MissingPath.html +1 -1
  151. data/docs/api/Brut/FrontEnd/Routing/PageRoute.html +1 -1
  152. data/docs/api/Brut/FrontEnd/Routing/Route.html +1 -1
  153. data/docs/api/Brut/FrontEnd/Routing.html +1 -1
  154. data/docs/api/Brut/FrontEnd/Session.html +1 -1
  155. data/docs/api/Brut/FrontEnd.html +1 -1
  156. data/docs/api/Brut/I18n/BaseMethods.html +1 -1
  157. data/docs/api/Brut/I18n/ForBackEnd.html +1 -1
  158. data/docs/api/Brut/I18n/ForCLI.html +1 -1
  159. data/docs/api/Brut/I18n/ForHTML.html +1 -1
  160. data/docs/api/Brut/I18n/HTTPAcceptLanguage/AlwaysEnglish.html +1 -1
  161. data/docs/api/Brut/I18n/HTTPAcceptLanguage.html +1 -1
  162. data/docs/api/Brut/I18n.html +1 -1
  163. data/docs/api/Brut/Instrumentation/LoggerSpanExporter.html +1 -1
  164. data/docs/api/Brut/Instrumentation/OpenTelemetry/NormalizedAttributes.html +1 -1
  165. data/docs/api/Brut/Instrumentation/OpenTelemetry/Span.html +1 -1
  166. data/docs/api/Brut/Instrumentation/OpenTelemetry.html +1 -1
  167. data/docs/api/Brut/Instrumentation.html +1 -1
  168. data/docs/api/Brut/SinatraHelpers/ClassMethods.html +1 -1
  169. data/docs/api/Brut/SinatraHelpers.html +1 -1
  170. data/docs/api/Brut/SpecSupport/ClockSupport.html +1 -1
  171. data/docs/api/Brut/SpecSupport/ComponentSupport.html +1 -1
  172. data/docs/api/Brut/SpecSupport/E2ETestServer.html +20 -20
  173. data/docs/api/Brut/SpecSupport/E2eSupport.html +1 -1
  174. data/docs/api/Brut/SpecSupport/EnhancedNode.html +1 -1
  175. data/docs/api/Brut/SpecSupport/FlashSupport.html +1 -1
  176. data/docs/api/Brut/SpecSupport/GeneralSupport/ClassMethods.html +1 -1
  177. data/docs/api/Brut/SpecSupport/GeneralSupport.html +1 -1
  178. data/docs/api/Brut/SpecSupport/HandlerSupport.html +2 -2
  179. data/docs/api/Brut/SpecSupport/Matchers/BeABug.html +142 -0
  180. data/docs/api/Brut/SpecSupport/Matchers/BePageFor.html +142 -0
  181. data/docs/api/Brut/SpecSupport/Matchers/BeRoutingFor.html +155 -0
  182. data/docs/api/Brut/SpecSupport/Matchers/HaveConstraintViolation.html +55 -25
  183. data/docs/api/Brut/SpecSupport/Matchers/HaveGenerated.html +149 -0
  184. data/docs/api/Brut/SpecSupport/Matchers/HaveHTMLAttribute.html +46 -19
  185. data/docs/api/Brut/SpecSupport/Matchers/HaveI18nString.html +149 -0
  186. data/docs/api/Brut/SpecSupport/Matchers/HaveLinkTo.html +149 -0
  187. data/docs/api/Brut/SpecSupport/Matchers/HaveRedirectedTo.html +165 -0
  188. data/docs/api/Brut/SpecSupport/Matchers/HaveReturnedHttpStatus.html +158 -0
  189. data/docs/api/Brut/SpecSupport/Matchers/HaveReturnedRackResponse.html +156 -0
  190. data/docs/api/Brut/SpecSupport/Matchers.html +2 -2
  191. data/docs/api/Brut/SpecSupport/RSpecSetup/OptionalSidekiqSupport.html +24 -24
  192. data/docs/api/Brut/SpecSupport/RSpecSetup.html +55 -20
  193. data/docs/api/Brut/SpecSupport/SessionSupport.html +1 -1
  194. data/docs/api/Brut/SpecSupport.html +1 -1
  195. data/docs/api/Brut.html +1 -1
  196. data/docs/api/Clock.html +1 -1
  197. data/docs/api/RichString.html +1 -1
  198. data/docs/api/SemanticLogger/Appender/Async.html +1 -1
  199. data/docs/api/Sequel/Extensions/BrutInstrumentation.html +5 -1
  200. data/docs/api/Sequel/Extensions/BrutMigrations.html +36 -28
  201. data/docs/api/Sequel/Extensions.html +1 -1
  202. data/docs/api/Sequel/Plugins/CreatedAt/InstanceMethods.html +1 -1
  203. data/docs/api/Sequel/Plugins/CreatedAt.html +1 -1
  204. data/docs/api/Sequel/Plugins/ExternalId/ClassMethods.html +1 -1
  205. data/docs/api/Sequel/Plugins/ExternalId/InstanceMethods.html +1 -1
  206. data/docs/api/Sequel/Plugins/ExternalId.html +1 -1
  207. data/docs/api/Sequel/Plugins/FindBang/ClassMethods.html +1 -1
  208. data/docs/api/Sequel/Plugins/FindBang.html +1 -1
  209. data/docs/api/Sequel/Plugins.html +1 -1
  210. data/docs/api/Sequel.html +1 -1
  211. data/docs/api/SpecSupport/Matchers/BeABug.html +143 -0
  212. data/docs/api/_index.html +92 -1
  213. data/docs/api/class_list.html +1 -1
  214. data/docs/api/file.README.html +1 -1
  215. data/docs/api/index.html +1 -1
  216. data/docs/api/method_list.html +392 -336
  217. data/docs/api/top-level-namespace.html +1 -1
  218. data/docs/assets/{ai.md.tZrjP9im.js → ai.md._6HCDL6d.js} +1 -1
  219. data/docs/assets/ai.md._6HCDL6d.lean.js +1 -0
  220. data/docs/assets/{app.D_yaTITQ.js → app.BX81XO4N.js} +1 -1
  221. data/docs/assets/chunks/@localSearchIndexroot.CoYzciVi.js +1 -0
  222. data/docs/assets/chunks/{VPLocalSearchBox.B2-ZzyTY.js → VPLocalSearchBox.gABXcTWp.js} +1 -1
  223. data/docs/assets/chunks/{theme.CfGFVRvE.js → theme.DwUXXAL3.js} +2 -2
  224. data/docs/assets/{components.md.eCttGlN-.js → components.md.CRUMdRoN.js} +1 -1
  225. data/docs/assets/{configuration.md.BRriU0cL.js → configuration.md.BGHl8oRC.js} +1 -1
  226. data/docs/assets/{dev-environment.md.BNc8AYiK.js → dev-environment.md.GZv6xvi9.js} +1 -1
  227. data/docs/assets/doc-conventions.md.-kN3Xo5C.js +1 -0
  228. data/docs/assets/{doc-conventions.md.DCfRXXi-.lean.js → doc-conventions.md.-kN3Xo5C.lean.js} +1 -1
  229. data/docs/assets/{forms.md.CBTYQ_Cz.js → forms.md.B-koVgyw.js} +23 -23
  230. data/docs/assets/{forms.md.CBTYQ_Cz.lean.js → forms.md.B-koVgyw.lean.js} +1 -1
  231. data/docs/assets/getting-started.md.Ciz82L0m.js +25 -0
  232. data/docs/assets/getting-started.md.Ciz82L0m.lean.js +1 -0
  233. data/docs/assets/{instrumentation.md.CL6ax7nT.js → instrumentation.md.a9Pjps4P.js} +2 -2
  234. data/docs/assets/{instrumentation.md.CL6ax7nT.lean.js → instrumentation.md.a9Pjps4P.lean.js} +1 -1
  235. data/docs/assets/layouts.md.cPnh3NId.js +51 -0
  236. data/docs/assets/layouts.md.cPnh3NId.lean.js +1 -0
  237. data/docs/assets/lsp.md.Bsu-f6VU.js +1 -0
  238. data/docs/assets/lsp.md.Bsu-f6VU.lean.js +1 -0
  239. data/docs/assets/{overview.md.CDalkuxV.js → overview.md.C5wlBcR5.js} +3 -3
  240. data/docs/assets/recipes_authentication.md.CAsXf7hk.js +1 -0
  241. data/docs/assets/recipes_authentication.md.CAsXf7hk.lean.js +1 -0
  242. data/docs/assets.html +4 -4
  243. data/docs/brut-js/api/AjaxSubmit.html +1 -1
  244. data/docs/brut-js/api/AjaxSubmit.js.html +1 -1
  245. data/docs/brut-js/api/Autosubmit.html +1 -1
  246. data/docs/brut-js/api/Autosubmit.js.html +1 -1
  247. data/docs/brut-js/api/BaseCustomElement.html +1 -1
  248. data/docs/brut-js/api/BaseCustomElement.js.html +1 -1
  249. data/docs/brut-js/api/BrutCustomElements.html +1 -1
  250. data/docs/brut-js/api/BufferedLogger.html +1 -1
  251. data/docs/brut-js/api/ConfirmSubmit.html +1 -1
  252. data/docs/brut-js/api/ConfirmSubmit.js.html +1 -1
  253. data/docs/brut-js/api/ConfirmationDialog.html +1 -1
  254. data/docs/brut-js/api/ConfirmationDialog.js.html +1 -1
  255. data/docs/brut-js/api/ConstraintViolationMessage.html +1 -1
  256. data/docs/brut-js/api/ConstraintViolationMessage.js.html +1 -1
  257. data/docs/brut-js/api/ConstraintViolationMessages.html +1 -1
  258. data/docs/brut-js/api/ConstraintViolationMessages.js.html +1 -1
  259. data/docs/brut-js/api/CopyToClipboard.html +1 -1
  260. data/docs/brut-js/api/CopyToClipboard.js.html +1 -1
  261. data/docs/brut-js/api/Form.html +1 -1
  262. data/docs/brut-js/api/Form.js.html +1 -1
  263. data/docs/brut-js/api/I18nTranslation.html +1 -1
  264. data/docs/brut-js/api/I18nTranslation.js.html +1 -1
  265. data/docs/brut-js/api/LocaleDetection.html +1 -1
  266. data/docs/brut-js/api/LocaleDetection.js.html +1 -1
  267. data/docs/brut-js/api/Logger.html +1 -1
  268. data/docs/brut-js/api/Logger.js.html +1 -1
  269. data/docs/brut-js/api/Message.html +1 -1
  270. data/docs/brut-js/api/Message.js.html +1 -1
  271. data/docs/brut-js/api/PrefixedLogger.html +1 -1
  272. data/docs/brut-js/api/RichString.html +1 -1
  273. data/docs/brut-js/api/RichString.js.html +1 -1
  274. data/docs/brut-js/api/Tabs.html +1 -1
  275. data/docs/brut-js/api/Tabs.js.html +1 -1
  276. data/docs/brut-js/api/Tracing.html +1 -1
  277. data/docs/brut-js/api/Tracing.js.html +1 -1
  278. data/docs/brut-js/api/external-CustomElementRegistry.html +1 -1
  279. data/docs/brut-js/api/external-Performance.html +1 -1
  280. data/docs/brut-js/api/external-Promise.html +1 -1
  281. data/docs/brut-js/api/external-ValidityState.html +1 -1
  282. data/docs/brut-js/api/external-Window.html +1 -1
  283. data/docs/brut-js/api/external-fetch.html +1 -1
  284. data/docs/brut-js/api/global.html +1 -1
  285. data/docs/brut-js/api/index.html +1 -1
  286. data/docs/brut-js/api/index.js.html +1 -1
  287. data/docs/brut-js/api/module-testing.html +1 -1
  288. data/docs/brut-js/api/testing.AssetMetadata.html +1 -1
  289. data/docs/brut-js/api/testing.AssetMetadataLoader.html +1 -1
  290. data/docs/brut-js/api/testing.CustomElementTest.html +1 -1
  291. data/docs/brut-js/api/testing.DOMCreator.html +1 -1
  292. data/docs/brut-js/api/testing_AssetMetadata.js.html +1 -1
  293. data/docs/brut-js/api/testing_AssetMetadataLoader.js.html +1 -1
  294. data/docs/brut-js/api/testing_CustomElementTest.js.html +1 -1
  295. data/docs/brut-js/api/testing_DOMCreator.js.html +1 -1
  296. data/docs/brut-js/api/testing_index.js.html +1 -1
  297. data/docs/brut-js.html +4 -4
  298. data/docs/business-logic.html +4 -4
  299. data/docs/cli.html +4 -4
  300. data/docs/components.html +6 -6
  301. data/docs/configuration.html +5 -5
  302. data/docs/css.html +4 -4
  303. data/docs/custom-element-tests.html +4 -4
  304. data/docs/database-access.html +4 -4
  305. data/docs/database-schema.html +4 -4
  306. data/docs/deployment.html +4 -4
  307. data/docs/dev-environment.html +5 -5
  308. data/docs/doc-conventions.html +5 -5
  309. data/docs/end-to-end-tests.html +4 -4
  310. data/docs/flash-and-session.html +4 -4
  311. data/docs/forms.html +27 -27
  312. data/docs/getting-started.html +29 -6
  313. data/docs/handlers.html +4 -4
  314. data/docs/hashmap.json +1 -1
  315. data/docs/hooks.html +4 -4
  316. data/docs/i18n.html +4 -4
  317. data/docs/index.html +3 -3
  318. data/docs/instrumentation.html +5 -5
  319. data/docs/javascript.html +4 -4
  320. data/docs/jobs.html +4 -4
  321. data/docs/keyword-injection.html +4 -4
  322. data/docs/layouts.html +74 -0
  323. data/docs/lsp.html +24 -0
  324. data/docs/markdown-examples.html +4 -4
  325. data/docs/middleware.html +4 -4
  326. data/docs/not-released.html +4 -4
  327. data/docs/overview.html +8 -8
  328. data/docs/pages.html +5 -5
  329. data/docs/recipes/authentication.html +24 -0
  330. data/docs/routes.html +4 -4
  331. data/docs/security.html +4 -4
  332. data/docs/seed-data.html +4 -4
  333. data/docs/space-time-continuum.html +4 -4
  334. data/docs/tutorial.html +4 -4
  335. data/docs/unit-tests.html +4 -4
  336. data/lib/brut/cli/app.rb +7 -2
  337. data/lib/brut/cli/apps/deploy_base.rb +86 -0
  338. data/lib/brut/cli/apps/heroku_container_based_deploy.rb +194 -0
  339. data/lib/brut/cli/command.rb +7 -13
  340. data/lib/brut/cli/executor.rb +31 -5
  341. data/lib/brut/cli/options.rb +4 -0
  342. data/lib/brut/cli.rb +4 -3
  343. data/lib/brut/framework/container.rb +25 -7
  344. data/lib/brut/framework/errors/abstract_method.rb +7 -0
  345. data/lib/brut/framework/errors.rb +4 -2
  346. data/lib/brut/front_end/middlewares/reload_app.rb +2 -0
  347. data/lib/brut/spec_support/rspec_setup.rb +42 -2
  348. data/lib/brut/version.rb +1 -1
  349. data/lib/sequel/extensions/brut_instrumentation.rb +4 -0
  350. metadata +49 -23
  351. data/docs/assets/ai.md.tZrjP9im.lean.js +0 -1
  352. data/docs/assets/chunks/@localSearchIndexroot.BsN5i0Fi.js +0 -1
  353. data/docs/assets/doc-conventions.md.DCfRXXi-.js +0 -1
  354. data/docs/assets/getting-started.md.Bz2s1Vjb.js +0 -2
  355. data/docs/assets/getting-started.md.Bz2s1Vjb.lean.js +0 -1
  356. /data/docs/assets/{components.md.eCttGlN-.lean.js → components.md.CRUMdRoN.lean.js} +0 -0
  357. /data/docs/assets/{configuration.md.BRriU0cL.lean.js → configuration.md.BGHl8oRC.lean.js} +0 -0
  358. /data/docs/assets/{dev-environment.md.BNc8AYiK.lean.js → dev-environment.md.GZv6xvi9.lean.js} +0 -0
  359. /data/docs/assets/{overview.md.CDalkuxV.lean.js → overview.md.C5wlBcR5.lean.js} +0 -0
@@ -0,0 +1,194 @@
1
+ require "brut/cli"
2
+ class Brut::CLI::Apps::HerokuContainerBasedDeploy < Brut::CLI::Apps::DeployBase
3
+ description "Deploy to Heroku using containers"
4
+ default_command :deploy
5
+ configure_only!
6
+
7
+ class Deploy < Brut::CLI::Command
8
+ description "Build images, push them to Heroku, and deploy them"
9
+
10
+ detailed_description %{
11
+ Manages a deploy process based on using Heroku's Container Registry. See
12
+
13
+ https://devcenter.heroku.com/articles/container-registry-and-runtime
14
+
15
+ for details. You are assumed to understand this. This command will make the process somewhat easier.
16
+
17
+ This will use deploy/Dockerfile as a template to create one Dockerfile for each process you want to run in Heroku. deploy/heroku_config.rb is where the processes and their commands are configured.
18
+
19
+ The release phase is included automatically, based on bin/release.
20
+ }
21
+
22
+ opts.on("--platform=PLATFORM","Override default platform. Can be any Docker platform.")
23
+ opts.on("--[no-]dry-run", "Print the commands that would be run and don't actually do anything. Implies --skip-checks")
24
+ opts.on("--[no-]skip-checks", "Skip checks for code having been committed and pushed")
25
+ opts.on("--[no-]deploy", "After images are pushed, actually deploy them")
26
+ opts.on("--[no-]push", "After images are created, push them to Heroku's registry. If false, implies --no-deploy")
27
+
28
+ def after_bootstrap(app:)
29
+ @app_id = app.id
30
+ @organization = app.organization
31
+ end
32
+
33
+ def execute
34
+ options.set_default(:deploy, true)
35
+ options.set_default(:push, true)
36
+ if !options.push?
37
+ options[:deploy] = false
38
+ end
39
+ local_repo_checks = Brut::CLI::Apps::DeployBase::GitChecks.new(
40
+ out: @out,
41
+ err: @err,
42
+ executor: @executor,
43
+ warn_only: options.skip_checks? || options.dry_run?
44
+ )
45
+ if options.dry_run?
46
+ def system!(*args)
47
+ out.puts "DRY RUN, NOT EXECUTING '#{args}'"
48
+ end
49
+ end
50
+
51
+ version = begin
52
+ git_guess = %{git rev-parse HEAD}
53
+ stdout, stderr, status = Open3.capture3(git_guess)
54
+ if status.success?
55
+ stdout.strip
56
+ else
57
+ raise "Attempt to use git via command '#{git_guess}' to figure out the version failed: #{stdout}#{stderr}"
58
+ end
59
+ end
60
+ short_version = version[0..7]
61
+
62
+ platform = options.platform || "linux/amd64"
63
+ heroku_app_name = @app_id
64
+
65
+ out.puts "Reading HerokuConfig:"
66
+ require_relative Brut.container.project_root / "deploy" / "heroku_config"
67
+
68
+ additional_images = HerokuConfig.additional_images.map { |name,config|
69
+ cmd = config.fetch(:cmd)
70
+ out.puts " - #{name} will run #{cmd} in production"
71
+ image_name = %{#{@organization}/#{@app_id}:#{short_version}-#{name}}
72
+ [
73
+ name,
74
+ {
75
+ cmd:,
76
+ image_name:,
77
+ dockerfile: "deploy/Dockerfile.#{name}",
78
+ heroku_image_name: "registry.heroku.com/#{heroku_app_name}/#{name}",
79
+ }
80
+ ]
81
+ }.to_h
82
+
83
+ images = {
84
+ "web" => {
85
+ cmd: "bin/run",
86
+ image_name: %{#{@organization}/#{@app_id}:#{short_version}-web},
87
+ dockerfile: "deploy/Dockerfile.web",
88
+ heroku_image_name: "registry.heroku.com/#{heroku_app_name}/web",
89
+ },
90
+ "release" => {
91
+ cmd: "bin/release",
92
+ image_name: %{#{@organization}/#{@app_id}:#{short_version}-release},
93
+ dockerfile: "deploy/Dockerfile.release",
94
+ heroku_image_name: "registry.heroku.com/#{heroku_app_name}/release",
95
+ },
96
+ }.merge(additional_images)
97
+
98
+ out.puts " - release will run bin/release in production"
99
+
100
+ local_repo_checks.check!
101
+ require_heroku_login!(options)
102
+
103
+ FileUtils.chdir Brut.container.project_root do
104
+
105
+ out.puts "Generating Dockerfiles"
106
+ images.each do |name,metadata|
107
+ cmd = metadata.fetch(:cmd)
108
+ dockerfile = metadata.fetch(:dockerfile)
109
+
110
+ out.puts "Creating '#{dockerfile}' for '#{name}' that will use command '#{cmd}'"
111
+
112
+ File.open(dockerfile,"w") do |file|
113
+ file.puts "# DO NOT EDIT - THIS IS GENERATED"
114
+ file.puts "# To make changes, modifiy deploy/Dockerfile and run #{$0}"
115
+ file.puts File.read("deploy/Dockerfile")
116
+ file.puts
117
+ file.puts "# Added by #{$0}"
118
+ file.puts %{CMD [ "bundle", "exec", "#{cmd}" ]}
119
+ end
120
+ end
121
+
122
+ out.puts "Building images"
123
+ docker_quiet_option = if global_options.log_level != "debug"
124
+ "--quiet"
125
+ else
126
+ ""
127
+ end
128
+ images.each do |name,metadata|
129
+ image_name = metadata.fetch(:image_name)
130
+ dockerfile = metadata.fetch(:dockerfile)
131
+
132
+
133
+ out.puts "Creating docker image with name '#{image_name}' and platform '#{platform}'"
134
+ command = %{docker build #{docker_quiet_option} --build-arg app_git_sha1=#{version} --file #{Brut.container.project_root}/#{dockerfile} --platform #{platform} --tag #{image_name} .}
135
+ system!(command)
136
+ end
137
+
138
+ out.puts "Taggging images for Heroku"
139
+ images.each do |name,metadata|
140
+ image_name = metadata.fetch(:image_name)
141
+ heroku_image_name = metadata.fetch(:heroku_image_name)
142
+
143
+ out.puts "Tagging '#{image_name}' with '#{heroku_image_name}' for Heroku"
144
+ command = %{docker tag #{image_name} #{heroku_image_name}}
145
+ system!(command)
146
+ end
147
+
148
+ if options.push?
149
+ out.puts "Pushing to Heroku Registry"
150
+ images.each do |name,metadata|
151
+ heroku_image_name = metadata.fetch(:heroku_image_name)
152
+
153
+ out.puts "Pushing '#{heroku_image_name}'"
154
+
155
+ command = %{docker push #{docker_quiet_option} #{heroku_image_name}}
156
+ system!(command)
157
+ end
158
+ else
159
+ out.puts "Not pushing images"
160
+ end
161
+
162
+ names = images.map(&:first).join(" ")
163
+ deploy_command = "heroku container:release #{names}"
164
+ if options.deploy?
165
+ out.puts "Deploying images to Heroku"
166
+ system!(deploy_command)
167
+ else
168
+ out.puts "Not deploying. To deploy the images just pushed:"
169
+ out.puts ""
170
+ out.puts " #{deploy_command}"
171
+ end
172
+ end
173
+ end
174
+ private
175
+ def require_heroku_login!(options)
176
+ if system("heroku whoami")
177
+ out.puts "You are logged in to Heroku"
178
+ else
179
+ out.puts "You are not logged into Heroku."
180
+ out.puts "Please run the following:"
181
+ out.puts ""
182
+ out.puts "heroku auth:login"
183
+ out.puts "heroku container:login"
184
+ out.puts ""
185
+ out.puts "Then, re-run this"
186
+ if options.dry_run?
187
+ out.puts "Dry run - ignoring"
188
+ return
189
+ end
190
+ exit 1
191
+ end
192
+ end
193
+ end
194
+ end
@@ -198,6 +198,13 @@ class Brut::CLI::Command
198
198
  def before_execute
199
199
  end
200
200
 
201
+ # Called after all setup has been executed. Brut will have been started/loaded.
202
+ # This will *not* be called if anything caused execution to be aborted.
203
+ #
204
+ # @param [Brut::Framework::App] app Your Brut app.
205
+ def after_bootstrap(app:)
206
+ end
207
+
201
208
  # @!visibility private
202
209
  def set_env_if_needed
203
210
  if self.class.requires_project_env?
@@ -219,19 +226,6 @@ class Brut::CLI::Command
219
226
  raise ex
220
227
  end
221
228
 
222
- # @!visibility private
223
- def bootstrap!(project_root:, configure_only:)
224
- require "bundler"
225
- Bundler.require(:default, ENV["RACK_ENV"].to_sym)
226
- if configure_only
227
- require "#{project_root}/app/pre_boot"
228
- Brut::Framework.new(app: ::App.new)
229
- else
230
- require "#{project_root}/app/boot"
231
- end
232
- continue_execution
233
- end
234
-
235
229
  private
236
230
 
237
231
  # @!visibility public
@@ -16,14 +16,40 @@ class Brut::CLI::Executor
16
16
  @err = err
17
17
  end
18
18
 
19
- # Execute a command, logging it to the standard output and outputing the commands output and error to the standard output and error,
20
- # respecitively
19
+ # Execute a command, logging it to the standard output and outputing the
20
+ # commands output and error to the standard output and error, respectively. If
21
+ # the command exits nonzero, the exit status is returned.
22
+ #
23
+ # Generally, you want to use {#system!} for commands that must succeed
24
+ # for the caller to continue. Only use this method if you need
25
+ # to do special error-handling when the underlying command fails.
26
+ #
27
+ # @see https://docs.ruby-lang.org/en/3.3/Open3.html#method-c-popen3
28
+ # @see #system!
29
+ #
30
+ # @param [String|Array] args Whatever you would give to `Kernel#system` or `Open3.popen3`.
31
+ # @return [int] 0 if the command completed normally, otherwise the nonzero exit status. **DO NOT TREAT THIS AS A BOOLEAN VALUE**
32
+ def system(*args)
33
+ self.system!(*args)
34
+ 0
35
+ rescue Brut::CLI::SystemExecError => e
36
+ e.exit_status
37
+ end
38
+
39
+ # Execute a command, logging it to the standard output and outputing the
40
+ # commands output and error to the standard output and error, respectively. If
41
+ # the command exits nonzero, an exception is raised and your CLI app will
42
+ # also exit nonzero.
43
+ #
44
+ # If you need to handle the command exiting nonzero, use {#system}
45
+ # instead, as it will not raise an exception.
21
46
  #
22
47
  # @see https://docs.ruby-lang.org/en/3.3/Open3.html#method-c-popen3
48
+ # @see #system
23
49
  #
24
50
  # @param [String|Array] args Whatever you would give to `Kernel#system` or `Open3.popen3`.
25
- # @raise Brut::CLI::Error::SystemExecError if the spawed command exits nonzer
26
- # @return [true]
51
+ # @raise Brut::CLI::Error::SystemExecError if the spawed command exits nonzero
52
+ # @return [int] Always returns 0
27
53
  def system!(*args)
28
54
  @out.puts "Executing #{args}"
29
55
  wait_thread = Open3.popen3(*args) do |_stdin,stdout,stderr,wait_thread|
@@ -52,6 +78,6 @@ class Brut::CLI::Executor
52
78
  else
53
79
  raise Brut::CLI::SystemExecError.new(args,wait_thread.value.exitstatus)
54
80
  end
55
- true
81
+ 0
56
82
  end
57
83
  end
@@ -12,6 +12,10 @@ class Brut::CLI::Options
12
12
  # Access an options value directly.
13
13
  # @param [String] key the key to use. This must be the exact name you used when calling `opts.on` or when creating the `OptionParser` for your app or command. Generally, use the {#method_missing}-provided version instead of this.
14
14
  def [](key) = @parsed_options[key]
15
+
16
+ def []=(key,value)
17
+ @parsed_options[key] = value
18
+ end
15
19
  # Check if `key` was provided on the command line.
16
20
  # @param [String] key the key to use. This must be the exact name you used when calling `opts.on` or when creating the `OptionParser` for your app or command.
17
21
  def key?(key) = @parsed_options.key?(key)
data/lib/brut/cli.rb CHANGED
@@ -42,9 +42,10 @@ module Brut
42
42
  # Holds Brut-provided CLI apps that are set up in your project.
43
43
  module Apps
44
44
  autoload(:DB,"brut/cli/apps/db")
45
- autoload(:DB,"brut/cli/apps/test")
46
- autoload(:DB,"brut/cli/apps/build_assets")
47
- autoload(:DB,"brut/cli/apps/scaffold")
45
+ autoload(:Test,"brut/cli/apps/test")
46
+ autoload(:BuildAssets,"brut/cli/apps/build_assets")
47
+ autoload(:Scaffold,"brut/cli/apps/scaffold")
48
+ autoload(:DeployBase,"brut/cli/apps/deploy_base")
48
49
  end
49
50
  end
50
51
  end
@@ -78,7 +78,7 @@ class Brut::Framework::Container
78
78
  self.validate_name!(name:,type:,allow_app_override:)
79
79
  if value == :use_block
80
80
  derive_with = block
81
- @container[name] = { value: nil, derive_with: derive_with }
81
+ @container[name] = { derive_with: derive_with }
82
82
  else
83
83
  if type == :boolean
84
84
  value = !!value
@@ -111,9 +111,11 @@ class Brut::Framework::Container
111
111
  raise ArgumentError,"#{name} does not allow the app to override it"
112
112
  end
113
113
  if value == :use_block
114
- @container[name] = { value: nil, derive_with: block }
114
+ @container[name][:derive_with] = block
115
+ @container[name].delete(:value)
115
116
  else
116
- @container[name] = { value: value }
117
+ @container[name][:value] = value
118
+ @container[name].delete(:derive_with)
117
119
  end
118
120
  end
119
121
 
@@ -191,16 +193,16 @@ class Brut::Framework::Container
191
193
  # TODO: Provide a cleanr impl and better error checking if things go wrong
192
194
  x = @container.fetch(name)
193
195
 
194
- value = x[:value]
196
+ has_value = x.key?(:value)
195
197
 
196
- if !value.nil? || (x[:allow_nil] && value.nil?)
198
+ if has_value
197
199
  handle_path_values(name,x)
198
- return value
200
+ return x[:value]
199
201
  end
200
202
 
201
203
  deriver = x[:derive_with]
202
204
  if deriver.nil?
203
- raise "Something is seriously wrong. '#{name}' was stored in container without a derive_with value"
205
+ raise "Something is seriously wrong. '#{name}' was stored in container without a static value, but also without a derive_with key"
204
206
  end
205
207
 
206
208
  parameters = deriver.parameters(lambda: true)
@@ -218,6 +220,22 @@ class Brut::Framework::Container
218
220
  handle_path_values(name,x)
219
221
  x[:value]
220
222
  end
223
+
224
+ def reload
225
+ @container.each do |name, contained_value|
226
+ if contained_value.key?(:value) && contained_value[:type].to_s == "Class"
227
+ if contained_value.key?(:derive_with)
228
+ contained_value.delete(:value)
229
+ else
230
+ klass = contained_value[:value]
231
+ new_klass = klass.name.split(/::/).reduce(Module) { |mod,part|
232
+ mod.const_get(part)
233
+ }
234
+ contained_value[:value] = new_klass
235
+ end
236
+ end
237
+ end
238
+ end
221
239
  private
222
240
 
223
241
  def handle_path_values(name,contained_value)
@@ -2,4 +2,11 @@
2
2
  # which methods a subclass is expected to override and for which no default behavior
3
3
  # makes sense.
4
4
  class Brut::Framework::Errors::AbstractMethod < Brut::Framework::Error
5
+ def initialize(method_name=nil)
6
+ if method_name
7
+ super("The method `#{method_name}` must be implemented")
8
+ else
9
+ super("An abstract method must be implemented")
10
+ end
11
+ end
5
12
  end
@@ -27,9 +27,11 @@ module Brut
27
27
  # a method that a subclass must implement, but for which there is no useful default
28
28
  # implementation.
29
29
  #
30
+ # @param [String|Symbol] method_name name of the method that must be implemented. If omitted, the value is guessed from `caller_locations`
30
31
  # @raise [Brut::Framework::Errors::AbstractMethod]
31
- def abstract_method!
32
- raise Brut::Framework::Errors::AbstractMethod
32
+ def abstract_method!(method_name=nil)
33
+ method_name ||= caller_locations(1,1)[0].label
34
+ raise Brut::Framework::Errors::AbstractMethod.new(method_name)
33
35
  end
34
36
  end
35
37
  # Base class for errors thrown by Brut classes. Generally, Brut will not create its own version
@@ -28,6 +28,8 @@ class Brut::FrontEnd::Middlewares::ReloadApp < Brut::FrontEnd::Middleware
28
28
  span.add_event("Routing reloaded")
29
29
  Brut.container.asset_path_resolver.reload
30
30
  span.add_event("Asset Path Resolver reloaded")
31
+ Brut.container.reload
32
+ span.add_event("Brut.container reloaded")
31
33
  ::I18n.reload!
32
34
  span.add_event("I18n reloaded")
33
35
  rescue => ex
@@ -43,8 +43,16 @@ class Brut::SpecSupport::RSpecSetup
43
43
  # Create the setup with the given RSpec configuration.
44
44
  #
45
45
  # @param [RSpec::Core::Configuration] rspec_config yielded from `RSpec.configure`
46
- def initialize(rspec_config:)
47
- @config = rspec_config
46
+ # @param [boolean] monkey_patch_summary_notification if true (the default),
47
+ # 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
49
+ # re-run a test. But, it's still monkey-patching.
50
+ def initialize(rspec_config:,
51
+ monkey_patch_summary_notification: true)
52
+
53
+ @config = rspec_config
54
+ @monkey_patch_summary_notification = monkey_patch_summary_notification
55
+
48
56
  SemanticLogger.default_level = ENV.fetch("LOGGER_LEVEL_FOR_TESTS","warn")
49
57
  end
50
58
 
@@ -155,6 +163,9 @@ class Brut::SpecSupport::RSpecSetup
155
163
  @config.after(:suite) do
156
164
  Brut::SpecSupport::E2ETestServer.instance.stop
157
165
  end
166
+ if @monkey_patch_summary_notification
167
+ monkey_patch_summary_notification!
168
+ end
158
169
  end
159
170
 
160
171
  class OptionalSidekiqSupport
@@ -181,4 +192,33 @@ class Brut::SpecSupport::RSpecSetup
181
192
  end
182
193
  end
183
194
 
195
+ private
196
+
197
+ def monkey_patch_summary_notification!
198
+ require "rspec/core/notifications"
199
+ klass = RSpec::Core::Notifications::SummaryNotification
200
+ if !klass.instance_variable_get("@_brut_has_monkeypatched")
201
+ klass.class_eval do
202
+ # Slightly reformatted, but the only line that's different
203
+ # is the one that said to use './rspec'. Now it says 'bin/test run'
204
+ def colorized_rerun_commands(colorizer=::RSpec::Core::Formatters::ConsoleCodes)
205
+ "\nFailed examples:\n\n" +
206
+ failed_examples.map do |example|
207
+ rerun_argument = rerun_argument_for(example)
208
+ colorizer.wrap(
209
+ "bin/test run #{rerun_argument}", # <--- this is the only difference
210
+ RSpec.configuration.failure_color
211
+ ) +
212
+ " " +
213
+ colorizer.wrap(
214
+ "# #{example.full_description}",
215
+ RSpec.configuration.detail_color
216
+ )
217
+ end.join("\n")
218
+ end
219
+ end
220
+ klass.instance_variable_set("@_brut_has_monkeypatched",true)
221
+ end
222
+ end
184
223
  end
224
+
data/lib/brut/version.rb CHANGED
@@ -1,4 +1,4 @@
1
1
  module Brut
2
2
  # @!visibility private
3
- VERSION = "0.0.27"
3
+ VERSION = "0.0.28"
4
4
  end
@@ -1,6 +1,10 @@
1
1
  module Sequel
2
2
  module Extensions
3
3
  # Instruments all SQL executions.
4
+ #
5
+ # *NOTE* this will include the actual SQL query text in the
6
+ # span, so any literal values in the query will be in the observability
7
+ # platforms.
4
8
  module BrutInstrumentation
5
9
  # @!visibility private
6
10
  def log_connection_yield(sql,conn,args=nil)
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: brut
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.27
4
+ version: 0.0.28
5
5
  platform: ruby
6
6
  authors:
7
7
  - David Bryant Copeland
@@ -614,6 +614,7 @@ files:
614
614
  - brutrb.com/javascript.md
615
615
  - brutrb.com/jobs.md
616
616
  - brutrb.com/keyword-injection.md
617
+ - brutrb.com/layouts.md
617
618
  - brutrb.com/lsp.md
618
619
  - brutrb.com/markdown-examples.md
619
620
  - brutrb.com/middleware.md
@@ -662,6 +663,10 @@ files:
662
663
  - docs/api/Brut/CLI/Apps/DB/Rebuild.html
663
664
  - docs/api/Brut/CLI/Apps/DB/Seed.html
664
665
  - docs/api/Brut/CLI/Apps/DB/Status.html
666
+ - docs/api/Brut/CLI/Apps/DeployBase.html
667
+ - docs/api/Brut/CLI/Apps/DeployBase/GitChecks.html
668
+ - docs/api/Brut/CLI/Apps/HerokuContainerBasedDeploy.html
669
+ - docs/api/Brut/CLI/Apps/HerokuContainerBasedDeploy/Deploy.html
665
670
  - docs/api/Brut/CLI/Apps/Scaffold.html
666
671
  - docs/api/Brut/CLI/Apps/Scaffold/Action.html
667
672
  - docs/api/Brut/CLI/Apps/Scaffold/Action/Route.html
@@ -803,8 +808,17 @@ files:
803
808
  - docs/api/Brut/SpecSupport/GeneralSupport/ClassMethods.html
804
809
  - docs/api/Brut/SpecSupport/HandlerSupport.html
805
810
  - docs/api/Brut/SpecSupport/Matchers.html
811
+ - docs/api/Brut/SpecSupport/Matchers/BeABug.html
812
+ - docs/api/Brut/SpecSupport/Matchers/BePageFor.html
813
+ - docs/api/Brut/SpecSupport/Matchers/BeRoutingFor.html
806
814
  - docs/api/Brut/SpecSupport/Matchers/HaveConstraintViolation.html
815
+ - docs/api/Brut/SpecSupport/Matchers/HaveGenerated.html
807
816
  - docs/api/Brut/SpecSupport/Matchers/HaveHTMLAttribute.html
817
+ - docs/api/Brut/SpecSupport/Matchers/HaveI18nString.html
818
+ - docs/api/Brut/SpecSupport/Matchers/HaveLinkTo.html
819
+ - docs/api/Brut/SpecSupport/Matchers/HaveRedirectedTo.html
820
+ - docs/api/Brut/SpecSupport/Matchers/HaveReturnedHttpStatus.html
821
+ - docs/api/Brut/SpecSupport/Matchers/HaveReturnedRackResponse.html
808
822
  - docs/api/Brut/SpecSupport/RSpecSetup.html
809
823
  - docs/api/Brut/SpecSupport/RSpecSetup/OptionalSidekiqSupport.html
810
824
  - docs/api/Brut/SpecSupport/SessionSupport.html
@@ -823,6 +837,7 @@ files:
823
837
  - docs/api/Sequel/Plugins/ExternalId/InstanceMethods.html
824
838
  - docs/api/Sequel/Plugins/FindBang.html
825
839
  - docs/api/Sequel/Plugins/FindBang/ClassMethods.html
840
+ - docs/api/SpecSupport/Matchers/BeABug.html
826
841
  - docs/api/_index.html
827
842
  - docs/api/class_list.html
828
843
  - docs/api/css/common.css
@@ -838,25 +853,25 @@ files:
838
853
  - docs/api/method_list.html
839
854
  - docs/api/top-level-namespace.html
840
855
  - docs/assets.html
841
- - docs/assets/ai.md.tZrjP9im.js
842
- - docs/assets/ai.md.tZrjP9im.lean.js
843
- - docs/assets/app.D_yaTITQ.js
856
+ - docs/assets/ai.md._6HCDL6d.js
857
+ - docs/assets/ai.md._6HCDL6d.lean.js
858
+ - docs/assets/app.BX81XO4N.js
844
859
  - docs/assets/assets.md.D3wunzLx.js
845
860
  - docs/assets/assets.md.D3wunzLx.lean.js
846
861
  - docs/assets/brut-js.md.o2DAO2s2.js
847
862
  - docs/assets/brut-js.md.o2DAO2s2.lean.js
848
863
  - docs/assets/business-logic.md.BY4hGy0m.js
849
864
  - docs/assets/business-logic.md.BY4hGy0m.lean.js
850
- - docs/assets/chunks/@localSearchIndexroot.BsN5i0Fi.js
851
- - docs/assets/chunks/VPLocalSearchBox.B2-ZzyTY.js
865
+ - docs/assets/chunks/@localSearchIndexroot.CoYzciVi.js
866
+ - docs/assets/chunks/VPLocalSearchBox.gABXcTWp.js
852
867
  - docs/assets/chunks/framework.1L-BeKqY.js
853
- - docs/assets/chunks/theme.CfGFVRvE.js
868
+ - docs/assets/chunks/theme.DwUXXAL3.js
854
869
  - docs/assets/cli.md.RmeA2b0i.js
855
870
  - docs/assets/cli.md.RmeA2b0i.lean.js
856
- - docs/assets/components.md.eCttGlN-.js
857
- - docs/assets/components.md.eCttGlN-.lean.js
858
- - docs/assets/configuration.md.BRriU0cL.js
859
- - docs/assets/configuration.md.BRriU0cL.lean.js
871
+ - docs/assets/components.md.CRUMdRoN.js
872
+ - docs/assets/components.md.CRUMdRoN.lean.js
873
+ - docs/assets/configuration.md.BGHl8oRC.js
874
+ - docs/assets/configuration.md.BGHl8oRC.lean.js
860
875
  - docs/assets/css.md.DJgj2clw.js
861
876
  - docs/assets/css.md.DJgj2clw.lean.js
862
877
  - docs/assets/custom-element-tests.md.BrYJQEl3.js
@@ -869,18 +884,18 @@ files:
869
884
  - docs/assets/deployment.md.Dbka4OTr.lean.js
870
885
  - docs/assets/dev-env-overview.Gj7NWM8-.png
871
886
  - docs/assets/dev-env-protocol.DysDAtnz.png
872
- - docs/assets/dev-environment.md.BNc8AYiK.js
873
- - docs/assets/dev-environment.md.BNc8AYiK.lean.js
874
- - docs/assets/doc-conventions.md.DCfRXXi-.js
875
- - docs/assets/doc-conventions.md.DCfRXXi-.lean.js
887
+ - docs/assets/dev-environment.md.GZv6xvi9.js
888
+ - docs/assets/dev-environment.md.GZv6xvi9.lean.js
889
+ - docs/assets/doc-conventions.md.-kN3Xo5C.js
890
+ - docs/assets/doc-conventions.md.-kN3Xo5C.lean.js
876
891
  - docs/assets/end-to-end-tests.md.yfQHC0b5.js
877
892
  - docs/assets/end-to-end-tests.md.yfQHC0b5.lean.js
878
893
  - docs/assets/flash-and-session.md.BXY8RvT0.js
879
894
  - docs/assets/flash-and-session.md.BXY8RvT0.lean.js
880
- - docs/assets/forms.md.CBTYQ_Cz.js
881
- - docs/assets/forms.md.CBTYQ_Cz.lean.js
882
- - docs/assets/getting-started.md.Bz2s1Vjb.js
883
- - docs/assets/getting-started.md.Bz2s1Vjb.lean.js
895
+ - docs/assets/forms.md.B-koVgyw.js
896
+ - docs/assets/forms.md.B-koVgyw.lean.js
897
+ - docs/assets/getting-started.md.Ciz82L0m.js
898
+ - docs/assets/getting-started.md.Ciz82L0m.lean.js
884
899
  - docs/assets/handlers.md.089DVD3v.js
885
900
  - docs/assets/handlers.md.089DVD3v.lean.js
886
901
  - docs/assets/hooks.md.C4-moMny.js
@@ -889,14 +904,18 @@ files:
889
904
  - docs/assets/i18n.md.Do9i1qWl.lean.js
890
905
  - docs/assets/index.md.B28EwVpq.js
891
906
  - docs/assets/index.md.B28EwVpq.lean.js
892
- - docs/assets/instrumentation.md.CL6ax7nT.js
893
- - docs/assets/instrumentation.md.CL6ax7nT.lean.js
907
+ - docs/assets/instrumentation.md.a9Pjps4P.js
908
+ - docs/assets/instrumentation.md.a9Pjps4P.lean.js
894
909
  - docs/assets/javascript.md.GWbhRS51.js
895
910
  - docs/assets/javascript.md.GWbhRS51.lean.js
896
911
  - docs/assets/jobs.md.S-2amAYp.js
897
912
  - docs/assets/jobs.md.S-2amAYp.lean.js
898
913
  - docs/assets/keyword-injection.md.Dt2tKREs.js
899
914
  - docs/assets/keyword-injection.md.Dt2tKREs.lean.js
915
+ - docs/assets/layouts.md.cPnh3NId.js
916
+ - docs/assets/layouts.md.cPnh3NId.lean.js
917
+ - docs/assets/lsp.md.Bsu-f6VU.js
918
+ - docs/assets/lsp.md.Bsu-f6VU.lean.js
900
919
  - docs/assets/markdown-examples.md.CCFEQO44.js
901
920
  - docs/assets/markdown-examples.md.CCFEQO44.lean.js
902
921
  - docs/assets/middleware.md.Czz_UlJN.js
@@ -904,10 +923,12 @@ files:
904
923
  - docs/assets/not-released.md.BBy28McC.js
905
924
  - docs/assets/not-released.md.BBy28McC.lean.js
906
925
  - docs/assets/overview.Da81cB9R.png
907
- - docs/assets/overview.md.CDalkuxV.js
908
- - docs/assets/overview.md.CDalkuxV.lean.js
926
+ - docs/assets/overview.md.C5wlBcR5.js
927
+ - docs/assets/overview.md.C5wlBcR5.lean.js
909
928
  - docs/assets/pages.md.BE3kfOc5.js
910
929
  - docs/assets/pages.md.BE3kfOc5.lean.js
930
+ - docs/assets/recipes_authentication.md.CAsXf7hk.js
931
+ - docs/assets/recipes_authentication.md.CAsXf7hk.lean.js
911
932
  - docs/assets/routes.md.BMM7peut.js
912
933
  - docs/assets/routes.md.BMM7peut.lean.js
913
934
  - docs/assets/security.md.C668yXCi.js
@@ -1040,11 +1061,14 @@ files:
1040
1061
  - docs/javascript.html
1041
1062
  - docs/jobs.html
1042
1063
  - docs/keyword-injection.html
1064
+ - docs/layouts.html
1065
+ - docs/lsp.html
1043
1066
  - docs/markdown-examples.html
1044
1067
  - docs/middleware.html
1045
1068
  - docs/not-released.html
1046
1069
  - docs/overview.html
1047
1070
  - docs/pages.html
1071
+ - docs/recipes/authentication.html
1048
1072
  - docs/routes.html
1049
1073
  - docs/security.html
1050
1074
  - docs/seed-data.html
@@ -1075,6 +1099,8 @@ files:
1075
1099
  - lib/brut/cli/app_runner.rb
1076
1100
  - lib/brut/cli/apps/build_assets.rb
1077
1101
  - lib/brut/cli/apps/db.rb
1102
+ - lib/brut/cli/apps/deploy_base.rb
1103
+ - lib/brut/cli/apps/heroku_container_based_deploy.rb
1078
1104
  - lib/brut/cli/apps/scaffold.rb
1079
1105
  - lib/brut/cli/apps/test.rb
1080
1106
  - lib/brut/cli/command.rb
@@ -1 +0,0 @@
1
- import{_ as t,c as o,o as a,ag as s}from"./chunks/framework.1L-BeKqY.js";const b=JSON.parse('{"title":"AI Declaration and Notes","description":"","frontmatter":{},"headers":[],"relativePath":"ai.md","filePath":"ai.md"}'),r={name:"ai.md"};function n(i,e,l,d,h,u){return a(),o("div",null,e[0]||(e[0]=[s("",26)]))}const p=t(r,[["render",n]]);export{b as __pageData,p as default};