brut 0.8.0 → 0.9.1

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 (420) hide show
  1. checksums.yaml +4 -4
  2. data/.gitignore +9 -0
  3. data/CHANGELOG.md +13 -0
  4. data/Dockerfile.dx +8 -1
  5. data/Gemfile.lock +101 -63
  6. data/bin/ci +9 -5
  7. data/bin/docs +1 -1
  8. data/bin/generate-and-run-rubocop +52 -0
  9. data/bin/rubocop +27 -0
  10. data/bin/setup +46 -0
  11. data/bin/test +18 -0
  12. data/brut-css/bin/publish +1 -1
  13. data/brut-css/package-lock.json +2 -2
  14. data/brut-css/package.json +1 -1
  15. data/brut-js/bin/publish +1 -1
  16. data/brut-js/package-lock.json +2 -2
  17. data/brut-js/package.json +1 -1
  18. data/brut-js/specs/ConfirmSubmit.spec.js +32 -1
  19. data/brut-js/src/ConfirmSubmit.js +28 -7
  20. data/brut.gemspec +32 -26
  21. data/brutrb.com/.vitepress/config.mjs +3 -0
  22. data/brutrb.com/database-schema.md +1 -1
  23. data/brutrb.com/images/tutorial/basic-form-with-violations.png +0 -0
  24. data/brutrb.com/images/tutorial/basic-form.png +0 -0
  25. data/brutrb.com/images/tutorial/initial-home-page.png +0 -0
  26. data/brutrb.com/images/tutorial/new-post-editor.png +0 -0
  27. data/brutrb.com/images/tutorial/new-post-home-page.png +0 -0
  28. data/brutrb.com/images/tutorial/styled-form-with-server-side-violations.png +0 -0
  29. data/brutrb.com/images/tutorial/styled-form-with-violations.png +0 -0
  30. data/brutrb.com/images/tutorial/styled-home-page-with-posts.png +0 -0
  31. data/brutrb.com/images/tutorial/styled-home-page.png +0 -0
  32. data/brutrb.com/images/tutorial/welcome-to-brut.png +0 -0
  33. data/brutrb.com/recipes/migrations.md +1 -1
  34. data/brutrb.com/tutorial.md +1728 -3
  35. data/docker-compose.dx.yml +3 -0
  36. data/docs/404.html +2 -2
  37. data/docs/adrs.html +3 -3
  38. data/docs/ai.html +3 -3
  39. data/docs/api/Brut/BackEnd/SeedData.html +2 -2
  40. data/docs/api/Brut/BackEnd/Sidekiq/Middlewares/Server/FlushSpans.html +2 -2
  41. data/docs/api/Brut/BackEnd/Sidekiq/Middlewares/Server.html +2 -2
  42. data/docs/api/Brut/BackEnd/Sidekiq/Middlewares.html +2 -2
  43. data/docs/api/Brut/BackEnd/Sidekiq.html +2 -2
  44. data/docs/api/Brut/BackEnd/Validators/FormValidator.html +2 -2
  45. data/docs/api/Brut/BackEnd/Validators.html +2 -2
  46. data/docs/api/Brut/BackEnd.html +2 -2
  47. data/docs/api/Brut/CLI/App.html +2 -2
  48. data/docs/api/Brut/CLI/AppRunner.html +2 -2
  49. data/docs/api/Brut/CLI/Apps/BuildAssets/All.html +2 -2
  50. data/docs/api/Brut/CLI/Apps/BuildAssets/CSS.html +2 -2
  51. data/docs/api/Brut/CLI/Apps/BuildAssets/Images.html +2 -2
  52. data/docs/api/Brut/CLI/Apps/BuildAssets/JS.html +2 -2
  53. data/docs/api/Brut/CLI/Apps/BuildAssets.html +2 -2
  54. data/docs/api/Brut/CLI/Apps/DB/Create.html +2 -2
  55. data/docs/api/Brut/CLI/Apps/DB/Drop.html +2 -2
  56. data/docs/api/Brut/CLI/Apps/DB/Migrate.html +2 -2
  57. data/docs/api/Brut/CLI/Apps/DB/NewMigration.html +2 -2
  58. data/docs/api/Brut/CLI/Apps/DB/Rebuild.html +2 -2
  59. data/docs/api/Brut/CLI/Apps/DB/Seed.html +2 -2
  60. data/docs/api/Brut/CLI/Apps/DB/Status.html +2 -2
  61. data/docs/api/Brut/CLI/Apps/DB.html +2 -2
  62. data/docs/api/Brut/CLI/Apps/DeployBase/GitChecks.html +2 -2
  63. data/docs/api/Brut/CLI/Apps/DeployBase.html +2 -2
  64. data/docs/api/Brut/CLI/Apps/HerokuContainerBasedDeploy/Deploy.html +3 -3
  65. data/docs/api/Brut/CLI/Apps/HerokuContainerBasedDeploy.html +2 -2
  66. data/docs/api/Brut/CLI/Apps/Scaffold/Action/Route.html +2 -2
  67. data/docs/api/Brut/CLI/Apps/Scaffold/Action.html +2 -2
  68. data/docs/api/Brut/CLI/Apps/Scaffold/Component.html +2 -2
  69. data/docs/api/Brut/CLI/Apps/Scaffold/CustomElementTest.html +2 -2
  70. data/docs/api/Brut/CLI/Apps/Scaffold/DbModel.html +2 -2
  71. data/docs/api/Brut/CLI/Apps/Scaffold/E2ETest.html +2 -2
  72. data/docs/api/Brut/CLI/Apps/Scaffold/Form.html +2 -2
  73. data/docs/api/Brut/CLI/Apps/Scaffold/Page/Route.html +2 -2
  74. data/docs/api/Brut/CLI/Apps/Scaffold/Page.html +2 -2
  75. data/docs/api/Brut/CLI/Apps/Scaffold/RoutesEditor.html +2 -2
  76. data/docs/api/Brut/CLI/Apps/Scaffold/Test.html +3 -3
  77. data/docs/api/Brut/CLI/Apps/Scaffold.html +2 -2
  78. data/docs/api/Brut/CLI/Apps/Test/Audit.html +2 -2
  79. data/docs/api/Brut/CLI/Apps/Test/E2e.html +2 -2
  80. data/docs/api/Brut/CLI/Apps/Test/JS.html +2 -2
  81. data/docs/api/Brut/CLI/Apps/Test/Run.html +2 -2
  82. data/docs/api/Brut/CLI/Apps/Test.html +2 -2
  83. data/docs/api/Brut/CLI/Apps.html +2 -2
  84. data/docs/api/Brut/CLI/Command.html +2 -2
  85. data/docs/api/Brut/CLI/Error.html +2 -2
  86. data/docs/api/Brut/CLI/ExecutionResults/Result.html +2 -2
  87. data/docs/api/Brut/CLI/ExecutionResults.html +2 -2
  88. data/docs/api/Brut/CLI/Executor.html +2 -2
  89. data/docs/api/Brut/CLI/InvalidOption.html +2 -2
  90. data/docs/api/Brut/CLI/Options.html +80 -2
  91. data/docs/api/Brut/CLI/Output.html +2 -2
  92. data/docs/api/Brut/CLI/SystemExecError.html +2 -2
  93. data/docs/api/Brut/CLI.html +2 -2
  94. data/docs/api/Brut/FactoryBot.html +3 -3
  95. data/docs/api/Brut/Framework/App.html +3 -3
  96. data/docs/api/Brut/Framework/Config.html +27 -15
  97. data/docs/api/Brut/Framework/Container.html +2 -2
  98. data/docs/api/Brut/Framework/Error.html +2 -2
  99. data/docs/api/Brut/Framework/Errors/AbstractMethod.html +2 -2
  100. data/docs/api/Brut/Framework/Errors/Bug.html +2 -2
  101. data/docs/api/Brut/Framework/Errors/MissingConfiguration.html +2 -2
  102. data/docs/api/Brut/Framework/Errors/MissingParameter.html +2 -2
  103. data/docs/api/Brut/Framework/Errors/NoClassForPath.html +2 -2
  104. data/docs/api/Brut/Framework/Errors/NotFound.html +2 -2
  105. data/docs/api/Brut/Framework/Errors/NotImplemented.html +2 -2
  106. data/docs/api/Brut/Framework/Errors.html +2 -2
  107. data/docs/api/Brut/Framework/FussyTypeEnforcement.html +2 -2
  108. data/docs/api/Brut/Framework/MCP.html +21 -11
  109. data/docs/api/Brut/Framework/ProjectEnvironment.html +2 -2
  110. data/docs/api/Brut/Framework.html +2 -2
  111. data/docs/api/Brut/FrontEnd/AssetPathResolver.html +2 -2
  112. data/docs/api/Brut/FrontEnd/Component/Helpers.html +2 -2
  113. data/docs/api/Brut/FrontEnd/Component.html +2 -2
  114. data/docs/api/Brut/FrontEnd/Components/ConstraintViolations.html +2 -2
  115. data/docs/api/Brut/FrontEnd/Components/FormTag.html +4 -4
  116. data/docs/api/Brut/FrontEnd/Components/I18nTranslations.html +2 -2
  117. data/docs/api/Brut/FrontEnd/Components/Input.html +2 -2
  118. data/docs/api/Brut/FrontEnd/Components/Inputs/CsrfToken.html +2 -2
  119. data/docs/api/Brut/FrontEnd/Components/Inputs/InputTag.html +2 -2
  120. data/docs/api/Brut/FrontEnd/Components/Inputs/RadioButton.html +2 -2
  121. data/docs/api/Brut/FrontEnd/Components/Inputs/SelectTagWithOptions.html +2 -2
  122. data/docs/api/Brut/FrontEnd/Components/Inputs/TextareaTag.html +2 -2
  123. data/docs/api/Brut/FrontEnd/Components/Inputs.html +2 -2
  124. data/docs/api/Brut/FrontEnd/Components/LocaleDetection.html +2 -2
  125. data/docs/api/Brut/FrontEnd/Components/PageIdentifier.html +2 -2
  126. data/docs/api/Brut/FrontEnd/Components/TimeTag.html +2 -2
  127. data/docs/api/Brut/FrontEnd/Components/Traceparent.html +2 -2
  128. data/docs/api/Brut/FrontEnd/Components.html +2 -2
  129. data/docs/api/Brut/FrontEnd/CsrfProtector.html +250 -0
  130. data/docs/api/Brut/FrontEnd/Download.html +2 -2
  131. data/docs/api/Brut/FrontEnd/Flash.html +2 -2
  132. data/docs/api/Brut/FrontEnd/Form.html +6 -6
  133. data/docs/api/Brut/FrontEnd/Forms/ConstraintViolation.html +2 -2
  134. data/docs/api/Brut/FrontEnd/Forms/Input/Color.html +2 -2
  135. data/docs/api/Brut/FrontEnd/Forms/Input/TimeOfDay.html +2 -2
  136. data/docs/api/Brut/FrontEnd/Forms/Input.html +2 -2
  137. data/docs/api/Brut/FrontEnd/Forms/InputDeclarations.html +2 -2
  138. data/docs/api/Brut/FrontEnd/Forms/InputDefinition.html +2 -2
  139. data/docs/api/Brut/FrontEnd/Forms/RadioButtonGroupInput.html +2 -2
  140. data/docs/api/Brut/FrontEnd/Forms/RadioButtonGroupInputDefinition.html +2 -2
  141. data/docs/api/Brut/FrontEnd/Forms/SelectInput.html +2 -2
  142. data/docs/api/Brut/FrontEnd/Forms/SelectInputDefinition.html +2 -2
  143. data/docs/api/Brut/FrontEnd/Forms/ValidityState.html +2 -2
  144. data/docs/api/Brut/FrontEnd/Forms.html +2 -2
  145. data/docs/api/Brut/FrontEnd/GenericResponse.html +2 -2
  146. data/docs/api/Brut/FrontEnd/Handler.html +2 -2
  147. data/docs/api/Brut/FrontEnd/Handlers/CspReportingHandler.html +2 -2
  148. data/docs/api/Brut/FrontEnd/Handlers/InstrumentationHandler/TraceParent.html +2 -2
  149. data/docs/api/Brut/FrontEnd/Handlers/InstrumentationHandler.html +2 -2
  150. data/docs/api/Brut/FrontEnd/Handlers/LocaleDetectionHandler.html +2 -2
  151. data/docs/api/Brut/FrontEnd/Handlers/MissingHandler/Form.html +2 -2
  152. data/docs/api/Brut/FrontEnd/Handlers/MissingHandler.html +2 -2
  153. data/docs/api/Brut/FrontEnd/Handlers.html +2 -2
  154. data/docs/api/Brut/FrontEnd/HandlingResults.html +2 -2
  155. data/docs/api/Brut/FrontEnd/HttpMethod.html +2 -2
  156. data/docs/api/Brut/FrontEnd/HttpStatus.html +2 -2
  157. data/docs/api/Brut/FrontEnd/InlineSvgLocator.html +2 -2
  158. data/docs/api/Brut/FrontEnd/Layout.html +2 -2
  159. data/docs/api/Brut/FrontEnd/Middleware.html +2 -2
  160. data/docs/api/Brut/FrontEnd/Middlewares/AnnotateBrutOwnedPaths.html +2 -2
  161. data/docs/api/Brut/FrontEnd/Middlewares/Favicon.html +2 -2
  162. data/docs/api/Brut/FrontEnd/Middlewares/OpenTelemetrySpan.html +2 -2
  163. data/docs/api/Brut/FrontEnd/Middlewares/ReloadApp.html +2 -2
  164. data/docs/api/Brut/FrontEnd/Middlewares.html +2 -2
  165. data/docs/api/Brut/FrontEnd/Page.html +2 -2
  166. data/docs/api/Brut/FrontEnd/Pages/MissingPage.html +2 -2
  167. data/docs/api/Brut/FrontEnd/Pages.html +2 -2
  168. data/docs/api/Brut/FrontEnd/RequestContext.html +2 -2
  169. data/docs/api/Brut/FrontEnd/RouteHook.html +2 -2
  170. data/docs/api/Brut/FrontEnd/RouteHooks/AgeFlash.html +2 -2
  171. data/docs/api/Brut/FrontEnd/RouteHooks/CSPNoInlineScripts.html +2 -2
  172. data/docs/api/Brut/FrontEnd/RouteHooks/CSPNoInlineStylesOrScripts/ReportOnly.html +2 -2
  173. data/docs/api/Brut/FrontEnd/RouteHooks/CSPNoInlineStylesOrScripts.html +2 -2
  174. data/docs/api/Brut/FrontEnd/RouteHooks/LocaleDetection.html +2 -2
  175. data/docs/api/Brut/FrontEnd/RouteHooks/SetupRequestContext.html +2 -2
  176. data/docs/api/Brut/FrontEnd/RouteHooks.html +2 -2
  177. data/docs/api/Brut/FrontEnd/Routing/FormHandlerRoute.html +2 -2
  178. data/docs/api/Brut/FrontEnd/Routing/FormRoute.html +2 -2
  179. data/docs/api/Brut/FrontEnd/Routing/MissingForm.html +2 -2
  180. data/docs/api/Brut/FrontEnd/Routing/MissingHandler.html +2 -2
  181. data/docs/api/Brut/FrontEnd/Routing/MissingPage.html +2 -2
  182. data/docs/api/Brut/FrontEnd/Routing/MissingPath.html +2 -2
  183. data/docs/api/Brut/FrontEnd/Routing/PageRoute.html +2 -2
  184. data/docs/api/Brut/FrontEnd/Routing/Route.html +2 -2
  185. data/docs/api/Brut/FrontEnd/Routing.html +2 -2
  186. data/docs/api/Brut/FrontEnd/Session.html +2 -2
  187. data/docs/api/Brut/FrontEnd.html +3 -3
  188. data/docs/api/Brut/I18n/BaseMethods.html +3 -3
  189. data/docs/api/Brut/I18n/ForBackEnd.html +2 -2
  190. data/docs/api/Brut/I18n/ForCLI.html +2 -2
  191. data/docs/api/Brut/I18n/ForHTML.html +2 -2
  192. data/docs/api/Brut/I18n/HTTPAcceptLanguage/AlwaysEnglish.html +2 -2
  193. data/docs/api/Brut/I18n/HTTPAcceptLanguage.html +2 -2
  194. data/docs/api/Brut/I18n.html +2 -2
  195. data/docs/api/Brut/Instrumentation/LoggerSpanExporter.html +2 -2
  196. data/docs/api/Brut/Instrumentation/OpenTelemetry/NormalizedAttributes.html +2 -2
  197. data/docs/api/Brut/Instrumentation/OpenTelemetry/Span.html +2 -2
  198. data/docs/api/Brut/Instrumentation/OpenTelemetry.html +2 -2
  199. data/docs/api/Brut/Instrumentation.html +2 -2
  200. data/docs/api/Brut/RubocopConfig.html +237 -0
  201. data/docs/api/Brut/SinatraHelpers/ClassMethods.html +2 -2
  202. data/docs/api/Brut/SinatraHelpers.html +2 -2
  203. data/docs/api/Brut/SpecSupport/ClockSupport.html +2 -2
  204. data/docs/api/Brut/SpecSupport/ComponentSupport.html +7 -13
  205. data/docs/api/Brut/SpecSupport/E2ETestServer.html +2 -2
  206. data/docs/api/Brut/SpecSupport/E2eSupport.html +2 -2
  207. data/docs/api/Brut/SpecSupport/EnhancedNode.html +2 -2
  208. data/docs/api/Brut/SpecSupport/FlashSupport.html +2 -2
  209. data/docs/api/Brut/SpecSupport/GeneralSupport/ClassMethods.html +2 -2
  210. data/docs/api/Brut/SpecSupport/GeneralSupport.html +2 -2
  211. data/docs/api/Brut/SpecSupport/HandlerSupport.html +2 -2
  212. data/docs/api/Brut/SpecSupport/Matchers/BeABug.html +2 -2
  213. data/docs/api/Brut/SpecSupport/Matchers/BePageFor.html +2 -2
  214. data/docs/api/Brut/SpecSupport/Matchers/BeRoutingFor.html +2 -2
  215. data/docs/api/Brut/SpecSupport/Matchers/HaveConstraintViolation.html +2 -2
  216. data/docs/api/Brut/SpecSupport/Matchers/HaveGenerated.html +2 -2
  217. data/docs/api/Brut/SpecSupport/Matchers/HaveHTMLAttribute.html +2 -2
  218. data/docs/api/Brut/SpecSupport/Matchers/HaveI18nString.html +2 -2
  219. data/docs/api/Brut/SpecSupport/Matchers/HaveLinkTo.html +2 -2
  220. data/docs/api/Brut/SpecSupport/Matchers/HaveRedirectedTo.html +2 -2
  221. data/docs/api/Brut/SpecSupport/Matchers/HaveReturnedHttpStatus.html +2 -2
  222. data/docs/api/Brut/SpecSupport/Matchers/HaveReturnedRackResponse.html +2 -2
  223. data/docs/api/Brut/SpecSupport/Matchers.html +2 -2
  224. data/docs/api/Brut/SpecSupport/RSpecSetup/OptionalSidekiqSupport.html +2 -2
  225. data/docs/api/Brut/SpecSupport/RSpecSetup.html +4 -4
  226. data/docs/api/Brut/SpecSupport/SessionSupport.html +2 -2
  227. data/docs/api/Brut/SpecSupport.html +2 -2
  228. data/docs/api/Brut.html +128 -12
  229. data/docs/api/Clock.html +2 -2
  230. data/docs/api/ModuleName.html +28 -28
  231. data/docs/api/RichString.html +22 -22
  232. data/docs/api/SemanticLogger/Appender/Async.html +2 -2
  233. data/docs/api/Sequel/Extensions/BrutInstrumentation.html +2 -2
  234. data/docs/api/Sequel/Extensions/BrutMigrations.html +2 -2
  235. data/docs/api/Sequel/Extensions.html +2 -2
  236. data/docs/api/Sequel/Plugins/CreatedAt/InstanceMethods.html +2 -2
  237. data/docs/api/Sequel/Plugins/CreatedAt.html +2 -2
  238. data/docs/api/Sequel/Plugins/ExternalId/ClassMethods.html +2 -2
  239. data/docs/api/Sequel/Plugins/ExternalId/InstanceMethods.html +2 -2
  240. data/docs/api/Sequel/Plugins/ExternalId.html +2 -2
  241. data/docs/api/Sequel/Plugins/FindBang/ClassMethods.html +2 -2
  242. data/docs/api/Sequel/Plugins/FindBang.html +2 -2
  243. data/docs/api/Sequel/Plugins.html +2 -2
  244. data/docs/api/Sequel.html +2 -2
  245. data/docs/api/_index.html +16 -2
  246. data/docs/api/class_list.html +1 -1
  247. data/docs/api/file.README.html +28 -2
  248. data/docs/api/index.html +28 -2
  249. data/docs/api/method_list.html +192 -168
  250. data/docs/api/top-level-namespace.html +2 -2
  251. data/docs/assets/{app.DyQLb4Ot.js → app.BuBdZoUg.js} +1 -1
  252. data/docs/assets/basic-form-with-violations.Cv6Y9-Q_.png +0 -0
  253. data/docs/assets/basic-form.DbHnu0oW.png +0 -0
  254. data/docs/assets/chunks/@localSearchIndexroot.BZ_a3X0T.js +1 -0
  255. data/docs/assets/chunks/{VPLocalSearchBox.T1iA-eJx.js → VPLocalSearchBox.UtnyvkX-.js} +1 -1
  256. data/docs/assets/chunks/{theme.ChwsbWjK.js → theme.DqwvuBEK.js} +2 -2
  257. data/docs/assets/{components.md.DHh-NwKs.js → components.md.Bu80E2Nr.js} +3 -3
  258. data/docs/assets/{configuration.md.D8Wz3oJU.js → configuration.md.CuIxVsSf.js} +1 -1
  259. data/docs/assets/{database-schema.md.C5gXexJi.js → database-schema.md.LpmBPVEU.js} +1 -1
  260. data/docs/assets/{forms.md.BRE85eju.js → forms.md.DnLbzVDa.js} +1 -1
  261. data/docs/assets/{getting-started.md.2ioiTe-B.js → getting-started.md.DdQLmU3C.js} +2 -2
  262. data/docs/assets/initial-home-page.DNIaYmgP.png +0 -0
  263. data/docs/assets/new-post-editor.DrHr-5oh.png +0 -0
  264. data/docs/assets/new-post-home-page.Bm34lyMg.png +0 -0
  265. data/docs/assets/{recipes_migrations.md.DPN3gQE3.js → recipes_migrations.md.CTcnWDJF.js} +1 -1
  266. data/docs/assets/styled-form-with-server-side-violations.Bjxd8Dpv.png +0 -0
  267. data/docs/assets/styled-form-with-violations.Bv_sa9tg.png +0 -0
  268. data/docs/assets/styled-home-page-with-posts.Dd4kG89D.png +0 -0
  269. data/docs/assets/styled-home-page.BzdI7dWz.png +0 -0
  270. data/docs/assets/tutorial.md.C4zR5XPG.js +728 -0
  271. data/docs/assets/tutorial.md.C4zR5XPG.lean.js +1 -0
  272. data/docs/assets/welcome-to-brut.VSWzl17-.png +0 -0
  273. data/docs/assets.html +3 -3
  274. data/docs/brut-js/api/AjaxSubmit.html +1 -1
  275. data/docs/brut-js/api/AjaxSubmit.js.html +1 -1
  276. data/docs/brut-js/api/Autosubmit.html +1 -1
  277. data/docs/brut-js/api/Autosubmit.js.html +1 -1
  278. data/docs/brut-js/api/BaseCustomElement.html +1 -1
  279. data/docs/brut-js/api/BaseCustomElement.js.html +1 -1
  280. data/docs/brut-js/api/BrutCustomElements.html +1 -1
  281. data/docs/brut-js/api/BufferedLogger.html +1 -1
  282. data/docs/brut-js/api/ConfirmSubmit.html +18 -10
  283. data/docs/brut-js/api/ConfirmSubmit.js.html +29 -8
  284. data/docs/brut-js/api/ConfirmationDialog.html +1 -1
  285. data/docs/brut-js/api/ConfirmationDialog.js.html +1 -1
  286. data/docs/brut-js/api/ConstraintViolationMessage.html +1 -1
  287. data/docs/brut-js/api/ConstraintViolationMessage.js.html +1 -1
  288. data/docs/brut-js/api/ConstraintViolationMessages.html +1 -1
  289. data/docs/brut-js/api/ConstraintViolationMessages.js.html +1 -1
  290. data/docs/brut-js/api/CopyToClipboard.html +1 -1
  291. data/docs/brut-js/api/CopyToClipboard.js.html +1 -1
  292. data/docs/brut-js/api/Form.html +1 -1
  293. data/docs/brut-js/api/Form.js.html +1 -1
  294. data/docs/brut-js/api/I18nTranslation.html +1 -1
  295. data/docs/brut-js/api/I18nTranslation.js.html +1 -1
  296. data/docs/brut-js/api/LocaleDetection.html +1 -1
  297. data/docs/brut-js/api/LocaleDetection.js.html +1 -1
  298. data/docs/brut-js/api/Logger.html +1 -1
  299. data/docs/brut-js/api/Logger.js.html +1 -1
  300. data/docs/brut-js/api/Message.html +1 -1
  301. data/docs/brut-js/api/Message.js.html +1 -1
  302. data/docs/brut-js/api/PrefixedLogger.html +1 -1
  303. data/docs/brut-js/api/RichString.html +1 -1
  304. data/docs/brut-js/api/RichString.js.html +1 -1
  305. data/docs/brut-js/api/Tabs.html +1 -1
  306. data/docs/brut-js/api/Tabs.js.html +1 -1
  307. data/docs/brut-js/api/Tracing.html +1 -1
  308. data/docs/brut-js/api/Tracing.js.html +1 -1
  309. data/docs/brut-js/api/external-CustomElementRegistry.html +1 -1
  310. data/docs/brut-js/api/external-Performance.html +1 -1
  311. data/docs/brut-js/api/external-Promise.html +1 -1
  312. data/docs/brut-js/api/external-ValidityState.html +1 -1
  313. data/docs/brut-js/api/external-Window.html +1 -1
  314. data/docs/brut-js/api/external-fetch.html +1 -1
  315. data/docs/brut-js/api/global.html +1 -1
  316. data/docs/brut-js/api/index.html +1 -1
  317. data/docs/brut-js/api/index.js.html +1 -1
  318. data/docs/brut-js/api/module-testing.html +1 -1
  319. data/docs/brut-js/api/testing.AssetMetadata.html +1 -1
  320. data/docs/brut-js/api/testing.AssetMetadataLoader.html +1 -1
  321. data/docs/brut-js/api/testing.CustomElementTest.html +1 -1
  322. data/docs/brut-js/api/testing.DOMCreator.html +1 -1
  323. data/docs/brut-js/api/testing_AssetMetadata.js.html +1 -1
  324. data/docs/brut-js/api/testing_AssetMetadataLoader.js.html +1 -1
  325. data/docs/brut-js/api/testing_CustomElementTest.js.html +1 -1
  326. data/docs/brut-js/api/testing_DOMCreator.js.html +1 -1
  327. data/docs/brut-js/api/testing_index.js.html +1 -1
  328. data/docs/brut-js.html +3 -3
  329. data/docs/business-logic.html +3 -3
  330. data/docs/cli.html +3 -3
  331. data/docs/components.html +7 -7
  332. data/docs/configuration.html +5 -5
  333. data/docs/css.html +3 -3
  334. data/docs/custom-element-tests.html +3 -3
  335. data/docs/database-access.html +3 -3
  336. data/docs/database-schema.html +5 -5
  337. data/docs/deployment.html +3 -3
  338. data/docs/dev-environment.html +3 -3
  339. data/docs/dir-structure.html +3 -3
  340. data/docs/doc-conventions.html +3 -3
  341. data/docs/end-to-end-tests.html +3 -3
  342. data/docs/features.html +3 -3
  343. data/docs/flash-and-session.html +3 -3
  344. data/docs/form-constraints.html +3 -3
  345. data/docs/forms.html +5 -5
  346. data/docs/getting-started.html +6 -6
  347. data/docs/handlers.html +3 -3
  348. data/docs/hashmap.json +1 -1
  349. data/docs/hooks.html +3 -3
  350. data/docs/i18n.html +3 -3
  351. data/docs/index.html +3 -3
  352. data/docs/instrumentation.html +3 -3
  353. data/docs/javascript.html +3 -3
  354. data/docs/jobs.html +3 -3
  355. data/docs/keyword-injection.html +3 -3
  356. data/docs/layouts.html +3 -3
  357. data/docs/lsp.html +3 -3
  358. data/docs/markdown-examples.html +3 -3
  359. data/docs/middleware.html +3 -3
  360. data/docs/overview.html +3 -3
  361. data/docs/pages.html +3 -3
  362. data/docs/recipes/alternate-layouts.html +3 -3
  363. data/docs/recipes/authentication.html +3 -3
  364. data/docs/recipes/blank-layouts.html +3 -3
  365. data/docs/recipes/custom-flash.html +3 -3
  366. data/docs/recipes/indexed-forms.html +3 -3
  367. data/docs/recipes/migrations.html +5 -5
  368. data/docs/recipes/text-field-component.html +3 -3
  369. data/docs/roadmap.html +3 -3
  370. data/docs/routes.html +3 -3
  371. data/docs/security.html +3 -3
  372. data/docs/seed-data.html +3 -3
  373. data/docs/space-time-continuum.html +3 -3
  374. data/docs/tutorial.html +732 -5
  375. data/docs/unit-tests.html +3 -3
  376. data/docs/why.html +3 -3
  377. data/dx/build +45 -9
  378. data/lib/brut/cli/app.rb +1 -1
  379. data/lib/brut/cli/apps/heroku_container_based_deploy.rb +1 -1
  380. data/lib/brut/cli/apps/scaffold.rb +1 -1
  381. data/lib/brut/cli/options.rb +4 -0
  382. data/lib/brut/factory_bot.rb +1 -1
  383. data/lib/brut/framework/app.rb +1 -1
  384. data/lib/brut/framework/config.rb +18 -12
  385. data/lib/brut/framework/mcp.rb +12 -7
  386. data/lib/brut/front_end/csrf_protector.rb +30 -0
  387. data/lib/brut/front_end/form.rb +4 -4
  388. data/lib/brut/front_end/page.rb +1 -1
  389. data/lib/brut/front_end/routing.rb +1 -1
  390. data/lib/brut/front_end.rb +1 -0
  391. data/lib/brut/i18n/base_methods.rb +1 -1
  392. data/lib/brut/instrumentation/logger_span_exporter.rb +1 -1
  393. data/lib/brut/junk_drawer.rb +3 -1
  394. data/lib/brut/rubocop_config.rb +123 -0
  395. data/lib/brut/spec_support/component_support.rb +0 -3
  396. data/lib/brut/spec_support/rspec_setup.rb +2 -2
  397. data/lib/brut/version.rb +1 -1
  398. data/mkbrut/Gemfile.lock +1 -1
  399. data/mkbrut/dx +1 -0
  400. data/mkbrut/lib/mkbrut/app.rb +1 -1
  401. data/mkbrut/lib/mkbrut/cli.rb +1 -1
  402. data/mkbrut/lib/mkbrut/segments/heroku.rb +1 -1
  403. data/mkbrut/lib/mkbrut/version.rb +1 -1
  404. data/mkbrut/mkbrut.gemspec +3 -1
  405. data/mkbrut/templates/Base/app/config/i18n/en/1_defaults.rb +2 -2
  406. data/mkbrut/templates/Base/app/config/i18n/en/2_app.rb +1 -1
  407. data/mkbrut/templates/Base/bin/setup +1 -1
  408. data/mkbrut/templates/segments/Demo/app/src/front_end/components/flash_component.rb +1 -1
  409. data/specs/brut/junk_drawer.spec.rb +4 -0
  410. metadata +92 -35
  411. data/.rspec +0 -3
  412. data/docs/assets/chunks/@localSearchIndexroot.CmtZyrFA.js +0 -1
  413. data/docs/assets/tutorial.md.BIb7XT6j.js +0 -1
  414. data/docs/assets/tutorial.md.BIb7XT6j.lean.js +0 -1
  415. /data/docs/assets/{components.md.DHh-NwKs.lean.js → components.md.Bu80E2Nr.lean.js} +0 -0
  416. /data/docs/assets/{configuration.md.D8Wz3oJU.lean.js → configuration.md.CuIxVsSf.lean.js} +0 -0
  417. /data/docs/assets/{database-schema.md.C5gXexJi.lean.js → database-schema.md.LpmBPVEU.lean.js} +0 -0
  418. /data/docs/assets/{forms.md.BRE85eju.lean.js → forms.md.DnLbzVDa.lean.js} +0 -0
  419. /data/docs/assets/{getting-started.md.2ioiTe-B.lean.js → getting-started.md.DdQLmU3C.lean.js} +0 -0
  420. /data/docs/assets/{recipes_migrations.md.DPN3gQE3.lean.js → recipes_migrations.md.CTcnWDJF.lean.js} +0 -0
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: add23c2780a2ba1fe444b067c50d3451d9b28cd1bacbed9e1ab1693963bcbd03
4
- data.tar.gz: 4f44397c6688843f6d4c9f61121879fd711dfcec5b1b024f6a8be038cc84be54
3
+ metadata.gz: 4b580e8b69cc722fb2d84c090f7848b9c45623de2faaa996a14914d52773c48a
4
+ data.tar.gz: 37b84eb37ac974c48c054be0305086622fab712345d7ef581b7bd58f3ec7a79e
5
5
  SHA512:
