brut 0.5.0 → 0.9.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (564) hide show
  1. checksums.yaml +4 -4
  2. data/.gitignore +13 -0
  3. data/CHANGELOG.md +14 -0
  4. data/Dockerfile.dx +27 -1
  5. data/Gemfile.lock +33 -1
  6. data/README.md +19 -0
  7. data/assets/YouTubeThumb.pxd +0 -0
  8. data/bin/build +86 -0
  9. data/bin/ci +40 -0
  10. data/bin/docs +40 -10
  11. data/bin/generate-and-run-rubocop +52 -0
  12. data/bin/publish +61 -0
  13. data/bin/rubocop +27 -0
  14. data/bin/setup +52 -0
  15. data/bin/test +18 -0
  16. data/brut-css/bin/build +19 -0
  17. data/brut-css/bin/ci +19 -0
  18. data/brut-css/bin/docs +19 -0
  19. data/brut-css/bin/publish +21 -0
  20. data/brut-css/bin/setup +1 -0
  21. data/brut-css/package-lock.json +2 -2
  22. data/brut-css/package.json +1 -1
  23. data/brut-js/bin/build +15 -6
  24. data/brut-js/bin/docs +25 -0
  25. data/brut-js/bin/publish +21 -0
  26. data/brut-js/bin/setup +1 -0
  27. data/brut-js/dx +1 -0
  28. data/brut-js/package-lock.json +2 -2
  29. data/brut-js/package.json +1 -1
  30. data/brut.gemspec +34 -28
  31. data/brutrb.com/.vitepress/config.mjs +3 -0
  32. data/brutrb.com/bin/setup +1 -0
  33. data/brutrb.com/database-schema.md +1 -1
  34. data/brutrb.com/getting-started.md +3 -0
  35. data/brutrb.com/overview.md +6 -0
  36. data/brutrb.com/recipes/migrations.md +1 -1
  37. data/brutrb.com/tutorial.md +7 -3
  38. data/docker-compose.dx.yml +3 -0
  39. data/docs/404.html +2 -2
  40. data/docs/adrs.html +3 -3
  41. data/docs/ai.html +3 -3
  42. data/docs/api/Brut/BackEnd/SeedData.html +2 -2
  43. data/docs/api/Brut/BackEnd/Sidekiq/Middlewares/Server/FlushSpans.html +2 -2
  44. data/docs/api/Brut/BackEnd/Sidekiq/Middlewares/Server.html +2 -2
  45. data/docs/api/Brut/BackEnd/Sidekiq/Middlewares.html +2 -2
  46. data/docs/api/Brut/BackEnd/Sidekiq.html +2 -2
  47. data/docs/api/Brut/BackEnd/Validators/FormValidator.html +2 -2
  48. data/docs/api/Brut/BackEnd/Validators.html +2 -2
  49. data/docs/api/Brut/BackEnd.html +2 -2
  50. data/docs/api/Brut/CLI/App.html +2 -2
  51. data/docs/api/Brut/CLI/AppRunner.html +2 -2
  52. data/docs/api/Brut/CLI/Apps/BuildAssets/All.html +2 -2
  53. data/docs/api/Brut/CLI/Apps/BuildAssets/CSS.html +2 -2
  54. data/docs/api/Brut/CLI/Apps/BuildAssets/Images.html +2 -2
  55. data/docs/api/Brut/CLI/Apps/BuildAssets/JS.html +2 -2
  56. data/docs/api/Brut/CLI/Apps/BuildAssets.html +2 -2
  57. data/docs/api/Brut/CLI/Apps/DB/Create.html +2 -2
  58. data/docs/api/Brut/CLI/Apps/DB/Drop.html +2 -2
  59. data/docs/api/Brut/CLI/Apps/DB/Migrate.html +2 -2
  60. data/docs/api/Brut/CLI/Apps/DB/NewMigration.html +2 -2
  61. data/docs/api/Brut/CLI/Apps/DB/Rebuild.html +2 -2
  62. data/docs/api/Brut/CLI/Apps/DB/Seed.html +2 -2
  63. data/docs/api/Brut/CLI/Apps/DB/Status.html +2 -2
  64. data/docs/api/Brut/CLI/Apps/DB.html +2 -2
  65. data/docs/api/Brut/CLI/Apps/DeployBase/GitChecks.html +2 -2
  66. data/docs/api/Brut/CLI/Apps/DeployBase.html +2 -2
  67. data/docs/api/Brut/CLI/Apps/HerokuContainerBasedDeploy/Deploy.html +3 -3
  68. data/docs/api/Brut/CLI/Apps/HerokuContainerBasedDeploy.html +2 -2
  69. data/docs/api/Brut/CLI/Apps/Scaffold/Action/Route.html +2 -2
  70. data/docs/api/Brut/CLI/Apps/Scaffold/Action.html +2 -2
  71. data/docs/api/Brut/CLI/Apps/Scaffold/Component.html +2 -2
  72. data/docs/api/Brut/CLI/Apps/Scaffold/CustomElementTest.html +2 -2
  73. data/docs/api/Brut/CLI/Apps/Scaffold/DbModel.html +2 -2
  74. data/docs/api/Brut/CLI/Apps/Scaffold/E2ETest.html +2 -2
  75. data/docs/api/Brut/CLI/Apps/Scaffold/Form.html +2 -2
  76. data/docs/api/Brut/CLI/Apps/Scaffold/Page/Route.html +2 -2
  77. data/docs/api/Brut/CLI/Apps/Scaffold/Page.html +2 -2
  78. data/docs/api/Brut/CLI/Apps/Scaffold/RoutesEditor.html +2 -2
  79. data/docs/api/Brut/CLI/Apps/Scaffold/Test.html +3 -3
  80. data/docs/api/Brut/CLI/Apps/Scaffold.html +2 -2
  81. data/docs/api/Brut/CLI/Apps/Test/Audit.html +2 -2
  82. data/docs/api/Brut/CLI/Apps/Test/E2e.html +2 -2
  83. data/docs/api/Brut/CLI/Apps/Test/JS.html +2 -2
  84. data/docs/api/Brut/CLI/Apps/Test/Run.html +2 -2
  85. data/docs/api/Brut/CLI/Apps/Test.html +2 -2
  86. data/docs/api/Brut/CLI/Apps.html +2 -2
  87. data/docs/api/Brut/CLI/Command.html +2 -2
  88. data/docs/api/Brut/CLI/Error.html +2 -2
  89. data/docs/api/Brut/CLI/ExecutionResults/Result.html +2 -2
  90. data/docs/api/Brut/CLI/ExecutionResults.html +2 -2
  91. data/docs/api/Brut/CLI/Executor.html +2 -2
  92. data/docs/api/Brut/CLI/InvalidOption.html +2 -2
  93. data/docs/api/Brut/CLI/Options.html +80 -2
  94. data/docs/api/Brut/CLI/Output.html +2 -2
  95. data/docs/api/Brut/CLI/SystemExecError.html +2 -2
  96. data/docs/api/Brut/CLI.html +2 -2
  97. data/docs/api/Brut/FactoryBot.html +3 -3
  98. data/docs/api/Brut/Framework/App.html +3 -3
  99. data/docs/api/Brut/Framework/Config.html +25 -3
  100. data/docs/api/Brut/Framework/Container.html +2 -2
  101. data/docs/api/Brut/Framework/Error.html +2 -2
  102. data/docs/api/Brut/Framework/Errors/AbstractMethod.html +2 -2
  103. data/docs/api/Brut/Framework/Errors/Bug.html +2 -2
  104. data/docs/api/Brut/Framework/Errors/MissingConfiguration.html +2 -2
  105. data/docs/api/Brut/Framework/Errors/MissingParameter.html +2 -2
  106. data/docs/api/Brut/Framework/Errors/NoClassForPath.html +2 -2
  107. data/docs/api/Brut/Framework/Errors/NotFound.html +2 -2
  108. data/docs/api/Brut/Framework/Errors/NotImplemented.html +2 -2
  109. data/docs/api/Brut/Framework/Errors.html +2 -2
  110. data/docs/api/Brut/Framework/FussyTypeEnforcement.html +2 -2
  111. data/docs/api/Brut/Framework/MCP.html +21 -11
  112. data/docs/api/Brut/Framework/ProjectEnvironment.html +2 -2
  113. data/docs/api/Brut/Framework.html +2 -2
  114. data/docs/api/Brut/FrontEnd/AssetPathResolver.html +2 -2
  115. data/docs/api/Brut/FrontEnd/Component/Helpers.html +2 -2
  116. data/docs/api/Brut/FrontEnd/Component.html +2 -2
  117. data/docs/api/Brut/FrontEnd/Components/ConstraintViolations.html +2 -2
  118. data/docs/api/Brut/FrontEnd/Components/FormTag.html +4 -4
  119. data/docs/api/Brut/FrontEnd/Components/I18nTranslations.html +2 -2
  120. data/docs/api/Brut/FrontEnd/Components/Input.html +2 -2
  121. data/docs/api/Brut/FrontEnd/Components/Inputs/CsrfToken.html +2 -2
  122. data/docs/api/Brut/FrontEnd/Components/Inputs/InputTag.html +2 -2
  123. data/docs/api/Brut/FrontEnd/Components/Inputs/RadioButton.html +2 -2
  124. data/docs/api/Brut/FrontEnd/Components/Inputs/SelectTagWithOptions.html +2 -2
  125. data/docs/api/Brut/FrontEnd/Components/Inputs/TextareaTag.html +2 -2
  126. data/docs/api/Brut/FrontEnd/Components/Inputs.html +2 -2
  127. data/docs/api/Brut/FrontEnd/Components/LocaleDetection.html +2 -2
  128. data/docs/api/Brut/FrontEnd/Components/PageIdentifier.html +2 -2
  129. data/docs/api/Brut/FrontEnd/Components/TimeTag.html +2 -2
  130. data/docs/api/Brut/FrontEnd/Components/Traceparent.html +2 -2
  131. data/docs/api/Brut/FrontEnd/Components.html +2 -2
  132. data/docs/api/Brut/FrontEnd/CsrfProtector.html +250 -0
  133. data/docs/api/Brut/FrontEnd/Download.html +2 -2
  134. data/docs/api/Brut/FrontEnd/Flash.html +2 -2
  135. data/docs/api/Brut/FrontEnd/Form.html +6 -6
  136. data/docs/api/Brut/FrontEnd/Forms/ConstraintViolation.html +2 -2
  137. data/docs/api/Brut/FrontEnd/Forms/Input/Color.html +2 -2
  138. data/docs/api/Brut/FrontEnd/Forms/Input/TimeOfDay.html +2 -2
  139. data/docs/api/Brut/FrontEnd/Forms/Input.html +2 -2
  140. data/docs/api/Brut/FrontEnd/Forms/InputDeclarations.html +2 -2
  141. data/docs/api/Brut/FrontEnd/Forms/InputDefinition.html +2 -2
  142. data/docs/api/Brut/FrontEnd/Forms/RadioButtonGroupInput.html +2 -2
  143. data/docs/api/Brut/FrontEnd/Forms/RadioButtonGroupInputDefinition.html +2 -2
  144. data/docs/api/Brut/FrontEnd/Forms/SelectInput.html +2 -2
  145. data/docs/api/Brut/FrontEnd/Forms/SelectInputDefinition.html +2 -2
  146. data/docs/api/Brut/FrontEnd/Forms/ValidityState.html +2 -2
  147. data/docs/api/Brut/FrontEnd/Forms.html +2 -2
  148. data/docs/api/Brut/FrontEnd/GenericResponse.html +2 -2
  149. data/docs/api/Brut/FrontEnd/Handler.html +2 -2
  150. data/docs/api/Brut/FrontEnd/Handlers/CspReportingHandler.html +2 -2
  151. data/docs/api/Brut/FrontEnd/Handlers/InstrumentationHandler/TraceParent.html +2 -2
  152. data/docs/api/Brut/FrontEnd/Handlers/InstrumentationHandler.html +2 -2
  153. data/docs/api/Brut/FrontEnd/Handlers/LocaleDetectionHandler.html +2 -2
  154. data/docs/api/Brut/FrontEnd/Handlers/MissingHandler/Form.html +2 -2
  155. data/docs/api/Brut/FrontEnd/Handlers/MissingHandler.html +2 -2
  156. data/docs/api/Brut/FrontEnd/Handlers.html +2 -2
  157. data/docs/api/Brut/FrontEnd/HandlingResults.html +2 -2
  158. data/docs/api/Brut/FrontEnd/HttpMethod.html +2 -2
  159. data/docs/api/Brut/FrontEnd/HttpStatus.html +2 -2
  160. data/docs/api/Brut/FrontEnd/InlineSvgLocator.html +2 -2
  161. data/docs/api/Brut/FrontEnd/Layout.html +2 -2
  162. data/docs/api/Brut/FrontEnd/Middleware.html +2 -2
  163. data/docs/api/Brut/FrontEnd/Middlewares/AnnotateBrutOwnedPaths.html +2 -2
  164. data/docs/api/Brut/FrontEnd/Middlewares/Favicon.html +2 -2
  165. data/docs/api/Brut/FrontEnd/Middlewares/OpenTelemetrySpan.html +2 -2
  166. data/docs/api/Brut/FrontEnd/Middlewares/ReloadApp.html +2 -2
  167. data/docs/api/Brut/FrontEnd/Middlewares.html +2 -2
  168. data/docs/api/Brut/FrontEnd/Page.html +2 -2
  169. data/docs/api/Brut/FrontEnd/Pages/MissingPage.html +2 -2
  170. data/docs/api/Brut/FrontEnd/Pages.html +2 -2
  171. data/docs/api/Brut/FrontEnd/RequestContext.html +2 -2
  172. data/docs/api/Brut/FrontEnd/RouteHook.html +2 -2
  173. data/docs/api/Brut/FrontEnd/RouteHooks/AgeFlash.html +2 -2
  174. data/docs/api/Brut/FrontEnd/RouteHooks/CSPNoInlineScripts.html +2 -2
  175. data/docs/api/Brut/FrontEnd/RouteHooks/CSPNoInlineStylesOrScripts/ReportOnly.html +2 -2
  176. data/docs/api/Brut/FrontEnd/RouteHooks/CSPNoInlineStylesOrScripts.html +2 -2
  177. data/docs/api/Brut/FrontEnd/RouteHooks/LocaleDetection.html +2 -2
  178. data/docs/api/Brut/FrontEnd/RouteHooks/SetupRequestContext.html +2 -2
  179. data/docs/api/Brut/FrontEnd/RouteHooks.html +2 -2
  180. data/docs/api/Brut/FrontEnd/Routing/FormHandlerRoute.html +2 -2
  181. data/docs/api/Brut/FrontEnd/Routing/FormRoute.html +2 -2
  182. data/docs/api/Brut/FrontEnd/Routing/MissingForm.html +2 -2
  183. data/docs/api/Brut/FrontEnd/Routing/MissingHandler.html +2 -2
  184. data/docs/api/Brut/FrontEnd/Routing/MissingPage.html +2 -2
  185. data/docs/api/Brut/FrontEnd/Routing/MissingPath.html +2 -2
  186. data/docs/api/Brut/FrontEnd/Routing/PageRoute.html +2 -2
  187. data/docs/api/Brut/FrontEnd/Routing/Route.html +2 -2
  188. data/docs/api/Brut/FrontEnd/Routing.html +2 -2
  189. data/docs/api/Brut/FrontEnd/Session.html +2 -2
  190. data/docs/api/Brut/FrontEnd.html +3 -3
  191. data/docs/api/Brut/I18n/BaseMethods.html +3 -3
  192. data/docs/api/Brut/I18n/ForBackEnd.html +2 -2
  193. data/docs/api/Brut/I18n/ForCLI.html +2 -2
  194. data/docs/api/Brut/I18n/ForHTML.html +2 -2
  195. data/docs/api/Brut/I18n/HTTPAcceptLanguage/AlwaysEnglish.html +2 -2
  196. data/docs/api/Brut/I18n/HTTPAcceptLanguage.html +2 -2
  197. data/docs/api/Brut/I18n.html +2 -2
  198. data/docs/api/Brut/Instrumentation/LoggerSpanExporter.html +2 -2
  199. data/docs/api/Brut/Instrumentation/OpenTelemetry/NormalizedAttributes.html +2 -2
  200. data/docs/api/Brut/Instrumentation/OpenTelemetry/Span.html +2 -2
  201. data/docs/api/Brut/Instrumentation/OpenTelemetry.html +2 -2
  202. data/docs/api/Brut/Instrumentation.html +2 -2
  203. data/docs/api/Brut/RubocopConfig.html +237 -0
  204. data/docs/api/Brut/SinatraHelpers/ClassMethods.html +2 -2
  205. data/docs/api/Brut/SinatraHelpers.html +2 -2
  206. data/docs/api/Brut/SpecSupport/ClockSupport.html +2 -2
  207. data/docs/api/Brut/SpecSupport/ComponentSupport.html +7 -13
  208. data/docs/api/Brut/SpecSupport/E2ETestServer.html +2 -2
  209. data/docs/api/Brut/SpecSupport/E2eSupport.html +2 -2
  210. data/docs/api/Brut/SpecSupport/EnhancedNode.html +2 -2
  211. data/docs/api/Brut/SpecSupport/FlashSupport.html +2 -2
  212. data/docs/api/Brut/SpecSupport/GeneralSupport/ClassMethods.html +2 -2
  213. data/docs/api/Brut/SpecSupport/GeneralSupport.html +2 -2
  214. data/docs/api/Brut/SpecSupport/HandlerSupport.html +2 -2
  215. data/docs/api/Brut/SpecSupport/Matchers/BeABug.html +2 -2
  216. data/docs/api/Brut/SpecSupport/Matchers/BePageFor.html +2 -2
  217. data/docs/api/Brut/SpecSupport/Matchers/BeRoutingFor.html +2 -2
  218. data/docs/api/Brut/SpecSupport/Matchers/HaveConstraintViolation.html +2 -2
  219. data/docs/api/Brut/SpecSupport/Matchers/HaveGenerated.html +2 -2
  220. data/docs/api/Brut/SpecSupport/Matchers/HaveHTMLAttribute.html +2 -2
  221. data/docs/api/Brut/SpecSupport/Matchers/HaveI18nString.html +2 -2
  222. data/docs/api/Brut/SpecSupport/Matchers/HaveLinkTo.html +2 -2
  223. data/docs/api/Brut/SpecSupport/Matchers/HaveRedirectedTo.html +2 -2
  224. data/docs/api/Brut/SpecSupport/Matchers/HaveReturnedHttpStatus.html +2 -2
  225. data/docs/api/Brut/SpecSupport/Matchers/HaveReturnedRackResponse.html +2 -2
  226. data/docs/api/Brut/SpecSupport/Matchers.html +2 -2
  227. data/docs/api/Brut/SpecSupport/RSpecSetup/OptionalSidekiqSupport.html +2 -2
  228. data/docs/api/Brut/SpecSupport/RSpecSetup.html +4 -4
  229. data/docs/api/Brut/SpecSupport/SessionSupport.html +2 -2
  230. data/docs/api/Brut/SpecSupport.html +2 -2
  231. data/docs/api/Brut.html +128 -12
  232. data/docs/api/Clock.html +2 -2
  233. data/docs/api/ModuleName.html +28 -28
  234. data/docs/api/RichString.html +22 -22
  235. data/docs/api/SemanticLogger/Appender/Async.html +2 -2
  236. data/docs/api/Sequel/Extensions/BrutInstrumentation.html +2 -2
  237. data/docs/api/Sequel/Extensions/BrutMigrations.html +2 -2
  238. data/docs/api/Sequel/Extensions.html +2 -2
  239. data/docs/api/Sequel/Plugins/CreatedAt/InstanceMethods.html +2 -2
  240. data/docs/api/Sequel/Plugins/CreatedAt.html +2 -2
  241. data/docs/api/Sequel/Plugins/ExternalId/ClassMethods.html +2 -2
  242. data/docs/api/Sequel/Plugins/ExternalId/InstanceMethods.html +2 -2
  243. data/docs/api/Sequel/Plugins/ExternalId.html +2 -2
  244. data/docs/api/Sequel/Plugins/FindBang/ClassMethods.html +2 -2
  245. data/docs/api/Sequel/Plugins/FindBang.html +2 -2
  246. data/docs/api/Sequel/Plugins.html +2 -2
  247. data/docs/api/Sequel.html +2 -2
  248. data/docs/api/_index.html +16 -2
  249. data/docs/api/class_list.html +1 -1
  250. data/docs/api/file.README.html +28 -2
  251. data/docs/api/index.html +28 -2
  252. data/docs/api/method_list.html +192 -168
  253. data/docs/api/top-level-namespace.html +2 -2
  254. data/docs/assets/{app.D6BuVHo9.js → app.CmkhEsw7.js} +1 -1
  255. data/docs/assets/chunks/@localSearchIndexroot.DUha-mf5.js +1 -0
  256. data/docs/assets/chunks/{VPLocalSearchBox.BpvHMbx6.js → VPLocalSearchBox.CDh583Oj.js} +1 -1
  257. data/docs/assets/chunks/{theme.wlAOvi2f.js → theme.B0_7GeW8.js} +2 -2
  258. data/docs/assets/{components.md.iLiv2E9X.js → components.md.-22ecBxM.js} +3 -3
  259. data/docs/assets/{configuration.md.DmuAdsli.js → configuration.md.CLKL1lFf.js} +1 -1
  260. data/docs/assets/{database-schema.md.C5gXexJi.js → database-schema.md.LpmBPVEU.js} +1 -1
  261. data/docs/assets/{forms.md.D8aa_qI-.js → forms.md.CBI5--o2.js} +1 -1
  262. data/docs/assets/{getting-started.md.DLplsDUd.js → getting-started.md.D5nzBZ4J.js} +6 -3
  263. data/docs/assets/{getting-started.md.DLplsDUd.lean.js → getting-started.md.D5nzBZ4J.lean.js} +1 -1
  264. data/docs/assets/overview.md.DlKiRRG_.js +1 -0
  265. data/docs/assets/overview.md.DlKiRRG_.lean.js +1 -0
  266. data/docs/assets/{recipes_migrations.md.DPN3gQE3.js → recipes_migrations.md.CTcnWDJF.js} +1 -1
  267. data/docs/assets/tutorial.md.BIb7XT6j.js +1 -0
  268. data/docs/assets/tutorial.md.BIb7XT6j.lean.js +1 -0
  269. data/docs/assets.html +3 -3
  270. data/docs/brut-js/api/AjaxSubmit.html +1 -1
  271. data/docs/brut-js/api/AjaxSubmit.js.html +1 -1
  272. data/docs/brut-js/api/Autosubmit.html +1 -1
  273. data/docs/brut-js/api/Autosubmit.js.html +1 -1
  274. data/docs/brut-js/api/BaseCustomElement.html +1 -1
  275. data/docs/brut-js/api/BaseCustomElement.js.html +1 -1
  276. data/docs/brut-js/api/BrutCustomElements.html +1 -1
  277. data/docs/brut-js/api/BufferedLogger.html +1 -1
  278. data/docs/brut-js/api/ConfirmSubmit.html +1 -1
  279. data/docs/brut-js/api/ConfirmSubmit.js.html +1 -1
  280. data/docs/brut-js/api/ConfirmationDialog.html +1 -1
  281. data/docs/brut-js/api/ConfirmationDialog.js.html +1 -1
  282. data/docs/brut-js/api/ConstraintViolationMessage.html +1 -1
  283. data/docs/brut-js/api/ConstraintViolationMessage.js.html +1 -1
  284. data/docs/brut-js/api/ConstraintViolationMessages.html +1 -1
  285. data/docs/brut-js/api/ConstraintViolationMessages.js.html +1 -1
  286. data/docs/brut-js/api/CopyToClipboard.html +1 -1
  287. data/docs/brut-js/api/CopyToClipboard.js.html +1 -1
  288. data/docs/brut-js/api/Form.html +1 -1
  289. data/docs/brut-js/api/Form.js.html +1 -1
  290. data/docs/brut-js/api/I18nTranslation.html +1 -1
  291. data/docs/brut-js/api/I18nTranslation.js.html +1 -1
  292. data/docs/brut-js/api/LocaleDetection.html +1 -1
  293. data/docs/brut-js/api/LocaleDetection.js.html +1 -1
  294. data/docs/brut-js/api/Logger.html +1 -1
  295. data/docs/brut-js/api/Logger.js.html +1 -1
  296. data/docs/brut-js/api/Message.html +1 -1
  297. data/docs/brut-js/api/Message.js.html +1 -1
  298. data/docs/brut-js/api/PrefixedLogger.html +1 -1
  299. data/docs/brut-js/api/RichString.html +1 -1
  300. data/docs/brut-js/api/RichString.js.html +1 -1
  301. data/docs/brut-js/api/Tabs.html +1 -1
  302. data/docs/brut-js/api/Tabs.js.html +1 -1
  303. data/docs/brut-js/api/Tracing.html +1 -1
  304. data/docs/brut-js/api/Tracing.js.html +1 -1
  305. data/docs/brut-js/api/external-CustomElementRegistry.html +1 -1
  306. data/docs/brut-js/api/external-Performance.html +1 -1
  307. data/docs/brut-js/api/external-Promise.html +1 -1
  308. data/docs/brut-js/api/external-ValidityState.html +1 -1
  309. data/docs/brut-js/api/external-Window.html +1 -1
  310. data/docs/brut-js/api/external-fetch.html +1 -1
  311. data/docs/brut-js/api/global.html +1 -1
  312. data/docs/brut-js/api/index.html +1 -1
  313. data/docs/brut-js/api/index.js.html +1 -1
  314. data/docs/brut-js/api/module-testing.html +1 -1
  315. data/docs/brut-js/api/testing.AssetMetadata.html +1 -1
  316. data/docs/brut-js/api/testing.AssetMetadataLoader.html +1 -1
  317. data/docs/brut-js/api/testing.CustomElementTest.html +1 -1
  318. data/docs/brut-js/api/testing.DOMCreator.html +1 -1
  319. data/docs/brut-js/api/testing_AssetMetadata.js.html +1 -1
  320. data/docs/brut-js/api/testing_AssetMetadataLoader.js.html +1 -1
  321. data/docs/brut-js/api/testing_CustomElementTest.js.html +1 -1
  322. data/docs/brut-js/api/testing_DOMCreator.js.html +1 -1
  323. data/docs/brut-js/api/testing_index.js.html +1 -1
  324. data/docs/brut-js.html +3 -3
  325. data/docs/business-logic.html +3 -3
  326. data/docs/cli.html +3 -3
  327. data/docs/components.html +7 -7
  328. data/docs/configuration.html +5 -5
  329. data/docs/css.html +3 -3
  330. data/docs/custom-element-tests.html +3 -3
  331. data/docs/database-access.html +3 -3
  332. data/docs/database-schema.html +5 -5
  333. data/docs/deployment.html +3 -3
  334. data/docs/dev-environment.html +3 -3
  335. data/docs/dir-structure.html +3 -3
  336. data/docs/doc-conventions.html +3 -3
  337. data/docs/end-to-end-tests.html +3 -3
  338. data/docs/features.html +3 -3
  339. data/docs/flash-and-session.html +3 -3
  340. data/docs/form-constraints.html +3 -3
  341. data/docs/forms.html +5 -5
  342. data/docs/getting-started.html +9 -6
  343. data/docs/handlers.html +3 -3
  344. data/docs/hashmap.json +1 -1
  345. data/docs/hooks.html +3 -3
  346. data/docs/i18n.html +3 -3
  347. data/docs/index.html +3 -3
  348. data/docs/instrumentation.html +3 -3
  349. data/docs/javascript.html +3 -3
  350. data/docs/jobs.html +3 -3
  351. data/docs/keyword-injection.html +3 -3
  352. data/docs/layouts.html +3 -3
  353. data/docs/lsp.html +3 -3
  354. data/docs/markdown-examples.html +3 -3
  355. data/docs/middleware.html +3 -3
  356. data/docs/overview.html +5 -5
  357. data/docs/pages.html +3 -3
  358. data/docs/recipes/alternate-layouts.html +3 -3
  359. data/docs/recipes/authentication.html +3 -3
  360. data/docs/recipes/blank-layouts.html +3 -3
  361. data/docs/recipes/custom-flash.html +3 -3
  362. data/docs/recipes/indexed-forms.html +3 -3
  363. data/docs/recipes/migrations.html +5 -5
  364. data/docs/recipes/text-field-component.html +3 -3
  365. data/docs/roadmap.html +3 -3
  366. data/docs/routes.html +3 -3
  367. data/docs/security.html +3 -3
  368. data/docs/seed-data.html +3 -3
  369. data/docs/space-time-continuum.html +3 -3
  370. data/docs/tutorial.html +5 -5
  371. data/docs/unit-tests.html +3 -3
  372. data/docs/why.html +3 -3
  373. data/dx/build +45 -9
  374. data/lib/brut/cli/app.rb +1 -1
  375. data/lib/brut/cli/apps/heroku_container_based_deploy.rb +1 -1
  376. data/lib/brut/cli/apps/scaffold.rb +1 -1
  377. data/lib/brut/cli/options.rb +4 -0
  378. data/lib/brut/factory_bot.rb +1 -1
  379. data/lib/brut/framework/app.rb +1 -1
  380. data/lib/brut/framework/config.rb +11 -0
  381. data/lib/brut/framework/mcp.rb +13 -8
  382. data/lib/brut/front_end/components/form_tag.rb +2 -2
  383. data/lib/brut/front_end/csrf_protector.rb +30 -0
  384. data/lib/brut/front_end/form.rb +4 -4
  385. data/lib/brut/front_end/page.rb +1 -1
  386. data/lib/brut/front_end/routing.rb +1 -1
  387. data/lib/brut/front_end.rb +1 -0
  388. data/lib/brut/i18n/base_methods.rb +1 -1
  389. data/lib/brut/instrumentation/logger_span_exporter.rb +1 -1
  390. data/lib/brut/junk_drawer.rb +3 -1
  391. data/lib/brut/rubocop_config.rb +123 -0
  392. data/lib/brut/spec_support/component_support.rb +0 -3
  393. data/lib/brut/spec_support/rspec_setup.rb +2 -2
  394. data/lib/brut/version.rb +1 -1
  395. data/mkbrut/.gitignore +16 -0
  396. data/mkbrut/CODE_OF_CONDUCT.txt +100 -0
  397. data/mkbrut/Gemfile +3 -0
  398. data/mkbrut/Gemfile.lock +19 -0
  399. data/mkbrut/LICENSE.txt +370 -0
  400. data/mkbrut/README.md +145 -0
  401. data/mkbrut/Rakefile +2 -0
  402. data/mkbrut/bin/build +36 -0
  403. data/mkbrut/bin/ci +19 -0
  404. data/mkbrut/bin/docs +19 -0
  405. data/mkbrut/bin/publish +129 -0
  406. data/mkbrut/bin/rake +16 -0
  407. data/mkbrut/bin/setup +30 -0
  408. data/mkbrut/brut-welcome.png +0 -0
  409. data/mkbrut/deploy/.dockerignore +2 -0
  410. data/mkbrut/deploy/Dockerfile +25 -0
  411. data/mkbrut/dx +1 -0
  412. data/mkbrut/exe/mkbrut +5 -0
  413. data/mkbrut/lib/mkbrut/app.rb +79 -0
  414. data/mkbrut/lib/mkbrut/app_id.rb +8 -0
  415. data/mkbrut/lib/mkbrut/app_name.rb +29 -0
  416. data/mkbrut/lib/mkbrut/app_options.rb +36 -0
  417. data/mkbrut/lib/mkbrut/base.rb +57 -0
  418. data/mkbrut/lib/mkbrut/cli.rb +107 -0
  419. data/mkbrut/lib/mkbrut/erb_binding_delegate.rb +20 -0
  420. data/mkbrut/lib/mkbrut/internet_identifier.rb +32 -0
  421. data/mkbrut/lib/mkbrut/invalid_identifier.rb +4 -0
  422. data/mkbrut/lib/mkbrut/ops/add_css_import.rb +42 -0
  423. data/mkbrut/lib/mkbrut/ops/add_i18n_message.rb +74 -0
  424. data/mkbrut/lib/mkbrut/ops/add_method.rb +48 -0
  425. data/mkbrut/lib/mkbrut/ops/append_to_file.rb +20 -0
  426. data/mkbrut/lib/mkbrut/ops/base_op.rb +21 -0
  427. data/mkbrut/lib/mkbrut/ops/copy_file.rb +12 -0
  428. data/mkbrut/lib/mkbrut/ops/insert_code_in_method.rb +58 -0
  429. data/mkbrut/lib/mkbrut/ops/insert_route.rb +52 -0
  430. data/mkbrut/lib/mkbrut/ops/mkdir.rb +13 -0
  431. data/mkbrut/lib/mkbrut/ops/prism_parsing_op.rb +70 -0
  432. data/mkbrut/lib/mkbrut/ops/render_template.rb +26 -0
  433. data/mkbrut/lib/mkbrut/ops/skip_file.rb +10 -0
  434. data/mkbrut/lib/mkbrut/ops.rb +16 -0
  435. data/mkbrut/lib/mkbrut/organization.rb +5 -0
  436. data/mkbrut/lib/mkbrut/prefix.rb +26 -0
  437. data/mkbrut/lib/mkbrut/prefixed_io.rb +16 -0
  438. data/mkbrut/lib/mkbrut/segments/bare_bones.rb +185 -0
  439. data/mkbrut/lib/mkbrut/segments/demo.rb +121 -0
  440. data/mkbrut/lib/mkbrut/segments/heroku.rb +30 -0
  441. data/mkbrut/lib/mkbrut/segments/sidekiq.rb +3 -0
  442. data/mkbrut/lib/mkbrut/segments.rb +8 -0
  443. data/mkbrut/lib/mkbrut/version.rb +3 -0
  444. data/mkbrut/lib/mkbrut/versions.rb +13 -0
  445. data/mkbrut/lib/mkbrut.rb +18 -0
  446. data/mkbrut/mkbrut.gemspec +34 -0
  447. data/mkbrut/templates/Base/.dockerignore +25 -0
  448. data/mkbrut/templates/Base/.env.development.erb +60 -0
  449. data/mkbrut/templates/Base/.env.test.erb +8 -0
  450. data/mkbrut/templates/Base/.gitignore +31 -0
  451. data/mkbrut/templates/Base/.projections.json +59 -0
  452. data/mkbrut/templates/Base/Dockerfile.dx +205 -0
  453. data/mkbrut/templates/Base/Gemfile.erb +53 -0
  454. data/mkbrut/templates/Base/Procfile.development +5 -0
  455. data/mkbrut/templates/Base/Procfile.test +1 -0
  456. data/mkbrut/templates/Base/README.md +4 -0
  457. data/mkbrut/templates/Base/README.md.erb +40 -0
  458. data/mkbrut/templates/Base/app/bootstrap.rb +61 -0
  459. data/mkbrut/templates/Base/app/config/i18n/en/1_defaults.rb +128 -0
  460. data/mkbrut/templates/Base/app/config/i18n/en/2_app.rb +24 -0
  461. data/mkbrut/templates/Base/app/public/static/manifest.json.erb +33 -0
  462. data/mkbrut/templates/Base/app/src/app.rb.erb +37 -0
  463. data/mkbrut/templates/Base/app/src/back_end/data_models/app_data_model.rb +5 -0
  464. data/mkbrut/templates/Base/app/src/back_end/data_models/db.rb +19 -0
  465. data/mkbrut/templates/Base/app/src/back_end/data_models/migrations/20240101130000_citext.rb +6 -0
  466. data/mkbrut/templates/Base/app/src/back_end/data_models/seed/seed_data.rb +9 -0
  467. data/mkbrut/templates/Base/app/src/front_end/components/app_component.rb +8 -0
  468. data/mkbrut/templates/Base/app/src/front_end/components/custom_element_registration.rb.erb +7 -0
  469. data/mkbrut/templates/Base/app/src/front_end/css/index.css +2 -0
  470. data/mkbrut/templates/Base/app/src/front_end/css/svgs.css +12 -0
  471. data/mkbrut/templates/Base/app/src/front_end/forms/app_form.rb +4 -0
  472. data/mkbrut/templates/Base/app/src/front_end/handlers/app_handler.rb +4 -0
  473. data/mkbrut/templates/Base/app/src/front_end/images/LogoPylon.png +0 -0
  474. data/mkbrut/templates/Base/app/src/front_end/images/LogoTransit.png +0 -0
  475. data/mkbrut/templates/Base/app/src/front_end/images/apple-touch-icon-120x120.png +0 -0
  476. data/mkbrut/templates/Base/app/src/front_end/images/apple-touch-icon-152x152.png +0 -0
  477. data/mkbrut/templates/Base/app/src/front_end/images/apple-touch-icon-167x167.png +0 -0
  478. data/mkbrut/templates/Base/app/src/front_end/images/apple-touch-icon-180x180.png +0 -0
  479. data/mkbrut/templates/Base/app/src/front_end/images/favicon.ico +0 -0
  480. data/mkbrut/templates/Base/app/src/front_end/images/icon.png +0 -0
  481. data/mkbrut/templates/Base/app/src/front_end/images/mkicons.sh +6 -0
  482. data/mkbrut/templates/Base/app/src/front_end/js/index.js +6 -0
  483. data/mkbrut/templates/Base/app/src/front_end/layouts/default_layout.rb.erb +73 -0
  484. data/mkbrut/templates/Base/app/src/front_end/pages/app_page.rb +11 -0
  485. data/mkbrut/templates/Base/app/src/front_end/pages/home_page.rb +62 -0
  486. data/mkbrut/templates/Base/app/src/front_end/support/app_session.rb +6 -0
  487. data/mkbrut/templates/Base/app/src/front_end/svgs/README.md +5 -0
  488. data/mkbrut/templates/Base/app/src/front_end/svgs/comment-button.svg +59 -0
  489. data/mkbrut/templates/Base/bin/README.md.erb +5 -0
  490. data/mkbrut/templates/Base/bin/build-assets +7 -0
  491. data/mkbrut/templates/Base/bin/ci +39 -0
  492. data/mkbrut/templates/Base/bin/console +31 -0
  493. data/mkbrut/templates/Base/bin/db +9 -0
  494. data/mkbrut/templates/Base/bin/dbconsole +51 -0
  495. data/mkbrut/templates/Base/bin/dev +25 -0
  496. data/mkbrut/templates/Base/bin/release +26 -0
  497. data/mkbrut/templates/Base/bin/run +86 -0
  498. data/mkbrut/templates/Base/bin/scaffold +9 -0
  499. data/mkbrut/templates/Base/bin/setup +256 -0
  500. data/mkbrut/templates/Base/bin/startup-message +65 -0
  501. data/mkbrut/templates/Base/bin/test +9 -0
  502. data/mkbrut/templates/Base/bin/test-server +29 -0
  503. data/mkbrut/templates/Base/bin/watch-and-build-assets +37 -0
  504. data/mkbrut/templates/Base/config.ru +16 -0
  505. data/mkbrut/templates/Base/docker-compose.dx.yml +92 -0
  506. data/mkbrut/templates/Base/dx/README.md +28 -0
  507. data/mkbrut/templates/Base/dx/bash_customizations +12 -0
  508. data/mkbrut/templates/Base/dx/bash_customizations.local +8 -0
  509. data/mkbrut/templates/Base/dx/build +107 -0
  510. data/mkbrut/templates/Base/dx/docker-compose.env.erb +25 -0
  511. data/mkbrut/templates/Base/dx/dx.sh.lib +137 -0
  512. data/mkbrut/templates/Base/dx/exec +68 -0
  513. data/mkbrut/templates/Base/dx/prune +19 -0
  514. data/mkbrut/templates/Base/dx/show-help-in-app-container-then-wait.sh +38 -0
  515. data/mkbrut/templates/Base/dx/start +30 -0
  516. data/mkbrut/templates/Base/dx/stop +23 -0
  517. data/mkbrut/templates/Base/package.json.erb +37 -0
  518. data/mkbrut/templates/Base/puma.config.rb +53 -0
  519. data/mkbrut/templates/Base/specs/e2e/home_page.spec.rb.erb +23 -0
  520. data/mkbrut/templates/Base/specs/front_end/js/SpecHelper.js +24 -0
  521. data/mkbrut/templates/Base/specs/front_end/pages/home_page.spec.rb +22 -0
  522. data/mkbrut/templates/Base/specs/lint_factories.spec.rb +7 -0
  523. data/mkbrut/templates/Base/specs/spec_helper.rb +78 -0
  524. data/mkbrut/templates/Base/specs/support.rb +2 -0
  525. data/mkbrut/templates/segments/BareBones/app/src/front_end/handlers/trigger_exception_handler.rb +24 -0
  526. data/mkbrut/templates/segments/BareBones/app/src/front_end/js/Example.js.erb +49 -0
  527. data/mkbrut/templates/segments/BareBones/specs/front_end/handlers/trigger_exception_handler.spec.rb +41 -0
  528. data/mkbrut/templates/segments/BareBones/specs/front_end/js/Example.spec.js.erb +38 -0
  529. data/mkbrut/templates/segments/Demo/app/src/back_end/data_models/db/guestbook_message.rb +3 -0
  530. data/mkbrut/templates/segments/Demo/app/src/back_end/data_models/migrations/20250628194124_guestbook.rb +14 -0
  531. data/mkbrut/templates/segments/Demo/app/src/front_end/components/flash_component.rb +36 -0
  532. data/mkbrut/templates/segments/Demo/app/src/front_end/css/constraint-violations.css +18 -0
  533. data/mkbrut/templates/segments/Demo/app/src/front_end/css/fonts.css +19 -0
  534. data/mkbrut/templates/segments/Demo/app/src/front_end/fonts/monaspace-xenon.ttf +0 -0
  535. data/mkbrut/templates/segments/Demo/app/src/front_end/forms/guestbook_message_form.rb +4 -0
  536. data/mkbrut/templates/segments/Demo/app/src/front_end/handlers/guestbook_message_handler.rb +64 -0
  537. data/mkbrut/templates/segments/Demo/app/src/front_end/pages/guestbook_page/message_component.rb +41 -0
  538. data/mkbrut/templates/segments/Demo/app/src/front_end/pages/guestbook_page.rb +43 -0
  539. data/mkbrut/templates/segments/Demo/app/src/front_end/pages/new_guestbook_message_page.rb +64 -0
  540. data/mkbrut/templates/segments/Demo/specs/back_end/data_models/db/guestbook_message.spec.rb +5 -0
  541. data/mkbrut/templates/segments/Demo/specs/e2e/guest_message.spec.rb +54 -0
  542. data/mkbrut/templates/segments/Demo/specs/factories/db/guestbook_message.factory.rb +7 -0
  543. data/mkbrut/templates/segments/Demo/specs/front_end/components/flash_component.spec.rb +5 -0
  544. data/mkbrut/templates/segments/Demo/specs/front_end/handlers/guestbook_message_handler.spec.rb +122 -0
  545. data/mkbrut/templates/segments/Demo/specs/front_end/pages/guestbook_page/message_component.spec.rb +5 -0
  546. data/mkbrut/templates/segments/Demo/specs/front_end/pages/guestbook_page.spec.rb +52 -0
  547. data/mkbrut/templates/segments/Demo/specs/front_end/pages/new_guestbook_message_page.spec.rb +5 -0
  548. data/mkbrut/templates/segments/Heroku/bin/deploy +11 -0
  549. data/mkbrut/templates/segments/Heroku/deploy/Dockerfile +125 -0
  550. data/mkbrut/templates/segments/Heroku/deploy/docker-entrypoint +15 -0
  551. data/mkbrut/templates/segments/Heroku/deploy/heroku_config.rb +26 -0
  552. data/specs/brut/junk_drawer.spec.rb +4 -0
  553. metadata +242 -41
  554. data/.rspec +0 -3
  555. data/docs/assets/chunks/@localSearchIndexroot.COP2Bcmp.js +0 -1
  556. data/docs/assets/overview.md.iMnwLO4x.js +0 -1
  557. data/docs/assets/overview.md.iMnwLO4x.lean.js +0 -1
  558. data/docs/assets/tutorial.md.BYXj4cOu.js +0 -1
  559. data/docs/assets/tutorial.md.BYXj4cOu.lean.js +0 -1
  560. /data/docs/assets/{components.md.iLiv2E9X.lean.js → components.md.-22ecBxM.lean.js} +0 -0
  561. /data/docs/assets/{configuration.md.DmuAdsli.lean.js → configuration.md.CLKL1lFf.lean.js} +0 -0
  562. /data/docs/assets/{database-schema.md.C5gXexJi.lean.js → database-schema.md.LpmBPVEU.lean.js} +0 -0
  563. /data/docs/assets/{forms.md.D8aa_qI-.lean.js → forms.md.CBI5--o2.lean.js} +0 -0
  564. /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: 6ddbdd2db5bb6ea9013486bc8ad279affec3d3a824d05ebbd8c4b4933a1c5468
