brut 0.16.0 → 0.18.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/exe/brut +34 -0
- data/lib/brut/cli/apps/build_assets.rb +78 -48
- data/lib/brut/cli/apps/db.rb +168 -202
- data/lib/brut/cli/apps/deploy.rb +291 -0
- data/lib/brut/cli/apps/heroku_container_based_deploy.rb +7 -1
- data/{mkbrut/lib/mkbrut → lib/brut/cli/apps/new}/add_segment.rb +5 -5
- data/{mkbrut/lib/mkbrut → lib/brut/cli/apps/new}/add_segment_options.rb +1 -1
- data/lib/brut/cli/apps/new/app.rb +240 -0
- data/{mkbrut/lib/mkbrut → lib/brut/cli/apps/new}/app_id.rb +1 -1
- data/lib/brut/cli/apps/new/app_name.rb +29 -0
- data/{mkbrut/lib/mkbrut → lib/brut/cli/apps/new}/base.rb +9 -6
- data/lib/brut/cli/apps/new/erb_binding_delegate.rb +23 -0
- data/{mkbrut/lib/mkbrut → lib/brut/cli/apps/new}/internet_identifier.rb +5 -5
- data/{mkbrut/lib/mkbrut → lib/brut/cli/apps/new}/invalid_identifier.rb +1 -1
- data/{mkbrut/lib/mkbrut/app.rb → lib/brut/cli/apps/new/old_app.rb} +8 -11
- data/{mkbrut/lib/mkbrut → lib/brut/cli/apps/new}/ops/add_css_import.rb +1 -1
- data/{mkbrut/lib/mkbrut → lib/brut/cli/apps/new}/ops/add_i18n_message.rb +1 -1
- data/{mkbrut/lib/mkbrut → lib/brut/cli/apps/new}/ops/add_method.rb +1 -1
- data/{mkbrut/lib/mkbrut → lib/brut/cli/apps/new}/ops/append_to_file.rb +1 -1
- data/{mkbrut/lib/mkbrut → lib/brut/cli/apps/new}/ops/base_op.rb +3 -3
- data/{mkbrut/lib/mkbrut → lib/brut/cli/apps/new}/ops/copy_file.rb +1 -1
- data/{mkbrut/lib/mkbrut → lib/brut/cli/apps/new}/ops/insert_code_in_method.rb +1 -1
- data/{mkbrut/lib/mkbrut → lib/brut/cli/apps/new}/ops/insert_into_file.rb +1 -1
- data/{mkbrut/lib/mkbrut → lib/brut/cli/apps/new}/ops/insert_route.rb +1 -1
- data/{mkbrut/lib/mkbrut → lib/brut/cli/apps/new}/ops/mkdir.rb +1 -1
- data/{mkbrut/lib/mkbrut → lib/brut/cli/apps/new}/ops/prism_parsing_op.rb +1 -1
- data/{mkbrut/lib/mkbrut → lib/brut/cli/apps/new}/ops/render_template.rb +1 -1
- data/{mkbrut/lib/mkbrut → lib/brut/cli/apps/new}/ops/skip_file.rb +1 -1
- data/lib/brut/cli/apps/new/ops.rb +17 -0
- data/lib/brut/cli/apps/new/organization.rb +5 -0
- data/{mkbrut/lib/mkbrut → lib/brut/cli/apps/new}/prefix.rb +1 -1
- data/{mkbrut/lib/mkbrut → lib/brut/cli/apps/new}/segments/bare_bones.rb +12 -11
- data/{mkbrut/lib/mkbrut → lib/brut/cli/apps/new}/segments/demo.rb +16 -15
- data/{mkbrut/lib/mkbrut → lib/brut/cli/apps/new}/segments/heroku.rb +9 -5
- data/{mkbrut/lib/mkbrut → lib/brut/cli/apps/new}/segments/sidekiq.rb +44 -21
- data/lib/brut/cli/apps/new/segments.rb +8 -0
- data/lib/brut/cli/apps/new/version.rb +3 -0
- data/{mkbrut/lib/mkbrut → lib/brut/cli/apps/new}/versions.rb +2 -2
- data/lib/brut/cli/apps/new.rb +26 -0
- data/lib/brut/cli/apps/scaffold.rb +150 -141
- data/lib/brut/cli/apps/test.rb +95 -69
- data/lib/brut/cli/commands/base_command.rb +174 -0
- data/lib/brut/cli/commands/compound_command.rb +29 -0
- data/lib/brut/cli/commands/execution_context.rb +32 -0
- data/lib/brut/cli/commands/help.rb +26 -0
- data/lib/brut/cli/commands/output_error.rb +13 -0
- data/lib/brut/cli/commands/raise_error.rb +11 -0
- data/lib/brut/cli/commands.rb +8 -0
- data/lib/brut/cli/execute_result.rb +39 -0
- data/lib/brut/cli/executor.rb +9 -4
- data/lib/brut/cli/output.rb +13 -0
- data/lib/brut/cli/parsed_command_line.rb +143 -0
- data/lib/brut/cli/runner.rb +124 -0
- data/lib/brut/cli.rb +7 -29
- data/lib/brut/framework/container.rb +1 -1
- data/lib/brut/framework/mcp.rb +59 -13
- data/lib/brut/framework/project_environment.rb +3 -1
- data/lib/brut/junk_drawer.rb +3 -1
- data/lib/brut/spec_support/cli_command_support.rb +45 -0
- data/lib/brut/spec_support/e2e_test_server.rb +3 -0
- data/lib/brut/spec_support/general_support.rb +1 -1
- data/lib/brut/spec_support/matchers/have_executed.rb +35 -0
- data/lib/brut/spec_support/rspec_setup.rb +4 -8
- data/lib/brut/spec_support.rb +1 -0
- data/lib/brut/tui/ansi_escape_code.rb +104 -0
- data/lib/brut/tui/event_loop.rb +168 -0
- data/lib/brut/tui/events/base_event.rb +29 -0
- data/lib/brut/tui/events/event_bus.rb +73 -0
- data/lib/brut/tui/events/event_loop_started.rb +5 -0
- data/lib/brut/tui/events/exception.rb +24 -0
- data/lib/brut/tui/events/tick.rb +12 -0
- data/lib/brut/tui/events.rb +7 -0
- data/lib/brut/tui/markup_string.rb +70 -0
- data/lib/brut/tui/script/block_step.rb +17 -0
- data/lib/brut/tui/script/events/command_execution_failed.rb +4 -0
- data/lib/brut/tui/script/events/command_execution_succeeded.rb +3 -0
- data/lib/brut/tui/script/events/command_std_err.rb +3 -0
- data/lib/brut/tui/script/events/command_std_out.rb +14 -0
- data/lib/brut/tui/script/events/executing_command.rb +12 -0
- data/lib/brut/tui/script/events/message.rb +15 -0
- data/lib/brut/tui/script/events/phase_completed.rb +4 -0
- data/lib/brut/tui/script/events/phase_started.rb +14 -0
- data/lib/brut/tui/script/events/script_completed.rb +5 -0
- data/lib/brut/tui/script/events/script_started.rb +12 -0
- data/lib/brut/tui/script/events/step_completed.rb +3 -0
- data/lib/brut/tui/script/events/step_started.rb +12 -0
- data/lib/brut/tui/script/events.rb +14 -0
- data/lib/brut/tui/script/exec_step.rb +67 -0
- data/lib/brut/tui/script/logging_subscriber.rb +98 -0
- data/lib/brut/tui/script/puts_subscriber.rb +109 -0
- data/lib/brut/tui/script/step.rb +13 -0
- data/lib/brut/tui/script.rb +215 -0
- data/lib/brut/tui/terminal.rb +74 -0
- data/lib/brut/tui/terminal_theme.rb +144 -0
- data/lib/brut/tui/themes/dark.rb +14 -0
- data/lib/brut/tui/themes/light.rb +17 -0
- data/lib/brut/tui/themes/none.rb +9 -0
- data/lib/brut/tui/themes.rb +5 -0
- data/lib/brut/tui.rb +15 -0
- data/lib/brut/version.rb +1 -1
- data/lib/brut.rb +1 -0
- data/templates/Base/.env.development.local +2 -0
- data/templates/Base/bin/ci +42 -0
- data/{mkbrut/templates → templates}/Base/bin/release +2 -2
- data/templates/Base/bin/setup +174 -0
- data/{mkbrut/templates → templates}/Base/bin/watch-and-build-assets +1 -1
- data/{mkbrut/templates → templates}/Base/dx/docker-compose.env.erb +1 -1
- data/{mkbrut/templates → templates}/segments/Demo/app/src/front_end/css/fonts.css +1 -1
- data/{mkbrut/templates → templates}/segments/Heroku/deploy/Dockerfile +2 -2
- data/templates/segments/Heroku/deploy/docker_config.rb +30 -0
- metadata +254 -1009
- data/.gitignore +0 -55
- data/.projections.json +0 -10
- data/CHANGELOG.md +0 -167
- data/CODE_OF_CONDUCT.txt +0 -99
- data/Dockerfile.dx +0 -82
- data/Gemfile +0 -6
- data/Gemfile.lock +0 -243
- data/LICENSE.txt +0 -370
- data/README.md +0 -90
- data/Rakefile +0 -25
- data/assets/Logo-Square.pxd +0 -0
- data/assets/LogoPylon.pxd +0 -0
- data/assets/LogoStop.pxd +0 -0
- data/assets/LogoTall.pxd +0 -0
- data/assets/MetroIcon.graffle +0 -0
- data/assets/MetroLogo.graffle +0 -0
- data/assets/SocialImage.png +0 -0
- data/assets/SocialImage.pxd +0 -0
- data/assets/YouTubeThumb.pxd +0 -0
- data/bin/bin_kit.rb +0 -51
- data/bin/build +0 -86
- data/bin/ci +0 -40
- data/bin/dev +0 -20
- data/bin/docs +0 -79
- data/bin/generate-and-run-rubocop +0 -52
- data/bin/new-version +0 -8
- data/bin/publish +0 -61
- data/bin/rake +0 -27
- data/bin/rspec +0 -27
- data/bin/rubocop +0 -27
- data/bin/setup +0 -252
- data/bin/test +0 -18
- data/brut-css/.nvim.lua +0 -1
- data/brut-css/README.md +0 -28
- data/brut-css/bin/build +0 -50
- data/brut-css/bin/ci +0 -19
- data/brut-css/bin/dev +0 -1
- data/brut-css/bin/docs +0 -34
- data/brut-css/bin/publish +0 -21
- data/brut-css/bin/setup +0 -6
- data/brut-css/config/media-queries-all.css +0 -15
- data/brut-css/config/media-queries-minimal.css +0 -5
- data/brut-css/config/postcss.config.cjs +0 -7
- data/brut-css/config/pseudo-classes-all.css +0 -9
- data/brut-css/dx +0 -1
- data/brut-css/package-lock.json +0 -3165
- data/brut-css/package.json +0 -36
- data/brut-css/src/css/appearance.css +0 -145
- data/brut-css/src/css/border.css +0 -522
- data/brut-css/src/css/colors.css +0 -3502
- data/brut-css/src/css/dimensions.css +0 -548
- data/brut-css/src/css/flex.css +0 -179
- data/brut-css/src/css/index.css +0 -13
- data/brut-css/src/css/layout.css +0 -120
- data/brut-css/src/css/list.css +0 -41
- data/brut-css/src/css/positioning.css +0 -354
- data/brut-css/src/css/properties/colors.css +0 -455
- data/brut-css/src/css/properties/index.css +0 -3
- data/brut-css/src/css/properties/spacing.css +0 -140
- data/brut-css/src/css/properties/typography.css +0 -224
- data/brut-css/src/css/reset.css +0 -107
- data/brut-css/src/css/spacing.css +0 -585
- data/brut-css/src/css/typography.css +0 -519
- data/brut-css/src/css/utils.css +0 -104
- data/brut-css/src/docs/1_getting-started/1_overview.md +0 -46
- data/brut-css/src/docs/1_getting-started/2_installation.md +0 -25
- data/brut-css/src/docs/1_getting-started/3_core-concepts.md +0 -75
- data/brut-css/src/docs/1_getting-started/4_simple-example.md +0 -132
- data/brut-css/src/docs/1_getting-started/page.html.ejs +0 -10
- data/brut-css/src/docs/2_properties/page.html.ejs +0 -71
- data/brut-css/src/docs/3_classes/color-demo.html.ejs +0 -31
- data/brut-css/src/docs/3_classes/page.html.ejs +0 -87
- data/brut-css/src/docs/4_customization/1_design-system.md +0 -36
- data/brut-css/src/docs/4_customization/2_breakpoints.md +0 -75
- data/brut-css/src/docs/4_customization/3_pseudo-classes.md +0 -74
- data/brut-css/src/docs/4_customization/4_advanced-configuration.md +0 -40
- data/brut-css/src/docs/4_customization/page.html.ejs +0 -10
- data/brut-css/src/docs/docs.css +0 -98
- data/brut-css/src/docs/includes/body-and-header.html.ejs +0 -30
- data/brut-css/src/docs/includes/footer-and-rest.html.ejs +0 -9
- data/brut-css/src/docs/includes/head.html.ejs +0 -5
- data/brut-css/src/docs/includes/nav.html.ejs +0 -10
- data/brut-css/src/docs/index.html.ejs +0 -32
- data/brut-css/src/docs/prism-twilight.min.css +0 -1
- data/brut-css/src/js/Logger.js +0 -71
- data/brut-css/src/js/build.js +0 -111
- data/brut-css/src/js/cli/CLIArgError.js +0 -7
- data/brut-css/src/js/cli/Debug.js +0 -27
- data/brut-css/src/js/cli/DocsDir.js +0 -16
- data/brut-css/src/js/cli/DocsTemplateSourceDir.js +0 -16
- data/brut-css/src/js/cli/InputFile.js +0 -31
- data/brut-css/src/js/cli/MediaQueryConfigFile.js +0 -10
- data/brut-css/src/js/cli/OutputFile.js +0 -22
- data/brut-css/src/js/cli/ParsedArg.js +0 -17
- data/brut-css/src/js/cli/PathToBrutCSSRoot.js +0 -19
- data/brut-css/src/js/cli/PseudoClassConfigFile.js +0 -11
- data/brut-css/src/js/cli.js +0 -108
- data/brut-css/src/js/docGenerator.js +0 -467
- data/brut-css/src/js/mediaQueryConfigParser.js +0 -98
- data/brut-css/src/js/post-css-plugins/addMediaQueriesPlugin.js +0 -49
- data/brut-css/src/js/post-css-plugins/addPseudoClassesPlugin.js +0 -42
- data/brut-css/src/js/post-css-plugins/generateDocumentationPlugin/Category.js +0 -9
- data/brut-css/src/js/post-css-plugins/generateDocumentationPlugin/DocState.js +0 -185
- data/brut-css/src/js/post-css-plugins/generateDocumentationPlugin/Documentable.js +0 -8
- data/brut-css/src/js/post-css-plugins/generateDocumentationPlugin/Group.js +0 -7
- data/brut-css/src/js/post-css-plugins/generateDocumentationPlugin/ParsedComment.js +0 -73
- data/brut-css/src/js/post-css-plugins/generateDocumentationPlugin/Property.js +0 -9
- data/brut-css/src/js/post-css-plugins/generateDocumentationPlugin/PropertyCategory.js +0 -4
- data/brut-css/src/js/post-css-plugins/generateDocumentationPlugin/PropertyGroup.js +0 -8
- data/brut-css/src/js/post-css-plugins/generateDocumentationPlugin/Rule.js +0 -12
- data/brut-css/src/js/post-css-plugins/generateDocumentationPlugin/RuleCategory.js +0 -4
- data/brut-css/src/js/post-css-plugins/generateDocumentationPlugin/RuleGroup.js +0 -8
- data/brut-css/src/js/post-css-plugins/generateDocumentationPlugin/SeeRef.js +0 -5
- data/brut-css/src/js/post-css-plugins/generateDocumentationPlugin/SeeURL.js +0 -9
- data/brut-css/src/js/post-css-plugins/generateDocumentationPlugin.js +0 -49
- data/brut-css/src/js/post-css-plugins/generateRootCustomPropertiesPlugin.js +0 -45
- data/brut-css/src/js/pseudoClassConfigParser.js +0 -145
- data/brut-js/.projections.json +0 -10
- data/brut-js/README.md +0 -118
- data/brut-js/bin/build +0 -19
- data/brut-js/bin/ci +0 -5
- data/brut-js/bin/docs +0 -25
- data/brut-js/bin/publish +0 -21
- data/brut-js/bin/setup +0 -6
- data/brut-js/docs/README.md +0 -8
- data/brut-js/docs/jsdoc-plugins/customElementTag.js +0 -8
- data/brut-js/docs/jsdoc-theme/publish.js +0 -692
- data/brut-js/docs/jsdoc-theme/static/scripts/linenumber.js +0 -25
- data/brut-js/docs/jsdoc-theme/static/scripts/prettify/Apache-License-2.0.txt +0 -202
- data/brut-js/docs/jsdoc-theme/static/scripts/prettify/lang-css.js +0 -2
- data/brut-js/docs/jsdoc-theme/static/scripts/prettify/prettify.js +0 -28
- data/brut-js/docs/jsdoc-theme/static/styles/jsdoc-default.css +0 -327
- data/brut-js/docs/jsdoc-theme/static/styles/prettify-jsdoc.css +0 -111
- data/brut-js/docs/jsdoc-theme/static/styles/prettify-tomorrow.css +0 -132
- data/brut-js/docs/jsdoc-theme/tmpl/augments.tmpl +0 -10
- data/brut-js/docs/jsdoc-theme/tmpl/container.tmpl +0 -199
- data/brut-js/docs/jsdoc-theme/tmpl/details.tmpl +0 -143
- data/brut-js/docs/jsdoc-theme/tmpl/example.tmpl +0 -2
- data/brut-js/docs/jsdoc-theme/tmpl/examples.tmpl +0 -13
- data/brut-js/docs/jsdoc-theme/tmpl/exceptions.tmpl +0 -32
- data/brut-js/docs/jsdoc-theme/tmpl/layout.tmpl +0 -38
- data/brut-js/docs/jsdoc-theme/tmpl/mainpage.tmpl +0 -14
- data/brut-js/docs/jsdoc-theme/tmpl/members.tmpl +0 -38
- data/brut-js/docs/jsdoc-theme/tmpl/method.tmpl +0 -131
- data/brut-js/docs/jsdoc-theme/tmpl/modifies.tmpl +0 -14
- data/brut-js/docs/jsdoc-theme/tmpl/params.tmpl +0 -131
- data/brut-js/docs/jsdoc-theme/tmpl/properties.tmpl +0 -108
- data/brut-js/docs/jsdoc-theme/tmpl/returns.tmpl +0 -19
- data/brut-js/docs/jsdoc-theme/tmpl/source.tmpl +0 -8
- data/brut-js/docs/jsdoc-theme/tmpl/tutorial.tmpl +0 -19
- data/brut-js/docs/jsdoc-theme/tmpl/type.tmpl +0 -7
- data/brut-js/docs/jsdoc.config.json +0 -23
- data/brut-js/docs/package-lock.json +0 -343
- data/brut-js/docs/package.json +0 -7
- data/brut-js/dx +0 -1
- data/brut-js/package-lock.json +0 -2210
- data/brut-js/package.json +0 -36
- data/brut-js/specs/AjaxSubmit.spec.js +0 -453
- data/brut-js/specs/Autosubmit.spec.js +0 -127
- data/brut-js/specs/ConfirmSubmit.spec.js +0 -224
- data/brut-js/specs/ConstraintViolationMessage.spec.js +0 -33
- data/brut-js/specs/ConstraintViolationMessages.spec.js +0 -32
- data/brut-js/specs/CopyToClipboard.spec.js +0 -35
- data/brut-js/specs/Form.spec.js +0 -137
- data/brut-js/specs/I18nTranslation.spec.js +0 -19
- data/brut-js/specs/LocaleDetection.spec.js +0 -22
- data/brut-js/specs/Message.spec.js +0 -15
- data/brut-js/specs/SpecHelper.js +0 -23
- data/brut-js/specs/Tabs.spec.js +0 -41
- data/brut-js/specs/Toast.spec.js +0 -34
- data/brut-js/specs/config/asset_metadata.json +0 -7
- data/brut-js/src/AjaxSubmit.js +0 -499
- data/brut-js/src/Autosubmit.js +0 -63
- data/brut-js/src/BaseCustomElement.js +0 -261
- data/brut-js/src/ConfirmSubmit.js +0 -137
- data/brut-js/src/ConfirmationDialog.js +0 -143
- data/brut-js/src/ConstraintViolationMessage.js +0 -140
- data/brut-js/src/ConstraintViolationMessages.js +0 -98
- data/brut-js/src/CopyToClipboard.js +0 -96
- data/brut-js/src/Form.js +0 -147
- data/brut-js/src/I18nTranslation.js +0 -64
- data/brut-js/src/LocaleDetection.js +0 -117
- data/brut-js/src/Logger.js +0 -90
- data/brut-js/src/Message.js +0 -62
- data/brut-js/src/RichString.js +0 -116
- data/brut-js/src/Tabs.js +0 -168
- data/brut-js/src/Toast.js +0 -102
- data/brut-js/src/Tracing.js +0 -247
- data/brut-js/src/appForTestingOnly.js +0 -15
- data/brut-js/src/index.js +0 -133
- data/brut-js/src/testing/AssetMetadata.js +0 -35
- data/brut-js/src/testing/AssetMetadataLoader.js +0 -25
- data/brut-js/src/testing/CustomElementTest.js +0 -235
- data/brut-js/src/testing/DOMCreator.js +0 -45
- data/brut-js/src/testing/index.js +0 -48
- data/brut.gemspec +0 -71
- data/brutrb.com/.vitepress/config.mjs +0 -164
- data/brutrb.com/.vitepress/plugins/jsdocLinker.js +0 -34
- data/brutrb.com/.vitepress/plugins/rdocLinker.js +0 -18
- data/brutrb.com/.vitepress/theme/custom.css +0 -14
- data/brutrb.com/.vitepress/theme/index.js +0 -18
- data/brutrb.com/.vitepress/theme/style.css +0 -139
- data/brutrb.com/adrs.md +0 -16
- data/brutrb.com/ai.md +0 -68
- data/brutrb.com/assets.md +0 -131
- data/brutrb.com/bin/build +0 -5
- data/brutrb.com/bin/deploy +0 -7
- data/brutrb.com/bin/dev +0 -5
- data/brutrb.com/bin/setup +0 -6
- data/brutrb.com/brut-js.md +0 -128
- data/brutrb.com/business-logic.md +0 -55
- data/brutrb.com/cli.md +0 -274
- data/brutrb.com/components.md +0 -265
- data/brutrb.com/configuration.md +0 -256
- data/brutrb.com/css.md +0 -103
- data/brutrb.com/custom-element-tests.md +0 -148
- data/brutrb.com/database-access.md +0 -201
- data/brutrb.com/database-schema.md +0 -320
- data/brutrb.com/deployment.md +0 -158
- data/brutrb.com/dev-environment.md +0 -186
- data/brutrb.com/dir-structure.md +0 -120
- data/brutrb.com/doc-conventions.md +0 -41
- data/brutrb.com/dx +0 -1
- data/brutrb.com/end-to-end-tests.md +0 -176
- data/brutrb.com/features.md +0 -373
- data/brutrb.com/flash-and-session.md +0 -208
- data/brutrb.com/form-constraints.md +0 -266
- data/brutrb.com/forms.md +0 -238
- data/brutrb.com/getting-started.md +0 -142
- data/brutrb.com/handlers.md +0 -177
- data/brutrb.com/hooks.md +0 -176
- data/brutrb.com/i18n.md +0 -190
- data/brutrb.com/images/DevEnvironment.graffle +0 -0
- data/brutrb.com/images/DevEnvironment.png +0 -0
- data/brutrb.com/images/LogoSquare.png +0 -0
- data/brutrb.com/images/LogoStop.png +0 -0
- data/brutrb.com/images/LogoTall.png +0 -0
- data/brutrb.com/images/Makefile +0 -10
- data/brutrb.com/images/OverviewMetro.graffle +0 -0
- data/brutrb.com/images/OverviewMetro.png +0 -0
- data/brutrb.com/images/dev-env-overview.dot +0 -54
- data/brutrb.com/images/dev-env-overview.png +0 -0
- data/brutrb.com/images/dev-env-protocol.dot +0 -37
- data/brutrb.com/images/dev-env-protocol.png +0 -0
- data/brutrb.com/images/overview.graffle +0 -0
- data/brutrb.com/images/overview.png +0 -0
- data/brutrb.com/images/spa.dot +0 -19
- data/brutrb.com/images/spa.png +0 -0
- data/brutrb.com/images/tutorial/02-confirmation-dialog-browser-element-styled.png +0 -0
- data/brutrb.com/images/tutorial/02-confirmation-dialog-browser-element.png +0 -0
- data/brutrb.com/images/tutorial/02-confirmation-dialog-browser.png +0 -0
- data/brutrb.com/images/tutorial/02-confirmation-flow.graffle +0 -0
- data/brutrb.com/images/tutorial/02-confirmation-flow.png +0 -0
- data/brutrb.com/images/tutorial/basic-form-with-violations.png +0 -0
- data/brutrb.com/images/tutorial/basic-form.png +0 -0
- data/brutrb.com/images/tutorial/initial-home-page.png +0 -0
- data/brutrb.com/images/tutorial/new-post-editor.png +0 -0
- data/brutrb.com/images/tutorial/new-post-home-page.png +0 -0
- data/brutrb.com/images/tutorial/styled-form-with-server-side-violations.png +0 -0
- data/brutrb.com/images/tutorial/styled-form-with-violations.png +0 -0
- data/brutrb.com/images/tutorial/styled-home-page-with-posts.png +0 -0
- data/brutrb.com/images/tutorial/styled-home-page.png +0 -0
- data/brutrb.com/images/tutorial/welcome-to-brut.png +0 -0
- data/brutrb.com/images/workspace-protocol.dot +0 -44
- data/brutrb.com/images/workspace-protocol.png +0 -0
- data/brutrb.com/index.md +0 -34
- data/brutrb.com/instrumentation.md +0 -331
- data/brutrb.com/javascript.md +0 -122
- data/brutrb.com/jobs.md +0 -114
- data/brutrb.com/keyword-injection.md +0 -195
- data/brutrb.com/layouts.md +0 -156
- data/brutrb.com/lsp.md +0 -23
- data/brutrb.com/markdown-examples.md +0 -85
- data/brutrb.com/middleware.md +0 -80
- data/brutrb.com/overview.md +0 -68
- data/brutrb.com/package-lock.json +0 -2451
- data/brutrb.com/package.json +0 -11
- data/brutrb.com/pages.md +0 -290
- data/brutrb.com/public/SocialImage.png +0 -0
- data/brutrb.com/public/favicon.ico +0 -0
- data/brutrb.com/recipes/alternate-layouts.md +0 -32
- data/brutrb.com/recipes/authentication.md +0 -336
- data/brutrb.com/recipes/custom-flash.md +0 -51
- data/brutrb.com/recipes/dev-env-secrets.md +0 -87
- data/brutrb.com/recipes/form-errors.md +0 -148
- data/brutrb.com/recipes/indexed-forms.md +0 -149
- data/brutrb.com/recipes/migrations.md +0 -210
- data/brutrb.com/recipes/text-field-component.md +0 -182
- data/brutrb.com/roadmap.md +0 -52
- data/brutrb.com/routes.md +0 -189
- data/brutrb.com/security.md +0 -102
- data/brutrb.com/seed-data.md +0 -63
- data/brutrb.com/space-time-continuum.md +0 -81
- data/brutrb.com/tutorial.md +0 -138
- data/brutrb.com/tutorials/01-intro.md +0 -1654
- data/brutrb.com/tutorials/02-dialog.md +0 -569
- data/brutrb.com/unit-tests.md +0 -148
- data/brutrb.com/why.md +0 -19
- data/docker-compose.dx.yml +0 -25
- data/docs/404.html +0 -26
- data/docs/CNAME +0 -1
- data/docs/SocialImage.png +0 -0
- data/docs/adrs.html +0 -29
- data/docs/ai.html +0 -29
- data/docs/api/Brut/BackEnd/SeedData.html +0 -493
- data/docs/api/Brut/BackEnd/Sidekiq/Middlewares/Server/FlushSpans.html +0 -214
- data/docs/api/Brut/BackEnd/Sidekiq/Middlewares/Server.html +0 -125
- data/docs/api/Brut/BackEnd/Sidekiq/Middlewares.html +0 -125
- data/docs/api/Brut/BackEnd/Sidekiq.html +0 -125
- data/docs/api/Brut/BackEnd/Validators/FormValidator.html +0 -414
- data/docs/api/Brut/BackEnd/Validators.html +0 -128
- data/docs/api/Brut/BackEnd.html +0 -132
- data/docs/api/Brut/CLI/App.html +0 -1601
- data/docs/api/Brut/CLI/AppRunner.html +0 -491
- data/docs/api/Brut/CLI/Apps/BuildAssets/All.html +0 -264
- data/docs/api/Brut/CLI/Apps/BuildAssets/CSS.html +0 -306
- data/docs/api/Brut/CLI/Apps/BuildAssets/Images.html +0 -262
- data/docs/api/Brut/CLI/Apps/BuildAssets/JS.html +0 -314
- data/docs/api/Brut/CLI/Apps/BuildAssets.html +0 -183
- data/docs/api/Brut/CLI/Apps/DB/Create.html +0 -365
- data/docs/api/Brut/CLI/Apps/DB/Drop.html +0 -357
- data/docs/api/Brut/CLI/Apps/DB/Migrate.html +0 -389
- data/docs/api/Brut/CLI/Apps/DB/NewMigration.html +0 -339
- data/docs/api/Brut/CLI/Apps/DB/Rebuild.html +0 -329
- data/docs/api/Brut/CLI/Apps/DB/Seed.html +0 -347
- data/docs/api/Brut/CLI/Apps/DB/Status.html +0 -383
- data/docs/api/Brut/CLI/Apps/DB.html +0 -183
- data/docs/api/Brut/CLI/Apps/DeployBase/GitChecks.html +0 -270
- data/docs/api/Brut/CLI/Apps/DeployBase.html +0 -257
- data/docs/api/Brut/CLI/Apps/HerokuContainerBasedDeploy/Deploy.html +0 -587
- data/docs/api/Brut/CLI/Apps/HerokuContainerBasedDeploy.html +0 -196
- data/docs/api/Brut/CLI/Apps/Scaffold/Action/Route.html +0 -303
- data/docs/api/Brut/CLI/Apps/Scaffold/Action.html +0 -508
- data/docs/api/Brut/CLI/Apps/Scaffold/Component.html +0 -398
- data/docs/api/Brut/CLI/Apps/Scaffold/CustomElementTest.html +0 -374
- data/docs/api/Brut/CLI/Apps/Scaffold/DbModel.html +0 -384
- data/docs/api/Brut/CLI/Apps/Scaffold/E2ETest.html +0 -410
- data/docs/api/Brut/CLI/Apps/Scaffold/Form.html +0 -262
- data/docs/api/Brut/CLI/Apps/Scaffold/Page/Route.html +0 -303
- data/docs/api/Brut/CLI/Apps/Scaffold/Page.html +0 -480
- data/docs/api/Brut/CLI/Apps/Scaffold/RoutesEditor.html +0 -450
- data/docs/api/Brut/CLI/Apps/Scaffold/Test.html +0 -380
- data/docs/api/Brut/CLI/Apps/Scaffold.html +0 -253
- data/docs/api/Brut/CLI/Apps/Test/Audit.html +0 -470
- data/docs/api/Brut/CLI/Apps/Test/E2e.html +0 -407
- data/docs/api/Brut/CLI/Apps/Test/JS.html +0 -262
- data/docs/api/Brut/CLI/Apps/Test/Run.html +0 -578
- data/docs/api/Brut/CLI/Apps/Test.html +0 -253
- data/docs/api/Brut/CLI/Apps.html +0 -125
- data/docs/api/Brut/CLI/Command.html +0 -2425
- data/docs/api/Brut/CLI/Error.html +0 -139
- data/docs/api/Brut/CLI/ExecutionResults/Result.html +0 -664
- data/docs/api/Brut/CLI/ExecutionResults.html +0 -675
- data/docs/api/Brut/CLI/Executor.html +0 -561
- data/docs/api/Brut/CLI/InvalidOption.html +0 -245
- data/docs/api/Brut/CLI/Options.html +0 -880
- data/docs/api/Brut/CLI/Output.html +0 -699
- data/docs/api/Brut/CLI/SystemExecError.html +0 -451
- data/docs/api/Brut/CLI.html +0 -263
- data/docs/api/Brut/FactoryBot.html +0 -225
- data/docs/api/Brut/Framework/App.html +0 -1097
- data/docs/api/Brut/Framework/Config.html +0 -1071
- data/docs/api/Brut/Framework/Container.html +0 -1464
- data/docs/api/Brut/Framework/Error.html +0 -140
- data/docs/api/Brut/Framework/Errors/AbstractMethod.html +0 -232
- data/docs/api/Brut/Framework/Errors/Bug.html +0 -234
- data/docs/api/Brut/Framework/Errors/MissingConfiguration.html +0 -257
- data/docs/api/Brut/Framework/Errors/MissingParameter.html +0 -273
- data/docs/api/Brut/Framework/Errors/NoClassForPath.html +0 -471
- data/docs/api/Brut/Framework/Errors/NotFound.html +0 -308
- data/docs/api/Brut/Framework/Errors/NotImplemented.html +0 -234
- data/docs/api/Brut/Framework/Errors.html +0 -351
- data/docs/api/Brut/Framework/FussyTypeEnforcement.html +0 -392
- data/docs/api/Brut/Framework/MCP.html +0 -871
- data/docs/api/Brut/Framework/ProjectEnvironment.html +0 -648
- data/docs/api/Brut/Framework.html +0 -129
- data/docs/api/Brut/FrontEnd/AssetPathResolver.html +0 -317
- data/docs/api/Brut/FrontEnd/Component/Helpers.html +0 -420
- data/docs/api/Brut/FrontEnd/Component.html +0 -434
- data/docs/api/Brut/FrontEnd/Components/ConstraintViolations.html +0 -491
- data/docs/api/Brut/FrontEnd/Components/FormTag.html +0 -526
- data/docs/api/Brut/FrontEnd/Components/I18nTranslations.html +0 -313
- data/docs/api/Brut/FrontEnd/Components/Input.html +0 -195
- data/docs/api/Brut/FrontEnd/Components/Inputs/ButtonTag.html +0 -447
- data/docs/api/Brut/FrontEnd/Components/Inputs/CsrfToken.html +0 -339
- data/docs/api/Brut/FrontEnd/Components/Inputs/InputTag.html +0 -568
- data/docs/api/Brut/FrontEnd/Components/Inputs/RadioButton.html +0 -419
- data/docs/api/Brut/FrontEnd/Components/Inputs/SelectTagWithOptions.html +0 -610
- data/docs/api/Brut/FrontEnd/Components/Inputs/TextareaTag.html +0 -534
- data/docs/api/Brut/FrontEnd/Components/Inputs.html +0 -125
- data/docs/api/Brut/FrontEnd/Components/LocaleDetection.html +0 -367
- data/docs/api/Brut/FrontEnd/Components/PageIdentifier.html +0 -355
- data/docs/api/Brut/FrontEnd/Components/TimeTag.html +0 -655
- data/docs/api/Brut/FrontEnd/Components/Traceparent.html +0 -352
- data/docs/api/Brut/FrontEnd/Components.html +0 -156
- data/docs/api/Brut/FrontEnd/CsrfProtector.html +0 -250
- data/docs/api/Brut/FrontEnd/Download.html +0 -467
- data/docs/api/Brut/FrontEnd/Flash.html +0 -1150
- data/docs/api/Brut/FrontEnd/Form.html +0 -1227
- data/docs/api/Brut/FrontEnd/Forms/Button.html +0 -331
- data/docs/api/Brut/FrontEnd/Forms/ButtonInputDefinition.html +0 -537
- data/docs/api/Brut/FrontEnd/Forms/ConstraintViolation.html +0 -590
- data/docs/api/Brut/FrontEnd/Forms/Input/Color.html +0 -201
- data/docs/api/Brut/FrontEnd/Forms/Input/TimeOfDay.html +0 -535
- data/docs/api/Brut/FrontEnd/Forms/Input.html +0 -1567
- data/docs/api/Brut/FrontEnd/Forms/InputDeclarations.html +0 -635
- data/docs/api/Brut/FrontEnd/Forms/InputDefinition.html +0 -1336
- data/docs/api/Brut/FrontEnd/Forms/RadioButtonGroupInput.html +0 -730
- data/docs/api/Brut/FrontEnd/Forms/RadioButtonGroupInputDefinition.html +0 -587
- data/docs/api/Brut/FrontEnd/Forms/SelectInput.html +0 -734
- data/docs/api/Brut/FrontEnd/Forms/SelectInputDefinition.html +0 -582
- data/docs/api/Brut/FrontEnd/Forms/ValidityState.html +0 -659
- data/docs/api/Brut/FrontEnd/Forms.html +0 -127
- data/docs/api/Brut/FrontEnd/GenericResponse.html +0 -377
- data/docs/api/Brut/FrontEnd/Handler.html +0 -442
- data/docs/api/Brut/FrontEnd/Handlers/CspReportingHandler.html +0 -318
- data/docs/api/Brut/FrontEnd/Handlers/InstrumentationHandler/TraceParent.html +0 -336
- data/docs/api/Brut/FrontEnd/Handlers/InstrumentationHandler.html +0 -399
- data/docs/api/Brut/FrontEnd/Handlers/LocaleDetectionHandler.html +0 -354
- data/docs/api/Brut/FrontEnd/Handlers/MissingHandler/Form.html +0 -151
- data/docs/api/Brut/FrontEnd/Handlers/MissingHandler.html +0 -315
- data/docs/api/Brut/FrontEnd/Handlers.html +0 -125
- data/docs/api/Brut/FrontEnd/HandlingResults.html +0 -339
- data/docs/api/Brut/FrontEnd/HttpMethod.html +0 -661
- data/docs/api/Brut/FrontEnd/HttpStatus.html +0 -496
- data/docs/api/Brut/FrontEnd/InlineSvgLocator.html +0 -284
- data/docs/api/Brut/FrontEnd/Layout.html +0 -486
- data/docs/api/Brut/FrontEnd/Middleware.html +0 -135
- data/docs/api/Brut/FrontEnd/Middlewares/AnnotateBrutOwnedPaths.html +0 -288
- data/docs/api/Brut/FrontEnd/Middlewares/Favicon.html +0 -292
- data/docs/api/Brut/FrontEnd/Middlewares/OpenTelemetrySpan.html +0 -324
- data/docs/api/Brut/FrontEnd/Middlewares/ReloadApp.html +0 -376
- data/docs/api/Brut/FrontEnd/Middlewares.html +0 -125
- data/docs/api/Brut/FrontEnd/Page.html +0 -781
- data/docs/api/Brut/FrontEnd/Pages/MissingPage.html +0 -797
- data/docs/api/Brut/FrontEnd/Pages.html +0 -125
- data/docs/api/Brut/FrontEnd/RequestContext.html +0 -1312
- data/docs/api/Brut/FrontEnd/RouteHook.html +0 -424
- data/docs/api/Brut/FrontEnd/RouteHooks/AgeFlash.html +0 -242
- data/docs/api/Brut/FrontEnd/RouteHooks/CSPNoInlineScripts.html +0 -249
- data/docs/api/Brut/FrontEnd/RouteHooks/CSPNoInlineStylesOrScripts/ReportOnly.html +0 -264
- data/docs/api/Brut/FrontEnd/RouteHooks/CSPNoInlineStylesOrScripts.html +0 -261
- data/docs/api/Brut/FrontEnd/RouteHooks/LocaleDetection.html +0 -284
- data/docs/api/Brut/FrontEnd/RouteHooks/SetupRequestContext.html +0 -252
- data/docs/api/Brut/FrontEnd/RouteHooks.html +0 -115
- data/docs/api/Brut/FrontEnd/Routing/FormHandlerRoute.html +0 -227
- data/docs/api/Brut/FrontEnd/Routing/FormRoute.html +0 -305
- data/docs/api/Brut/FrontEnd/Routing/MissingForm.html +0 -324
- data/docs/api/Brut/FrontEnd/Routing/MissingHandler.html +0 -319
- data/docs/api/Brut/FrontEnd/Routing/MissingPage.html +0 -315
- data/docs/api/Brut/FrontEnd/Routing/MissingPath.html +0 -315
- data/docs/api/Brut/FrontEnd/Routing/PageRoute.html +0 -327
- data/docs/api/Brut/FrontEnd/Routing/Route.html +0 -761
- data/docs/api/Brut/FrontEnd/Routing.html +0 -927
- data/docs/api/Brut/FrontEnd/Session.html +0 -1195
- data/docs/api/Brut/FrontEnd.html +0 -134
- data/docs/api/Brut/I18n/BaseMethods.html +0 -931
- data/docs/api/Brut/I18n/ForBackEnd.html +0 -302
- data/docs/api/Brut/I18n/ForCLI.html +0 -302
- data/docs/api/Brut/I18n/ForHTML.html +0 -296
- data/docs/api/Brut/I18n/HTTPAcceptLanguage/AlwaysEnglish.html +0 -316
- data/docs/api/Brut/I18n/HTTPAcceptLanguage.html +0 -930
- data/docs/api/Brut/I18n.html +0 -127
- data/docs/api/Brut/Instrumentation/LoggerSpanExporter.html +0 -435
- data/docs/api/Brut/Instrumentation/Methods/ClassMethods.html +0 -596
- data/docs/api/Brut/Instrumentation/Methods.html +0 -173
- data/docs/api/Brut/Instrumentation/OpenTelemetry/NormalizedAttributes.html +0 -286
- data/docs/api/Brut/Instrumentation/OpenTelemetry/Span.html +0 -302
- data/docs/api/Brut/Instrumentation/OpenTelemetry.html +0 -866
- data/docs/api/Brut/Instrumentation.html +0 -128
- data/docs/api/Brut/RubocopConfig.html +0 -237
- data/docs/api/Brut/SinatraHelpers/ClassMethods.html +0 -534
- data/docs/api/Brut/SinatraHelpers.html +0 -281
- data/docs/api/Brut/SpecSupport/ClockSupport.html +0 -383
- data/docs/api/Brut/SpecSupport/ComponentSupport.html +0 -496
- data/docs/api/Brut/SpecSupport/E2ETestServer.html +0 -503
- data/docs/api/Brut/SpecSupport/E2eSupport.html +0 -142
- data/docs/api/Brut/SpecSupport/EnhancedNode.html +0 -403
- data/docs/api/Brut/SpecSupport/FlashSupport.html +0 -278
- data/docs/api/Brut/SpecSupport/GeneralSupport/ClassMethods.html +0 -401
- data/docs/api/Brut/SpecSupport/GeneralSupport.html +0 -195
- data/docs/api/Brut/SpecSupport/HandlerSupport.html +0 -160
- data/docs/api/Brut/SpecSupport/Matchers/BeABug.html +0 -142
- data/docs/api/Brut/SpecSupport/Matchers/BePageFor.html +0 -142
- data/docs/api/Brut/SpecSupport/Matchers/BeRoutingFor.html +0 -155
- data/docs/api/Brut/SpecSupport/Matchers/HaveConstraintViolation.html +0 -583
- data/docs/api/Brut/SpecSupport/Matchers/HaveGenerated.html +0 -149
- data/docs/api/Brut/SpecSupport/Matchers/HaveHTMLAttribute.html +0 -466
- data/docs/api/Brut/SpecSupport/Matchers/HaveI18nString.html +0 -149
- data/docs/api/Brut/SpecSupport/Matchers/HaveLinkTo.html +0 -149
- data/docs/api/Brut/SpecSupport/Matchers/HaveRedirectedTo.html +0 -165
- data/docs/api/Brut/SpecSupport/Matchers/HaveReturnedHttpStatus.html +0 -158
- data/docs/api/Brut/SpecSupport/Matchers/HaveReturnedRackResponse.html +0 -156
- data/docs/api/Brut/SpecSupport/Matchers.html +0 -125
- data/docs/api/Brut/SpecSupport/RSpecSetup/OptionalSidekiqSupport.html +0 -335
- data/docs/api/Brut/SpecSupport/RSpecSetup.html +0 -637
- data/docs/api/Brut/SpecSupport/SessionSupport.html +0 -196
- data/docs/api/Brut/SpecSupport.html +0 -129
- data/docs/api/Brut.html +0 -341
- data/docs/api/Clock.html +0 -603
- data/docs/api/ModuleName.html +0 -595
- data/docs/api/RichString.html +0 -775
- data/docs/api/SemanticLogger/Appender/Async.html +0 -219
- data/docs/api/Sequel/Extensions/BrutInstrumentation.html +0 -119
- data/docs/api/Sequel/Extensions/BrutMigrations.html +0 -541
- data/docs/api/Sequel/Extensions.html +0 -117
- data/docs/api/Sequel/Plugins/CreatedAt/InstanceMethods.html +0 -105
- data/docs/api/Sequel/Plugins/CreatedAt.html +0 -125
- data/docs/api/Sequel/Plugins/ExternalId/ClassMethods.html +0 -207
- data/docs/api/Sequel/Plugins/ExternalId/InstanceMethods.html +0 -186
- data/docs/api/Sequel/Plugins/ExternalId.html +0 -218
- data/docs/api/Sequel/Plugins/FindBang/ClassMethods.html +0 -202
- data/docs/api/Sequel/Plugins/FindBang.html +0 -125
- data/docs/api/Sequel/Plugins.html +0 -117
- data/docs/api/Sequel.html +0 -117
- data/docs/api/_index.html +0 -1719
- data/docs/api/class_list.html +0 -54
- data/docs/api/css/common.css +0 -1
- data/docs/api/css/full_list.css +0 -59
- data/docs/api/css/style.css +0 -504
- data/docs/api/file.README.html +0 -172
- data/docs/api/file_list.html +0 -59
- data/docs/api/frames.html +0 -22
- data/docs/api/index.html +0 -172
- data/docs/api/js/app.js +0 -344
- data/docs/api/js/full_list.js +0 -242
- data/docs/api/js/jquery.js +0 -4
- data/docs/api/method_list.html +0 -4422
- data/docs/api/top-level-namespace.html +0 -112
- data/docs/assets/02-confirmation-dialog-browser-element-styled.3NEGM20-.png +0 -0
- data/docs/assets/02-confirmation-dialog-browser-element.DPsf0xUW.png +0 -0
- data/docs/assets/02-confirmation-dialog-browser.DH8ALFO4.png +0 -0
- data/docs/assets/02-confirmation-flow.D9gZ0S5U.png +0 -0
- data/docs/assets/DevEnvironment.DaFcVfwP.png +0 -0
- data/docs/assets/LogoStop.Gb3tDhL1.png +0 -0
- data/docs/assets/OverviewMetro.DUS-5fUZ.png +0 -0
- data/docs/assets/adrs.md.YglbWtQe.js +0 -1
- data/docs/assets/adrs.md.YglbWtQe.lean.js +0 -1
- data/docs/assets/ai.md.ChLnvDAX.js +0 -1
- data/docs/assets/ai.md.ChLnvDAX.lean.js +0 -1
- data/docs/assets/app.CovevI7X.js +0 -1
- data/docs/assets/assets.md.BEF6Oz6K.js +0 -19
- data/docs/assets/assets.md.BEF6Oz6K.lean.js +0 -1
- data/docs/assets/basic-form-with-violations.Cv6Y9-Q_.png +0 -0
- data/docs/assets/basic-form.DbHnu0oW.png +0 -0
- data/docs/assets/brut-js.md.BMz0X1Rz.js +0 -12
- data/docs/assets/brut-js.md.BMz0X1Rz.lean.js +0 -1
- data/docs/assets/business-logic.md.DbuaOYGU.js +0 -1
- data/docs/assets/business-logic.md.DbuaOYGU.lean.js +0 -1
- data/docs/assets/chunks/@localSearchIndexroot.BiNc3tFI.js +0 -1
- data/docs/assets/chunks/VPLocalSearchBox.CrvLAvKW.js +0 -8
- data/docs/assets/chunks/framework.C4nOkCZI.js +0 -18
- data/docs/assets/chunks/theme.BAi5_yQI.js +0 -2
- data/docs/assets/cli.md.DDMar_51.js +0 -122
- data/docs/assets/cli.md.DDMar_51.lean.js +0 -1
- data/docs/assets/components.md.9sqJ27Oc.js +0 -96
- data/docs/assets/components.md.9sqJ27Oc.lean.js +0 -1
- data/docs/assets/configuration.md.Cb_oAR8Z.js +0 -78
- data/docs/assets/configuration.md.Cb_oAR8Z.lean.js +0 -1
- data/docs/assets/css.md.K5rOCOQY.js +0 -21
- data/docs/assets/css.md.K5rOCOQY.lean.js +0 -1
- data/docs/assets/custom-element-tests.md.DiLe-eFw.js +0 -69
- data/docs/assets/custom-element-tests.md.DiLe-eFw.lean.js +0 -1
- data/docs/assets/database-access.md.Dc8l2Plf.js +0 -63
- data/docs/assets/database-access.md.Dc8l2Plf.lean.js +0 -1
- data/docs/assets/database-schema.md.BJ_JhXmO.js +0 -70
- data/docs/assets/database-schema.md.BJ_JhXmO.lean.js +0 -1
- data/docs/assets/deployment.md.CHTx2eTR.js +0 -55
- data/docs/assets/deployment.md.CHTx2eTR.lean.js +0 -1
- data/docs/assets/dev-env-protocol.DysDAtnz.png +0 -0
- data/docs/assets/dev-environment.md.B1S9p5ZK.js +0 -16
- data/docs/assets/dev-environment.md.B1S9p5ZK.lean.js +0 -1
- data/docs/assets/dir-structure.md.D1T2kGwj.js +0 -46
- data/docs/assets/dir-structure.md.D1T2kGwj.lean.js +0 -1
- data/docs/assets/doc-conventions.md.CDnWaEFg.js +0 -1
- data/docs/assets/doc-conventions.md.CDnWaEFg.lean.js +0 -1
- data/docs/assets/end-to-end-tests.md.BJJdNDYL.js +0 -28
- data/docs/assets/end-to-end-tests.md.BJJdNDYL.lean.js +0 -1
- data/docs/assets/features.md.BDWxnyNO.js +0 -154
- data/docs/assets/features.md.BDWxnyNO.lean.js +0 -1
- data/docs/assets/flash-and-session.md.CUsMxoNl.js +0 -79
- data/docs/assets/flash-and-session.md.CUsMxoNl.lean.js +0 -1
- data/docs/assets/form-constraints.md.KlfXSKm2.js +0 -90
- data/docs/assets/form-constraints.md.KlfXSKm2.lean.js +0 -1
- data/docs/assets/forms.md.BdpYpNIk.js +0 -64
- data/docs/assets/forms.md.BdpYpNIk.lean.js +0 -1
- data/docs/assets/getting-started.md.CKpNGvno.js +0 -31
- data/docs/assets/getting-started.md.CKpNGvno.lean.js +0 -1
- data/docs/assets/handlers.md.C5tUwmmo.js +0 -54
- data/docs/assets/handlers.md.C5tUwmmo.lean.js +0 -1
- data/docs/assets/hooks.md.CoiYCKRc.js +0 -80
- data/docs/assets/hooks.md.CoiYCKRc.lean.js +0 -1
- data/docs/assets/i18n.md.DxkCKhUw.js +0 -23
- data/docs/assets/i18n.md.DxkCKhUw.lean.js +0 -1
- data/docs/assets/index.md.DnphWyQd.js +0 -1
- data/docs/assets/index.md.DnphWyQd.lean.js +0 -1
- data/docs/assets/initial-home-page.DNIaYmgP.png +0 -0
- data/docs/assets/instrumentation.md.BcxjC4jd.js +0 -90
- data/docs/assets/instrumentation.md.BcxjC4jd.lean.js +0 -1
- data/docs/assets/javascript.md.D6fxhaQb.js +0 -31
- data/docs/assets/javascript.md.D6fxhaQb.lean.js +0 -1
- data/docs/assets/jobs.md.Bi3qb3v6.js +0 -25
- data/docs/assets/jobs.md.Bi3qb3v6.lean.js +0 -1
- data/docs/assets/keyword-injection.md.CqLnnzIz.js +0 -21
- data/docs/assets/keyword-injection.md.CqLnnzIz.lean.js +0 -1
- data/docs/assets/layouts.md.HEbeK7Jr.js +0 -68
- data/docs/assets/layouts.md.HEbeK7Jr.lean.js +0 -1
- data/docs/assets/lsp.md.bE9dW8n9.js +0 -1
- data/docs/assets/lsp.md.bE9dW8n9.lean.js +0 -1
- data/docs/assets/markdown-examples.md.BPmtHlc-.js +0 -33
- data/docs/assets/markdown-examples.md.BPmtHlc-.lean.js +0 -1
- data/docs/assets/middleware.md.BhOIsg59.js +0 -20
- data/docs/assets/middleware.md.BhOIsg59.lean.js +0 -1
- data/docs/assets/new-post-editor.DrHr-5oh.png +0 -0
- data/docs/assets/new-post-home-page.Bm34lyMg.png +0 -0
- data/docs/assets/overview.md.BpWAgPFH.js +0 -1
- data/docs/assets/overview.md.BpWAgPFH.lean.js +0 -1
- data/docs/assets/pages.md.B3sQXpEd.js +0 -45
- data/docs/assets/pages.md.B3sQXpEd.lean.js +0 -1
- data/docs/assets/recipes_alternate-layouts.md.C1QzVkA7.js +0 -22
- data/docs/assets/recipes_alternate-layouts.md.C1QzVkA7.lean.js +0 -1
- data/docs/assets/recipes_authentication.md.CyvoIW82.js +0 -157
- data/docs/assets/recipes_authentication.md.CyvoIW82.lean.js +0 -1
- data/docs/assets/recipes_custom-flash.md.6gFqf2uL.js +0 -26
- data/docs/assets/recipes_custom-flash.md.6gFqf2uL.lean.js +0 -1
- data/docs/assets/recipes_dev-env-secrets.md.DC_jVY9U.js +0 -12
- data/docs/assets/recipes_dev-env-secrets.md.DC_jVY9U.lean.js +0 -1
- data/docs/assets/recipes_form-errors.md.B5ptSzMO.js +0 -66
- data/docs/assets/recipes_form-errors.md.B5ptSzMO.lean.js +0 -1
- data/docs/assets/recipes_indexed-forms.md.BYYQGW2C.js +0 -74
- data/docs/assets/recipes_indexed-forms.md.BYYQGW2C.lean.js +0 -1
- data/docs/assets/recipes_migrations.md.Cid7-3cu.js +0 -97
- data/docs/assets/recipes_migrations.md.Cid7-3cu.lean.js +0 -1
- data/docs/assets/recipes_text-field-component.md.VhOsCtKI.js +0 -101
- data/docs/assets/recipes_text-field-component.md.VhOsCtKI.lean.js +0 -1
- data/docs/assets/roadmap.md.DqC1Y7Zt.js +0 -1
- data/docs/assets/roadmap.md.DqC1Y7Zt.lean.js +0 -1
- data/docs/assets/routes.md.C1dgIBtD.js +0 -21
- data/docs/assets/routes.md.C1dgIBtD.lean.js +0 -1
- data/docs/assets/security.md.Jn4SY1uK.js +0 -1
- data/docs/assets/security.md.Jn4SY1uK.lean.js +0 -1
- data/docs/assets/seed-data.md.UZW0WxYN.js +0 -14
- data/docs/assets/seed-data.md.UZW0WxYN.lean.js +0 -1
- data/docs/assets/spa.qejUdp-5.png +0 -0
- data/docs/assets/space-time-continuum.md.D9rYGDFH.js +0 -1
- data/docs/assets/space-time-continuum.md.D9rYGDFH.lean.js +0 -1
- data/docs/assets/style.B1z60PPQ.css +0 -1
- data/docs/assets/styled-form-with-server-side-violations.Bjxd8Dpv.png +0 -0
- data/docs/assets/styled-form-with-violations.Bv_sa9tg.png +0 -0
- data/docs/assets/styled-home-page-with-posts.Dd4kG89D.png +0 -0
- data/docs/assets/styled-home-page.BzdI7dWz.png +0 -0
- data/docs/assets/tutorial.md.BX6f6l00.js +0 -27
- data/docs/assets/tutorial.md.BX6f6l00.lean.js +0 -1
- data/docs/assets/tutorials_01-intro.md.CzZ3kpF_.js +0 -708
- data/docs/assets/tutorials_01-intro.md.CzZ3kpF_.lean.js +0 -1
- data/docs/assets/tutorials_02-dialog.md.Z_DOF2mU.js +0 -274
- data/docs/assets/tutorials_02-dialog.md.Z_DOF2mU.lean.js +0 -1
- data/docs/assets/unit-tests.md.vDsdBbO_.js +0 -13
- data/docs/assets/unit-tests.md.vDsdBbO_.lean.js +0 -1
- data/docs/assets/welcome-to-brut.VSWzl17-.png +0 -0
- data/docs/assets/why.md.4WpxdrQ2.js +0 -1
- data/docs/assets/why.md.4WpxdrQ2.lean.js +0 -1
- data/docs/assets/workspace-protocol.C0gXsoDb.png +0 -0
- data/docs/assets.html +0 -47
- data/docs/brut-css/brut.max.css +0 -22372
- data/docs/brut-css/classes/appearances.html +0 -783
- data/docs/brut-css/classes/background-colors.html +0 -3529
- data/docs/brut-css/classes/border-colors.html +0 -3529
- data/docs/brut-css/classes/borders.html +0 -2293
- data/docs/brut-css/classes/dimensions.html +0 -2581
- data/docs/brut-css/classes/flex.html +0 -917
- data/docs/brut-css/classes/foreground-colors.html +0 -3261
- data/docs/brut-css/classes/junk-drawer.html +0 -431
- data/docs/brut-css/classes/layout.html +0 -668
- data/docs/brut-css/classes/lists.html +0 -331
- data/docs/brut-css/classes/positioning.html +0 -1751
- data/docs/brut-css/classes/spacings.html +0 -2633
- data/docs/brut-css/classes/typography.html +0 -2206
- data/docs/brut-css/customization/advanced-configuration.html +0 -204
- data/docs/brut-css/customization/breakpoints.html +0 -227
- data/docs/brut-css/customization/design-system.html +0 -197
- data/docs/brut-css/customization/pseudo-classes.html +0 -228
- data/docs/brut-css/docs.css +0 -98
- data/docs/brut-css/getting-started/core-concepts.html +0 -234
- data/docs/brut-css/getting-started/installation.html +0 -190
- data/docs/brut-css/getting-started/overview.html +0 -210
- data/docs/brut-css/getting-started/simple-example.html +0 -285
- data/docs/brut-css/index.html +0 -193
- data/docs/brut-css/prism-twilight.min.css +0 -1
- data/docs/brut-css/properties/colors.html +0 -1548
- data/docs/brut-css/properties/spacings.html +0 -614
- data/docs/brut-css/properties/typography.html +0 -777
- data/docs/brut-js/api/AjaxSubmit.html +0 -452
- data/docs/brut-js/api/AjaxSubmit.js.html +0 -550
- data/docs/brut-js/api/Autosubmit.html +0 -192
- data/docs/brut-js/api/Autosubmit.js.html +0 -114
- data/docs/brut-js/api/BaseCustomElement.html +0 -1091
- data/docs/brut-js/api/BaseCustomElement.js.html +0 -312
- data/docs/brut-js/api/BrutCustomElements.html +0 -172
- data/docs/brut-js/api/BufferedLogger.html +0 -173
- data/docs/brut-js/api/ConfirmSubmit.html +0 -286
- data/docs/brut-js/api/ConfirmSubmit.js.html +0 -188
- data/docs/brut-js/api/ConfirmationDialog.html +0 -425
- data/docs/brut-js/api/ConfirmationDialog.js.html +0 -194
- data/docs/brut-js/api/ConstraintViolationMessage.html +0 -498
- data/docs/brut-js/api/ConstraintViolationMessage.js.html +0 -191
- data/docs/brut-js/api/ConstraintViolationMessages.html +0 -590
- data/docs/brut-js/api/ConstraintViolationMessages.js.html +0 -149
- data/docs/brut-js/api/CopyToClipboard.html +0 -345
- data/docs/brut-js/api/CopyToClipboard.js.html +0 -147
- data/docs/brut-js/api/Form.html +0 -291
- data/docs/brut-js/api/Form.js.html +0 -198
- data/docs/brut-js/api/I18nTranslation.html +0 -409
- data/docs/brut-js/api/I18nTranslation.js.html +0 -115
- data/docs/brut-js/api/LocaleDetection.html +0 -312
- data/docs/brut-js/api/LocaleDetection.js.html +0 -168
- data/docs/brut-js/api/Logger.html +0 -702
- data/docs/brut-js/api/Logger.js.html +0 -141
- data/docs/brut-js/api/Message.html +0 -238
- data/docs/brut-js/api/Message.js.html +0 -113
- data/docs/brut-js/api/PrefixedLogger.html +0 -369
- data/docs/brut-js/api/RichString.html +0 -1049
- data/docs/brut-js/api/RichString.js.html +0 -167
- data/docs/brut-js/api/Tabs.html +0 -295
- data/docs/brut-js/api/Tabs.js.html +0 -219
- data/docs/brut-js/api/Toast.html +0 -270
- data/docs/brut-js/api/Toast.js.html +0 -153
- data/docs/brut-js/api/Tracing.html +0 -277
- data/docs/brut-js/api/Tracing.js.html +0 -298
- data/docs/brut-js/api/external-CustomElementRegistry.html +0 -140
- data/docs/brut-js/api/external-Performance.html +0 -138
- data/docs/brut-js/api/external-Promise.html +0 -138
- data/docs/brut-js/api/external-ValidityState.html +0 -138
- data/docs/brut-js/api/external-Window.html +0 -233
- data/docs/brut-js/api/external-fetch.html +0 -138
- data/docs/brut-js/api/global.html +0 -400
- data/docs/brut-js/api/index.html +0 -168
- data/docs/brut-js/api/index.js.html +0 -184
- data/docs/brut-js/api/module-testing.html +0 -383
- data/docs/brut-js/api/scripts/linenumber.js +0 -25
- data/docs/brut-js/api/scripts/prettify/Apache-License-2.0.txt +0 -202
- data/docs/brut-js/api/scripts/prettify/lang-css.js +0 -2
- data/docs/brut-js/api/scripts/prettify/prettify.js +0 -28
- data/docs/brut-js/api/styles/jsdoc-default.css +0 -327
- data/docs/brut-js/api/styles/prettify-jsdoc.css +0 -111
- data/docs/brut-js/api/styles/prettify-tomorrow.css +0 -132
- data/docs/brut-js/api/testing.AssetMetadata.html +0 -172
- data/docs/brut-js/api/testing.AssetMetadataLoader.html +0 -171
- data/docs/brut-js/api/testing.CustomElementTest.html +0 -679
- data/docs/brut-js/api/testing.DOMCreator.html +0 -171
- data/docs/brut-js/api/testing_AssetMetadata.js.html +0 -86
- data/docs/brut-js/api/testing_AssetMetadataLoader.js.html +0 -76
- data/docs/brut-js/api/testing_CustomElementTest.js.html +0 -286
- data/docs/brut-js/api/testing_DOMCreator.js.html +0 -96
- data/docs/brut-js/api/testing_index.js.html +0 -99
- data/docs/brut-js.html +0 -40
- data/docs/business-logic.html +0 -29
- data/docs/cli.html +0 -150
- data/docs/components.html +0 -124
- data/docs/configuration.html +0 -106
- data/docs/css.html +0 -49
- data/docs/custom-element-tests.html +0 -97
- data/docs/database-access.html +0 -91
- data/docs/database-schema.html +0 -98
- data/docs/deployment.html +0 -83
- data/docs/dev-environment.html +0 -44
- data/docs/dir-structure.html +0 -74
- data/docs/doc-conventions.html +0 -29
- data/docs/end-to-end-tests.html +0 -56
- data/docs/favicon.ico +0 -0
- data/docs/features.html +0 -182
- data/docs/flash-and-session.html +0 -107
- data/docs/form-constraints.html +0 -118
- data/docs/forms.html +0 -92
- data/docs/getting-started.html +0 -59
- data/docs/handlers.html +0 -82
- data/docs/hashmap.json +0 -1
- data/docs/hooks.html +0 -108
- data/docs/i18n.html +0 -51
- data/docs/index.html +0 -29
- data/docs/instrumentation.html +0 -118
- data/docs/javascript.html +0 -59
- data/docs/jobs.html +0 -53
- data/docs/keyword-injection.html +0 -49
- data/docs/layouts.html +0 -96
- data/docs/lsp.html +0 -29
- data/docs/markdown-examples.html +0 -61
- data/docs/middleware.html +0 -48
- data/docs/overview.html +0 -29
- data/docs/pages.html +0 -73
- data/docs/recipes/alternate-layouts.html +0 -50
- data/docs/recipes/authentication.html +0 -185
- data/docs/recipes/custom-flash.html +0 -54
- data/docs/recipes/dev-env-secrets.html +0 -40
- data/docs/recipes/form-errors.html +0 -94
- data/docs/recipes/indexed-forms.html +0 -102
- data/docs/recipes/migrations.html +0 -125
- data/docs/recipes/text-field-component.html +0 -129
- data/docs/roadmap.html +0 -29
- data/docs/routes.html +0 -49
- data/docs/security.html +0 -29
- data/docs/seed-data.html +0 -42
- data/docs/space-time-continuum.html +0 -29
- data/docs/tutorial.html +0 -55
- data/docs/tutorials/01-intro.html +0 -736
- data/docs/tutorials/02-dialog.html +0 -302
- data/docs/unit-tests.html +0 -41
- data/docs/vp-icons.css +0 -1
- data/docs/why.html +0 -29
- data/docs-todo.md +0 -32
- data/dx/bash_customizations +0 -6
- data/dx/build +0 -73
- data/dx/build.pre +0 -15
- data/dx/docker-compose.env +0 -22
- data/dx/dx.sh.lib +0 -24
- data/dx/exec +0 -75
- data/dx/setupkit.sh.lib +0 -144
- data/dx/show-help-in-app-container-then-wait.sh +0 -38
- data/lib/brut/cli/app.rb +0 -238
- data/lib/brut/cli/app_runner.rb +0 -252
- data/lib/brut/cli/command.rb +0 -258
- data/lib/brut/cli/execution_results.rb +0 -119
- data/lib/brut/front_end/layouts/_internal.html.erb +0 -68
- data/lib/brut/front_end/pages/_missing_page.html.erb +0 -17
- data/mkbrut/.gitignore +0 -16
- data/mkbrut/CODE_OF_CONDUCT.txt +0 -100
- data/mkbrut/Gemfile +0 -3
- data/mkbrut/Gemfile.lock +0 -20
- data/mkbrut/LICENSE.txt +0 -370
- data/mkbrut/README.md +0 -145
- data/mkbrut/Rakefile +0 -2
- data/mkbrut/bin/build +0 -36
- data/mkbrut/bin/ci +0 -19
- data/mkbrut/bin/docs +0 -19
- data/mkbrut/bin/publish +0 -129
- data/mkbrut/bin/rake +0 -16
- data/mkbrut/bin/setup +0 -30
- data/mkbrut/brut-welcome.png +0 -0
- data/mkbrut/deploy/.dockerignore +0 -2
- data/mkbrut/deploy/Dockerfile +0 -25
- data/mkbrut/dx +0 -1
- data/mkbrut/exe/mkbrut +0 -5
- data/mkbrut/lib/mkbrut/app_name.rb +0 -29
- data/mkbrut/lib/mkbrut/app_options.rb +0 -36
- data/mkbrut/lib/mkbrut/cli.rb +0 -189
- data/mkbrut/lib/mkbrut/erb_binding_delegate.rb +0 -20
- data/mkbrut/lib/mkbrut/ops.rb +0 -17
- data/mkbrut/lib/mkbrut/organization.rb +0 -5
- data/mkbrut/lib/mkbrut/segments.rb +0 -8
- data/mkbrut/lib/mkbrut/version.rb +0 -3
- data/mkbrut/lib/mkbrut.rb +0 -20
- data/mkbrut/mkbrut.gemspec +0 -34
- data/mkbrut/templates/Base/app/src/front_end/images/LogoPylon.png +0 -0
- data/mkbrut/templates/Base/bin/build-assets +0 -7
- data/mkbrut/templates/Base/bin/ci +0 -39
- data/mkbrut/templates/Base/bin/db +0 -9
- data/mkbrut/templates/Base/bin/scaffold +0 -9
- data/mkbrut/templates/Base/bin/setup +0 -287
- data/mkbrut/templates/Base/bin/test +0 -9
- data/mkbrut/templates/Base/bin/test-server +0 -29
- data/mkbrut/templates/Base/dx/prune +0 -19
- data/mkbrut/templates/Base/dx/start +0 -30
- data/mkbrut/templates/Base/dx/stop +0 -23
- data/mkbrut/templates/segments/Heroku/deploy/heroku_config.rb +0 -27
- data/specs/brut/front_end/forms/input.spec.rb +0 -978
- data/specs/brut/front_end/forms/radio_button_group_input.spec.rb +0 -54
- data/specs/brut/front_end/forms/select_input.spec.rb +0 -54
- data/specs/brut/instrumentation/methods.spec.rb +0 -399
- data/specs/brut/junk_drawer.spec.rb +0 -79
- data/specs/spec_helper.rb +0 -27
- data/specs/support/matchers/have_constraint_violation.rb +0 -23
- data/specs/support/matchers.rb +0 -5
- data/specs/support.rb +0 -3
- /data/{mkbrut/lib/mkbrut → lib/brut/cli/apps/new}/prefixed_io.rb +0 -0
- /data/{mkbrut/templates → templates}/Base/.dockerignore +0 -0
- /data/{mkbrut/templates → templates}/Base/.env.development.erb +0 -0
- /data/{mkbrut/templates → templates}/Base/.env.test.erb +0 -0
- /data/{mkbrut/templates → templates}/Base/.gitignore +0 -0
- /data/{mkbrut/templates → templates}/Base/.projections.json +0 -0
- /data/{mkbrut/templates → templates}/Base/Dockerfile.dx +0 -0
- /data/{mkbrut/templates → templates}/Base/Gemfile.erb +0 -0
- /data/{mkbrut/templates → templates}/Base/Procfile.development +0 -0
- /data/{mkbrut/templates → templates}/Base/Procfile.test +0 -0
- /data/{mkbrut/templates → templates}/Base/README.md +0 -0
- /data/{mkbrut/templates → templates}/Base/README.md.erb +0 -0
- /data/{mkbrut/templates → templates}/Base/app/bootstrap.rb +0 -0
- /data/{mkbrut/templates → templates}/Base/app/config/i18n/en/1_defaults.rb +0 -0
- /data/{mkbrut/templates → templates}/Base/app/config/i18n/en/2_app.rb +0 -0
- /data/{mkbrut/templates → templates}/Base/app/public/static/manifest.json.erb +0 -0
- /data/{mkbrut/templates → templates}/Base/app/src/app.rb.erb +0 -0
- /data/{mkbrut/templates → templates}/Base/app/src/back_end/data_models/app_data_model.rb +0 -0
- /data/{mkbrut/templates → templates}/Base/app/src/back_end/data_models/db.rb +0 -0
- /data/{mkbrut/templates → templates}/Base/app/src/back_end/data_models/migrations/20240101130000_citext.rb +0 -0
- /data/{mkbrut/templates → templates}/Base/app/src/back_end/data_models/seed/seed_data.rb +0 -0
- /data/{mkbrut/templates → templates}/Base/app/src/front_end/components/app_component.rb +0 -0
- /data/{mkbrut/templates → templates}/Base/app/src/front_end/components/custom_element_registration.rb.erb +0 -0
- /data/{mkbrut/templates → templates}/Base/app/src/front_end/css/index.css +0 -0
- /data/{mkbrut/templates → templates}/Base/app/src/front_end/css/svgs.css +0 -0
- /data/{mkbrut/templates → templates}/Base/app/src/front_end/forms/app_form.rb +0 -0
- /data/{mkbrut/templates → templates}/Base/app/src/front_end/handlers/app_handler.rb +0 -0
- /data/{brutrb.com → templates/Base/app/src/front_end}/images/LogoPylon.png +0 -0
- /data/{mkbrut/templates → templates}/Base/app/src/front_end/images/LogoTransit.png +0 -0
- /data/{mkbrut/templates → templates}/Base/app/src/front_end/images/apple-touch-icon-120x120.png +0 -0
- /data/{mkbrut/templates → templates}/Base/app/src/front_end/images/apple-touch-icon-152x152.png +0 -0
- /data/{mkbrut/templates → templates}/Base/app/src/front_end/images/apple-touch-icon-167x167.png +0 -0
- /data/{mkbrut/templates → templates}/Base/app/src/front_end/images/apple-touch-icon-180x180.png +0 -0
- /data/{mkbrut/templates → templates}/Base/app/src/front_end/images/favicon.ico +0 -0
- /data/{mkbrut/templates → templates}/Base/app/src/front_end/images/icon.png +0 -0
- /data/{mkbrut/templates → templates}/Base/app/src/front_end/images/mkicons.sh +0 -0
- /data/{mkbrut/templates → templates}/Base/app/src/front_end/js/index.js +0 -0
- /data/{mkbrut/templates → templates}/Base/app/src/front_end/layouts/blank_layout.rb +0 -0
- /data/{mkbrut/templates → templates}/Base/app/src/front_end/layouts/default_layout.rb.erb +0 -0
- /data/{mkbrut/templates → templates}/Base/app/src/front_end/pages/app_page.rb +0 -0
- /data/{mkbrut/templates → templates}/Base/app/src/front_end/pages/home_page.rb +0 -0
- /data/{mkbrut/templates → templates}/Base/app/src/front_end/support/app_session.rb +0 -0
- /data/{mkbrut/templates → templates}/Base/app/src/front_end/svgs/README.md +0 -0
- /data/{mkbrut/templates → templates}/Base/app/src/front_end/svgs/comment-button.svg +0 -0
- /data/{mkbrut/templates → templates}/Base/bin/README.md.erb +0 -0
- /data/{mkbrut/templates → templates}/Base/bin/console +0 -0
- /data/{mkbrut/templates → templates}/Base/bin/dbconsole +0 -0
- /data/{mkbrut/templates → templates}/Base/bin/dev +0 -0
- /data/{mkbrut/templates → templates}/Base/bin/run +0 -0
- /data/{mkbrut/templates → templates}/Base/bin/run.run +0 -0
- /data/{mkbrut/templates → templates}/Base/bin/startup-message +0 -0
- /data/{mkbrut/templates → templates}/Base/config.ru +0 -0
- /data/{mkbrut/templates → templates}/Base/docker-compose.dx.yml +0 -0
- /data/{mkbrut/templates → templates}/Base/dx/README.md +0 -0
- /data/{mkbrut/templates → templates}/Base/dx/bash_customizations +0 -0
- /data/{mkbrut/templates → templates}/Base/dx/bash_customizations.local +0 -0
- /data/{mkbrut/templates → templates}/Base/dx/build +0 -0
- /data/{mkbrut/templates → templates}/Base/dx/dx.sh.lib +0 -0
- /data/{mkbrut/templates → templates}/Base/dx/exec +0 -0
- /data/{dx → templates/Base/dx}/prune +0 -0
- /data/{mkbrut/templates → templates}/Base/dx/show-help-in-app-container-then-wait.sh +0 -0
- /data/{dx → templates/Base/dx}/start +0 -0
- /data/{dx → templates/Base/dx}/stop +0 -0
- /data/{mkbrut/templates → templates}/Base/package.json.erb +0 -0
- /data/{mkbrut/templates → templates}/Base/puma.config.rb +0 -0
- /data/{mkbrut/templates → templates}/Base/specs/e2e/home_page.spec.rb.erb +0 -0
- /data/{mkbrut/templates → templates}/Base/specs/front_end/js/SpecHelper.js +0 -0
- /data/{mkbrut/templates → templates}/Base/specs/front_end/pages/home_page.spec.rb +0 -0
- /data/{mkbrut/templates → templates}/Base/specs/lint_factories.spec.rb +0 -0
- /data/{mkbrut/templates → templates}/Base/specs/spec_helper.rb +0 -0
- /data/{mkbrut/templates → templates}/Base/specs/support.rb +0 -0
- /data/{mkbrut/templates → templates}/segments/BareBones/app/src/front_end/handlers/trigger_exception_handler.rb +0 -0
- /data/{mkbrut/templates → templates}/segments/BareBones/app/src/front_end/js/Example.js.erb +0 -0
- /data/{mkbrut/templates → templates}/segments/BareBones/specs/front_end/handlers/trigger_exception_handler.spec.rb +0 -0
- /data/{mkbrut/templates → templates}/segments/BareBones/specs/front_end/js/Example.spec.js.erb +0 -0
- /data/{mkbrut/templates → templates}/segments/Demo/app/src/back_end/data_models/db/guestbook_message.rb +0 -0
- /data/{mkbrut/templates → templates}/segments/Demo/app/src/back_end/data_models/migrations/20250628194124_guestbook.rb +0 -0
- /data/{mkbrut/templates → templates}/segments/Demo/app/src/front_end/components/flash_component.rb +0 -0
- /data/{mkbrut/templates → templates}/segments/Demo/app/src/front_end/css/constraint-violations.css +0 -0
- /data/{mkbrut/templates → templates}/segments/Demo/app/src/front_end/fonts/monaspace-xenon.ttf +0 -0
- /data/{mkbrut/templates → templates}/segments/Demo/app/src/front_end/forms/guestbook_message_form.rb +0 -0
- /data/{mkbrut/templates → templates}/segments/Demo/app/src/front_end/handlers/guestbook_message_handler.rb +0 -0
- /data/{mkbrut/templates → templates}/segments/Demo/app/src/front_end/pages/guestbook_page/message_component.rb +0 -0
- /data/{mkbrut/templates → templates}/segments/Demo/app/src/front_end/pages/guestbook_page.rb +0 -0
- /data/{mkbrut/templates → templates}/segments/Demo/app/src/front_end/pages/new_guestbook_message_page.rb +0 -0
- /data/{mkbrut/templates → templates}/segments/Demo/specs/back_end/data_models/db/guestbook_message.spec.rb +0 -0
- /data/{mkbrut/templates → templates}/segments/Demo/specs/e2e/guest_message.spec.rb +0 -0
- /data/{mkbrut/templates → templates}/segments/Demo/specs/factories/db/guestbook_message.factory.rb +0 -0
- /data/{mkbrut/templates → templates}/segments/Demo/specs/front_end/components/flash_component.spec.rb +0 -0
- /data/{mkbrut/templates → templates}/segments/Demo/specs/front_end/handlers/guestbook_message_handler.spec.rb +0 -0
- /data/{mkbrut/templates → templates}/segments/Demo/specs/front_end/pages/guestbook_page/message_component.spec.rb +0 -0
- /data/{mkbrut/templates → templates}/segments/Demo/specs/front_end/pages/guestbook_page.spec.rb +0 -0
- /data/{mkbrut/templates → templates}/segments/Demo/specs/front_end/pages/new_guestbook_message_page.spec.rb +0 -0
- /data/{mkbrut/templates → templates}/segments/Heroku/bin/deploy +0 -0
- /data/{mkbrut/templates → templates}/segments/Heroku/deploy/docker-entrypoint +0 -0
- /data/{mkbrut/templates → templates}/segments/Sidekiq/app/boot_sidekiq.rb +0 -0
- /data/{mkbrut/templates → templates}/segments/Sidekiq/app/config/sidekiq.yml +0 -0
- /data/{mkbrut/templates → templates}/segments/Sidekiq/app/src/back_end/jobs/app_job.rb +0 -0
- /data/{mkbrut/templates → templates}/segments/Sidekiq/app/src/back_end/jobs/example_job.rb +0 -0
- /data/{mkbrut/templates → templates}/segments/Sidekiq/app/src/back_end/segments/sidekiq_segment.rb +0 -0
- /data/{mkbrut/templates → templates}/segments/Sidekiq/bin/run.sidekiq +0 -0
- /data/{mkbrut/templates → templates}/segments/Sidekiq/specs/back_end/jobs/example_job.spec.rb +0 -0
- /data/{mkbrut/templates → templates}/segments/Sidekiq/specs/integration/sidekiq_works.spec.rb +0 -0
data/lib/brut/cli/apps/test.rb
CHANGED
|
@@ -1,23 +1,27 @@
|
|
|
1
1
|
require "shellwords"
|
|
2
2
|
require "brut/cli"
|
|
3
3
|
|
|
4
|
-
class Brut::CLI::Apps::Test < Brut::CLI::
|
|
5
|
-
description "Run and audit tests of the app"
|
|
6
|
-
default_command :run
|
|
4
|
+
class Brut::CLI::Apps::Test < Brut::CLI::Commands::BaseCommand
|
|
5
|
+
def description = "Run and audit tests of the app"
|
|
7
6
|
|
|
8
|
-
def
|
|
9
|
-
|
|
10
|
-
|
|
7
|
+
def default_rack_env = "development"
|
|
8
|
+
def default_command_class = Run
|
|
9
|
+
|
|
10
|
+
class Run < Brut::CLI::Commands::BaseCommand
|
|
11
|
+
def default_rack_env = "development"
|
|
12
|
+
def description = "Run non-e2e tests"
|
|
13
|
+
def opts = [
|
|
14
|
+
[ "--[no-]rebuild", "If true, test database is rebuilt before tests are run (default false)" ],
|
|
15
|
+
[ "--[no-]rebuild-after", "If true, test database is rebuilt after tests are run (default false)" ],
|
|
16
|
+
[ "--seed SEED", "Set the random seed to allow duplicating a test run" ],
|
|
17
|
+
]
|
|
18
|
+
def args_description = "specs_to_run..."
|
|
11
19
|
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
args "specs_to_run..."
|
|
18
|
-
env_var("LOGGER_LEVEL_FOR_TESTS",purpose: "Can be set to debug, info, warn, error, or fatal to control logging during tests. Defaults to 'warn' to avoid verbose test output")
|
|
19
|
-
env_var("RSPEC_WARNINGS", purpose: "If set to 'true', configures RSpec warnings for the test run. NOTE: this is used in the app's spec_helper.rb so could've been removed")
|
|
20
|
-
env_var("RSPEC_PROFILE_EXAMPLES", purpose: "If set to any value, it is converted to an int and set as RSpec's number of examples to profile. NOTE: this is used in the app's spec_helper.rb so could've been removed")
|
|
20
|
+
def env_vars = [
|
|
21
|
+
[ "LOGGER_LEVEL_FOR_TESTS","Can be set to debug, info, warn, error, or fatal to control logging during tests. Defaults to 'warn' to avoid verbose test output" ],
|
|
22
|
+
[ "RSPEC_WARNINGS", "If set to 'true', configures RSpec warnings for the test run. NOTE: this is used in the app's spec_helper.rb so could've been removed" ],
|
|
23
|
+
[ "RSPEC_PROFILE_EXAMPLES", "If set to any value, it is converted to an int and set as RSpec's number of examples to profile. NOTE: this is used in the app's spec_helper.rb so could've been removed" ],
|
|
24
|
+
]
|
|
21
25
|
|
|
22
26
|
|
|
23
27
|
def rspec_command
|
|
@@ -25,9 +29,9 @@ class Brut::CLI::Apps::Test < Brut::CLI::App
|
|
|
25
29
|
"bin/rspec",
|
|
26
30
|
"-I", Brut.container.app_specs_dir,
|
|
27
31
|
"-I", Brut.container.app_src_dir,
|
|
28
|
-
"-I lib/", # not needed when Brut is gemified
|
|
32
|
+
#"-I lib/", # not needed when Brut is gemified
|
|
29
33
|
rspec_cli_args,
|
|
30
|
-
"-P
|
|
34
|
+
"-P '**/*.spec.rb'",
|
|
31
35
|
]
|
|
32
36
|
if options.seed
|
|
33
37
|
parts << "--seed #{options.seed}"
|
|
@@ -40,72 +44,92 @@ class Brut::CLI::Apps::Test < Brut::CLI::App
|
|
|
40
44
|
def rebuild_by_default? = false
|
|
41
45
|
def rebuild_after_by_default? = false
|
|
42
46
|
|
|
43
|
-
def
|
|
44
|
-
Brut.container.sequel_db_handle.disconnect
|
|
47
|
+
def run
|
|
45
48
|
if options.rebuild?(default: rebuild_by_default?)
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
system! "
|
|
49
|
-
end
|
|
50
|
-
end
|
|
51
|
-
Brut.container.instrumentation.span("tests.run") do |span|
|
|
52
|
-
if args.empty?
|
|
53
|
-
span.add_prefixed_attributes("brut.cli.test", tests: :all)
|
|
54
|
-
out.puts "Running all tests"
|
|
55
|
-
system! "#{rspec_command} #{Brut.container.app_specs_dir}/"
|
|
56
|
-
else
|
|
57
|
-
span.add_prefixed_attributes("brut.cli.test", tests: args.length)
|
|
58
|
-
test_args = args.map { |_|
|
|
59
|
-
'"' + Shellwords.escape(_) + '"'
|
|
60
|
-
}.join(" ")
|
|
61
|
-
system! "#{rspec_command} #{test_args}"
|
|
49
|
+
stdout.puts "Rebuilding test database schema"
|
|
50
|
+
Bundler.with_unbundled_env do
|
|
51
|
+
system! "brut db rebuild --env=test"
|
|
62
52
|
end
|
|
63
53
|
end
|
|
54
|
+
run_tests
|
|
64
55
|
if options.rebuild_after?(default: rebuild_after_by_default?)
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
system! "
|
|
56
|
+
stdout.puts "Re-Rebuilding test database schema"
|
|
57
|
+
Bundler.with_unbundled_env do
|
|
58
|
+
system! "brut db rebuild --env=test"
|
|
68
59
|
end
|
|
69
60
|
end
|
|
70
61
|
0
|
|
71
62
|
end
|
|
63
|
+
|
|
64
|
+
private
|
|
65
|
+
|
|
66
|
+
def run_tests
|
|
67
|
+
command = if argv.empty?
|
|
68
|
+
stdout.puts "Running all tests"
|
|
69
|
+
"#{rspec_command} #{Brut.container.app_specs_dir}/"
|
|
70
|
+
else
|
|
71
|
+
stdout.puts "Running only #{argv.join(", ")}"
|
|
72
|
+
test_args = argv.map { |_|
|
|
73
|
+
'"' + Shellwords.escape(_) + '"'
|
|
74
|
+
}.join(" ")
|
|
75
|
+
"#{rspec_command} #{test_args}"
|
|
76
|
+
end
|
|
77
|
+
Bundler.with_unbundled_env do
|
|
78
|
+
system! command
|
|
79
|
+
end
|
|
80
|
+
end
|
|
72
81
|
end
|
|
73
82
|
class E2e < Run
|
|
74
|
-
description "Run
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
env_var("E2E_SLOW_MO",purpose: "If set to, will attempt to slow operations down by this many milliseconds")
|
|
81
|
-
env_var("E2E_TIMEOUT_MS",purpose: "ms to wait for any browser activity before failing the test. And here you didn't think you'd get away without using sleep in browse-based tests?")
|
|
82
|
-
env_var("LOGGER_LEVEL_FOR_TESTS",purpose: "Can be set to debug, info, warn, error, or fatal to control logging during tests. Defaults to 'warn' to avoid verbose test output")
|
|
83
|
-
env_var("RSPEC_WARNINGS", purpose: "If set to 'true', configures RSpec warnings for the test run. NOTE: this is used in the app's spec_helper.rb so could've been removed")
|
|
84
|
-
env_var("RSPEC_PROFILE_EXAMPLES", purpose: "If set to any value, it is converted to an int and set as RSpec's number of examples to profile. NOTE: this is used in the app's spec_helper.rb so could've been removed")
|
|
83
|
+
def description = "Run end-to-end (browser) tests"
|
|
84
|
+
def env_vars = super + [
|
|
85
|
+
[ "E2E_RECORD_VIDEOS","If set to 'true', videos of each test run are saved in `./tmp/e2e-videos`" ],
|
|
86
|
+
[ "E2E_SLOW_MO","If set to, will attempt to slow operations down by this many milliseconds" ],
|
|
87
|
+
[ "E2E_TIMEOUT_MS","ms to wait for any browser activity before failing the test. And here you didn't think you'd get away without using sleep in browse-based tests?" ],
|
|
88
|
+
]
|
|
85
89
|
|
|
86
90
|
def rspec_cli_args = "--tag e2e"
|
|
87
91
|
def rebuild_by_default? = true
|
|
88
92
|
def rebuild_after_by_default? = true
|
|
93
|
+
|
|
94
|
+
private
|
|
95
|
+
|
|
96
|
+
def run_tests
|
|
97
|
+
require "brut/spec_support/e2e_test_server"
|
|
98
|
+
Brut::SpecSupport::E2ETestServer.instance.start
|
|
99
|
+
super
|
|
100
|
+
ensure
|
|
101
|
+
Brut::SpecSupport::E2ETestServer.instance.stop
|
|
102
|
+
end
|
|
89
103
|
end
|
|
90
|
-
class Js < Brut::CLI::
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
def
|
|
104
|
+
class Js < Brut::CLI::Commands::BaseCommand
|
|
105
|
+
def default_rack_env = "development"
|
|
106
|
+
def description = "Run JavaScript unit tests"
|
|
107
|
+
def opts = [
|
|
108
|
+
[ "--[no-]build-assets","Build all assets before running the tests" ],
|
|
109
|
+
]
|
|
110
|
+
|
|
111
|
+
def run
|
|
112
|
+
options.set_default(:"build-assets", true)
|
|
94
113
|
if options.build_assets?
|
|
95
|
-
|
|
114
|
+
Bundler.with_unbundled_env do
|
|
115
|
+
system!({ "RACK_ENV" => "test" }, "brut build-assets all")
|
|
116
|
+
end
|
|
96
117
|
end
|
|
97
118
|
system!({ "NODE_DISABLE_COLORS" => "1" },"npx mocha #{Brut.container.js_specs_dir} --no-color --extension 'spec.js' --recursive")
|
|
98
119
|
0
|
|
99
120
|
end
|
|
100
121
|
end
|
|
101
|
-
class Audit < Brut::CLI::
|
|
102
|
-
|
|
122
|
+
class Audit < Brut::CLI::Commands::BaseCommand
|
|
123
|
+
def default_rack_env = "development"
|
|
124
|
+
def description = "Audits all of the app's classes to see if test files exist"
|
|
103
125
|
|
|
104
|
-
opts
|
|
105
|
-
|
|
106
|
-
|
|
126
|
+
def opts = [
|
|
127
|
+
[ "--ignore PATH[,PATH]","Ignore any files in these paths, relative to app root",Array ],
|
|
128
|
+
[ "--type TYPE","Only audit this type of file" ],
|
|
129
|
+
[ "--show-scaffold","If set, shows the command to scaffold the missing tests" ],
|
|
130
|
+
]
|
|
107
131
|
|
|
108
|
-
def
|
|
132
|
+
def run
|
|
109
133
|
app_files = Dir["#{Brut.container.app_src_dir}/**/*"].select { |file|
|
|
110
134
|
if file.start_with?(Brut.container.app_specs_dir.to_s)
|
|
111
135
|
false
|
|
@@ -175,43 +199,45 @@ class Brut::CLI::Apps::Test < Brut::CLI::App
|
|
|
175
199
|
hash[:type] = :infrastructure
|
|
176
200
|
hash[:test_expected] = false
|
|
177
201
|
else
|
|
178
|
-
hash[:type] =
|
|
202
|
+
hash[:type] = pathname.relative_path_from(Brut.container.back_end_src_dir).dirname
|
|
179
203
|
end
|
|
180
204
|
else
|
|
181
205
|
hash[:type] = :other
|
|
182
206
|
hash[:test_expected] = false
|
|
183
207
|
end
|
|
184
208
|
hash
|
|
185
|
-
}.compact
|
|
209
|
+
}.compact.sort_by { it[:type].to_s + it[:source_file].to_s }
|
|
186
210
|
|
|
187
211
|
files_missing = []
|
|
188
212
|
printed_header = false
|
|
189
213
|
audit.each do |file_audit|
|
|
190
214
|
if !file_audit[:test_file].exist?
|
|
191
|
-
if options.
|
|
215
|
+
if options.type.nil? || file_audit[:type] == options.type.to_sym
|
|
192
216
|
if file_audit[:test_expected]
|
|
193
217
|
files_missing << file_audit[:source_file]
|
|
194
218
|
if !printed_header
|
|
195
|
-
|
|
196
|
-
|
|
219
|
+
stdout.puts "These files are missing tests:"
|
|
220
|
+
stdout.puts ""
|
|
221
|
+
stdout.printf "%-25s %s\n","Type", "Path"
|
|
222
|
+
stdout.puts "-------------------------------------------"
|
|
197
223
|
printed_header = true
|
|
198
224
|
end
|
|
199
|
-
|
|
225
|
+
stdout.puts "#{file_audit[:type].to_s.ljust(25)} - #{file_audit[:source_file]}"
|
|
200
226
|
end
|
|
201
227
|
end
|
|
202
228
|
end
|
|
203
229
|
end
|
|
204
230
|
if files_missing.empty?
|
|
205
|
-
|
|
231
|
+
stdout.puts "All tests exists!"
|
|
206
232
|
0
|
|
207
233
|
else
|
|
208
234
|
if options.show_scaffold?
|
|
209
|
-
|
|
235
|
+
stdout.puts
|
|
210
236
|
files_missing_args = files_missing.map { |file|
|
|
211
237
|
' "' + Shellwords.escape(file.to_s) + '"'
|
|
212
238
|
}.join(" \\\n")
|
|
213
239
|
|
|
214
|
-
|
|
240
|
+
stdout.puts "Run this command to generate empty tests:\n\nbrut scaffold test \\\n#{files_missing_args}"
|
|
215
241
|
end
|
|
216
242
|
1
|
|
217
243
|
end
|
|
@@ -0,0 +1,174 @@
|
|
|
1
|
+
require "brut/junk_drawer"
|
|
2
|
+
class Brut::CLI::Commands::BaseCommand
|
|
3
|
+
|
|
4
|
+
attr_accessor :parent_command
|
|
5
|
+
|
|
6
|
+
# The name of the command that the developer should use on the command line. By default, this is
|
|
7
|
+
# the underscorized version of the class' simple name.
|
|
8
|
+
# @return [String] String the developer should use on the command line. If it has spaces or
|
|
9
|
+
# characters special to the shell, you will have a great sadness and possibly other mayhem.
|
|
10
|
+
def name = RichString.new(self.class.name.split(/::/).last).underscorized
|
|
11
|
+
|
|
12
|
+
# Execute the command in the given context. This is the method to call to execute a command programmatically, however you
|
|
13
|
+
# should not override this method. Instead, override `.run` to provide your command's logic.
|
|
14
|
+
#
|
|
15
|
+
# @param [Brut::CLI::ExecutionContext] execution_context the context in which the command will run, providing access
|
|
16
|
+
# to standard streams, the parsed options, and unparsed arguments.
|
|
17
|
+
def execute(execution_context)
|
|
18
|
+
@execution_context = execution_context
|
|
19
|
+
self.run
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
# True if the command requires Brut to fully bootstrap and start itself up. Bootstrapping isn't running a web server but it will
|
|
23
|
+
# do everything else, including connecting too all databases. Your command should return true for this if it needs to access a database
|
|
24
|
+
# or make API calls outside `Brut::CLI`. If this returns false, Brut's configuration options will still be available.
|
|
25
|
+
#
|
|
26
|
+
# By default, this returns the value for `bootstrap?` of the `default_command`. If there is no `default_command`, this returns false.
|
|
27
|
+
#
|
|
28
|
+
# @return [true|false] True if Brut should be fully bootstrap and connect to all database servers (e.g.). False if Brut should only
|
|
29
|
+
# set up its configuration options.
|
|
30
|
+
def bootstrap? = default_command&.bootstrap? || false
|
|
31
|
+
|
|
32
|
+
# The default `RACK_ENV` to use for this command. This value is used when no `RACK_ENV` is present in the UNIX environment
|
|
33
|
+
# and when `--env` has not been used on the command line. Do note that setting this in an app or parent command does
|
|
34
|
+
# not translate to the subcommands.
|
|
35
|
+
#
|
|
36
|
+
# @return [String|nil] If nil, Brut configuration will not be loaded and the command will run more or less as if it were a plain
|
|
37
|
+
# Ruby script. If a `String`, this value will be set as the `RACK_ENV` if it's not been otherwise specified.
|
|
38
|
+
def default_rack_env = default_command&.default_rack_env
|
|
39
|
+
|
|
40
|
+
# @return [String] description of this command for use in help output
|
|
41
|
+
def description = ""
|
|
42
|
+
|
|
43
|
+
# @return [String] description of the arguments this command accepts. Used for documentation only.
|
|
44
|
+
def args_description = nil
|
|
45
|
+
|
|
46
|
+
# @return [Array<Array<String>>] Array of arrays documenting which environment variables affect this command's behavior.
|
|
47
|
+
# The array should have two elements: the env var name as a string, and a string documenting its purpose. This is
|
|
48
|
+
# used for documentation only.
|
|
49
|
+
def env_vars = []
|
|
50
|
+
|
|
51
|
+
# Used to specify the command line options for the command.
|
|
52
|
+
# @return [Array<Array<Object>>] an array of arrays representing this command's reecognized command line options. Each member
|
|
53
|
+
# of the array is treated as arguments to `OptionParser#on`. Please consult the Rubydoc for that method to know what
|
|
54
|
+
# you can use here. It is quite flexible, including type conversions, documentation, and multiple forms of options.
|
|
55
|
+
def opts = []
|
|
56
|
+
|
|
57
|
+
# Specify type conversions for options. This is a loose wrapper around `OptionParser#accept` with a convienience feature
|
|
58
|
+
# to allow simpler conversions without a proc.
|
|
59
|
+
#
|
|
60
|
+
# @example
|
|
61
|
+
# class Type
|
|
62
|
+
# def initialize(value)
|
|
63
|
+
# value = value.to_s
|
|
64
|
+
# if ["new", "old", "promoted" ].include?(value)
|
|
65
|
+
# @value = value
|
|
66
|
+
# else
|
|
67
|
+
# raise ArgumentError, "'#{value}' is not a valid Type"
|
|
68
|
+
# end
|
|
69
|
+
# end
|
|
70
|
+
# end
|
|
71
|
+
# def opts = [
|
|
72
|
+
# [ "--type=TYPE", "The type of thing", Type ]
|
|
73
|
+
# ]
|
|
74
|
+
# def accepts = [
|
|
75
|
+
# Type,
|
|
76
|
+
# ]
|
|
77
|
+
# # or
|
|
78
|
+
# def accepts = [
|
|
79
|
+
# [ Type, ->(val) { Type.new(val) },
|
|
80
|
+
# ]
|
|
81
|
+
#
|
|
82
|
+
# @return [Array<Array>|Array<Class>] Must be an array. Any element that is a class will be used to convert any options
|
|
83
|
+
# of that type when the type is used in `opts`. If the element is a class, it is assumed that values can be converted
|
|
84
|
+
# via `.new`. If the class does not support `.new` as a conversion method, the element should be a two-element array
|
|
85
|
+
# where index 0 is the class and index 1 is a proc to convert the command line argument to the class's type.
|
|
86
|
+
def accepts = []
|
|
87
|
+
|
|
88
|
+
# Command to run if none provided on the command line.
|
|
89
|
+
# @return [Brut::CLI::Commands::BaseCommand|nil] if `nil`, it is an error to run this command without a subcommand. If not-`nil`,
|
|
90
|
+
# the returned command will be executed.
|
|
91
|
+
def default_command = self.commands.detect { it.class == default_command_class }
|
|
92
|
+
|
|
93
|
+
def default_command_class = nil
|
|
94
|
+
|
|
95
|
+
# Returns a list of commands that represent the subcommands available to this command. By default, this
|
|
96
|
+
# will return all commands that are inner classes of this command.
|
|
97
|
+
#
|
|
98
|
+
# @return [Array<Brut::CLI::Commands::BaseCommand>]
|
|
99
|
+
def commands
|
|
100
|
+
self.class.constants.map { |name|
|
|
101
|
+
self.class.const_get(name)
|
|
102
|
+
}.select { |constant|
|
|
103
|
+
constant.kind_of?(Class) && constant.ancestors.include?(Brut::CLI::Commands::BaseCommand)
|
|
104
|
+
}.map(&:new)
|
|
105
|
+
end
|
|
106
|
+
|
|
107
|
+
private
|
|
108
|
+
|
|
109
|
+
# Provides access the `Brut::CLI::Commands::ExecutionContext` used the last time `#execute` was called.
|
|
110
|
+
# This should only be accessed in tests and sparingly.
|
|
111
|
+
def execution_context
|
|
112
|
+
@execution_context ||= Brut::CLI::Commands::ExecutionContext.new
|
|
113
|
+
end
|
|
114
|
+
|
|
115
|
+
# Access the command line arguments leftover after all options have been parsed, when `.execute` was called
|
|
116
|
+
#
|
|
117
|
+
# @return [Array<String>] leftover command line arguments
|
|
118
|
+
# @!visibility public
|
|
119
|
+
def argv = self.execution_context.argv
|
|
120
|
+
|
|
121
|
+
# Convienience methods to defer to `Brut::CLI::Commands::ExecutionContext`'s `Brut::CLI::Executor#system!`.
|
|
122
|
+
# @!visibility public
|
|
123
|
+
def system!(*args,&block)
|
|
124
|
+
self.execution_context.executor.system!(*args,&block)
|
|
125
|
+
end
|
|
126
|
+
|
|
127
|
+
# Convienience methods to defer to `Brut::CLI::Commands::ExecutionContext#stdout`'s `puts`.
|
|
128
|
+
# @!visibility public
|
|
129
|
+
def puts(*args)
|
|
130
|
+
self.execution_context.stdout.puts(*args)
|
|
131
|
+
end
|
|
132
|
+
|
|
133
|
+
# Convienience methods to defer to `Brut::CLI::Commands::ExecutionContext#stderr`. You should use this over `STDERR` or `$stderr`.
|
|
134
|
+
# @!visibility public
|
|
135
|
+
def stderr = self.execution_context.stderr
|
|
136
|
+
# Convienience methods to defer to `Brut::CLI::Commands::ExecutionContext#stdin`. You should use this over `STDIN` of `$stdin`.
|
|
137
|
+
# @!visibility public
|
|
138
|
+
def stdin = self.execution_context.stdin
|
|
139
|
+
# Convienience methods to defer to `Brut::CLI::Commands::ExecutionContext#stdout`. You should use this over `STDOUT` of `$stdout`. Note
|
|
140
|
+
# that if you just want to output a string, use `puts`.
|
|
141
|
+
# @!visibility public
|
|
142
|
+
def stdout = self.execution_context.stdout
|
|
143
|
+
# Convienience methods to defer to `Brut::CLI::Commands::ExecutionContext#options`.
|
|
144
|
+
# @!visibility public
|
|
145
|
+
def options = self.execution_context.options
|
|
146
|
+
# Convienience methods to defer to `Brut::CLI::Commands::ExecutionContext#env`. You should use this over `ENV`.
|
|
147
|
+
# @!visibility public
|
|
148
|
+
def env = self.execution_context.env
|
|
149
|
+
|
|
150
|
+
|
|
151
|
+
# Runs whatever logic this command exists to execute. This is the method you must implement, however `#execute` is the public
|
|
152
|
+
# API and what you should call if you want to programmatically execute a command.
|
|
153
|
+
#
|
|
154
|
+
# The default implementation will generate an error, which is suitable for an app or namespace command that require a subcommand.
|
|
155
|
+
#
|
|
156
|
+
# @return [Integer|Object|StandardError] When an integer is returned, that is considered the exit status of the CLI
|
|
157
|
+
# invocation that ultimately called this command. If an `Object` (including `nil` and non-`Integer` numbers) is returned,
|
|
158
|
+
# the command is assumed to have succeeded and the return value is ignored. If an exception is returned, it's treated
|
|
159
|
+
# the same as if it were raised (don't return an exception).
|
|
160
|
+
# @raise [Brut::CLI::Error|StandardError] If a `Brut::CLI::Error`, the command
|
|
161
|
+
# is considered failed and the exception's message is printed to stderr and the exit status is nonzero. If another
|
|
162
|
+
# type of exception, it is bubbled up and shown to the user. Generally do not return any sort of exception - allow it to raise.
|
|
163
|
+
# @!visibility public
|
|
164
|
+
def run
|
|
165
|
+
if argv[0]
|
|
166
|
+
stderr.puts "No such command '#{argv[0]}'"
|
|
167
|
+
return 1
|
|
168
|
+
end
|
|
169
|
+
|
|
170
|
+
|
|
171
|
+
stderr.puts "Command is required"
|
|
172
|
+
1
|
|
173
|
+
end
|
|
174
|
+
end
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
# A command that exists only to call other commands in order. This is useful if you want
|
|
2
|
+
# a convienience command to call two or more other commands. By default, each command
|
|
3
|
+
# must succeed for the others to be called.
|
|
4
|
+
class Brut::CLI::Commands::CompoundCommand < Brut::CLI::Commands::BaseCommand
|
|
5
|
+
# Create the compound command with the given list of commands. Note that these
|
|
6
|
+
# commands will be executed with *this* commands `Brut::CLI::Commands::ExecutionContext`, so these commands
|
|
7
|
+
# should all be able to work with whatever command line arguments and `argv` would be provided.
|
|
8
|
+
def initialize(commands)
|
|
9
|
+
@commands = commands
|
|
10
|
+
end
|
|
11
|
+
|
|
12
|
+
# Overrides the parent class to call each command in order. Note that if you subclass this class, **`run` is
|
|
13
|
+
# not called**. If you want to perform custom logic, you must override this method, but take care to call
|
|
14
|
+
# methods on the passed `execution_context`. Methods like `puts`, `system!`, and `options` **will not work** here
|
|
15
|
+
# since they assume an ivar named `@execution_context` has been set.
|
|
16
|
+
def execute(execution_context)
|
|
17
|
+
@commands.each do |command|
|
|
18
|
+
execute_result = Brut::CLI::ExecuteResult.new do
|
|
19
|
+
command.execute(execution_context)
|
|
20
|
+
end
|
|
21
|
+
if execute_result.failed?
|
|
22
|
+
return execute_result.exit_status do |error_message|
|
|
23
|
+
@stderr.puts error_message
|
|
24
|
+
end
|
|
25
|
+
end
|
|
26
|
+
end
|
|
27
|
+
0
|
|
28
|
+
end
|
|
29
|
+
end
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
# The context in which a command's execution is run. This holds essentially all values that are input to
|
|
2
|
+
# the command, including parsed command line options, unparsed arguments, the UNIX environment, and
|
|
3
|
+
# the three s/O streams (stderr, stdout, stdin).
|
|
4
|
+
class Brut::CLI::Commands::ExecutionContext
|
|
5
|
+
|
|
6
|
+
def initialize(
|
|
7
|
+
argv: :default,
|
|
8
|
+
options: :default,
|
|
9
|
+
env: :default,
|
|
10
|
+
stdout: :default,
|
|
11
|
+
stderr: :default,
|
|
12
|
+
stdin: :default,
|
|
13
|
+
executor: :default
|
|
14
|
+
)
|
|
15
|
+
@argv = argv == :default ? [] : argv
|
|
16
|
+
@options = options == :default ? Brut::CLI::Options.new({}) : options
|
|
17
|
+
@env = env == :default ? {} : env
|
|
18
|
+
@stdout = Brut::CLI::Output.from_io(stdout == :default ? $stdout : stdout)
|
|
19
|
+
@stderr = Brut::CLI::Output.from_io(stderr == :default ? $stderr : stderr)
|
|
20
|
+
@stdin = stdin == :default ? $stdin : stdin
|
|
21
|
+
@executor = executor == :default ? Brut::CLI::Executor.new(out: self.stdout, err: self.stderr) : executor
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
attr_reader :argv,
|
|
25
|
+
:options,
|
|
26
|
+
:env,
|
|
27
|
+
:stdout,
|
|
28
|
+
:stderr,
|
|
29
|
+
:stdin,
|
|
30
|
+
:executor
|
|
31
|
+
|
|
32
|
+
end
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
class Brut::CLI::Commands::Help < Brut::CLI::Commands::BaseCommand
|
|
2
|
+
def description = "Get help for the app or a command"
|
|
3
|
+
attr_accessor :option_parser
|
|
4
|
+
|
|
5
|
+
def initialize(command,option_parser)
|
|
6
|
+
@command = command
|
|
7
|
+
@option_parser = option_parser
|
|
8
|
+
end
|
|
9
|
+
|
|
10
|
+
def commands = []
|
|
11
|
+
|
|
12
|
+
def run
|
|
13
|
+
stdout.puts_no_prefix @option_parser.to_s
|
|
14
|
+
if @command.commands.any?
|
|
15
|
+
stdout.puts_no_prefix
|
|
16
|
+
stdout.puts_no_prefix "COMMANDS"
|
|
17
|
+
stdout.puts_no_prefix
|
|
18
|
+
@command.commands.each do |command|
|
|
19
|
+
stdout.puts_no_prefix " #{command.name} - #{command.description}"
|
|
20
|
+
end
|
|
21
|
+
end
|
|
22
|
+
0
|
|
23
|
+
end
|
|
24
|
+
def bootstrap? = false
|
|
25
|
+
def default_rack_env = nil
|
|
26
|
+
end
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
class Brut::CLI::Commands::OutputError < Brut::CLI::Commands::BaseCommand
|
|
2
|
+
attr_reader :exception
|
|
3
|
+
def initialize(exception)
|
|
4
|
+
@exception = exception
|
|
5
|
+
end
|
|
6
|
+
def run
|
|
7
|
+
stderr.puts @exception.message
|
|
8
|
+
65
|
|
9
|
+
end
|
|
10
|
+
|
|
11
|
+
def bootstrap? = false
|
|
12
|
+
def default_rack_env = nil
|
|
13
|
+
end
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
module Brut::CLI::Commands
|
|
2
|
+
autoload(:BaseCommand, "brut/cli/commands/base_command")
|
|
3
|
+
autoload(:CompoundCommand, "brut/cli/commands/compound_command")
|
|
4
|
+
autoload(:Help, "brut/cli/commands/help")
|
|
5
|
+
autoload(:OutputError, "brut/cli/commands/output_error")
|
|
6
|
+
autoload(:RaiseError, "brut/cli/commands/raise_error")
|
|
7
|
+
autoload(:ExecutionContext, "brut/cli/commands/execution_context")
|
|
8
|
+
end
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
# Wraps the result of calling `Brut::CLI::Commands::BaseCommand#execute` and
|
|
2
|
+
# interpreting it as an exit code
|
|
3
|
+
class Brut::CLI::ExecuteResult
|
|
4
|
+
def initialize(&block)
|
|
5
|
+
@actual_result = begin
|
|
6
|
+
block.()
|
|
7
|
+
rescue Brut::CLI::Error => ex
|
|
8
|
+
ex
|
|
9
|
+
end
|
|
10
|
+
end
|
|
11
|
+
|
|
12
|
+
def success? = self.exit_status == 0
|
|
13
|
+
def failed? = !self.success?
|
|
14
|
+
|
|
15
|
+
# Get the exit status for the given result. This will call
|
|
16
|
+
# the block given with an error message if there is one.
|
|
17
|
+
#
|
|
18
|
+
# @yield [error_message] If a block is passed, it's called when a {Brut::CLI::Error} was the return
|
|
19
|
+
# value of the command, so that you can access the message of the error.
|
|
20
|
+
# @yieldparam error_message [String] the error message from the {Brut::CLI::Error}.
|
|
21
|
+
#
|
|
22
|
+
# @return [Integer] value betweeen 0 and 255 representing the exit status to use based on the
|
|
23
|
+
# value the command returned.
|
|
24
|
+
def exit_status(&when_error_message)
|
|
25
|
+
when_error_message ||= ->(*){}
|
|
26
|
+
case @actual_result
|
|
27
|
+
in Integer
|
|
28
|
+
@actual_result
|
|
29
|
+
in Brut::CLI::SystemExecError
|
|
30
|
+
when_error_message.(@actual_result.message)
|
|
31
|
+
@actual_result.exit_status
|
|
32
|
+
in Brut::CLI::Error
|
|
33
|
+
when_error_message.(@actual_result.message)
|
|
34
|
+
1
|
|
35
|
+
else
|
|
36
|
+
0
|
|
37
|
+
end
|
|
38
|
+
end
|
|
39
|
+
end
|
data/lib/brut/cli/executor.rb
CHANGED
|
@@ -50,7 +50,13 @@ class Brut::CLI::Executor
|
|
|
50
50
|
# @param [String|Array] args Whatever you would give to `Kernel#system` or `Open3.popen3`.
|
|
51
51
|
# @raise Brut::CLI::Error::SystemExecError if the spawed command exits nonzero
|
|
52
52
|
# @return [int] Always returns 0
|
|
53
|
-
def system!(*args)
|
|
53
|
+
def system!(*args,&block)
|
|
54
|
+
|
|
55
|
+
block ||= ->(output) {
|
|
56
|
+
@out.print output
|
|
57
|
+
@out.flush
|
|
58
|
+
}
|
|
59
|
+
|
|
54
60
|
@out.puts "Executing #{args}"
|
|
55
61
|
wait_thread = Open3.popen3(*args) do |_stdin,stdout,stderr,wait_thread|
|
|
56
62
|
o = stdout.read_nonblock(10, exception: false)
|
|
@@ -58,8 +64,7 @@ class Brut::CLI::Executor
|
|
|
58
64
|
while o || e
|
|
59
65
|
if o
|
|
60
66
|
if o != :wait_readable
|
|
61
|
-
|
|
62
|
-
@out.flush
|
|
67
|
+
block.(o)
|
|
63
68
|
end
|
|
64
69
|
o = stdout.read_nonblock(10, exception: false)
|
|
65
70
|
end
|
|
@@ -74,7 +79,7 @@ class Brut::CLI::Executor
|
|
|
74
79
|
wait_thread
|
|
75
80
|
end
|
|
76
81
|
if wait_thread.value.success?
|
|
77
|
-
@out.puts "#{args} succeeded"
|
|
82
|
+
@out.puts "#{args.length == 1 ? args[0] : args} succeeded"
|
|
78
83
|
else
|
|
79
84
|
raise Brut::CLI::SystemExecError.new(args,wait_thread.value.exitstatus)
|
|
80
85
|
end
|
data/lib/brut/cli/output.rb
CHANGED
|
@@ -14,6 +14,19 @@
|
|
|
14
14
|
# The prefix allows the human to know what output was generated by the app they ran and what not. This can be extremely helpful for
|
|
15
15
|
# debugging or just understanding what is going on.
|
|
16
16
|
class Brut::CLI::Output
|
|
17
|
+
|
|
18
|
+
def self.from_io(io_or_output)
|
|
19
|
+
case io_or_output
|
|
20
|
+
in Brut::CLI::Output
|
|
21
|
+
io_or_output
|
|
22
|
+
else
|
|
23
|
+
self.new(io: io_or_output, prefix: "")
|
|
24
|
+
end
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
attr_reader :io
|
|
28
|
+
attr_reader :prefix
|
|
29
|
+
|
|
17
30
|
# Create a wrapper for the given IO that will use the given prefix
|
|
18
31
|
#
|
|
19
32
|
# @param [IO] io an IO where output should be sent, for example `$stdout`.
|