6
- metadata.gz: 787f519b6c620c4586af3f53932fdbc6ded220766d36295ae9220d51d795a7c3498438cb6ad89051061731be95ab8c448d4d6c7519d97490e14ff433e954d747
7
- data.tar.gz: b76f693147690b5370f8db06747e6d73f3b9cffae625edaabdb0f3469806bbc2b2966d55aacc101c70e3e7c767690c4f1f8052a61677d90a26ec59753392fea8
6
+ metadata.gz: 43f5d19e8bb88c0e0956757b1826224f18f68eed46ef34d5a7e8df73b7a8638fb674f499c5e335edae84bd42fb2266fbb19ec347c7e14cbb18027c832e66f33b
7
+ data.tar.gz: 7b12806b7ce2164e6d1dd2eb85dc3d01902113fadb6762babcd265d8cca3659dc3bf2913db160c518c6ade57624d2e4558d779a62151807a6c0a9f7e4f2c72e9
data/.gitignore CHANGED
@@ -6,11 +6,17 @@
6
6
  # should never be checked in
7
7
  /dx/credentials
8
8
 
9
+ # This is per-developer configuration, generated by dx/build
10
+ /dx/build.args
11
+
9
12
  # Holds metadata during YARD builds. Don't need this checked in
10
13
  /.yardoc