4
- data.tar.gz: 823232c021e8c3d5477bc5655fefe6b51c54efcfcc73ca2ad0cab535964a23f1
3
+ metadata.gz: 1b2e311013cbdc55775be537b348e78a8c94d12842bff7fcdc09973f88be7eb9
4
+ data.tar.gz: 648599f601bbf5fa34ed21f7223b4cf82dcf1f12f58b7b60bdf28d5d56c191b2
5
5
  SHA512:
6
- metadata.gz: 152283ed984e5c7c8cd8faebdc5efbb24867efbe9a18a02a6896ab28654cc9b2b5fa39fe1ac9a13a6d477bd34ec3cb42a96034492d317f5355eb9e4434825395
7
- data.tar.gz: 52b69e78ad33ceb908bb6617960a33022f36df621b5d9f3da327a167600cd0c9dbc1902d90d86ec0bdfbef400fa3fded9261b4980feb2dd4264d5c87afb7535f
6
+ metadata.gz: 913cb4f1328ce98454004702f7e8ded76fcc18d44e090b6b96a50840b54519dcc1cde3f3746d9a772c2e33da8554d8485c28ccc35fd65ca98c154b6693c4ac07
7
+ data.tar.gz: c4ae0693b14b42f3ba58b10b83f6e98f6e300ddeafd40f89028f42eb1b2c534857d69de5917ff7a4234380fb2123815242ac7a2c805f1939f2f1cee033fa2744
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
@@ -38,3 +44,10 @@
38
44
 
39
45
  # Gems are installed here for LSP convienience
40
46
  /local-gems
47
+
48
+ # All I want in life is for every single instance of this file
49
+ # to be placed in hell, and waiting for Alan Dye when he arrives.
50
+ .DS_Store
51
+
52
+ # Don't want tmp checked in, but want to dump stuff there for sure
53
+ /tmp
data/CHANGELOG.md CHANGED
@@ -1,5 +1,19 @@
1
1
  # Brut CHANGELOG
2
2
 
3
+ ## v0.9.0 - Aug 7, 2025
4
+
5
+ * Added `Brut::FrontEnd::CsrfProtector` and the `csrf_protector` configuration option to allow some customization
6
+ over how CSRF protection works app-wide, namely to allow a POST to a webhook to not have to have an authenticity token.
7
+ I don't super love this solution, but it's unblocking me for now.
8
+
9
+ ## v0.8.0 - July 23, 2025
10
+
11
+ * Moved `mkbrut` into this repo
12
+ * Fixed issue where generated `dx/build` script would mess up `build.args`. See https://github.com/thirdtank/brut/issues/45
13
+ * Unify versioning for Brut, `mkbrut`, BrutJS, and BrutCSS
14
+ * Unify all workspace workflow scripts (see README.md)
15
+ * Minor doc updates to remove references to non-existent `form_tag`
16
+
3
17
  ## v0.5.0 - July 21, 2025