11
14
  # Location of YARD templates, this is temporary
12
15
  /.yard
13
16
 
17
+ # This is generated, so no need to check in
18
+ /.rubocop.yml
19
+
14
20
  # This is where generated API docs go
15
21
  /brutrb.com/public/api
16
22
  /brutrb.com/public/brut-js/api
@@ -42,3 +48,6 @@
42
48
  # All I want in life is for every single instance of this file
43
49
  # to be placed in hell, and waiting for Alan Dye when he arrives.
44
50
  .DS_Store
51
+
52
+ # tmp is nice to have, but not nice to check in.
53
+ /tmp
data/CHANGELOG.md CHANGED
@@ -1,8 +1,21 @@
1
1
  # Brut CHANGELOG
2
2
 
3
+ ## v0.9.1 - Aug 12, 2025
4
+
5
+ * Changed `<brut-confirm-submit>` to not ask for confirmation if the form is invalid
6
+ * Changed default production loggin to STDOUT as this is more correct + it cannot be changed by apps
7
+ currently due to https://github.com/thirdtank/brut/issues/51
8
+
9
+ ## v0.9.0 - Aug 7, 2025
10
+
11
+ * Added `Brut::FrontEnd::CsrfProtector` and the `csrf_protector` configuration option to allow some customization
12
+ over how CSRF protection works app-wide, namely to allow a POST to a webhook to not have to have an authenticity token.
13
+ I don't super love this solution, but it's unblocking me for now.
14
+
3
15
  ## v0.8.0 - July 23, 2025