4
18
 
5
19
  * **New helper** `entity` for creating HTML entities without needing `raw(safe(...))`
data/Dockerfile.dx CHANGED
@@ -4,6 +4,25 @@ SHELL [ "/bin/bash", "-o", "pipefail", "-c" ]
4
4
 
5
5
  ENV DEBIAN_FRONTEND=noninteractive
6
6
 
7
+ # Install Docker itself. Note that this is installed only what is needed to run
8
+ # the Docker CLI - the docker-compose.dx.yml will connect this docker's socket
9
+ # to the one on the host. This is only to run stuff like docker build and docker push.
10
+ # It's NOT intended to run docker containers inside this one.
11
+ RUN install -m 0755 -d /etc/apt/keyrings && \
12
+ curl -fsSL https://download.docker.com/linux/debian/gpg | gpg --dearmor -o /etc/apt/keyrings/docker.gpg && \
13
+ chmod a+r /etc/apt/keyrings/docker.gpg && \
14
+ echo \
15
+ "deb [arch="$(dpkg --print-architecture)" signed-by=/etc/apt/keyrings/docker.gpg] https://download.docker.com/linux/debian \
16
+ "$(. /etc/os-release && echo "$VERSION_CODENAME")" stable" | \
17
+ tee /etc/apt/sources.list.d/docker.list > /dev/null && \
18
+ apt-get update --quiet --yes && \
19
+ apt-get install --quiet --yes docker-ce \
20
+ docker-ce-cli \
21
+ containerd.io \
22
+ docker-buildx-plugin \
23
+ docker-compose-plugin
24
+
25
+
7
26
  # These packages are needed to set up other repos to install other
8
27
  # packages and/or are useful in installing other software
9
28
  RUN apt-get -y clean && \
@@ -25,12 +44,19 @@ RUN apt-get install -y vim && \
25
44
  ARG user_uid=10001
26
45
  # Their group id, which ideally matches their group id on the host
27
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=
28
52
 
29
53
  # Create the user's group ID if it does not exist
30
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
31
57
  # Create the user. Note that we put bash_customizations in both .profile and .bashrc
32
58
  # to increase the chances they are used when running bash in various configurations
33
- 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 && \
34
60
  echo ". ~/.bash_customizations" >> /home/appuser/.profile && \
35
61
  echo ". ~/.bash_customizations.local" >> /home/appuser/.profile && \
36
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.5.0)
4
+ brut (0.9.0)
5
5
  concurrent-ruby
6
6
  i18n
7
7
  irb
@@ -36,6 +36,7 @@ GEM
36
36
  securerandom (>= 0.3)
37
37
  tzinfo (~> 2.0, >= 2.0.5)
38
38
  uri (>= 0.13.1)
39
+ ast (2.4.3)
39
40
  base64 (0.2.0)
40
41
  benchmark (0.4.0)
41
42
  bigdecimal (3.1.8)
@@ -76,6 +77,9 @@ GEM
76
77
  pp (>= 0.6.0)