4
16
 
5
17
  * Moved `mkbrut` into this repo
18
+ * Fixed issue where generated `dx/build` script would mess up `build.args`. See https://github.com/thirdtank/brut/issues/45
6
19
  * Unify versioning for Brut, `mkbrut`, BrutJS, and BrutCSS
7
20
  * Unify all workspace workflow scripts (see README.md)
8
21
  * Minor doc updates to remove references to non-existent `form_tag`
data/Dockerfile.dx CHANGED
@@ -44,12 +44,19 @@ RUN apt-get install -y vim && \
44
44
  ARG user_uid=10001
45
45
  # Their group id, which ideally matches their group id on the host
46
46
  ARG user_gid=10002
47
+ # The group id that can access /var/run/docker.sock on the host.
48
+ # If this isn't mapped properly, no docker-out-of-docker commands will work
49
+ ARG docker_gid=10003
50
+ # Can be set to ',0' in order to add the user to roo's group
51
+ ARG sadly_user_must_be_added_to_root=
47
52
 
48
53
  # Create the user's group ID if it does not exist
49
54
  RUN getent group ${user_gid} || groupadd --gid ${user_gid} appgroup
55
+ # Create the docker group id if it does not exist
56
+ RUN getent group ${docker_gid} || groupadd --gid ${docker_gid} hostdocker
50
57
  # Create the user. Note that we put bash_customizations in both .profile and .bashrc