77
78
  rdoc (>= 4.0.0)
78
79
  reline (>= 0.4.2)
80
+ json (2.13.0)
81
+ language_server-protocol (3.17.0.5)
82
+ lint_roller (1.1.0)
79
83
  logger (1.6.1)
80
84
  mini_portile2 (2.8.9)
81
85
  minitest (5.25.1)
@@ -114,6 +118,10 @@ GEM
114
118
  opentelemetry-semantic_conventions (1.10.1)
115
119
  opentelemetry-api (~> 1.0)
116
120
  ostruct (0.6.1)
121
+ parallel (1.27.0)
122
+ parser (3.3.8.0)
123
+ ast (~> 2.4.1)
124
+ racc
117
125
  phlex (2.2.1)
118
126
  zeitwerk (~> 2.7)
119
127
  pp (0.6.2)
@@ -132,10 +140,12 @@ GEM
132
140
  rack (>= 3.0.0)
133
141
  rackup (2.2.1)
134
142
  rack (>= 3)
143
+ rainbow (3.1.1)
135
144
  rake (13.2.1)
136
145
  rdiscount (2.2.7.3)
137
146
  rdoc (6.12.0)
138
147
  psych (>= 4.0.0)
148
+ regexp_parser (2.10.0)
139
149
  reline (0.6.0)