51
58
  # to increase the chances they are used when running bash in various configurations
52
- RUN useradd --uid ${user_uid} --gid ${user_gid} --create-home --home-dir /home/appuser appuser && \
59
+ RUN useradd --uid ${user_uid} --gid ${user_gid} --groups ${sadly_user_must_be_added_to_root}${docker_gid} --create-home --home-dir /home/appuser appuser && \
53
60
  echo ". ~/.bash_customizations" >> /home/appuser/.profile && \
54
61
  echo ". ~/.bash_customizations.local" >> /home/appuser/.profile && \
55
62
  echo ". ~/.bash_customizations" >> /home/appuser/.bashrc && \
data/Gemfile.lock CHANGED
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- brut (0.8.0)
4
+ brut (0.9.1)
5
5
  concurrent-ruby
6
6
  i18n
7
7
  irb
@@ -23,7 +23,7 @@ PATH
23
23
  GEM
24
24
  remote: https://rubygems.org/
25
25
  specs:
26
- activesupport (8.0.0)
26
+ activesupport (8.0.2)
27
27
  base64
28
28
  benchmark (>= 0.3)
29
29
  bigdecimal
@@ -36,142 +36,178 @@ GEM
36
36
  securerandom (>= 0.3)
37
37
  tzinfo (~> 2.0, >= 2.0.5)