140
150
  io-console (~> 0.5)
141
151
  rspec (3.13.0)
@@ -151,6 +161,23 @@ GEM
151
161
  diff-lcs (>= 1.2.0, < 2.0)
152
162
  rspec-support (~> 3.13.0)
153
163
  rspec-support (3.13.1)
164
+ rubocop (1.74.0)
165
+ json (~> 2.3)
166
+ language_server-protocol (~> 3.17.0.2)
167
+ lint_roller (~> 1.1.0)
168
+ parallel (~> 1.10)
169
+ parser (>= 3.3.0.2)
170
+ rainbow (>= 2.2.2, < 4.0)
171
+ regexp_parser (>= 2.9.3, < 3.0)
172
+ rubocop-ast (>= 1.38.0, < 2.0)
173
+ ruby-progressbar (~> 1.7)
174
+ unicode-display_width (>= 2.4.0, < 4.0)
175
+ rubocop-ast (1.42.0)
176
+ parser (>= 3.3.7.2)
177
+ rubocop-disable_syntax (0.2.0)
178
+ lint_roller
179
+ rubocop (>= 1.72.0)
180
+ ruby-progressbar (1.13.0)
154
181
  ruby2_keywords (0.0.5)
155
182
  securerandom (0.3.2)
156
183
  semantic_logger (4.16.1)
@@ -169,6 +196,9 @@ GEM
169
196
  concurrent-ruby (~> 1.0)
170
197
  tzinfo-data (1.2024.2)
171
198
  tzinfo (>= 1.0.0)
199
+ unicode-display_width (3.1.4)
200
+ unicode-emoji (~> 4.0, >= 4.0.4)
201
+ unicode-emoji (4.0.4)
172
202
  uri (1.0.2)
173
203
  yard (0.9.37)
174
204
  zeitwerk (2.7.1)
@@ -192,6 +222,8 @@ DEPENDENCIES
192
222
  rdiscount
193
223
  rdoc
194
224
  rspec (~> 3.0)
225
+ rubocop
226
+ rubocop-disable_syntax
195
227
  yard
196
228
 
197
229
  BUNDLED WITH
data/README.md CHANGED
@@ -69,3 +69,22 @@ with your editor, but all commands are run inside Docker, which should be more c
69
69
 
70
70
  The `--no-credentials` means that you will not be able to push to GitHub or RubyGems from within the Docker container. This ability is only needed by maintainers to push new versions of the gem. You can push to GitHub from your computer.
71
71
 
72
+ ### Conventions in MonoRepo
73
+
74
+ This repo contains all five main parts of Brut:
75
+
76
+ * BrutRB, the Ruby web framework (in this directory, code in `lib`)
77
+ * BrutJS, the JS library with custom elements (in `brut-js/`)
78
+ * BrutCSS, the CSS library (in `brut-css/`)
79
+ * `mkbrut`, the CLI to create new Brut apps (in `mkbrut/`)
80
+ * `brutrb.com`, the website, powered by VitePress (in `brutrb.com`)
81
+
82
+ Each repo must conform to the *Workspace Protocol*, which are scripts in `bin/` that perform certain tasks:
83
+
84
+ * `bin/setup` - performs any setup
85
+ * `bin/docs` - builds all documentation, placing it where `brutrb.com` can find it.
86
+ * `bin/build` - builds deployable artifacts, if needed
87
+ * `bin/ci` - runs all tests, if applicable
88
+
89
+ The primary `bin` scripts at the root work for both BrutRB, the web framework, and recurse into the other directories to perform their
90
+ actions as well.
Binary file
data/bin/build ADDED
@@ -0,0 +1,86 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require "optparse"
4
+ require "pathname"
5
+ require "fileutils"
6
+ require "json"
7
+ require_relative "bin_kit"
8
+
9
+ def main
10
+
11
+ brutjs_dir = (Pathname(__FILE__).dirname / ".." / "brut-js" ).expand_path.to_s
12
+ brutcss_dir = (Pathname(__FILE__).dirname / ".." / "brut-css" ).expand_path.to_s
13
+ mkbrut_dir = (Pathname(__FILE__).dirname / ".." / "mkbrut" ).expand_path.to_s
14
+
15
+ require_relative "../lib/brut/version"
16
+ require_relative "#{mkbrut_dir}/lib/mkbrut/version"
17
+
18
+ brut_js_package_json = JSON.parse(File.read("#{brutjs_dir}/package.json"))
19
+ brut_css_package_json = JSON.parse(File.read("#{brutcss_dir}/package.json"))
20
+
21
+ brut_version = Brut::VERSION.strip
22
+ brut_js_version = brut_js_package_json["version"].strip
23
+ brut_css_version = brut_css_package_json["version"].strip
24
+ mkbrut_version = MKBrut::VERSION.strip
25
+
26
+ if [ brut_version, brut_js_version, brut_css_version, mkbrut_version ].uniq.size != 1
27
+ log "Some versions are mismatched! All versions should be the same to build and release"
28
+ puts
29
+ log sprintf("BrutRb: %10s from lib/brut/version.rb", brut_version)
30
+ log sprintf("BrutJS: %10s from brut-js/package.json", brut_js_version)
31
+ log sprintf("BrutCSS: %10s from brut-css/package.json", brut_css_version)
32
+ log sprintf("mkbrut: %10s from mkbrut/lib/mkbrut/version.rb", mkbrut_version)
33
+ exit 1
34
+ else
35
+ log "Building v#{brut_version} of all artifacts"
36
+ end
37
+
38
+ log "Building brut gem"
39
+ system!("bin/rake build")
40
+
41
+ log "Building brut-js"
42
+ FileUtils.chdir brutjs_dir do
43
+ system!("bin/build")
44
+ end
45
+
46
+ log "Building brut-css"
47
+ FileUtils.chdir brutcss_dir do
48
+ system!("bin/build")
49
+ end
50
+
51
+ log "Building mkbrut"
52
+ FileUtils.chdir mkbrut_dir do
53
+ system!("bin/build")
54
+ end
55
+ end
56
+
57
+ options = {
58
+ repo_check: true,
59
+ }
60
+ OptionParser.new do |opts|
61
+ opts.banner = "Usage: build [options]\n\n Builds deployable artifacts\n\nOPTIONS"
62
+
63
+ opts.on("-h", "--help", "Display this help message") do
64
+ puts opts
65
+ exit
66
+ end
67
+ opts.on("--skip-repo-check", "If set, allows you to proceed without a clean Git repo. Note that this may cause gems not to build properly") do
68
+ options[:repo_check] = false
69
+ end
70
+ end.parse!
71
+
72
+ def require_clean_repo!
73
+ out, err = capture!("git status --porcelain")
74
+ if out.to_s.strip != ""
75
+ log out
76
+ log err
77
+ log "Your git repository is not clean. Please commit or stash your changes before running this script."
78
+ exit 1
79
+ end
80
+ end
81
+
82
+ if options[:repo_check]
83
+ require_clean_repo!
84
+ end
85
+ main
86
+
data/bin/ci ADDED
@@ -0,0 +1,40 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require "optparse"
4
+ require "pathname"
5
+ require "fileutils"
6
+ require_relative "bin_kit"
7
+
8
+ OptionParser.new do |opts|
9
+ opts.banner = "Usage: ci [options]\n\n Runs all tests/QA in all repos\n\nOPTIONS\n\n"
10
+
11
+ opts.on("-h", "--help", "Display this help message") do
12
+ puts opts
13
+ puts
14
+ exit
15
+ end
16
+ end.parse!
17
+
18
+ brutjs_dir = (Pathname(__FILE__).dirname / ".." / "brut-js" ).expand_path.to_s
19
+ brutcss_dir = (Pathname(__FILE__).dirname / ".." / "brut-css" ).expand_path.to_s
20
+ mkbrut_dir = (Pathname(__FILE__).dirname / ".." / "mkbrut" ).expand_path.to_s
21
+
22
+ log "Running BrutRB tests"
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")
32
+
33
+ log "Running brut-js tests"
34
+ FileUtils.chdir brutjs_dir do
35
+ system!("bin/ci")
36
+ end
37
+ log "Running brut-css tests"
38
+ FileUtils.chdir brutcss_dir do
39
+ system!("bin/ci")
40
+ end
data/bin/docs CHANGED
@@ -3,29 +3,41 @@
3
3
  require "optparse"