38
38
  uri (>= 0.13.1)
39
- base64 (0.2.0)
40
- benchmark (0.4.0)
41
- bigdecimal (3.1.8)
42
- concurrent-ruby (1.3.4)
43
- connection_pool (2.4.1)
39
+ ast (2.4.3)
40
+ base64 (0.3.0)
41
+ benchmark (0.4.1)
42
+ bigdecimal (3.2.2)
43
+ concurrent-ruby (1.3.5)
44
+ connection_pool (2.5.3)
44
45
  date (3.4.1)
45
- diff-lcs (1.5.1)
46
- dotenv (3.1.4)
47
- drb (2.2.1)
48
- factory_bot (6.5.0)
49
- activesupport (>= 5.0.0)
50
- faker (3.5.1)
46
+ diff-lcs (1.6.2)
47
+ dotenv (3.1.8)
48
+ drb (2.2.3)
49
+ erb (5.0.2)
50
+ factory_bot (6.5.4)
51
+ activesupport (>= 6.1.0)
52
+ faker (3.5.2)
51
53
  i18n (>= 1.8.11, < 2)
52
- google-protobuf (4.29.3)
54
+ google-protobuf (4.31.1)
53
55
  bigdecimal
54
56
  rake (>= 13)
55
- google-protobuf (4.29.3-aarch64-linux)
57
+ google-protobuf (4.31.1-aarch64-linux-gnu)
56
58
  bigdecimal
57
59
  rake (>= 13)
58
- google-protobuf (4.29.3-arm64-darwin)
60
+ google-protobuf (4.31.1-arm64-darwin)
59
61
  bigdecimal
60
62
  rake (>= 13)
61
- google-protobuf (4.29.3-x86-linux)
63
+ google-protobuf (4.31.1-x86-linux-gnu)
62
64
  bigdecimal
63
65
  rake (>= 13)
64
- google-protobuf (4.29.3-x86_64-darwin)
66
+ google-protobuf (4.31.1-x86_64-darwin)
65
67
  bigdecimal
66
68
  rake (>= 13)
67
- google-protobuf (4.29.3-x86_64-linux)
69
+ google-protobuf (4.31.1-x86_64-linux-gnu)
68
70
  bigdecimal
69
71
  rake (>= 13)
70
- googleapis-common-protos-types (1.18.0)
72
+ googleapis-common-protos-types (1.20.0)
71
73
  google-protobuf (>= 3.18, < 5.a)
72
- i18n (1.14.6)
74
+ i18n (1.14.7)
73
75
  concurrent-ruby (~> 1.0)
74
- io-console (0.8.0)
75
- irb (1.15.1)
76
+ io-console (0.8.1)
77
+ irb (1.15.2)
76
78
  pp (>= 0.6.0)
77
79
  rdoc (>= 4.0.0)
78
80
  reline (>= 0.4.2)
79
- logger (1.6.1)
81
+ json (2.13.2)
82
+ language_server-protocol (3.17.0.5)
83
+ lint_roller (1.1.0)
84
+ logger (1.7.0)
80
85
  mini_portile2 (2.8.9)
81
- minitest (5.25.1)
82
- mustermann (3.0.3)
86
+ minitest (5.25.5)
87
+ mustermann (3.0.4)
83
88
  ruby2_keywords (~> 0.0.1)
84
- nokogiri (1.18.8)
89
+ nokogiri (1.18.9)
85
90
  mini_portile2 (~> 2.8.2)
86
91
  racc (~> 1.4)
87
- nokogiri (1.18.8-aarch64-linux-gnu)
92
+ nokogiri (1.18.9-aarch64-linux-gnu)
88
93
  racc (~> 1.4)
89
- nokogiri (1.18.8-arm-linux-gnu)
94
+ nokogiri (1.18.9-arm-linux-gnu)
90
95
  racc (~> 1.4)
91
- nokogiri (1.18.8-arm64-darwin)
96
+ nokogiri (1.18.9-arm64-darwin)
92
97
  racc (~> 1.4)
93
- nokogiri (1.18.8-x86_64-darwin)
98
+ nokogiri (1.18.9-x86_64-darwin)
94
99
  racc (~> 1.4)
95
- nokogiri (1.18.8-x86_64-linux-gnu)
100
+ nokogiri (1.18.9-x86_64-linux-gnu)
96
101
  racc (~> 1.4)
97
- opentelemetry-api (1.4.0)
98
- opentelemetry-common (0.21.0)
102
+ opentelemetry-api (1.5.0)
103
+ opentelemetry-common (0.22.0)
99
104
  opentelemetry-api (~> 1.0)
100
- opentelemetry-exporter-otlp (0.29.1)
105
+ opentelemetry-exporter-otlp (0.30.0)
101
106
  google-protobuf (>= 3.18)
102
107
  googleapis-common-protos-types (~> 1.3)
103
108
  opentelemetry-api (~> 1.1)
104
109
  opentelemetry-common (~> 0.20)
105
110
  opentelemetry-sdk (~> 1.2)
106
111
  opentelemetry-semantic_conventions
107
- opentelemetry-registry (0.3.1)
112
+ opentelemetry-registry (0.4.0)
108
113
  opentelemetry-api (~> 1.1)
109
- opentelemetry-sdk (1.7.0)
114
+ opentelemetry-sdk (1.8.0)
110
115
  opentelemetry-api (~> 1.1)
111
116
  opentelemetry-common (~> 0.20)
112
117
  opentelemetry-registry (~> 0.2)
113
118
  opentelemetry-semantic_conventions
114
- opentelemetry-semantic_conventions (1.10.1)
119
+ opentelemetry-semantic_conventions (1.11.0)
115
120
  opentelemetry-api (~> 1.0)
116
- ostruct (0.6.1)
117
- phlex (2.2.1)
121
+ ostruct (0.6.3)
122
+ parallel (1.27.0)
123
+ parser (3.3.9.0)
124
+ ast (~> 2.4.1)
125
+ racc
126
+ phlex (2.3.1)
118
127
  zeitwerk (~> 2.7)
119
128
  pp (0.6.2)
120
129
  prettyprint
121
130
  prettyprint (0.2.0)
122
- prism (1.2.0)
123
- psych (5.2.3)
131
+ prism (1.4.0)
132
+ psych (5.2.6)
124
133
  date
125
134
  stringio
126
135
  racc (1.8.1)
127
- rack (3.1.8)
128
- rack-protection (4.0.0)
136
+ rack (3.2.0)
137
+ rack-protection (4.1.1)
129
138
  base64 (>= 0.1.0)
139
+ logger (>= 1.6.0)
130
140
  rack (>= 3.0.0, < 4)
131
- rack-session (2.0.0)
141
+ rack-session (2.1.1)
142
+ base64 (>= 0.1.0)
132
143
  rack (>= 3.0.0)
133
144
  rackup (2.2.1)
134
145
  rack (>= 3)
135
- rake (13.2.1)
146
+ rainbow (3.1.1)
147
+ rake (13.3.0)
136
148
  rdiscount (2.2.7.3)
137
- rdoc (6.12.0)
149
+ rdoc (6.14.2)
150
+ erb
138
151
  psych (>= 4.0.0)
139
- reline (0.6.0)
152
+ regexp_parser (2.11.1)
153
+ reline (0.6.2)
140
154
  io-console (~> 0.5)
141
- rspec (3.13.0)
155
+ rspec (3.13.1)
142
156
  rspec-core (~> 3.13.0)
143
157
  rspec-expectations (~> 3.13.0)
144
158
  rspec-mocks (~> 3.13.0)
145
- rspec-core (3.13.2)
159
+ rspec-core (3.13.5)
146
160
  rspec-support (~> 3.13.0)
147
- rspec-expectations (3.13.3)
161
+ rspec-expectations (3.13.5)
148
162
  diff-lcs (>= 1.2.0, < 2.0)
149
163
  rspec-support (~> 3.13.0)
150
- rspec-mocks (3.13.2)
164
+ rspec-mocks (3.13.5)
151
165
  diff-lcs (>= 1.2.0, < 2.0)
152
166
  rspec-support (~> 3.13.0)
153
- rspec-support (3.13.1)
167
+ rspec-support (3.13.4)
168
+ rubocop (1.79.2)
169
+ json (~> 2.3)
170
+ language_server-protocol (~> 3.17.0.2)
171
+ lint_roller (~> 1.1.0)
172
+ parallel (~> 1.10)
173
+ parser (>= 3.3.0.2)
174
+ rainbow (>= 2.2.2, < 4.0)
175
+ regexp_parser (>= 2.9.3, < 3.0)
176
+ rubocop-ast (>= 1.46.0, < 2.0)
177
+ ruby-progressbar (~> 1.7)
178
+ unicode-display_width (>= 2.4.0, < 4.0)
179
+ rubocop-ast (1.46.0)
180
+ parser (>= 3.3.7.2)
181
+ prism (~> 1.4)
182
+ rubocop-disable_syntax (0.2.0)
183
+ lint_roller
184
+ rubocop (>= 1.72.0)
185
+ ruby-progressbar (1.13.0)
154
186
  ruby2_keywords (0.0.5)
155
- securerandom (0.3.2)
156
- semantic_logger (4.16.1)
187
+ securerandom (0.4.1)
188
+ semantic_logger (4.17.0)
157
189
  concurrent-ruby (~> 1.0)
158
- sequel (5.86.0)
190
+ sequel (5.95.1)
159
191
  bigdecimal
160
- sinatra (4.0.0)
192
+ sinatra (4.1.1)
193
+ logger (>= 1.6.0)
161
194
  mustermann (~> 3.0)
162
195
  rack (>= 3.0.0, < 4)
163
- rack-protection (= 4.0.0)
196
+ rack-protection (= 4.1.1)
164
197
  rack-session (>= 2.0.0, < 3)
165
198
  tilt (~> 2.0)
166
- stringio (3.1.3)
167
- tilt (2.4.0)
199
+ stringio (3.1.7)
200
+ tilt (2.6.1)
168
201
  tzinfo (2.0.6)
169
202
  concurrent-ruby (~> 1.0)
170
- tzinfo-data (1.2024.2)
203
+ tzinfo-data (1.2025.2)
171
204
  tzinfo (>= 1.0.0)
172
- uri (1.0.2)
205
+ unicode-display_width (3.1.4)
206
+ unicode-emoji (~> 4.0, >= 4.0.4)
207
+ unicode-emoji (4.0.4)
208
+ uri (1.0.3)
173
209
  yard (0.9.37)
174
- zeitwerk (2.7.1)
210
+ zeitwerk (2.7.3)
175
211
 
176
212
  PLATFORMS
177
213
  aarch64-linux
@@ -192,6 +228,8 @@ DEPENDENCIES
192
228
  rdiscount
193
229
  rdoc
194
230
  rspec (~> 3.0)
231
+ rubocop
232
+ rubocop-disable_syntax
195
233
  yard
196
234
 
197
235
  BUNDLED WITH
data/bin/ci CHANGED
@@ -20,7 +20,15 @@ brutcss_dir = (Pathname(__FILE__).dirname / ".." / "brut-css" ).expand_path.to_s
20
20
  mkbrut_dir = (Pathname(__FILE__).dirname / ".." / "mkbrut" ).expand_path.to_s
21
21
 
22
22
  log "Running BrutRB tests"
23
- system!("bin/rspec")
23
+ system!("bin/test")
24
+
25
+ log "Running mkbrut tests"
26
+ FileUtils.chdir mkbrut_dir do
27
+ system!("bin/ci")
28
+ end
29
+
30
+ log "Running Rubcop"
31
+ system!("bin/generate-and-run-rubocop")
24
32
 
25
33
  log "Running brut-js tests"
26
34
  FileUtils.chdir brutjs_dir do
@@ -30,7 +38,3 @@ log "Running brut-css tests"
30
38
  FileUtils.chdir brutcss_dir do
31
39
  system!("bin/ci")
32
40
  end
33
- log "Running mkbrut tests"
34
- FileUtils.chdir mkbrut_dir do
35
- system!("bin/ci")
36
- end
data/bin/docs CHANGED
@@ -37,7 +37,7 @@ log "Hacking CSS"
37
37
 
38
38
  [
39
39
  docs_dir / "css" / "style.css",
40
- docs_dir / "css" / "full_list.css"
40
+ docs_dir / "css" / "full_list.css",
41
41
  ].each do |css_file_to_hack|
42
42
  lines = File.read(css_file_to_hack).split(/\n/)
43
43
  File.open(css_file_to_hack, "w") do |f|