4
4
  require "pathname"
5
5
  require "fileutils"
6
+ require_relative "bin_kit"
7
+
8
+ options = {
9
+ dotcom: true,
10
+ }
6
11
 
7
- options = {}
8
12
  OptionParser.new do |opts|
9
- opts.banner = "Usage: docs [options]"
13
+ opts.banner = "Usage: docs [options]\n\n Generates all documentation for the project\n\nOPTIONS\n\n"
10
14
 
11
15
  opts.on("-h", "--help", "Display this help message") do
12
16
  puts opts
17
+ puts
13
18
  exit
14
19
  end
20
+ opts.on("--[no-]dotcom", "Deploy (or not), brutrb.com to the docs/ directory (default #{options[:dotcom]})") do |value|
21
+ options[:dotcom] = value
22
+ end
15
23
  end.parse!
16
24
 
17
- public_dir = (Pathname(__FILE__).dirname / ".." / "brutrb.com" / "public" ).expand_path
18
- docs_dir = public_dir / "api"
19
- brutjs_dir = (Pathname(__FILE__).dirname / ".." / "brut-js" ).expand_path.to_s
25
+ dotcom_dir = (Pathname(__FILE__).dirname / ".." / "brutrb.com" ).expand_path
26
+ public_dir = (dotcom_dir / "public" ).expand_path
27
+ docs_dir = public_dir / "api"
28
+ brutjs_dir = (Pathname(__FILE__).dirname / ".." / "brut-js" ).expand_path.to_s
29
+ brutcss_dir = (Pathname(__FILE__).dirname / ".." / "brut-css" ).expand_path.to_s
30
+ mkbrut_dir = (Pathname(__FILE__).dirname / ".." / "mkbrut" ).expand_path.to_s
20
31
 
21
- system(
22
- "bundle exec yard doc -o '#{docs_dir}' -m markdown -M rdiscount --backtrace"
32
+ system!(
33
+ "bundle exec yard doc -o '#{docs_dir}' --no-progress -m markdown -M rdiscount --backtrace",
23
34
  )
24
35
 
25
- puts "Hacking CSS"
36
+ log "Hacking CSS"
37
+
26
38
  [
27
39
  docs_dir / "css" / "style.css",
28
- docs_dir / "css" / "full_list.css"
40
+ docs_dir / "css" / "full_list.css",
29
41
  ].each do |css_file_to_hack|
30
42
  lines = File.read(css_file_to_hack).split(/\n/)
31
43
  File.open(css_file_to_hack, "w") do |f|
@@ -44,6 +56,24 @@ puts "Hacking CSS"
44
56
  end
45
57
  end
46
58
 
59
+ log "Generating brut-js docs"
47
60
  FileUtils.chdir brutjs_dir do
48
- system("bin/build")
61
+ system!("bin/docs")
62
+ end
63
+ log "Generating brut-css docs"
64
+ FileUtils.chdir brutcss_dir do
65
+ system!("bin/docs")
66
+ end
67
+ log "Generating mkbrut docs"
68
+ FileUtils.chdir mkbrut_dir do
69
+ system!("bin/docs")
70
+ end
71
+
72
+ if options[:dotcom]
73
+ log "Deploying brutrb.com to docs/"
74
+ FileUtils.chdir dotcom_dir do
75
+ system!("bin/deploy")
76
+ end
77
+ else
78
+ log "Skipping brutrb.com deployment"
49
79
  end
@@ -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/publish ADDED
@@ -0,0 +1,61 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require "optparse"
4
+ require "pathname"
5
+ require "fileutils"
6
+ require "json"
7
+ require_relative "bin_kit"
8
+
9
+ def main
10
+
11
+ log "Building artifacts"
12
+ system!("bin/build")
13
+
14
+ brutjs_dir = (Pathname(__FILE__).dirname / ".." / "brut-js" ).expand_path.to_s
15
+ brutcss_dir = (Pathname(__FILE__).dirname / ".." / "brut-css" ).expand_path.to_s
16
+ mkbrut_dir = (Pathname(__FILE__).dirname / ".." / "mkbrut" ).expand_path.to_s
17
+
18
+ log "Pushing brut"
19
+ system!("bin/rake release")
20
+
21
+ log "Pushing brujt-js"
22
+ FileUtils.chdir brutjs_dir do
23
+ system!("bin/publish")
24
+ end
25
+
26
+ log "Pushing brut-css"
27
+ FileUtils.chdir brutcss_dir do
28
+ system!("bin/publish")
29
+ end
30
+
31
+ log "Building mkbrut"
32
+ FileUtils.chdir mkbrut_dir do
33
+ system!("bin/publish")
34
+ end
35
+ end
36
+
37
+ options = {
38
+ repo_check: true,
39
+ }
40
+ OptionParser.new do |opts|
41
+ opts.banner = "Usage: publish [options]\n\n Builds and publishes all artifacts\n\nOPTIONS"
42
+
43
+ opts.on("-h", "--help", "Display this help message") do
44
+ puts opts
45
+ exit
46
+ end
47
+ end.parse!
48
+
49
+ def require_clean_repo!
50
+ out, err = capture!("git status --porcelain")
51
+ if out.to_s.strip != ""
52
+ log out
53
+ log err
54
+ log "Your git repository is not clean. Please commit or stash your changes before running this script."
55
+ exit 1
56
+ end
57
+ end
58
+
59
+ require_clean_repo!
60
+ main
61
+
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"
@@ -174,10 +220,16 @@ def setup(update_gems:,setup_credentials:)
174
220
  system! "bin/setup"
175
221
  end
176
222
 
223
+ log "Setting up mkbrut"
224
+ FileUtils.chdir project_root / "mkbrut" do
225
+ system! "bin/setup"
226
+ end
227
+
177
228
  log "Setting up brutrb.com"
178
229
  FileUtils.chdir project_root / "brutrb.com" do
179
230
  system! "bin/setup"
180
231
  end
232
+
181
233
  else
182
234
  log "Not setting up GitHub or RubyGems credentials. You won't be able to push the gem"
183
235
  end
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
+