@@ -0,0 +1,52 @@
1
+ #!/bin/bash
2
+
3
+ set -e
4
+
5
+ SCRIPT_DIR=$( cd -- "$( dirname -- "${0}" )" > /dev/null 2>&1 && pwd )
6
+ ROOT_DIR=$(realpath "$SCRIPT_DIR/..")
7
+
8
+ usage() {
9
+ echo "Usage: $0 [-R]"
10
+ echo
11
+ echo " Generates .rubocop.yml and runs rubocop"
12
+ echo
13
+ echo "OPTIONS"
14
+ echo
15
+ echo " -R - Do not run rubocop, just generate the configuration"
16
+ echo
17
+ }
18
+
19
+ for arg in "$@"; do
20
+ if [ "${arg}" = "-h" ] || [ "${arg}" = "--help" ] || [ "${arg}" = "help" ]; then
21
+ usage
22
+ exit 0
23
+ fi
24
+ done
25
+
26
+ RUN_RUBOCOP=true
27
+ while getopts "R" opt "${@}"; do
28
+ case ${opt} in
29
+ R )
30
+ RUN_RUBOCOP=false
31
+ ;;
32
+ \? )
33
+ log "🛑" "Unknown option: ${opt}"
34
+ usage
35
+ ;;
36
+ : )
37
+ log "🛑" "Invalid option: ${opt} requires an argument"
38
+ usage
39
+ ;;
40
+ esac
41
+ done
42
+ shift $((OPTIND -1))
43
+
44
+ cd $ROOT_DIR
45
+ echo "[ "$0" ] Generating .rubocop.yml"
46
+ ruby -I "lib" -r brut/rubocop_config -e "Brut::RubocopConfig.new.create_ridiculous_yaml" .rubocop.yml
47
+ if [ "$RUN_RUBOCOP" = true ]; then
48
+ echo "[ "$0" ] Running rubocop"
49
+ bin/rubocop
50
+ else
51
+ echo "[ "$0" ] Not Running rubocop"
52
+ fi
data/bin/rubocop ADDED
@@ -0,0 +1,27 @@
1
+ #!/usr/bin/env ruby
2
+ # frozen_string_literal: true
3
+
4
+ #
5
+ # This file was generated by Bundler.
6
+ #
7
+ # The application 'rubocop' is installed as part of a gem, and
8
+ # this file is here to facilitate running it.
9
+ #
10
+
11
+ ENV["BUNDLE_GEMFILE"] ||= File.expand_path("../Gemfile", __dir__)
12
+
13
+ bundle_binstub = File.expand_path("bundle", __dir__)
14
+
15
+ if File.file?(bundle_binstub)
16
+ if File.read(bundle_binstub, 300).include?("This file was generated by Bundler")
17
+ load(bundle_binstub)
18
+ else
19
+ abort("Your `bin/bundle` was not generated by Bundler, so this binstub cannot run.
20
+ Replace `bin/bundle` by running `bundle binstubs bundler --force`, then run this command again.")
21
+ end
22
+ end
23
+
24
+ require "rubygems"
25
+ require "bundler/setup"
26
+
27
+ load Gem.bin_path("rubocop", "rubocop")
data/bin/setup CHANGED
@@ -16,9 +16,15 @@ def setup(update_gems:,setup_credentials:)
16
16
  system! "bundle check --no-color || bundle install --no-color --quiet"
17
17
  end
18
18
 
19
+ log "Creating Rubocop configuration"
20
+ system! "bin/generate-and-run-rubocop -R"
21
+
19
22
  log "Installing Ruby LSP"
20
23
  system! "gem install ruby-lsp"
21
24
 
25
+ log "Installing rubocop-disable_syntax because I have not set up RubyLSP for bundler yet"
26
+ system! "gem install rubocop-disable_syntax"
27
+
22
28
  log "Installing JS/TS and CSS LSPs"
23
29
  system! "npm install -g typescript typescript-language-server vscode-langservers-extracted"
24
30
 
@@ -164,6 +170,46 @@ def setup(update_gems:,setup_credentials:)
164
170
  end
165
171
  end
166
172
 
173
+ docker_credentials_source = credentials_dir / "dockerhub.credentials"
174
+ docker_credentials_preamble = [
175
+ "# Username and PAT for Docker commands",
176
+ "# The file format is for bin/setup and bin/deploy",
177
+ "# to coordinate. This file format should be able to be",
178
+ "# sourced into a bash script via .",
179
+ ]
180
+ if !docker_credentials_source.exist?
181
+ log "#{docker_credentials_source} doesn't exist - creating"
182
+ File.open(docker_credentials_source,"w") do |file|
183
+ docker_credentials_preamble.each { |line| file.puts line }
184
+ end
185
+ end
186
+ existing_file = File.read(docker_credentials_source).split(/\n/).reject {
187
+ it =~ /^\s*#/
188
+ }.map { |line|
189
+ line.split(/=/,2).map(&:strip)
190
+ }.to_h
191
+ changed = false
192
+ if !existing_file.key?("DOCKERHUB_USERNAME")
193
+ log "What is the username for DockerHub you will use to push mkbrut images?"
194
+ existing_file["DOCKERHUB_USERNAME"] = gets.chomp
195
+ changed = true
196
+ end
197
+ if !existing_file.key?("DOCKERHUB_PAT")
198
+ log "What is the Personal Access Token (PAT) for DockerHub you will use to push mkbrut images?"
199
+ existing_file["DOCKERHUB_PAT"] = gets.chomp
200
+ changed = true
201
+ end
202
+ if changed
203
+ File.open(docker_credentials_source,"w") do |file|
204
+ docker_credentials_preamble.each { |line| file.puts line }
205
+ existing_file.each do |key,value|
206
+ file.puts "#{key}=#{value}"
207
+ end
208
+ end
209
+ else
210
+ log "#{docker_credentials_source} exists and looks good"
211
+ end
212
+
167
213
  log "Setting up BrutJS"
168
214
  FileUtils.chdir project_root / "brut-js" do
169
215
  system! "bin/setup"
data/bin/test ADDED
@@ -0,0 +1,18 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require "optparse"
4
+ require_relative "bin_kit"
5
+
6
+ OptionParser.new do |opts|
7
+ opts.banner = "Usage: test [options]\n\n Runs Brut tests only\n\nOPTIONS\n\n"
8
+
9
+ opts.on("-h", "--help", "Display this help message") do
10
+ puts opts
11
+ puts
12
+ exit
13
+ end
14
+ end.parse!
15
+
16
+ log "Running BrutRB tests"
17
+ system!("bin/rspec -I specs --require spec_helper -P \"specs/**/*.spec.rb\"")
18
+
data/brut-css/bin/publish CHANGED
@@ -18,4 +18,4 @@ for arg in "$@"; do
18
18
  fi
19
19
  done
20
20
 
21
- npm publish brut-css
21
+ npm publish
@@ -1,12 +1,12 @@
1
1
  {
2
2
  "name": "brut-css",
3
- "version": "0.8.0",
3
+ "version": "0.9.1",
4
4
  "lockfileVersion": 3,
5
5
  "requires": true,
6
6
  "packages": {
7
7
  "": {
8
8
  "name": "brut-css",
9
- "version": "0.8.0",
9
+ "version": "0.9.1",
10
10
  "license": "Hippocratic-2.1",
11
11
  "devDependencies": {
12
12
  "comment-parser": "^1.4.1",
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "brut-css",
3
- "version": "0.8.0",
3
+ "version": "0.9.1",
4
4
  "description": "Utility CSS Library for Full Stack Developers",
5
5
  "keywords": [
6
6
  "css"
data/brut-js/bin/publish CHANGED
@@ -18,4 +18,4 @@ for arg in "$@"; do
18
18
  fi
19
19
  done
20
20
 
21
- npm publish brut-js
21
+ npm publish
@@ -1,12 +1,12 @@
1
1
  {
2
2
  "name": "brut-js",
3
- "version": "0.8.0",
3
+ "version": "0.9.1",
4
4
  "lockfileVersion": 3,
5
5
  "requires": true,
6
6
  "packages": {
7
7
  "": {
8
8
  "name": "brut-js",
9
- "version": "0.8.0",
9
+ "version": "0.9.1",
10
10
  "license": "Hippocratic-2.1",
11
11
  "devDependencies": {
12
12
  "esbuild": "^0.24.0",
data/brut-js/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "brut-js",
3
- "version": "0.8.0",
3
+ "version": "0.9.1",
4
4
  "type": "module",
5
5
  "keywords": [ "WebComponents", "Custom Elements" ],
6
6
  "bugs": {
@@ -7,7 +7,7 @@ describe("<brut-confirm-submit>", () => {
7
7
  <input type="text" name="text">
8
8
  <brut-confirm-submit message='You sure?'>
9
9
  <button>Save</button>
10
- <input type="submit" value="Submit">
10
+ <input type="submit" value="Submit" required minlength="3" value="abcd">
11
11
  </brut-confirm-submit>
12
12
  </form>
13
13
  `).test("uses window.confirm and cancels the click on Cancel", ({window,document,assert}) => {
@@ -82,6 +82,37 @@ describe("<brut-confirm-submit>", () => {
82
82
  assert.equal(messageShown,"You sure?")
83
83
  assert(submitted)
84
84
  })
85
+ withHTML(`
86
+ <form>
87
+ <input type="text" name="text" required minlength="3">
88
+ <brut-confirm-submit message='You sure?'>
89
+ <button>Save</button>
90
+ <input type="submit" value="Submit">
91
+ </brut-confirm-submit>
92
+ </form>
93
+ `).test("Does not show if form is invalid", ({window,document,assert}) => {
94
+ const form = document.querySelector("form")
95
+ const button = document.querySelector("button")
96
+
97
+ let submitted = false
98
+ form.addEventListener("submit", (event) => {
99
+ event.preventDefault()
100
+ submitted = true
101
+ })
102
+
103
+ let shown = false
104
+ let messageShown = null
105
+
106
+ window.confirm = (message) => {
107
+ shown = true
108
+ messageShown = message
109
+ return false // "Cancel"
110
+ }
111
+
112
+ button.click()
113
+ assert(!shown)
114
+ assert(!submitted)
115
+ })
85
116
  })
86
117
  describe("with an implicit dialog", () => {
87
118
  withHTML(`