├── .github ├── dependabot.yml ├── release-drafter.yml └── workflows │ ├── ci.yml │ └── release-drafter.yml ├── .gitignore ├── .kodiak.toml ├── .overcommit.yml ├── .prettierignore ├── .rubocop.yml ├── CHANGELOG.md ├── CODE_OF_CONDUCT.md ├── Gemfile ├── LICENSE.txt ├── README.md ├── Rakefile ├── bin ├── console ├── mt └── setup ├── config ├── generators.yml └── rails_versions.yml ├── demo.gif ├── examples ├── README.md ├── all │ ├── .annotaterb.yml │ ├── .dockerignore │ ├── .editorconfig │ ├── .env.sample │ ├── .erb_lint.yml │ ├── .gitattributes │ ├── .github │ │ ├── PULL_REQUEST_TEMPLATE.md │ │ ├── dependabot.yml │ │ └── workflows │ │ │ └── ci.yml │ ├── .gitignore │ ├── .overcommit.yml │ ├── .prettierrc.cjs │ ├── .rubocop.yml │ ├── .ruby-version │ ├── .stylelintrc.js │ ├── .tomo │ │ ├── config.rb │ │ └── plugins │ │ │ └── all_example.rb │ ├── DEPLOYMENT.md │ ├── Dockerfile │ ├── Gemfile │ ├── Gemfile.lock │ ├── Procfile │ ├── README.md │ ├── Rakefile │ ├── Thorfile │ ├── app │ │ ├── assets │ │ │ ├── images │ │ │ │ └── .keep │ │ │ └── stylesheets │ │ │ │ └── application.css │ │ ├── controllers │ │ │ ├── application_controller.rb │ │ │ ├── concerns │ │ │ │ ├── .keep │ │ │ │ └── basic_auth.rb │ │ │ └── home_controller.rb │ │ ├── helpers │ │ │ └── application_helper.rb │ │ ├── javascript │ │ │ ├── application.js │ │ │ └── controllers │ │ │ │ ├── application.js │ │ │ │ ├── hello_controller.js │ │ │ │ └── index.js │ │ ├── jobs │ │ │ └── application_job.rb │ │ ├── mailers │ │ │ └── application_mailer.rb │ │ ├── models │ │ │ ├── application_record.rb │ │ │ └── concerns │ │ │ │ └── .keep │ │ └── views │ │ │ ├── home │ │ │ └── index.html.erb │ │ │ ├── layouts │ │ │ ├── application.html.erb │ │ │ ├── mailer.html.erb │ │ │ └── mailer.text.erb │ │ │ └── pwa │ │ │ ├── manifest.json.erb │ │ │ └── service-worker.js │ ├── bin │ │ ├── brakeman │ │ ├── bundle │ │ ├── bundle-audit │ │ ├── bundler-audit │ │ ├── dev │ │ ├── docker-entrypoint │ │ ├── erb_lint │ │ ├── erblint │ │ ├── importmap │ │ ├── rails │ │ ├── rake │ │ ├── rubocop │ │ ├── setup │ │ ├── sidekiq │ │ ├── sidekiqmon │ │ ├── thor │ │ ├── thrust │ │ └── tomo │ ├── config.ru │ ├── config │ │ ├── application.rb │ │ ├── boot.rb │ │ ├── cable.yml │ │ ├── credentials.yml.enc │ │ ├── database.yml │ │ ├── environment.rb │ │ ├── environments │ │ │ ├── development.rb │ │ │ ├── production.rb │ │ │ ├── staging.rb │ │ │ └── test.rb │ │ ├── importmap.rb │ │ ├── initializers │ │ │ ├── assets.rb │ │ │ ├── content_security_policy.rb │ │ │ ├── filter_parameter_logging.rb │ │ │ ├── generators.rb │ │ │ ├── inflections.rb │ │ │ ├── rack_mini_profiler.rb │ │ │ └── sidekiq.rb │ │ ├── locales │ │ │ └── en.yml │ │ ├── puma.rb │ │ ├── routes.rb │ │ ├── sidekiq.yml │ │ └── storage.yml │ ├── db │ │ ├── schema.rb │ │ └── seeds.rb │ ├── eslint.config.js │ ├── lib │ │ ├── puma │ │ │ └── plugin │ │ │ │ └── open.rb │ │ └── tasks │ │ │ ├── .keep │ │ │ ├── annotate_rb.rake │ │ │ ├── erb_lint.rake │ │ │ ├── eslint.rake │ │ │ ├── rubocop.rake │ │ │ └── stylelint.rake │ ├── log │ │ └── .keep │ ├── package.json │ ├── public │ │ ├── 400.html │ │ ├── 404.html │ │ ├── 406-unsupported-browser.html │ │ ├── 422.html │ │ ├── 500.html │ │ ├── icon.png │ │ ├── icon.svg │ │ └── robots.txt │ ├── script │ │ └── .keep │ ├── storage │ │ └── .keep │ ├── test │ │ ├── application_system_test_case.rb │ │ ├── controllers │ │ │ └── .keep │ │ ├── fixtures │ │ │ └── files │ │ │ │ └── .keep │ │ ├── helpers │ │ │ └── .keep │ │ ├── integration │ │ │ └── .keep │ │ ├── mailers │ │ │ └── .keep │ │ ├── models │ │ │ └── .keep │ │ ├── support │ │ │ ├── capybara.rb │ │ │ ├── factory_bot.rb │ │ │ ├── mailer.rb │ │ │ ├── mocha.rb │ │ │ ├── shoulda.rb │ │ │ ├── vcr.rb │ │ │ └── webmock.rb │ │ ├── system │ │ │ └── .keep │ │ └── test_helper.rb │ ├── tmp │ │ ├── .keep │ │ ├── pids │ │ │ └── .keep │ │ └── storage │ │ │ └── .keep │ ├── vendor │ │ ├── .keep │ │ └── javascript │ │ │ └── .keep │ └── yarn.lock ├── default │ ├── .dockerignore │ ├── .editorconfig │ ├── .gitattributes │ ├── .github │ │ ├── dependabot.yml │ │ └── workflows │ │ │ └── ci.yml │ ├── .gitignore │ ├── .kamal │ │ ├── hooks │ │ │ ├── docker-setup.sample │ │ │ ├── post-deploy.sample │ │ │ ├── post-proxy-reboot.sample │ │ │ ├── pre-build.sample │ │ │ ├── pre-connect.sample │ │ │ ├── pre-deploy.sample │ │ │ └── pre-proxy-reboot.sample │ │ └── secrets │ ├── .prettierrc.cjs │ ├── .rubocop.yml │ ├── .ruby-version │ ├── DEPLOYMENT.md │ ├── Dockerfile │ ├── Gemfile │ ├── Gemfile.lock │ ├── Procfile │ ├── README.md │ ├── Rakefile │ ├── app │ │ ├── assets │ │ │ ├── images │ │ │ │ └── .keep │ │ │ └── stylesheets │ │ │ │ └── application.css │ │ ├── controllers │ │ │ ├── application_controller.rb │ │ │ ├── concerns │ │ │ │ └── .keep │ │ │ └── home_controller.rb │ │ ├── helpers │ │ │ └── application_helper.rb │ │ ├── javascript │ │ │ ├── application.js │ │ │ └── controllers │ │ │ │ ├── application.js │ │ │ │ ├── hello_controller.js │ │ │ │ └── index.js │ │ ├── jobs │ │ │ └── application_job.rb │ │ ├── mailers │ │ │ └── application_mailer.rb │ │ ├── models │ │ │ ├── application_record.rb │ │ │ └── concerns │ │ │ │ └── .keep │ │ └── views │ │ │ ├── home │ │ │ └── index.html.erb │ │ │ ├── layouts │ │ │ ├── application.html.erb │ │ │ ├── mailer.html.erb │ │ │ └── mailer.text.erb │ │ │ └── pwa │ │ │ ├── manifest.json.erb │ │ │ └── service-worker.js │ ├── bin │ │ ├── brakeman │ │ ├── bundle │ │ ├── dev │ │ ├── docker-entrypoint │ │ ├── importmap │ │ ├── jobs │ │ ├── kamal │ │ ├── rails │ │ ├── rake │ │ ├── rubocop │ │ ├── setup │ │ └── thrust │ ├── config.ru │ ├── config │ │ ├── application.rb │ │ ├── boot.rb │ │ ├── cable.yml │ │ ├── cache.yml │ │ ├── credentials.yml.enc │ │ ├── database.yml │ │ ├── deploy.yml │ │ ├── environment.rb │ │ ├── environments │ │ │ ├── development.rb │ │ │ ├── production.rb │ │ │ └── test.rb │ │ ├── importmap.rb │ │ ├── initializers │ │ │ ├── assets.rb │ │ │ ├── content_security_policy.rb │ │ │ ├── filter_parameter_logging.rb │ │ │ ├── generators.rb │ │ │ └── inflections.rb │ │ ├── locales │ │ │ └── en.yml │ │ ├── puma.rb │ │ ├── queue.yml │ │ ├── recurring.yml │ │ ├── routes.rb │ │ └── storage.yml │ ├── db │ │ ├── cable_schema.rb │ │ ├── cache_schema.rb │ │ ├── queue_schema.rb │ │ ├── schema.rb │ │ └── seeds.rb │ ├── lib │ │ └── tasks │ │ │ └── .keep │ ├── log │ │ └── .keep │ ├── public │ │ ├── 400.html │ │ ├── 404.html │ │ ├── 406-unsupported-browser.html │ │ ├── 422.html │ │ ├── 500.html │ │ ├── icon.png │ │ ├── icon.svg │ │ └── robots.txt │ ├── script │ │ └── .keep │ ├── storage │ │ └── .keep │ ├── test │ │ ├── application_system_test_case.rb │ │ ├── controllers │ │ │ └── .keep │ │ ├── fixtures │ │ │ └── files │ │ │ │ └── .keep │ │ ├── helpers │ │ │ └── .keep │ │ ├── integration │ │ │ └── .keep │ │ ├── mailers │ │ │ └── .keep │ │ ├── models │ │ │ └── .keep │ │ ├── support │ │ │ ├── capybara.rb │ │ │ └── mailer.rb │ │ ├── system │ │ │ └── .keep │ │ └── test_helper.rb │ ├── tmp │ │ ├── .keep │ │ ├── pids │ │ │ └── .keep │ │ └── storage │ │ │ └── .keep │ └── vendor │ │ ├── .keep │ │ └── javascript │ │ └── .keep ├── rspec │ ├── .dockerignore │ ├── .editorconfig │ ├── .gitattributes │ ├── .github │ │ ├── dependabot.yml │ │ └── workflows │ │ │ └── ci.yml │ ├── .gitignore │ ├── .kamal │ │ ├── hooks │ │ │ ├── docker-setup.sample │ │ │ ├── post-deploy.sample │ │ │ ├── post-proxy-reboot.sample │ │ │ ├── pre-build.sample │ │ │ ├── pre-connect.sample │ │ │ ├── pre-deploy.sample │ │ │ └── pre-proxy-reboot.sample │ │ └── secrets │ ├── .prettierrc.cjs │ ├── .rspec │ ├── .rubocop.yml │ ├── .ruby-version │ ├── DEPLOYMENT.md │ ├── Dockerfile │ ├── Gemfile │ ├── Gemfile.lock │ ├── Procfile │ ├── README.md │ ├── Rakefile │ ├── app │ │ ├── assets │ │ │ ├── images │ │ │ │ └── .keep │ │ │ └── stylesheets │ │ │ │ └── application.css │ │ ├── controllers │ │ │ ├── application_controller.rb │ │ │ ├── concerns │ │ │ │ └── .keep │ │ │ └── home_controller.rb │ │ ├── helpers │ │ │ └── application_helper.rb │ │ ├── javascript │ │ │ ├── application.js │ │ │ └── controllers │ │ │ │ ├── application.js │ │ │ │ ├── hello_controller.js │ │ │ │ └── index.js │ │ ├── jobs │ │ │ └── application_job.rb │ │ ├── mailers │ │ │ └── application_mailer.rb │ │ ├── models │ │ │ ├── application_record.rb │ │ │ └── concerns │ │ │ │ └── .keep │ │ └── views │ │ │ ├── home │ │ │ └── index.html.erb │ │ │ ├── layouts │ │ │ ├── application.html.erb │ │ │ ├── mailer.html.erb │ │ │ └── mailer.text.erb │ │ │ └── pwa │ │ │ ├── manifest.json.erb │ │ │ └── service-worker.js │ ├── bin │ │ ├── brakeman │ │ ├── bundle │ │ ├── dev │ │ ├── docker-entrypoint │ │ ├── importmap │ │ ├── jobs │ │ ├── kamal │ │ ├── rails │ │ ├── rake │ │ ├── rspec │ │ ├── rubocop │ │ ├── setup │ │ └── thrust │ ├── config.ru │ ├── config │ │ ├── application.rb │ │ ├── boot.rb │ │ ├── cable.yml │ │ ├── cache.yml │ │ ├── credentials.yml.enc │ │ ├── database.yml │ │ ├── deploy.yml │ │ ├── environment.rb │ │ ├── environments │ │ │ ├── development.rb │ │ │ ├── production.rb │ │ │ └── test.rb │ │ ├── importmap.rb │ │ ├── initializers │ │ │ ├── assets.rb │ │ │ ├── content_security_policy.rb │ │ │ ├── filter_parameter_logging.rb │ │ │ ├── generators.rb │ │ │ └── inflections.rb │ │ ├── locales │ │ │ └── en.yml │ │ ├── puma.rb │ │ ├── queue.yml │ │ ├── recurring.yml │ │ ├── routes.rb │ │ └── storage.yml │ ├── db │ │ ├── cable_schema.rb │ │ ├── cache_schema.rb │ │ ├── queue_schema.rb │ │ ├── schema.rb │ │ └── seeds.rb │ ├── lib │ │ ├── tasks │ │ │ └── .keep │ │ └── templates │ │ │ └── rspec │ │ │ └── system │ │ │ └── system_spec.rb │ ├── log │ │ └── .keep │ ├── public │ │ ├── 400.html │ │ ├── 404.html │ │ ├── 406-unsupported-browser.html │ │ ├── 422.html │ │ ├── 500.html │ │ ├── icon.png │ │ ├── icon.svg │ │ └── robots.txt │ ├── script │ │ └── .keep │ ├── spec │ │ ├── mailers │ │ │ └── .keep │ │ ├── rails_helper.rb │ │ ├── spec_helper.rb │ │ └── support │ │ │ ├── capybara.rb │ │ │ ├── mailer.rb │ │ │ └── system.rb │ ├── storage │ │ └── .keep │ ├── tmp │ │ ├── .keep │ │ ├── pids │ │ │ └── .keep │ │ └── storage │ │ │ └── .keep │ └── vendor │ │ ├── .keep │ │ └── javascript │ │ └── .keep └── vite │ ├── .dockerignore │ ├── .editorconfig │ ├── .gitattributes │ ├── .github │ ├── dependabot.yml │ └── workflows │ │ └── ci.yml │ ├── .gitignore │ ├── .kamal │ ├── hooks │ │ ├── docker-setup.sample │ │ ├── post-deploy.sample │ │ ├── post-proxy-reboot.sample │ │ ├── pre-build.sample │ │ ├── pre-connect.sample │ │ ├── pre-deploy.sample │ │ └── pre-proxy-reboot.sample │ └── secrets │ ├── .node-version │ ├── .prettierrc.cjs │ ├── .rubocop.yml │ ├── .ruby-version │ ├── DEPLOYMENT.md │ ├── Dockerfile │ ├── Gemfile │ ├── Gemfile.lock │ ├── Procfile │ ├── README.md │ ├── Rakefile │ ├── app │ ├── controllers │ │ ├── application_controller.rb │ │ ├── concerns │ │ │ └── .keep │ │ └── home_controller.rb │ ├── frontend │ │ ├── controllers │ │ │ ├── application.js │ │ │ ├── hello_controller.js │ │ │ └── index.js │ │ ├── entrypoints │ │ │ └── application.js │ │ ├── images │ │ │ ├── .keep │ │ │ └── example.svg │ │ └── stylesheets │ │ │ ├── base.css │ │ │ ├── index.css │ │ │ └── reset.css │ ├── helpers │ │ ├── application_helper.rb │ │ └── inline_svg_helper.rb │ ├── jobs │ │ └── application_job.rb │ ├── mailers │ │ └── application_mailer.rb │ ├── models │ │ ├── application_record.rb │ │ └── concerns │ │ │ └── .keep │ └── views │ │ ├── home │ │ └── index.html.erb │ │ ├── layouts │ │ ├── application.html.erb │ │ ├── mailer.html.erb │ │ └── mailer.text.erb │ │ └── pwa │ │ ├── manifest.json.erb │ │ └── service-worker.js │ ├── bin │ ├── brakeman │ ├── bundle │ ├── dev │ ├── docker-entrypoint │ ├── jobs │ ├── kamal │ ├── rails │ ├── rake │ ├── rubocop │ ├── setup │ ├── thrust │ └── vite │ ├── config.ru │ ├── config │ ├── application.rb │ ├── boot.rb │ ├── cable.yml │ ├── cache.yml │ ├── credentials.yml.enc │ ├── database.yml │ ├── deploy.yml │ ├── environment.rb │ ├── environments │ │ ├── development.rb │ │ ├── production.rb │ │ └── test.rb │ ├── initializers │ │ ├── content_security_policy.rb │ │ ├── filter_parameter_logging.rb │ │ ├── generators.rb │ │ └── inflections.rb │ ├── locales │ │ └── en.yml │ ├── puma.rb │ ├── queue.yml │ ├── recurring.yml │ ├── routes.rb │ ├── storage.yml │ └── vite.json │ ├── db │ ├── cable_schema.rb │ ├── cache_schema.rb │ ├── queue_schema.rb │ ├── schema.rb │ └── seeds.rb │ ├── lib │ ├── tasks │ │ └── .keep │ └── vite_inline_svg_file_loader.rb │ ├── log │ └── .keep │ ├── package.json │ ├── postcss.config.cjs │ ├── public │ ├── 400.html │ ├── 404.html │ ├── 406-unsupported-browser.html │ ├── 422.html │ ├── 500.html │ ├── icon.png │ ├── icon.svg │ └── robots.txt │ ├── run-pty.json │ ├── script │ └── .keep │ ├── storage │ └── .keep │ ├── test │ ├── application_system_test_case.rb │ ├── controllers │ │ └── .keep │ ├── fixtures │ │ └── files │ │ │ └── .keep │ ├── helpers │ │ ├── .keep │ │ └── inline_svg_helper_test.rb │ ├── integration │ │ └── .keep │ ├── mailers │ │ └── .keep │ ├── models │ │ └── .keep │ ├── support │ │ ├── capybara.rb │ │ └── mailer.rb │ ├── system │ │ └── .keep │ ├── test_helper.rb │ └── vite_helper.rb │ ├── tmp │ ├── .keep │ ├── pids │ │ └── .keep │ └── storage │ │ └── .keep │ ├── vendor │ └── .keep │ ├── vite.config.ts │ └── yarn.lock ├── exe └── nextgen ├── lib ├── nextgen.rb └── nextgen │ ├── actions.rb │ ├── actions │ ├── bundler.rb │ ├── git.rb │ └── javascript.rb │ ├── cli.rb │ ├── commands │ └── create.rb │ ├── ext │ └── prompt │ │ ├── list.rb │ │ └── multilist.rb │ ├── generators.rb │ ├── generators │ ├── action_mailer.rb │ ├── annotaterb.rb │ ├── base.rb │ ├── basic_auth.rb │ ├── bundler_audit.rb │ ├── capybara_lockstep.rb │ ├── clean_gemfile.rb │ ├── dotenv.rb │ ├── erb_lint.rb │ ├── eslint.rb │ ├── factory_bot_rails.rb │ ├── git_safe.rb │ ├── github_pr_template.rb │ ├── good_migrations.rb │ ├── home_controller.rb │ ├── initial_git_commit.rb │ ├── letter_opener.rb │ ├── mocha.rb │ ├── node.rb │ ├── npm.rb │ ├── open_browser_on_start.rb │ ├── overcommit.rb │ ├── pgcli_rails.rb │ ├── rack_canonical_host.rb │ ├── rack_mini_profiler.rb │ ├── rspec_github_actions.rb │ ├── rspec_rails.rb │ ├── rspec_system_testing.rb │ ├── rubocop.rb │ ├── shoulda.rb │ ├── sidekiq.rb │ ├── staging.rb │ ├── stylelint.rb │ ├── thor.rb │ ├── tomo.rb │ ├── vcr.rb │ └── vite.rb │ ├── rails_command.rb │ ├── rails_options.rb │ ├── rails_version.rb │ ├── thor_extensions.rb │ ├── tidy_gemfile.rb │ └── version.rb ├── nextgen.gemspec ├── template ├── .editorconfig ├── .env.sample ├── .erb_lint.yml.tt ├── .github │ └── PULL_REQUEST_TEMPLATE.md.tt ├── .overcommit.yml.tt ├── .prettierrc.cjs ├── .rubocop.yml.tt ├── .stylelintrc.js ├── DEPLOYMENT.md ├── Procfile.tt ├── README.md.tt ├── Thorfile ├── app │ ├── controllers │ │ ├── concerns │ │ │ └── basic_auth.rb │ │ └── home_controller.rb │ ├── frontend │ │ ├── controllers │ │ │ └── index.js │ │ ├── images │ │ │ └── example.svg │ │ └── stylesheets │ │ │ ├── base.css │ │ │ ├── index.css │ │ │ └── reset.css │ ├── helpers │ │ └── inline_svg_helper.rb │ └── views │ │ └── home │ │ └── index.html.erb.tt ├── bin │ ├── dev │ ├── dev-node │ └── setup ├── config │ ├── environments │ │ └── staging.rb │ ├── initializers │ │ ├── generators.rb │ │ ├── rack_mini_profiler.rb │ │ └── sidekiq.rb │ └── sidekiq.yml ├── eslint.config.js ├── lib │ ├── puma │ │ └── plugin │ │ │ └── open.rb │ ├── tasks │ │ ├── auto_annotate_models.rake │ │ ├── erb_lint.rake │ │ ├── eslint.rake.tt │ │ ├── rubocop.rake │ │ └── stylelint.rake.tt │ ├── templates │ │ └── rspec │ │ │ └── system │ │ │ └── system_spec.rb │ └── vite_inline_svg_file_loader.rb ├── package.json ├── postcss.config.cjs ├── run-pty.json ├── spec │ └── support │ │ ├── factory_bot.rb │ │ ├── mailer.rb │ │ ├── shoulda.rb │ │ ├── system.rb │ │ └── webmock.rb └── test │ ├── application_system_test_case.rb │ ├── helpers │ └── inline_svg_helper_test.rb │ ├── support │ ├── capybara.rb.tt │ ├── factory_bot.rb │ ├── mailer.rb │ ├── mocha.rb │ ├── shoulda.rb │ ├── vcr.rb.tt │ └── webmock.rb │ └── vite_helper.rb └── test ├── e2e └── nextgen_e2e_test.rb ├── integration └── generators │ ├── github_pr_template_test.rb │ ├── mocha_test.rb │ ├── npm_test.rb │ ├── rspec_system_testing_test.rb │ ├── rubocop_test.rb │ ├── staging_test.rb │ ├── test_case.rb │ └── vcr_test.rb ├── nextgen ├── rails_options_test.rb ├── rails_version_test.rb └── tidy_gemfile_test.rb ├── nextgen_test.rb └── test_helper.rb /.github/dependabot.yml: -------------------------------------------------------------------------------- 1 | version: 2 2 | updates: 3 | - package-ecosystem: bundler 4 | directory: "/" 5 | schedule: 6 | interval: monthly 7 | time: "16:00" 8 | timezone: America/Los_Angeles 9 | open-pull-requests-limit: 10 10 | labels: 11 | - "🏠 Housekeeping" 12 | - package-ecosystem: github-actions 13 | directory: "/" 14 | schedule: 15 | interval: monthly 16 | time: "16:00" 17 | timezone: America/Los_Angeles 18 | open-pull-requests-limit: 10 19 | labels: 20 | - "🏠 Housekeeping" 21 | -------------------------------------------------------------------------------- /.github/release-drafter.yml: -------------------------------------------------------------------------------- 1 | name-template: "$RESOLVED_VERSION" 2 | tag-template: "v$RESOLVED_VERSION" 3 | categories: 4 | - title: "⚠️ Breaking Changes" 5 | label: "⚠️ Breaking" 6 | - title: "✨ New Features" 7 | label: "✨ Feature" 8 | - title: "🐛 Bug Fixes" 9 | label: "🐛 Bug Fix" 10 | - title: "📚 Documentation" 11 | label: "📚 Docs" 12 | - title: "🏠 Housekeeping" 13 | label: "🏠 Housekeeping" 14 | version-resolver: 15 | minor: 16 | labels: 17 | - "⚠️ Breaking" 18 | - "✨ Feature" 19 | default: patch 20 | change-template: "- $TITLE (#$NUMBER) @$AUTHOR" 21 | no-changes-template: "- No changes" 22 | template: | 23 | $CHANGES 24 | 25 | **Full Changelog:** https://github.com/$OWNER/$REPOSITORY/compare/$PREVIOUS_TAG...v$RESOLVED_VERSION 26 | -------------------------------------------------------------------------------- /.github/workflows/release-drafter.yml: -------------------------------------------------------------------------------- 1 | name: Release Drafter 2 | 3 | on: 4 | push: 5 | branches: 6 | - main 7 | 8 | permissions: 9 | contents: write 10 | pull-requests: read 11 | 12 | jobs: 13 | update_release_draft: 14 | runs-on: ubuntu-latest 15 | steps: 16 | - uses: release-drafter/release-drafter@v6 17 | env: 18 | GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} 19 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | /.bundle/ 2 | /.yardoc 3 | /_yardoc/ 4 | /coverage/ 5 | /doc/ 6 | /pkg/ 7 | /site/ 8 | /spec/reports/ 9 | /tmp/ 10 | /Gemfile.lock 11 | -------------------------------------------------------------------------------- /.kodiak.toml: -------------------------------------------------------------------------------- 1 | # .kodiak.toml 2 | # Minimal config. version is the only required field. 3 | version = 1 4 | 5 | [merge.automerge_dependencies] 6 | # auto merge all PRs opened by "dependabot" that are "minor" or "patch" version upgrades. "major" version upgrades will be ignored. 7 | versions = ["minor", "patch"] 8 | usernames = ["dependabot"] 9 | 10 | # if using `update.always`, add dependabot to `update.ignore_usernames` to allow 11 | # dependabot to update and close stale dependency upgrades. 12 | [update] 13 | ignored_usernames = ["dependabot"] 14 | -------------------------------------------------------------------------------- /.overcommit.yml: -------------------------------------------------------------------------------- 1 | # Overcommit hooks run automatically on certain git operations, like "git commit". 2 | # For a complete list of options that you can use to customize hooks, see: 3 | # https://github.com/sds/overcommit 4 | 5 | gemfile: false 6 | verify_signatures: false 7 | 8 | PreCommit: 9 | ALL: 10 | exclude: 11 | - "examples/**/*" 12 | 13 | BundleCheck: 14 | enabled: true 15 | 16 | FixMe: 17 | enabled: true 18 | keywords: ["FIXME"] 19 | exclude: 20 | - .overcommit.yml 21 | - template/.overcommit.yml.tt 22 | - "examples/**/*" 23 | 24 | LocalPathsInGemfile: 25 | enabled: true 26 | 27 | RuboCop: 28 | enabled: true 29 | required_executable: bundle 30 | command: ["bundle", "exec", "rubocop"] 31 | on_warn: fail 32 | 33 | YamlSyntax: 34 | enabled: true 35 | 36 | PostCheckout: 37 | ALL: 38 | quiet: true 39 | -------------------------------------------------------------------------------- /.prettierignore: -------------------------------------------------------------------------------- 1 | /CODE_OF_CONDUCT.md 2 | -------------------------------------------------------------------------------- /CHANGELOG.md: -------------------------------------------------------------------------------- 1 | Release notes for this project are kept here: https://github.com/mattbrictson/nextgen/releases 2 | -------------------------------------------------------------------------------- /Gemfile: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | source "https://rubygems.org" 4 | gemspec 5 | 6 | gem "mighty_test" unless RUBY_VERSION < "3.1" 7 | gem "minitest", "~> 5.11" 8 | gem "rake", "~> 13.0" 9 | gem "rubocop", "1.81.1" 10 | gem "rubocop-minitest", "0.38.2" 11 | gem "rubocop-packaging", "0.6.0" 12 | gem "rubocop-performance", "1.26.0" 13 | gem "rubocop-rake", "0.7.1" 14 | gem "webmock" 15 | -------------------------------------------------------------------------------- /bin/console: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env ruby 2 | # frozen_string_literal: true 3 | 4 | require "bundler/setup" 5 | require "nextgen" 6 | 7 | # You can add fixtures and/or initialization code here to make experimenting 8 | # with your gem easier. You can also use a different console, if you like. 9 | 10 | # (If you use this, don't forget to add pry to your Gemfile!) 11 | # require "pry" 12 | # Pry.start 13 | 14 | require "irb" 15 | IRB.start(__FILE__) 16 | -------------------------------------------------------------------------------- /bin/mt: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | # Normally this file would be a binstub generated by bundler, but this would break nextgen's tests. 4 | # When testing generators, we expect the generator code to execute within a clean bundler environment. 5 | # Unfortunately, bundler's generated binstubs pollute ENV in a way that breaks this requirement. 6 | # So rather than using the normal binstub, we just call `bundle exec` directly. 7 | 8 | bundle exec mt "$@" 9 | -------------------------------------------------------------------------------- /bin/setup: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | set -euo pipefail 3 | IFS=$'\n\t' 4 | set -vx 5 | 6 | which overcommit > /dev/null 2>&1 && overcommit --install 7 | bundle install 8 | 9 | # Do any other automated setup that you need to do here 10 | -------------------------------------------------------------------------------- /config/rails_versions.yml: -------------------------------------------------------------------------------- 1 | current: ¤t 2 | args: [] 3 | label: "%%CURRENT_VERSION%%" 4 | asset_pipelines: 5 | propshaft: Propshaft (default) 6 | databases: 7 | sqlite3: SQLite3 (default) 8 | postgresql: PostgreSQL (recommended) 9 | mysql: MySQL 10 | trilogy: Trilogy 11 | oracle: Oracle 12 | sqlserver: SQLServer 13 | jdbcmysql: JDBCMySQL 14 | jdbcsqlite3: JDBCSQLite3 15 | jdbcpostgresql: JDBCPostgreSQL 16 | jdbc: JDBC 17 | mariadb-mysql: MariaDB-MySQL 18 | mariadb-trilogy: MariaDB-Trilogy 19 | default_features: 20 | brakeman: Brakeman 21 | ci: GitHub Actions CI 22 | kamal: Kamal 23 | rubocop: RuboCop 24 | solid: Solid Cache+Queue 25 | thruster: Thruster 26 | optional_features: 27 | devcontainer: devcontainer files 28 | 29 | edge: 30 | <<: *current 31 | args: ["--edge"] 32 | label: "edge (8-0-stable)" 33 | 34 | main: 35 | <<: *current 36 | args: ["--main"] 37 | label: "main (%%MAIN_VERSION%%)" 38 | -------------------------------------------------------------------------------- /demo.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mattbrictson/nextgen/c3a0ac5fb693be54309d2d9bb363fb27550e5056/demo.gif -------------------------------------------------------------------------------- /examples/all/.dockerignore: -------------------------------------------------------------------------------- 1 | # See https://docs.docker.com/engine/reference/builder/#dockerignore-file for more about ignoring files. 2 | 3 | # Ignore git directory. 4 | /.git/ 5 | /.gitignore 6 | 7 | # Ignore bundler config. 8 | /.bundle 9 | 10 | # Ignore all environment files. 11 | /.env* 12 | 13 | # Ignore all default key files. 14 | /config/master.key 15 | /config/credentials/*.key 16 | 17 | # Ignore all logfiles and tempfiles. 18 | /log/* 19 | /tmp/* 20 | !/log/.keep 21 | !/tmp/.keep 22 | 23 | # Ignore pidfiles, but keep the directory. 24 | /tmp/pids/* 25 | !/tmp/pids/.keep 26 | 27 | # Ignore storage (uploaded files in development and any SQLite databases). 28 | /storage/* 29 | !/storage/.keep 30 | /tmp/storage/* 31 | !/tmp/storage/.keep 32 | 33 | # Ignore assets. 34 | /node_modules/ 35 | /app/assets/builds/* 36 | !/app/assets/builds/.keep 37 | /public/assets 38 | 39 | # Ignore CI service files. 40 | /.github 41 | 42 | # Ignore development files 43 | /.devcontainer 44 | 45 | # Ignore Docker-related files 46 | /.dockerignore 47 | /Dockerfile* 48 | -------------------------------------------------------------------------------- /examples/all/.editorconfig: -------------------------------------------------------------------------------- 1 | # https://editorconfig.org 2 | 3 | root = true 4 | 5 | [*] 6 | charset = utf-8 7 | indent_style = space 8 | indent_size = 2 9 | end_of_line = lf 10 | insert_final_newline = true 11 | trim_trailing_whitespace = true 12 | 13 | [Makefile] 14 | indent_style = tab 15 | -------------------------------------------------------------------------------- /examples/all/.env.sample: -------------------------------------------------------------------------------- 1 | # These environment variables are needed to run the app locally. 2 | # Copy these into a file named .env to have them loaded automatically. 3 | -------------------------------------------------------------------------------- /examples/all/.erb_lint.yml: -------------------------------------------------------------------------------- 1 | --- 2 | EnableDefaultLinters: true 3 | exclude: 4 | - "node_modules/**/*" 5 | - "vendor/**/*" 6 | linters: 7 | ErbSafety: 8 | enabled: true 9 | Rubocop: 10 | enabled: true 11 | rubocop_config: 12 | inherit_from: 13 | - .rubocop.yml 14 | Layout/InitialIndentation: 15 | Enabled: false 16 | Layout/TrailingEmptyLines: 17 | Enabled: false 18 | Lint/UselessAssignment: 19 | Enabled: false 20 | Naming/FileName: 21 | Enabled: false 22 | Rails/OutputSafety: 23 | Enabled: false 24 | Style/FrozenStringLiteralComment: 25 | Enabled: false 26 | -------------------------------------------------------------------------------- /examples/all/.gitattributes: -------------------------------------------------------------------------------- 1 | # See https://git-scm.com/docs/gitattributes for more about git attribute files. 2 | 3 | # Mark the database schema as having been generated. 4 | db/schema.rb linguist-generated 5 | 6 | # Mark any vendored files as having been vendored. 7 | vendor/* linguist-vendored 8 | config/credentials/*.yml.enc diff=rails_credentials 9 | config/credentials.yml.enc diff=rails_credentials 10 | 11 | # Mark VCR cassettes as having been generated. 12 | test/cassettes/* linguist-generated 13 | -------------------------------------------------------------------------------- /examples/all/.github/PULL_REQUEST_TEMPLATE.md: -------------------------------------------------------------------------------- 1 | Problem 2 | ======= 3 | 4 | 5 | 6 | 7 | 8 | Solution 9 | ======== 10 | 11 | Steps to verify 12 | --------------- 13 | 14 | 1. step 15 | 1. step 16 | 1. step 17 | 18 | Screenshots 19 | ----------- 20 | -------------------------------------------------------------------------------- /examples/all/.github/dependabot.yml: -------------------------------------------------------------------------------- 1 | version: 2 2 | updates: 3 | - package-ecosystem: bundler 4 | directory: "/" 5 | schedule: 6 | interval: daily 7 | open-pull-requests-limit: 10 8 | - package-ecosystem: github-actions 9 | directory: "/" 10 | schedule: 11 | interval: daily 12 | open-pull-requests-limit: 10 13 | -------------------------------------------------------------------------------- /examples/all/.gitignore: -------------------------------------------------------------------------------- 1 | # See https://help.github.com/articles/ignoring-files for more about ignoring files. 2 | # 3 | # Temporary files generated by your text editor or operating system 4 | # belong in git's global ignore instead: 5 | # `$XDG_CONFIG_HOME/git/ignore` or `~/.config/git/ignore` 6 | 7 | # Ignore bundler config. 8 | /.bundle 9 | 10 | # Ignore all environment files. 11 | /.env* 12 | 13 | # Ignore all logfiles and tempfiles. 14 | /log/* 15 | /tmp/* 16 | !/log/.keep 17 | !/tmp/.keep 18 | 19 | # Ignore pidfiles, but keep the directory. 20 | /tmp/pids/* 21 | !/tmp/pids/ 22 | !/tmp/pids/.keep 23 | 24 | # Ignore storage (uploaded files in development and any SQLite databases). 25 | /storage/* 26 | !/storage/.keep 27 | /tmp/storage/* 28 | !/tmp/storage/ 29 | !/tmp/storage/.keep 30 | 31 | /public/assets 32 | 33 | # Ignore master key for decrypting credentials and more. 34 | /config/master.key 35 | node_modules/ 36 | !/.env.sample 37 | -------------------------------------------------------------------------------- /examples/all/.prettierrc.cjs: -------------------------------------------------------------------------------- 1 | /** @type {import("prettier").Config} */ 2 | 3 | module.exports = { 4 | tabWidth: 2, 5 | useTabs: false, 6 | }; 7 | -------------------------------------------------------------------------------- /examples/all/.ruby-version: -------------------------------------------------------------------------------- 1 | 3.4.1 2 | -------------------------------------------------------------------------------- /examples/all/.tomo/plugins/all_example.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | # https://tomo.mattbrictson.com/tutorials/writing-custom-tasks/ 4 | -------------------------------------------------------------------------------- /examples/all/DEPLOYMENT.md: -------------------------------------------------------------------------------- 1 | # Deployment 2 | 3 | ## Environment variables 4 | 5 | These environment variables affect how the app functions when deployed in production. 6 | 7 | - `SIDEKIQ_CONCURRENCY` - Number of threads used per Sidekiq process (default: 5) 8 | - `RAILS_HOSTNAME` - Redirect all requests to the specified canonical hostname 9 | - `BASIC_AUTH_USERNAME` - If this and `BASIC_AUTH_PASSWORD` are present, visitors must use these credentials to access the app 10 | - `BASIC_AUTH_PASSWORD` 11 | - `RAILS_DISABLE_SSL` - Disable HSTS and secure cookies 12 | - `RAILS_ENV` **REQUIRED** - "production" or "staging" 13 | - `RAILS_MAX_THREADS` - Number of threads per Puma process (default: 3) 14 | - `SECRET_KEY_BASE` **REQUIRED** - Unique, secret key used to encrypt and sign cookies and other sensitive data 15 | - `WEB_CONCURRENCY` - Number of Puma processes (default: 1) 16 | -------------------------------------------------------------------------------- /examples/all/Procfile: -------------------------------------------------------------------------------- 1 | web: bundle exec puma -C config/puma.rb 2 | release: bundle exec rake db:migrate 3 | worker: bundle exec sidekiq -C config/sidekiq.yml 4 | -------------------------------------------------------------------------------- /examples/all/Rakefile: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | # Add your own tasks in files placed in lib/tasks ending in .rake, 4 | # for example lib/tasks/capistrano.rake, and they will automatically be available to Rake. 5 | 6 | require_relative "config/application" 7 | 8 | Rails.application.load_tasks 9 | 10 | Rake::Task[:default].prerequisites.clear if Rake::Task.task_defined?(:default) 11 | 12 | desc "Run all checks" 13 | task default: %w[test:all erb_lint eslint stylelint rubocop] do 14 | puts ">>>>>> [OK] All checks passed!" 15 | end 16 | 17 | desc "Apply auto-corrections" 18 | task fix: %w[erb_lint:autocorrect eslint:autocorrect stylelint:autocorrect rubocop:autocorrect_all] do 19 | puts ">>>>>> [OK] All fixes applied!" 20 | end 21 | -------------------------------------------------------------------------------- /examples/all/Thorfile: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | require_relative "config/environment" unless %w[-h --help help -T list -v version].include?(ARGV.first) 4 | 5 | class << Thor 6 | def exit_on_failure? 7 | true 8 | end 9 | end 10 | -------------------------------------------------------------------------------- /examples/all/app/assets/images/.keep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mattbrictson/nextgen/c3a0ac5fb693be54309d2d9bb363fb27550e5056/examples/all/app/assets/images/.keep -------------------------------------------------------------------------------- /examples/all/app/assets/stylesheets/application.css: -------------------------------------------------------------------------------- 1 | /* 2 | * This is a manifest file that'll be compiled into application.css. 3 | * 4 | * With Propshaft, assets are served efficiently without preprocessing steps. You can still include 5 | * application-wide styles in this file, but keep in mind that CSS precedence will follow the standard 6 | * cascading order, meaning styles declared later in the document or manifest will override earlier ones, 7 | * depending on specificity. 8 | * 9 | * Consider organizing styles into separate files for maintainability. 10 | */ 11 | -------------------------------------------------------------------------------- /examples/all/app/controllers/application_controller.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | class ApplicationController < ActionController::Base 4 | include BasicAuth 5 | # Only allow modern browsers supporting webp images, web push, badges, import maps, CSS nesting, and CSS :has. 6 | allow_browser versions: :modern 7 | end 8 | -------------------------------------------------------------------------------- /examples/all/app/controllers/concerns/.keep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mattbrictson/nextgen/c3a0ac5fb693be54309d2d9bb363fb27550e5056/examples/all/app/controllers/concerns/.keep -------------------------------------------------------------------------------- /examples/all/app/controllers/concerns/basic_auth.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | module BasicAuth 4 | extend ActiveSupport::Concern 5 | 6 | included do 7 | before_action :require_basic_auth 8 | end 9 | 10 | private 11 | 12 | def require_basic_auth 13 | expected_username = ENV.fetch("BASIC_AUTH_USERNAME", nil) 14 | expected_password = ENV.fetch("BASIC_AUTH_PASSWORD", nil) 15 | return true if expected_username.blank? || expected_password.blank? 16 | 17 | authenticate_or_request_with_http_basic do |username, password| 18 | ActiveSupport::SecurityUtils.secure_compare(username, expected_username) & 19 | ActiveSupport::SecurityUtils.secure_compare(password, expected_password) 20 | end 21 | end 22 | end 23 | -------------------------------------------------------------------------------- /examples/all/app/controllers/home_controller.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | class HomeController < ApplicationController 4 | def index 5 | end 6 | end 7 | -------------------------------------------------------------------------------- /examples/all/app/helpers/application_helper.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | module ApplicationHelper 4 | end 5 | -------------------------------------------------------------------------------- /examples/all/app/javascript/application.js: -------------------------------------------------------------------------------- 1 | // Configure your import map in config/importmap.rb. Read more: https://github.com/rails/importmap-rails 2 | import "@hotwired/turbo-rails"; 3 | import "controllers"; 4 | -------------------------------------------------------------------------------- /examples/all/app/javascript/controllers/application.js: -------------------------------------------------------------------------------- 1 | import { Application } from "@hotwired/stimulus"; 2 | 3 | const application = Application.start(); 4 | 5 | // Configure Stimulus development experience 6 | application.debug = false; 7 | window.Stimulus = application; 8 | 9 | export { application }; 10 | -------------------------------------------------------------------------------- /examples/all/app/javascript/controllers/hello_controller.js: -------------------------------------------------------------------------------- 1 | import { Controller } from "@hotwired/stimulus"; 2 | 3 | export default class extends Controller { 4 | connect() { 5 | this.element.textContent = "Hello World!"; 6 | } 7 | } 8 | -------------------------------------------------------------------------------- /examples/all/app/javascript/controllers/index.js: -------------------------------------------------------------------------------- 1 | // Import and register all your controllers from the importmap via controllers/**/*_controller 2 | import { application } from "controllers/application"; 3 | import { eagerLoadControllersFrom } from "@hotwired/stimulus-loading"; 4 | eagerLoadControllersFrom("controllers", application); 5 | -------------------------------------------------------------------------------- /examples/all/app/jobs/application_job.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | class ApplicationJob < ActiveJob::Base 4 | # Automatically retry jobs that encountered a deadlock 5 | # retry_on ActiveRecord::Deadlocked 6 | 7 | # Most jobs are safe to ignore if the underlying records are no longer available 8 | # discard_on ActiveJob::DeserializationError 9 | end 10 | -------------------------------------------------------------------------------- /examples/all/app/mailers/application_mailer.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | class ApplicationMailer < ActionMailer::Base 4 | default from: "from@example.com" 5 | layout "mailer" 6 | end 7 | -------------------------------------------------------------------------------- /examples/all/app/models/application_record.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | class ApplicationRecord < ActiveRecord::Base 4 | primary_abstract_class 5 | end 6 | -------------------------------------------------------------------------------- /examples/all/app/models/concerns/.keep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mattbrictson/nextgen/c3a0ac5fb693be54309d2d9bb363fb27550e5056/examples/all/app/models/concerns/.keep -------------------------------------------------------------------------------- /examples/all/app/views/home/index.html.erb: -------------------------------------------------------------------------------- 1 | <% provide(:title, "Home") %> 2 |

Find me in app/views/home/index.html.erb

3 | -------------------------------------------------------------------------------- /examples/all/app/views/layouts/mailer.html.erb: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 8 | 9 | 10 | 11 | <%= yield %> 12 | 13 | 14 | -------------------------------------------------------------------------------- /examples/all/app/views/layouts/mailer.text.erb: -------------------------------------------------------------------------------- 1 | <%= yield %> 2 | -------------------------------------------------------------------------------- /examples/all/app/views/pwa/manifest.json.erb: -------------------------------------------------------------------------------- 1 | { 2 | "name": "AllExample", 3 | "icons": [ 4 | { 5 | "src": "/icon.png", 6 | "type": "image/png", 7 | "sizes": "512x512" 8 | }, 9 | { 10 | "src": "/icon.png", 11 | "type": "image/png", 12 | "sizes": "512x512", 13 | "purpose": "maskable" 14 | } 15 | ], 16 | "start_url": "/", 17 | "display": "standalone", 18 | "scope": "/", 19 | "description": "AllExample.", 20 | "theme_color": "red", 21 | "background_color": "red" 22 | } 23 | -------------------------------------------------------------------------------- /examples/all/app/views/pwa/service-worker.js: -------------------------------------------------------------------------------- 1 | // Add a service worker for processing Web Push notifications: 2 | // 3 | // self.addEventListener("push", async (event) => { 4 | // const { title, options } = await event.data.json() 5 | // event.waitUntil(self.registration.showNotification(title, options)) 6 | // }) 7 | // 8 | // self.addEventListener("notificationclick", function(event) { 9 | // event.notification.close() 10 | // event.waitUntil( 11 | // clients.matchAll({ type: "window" }).then((clientList) => { 12 | // for (let i = 0; i < clientList.length; i++) { 13 | // let client = clientList[i] 14 | // let clientPath = (new URL(client.url)).pathname 15 | // 16 | // if (clientPath == event.notification.data.path && "focus" in client) { 17 | // return client.focus() 18 | // } 19 | // } 20 | // 21 | // if (clients.openWindow) { 22 | // return clients.openWindow(event.notification.data.path) 23 | // } 24 | // }) 25 | // ) 26 | // }) 27 | -------------------------------------------------------------------------------- /examples/all/bin/brakeman: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env ruby 2 | require "rubygems" 3 | require "bundler/setup" 4 | 5 | ARGV.unshift("--ensure-latest") 6 | 7 | load Gem.bin_path("brakeman", "brakeman") 8 | -------------------------------------------------------------------------------- /examples/all/bin/bundle-audit: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env ruby 2 | # frozen_string_literal: true 3 | 4 | # 5 | # This file was generated by Bundler. 6 | # 7 | # The application 'bundle-audit' 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("bundler-audit", "bundle-audit") 28 | -------------------------------------------------------------------------------- /examples/all/bin/bundler-audit: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env ruby 2 | # frozen_string_literal: true 3 | 4 | # 5 | # This file was generated by Bundler. 6 | # 7 | # The application 'bundler-audit' 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("bundler-audit", "bundler-audit") 28 | -------------------------------------------------------------------------------- /examples/all/bin/dev: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env ruby 2 | exec "./bin/rails", "server", *ARGV 3 | -------------------------------------------------------------------------------- /examples/all/bin/docker-entrypoint: -------------------------------------------------------------------------------- 1 | #!/bin/bash -e 2 | 3 | # Enable jemalloc for reduced memory usage and latency. 4 | if [ -z "${LD_PRELOAD+x}" ]; then 5 | LD_PRELOAD=$(find /usr/lib -name libjemalloc.so.2 -print -quit) 6 | export LD_PRELOAD 7 | fi 8 | 9 | # If running the rails server then create or migrate existing database 10 | if [ "${@: -2:1}" == "./bin/rails" ] && [ "${@: -1:1}" == "server" ]; then 11 | ./bin/rails db:prepare 12 | fi 13 | 14 | exec "${@}" 15 | -------------------------------------------------------------------------------- /examples/all/bin/erb_lint: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env ruby 2 | # frozen_string_literal: true 3 | 4 | # 5 | # This file was generated by Bundler. 6 | # 7 | # The application 'erb_lint' 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("erb_lint", "erb_lint") 28 | -------------------------------------------------------------------------------- /examples/all/bin/erblint: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env ruby 2 | # frozen_string_literal: true 3 | 4 | # 5 | # This file was generated by Bundler. 6 | # 7 | # The application 'erblint' 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("erb_lint", "erblint") 28 | -------------------------------------------------------------------------------- /examples/all/bin/importmap: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env ruby 2 | 3 | require_relative "../config/application" 4 | require "importmap/commands" 5 | -------------------------------------------------------------------------------- /examples/all/bin/rails: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env ruby 2 | APP_PATH = File.expand_path("../config/application", __dir__) 3 | require_relative "../config/boot" 4 | require "rails/commands" 5 | -------------------------------------------------------------------------------- /examples/all/bin/rake: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env ruby 2 | require_relative "../config/boot" 3 | require "rake" 4 | Rake.application.run 5 | -------------------------------------------------------------------------------- /examples/all/bin/rubocop: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env ruby 2 | require "rubygems" 3 | require "bundler/setup" 4 | 5 | # explicit rubocop config increases performance slightly while avoiding config confusion. 6 | ARGV.unshift("--config", File.expand_path("../.rubocop.yml", __dir__)) 7 | 8 | load Gem.bin_path("rubocop", "rubocop") 9 | -------------------------------------------------------------------------------- /examples/all/bin/sidekiq: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env ruby 2 | # frozen_string_literal: true 3 | 4 | # 5 | # This file was generated by Bundler. 6 | # 7 | # The application 'sidekiq' 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("sidekiq", "sidekiq") 28 | -------------------------------------------------------------------------------- /examples/all/bin/sidekiqmon: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env ruby 2 | # frozen_string_literal: true 3 | 4 | # 5 | # This file was generated by Bundler. 6 | # 7 | # The application 'sidekiqmon' 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("sidekiq", "sidekiqmon") 28 | -------------------------------------------------------------------------------- /examples/all/bin/thor: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env ruby 2 | # frozen_string_literal: true 3 | 4 | # 5 | # This file was generated by Bundler. 6 | # 7 | # The application 'thor' 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("thor", "thor") 28 | -------------------------------------------------------------------------------- /examples/all/bin/thrust: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env ruby 2 | require "rubygems" 3 | require "bundler/setup" 4 | 5 | load Gem.bin_path("thruster", "thrust") 6 | -------------------------------------------------------------------------------- /examples/all/bin/tomo: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env ruby 2 | # frozen_string_literal: true 3 | 4 | # 5 | # This file was generated by Bundler. 6 | # 7 | # The application 'tomo' 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("tomo", "tomo") 28 | -------------------------------------------------------------------------------- /examples/all/config.ru: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | # This file is used by Rack-based servers to start the application. 4 | 5 | require_relative "config/environment" 6 | 7 | use Rack::CanonicalHost, ENV.fetch("RAILS_HOSTNAME", nil) if ENV["RAILS_HOSTNAME"].present? 8 | run Rails.application 9 | Rails.application.load_server 10 | -------------------------------------------------------------------------------- /examples/all/config/boot.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | ENV["BUNDLE_GEMFILE"] ||= File.expand_path("../Gemfile", __dir__) 4 | 5 | require "bundler/setup" # Set up gems listed in the Gemfile. 6 | require "bootsnap/setup" # Speed up boot time by caching expensive operations. 7 | -------------------------------------------------------------------------------- /examples/all/config/cable.yml: -------------------------------------------------------------------------------- 1 | development: 2 | adapter: async 3 | 4 | test: 5 | adapter: test 6 | 7 | production: 8 | adapter: redis 9 | url: <%= ENV.fetch("REDIS_URL") { "redis://localhost:6379/1" } %> 10 | channel_prefix: all_example_production 11 | 12 | staging: 13 | adapter: redis 14 | url: <%= ENV.fetch("REDIS_URL") { "redis://localhost:6379/1" } %> 15 | channel_prefix: all_example_staging 16 | -------------------------------------------------------------------------------- /examples/all/config/credentials.yml.enc: -------------------------------------------------------------------------------- 1 | PfKinbQntxY+oh58sR4rGciyrAcWBFMwwSCNcVsBkCr1vkRD5aZZXH9ReWdT2woghFItLTQ/aFV6Ws9f7bbSzrII3/WzW8kIdXLkyieRrmXGXs2Jqapk3tQyZ8o618o8C9IWwiaG+UNmSdh0HGrwEQ1xI+Zuo7V+HXJ7VfyzGz9BG3xrH3674EL1U7baL+QqgU0kw3aDk5J+7HG82cVpMYef/EjpqIP2YlHkXonq7YGX4KwkE5SEZoNEI78Cnu2uN1FaF/E2oC8tAKZpz+PbtK98M3BTeAkk8bX862QQktmfT2M1YGiOi+QVXmcppzumG5HyJAbHclXFasP+yX9pUNqhtw2uT4uxwQx4pDZGo9teXw4cUaj96avBPkhXkrTQw9sYNTwywGb2UD5J+MTqMw+0aW/1/33WJMvaDUr1rHLh65EzAzapdktSYXUKtsHD+/YIyEqvwDii8EhuGT+p5w934XC69e9TyzRwdCuGXYplRcaurbq6NuC0--msRlx+XqiU7xvqIO--cGxRjd0DuooQaLkvx1d+wA== -------------------------------------------------------------------------------- /examples/all/config/environment.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | # Load the Rails application. 4 | require_relative "application" 5 | 6 | # Initialize the Rails application. 7 | Rails.application.initialize! 8 | -------------------------------------------------------------------------------- /examples/all/config/environments/staging.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | # The staging environment is based on production 4 | require_relative "production" 5 | -------------------------------------------------------------------------------- /examples/all/config/importmap.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | # Pin npm packages by running ./bin/importmap 4 | 5 | pin "application" 6 | pin "@hotwired/turbo-rails", to: "turbo.min.js" 7 | pin "@hotwired/stimulus", to: "stimulus.min.js" 8 | pin "@hotwired/stimulus-loading", to: "stimulus-loading.js" 9 | pin_all_from "app/javascript/controllers", under: "controllers" 10 | -------------------------------------------------------------------------------- /examples/all/config/initializers/assets.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | # Be sure to restart your server when you modify this file. 4 | 5 | # Version of your assets, change this if you want to expire all your assets. 6 | Rails.application.config.assets.version = "1.0" 7 | 8 | # Add additional assets to the asset load path. 9 | # Rails.application.config.assets.paths << Emoji.images_path 10 | -------------------------------------------------------------------------------- /examples/all/config/initializers/filter_parameter_logging.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | # Be sure to restart your server when you modify this file. 4 | 5 | # Configure parameters to be partially matched (e.g. passw matches password) and filtered from the log file. 6 | # Use this to limit dissemination of sensitive information. 7 | # See the ActiveSupport::ParameterFilter documentation for supported notations and behaviors. 8 | Rails.application.config.filter_parameters += [ 9 | :passw, :email, :secret, :token, :_key, :crypt, :salt, :certificate, :otp, :ssn, :cvv, :cvc 10 | ] 11 | -------------------------------------------------------------------------------- /examples/all/config/initializers/generators.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | Rails.application.config.generators do |g| 4 | # Generate "users_factory.rb" instead of "users.rb" 5 | g.factory_bot suffix: "factory" 6 | g.test_framework :test_unit, fixture: false, fixture_replacement: :factory_bot 7 | # Disable generators we don't need. 8 | g.javascripts false 9 | g.stylesheets false 10 | end 11 | -------------------------------------------------------------------------------- /examples/all/config/initializers/inflections.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | # Be sure to restart your server when you modify this file. 4 | 5 | # Add new inflection rules using the following format. Inflections 6 | # are locale specific, and you may define rules for as many different 7 | # locales as you wish. All of these examples are active by default: 8 | # ActiveSupport::Inflector.inflections(:en) do |inflect| 9 | # inflect.plural /^(ox)$/i, "\\1en" 10 | # inflect.singular /^(ox)en/i, "\\1" 11 | # inflect.irregular "person", "people" 12 | # inflect.uncountable %w( fish sheep ) 13 | # end 14 | 15 | # These inflection rules are supported but not enabled by default: 16 | # ActiveSupport::Inflector.inflections(:en) do |inflect| 17 | # inflect.acronym "RESTful" 18 | # end 19 | -------------------------------------------------------------------------------- /examples/all/config/initializers/rack_mini_profiler.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | return unless defined?(Rack::MiniProfiler) 4 | 5 | # https://github.com/MiniProfiler/rack-mini-profiler#configuration-options 6 | Rack::MiniProfiler.config.enable_hotwire_turbo_drive_support = true 7 | -------------------------------------------------------------------------------- /examples/all/config/locales/en.yml: -------------------------------------------------------------------------------- 1 | # Files in the config/locales directory are used for internationalization and 2 | # are automatically loaded by Rails. If you want to use locales other than 3 | # English, add the necessary files in this directory. 4 | # 5 | # To use the locales, use `I18n.t`: 6 | # 7 | # I18n.t "hello" 8 | # 9 | # In views, this is aliased to just `t`: 10 | # 11 | # <%= t("hello") %> 12 | # 13 | # To use a different locale, set it with `I18n.locale`: 14 | # 15 | # I18n.locale = :es 16 | # 17 | # This would use the information in config/locales/es.yml. 18 | # 19 | # To learn more about the API, please read the Rails Internationalization guide 20 | # at https://guides.rubyonrails.org/i18n.html. 21 | # 22 | # Be aware that YAML interprets the following case-insensitive strings as 23 | # booleans: `true`, `false`, `on`, `off`, `yes`, `no`. Therefore, these strings 24 | # must be quoted to be interpreted as strings. For example: 25 | # 26 | # en: 27 | # "yes": yup 28 | # enabled: "ON" 29 | 30 | en: 31 | hello: "Hello world" 32 | -------------------------------------------------------------------------------- /examples/all/config/routes.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | Rails.application.routes.draw do 4 | mount Sidekiq::Web => "/sidekiq" if defined?(Sidekiq) 5 | root "home#index" 6 | # Define your application routes per the DSL in https://guides.rubyonrails.org/routing.html 7 | 8 | # Reveal health status on /up that returns 200 if the app boots with no exceptions, otherwise 500. 9 | # Can be used by load balancers and uptime monitors to verify that the app is live. 10 | get "up" => "rails/health#show", as: :rails_health_check 11 | 12 | # Render dynamic PWA files from app/views/pwa/* (remember to link manifest in application.html.erb) 13 | # get "manifest" => "rails/pwa#manifest", as: :pwa_manifest 14 | # get "service-worker" => "rails/pwa#service_worker", as: :pwa_service_worker 15 | 16 | # Defines the root path route ("/") 17 | # root "posts#index" 18 | end 19 | -------------------------------------------------------------------------------- /examples/all/config/sidekiq.yml: -------------------------------------------------------------------------------- 1 | --- 2 | :queues: 3 | - default 4 | 5 | :concurrency: <%= ENV["SIDEKIQ_CONCURRENCY"] || ENV["RAILS_MAX_THREADS"] || 5 %> 6 | -------------------------------------------------------------------------------- /examples/all/db/schema.rb: -------------------------------------------------------------------------------- 1 | # This file is auto-generated from the current state of the database. Instead 2 | # of editing this file, please use the migrations feature of Active Record to 3 | # incrementally modify your database, and then regenerate this schema definition. 4 | # 5 | # This file is the source Rails uses to define your schema when running `bin/rails 6 | # db:schema:load`. When creating a new database, `bin/rails db:schema:load` tends to 7 | # be faster and is potentially less error prone than running all of your 8 | # migrations from scratch. Old migrations may fail to apply correctly if those 9 | # migrations use external dependencies or application code. 10 | # 11 | # It's strongly recommended that you check this file into your version control system. 12 | 13 | ActiveRecord::Schema[8.0].define(version: 0) do 14 | end 15 | -------------------------------------------------------------------------------- /examples/all/db/seeds.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | # This file should ensure the existence of records required to run the application in every environment (production, 4 | # development, test). The code here should be idempotent so that it can be executed at any point in every environment. 5 | # The data can then be loaded with the bin/rails db:seed command (or created alongside the database with db:setup). 6 | # 7 | # Example: 8 | # 9 | # ["Action", "Comedy", "Drama", "Horror"].each do |genre_name| 10 | # MovieGenre.find_or_create_by!(name: genre_name) 11 | # end 12 | -------------------------------------------------------------------------------- /examples/all/eslint.config.js: -------------------------------------------------------------------------------- 1 | /** @type {import("@types/eslint").Linter.Config */ 2 | 3 | import globals from "globals"; 4 | import js from "@eslint/js"; 5 | import eslintPluginPrettierRecommended from "eslint-plugin-prettier/recommended"; 6 | 7 | export default [ 8 | js.configs.recommended, 9 | eslintPluginPrettierRecommended, 10 | { 11 | languageOptions: { 12 | ecmaVersion: 2022, 13 | sourceType: "module", 14 | globals: { 15 | ...globals.browser, 16 | ...globals.es2021, 17 | }, 18 | }, 19 | rules: { 20 | "no-unused-vars": [ 21 | "error", 22 | { 23 | args: "after-used", 24 | argsIgnorePattern: "^_", 25 | varsIgnorePattern: "^_", 26 | }, 27 | ], 28 | "no-var": "error", 29 | "prettier/prettier": "error", 30 | }, 31 | }, 32 | ]; 33 | -------------------------------------------------------------------------------- /examples/all/lib/puma/plugin/open.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | require "puma/plugin" 4 | 5 | Puma::Plugin.create do 6 | def start(launcher) 7 | return unless defined?(Rails) && defined?(Launchy) 8 | return unless Rails.env.development? 9 | 10 | binding = launcher.options[:binds].grep(/^tcp|ssl/).first 11 | return if binding.nil? 12 | 13 | url = binding.sub(/^tcp/, "http").sub(/^ssl/, "https").sub("0.0.0.0", "localhost") 14 | Launchy.open(url) 15 | end 16 | end 17 | -------------------------------------------------------------------------------- /examples/all/lib/tasks/.keep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mattbrictson/nextgen/c3a0ac5fb693be54309d2d9bb363fb27550e5056/examples/all/lib/tasks/.keep -------------------------------------------------------------------------------- /examples/all/lib/tasks/annotate_rb.rake: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | # This rake task was added by annotate_rb gem. 4 | 5 | # Can set `ANNOTATERB_SKIP_ON_DB_TASKS` to be anything to skip this 6 | if Rails.env.development? && ENV["ANNOTATERB_SKIP_ON_DB_TASKS"].nil? 7 | require "annotate_rb" 8 | 9 | AnnotateRb::Core.load_rake_tasks 10 | end 11 | -------------------------------------------------------------------------------- /examples/all/lib/tasks/erb_lint.rake: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | desc "Run erb_lint" 4 | task :erb_lint do 5 | sh "bin/erb_lint --lint-all" 6 | end 7 | 8 | namespace :erb_lint do 9 | desc "Autocorrect erb_lint offenses" 10 | task :autocorrect do 11 | sh "bin/erb_lint --lint-all -a" 12 | end 13 | end 14 | -------------------------------------------------------------------------------- /examples/all/lib/tasks/eslint.rake: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | desc "Run ESLint" 4 | task :eslint do 5 | sh "yarn run lint:js" 6 | end 7 | 8 | namespace :eslint do 9 | desc "Autocorrect ESLint offenses" 10 | task :autocorrect do 11 | sh "yarn run fix:js" 12 | end 13 | end 14 | -------------------------------------------------------------------------------- /examples/all/lib/tasks/rubocop.rake: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | return unless Gem.loaded_specs.key?("rubocop") 4 | 5 | require "rubocop/rake_task" 6 | RuboCop::RakeTask.new(:rubocop) do |task| 7 | task.options.push "-c", ".rubocop.yml" 8 | end 9 | -------------------------------------------------------------------------------- /examples/all/lib/tasks/stylelint.rake: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | desc "Run Stylelint" 4 | task :stylelint do 5 | sh "yarn run lint:css" 6 | end 7 | 8 | namespace :stylelint do 9 | desc "Autocorrect Stylelint offenses" 10 | task :autocorrect do 11 | sh "yarn run fix:css" 12 | end 13 | end 14 | -------------------------------------------------------------------------------- /examples/all/log/.keep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mattbrictson/nextgen/c3a0ac5fb693be54309d2d9bb363fb27550e5056/examples/all/log/.keep -------------------------------------------------------------------------------- /examples/all/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "private": true, 3 | "type": "module", 4 | "engines": { 5 | "node": "^20.9.0 || >= 22.0.0" 6 | }, 7 | "devDependencies": { 8 | "@eslint/js": "^9.18.0", 9 | "@types/eslint": "^9.6.1", 10 | "eslint": "^9", 11 | "eslint-config-prettier": "^10.0.1", 12 | "eslint-formatter-compact": "^8.40.0", 13 | "eslint-plugin-prettier": "^5.2.2", 14 | "npm-run-all": "^4.1.5", 15 | "prettier": "^3.4.2", 16 | "stylelint": "^16.13.2", 17 | "stylelint-config-standard": "^37.0.0", 18 | "stylelint-prettier": "^5.0.2" 19 | }, 20 | "scripts": { 21 | "lint:js": "eslint 'app/{assets,components,frontend,javascript}/**/*.{cjs,js,jsx,ts,tsx}'", 22 | "fix:js": "npm run -- lint:js --fix", 23 | "lint": "npm-run-all lint:**", 24 | "fix": "npm-run-all fix:**", 25 | "lint:css": "stylelint 'app/{components,frontend,assets/stylesheets}/**/*.css'", 26 | "fix:css": "npm run -- lint:css --fix" 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /examples/all/public/icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mattbrictson/nextgen/c3a0ac5fb693be54309d2d9bb363fb27550e5056/examples/all/public/icon.png -------------------------------------------------------------------------------- /examples/all/public/icon.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /examples/all/public/robots.txt: -------------------------------------------------------------------------------- 1 | # See https://www.robotstxt.org/robotstxt.html for documentation on how to use the robots.txt file 2 | -------------------------------------------------------------------------------- /examples/all/script/.keep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mattbrictson/nextgen/c3a0ac5fb693be54309d2d9bb363fb27550e5056/examples/all/script/.keep -------------------------------------------------------------------------------- /examples/all/storage/.keep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mattbrictson/nextgen/c3a0ac5fb693be54309d2d9bb363fb27550e5056/examples/all/storage/.keep -------------------------------------------------------------------------------- /examples/all/test/application_system_test_case.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | require "test_helper" 4 | 5 | class ApplicationSystemTestCase < ActionDispatch::SystemTestCase 6 | driven_by :selenium, 7 | using: (ENV["SHOW_BROWSER"] ? :chrome : :headless_chrome), 8 | screen_size: [1400, 1400] do |options| 9 | # Allows running in Docker 10 | options.add_argument("--disable-dev-shm-usage") 11 | options.add_argument("--no-sandbox") 12 | 13 | # Fixes slowdowns on macOS 14 | options.add_argument("--disable-gpu") 15 | end 16 | end 17 | -------------------------------------------------------------------------------- /examples/all/test/controllers/.keep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mattbrictson/nextgen/c3a0ac5fb693be54309d2d9bb363fb27550e5056/examples/all/test/controllers/.keep -------------------------------------------------------------------------------- /examples/all/test/fixtures/files/.keep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mattbrictson/nextgen/c3a0ac5fb693be54309d2d9bb363fb27550e5056/examples/all/test/fixtures/files/.keep -------------------------------------------------------------------------------- /examples/all/test/helpers/.keep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mattbrictson/nextgen/c3a0ac5fb693be54309d2d9bb363fb27550e5056/examples/all/test/helpers/.keep -------------------------------------------------------------------------------- /examples/all/test/integration/.keep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mattbrictson/nextgen/c3a0ac5fb693be54309d2d9bb363fb27550e5056/examples/all/test/integration/.keep -------------------------------------------------------------------------------- /examples/all/test/mailers/.keep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mattbrictson/nextgen/c3a0ac5fb693be54309d2d9bb363fb27550e5056/examples/all/test/mailers/.keep -------------------------------------------------------------------------------- /examples/all/test/models/.keep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mattbrictson/nextgen/c3a0ac5fb693be54309d2d9bb363fb27550e5056/examples/all/test/models/.keep -------------------------------------------------------------------------------- /examples/all/test/support/capybara.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | ActiveSupport.on_load(:action_dispatch_system_test_case) do 4 | require "capybara" 5 | require "capybara-lockstep" 6 | require "capybara/rails" 7 | 8 | Capybara.configure do |config| 9 | config.default_max_wait_time = 2 10 | config.save_path = "tmp/screenshots" 11 | config.enable_aria_label = true 12 | config.server = :puma, {Silent: true} 13 | config.test_id = "data-testid" 14 | end 15 | end 16 | -------------------------------------------------------------------------------- /examples/all/test/support/factory_bot.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | ActiveSupport.on_load(:active_support_test_case) do 4 | include FactoryBot::Syntax::Methods 5 | end 6 | -------------------------------------------------------------------------------- /examples/all/test/support/mailer.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | ActiveSupport.on_load(:active_support_test_case) do 4 | setup { ActionMailer::Base.deliveries.clear } 5 | end 6 | -------------------------------------------------------------------------------- /examples/all/test/support/mocha.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | require "mocha/minitest" 4 | 5 | # Reference: https://rubydoc.info/gems/mocha/Mocha/Configuration 6 | Mocha.configure do |config| 7 | config.strict_keyword_argument_matching = true 8 | config.stubbing_non_existent_method = :prevent 9 | end 10 | -------------------------------------------------------------------------------- /examples/all/test/support/shoulda.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | Shoulda::Matchers.configure do |config| 4 | config.integrate do |with| 5 | with.test_framework :minitest 6 | with.library :rails 7 | end 8 | end 9 | -------------------------------------------------------------------------------- /examples/all/test/support/vcr.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | require "vcr" 4 | 5 | VCR.configure do |config| 6 | config.hook_into :webmock 7 | config.allow_http_connections_when_no_cassette = false 8 | config.ignore_localhost = true 9 | config.ignore_host "chromedriver.storage.googleapis.com" 10 | config.cassette_library_dir = File.expand_path("../cassettes", __dir__) 11 | config.default_cassette_options = { 12 | # Enable automatic expiration and re-recording of cassettes 13 | # re_record_interval: 1.week, 14 | record: ENV["CI"] ? :none : :once, 15 | record_on_error: false, 16 | match_requests_on: %i[method uri body] 17 | } 18 | 19 | # Make sure headers containing secrets aren't recorded in cassettes and stored in git 20 | %w[Authorization X-Api-Key].each do |sensitive_header| 21 | config.filter_sensitive_data("[#{sensitive_header.upcase}]") do |interaction| 22 | interaction.request.headers[sensitive_header]&.first 23 | end 24 | end 25 | end 26 | -------------------------------------------------------------------------------- /examples/all/test/support/webmock.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | require "webmock/minitest" 4 | -------------------------------------------------------------------------------- /examples/all/test/system/.keep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mattbrictson/nextgen/c3a0ac5fb693be54309d2d9bb363fb27550e5056/examples/all/test/system/.keep -------------------------------------------------------------------------------- /examples/all/test/test_helper.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | ENV["RAILS_ENV"] ||= "test" 4 | require_relative "../config/environment" 5 | require "rails/test_help" 6 | 7 | module ActiveSupport 8 | class TestCase 9 | # Run tests in parallel with specified workers 10 | parallelize(workers: :number_of_processors) 11 | 12 | # Setup all fixtures in test/fixtures/*.yml for all tests in alphabetical order. 13 | fixtures :all 14 | 15 | # Add more helper methods to be used by all tests here... 16 | end 17 | end 18 | 19 | Dir[File.expand_path("support/**/*.rb", __dir__)].each { |rb| require(rb) } 20 | -------------------------------------------------------------------------------- /examples/all/tmp/.keep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mattbrictson/nextgen/c3a0ac5fb693be54309d2d9bb363fb27550e5056/examples/all/tmp/.keep -------------------------------------------------------------------------------- /examples/all/tmp/pids/.keep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mattbrictson/nextgen/c3a0ac5fb693be54309d2d9bb363fb27550e5056/examples/all/tmp/pids/.keep -------------------------------------------------------------------------------- /examples/all/tmp/storage/.keep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mattbrictson/nextgen/c3a0ac5fb693be54309d2d9bb363fb27550e5056/examples/all/tmp/storage/.keep -------------------------------------------------------------------------------- /examples/all/vendor/.keep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mattbrictson/nextgen/c3a0ac5fb693be54309d2d9bb363fb27550e5056/examples/all/vendor/.keep -------------------------------------------------------------------------------- /examples/all/vendor/javascript/.keep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mattbrictson/nextgen/c3a0ac5fb693be54309d2d9bb363fb27550e5056/examples/all/vendor/javascript/.keep -------------------------------------------------------------------------------- /examples/default/.editorconfig: -------------------------------------------------------------------------------- 1 | # https://editorconfig.org 2 | 3 | root = true 4 | 5 | [*] 6 | charset = utf-8 7 | indent_style = space 8 | indent_size = 2 9 | end_of_line = lf 10 | insert_final_newline = true 11 | trim_trailing_whitespace = true 12 | 13 | [Makefile] 14 | indent_style = tab 15 | -------------------------------------------------------------------------------- /examples/default/.gitattributes: -------------------------------------------------------------------------------- 1 | # See https://git-scm.com/docs/gitattributes for more about git attribute files. 2 | 3 | # Mark the database schema as having been generated. 4 | db/schema.rb linguist-generated 5 | 6 | # Mark any vendored files as having been vendored. 7 | vendor/* linguist-vendored 8 | config/credentials/*.yml.enc diff=rails_credentials 9 | config/credentials.yml.enc diff=rails_credentials 10 | -------------------------------------------------------------------------------- /examples/default/.github/dependabot.yml: -------------------------------------------------------------------------------- 1 | version: 2 2 | updates: 3 | - package-ecosystem: bundler 4 | directory: "/" 5 | schedule: 6 | interval: daily 7 | open-pull-requests-limit: 10 8 | - package-ecosystem: github-actions 9 | directory: "/" 10 | schedule: 11 | interval: daily 12 | open-pull-requests-limit: 10 13 | -------------------------------------------------------------------------------- /examples/default/.gitignore: -------------------------------------------------------------------------------- 1 | # See https://help.github.com/articles/ignoring-files for more about ignoring files. 2 | # 3 | # Temporary files generated by your text editor or operating system 4 | # belong in git's global ignore instead: 5 | # `$XDG_CONFIG_HOME/git/ignore` or `~/.config/git/ignore` 6 | 7 | # Ignore bundler config. 8 | /.bundle 9 | 10 | # Ignore all environment files. 11 | /.env* 12 | 13 | # Ignore all logfiles and tempfiles. 14 | /log/* 15 | /tmp/* 16 | !/log/.keep 17 | !/tmp/.keep 18 | 19 | # Ignore pidfiles, but keep the directory. 20 | /tmp/pids/* 21 | !/tmp/pids/ 22 | !/tmp/pids/.keep 23 | 24 | # Ignore storage (uploaded files in development and any SQLite databases). 25 | /storage/* 26 | !/storage/.keep 27 | /tmp/storage/* 28 | !/tmp/storage/ 29 | !/tmp/storage/.keep 30 | 31 | /public/assets 32 | 33 | # Ignore master key for decrypting credentials and more. 34 | /config/master.key 35 | -------------------------------------------------------------------------------- /examples/default/.kamal/hooks/docker-setup.sample: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | echo "Docker set up on $KAMAL_HOSTS..." 4 | -------------------------------------------------------------------------------- /examples/default/.kamal/hooks/post-deploy.sample: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | # A sample post-deploy hook 4 | # 5 | # These environment variables are available: 6 | # KAMAL_RECORDED_AT 7 | # KAMAL_PERFORMER 8 | # KAMAL_VERSION 9 | # KAMAL_HOSTS 10 | # KAMAL_ROLE (if set) 11 | # KAMAL_DESTINATION (if set) 12 | # KAMAL_RUNTIME 13 | 14 | echo "$KAMAL_PERFORMER deployed $KAMAL_VERSION to $KAMAL_DESTINATION in $KAMAL_RUNTIME seconds" 15 | -------------------------------------------------------------------------------- /examples/default/.kamal/hooks/post-proxy-reboot.sample: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | echo "Rebooted kamal-proxy on $KAMAL_HOSTS" 4 | -------------------------------------------------------------------------------- /examples/default/.kamal/hooks/pre-proxy-reboot.sample: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | echo "Rebooting kamal-proxy on $KAMAL_HOSTS..." 4 | -------------------------------------------------------------------------------- /examples/default/.prettierrc.cjs: -------------------------------------------------------------------------------- 1 | /** @type {import("prettier").Config} */ 2 | 3 | module.exports = { 4 | tabWidth: 2, 5 | useTabs: false, 6 | }; 7 | -------------------------------------------------------------------------------- /examples/default/.rubocop.yml: -------------------------------------------------------------------------------- 1 | # Omakase Ruby styling for Rails 2 | inherit_gem: { rubocop-rails-omakase: rubocop.yml } 3 | 4 | # Overwrite or add rules to create your own house style 5 | # 6 | # # Use `[a, [b, c]]` not `[ a, [ b, c ] ]` 7 | # Layout/SpaceInsideArrayLiteralBrackets: 8 | # Enabled: false 9 | -------------------------------------------------------------------------------- /examples/default/.ruby-version: -------------------------------------------------------------------------------- 1 | 3.4.1 2 | -------------------------------------------------------------------------------- /examples/default/DEPLOYMENT.md: -------------------------------------------------------------------------------- 1 | # Deployment 2 | 3 | ## Environment variables 4 | 5 | These environment variables affect how the app functions when deployed in production. 6 | 7 | - `RAILS_DISABLE_SSL` - Disable HSTS and secure cookies 8 | - `RAILS_ENV` **REQUIRED** - "production" 9 | - `RAILS_MAX_THREADS` - Number of threads per Puma process (default: 3) 10 | - `SECRET_KEY_BASE` **REQUIRED** - Unique, secret key used to encrypt and sign cookies and other sensitive data 11 | - `WEB_CONCURRENCY` - Number of Puma processes (default: 1) 12 | -------------------------------------------------------------------------------- /examples/default/Gemfile: -------------------------------------------------------------------------------- 1 | source "https://rubygems.org" 2 | 3 | ruby file: ".ruby-version" 4 | 5 | gem "rails", "~> 8.0.1" 6 | gem "propshaft" 7 | gem "sqlite3", ">= 2.1" 8 | gem "puma", ">= 5.0" 9 | gem "importmap-rails" 10 | gem "turbo-rails" 11 | gem "stimulus-rails" 12 | gem "jbuilder" 13 | gem "tzinfo-data", platforms: %i[ windows jruby ] 14 | gem "solid_cache" 15 | gem "solid_queue" 16 | gem "solid_cable" 17 | gem "bootsnap", require: false 18 | gem "kamal", require: false 19 | gem "thruster", require: false 20 | 21 | group :development, :test do 22 | gem "debug", platforms: %i[ mri windows ], require: "debug/prelude" 23 | gem "brakeman", require: false 24 | gem "rubocop-rails-omakase", require: false 25 | end 26 | 27 | group :development do 28 | gem "web-console" 29 | end 30 | 31 | group :test do 32 | gem "capybara", require: false 33 | gem "selenium-webdriver", require: false 34 | end 35 | -------------------------------------------------------------------------------- /examples/default/Procfile: -------------------------------------------------------------------------------- 1 | web: bundle exec puma -C config/puma.rb 2 | release: bundle exec rake db:migrate 3 | -------------------------------------------------------------------------------- /examples/default/Rakefile: -------------------------------------------------------------------------------- 1 | # Add your own tasks in files placed in lib/tasks ending in .rake, 2 | # for example lib/tasks/capistrano.rake, and they will automatically be available to Rake. 3 | 4 | require_relative "config/application" 5 | 6 | Rails.application.load_tasks 7 | 8 | Rake::Task[:default].prerequisites.clear if Rake::Task.task_defined?(:default) 9 | 10 | desc "Run all checks" 11 | task default: %w[test:all] do 12 | puts ">>>>>> [OK] All checks passed!" 13 | end 14 | -------------------------------------------------------------------------------- /examples/default/app/assets/images/.keep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mattbrictson/nextgen/c3a0ac5fb693be54309d2d9bb363fb27550e5056/examples/default/app/assets/images/.keep -------------------------------------------------------------------------------- /examples/default/app/assets/stylesheets/application.css: -------------------------------------------------------------------------------- 1 | /* 2 | * This is a manifest file that'll be compiled into application.css. 3 | * 4 | * With Propshaft, assets are served efficiently without preprocessing steps. You can still include 5 | * application-wide styles in this file, but keep in mind that CSS precedence will follow the standard 6 | * cascading order, meaning styles declared later in the document or manifest will override earlier ones, 7 | * depending on specificity. 8 | * 9 | * Consider organizing styles into separate files for maintainability. 10 | */ 11 | -------------------------------------------------------------------------------- /examples/default/app/controllers/application_controller.rb: -------------------------------------------------------------------------------- 1 | class ApplicationController < ActionController::Base 2 | # Only allow modern browsers supporting webp images, web push, badges, import maps, CSS nesting, and CSS :has. 3 | allow_browser versions: :modern 4 | end 5 | -------------------------------------------------------------------------------- /examples/default/app/controllers/concerns/.keep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mattbrictson/nextgen/c3a0ac5fb693be54309d2d9bb363fb27550e5056/examples/default/app/controllers/concerns/.keep -------------------------------------------------------------------------------- /examples/default/app/controllers/home_controller.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | class HomeController < ApplicationController 4 | def index 5 | end 6 | end 7 | -------------------------------------------------------------------------------- /examples/default/app/helpers/application_helper.rb: -------------------------------------------------------------------------------- 1 | module ApplicationHelper 2 | end 3 | -------------------------------------------------------------------------------- /examples/default/app/javascript/application.js: -------------------------------------------------------------------------------- 1 | // Configure your import map in config/importmap.rb. Read more: https://github.com/rails/importmap-rails 2 | import "@hotwired/turbo-rails" 3 | import "controllers" 4 | -------------------------------------------------------------------------------- /examples/default/app/javascript/controllers/application.js: -------------------------------------------------------------------------------- 1 | import { Application } from "@hotwired/stimulus" 2 | 3 | const application = Application.start() 4 | 5 | // Configure Stimulus development experience 6 | application.debug = false 7 | window.Stimulus = application 8 | 9 | export { application } 10 | -------------------------------------------------------------------------------- /examples/default/app/javascript/controllers/hello_controller.js: -------------------------------------------------------------------------------- 1 | import { Controller } from "@hotwired/stimulus" 2 | 3 | export default class extends Controller { 4 | connect() { 5 | this.element.textContent = "Hello World!" 6 | } 7 | } 8 | -------------------------------------------------------------------------------- /examples/default/app/javascript/controllers/index.js: -------------------------------------------------------------------------------- 1 | // Import and register all your controllers from the importmap via controllers/**/*_controller 2 | import { application } from "controllers/application" 3 | import { eagerLoadControllersFrom } from "@hotwired/stimulus-loading" 4 | eagerLoadControllersFrom("controllers", application) 5 | -------------------------------------------------------------------------------- /examples/default/app/jobs/application_job.rb: -------------------------------------------------------------------------------- 1 | class ApplicationJob < ActiveJob::Base 2 | # Automatically retry jobs that encountered a deadlock 3 | # retry_on ActiveRecord::Deadlocked 4 | 5 | # Most jobs are safe to ignore if the underlying records are no longer available 6 | # discard_on ActiveJob::DeserializationError 7 | end 8 | -------------------------------------------------------------------------------- /examples/default/app/mailers/application_mailer.rb: -------------------------------------------------------------------------------- 1 | class ApplicationMailer < ActionMailer::Base 2 | default from: "from@example.com" 3 | layout "mailer" 4 | end 5 | -------------------------------------------------------------------------------- /examples/default/app/models/application_record.rb: -------------------------------------------------------------------------------- 1 | class ApplicationRecord < ActiveRecord::Base 2 | primary_abstract_class 3 | end 4 | -------------------------------------------------------------------------------- /examples/default/app/models/concerns/.keep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mattbrictson/nextgen/c3a0ac5fb693be54309d2d9bb363fb27550e5056/examples/default/app/models/concerns/.keep -------------------------------------------------------------------------------- /examples/default/app/views/home/index.html.erb: -------------------------------------------------------------------------------- 1 | <% provide(:title, "Home") %> 2 |

Find me in app/views/home/index.html.erb

3 | -------------------------------------------------------------------------------- /examples/default/app/views/layouts/mailer.html.erb: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 8 | 9 | 10 | 11 | <%= yield %> 12 | 13 | 14 | -------------------------------------------------------------------------------- /examples/default/app/views/layouts/mailer.text.erb: -------------------------------------------------------------------------------- 1 | <%= yield %> 2 | -------------------------------------------------------------------------------- /examples/default/app/views/pwa/manifest.json.erb: -------------------------------------------------------------------------------- 1 | { 2 | "name": "DefaultExample", 3 | "icons": [ 4 | { 5 | "src": "/icon.png", 6 | "type": "image/png", 7 | "sizes": "512x512" 8 | }, 9 | { 10 | "src": "/icon.png", 11 | "type": "image/png", 12 | "sizes": "512x512", 13 | "purpose": "maskable" 14 | } 15 | ], 16 | "start_url": "/", 17 | "display": "standalone", 18 | "scope": "/", 19 | "description": "DefaultExample.", 20 | "theme_color": "red", 21 | "background_color": "red" 22 | } 23 | -------------------------------------------------------------------------------- /examples/default/app/views/pwa/service-worker.js: -------------------------------------------------------------------------------- 1 | // Add a service worker for processing Web Push notifications: 2 | // 3 | // self.addEventListener("push", async (event) => { 4 | // const { title, options } = await event.data.json() 5 | // event.waitUntil(self.registration.showNotification(title, options)) 6 | // }) 7 | // 8 | // self.addEventListener("notificationclick", function(event) { 9 | // event.notification.close() 10 | // event.waitUntil( 11 | // clients.matchAll({ type: "window" }).then((clientList) => { 12 | // for (let i = 0; i < clientList.length; i++) { 13 | // let client = clientList[i] 14 | // let clientPath = (new URL(client.url)).pathname 15 | // 16 | // if (clientPath == event.notification.data.path && "focus" in client) { 17 | // return client.focus() 18 | // } 19 | // } 20 | // 21 | // if (clients.openWindow) { 22 | // return clients.openWindow(event.notification.data.path) 23 | // } 24 | // }) 25 | // ) 26 | // }) 27 | -------------------------------------------------------------------------------- /examples/default/bin/brakeman: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env ruby 2 | require "rubygems" 3 | require "bundler/setup" 4 | 5 | ARGV.unshift("--ensure-latest") 6 | 7 | load Gem.bin_path("brakeman", "brakeman") 8 | -------------------------------------------------------------------------------- /examples/default/bin/dev: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env ruby 2 | exec "./bin/rails", "server", *ARGV 3 | -------------------------------------------------------------------------------- /examples/default/bin/docker-entrypoint: -------------------------------------------------------------------------------- 1 | #!/bin/bash -e 2 | 3 | # Enable jemalloc for reduced memory usage and latency. 4 | if [ -z "${LD_PRELOAD+x}" ]; then 5 | LD_PRELOAD=$(find /usr/lib -name libjemalloc.so.2 -print -quit) 6 | export LD_PRELOAD 7 | fi 8 | 9 | # If running the rails server then create or migrate existing database 10 | if [ "${@: -2:1}" == "./bin/rails" ] && [ "${@: -1:1}" == "server" ]; then 11 | ./bin/rails db:prepare 12 | fi 13 | 14 | exec "${@}" 15 | -------------------------------------------------------------------------------- /examples/default/bin/importmap: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env ruby 2 | 3 | require_relative "../config/application" 4 | require "importmap/commands" 5 | -------------------------------------------------------------------------------- /examples/default/bin/jobs: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env ruby 2 | 3 | require_relative "../config/environment" 4 | require "solid_queue/cli" 5 | 6 | SolidQueue::Cli.start(ARGV) 7 | -------------------------------------------------------------------------------- /examples/default/bin/kamal: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env ruby 2 | # frozen_string_literal: true 3 | 4 | # 5 | # This file was generated by Bundler. 6 | # 7 | # The application 'kamal' 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("kamal", "kamal") 28 | -------------------------------------------------------------------------------- /examples/default/bin/rails: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env ruby 2 | APP_PATH = File.expand_path("../config/application", __dir__) 3 | require_relative "../config/boot" 4 | require "rails/commands" 5 | -------------------------------------------------------------------------------- /examples/default/bin/rake: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env ruby 2 | require_relative "../config/boot" 3 | require "rake" 4 | Rake.application.run 5 | -------------------------------------------------------------------------------- /examples/default/bin/rubocop: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env ruby 2 | require "rubygems" 3 | require "bundler/setup" 4 | 5 | # explicit rubocop config increases performance slightly while avoiding config confusion. 6 | ARGV.unshift("--config", File.expand_path("../.rubocop.yml", __dir__)) 7 | 8 | load Gem.bin_path("rubocop", "rubocop") 9 | -------------------------------------------------------------------------------- /examples/default/bin/thrust: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env ruby 2 | require "rubygems" 3 | require "bundler/setup" 4 | 5 | load Gem.bin_path("thruster", "thrust") 6 | -------------------------------------------------------------------------------- /examples/default/config.ru: -------------------------------------------------------------------------------- 1 | # This file is used by Rack-based servers to start the application. 2 | 3 | require_relative "config/environment" 4 | 5 | run Rails.application 6 | Rails.application.load_server 7 | -------------------------------------------------------------------------------- /examples/default/config/boot.rb: -------------------------------------------------------------------------------- 1 | ENV["BUNDLE_GEMFILE"] ||= File.expand_path("../Gemfile", __dir__) 2 | 3 | require "bundler/setup" # Set up gems listed in the Gemfile. 4 | require "bootsnap/setup" # Speed up boot time by caching expensive operations. 5 | -------------------------------------------------------------------------------- /examples/default/config/cable.yml: -------------------------------------------------------------------------------- 1 | # Async adapter only works within the same process, so for manually triggering cable updates from a console, 2 | # and seeing results in the browser, you must do so from the web console (running inside the dev process), 3 | # not a terminal started via bin/rails console! Add "console" to any action or any ERB template view 4 | # to make the web console appear. 5 | development: 6 | adapter: async 7 | 8 | test: 9 | adapter: test 10 | 11 | production: 12 | adapter: solid_cable 13 | connects_to: 14 | database: 15 | writing: cable 16 | polling_interval: 0.1.seconds 17 | message_retention: 1.day 18 | -------------------------------------------------------------------------------- /examples/default/config/cache.yml: -------------------------------------------------------------------------------- 1 | default: &default 2 | store_options: 3 | # Cap age of oldest cache entry to fulfill retention policies 4 | # max_age: <%= 60.days.to_i %> 5 | max_size: <%= 256.megabytes %> 6 | namespace: <%= Rails.env %> 7 | 8 | development: 9 | <<: *default 10 | 11 | test: 12 | <<: *default 13 | 14 | production: 15 | database: cache 16 | <<: *default 17 | -------------------------------------------------------------------------------- /examples/default/config/credentials.yml.enc: -------------------------------------------------------------------------------- 1 | 4aECmi+wJK8CnyT1lQW5fa62ABjaONdwXbY5Ooc809hYc3fQ50OetjHRNuDYYY91rYYp0ZwpnKCUt+bPXboRrzb6oABgYnI666IiQ+fHBAGu0KuQ2fg3TXJGjH144Hiai3v3f6jXe/49I1Bpp6A4t9AcG78i2YXOA5bbYj4KGN9ZUFzxlbmhJgyckpFhfpFCVnobr7w1UG2oP84jqla+njJAqmWPBPZyuQpo1ZkeJHs00J+pu/IxAlDPnmJt5h2+fDNuluX78Xm54ipr+XYgo9ka1s4nquM5fOALslUVncJXnn7MgNKT1YNuT726hOOdU3VB6Gk+lxfAxhyIVVofsarV8qjbt5Dh6m+VX6h0BEJzqEujE6Y9iz12cOzM1zfiuT+6EXaL0W4o3OTTsQPoe/Kmi7o4aPCoDr8ngS1HcCgfgj2+kDDbgnyvtt/wUqzg4l8inGy3g4EkKgk6mdPrxohAqXn1p0ANx4ORnJCp5vwTQYaoz2qZ2xOv--nDrc/vtFCldqCiKZ--URF5nV+2eDq5zbDpTgr2Kw== -------------------------------------------------------------------------------- /examples/default/config/environment.rb: -------------------------------------------------------------------------------- 1 | # Load the Rails application. 2 | require_relative "application" 3 | 4 | # Initialize the Rails application. 5 | Rails.application.initialize! 6 | -------------------------------------------------------------------------------- /examples/default/config/importmap.rb: -------------------------------------------------------------------------------- 1 | # Pin npm packages by running ./bin/importmap 2 | 3 | pin "application" 4 | pin "@hotwired/turbo-rails", to: "turbo.min.js" 5 | pin "@hotwired/stimulus", to: "stimulus.min.js" 6 | pin "@hotwired/stimulus-loading", to: "stimulus-loading.js" 7 | pin_all_from "app/javascript/controllers", under: "controllers" 8 | -------------------------------------------------------------------------------- /examples/default/config/initializers/assets.rb: -------------------------------------------------------------------------------- 1 | # Be sure to restart your server when you modify this file. 2 | 3 | # Version of your assets, change this if you want to expire all your assets. 4 | Rails.application.config.assets.version = "1.0" 5 | 6 | # Add additional assets to the asset load path. 7 | # Rails.application.config.assets.paths << Emoji.images_path 8 | -------------------------------------------------------------------------------- /examples/default/config/initializers/filter_parameter_logging.rb: -------------------------------------------------------------------------------- 1 | # Be sure to restart your server when you modify this file. 2 | 3 | # Configure parameters to be partially matched (e.g. passw matches password) and filtered from the log file. 4 | # Use this to limit dissemination of sensitive information. 5 | # See the ActiveSupport::ParameterFilter documentation for supported notations and behaviors. 6 | Rails.application.config.filter_parameters += [ 7 | :passw, :email, :secret, :token, :_key, :crypt, :salt, :certificate, :otp, :ssn, :cvv, :cvc 8 | ] 9 | -------------------------------------------------------------------------------- /examples/default/config/initializers/generators.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | Rails.application.config.generators do |g| 4 | # Disable generators we don't need. 5 | g.javascripts false 6 | g.stylesheets false 7 | end 8 | -------------------------------------------------------------------------------- /examples/default/config/initializers/inflections.rb: -------------------------------------------------------------------------------- 1 | # Be sure to restart your server when you modify this file. 2 | 3 | # Add new inflection rules using the following format. Inflections 4 | # are locale specific, and you may define rules for as many different 5 | # locales as you wish. All of these examples are active by default: 6 | # ActiveSupport::Inflector.inflections(:en) do |inflect| 7 | # inflect.plural /^(ox)$/i, "\\1en" 8 | # inflect.singular /^(ox)en/i, "\\1" 9 | # inflect.irregular "person", "people" 10 | # inflect.uncountable %w( fish sheep ) 11 | # end 12 | 13 | # These inflection rules are supported but not enabled by default: 14 | # ActiveSupport::Inflector.inflections(:en) do |inflect| 15 | # inflect.acronym "RESTful" 16 | # end 17 | -------------------------------------------------------------------------------- /examples/default/config/locales/en.yml: -------------------------------------------------------------------------------- 1 | # Files in the config/locales directory are used for internationalization and 2 | # are automatically loaded by Rails. If you want to use locales other than 3 | # English, add the necessary files in this directory. 4 | # 5 | # To use the locales, use `I18n.t`: 6 | # 7 | # I18n.t "hello" 8 | # 9 | # In views, this is aliased to just `t`: 10 | # 11 | # <%= t("hello") %> 12 | # 13 | # To use a different locale, set it with `I18n.locale`: 14 | # 15 | # I18n.locale = :es 16 | # 17 | # This would use the information in config/locales/es.yml. 18 | # 19 | # To learn more about the API, please read the Rails Internationalization guide 20 | # at https://guides.rubyonrails.org/i18n.html. 21 | # 22 | # Be aware that YAML interprets the following case-insensitive strings as 23 | # booleans: `true`, `false`, `on`, `off`, `yes`, `no`. Therefore, these strings 24 | # must be quoted to be interpreted as strings. For example: 25 | # 26 | # en: 27 | # "yes": yup 28 | # enabled: "ON" 29 | 30 | en: 31 | hello: "Hello world" 32 | -------------------------------------------------------------------------------- /examples/default/config/queue.yml: -------------------------------------------------------------------------------- 1 | default: &default 2 | dispatchers: 3 | - polling_interval: 1 4 | batch_size: 500 5 | workers: 6 | - queues: "*" 7 | threads: 3 8 | processes: <%= ENV.fetch("JOB_CONCURRENCY", 1) %> 9 | polling_interval: 0.1 10 | 11 | development: 12 | <<: *default 13 | 14 | test: 15 | <<: *default 16 | 17 | production: 18 | <<: *default 19 | -------------------------------------------------------------------------------- /examples/default/config/recurring.yml: -------------------------------------------------------------------------------- 1 | # production: 2 | # periodic_cleanup: 3 | # class: CleanSoftDeletedRecordsJob 4 | # queue: background 5 | # args: [ 1000, { batch_size: 500 } ] 6 | # schedule: every hour 7 | # periodic_command: 8 | # command: "SoftDeletedRecord.due.delete_all" 9 | # priority: 2 10 | # schedule: at 5am every day 11 | -------------------------------------------------------------------------------- /examples/default/config/routes.rb: -------------------------------------------------------------------------------- 1 | Rails.application.routes.draw do 2 | root "home#index" 3 | # Define your application routes per the DSL in https://guides.rubyonrails.org/routing.html 4 | 5 | # Reveal health status on /up that returns 200 if the app boots with no exceptions, otherwise 500. 6 | # Can be used by load balancers and uptime monitors to verify that the app is live. 7 | get "up" => "rails/health#show", as: :rails_health_check 8 | 9 | # Render dynamic PWA files from app/views/pwa/* (remember to link manifest in application.html.erb) 10 | # get "manifest" => "rails/pwa#manifest", as: :pwa_manifest 11 | # get "service-worker" => "rails/pwa#service_worker", as: :pwa_service_worker 12 | 13 | # Defines the root path route ("/") 14 | # root "posts#index" 15 | end 16 | -------------------------------------------------------------------------------- /examples/default/db/cable_schema.rb: -------------------------------------------------------------------------------- 1 | ActiveRecord::Schema[7.1].define(version: 1) do 2 | create_table "solid_cable_messages", force: :cascade do |t| 3 | t.binary "channel", limit: 1024, null: false 4 | t.binary "payload", limit: 536870912, null: false 5 | t.datetime "created_at", null: false 6 | t.integer "channel_hash", limit: 8, null: false 7 | t.index ["channel"], name: "index_solid_cable_messages_on_channel" 8 | t.index ["channel_hash"], name: "index_solid_cable_messages_on_channel_hash" 9 | t.index ["created_at"], name: "index_solid_cable_messages_on_created_at" 10 | end 11 | end 12 | -------------------------------------------------------------------------------- /examples/default/db/cache_schema.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | ActiveRecord::Schema[7.2].define(version: 1) do 4 | create_table "solid_cache_entries", force: :cascade do |t| 5 | t.binary "key", limit: 1024, null: false 6 | t.binary "value", limit: 536870912, null: false 7 | t.datetime "created_at", null: false 8 | t.integer "key_hash", limit: 8, null: false 9 | t.integer "byte_size", limit: 4, null: false 10 | t.index ["byte_size"], name: "index_solid_cache_entries_on_byte_size" 11 | t.index ["key_hash", "byte_size"], name: "index_solid_cache_entries_on_key_hash_and_byte_size" 12 | t.index ["key_hash"], name: "index_solid_cache_entries_on_key_hash", unique: true 13 | end 14 | end 15 | -------------------------------------------------------------------------------- /examples/default/db/schema.rb: -------------------------------------------------------------------------------- 1 | # This file is auto-generated from the current state of the database. Instead 2 | # of editing this file, please use the migrations feature of Active Record to 3 | # incrementally modify your database, and then regenerate this schema definition. 4 | # 5 | # This file is the source Rails uses to define your schema when running `bin/rails 6 | # db:schema:load`. When creating a new database, `bin/rails db:schema:load` tends to 7 | # be faster and is potentially less error prone than running all of your 8 | # migrations from scratch. Old migrations may fail to apply correctly if those 9 | # migrations use external dependencies or application code. 10 | # 11 | # It's strongly recommended that you check this file into your version control system. 12 | 13 | ActiveRecord::Schema[8.0].define(version: 0) do 14 | end 15 | -------------------------------------------------------------------------------- /examples/default/db/seeds.rb: -------------------------------------------------------------------------------- 1 | # This file should ensure the existence of records required to run the application in every environment (production, 2 | # development, test). The code here should be idempotent so that it can be executed at any point in every environment. 3 | # The data can then be loaded with the bin/rails db:seed command (or created alongside the database with db:setup). 4 | # 5 | # Example: 6 | # 7 | # ["Action", "Comedy", "Drama", "Horror"].each do |genre_name| 8 | # MovieGenre.find_or_create_by!(name: genre_name) 9 | # end 10 | -------------------------------------------------------------------------------- /examples/default/lib/tasks/.keep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mattbrictson/nextgen/c3a0ac5fb693be54309d2d9bb363fb27550e5056/examples/default/lib/tasks/.keep -------------------------------------------------------------------------------- /examples/default/log/.keep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mattbrictson/nextgen/c3a0ac5fb693be54309d2d9bb363fb27550e5056/examples/default/log/.keep -------------------------------------------------------------------------------- /examples/default/public/icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mattbrictson/nextgen/c3a0ac5fb693be54309d2d9bb363fb27550e5056/examples/default/public/icon.png -------------------------------------------------------------------------------- /examples/default/public/icon.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /examples/default/public/robots.txt: -------------------------------------------------------------------------------- 1 | # See https://www.robotstxt.org/robotstxt.html for documentation on how to use the robots.txt file 2 | -------------------------------------------------------------------------------- /examples/default/script/.keep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mattbrictson/nextgen/c3a0ac5fb693be54309d2d9bb363fb27550e5056/examples/default/script/.keep -------------------------------------------------------------------------------- /examples/default/storage/.keep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mattbrictson/nextgen/c3a0ac5fb693be54309d2d9bb363fb27550e5056/examples/default/storage/.keep -------------------------------------------------------------------------------- /examples/default/test/application_system_test_case.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | require "test_helper" 4 | 5 | class ApplicationSystemTestCase < ActionDispatch::SystemTestCase 6 | driven_by :selenium, 7 | using: (ENV["SHOW_BROWSER"] ? :chrome : :headless_chrome), 8 | screen_size: [1400, 1400] do |options| 9 | # Allows running in Docker 10 | options.add_argument("--disable-dev-shm-usage") 11 | options.add_argument("--no-sandbox") 12 | 13 | # Fixes slowdowns on macOS 14 | options.add_argument("--disable-gpu") 15 | end 16 | end 17 | -------------------------------------------------------------------------------- /examples/default/test/controllers/.keep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mattbrictson/nextgen/c3a0ac5fb693be54309d2d9bb363fb27550e5056/examples/default/test/controllers/.keep -------------------------------------------------------------------------------- /examples/default/test/fixtures/files/.keep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mattbrictson/nextgen/c3a0ac5fb693be54309d2d9bb363fb27550e5056/examples/default/test/fixtures/files/.keep -------------------------------------------------------------------------------- /examples/default/test/helpers/.keep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mattbrictson/nextgen/c3a0ac5fb693be54309d2d9bb363fb27550e5056/examples/default/test/helpers/.keep -------------------------------------------------------------------------------- /examples/default/test/integration/.keep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mattbrictson/nextgen/c3a0ac5fb693be54309d2d9bb363fb27550e5056/examples/default/test/integration/.keep -------------------------------------------------------------------------------- /examples/default/test/mailers/.keep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mattbrictson/nextgen/c3a0ac5fb693be54309d2d9bb363fb27550e5056/examples/default/test/mailers/.keep -------------------------------------------------------------------------------- /examples/default/test/models/.keep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mattbrictson/nextgen/c3a0ac5fb693be54309d2d9bb363fb27550e5056/examples/default/test/models/.keep -------------------------------------------------------------------------------- /examples/default/test/support/capybara.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | ActiveSupport.on_load(:action_dispatch_system_test_case) do 4 | require "capybara" 5 | require "capybara/rails" 6 | 7 | Capybara.configure do |config| 8 | config.default_max_wait_time = 2 9 | config.save_path = "tmp/screenshots" 10 | config.enable_aria_label = true 11 | config.server = :puma, {Silent: true} 12 | config.test_id = "data-testid" 13 | end 14 | end 15 | -------------------------------------------------------------------------------- /examples/default/test/support/mailer.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | ActiveSupport.on_load(:active_support_test_case) do 4 | setup { ActionMailer::Base.deliveries.clear } 5 | end 6 | -------------------------------------------------------------------------------- /examples/default/test/system/.keep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mattbrictson/nextgen/c3a0ac5fb693be54309d2d9bb363fb27550e5056/examples/default/test/system/.keep -------------------------------------------------------------------------------- /examples/default/test/test_helper.rb: -------------------------------------------------------------------------------- 1 | ENV["RAILS_ENV"] ||= "test" 2 | require_relative "../config/environment" 3 | require "rails/test_help" 4 | 5 | module ActiveSupport 6 | class TestCase 7 | # Run tests in parallel with specified workers 8 | parallelize(workers: :number_of_processors) 9 | 10 | # Setup all fixtures in test/fixtures/*.yml for all tests in alphabetical order. 11 | fixtures :all 12 | 13 | # Add more helper methods to be used by all tests here... 14 | end 15 | end 16 | 17 | Dir[File.expand_path("support/**/*.rb", __dir__)].sort.each { |rb| require(rb) } 18 | -------------------------------------------------------------------------------- /examples/default/tmp/.keep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mattbrictson/nextgen/c3a0ac5fb693be54309d2d9bb363fb27550e5056/examples/default/tmp/.keep -------------------------------------------------------------------------------- /examples/default/tmp/pids/.keep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mattbrictson/nextgen/c3a0ac5fb693be54309d2d9bb363fb27550e5056/examples/default/tmp/pids/.keep -------------------------------------------------------------------------------- /examples/default/tmp/storage/.keep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mattbrictson/nextgen/c3a0ac5fb693be54309d2d9bb363fb27550e5056/examples/default/tmp/storage/.keep -------------------------------------------------------------------------------- /examples/default/vendor/.keep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mattbrictson/nextgen/c3a0ac5fb693be54309d2d9bb363fb27550e5056/examples/default/vendor/.keep -------------------------------------------------------------------------------- /examples/default/vendor/javascript/.keep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mattbrictson/nextgen/c3a0ac5fb693be54309d2d9bb363fb27550e5056/examples/default/vendor/javascript/.keep -------------------------------------------------------------------------------- /examples/rspec/.editorconfig: -------------------------------------------------------------------------------- 1 | # https://editorconfig.org 2 | 3 | root = true 4 | 5 | [*] 6 | charset = utf-8 7 | indent_style = space 8 | indent_size = 2 9 | end_of_line = lf 10 | insert_final_newline = true 11 | trim_trailing_whitespace = true 12 | 13 | [Makefile] 14 | indent_style = tab 15 | -------------------------------------------------------------------------------- /examples/rspec/.gitattributes: -------------------------------------------------------------------------------- 1 | # See https://git-scm.com/docs/gitattributes for more about git attribute files. 2 | 3 | # Mark the database schema as having been generated. 4 | db/schema.rb linguist-generated 5 | 6 | # Mark any vendored files as having been vendored. 7 | vendor/* linguist-vendored 8 | config/credentials/*.yml.enc diff=rails_credentials 9 | config/credentials.yml.enc diff=rails_credentials 10 | -------------------------------------------------------------------------------- /examples/rspec/.github/dependabot.yml: -------------------------------------------------------------------------------- 1 | version: 2 2 | updates: 3 | - package-ecosystem: bundler 4 | directory: "/" 5 | schedule: 6 | interval: daily 7 | open-pull-requests-limit: 10 8 | - package-ecosystem: github-actions 9 | directory: "/" 10 | schedule: 11 | interval: daily 12 | open-pull-requests-limit: 10 13 | -------------------------------------------------------------------------------- /examples/rspec/.gitignore: -------------------------------------------------------------------------------- 1 | # See https://help.github.com/articles/ignoring-files for more about ignoring files. 2 | # 3 | # Temporary files generated by your text editor or operating system 4 | # belong in git's global ignore instead: 5 | # `$XDG_CONFIG_HOME/git/ignore` or `~/.config/git/ignore` 6 | 7 | # Ignore bundler config. 8 | /.bundle 9 | 10 | # Ignore all environment files. 11 | /.env* 12 | 13 | # Ignore all logfiles and tempfiles. 14 | /log/* 15 | /tmp/* 16 | !/log/.keep 17 | !/tmp/.keep 18 | 19 | # Ignore pidfiles, but keep the directory. 20 | /tmp/pids/* 21 | !/tmp/pids/ 22 | !/tmp/pids/.keep 23 | 24 | # Ignore storage (uploaded files in development and any SQLite databases). 25 | /storage/* 26 | !/storage/.keep 27 | /tmp/storage/* 28 | !/tmp/storage/ 29 | !/tmp/storage/.keep 30 | 31 | /public/assets 32 | 33 | # Ignore master key for decrypting credentials and more. 34 | /config/master.key 35 | /spec/examples.txt 36 | -------------------------------------------------------------------------------- /examples/rspec/.kamal/hooks/docker-setup.sample: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | echo "Docker set up on $KAMAL_HOSTS..." 4 | -------------------------------------------------------------------------------- /examples/rspec/.kamal/hooks/post-deploy.sample: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | # A sample post-deploy hook 4 | # 5 | # These environment variables are available: 6 | # KAMAL_RECORDED_AT 7 | # KAMAL_PERFORMER 8 | # KAMAL_VERSION 9 | # KAMAL_HOSTS 10 | # KAMAL_ROLE (if set) 11 | # KAMAL_DESTINATION (if set) 12 | # KAMAL_RUNTIME 13 | 14 | echo "$KAMAL_PERFORMER deployed $KAMAL_VERSION to $KAMAL_DESTINATION in $KAMAL_RUNTIME seconds" 15 | -------------------------------------------------------------------------------- /examples/rspec/.kamal/hooks/post-proxy-reboot.sample: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | echo "Rebooted kamal-proxy on $KAMAL_HOSTS" 4 | -------------------------------------------------------------------------------- /examples/rspec/.kamal/hooks/pre-proxy-reboot.sample: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | echo "Rebooting kamal-proxy on $KAMAL_HOSTS..." 4 | -------------------------------------------------------------------------------- /examples/rspec/.prettierrc.cjs: -------------------------------------------------------------------------------- 1 | /** @type {import("prettier").Config} */ 2 | 3 | module.exports = { 4 | tabWidth: 2, 5 | useTabs: false, 6 | }; 7 | -------------------------------------------------------------------------------- /examples/rspec/.rspec: -------------------------------------------------------------------------------- 1 | --require spec_helper 2 | -------------------------------------------------------------------------------- /examples/rspec/.rubocop.yml: -------------------------------------------------------------------------------- 1 | # Omakase Ruby styling for Rails 2 | inherit_gem: { rubocop-rails-omakase: rubocop.yml } 3 | 4 | # Overwrite or add rules to create your own house style 5 | # 6 | # # Use `[a, [b, c]]` not `[ a, [ b, c ] ]` 7 | # Layout/SpaceInsideArrayLiteralBrackets: 8 | # Enabled: false 9 | -------------------------------------------------------------------------------- /examples/rspec/.ruby-version: -------------------------------------------------------------------------------- 1 | 3.4.1 2 | -------------------------------------------------------------------------------- /examples/rspec/DEPLOYMENT.md: -------------------------------------------------------------------------------- 1 | # Deployment 2 | 3 | ## Environment variables 4 | 5 | These environment variables affect how the app functions when deployed in production. 6 | 7 | - `RAILS_DISABLE_SSL` - Disable HSTS and secure cookies 8 | - `RAILS_ENV` **REQUIRED** - "production" 9 | - `RAILS_MAX_THREADS` - Number of threads per Puma process (default: 3) 10 | - `SECRET_KEY_BASE` **REQUIRED** - Unique, secret key used to encrypt and sign cookies and other sensitive data 11 | - `WEB_CONCURRENCY` - Number of Puma processes (default: 1) 12 | -------------------------------------------------------------------------------- /examples/rspec/Gemfile: -------------------------------------------------------------------------------- 1 | source "https://rubygems.org" 2 | 3 | ruby file: ".ruby-version" 4 | 5 | gem "rails", "~> 8.0.1" 6 | gem "propshaft" 7 | gem "sqlite3", ">= 2.1" 8 | gem "puma", ">= 5.0" 9 | gem "importmap-rails" 10 | gem "turbo-rails" 11 | gem "stimulus-rails" 12 | gem "jbuilder" 13 | gem "tzinfo-data", platforms: %i[ windows jruby ] 14 | gem "solid_cache" 15 | gem "solid_queue" 16 | gem "solid_cable" 17 | gem "bootsnap", require: false 18 | gem "kamal", require: false 19 | gem "thruster", require: false 20 | 21 | group :development, :test do 22 | gem "rspec-rails" 23 | gem "debug", platforms: %i[ mri windows ], require: "debug/prelude" 24 | gem "brakeman", require: false 25 | gem "rubocop-rails-omakase", require: false 26 | end 27 | 28 | group :development do 29 | gem "web-console" 30 | end 31 | 32 | group :test do 33 | gem "selenium-webdriver", require: false 34 | gem "capybara", require: false 35 | end 36 | -------------------------------------------------------------------------------- /examples/rspec/Procfile: -------------------------------------------------------------------------------- 1 | web: bundle exec puma -C config/puma.rb 2 | release: bundle exec rake db:migrate 3 | -------------------------------------------------------------------------------- /examples/rspec/Rakefile: -------------------------------------------------------------------------------- 1 | # Add your own tasks in files placed in lib/tasks ending in .rake, 2 | # for example lib/tasks/capistrano.rake, and they will automatically be available to Rake. 3 | 4 | require_relative "config/application" 5 | 6 | Rails.application.load_tasks 7 | 8 | Rake::Task[:default].prerequisites.clear if Rake::Task.task_defined?(:default) 9 | 10 | desc "Run all checks" 11 | task default: %w[spec] do 12 | puts ">>>>>> [OK] All checks passed!" 13 | end 14 | -------------------------------------------------------------------------------- /examples/rspec/app/assets/images/.keep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mattbrictson/nextgen/c3a0ac5fb693be54309d2d9bb363fb27550e5056/examples/rspec/app/assets/images/.keep -------------------------------------------------------------------------------- /examples/rspec/app/assets/stylesheets/application.css: -------------------------------------------------------------------------------- 1 | /* 2 | * This is a manifest file that'll be compiled into application.css. 3 | * 4 | * With Propshaft, assets are served efficiently without preprocessing steps. You can still include 5 | * application-wide styles in this file, but keep in mind that CSS precedence will follow the standard 6 | * cascading order, meaning styles declared later in the document or manifest will override earlier ones, 7 | * depending on specificity. 8 | * 9 | * Consider organizing styles into separate files for maintainability. 10 | */ 11 | -------------------------------------------------------------------------------- /examples/rspec/app/controllers/application_controller.rb: -------------------------------------------------------------------------------- 1 | class ApplicationController < ActionController::Base 2 | # Only allow modern browsers supporting webp images, web push, badges, import maps, CSS nesting, and CSS :has. 3 | allow_browser versions: :modern 4 | end 5 | -------------------------------------------------------------------------------- /examples/rspec/app/controllers/concerns/.keep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mattbrictson/nextgen/c3a0ac5fb693be54309d2d9bb363fb27550e5056/examples/rspec/app/controllers/concerns/.keep -------------------------------------------------------------------------------- /examples/rspec/app/controllers/home_controller.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | class HomeController < ApplicationController 4 | def index 5 | end 6 | end 7 | -------------------------------------------------------------------------------- /examples/rspec/app/helpers/application_helper.rb: -------------------------------------------------------------------------------- 1 | module ApplicationHelper 2 | end 3 | -------------------------------------------------------------------------------- /examples/rspec/app/javascript/application.js: -------------------------------------------------------------------------------- 1 | // Configure your import map in config/importmap.rb. Read more: https://github.com/rails/importmap-rails 2 | import "@hotwired/turbo-rails" 3 | import "controllers" 4 | -------------------------------------------------------------------------------- /examples/rspec/app/javascript/controllers/application.js: -------------------------------------------------------------------------------- 1 | import { Application } from "@hotwired/stimulus" 2 | 3 | const application = Application.start() 4 | 5 | // Configure Stimulus development experience 6 | application.debug = false 7 | window.Stimulus = application 8 | 9 | export { application } 10 | -------------------------------------------------------------------------------- /examples/rspec/app/javascript/controllers/hello_controller.js: -------------------------------------------------------------------------------- 1 | import { Controller } from "@hotwired/stimulus" 2 | 3 | export default class extends Controller { 4 | connect() { 5 | this.element.textContent = "Hello World!" 6 | } 7 | } 8 | -------------------------------------------------------------------------------- /examples/rspec/app/javascript/controllers/index.js: -------------------------------------------------------------------------------- 1 | // Import and register all your controllers from the importmap via controllers/**/*_controller 2 | import { application } from "controllers/application" 3 | import { eagerLoadControllersFrom } from "@hotwired/stimulus-loading" 4 | eagerLoadControllersFrom("controllers", application) 5 | -------------------------------------------------------------------------------- /examples/rspec/app/jobs/application_job.rb: -------------------------------------------------------------------------------- 1 | class ApplicationJob < ActiveJob::Base 2 | # Automatically retry jobs that encountered a deadlock 3 | # retry_on ActiveRecord::Deadlocked 4 | 5 | # Most jobs are safe to ignore if the underlying records are no longer available 6 | # discard_on ActiveJob::DeserializationError 7 | end 8 | -------------------------------------------------------------------------------- /examples/rspec/app/mailers/application_mailer.rb: -------------------------------------------------------------------------------- 1 | class ApplicationMailer < ActionMailer::Base 2 | default from: "from@example.com" 3 | layout "mailer" 4 | end 5 | -------------------------------------------------------------------------------- /examples/rspec/app/models/application_record.rb: -------------------------------------------------------------------------------- 1 | class ApplicationRecord < ActiveRecord::Base 2 | primary_abstract_class 3 | end 4 | -------------------------------------------------------------------------------- /examples/rspec/app/models/concerns/.keep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mattbrictson/nextgen/c3a0ac5fb693be54309d2d9bb363fb27550e5056/examples/rspec/app/models/concerns/.keep -------------------------------------------------------------------------------- /examples/rspec/app/views/home/index.html.erb: -------------------------------------------------------------------------------- 1 | <% provide(:title, "Home") %> 2 |

Find me in app/views/home/index.html.erb

3 | -------------------------------------------------------------------------------- /examples/rspec/app/views/layouts/mailer.html.erb: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 8 | 9 | 10 | 11 | <%= yield %> 12 | 13 | 14 | -------------------------------------------------------------------------------- /examples/rspec/app/views/layouts/mailer.text.erb: -------------------------------------------------------------------------------- 1 | <%= yield %> 2 | -------------------------------------------------------------------------------- /examples/rspec/app/views/pwa/manifest.json.erb: -------------------------------------------------------------------------------- 1 | { 2 | "name": "RspecExample", 3 | "icons": [ 4 | { 5 | "src": "/icon.png", 6 | "type": "image/png", 7 | "sizes": "512x512" 8 | }, 9 | { 10 | "src": "/icon.png", 11 | "type": "image/png", 12 | "sizes": "512x512", 13 | "purpose": "maskable" 14 | } 15 | ], 16 | "start_url": "/", 17 | "display": "standalone", 18 | "scope": "/", 19 | "description": "RspecExample.", 20 | "theme_color": "red", 21 | "background_color": "red" 22 | } 23 | -------------------------------------------------------------------------------- /examples/rspec/app/views/pwa/service-worker.js: -------------------------------------------------------------------------------- 1 | // Add a service worker for processing Web Push notifications: 2 | // 3 | // self.addEventListener("push", async (event) => { 4 | // const { title, options } = await event.data.json() 5 | // event.waitUntil(self.registration.showNotification(title, options)) 6 | // }) 7 | // 8 | // self.addEventListener("notificationclick", function(event) { 9 | // event.notification.close() 10 | // event.waitUntil( 11 | // clients.matchAll({ type: "window" }).then((clientList) => { 12 | // for (let i = 0; i < clientList.length; i++) { 13 | // let client = clientList[i] 14 | // let clientPath = (new URL(client.url)).pathname 15 | // 16 | // if (clientPath == event.notification.data.path && "focus" in client) { 17 | // return client.focus() 18 | // } 19 | // } 20 | // 21 | // if (clients.openWindow) { 22 | // return clients.openWindow(event.notification.data.path) 23 | // } 24 | // }) 25 | // ) 26 | // }) 27 | -------------------------------------------------------------------------------- /examples/rspec/bin/brakeman: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env ruby 2 | require "rubygems" 3 | require "bundler/setup" 4 | 5 | ARGV.unshift("--ensure-latest") 6 | 7 | load Gem.bin_path("brakeman", "brakeman") 8 | -------------------------------------------------------------------------------- /examples/rspec/bin/dev: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env ruby 2 | exec "./bin/rails", "server", *ARGV 3 | -------------------------------------------------------------------------------- /examples/rspec/bin/docker-entrypoint: -------------------------------------------------------------------------------- 1 | #!/bin/bash -e 2 | 3 | # Enable jemalloc for reduced memory usage and latency. 4 | if [ -z "${LD_PRELOAD+x}" ]; then 5 | LD_PRELOAD=$(find /usr/lib -name libjemalloc.so.2 -print -quit) 6 | export LD_PRELOAD 7 | fi 8 | 9 | # If running the rails server then create or migrate existing database 10 | if [ "${@: -2:1}" == "./bin/rails" ] && [ "${@: -1:1}" == "server" ]; then 11 | ./bin/rails db:prepare 12 | fi 13 | 14 | exec "${@}" 15 | -------------------------------------------------------------------------------- /examples/rspec/bin/importmap: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env ruby 2 | 3 | require_relative "../config/application" 4 | require "importmap/commands" 5 | -------------------------------------------------------------------------------- /examples/rspec/bin/jobs: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env ruby 2 | 3 | require_relative "../config/environment" 4 | require "solid_queue/cli" 5 | 6 | SolidQueue::Cli.start(ARGV) 7 | -------------------------------------------------------------------------------- /examples/rspec/bin/kamal: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env ruby 2 | # frozen_string_literal: true 3 | 4 | # 5 | # This file was generated by Bundler. 6 | # 7 | # The application 'kamal' 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("kamal", "kamal") 28 | -------------------------------------------------------------------------------- /examples/rspec/bin/rails: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env ruby 2 | APP_PATH = File.expand_path("../config/application", __dir__) 3 | require_relative "../config/boot" 4 | require "rails/commands" 5 | -------------------------------------------------------------------------------- /examples/rspec/bin/rake: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env ruby 2 | require_relative "../config/boot" 3 | require "rake" 4 | Rake.application.run 5 | -------------------------------------------------------------------------------- /examples/rspec/bin/rspec: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env ruby 2 | # frozen_string_literal: true 3 | 4 | # 5 | # This file was generated by Bundler. 6 | # 7 | # The application 'rspec' 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("rspec-core", "rspec") 28 | -------------------------------------------------------------------------------- /examples/rspec/bin/rubocop: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env ruby 2 | require "rubygems" 3 | require "bundler/setup" 4 | 5 | # explicit rubocop config increases performance slightly while avoiding config confusion. 6 | ARGV.unshift("--config", File.expand_path("../.rubocop.yml", __dir__)) 7 | 8 | load Gem.bin_path("rubocop", "rubocop") 9 | -------------------------------------------------------------------------------- /examples/rspec/bin/thrust: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env ruby 2 | require "rubygems" 3 | require "bundler/setup" 4 | 5 | load Gem.bin_path("thruster", "thrust") 6 | -------------------------------------------------------------------------------- /examples/rspec/config.ru: -------------------------------------------------------------------------------- 1 | # This file is used by Rack-based servers to start the application. 2 | 3 | require_relative "config/environment" 4 | 5 | run Rails.application 6 | Rails.application.load_server 7 | -------------------------------------------------------------------------------- /examples/rspec/config/boot.rb: -------------------------------------------------------------------------------- 1 | ENV["BUNDLE_GEMFILE"] ||= File.expand_path("../Gemfile", __dir__) 2 | 3 | require "bundler/setup" # Set up gems listed in the Gemfile. 4 | require "bootsnap/setup" # Speed up boot time by caching expensive operations. 5 | -------------------------------------------------------------------------------- /examples/rspec/config/cable.yml: -------------------------------------------------------------------------------- 1 | # Async adapter only works within the same process, so for manually triggering cable updates from a console, 2 | # and seeing results in the browser, you must do so from the web console (running inside the dev process), 3 | # not a terminal started via bin/rails console! Add "console" to any action or any ERB template view 4 | # to make the web console appear. 5 | development: 6 | adapter: async 7 | 8 | test: 9 | adapter: test 10 | 11 | production: 12 | adapter: solid_cable 13 | connects_to: 14 | database: 15 | writing: cable 16 | polling_interval: 0.1.seconds 17 | message_retention: 1.day 18 | -------------------------------------------------------------------------------- /examples/rspec/config/cache.yml: -------------------------------------------------------------------------------- 1 | default: &default 2 | store_options: 3 | # Cap age of oldest cache entry to fulfill retention policies 4 | # max_age: <%= 60.days.to_i %> 5 | max_size: <%= 256.megabytes %> 6 | namespace: <%= Rails.env %> 7 | 8 | development: 9 | <<: *default 10 | 11 | test: 12 | <<: *default 13 | 14 | production: 15 | database: cache 16 | <<: *default 17 | -------------------------------------------------------------------------------- /examples/rspec/config/credentials.yml.enc: -------------------------------------------------------------------------------- 1 | RNd03yzut7pt4tkLiNIyPStG+p0OyoowpylBLF3AnUo8L/yKLLDxHo3sZNkoHEhIS46Xa8pXEeFzGseywZHR25ma9qvkoHsKqsKkaNfNCmXyGpeBpcWWJvi5FHSMJMLc1J9/ZJP+CQWGsb1THIPiFMlb9lRNBKrmD5u5O0txr9rmEfnElJpHJdOJRsuG6N98G0tWiJLU71gJBKfsC/eGTNUNULvFIT95JzWIMT/5wUzLf5lmKebGAJt3UgjEVKHabva3MTt8Z5nXYp0mne8EeJg+ReaAwfMBoX3SKODtJOk1pn/oTuA4CzbSpQGfITYKoG+7eJozyTCF2kqELXo3Ct84Sa1LPjDyrEapjuBjJ9xAU7ZU+XlzrNJoKi7sVrJUc2ZHjCVFps01BzyCWqZ82/IyJ1ExCUib65jYFOvV/bPFaQ+6fKRMV6CiFmwGZBZ9a69Nc6seM1Ya8jbfjNfeITXwwty6JKdmO7sQqJs2bPQoL0z4h174e53v--ac4kA/pQBBSHK7j4--sSRRLvOivZYmeJhRYO+neg== -------------------------------------------------------------------------------- /examples/rspec/config/environment.rb: -------------------------------------------------------------------------------- 1 | # Load the Rails application. 2 | require_relative "application" 3 | 4 | # Initialize the Rails application. 5 | Rails.application.initialize! 6 | -------------------------------------------------------------------------------- /examples/rspec/config/importmap.rb: -------------------------------------------------------------------------------- 1 | # Pin npm packages by running ./bin/importmap 2 | 3 | pin "application" 4 | pin "@hotwired/turbo-rails", to: "turbo.min.js" 5 | pin "@hotwired/stimulus", to: "stimulus.min.js" 6 | pin "@hotwired/stimulus-loading", to: "stimulus-loading.js" 7 | pin_all_from "app/javascript/controllers", under: "controllers" 8 | -------------------------------------------------------------------------------- /examples/rspec/config/initializers/assets.rb: -------------------------------------------------------------------------------- 1 | # Be sure to restart your server when you modify this file. 2 | 3 | # Version of your assets, change this if you want to expire all your assets. 4 | Rails.application.config.assets.version = "1.0" 5 | 6 | # Add additional assets to the asset load path. 7 | # Rails.application.config.assets.paths << Emoji.images_path 8 | -------------------------------------------------------------------------------- /examples/rspec/config/initializers/filter_parameter_logging.rb: -------------------------------------------------------------------------------- 1 | # Be sure to restart your server when you modify this file. 2 | 3 | # Configure parameters to be partially matched (e.g. passw matches password) and filtered from the log file. 4 | # Use this to limit dissemination of sensitive information. 5 | # See the ActiveSupport::ParameterFilter documentation for supported notations and behaviors. 6 | Rails.application.config.filter_parameters += [ 7 | :passw, :email, :secret, :token, :_key, :crypt, :salt, :certificate, :otp, :ssn, :cvv, :cvc 8 | ] 9 | -------------------------------------------------------------------------------- /examples/rspec/config/initializers/generators.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | Rails.application.config.generators do |g| 4 | # Disable generators we don't need. 5 | g.javascripts false 6 | g.stylesheets false 7 | g.routing_specs false 8 | g.view_specs false 9 | end 10 | -------------------------------------------------------------------------------- /examples/rspec/config/initializers/inflections.rb: -------------------------------------------------------------------------------- 1 | # Be sure to restart your server when you modify this file. 2 | 3 | # Add new inflection rules using the following format. Inflections 4 | # are locale specific, and you may define rules for as many different 5 | # locales as you wish. All of these examples are active by default: 6 | # ActiveSupport::Inflector.inflections(:en) do |inflect| 7 | # inflect.plural /^(ox)$/i, "\\1en" 8 | # inflect.singular /^(ox)en/i, "\\1" 9 | # inflect.irregular "person", "people" 10 | # inflect.uncountable %w( fish sheep ) 11 | # end 12 | 13 | # These inflection rules are supported but not enabled by default: 14 | # ActiveSupport::Inflector.inflections(:en) do |inflect| 15 | # inflect.acronym "RESTful" 16 | # end 17 | -------------------------------------------------------------------------------- /examples/rspec/config/locales/en.yml: -------------------------------------------------------------------------------- 1 | # Files in the config/locales directory are used for internationalization and 2 | # are automatically loaded by Rails. If you want to use locales other than 3 | # English, add the necessary files in this directory. 4 | # 5 | # To use the locales, use `I18n.t`: 6 | # 7 | # I18n.t "hello" 8 | # 9 | # In views, this is aliased to just `t`: 10 | # 11 | # <%= t("hello") %> 12 | # 13 | # To use a different locale, set it with `I18n.locale`: 14 | # 15 | # I18n.locale = :es 16 | # 17 | # This would use the information in config/locales/es.yml. 18 | # 19 | # To learn more about the API, please read the Rails Internationalization guide 20 | # at https://guides.rubyonrails.org/i18n.html. 21 | # 22 | # Be aware that YAML interprets the following case-insensitive strings as 23 | # booleans: `true`, `false`, `on`, `off`, `yes`, `no`. Therefore, these strings 24 | # must be quoted to be interpreted as strings. For example: 25 | # 26 | # en: 27 | # "yes": yup 28 | # enabled: "ON" 29 | 30 | en: 31 | hello: "Hello world" 32 | -------------------------------------------------------------------------------- /examples/rspec/config/queue.yml: -------------------------------------------------------------------------------- 1 | default: &default 2 | dispatchers: 3 | - polling_interval: 1 4 | batch_size: 500 5 | workers: 6 | - queues: "*" 7 | threads: 3 8 | processes: <%= ENV.fetch("JOB_CONCURRENCY", 1) %> 9 | polling_interval: 0.1 10 | 11 | development: 12 | <<: *default 13 | 14 | test: 15 | <<: *default 16 | 17 | production: 18 | <<: *default 19 | -------------------------------------------------------------------------------- /examples/rspec/config/recurring.yml: -------------------------------------------------------------------------------- 1 | # production: 2 | # periodic_cleanup: 3 | # class: CleanSoftDeletedRecordsJob 4 | # queue: background 5 | # args: [ 1000, { batch_size: 500 } ] 6 | # schedule: every hour 7 | # periodic_command: 8 | # command: "SoftDeletedRecord.due.delete_all" 9 | # priority: 2 10 | # schedule: at 5am every day 11 | -------------------------------------------------------------------------------- /examples/rspec/config/routes.rb: -------------------------------------------------------------------------------- 1 | Rails.application.routes.draw do 2 | root "home#index" 3 | # Define your application routes per the DSL in https://guides.rubyonrails.org/routing.html 4 | 5 | # Reveal health status on /up that returns 200 if the app boots with no exceptions, otherwise 500. 6 | # Can be used by load balancers and uptime monitors to verify that the app is live. 7 | get "up" => "rails/health#show", as: :rails_health_check 8 | 9 | # Render dynamic PWA files from app/views/pwa/* (remember to link manifest in application.html.erb) 10 | # get "manifest" => "rails/pwa#manifest", as: :pwa_manifest 11 | # get "service-worker" => "rails/pwa#service_worker", as: :pwa_service_worker 12 | 13 | # Defines the root path route ("/") 14 | # root "posts#index" 15 | end 16 | -------------------------------------------------------------------------------- /examples/rspec/db/cable_schema.rb: -------------------------------------------------------------------------------- 1 | ActiveRecord::Schema[7.1].define(version: 1) do 2 | create_table "solid_cable_messages", force: :cascade do |t| 3 | t.binary "channel", limit: 1024, null: false 4 | t.binary "payload", limit: 536870912, null: false 5 | t.datetime "created_at", null: false 6 | t.integer "channel_hash", limit: 8, null: false 7 | t.index ["channel"], name: "index_solid_cable_messages_on_channel" 8 | t.index ["channel_hash"], name: "index_solid_cable_messages_on_channel_hash" 9 | t.index ["created_at"], name: "index_solid_cable_messages_on_created_at" 10 | end 11 | end 12 | -------------------------------------------------------------------------------- /examples/rspec/db/cache_schema.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | ActiveRecord::Schema[7.2].define(version: 1) do 4 | create_table "solid_cache_entries", force: :cascade do |t| 5 | t.binary "key", limit: 1024, null: false 6 | t.binary "value", limit: 536870912, null: false 7 | t.datetime "created_at", null: false 8 | t.integer "key_hash", limit: 8, null: false 9 | t.integer "byte_size", limit: 4, null: false 10 | t.index ["byte_size"], name: "index_solid_cache_entries_on_byte_size" 11 | t.index ["key_hash", "byte_size"], name: "index_solid_cache_entries_on_key_hash_and_byte_size" 12 | t.index ["key_hash"], name: "index_solid_cache_entries_on_key_hash", unique: true 13 | end 14 | end 15 | -------------------------------------------------------------------------------- /examples/rspec/db/schema.rb: -------------------------------------------------------------------------------- 1 | # This file is auto-generated from the current state of the database. Instead 2 | # of editing this file, please use the migrations feature of Active Record to 3 | # incrementally modify your database, and then regenerate this schema definition. 4 | # 5 | # This file is the source Rails uses to define your schema when running `bin/rails 6 | # db:schema:load`. When creating a new database, `bin/rails db:schema:load` tends to 7 | # be faster and is potentially less error prone than running all of your 8 | # migrations from scratch. Old migrations may fail to apply correctly if those 9 | # migrations use external dependencies or application code. 10 | # 11 | # It's strongly recommended that you check this file into your version control system. 12 | 13 | ActiveRecord::Schema[8.0].define(version: 0) do 14 | end 15 | -------------------------------------------------------------------------------- /examples/rspec/db/seeds.rb: -------------------------------------------------------------------------------- 1 | # This file should ensure the existence of records required to run the application in every environment (production, 2 | # development, test). The code here should be idempotent so that it can be executed at any point in every environment. 3 | # The data can then be loaded with the bin/rails db:seed command (or created alongside the database with db:setup). 4 | # 5 | # Example: 6 | # 7 | # ["Action", "Comedy", "Drama", "Horror"].each do |genre_name| 8 | # MovieGenre.find_or_create_by!(name: genre_name) 9 | # end 10 | -------------------------------------------------------------------------------- /examples/rspec/lib/tasks/.keep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mattbrictson/nextgen/c3a0ac5fb693be54309d2d9bb363fb27550e5056/examples/rspec/lib/tasks/.keep -------------------------------------------------------------------------------- /examples/rspec/lib/templates/rspec/system/system_spec.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | require "rails_helper" 4 | 5 | RSpec.describe "<%= class_name %>" do 6 | pending "add some scenarios (or delete) #{__FILE__}" 7 | 8 | # it "renders a message on the home page" do 9 | # visit "/" 10 | # expect(page).to have_content("Hello, world!") 11 | # end 12 | end 13 | -------------------------------------------------------------------------------- /examples/rspec/log/.keep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mattbrictson/nextgen/c3a0ac5fb693be54309d2d9bb363fb27550e5056/examples/rspec/log/.keep -------------------------------------------------------------------------------- /examples/rspec/public/icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mattbrictson/nextgen/c3a0ac5fb693be54309d2d9bb363fb27550e5056/examples/rspec/public/icon.png -------------------------------------------------------------------------------- /examples/rspec/public/icon.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /examples/rspec/public/robots.txt: -------------------------------------------------------------------------------- 1 | # See https://www.robotstxt.org/robotstxt.html for documentation on how to use the robots.txt file 2 | -------------------------------------------------------------------------------- /examples/rspec/script/.keep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mattbrictson/nextgen/c3a0ac5fb693be54309d2d9bb363fb27550e5056/examples/rspec/script/.keep -------------------------------------------------------------------------------- /examples/rspec/spec/mailers/.keep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mattbrictson/nextgen/c3a0ac5fb693be54309d2d9bb363fb27550e5056/examples/rspec/spec/mailers/.keep -------------------------------------------------------------------------------- /examples/rspec/spec/support/capybara.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | ActiveSupport.on_load(:action_dispatch_system_test_case) do 4 | require "capybara" 5 | require "capybara/rails" 6 | require "capybara/rspec" 7 | 8 | Capybara.configure do |config| 9 | config.default_max_wait_time = 2 10 | config.save_path = "tmp/screenshots" 11 | config.enable_aria_label = true 12 | config.server = :puma, {Silent: true} 13 | config.test_id = "data-testid" 14 | end 15 | end 16 | -------------------------------------------------------------------------------- /examples/rspec/spec/support/mailer.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | RSpec.configure do |config| 4 | config.before(:each) do 5 | ActionMailer::Base.deliveries.clear 6 | end 7 | end 8 | -------------------------------------------------------------------------------- /examples/rspec/spec/support/system.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | RSpec.configure do |config| 4 | config.before(:each, type: :system) do 5 | driven_by :selenium, 6 | using: (ENV["SHOW_BROWSER"] ? :chrome : :headless_chrome), 7 | screen_size: [1400, 1400] do |options| 8 | # Allows running in Docker 9 | options.add_argument("--disable-dev-shm-usage") 10 | options.add_argument("--no-sandbox") 11 | 12 | # Fixes slowdowns on macOS 13 | options.add_argument("--disable-gpu") 14 | end 15 | end 16 | end 17 | -------------------------------------------------------------------------------- /examples/rspec/storage/.keep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mattbrictson/nextgen/c3a0ac5fb693be54309d2d9bb363fb27550e5056/examples/rspec/storage/.keep -------------------------------------------------------------------------------- /examples/rspec/tmp/.keep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mattbrictson/nextgen/c3a0ac5fb693be54309d2d9bb363fb27550e5056/examples/rspec/tmp/.keep -------------------------------------------------------------------------------- /examples/rspec/tmp/pids/.keep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mattbrictson/nextgen/c3a0ac5fb693be54309d2d9bb363fb27550e5056/examples/rspec/tmp/pids/.keep -------------------------------------------------------------------------------- /examples/rspec/tmp/storage/.keep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mattbrictson/nextgen/c3a0ac5fb693be54309d2d9bb363fb27550e5056/examples/rspec/tmp/storage/.keep -------------------------------------------------------------------------------- /examples/rspec/vendor/.keep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mattbrictson/nextgen/c3a0ac5fb693be54309d2d9bb363fb27550e5056/examples/rspec/vendor/.keep -------------------------------------------------------------------------------- /examples/rspec/vendor/javascript/.keep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mattbrictson/nextgen/c3a0ac5fb693be54309d2d9bb363fb27550e5056/examples/rspec/vendor/javascript/.keep -------------------------------------------------------------------------------- /examples/vite/.editorconfig: -------------------------------------------------------------------------------- 1 | # https://editorconfig.org 2 | 3 | root = true 4 | 5 | [*] 6 | charset = utf-8 7 | indent_style = space 8 | indent_size = 2 9 | end_of_line = lf 10 | insert_final_newline = true 11 | trim_trailing_whitespace = true 12 | 13 | [Makefile] 14 | indent_style = tab 15 | -------------------------------------------------------------------------------- /examples/vite/.gitattributes: -------------------------------------------------------------------------------- 1 | # See https://git-scm.com/docs/gitattributes for more about git attribute files. 2 | 3 | # Mark the database schema as having been generated. 4 | db/schema.rb linguist-generated 5 | 6 | # Mark any vendored files as having been vendored. 7 | vendor/* linguist-vendored 8 | config/credentials/*.yml.enc diff=rails_credentials 9 | config/credentials.yml.enc diff=rails_credentials 10 | -------------------------------------------------------------------------------- /examples/vite/.github/dependabot.yml: -------------------------------------------------------------------------------- 1 | version: 2 2 | updates: 3 | - package-ecosystem: bundler 4 | directory: "/" 5 | schedule: 6 | interval: daily 7 | open-pull-requests-limit: 10 8 | - package-ecosystem: github-actions 9 | directory: "/" 10 | schedule: 11 | interval: daily 12 | open-pull-requests-limit: 10 13 | -------------------------------------------------------------------------------- /examples/vite/.kamal/hooks/docker-setup.sample: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | echo "Docker set up on $KAMAL_HOSTS..." 4 | -------------------------------------------------------------------------------- /examples/vite/.kamal/hooks/post-deploy.sample: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | # A sample post-deploy hook 4 | # 5 | # These environment variables are available: 6 | # KAMAL_RECORDED_AT 7 | # KAMAL_PERFORMER 8 | # KAMAL_VERSION 9 | # KAMAL_HOSTS 10 | # KAMAL_ROLE (if set) 11 | # KAMAL_DESTINATION (if set) 12 | # KAMAL_RUNTIME 13 | 14 | echo "$KAMAL_PERFORMER deployed $KAMAL_VERSION to $KAMAL_DESTINATION in $KAMAL_RUNTIME seconds" 15 | -------------------------------------------------------------------------------- /examples/vite/.kamal/hooks/post-proxy-reboot.sample: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | echo "Rebooted kamal-proxy on $KAMAL_HOSTS" 4 | -------------------------------------------------------------------------------- /examples/vite/.kamal/hooks/pre-proxy-reboot.sample: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | echo "Rebooting kamal-proxy on $KAMAL_HOSTS..." 4 | -------------------------------------------------------------------------------- /examples/vite/.node-version: -------------------------------------------------------------------------------- 1 | 22.13.0 2 | -------------------------------------------------------------------------------- /examples/vite/.prettierrc.cjs: -------------------------------------------------------------------------------- 1 | /** @type {import("prettier").Config} */ 2 | 3 | module.exports = { 4 | tabWidth: 2, 5 | useTabs: false, 6 | }; 7 | -------------------------------------------------------------------------------- /examples/vite/.rubocop.yml: -------------------------------------------------------------------------------- 1 | # Omakase Ruby styling for Rails 2 | inherit_gem: { rubocop-rails-omakase: rubocop.yml } 3 | 4 | # Overwrite or add rules to create your own house style 5 | # 6 | # # Use `[a, [b, c]]` not `[ a, [ b, c ] ]` 7 | # Layout/SpaceInsideArrayLiteralBrackets: 8 | # Enabled: false 9 | -------------------------------------------------------------------------------- /examples/vite/.ruby-version: -------------------------------------------------------------------------------- 1 | 3.4.1 2 | -------------------------------------------------------------------------------- /examples/vite/DEPLOYMENT.md: -------------------------------------------------------------------------------- 1 | # Deployment 2 | 3 | ## Environment variables 4 | 5 | These environment variables affect how the app functions when deployed in production. 6 | 7 | - `RAILS_DISABLE_SSL` - Disable HSTS and secure cookies 8 | - `RAILS_ENV` **REQUIRED** - "production" 9 | - `RAILS_MAX_THREADS` - Number of threads per Puma process (default: 3) 10 | - `SECRET_KEY_BASE` **REQUIRED** - Unique, secret key used to encrypt and sign cookies and other sensitive data 11 | - `WEB_CONCURRENCY` - Number of Puma processes (default: 1) 12 | -------------------------------------------------------------------------------- /examples/vite/Gemfile: -------------------------------------------------------------------------------- 1 | source "https://rubygems.org" 2 | 3 | ruby file: ".ruby-version" 4 | 5 | gem "vite_rails", "~> 3.0" 6 | gem "rails", "~> 8.0.1" 7 | gem "sqlite3", ">= 2.1" 8 | gem "puma", ">= 5.0" 9 | gem "turbo-rails" 10 | gem "stimulus-rails" 11 | gem "jbuilder" 12 | gem "tzinfo-data", platforms: %i[ windows jruby ] 13 | gem "solid_cache" 14 | gem "solid_queue" 15 | gem "solid_cable" 16 | gem "bootsnap", require: false 17 | gem "kamal", require: false 18 | gem "thruster", require: false 19 | 20 | group :development, :test do 21 | gem "debug", platforms: %i[ mri windows ], require: "debug/prelude" 22 | gem "brakeman", require: false 23 | gem "rubocop-rails-omakase", require: false 24 | end 25 | 26 | group :development do 27 | gem "web-console" 28 | end 29 | 30 | group :test do 31 | gem "capybara", require: false 32 | gem "selenium-webdriver", require: false 33 | end 34 | -------------------------------------------------------------------------------- /examples/vite/Procfile: -------------------------------------------------------------------------------- 1 | web: bundle exec puma -C config/puma.rb 2 | release: bundle exec rake db:migrate 3 | -------------------------------------------------------------------------------- /examples/vite/Rakefile: -------------------------------------------------------------------------------- 1 | # Add your own tasks in files placed in lib/tasks ending in .rake, 2 | # for example lib/tasks/capistrano.rake, and they will automatically be available to Rake. 3 | 4 | require_relative "config/application" 5 | 6 | Rails.application.load_tasks 7 | 8 | Rake::Task[:default].prerequisites.clear if Rake::Task.task_defined?(:default) 9 | 10 | desc "Run all checks" 11 | task default: %w[test:all] do 12 | puts ">>>>>> [OK] All checks passed!" 13 | end 14 | -------------------------------------------------------------------------------- /examples/vite/app/controllers/application_controller.rb: -------------------------------------------------------------------------------- 1 | class ApplicationController < ActionController::Base 2 | # Only allow modern browsers supporting webp images, web push, badges, import maps, CSS nesting, and CSS :has. 3 | allow_browser versions: :modern 4 | end 5 | -------------------------------------------------------------------------------- /examples/vite/app/controllers/concerns/.keep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mattbrictson/nextgen/c3a0ac5fb693be54309d2d9bb363fb27550e5056/examples/vite/app/controllers/concerns/.keep -------------------------------------------------------------------------------- /examples/vite/app/controllers/home_controller.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | class HomeController < ApplicationController 4 | def index 5 | end 6 | end 7 | -------------------------------------------------------------------------------- /examples/vite/app/frontend/controllers/application.js: -------------------------------------------------------------------------------- 1 | import { Application } from "@hotwired/stimulus" 2 | 3 | const application = Application.start() 4 | 5 | // Configure Stimulus development experience 6 | application.debug = false 7 | window.Stimulus = application 8 | 9 | export { application } 10 | -------------------------------------------------------------------------------- /examples/vite/app/frontend/controllers/hello_controller.js: -------------------------------------------------------------------------------- 1 | import { Controller } from "@hotwired/stimulus" 2 | 3 | export default class extends Controller { 4 | connect() { 5 | this.element.textContent = "Hello World!" 6 | } 7 | } 8 | -------------------------------------------------------------------------------- /examples/vite/app/frontend/controllers/index.js: -------------------------------------------------------------------------------- 1 | import { application } from "./application"; 2 | import { registerControllers } from "stimulus-vite-helpers"; 3 | 4 | const controllers = import.meta.glob("./**/*_controller.js", { eager: true }); 5 | registerControllers(application, controllers); 6 | -------------------------------------------------------------------------------- /examples/vite/app/frontend/images/.keep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mattbrictson/nextgen/c3a0ac5fb693be54309d2d9bb363fb27550e5056/examples/vite/app/frontend/images/.keep -------------------------------------------------------------------------------- /examples/vite/app/frontend/images/example.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /examples/vite/app/frontend/stylesheets/base.css: -------------------------------------------------------------------------------- 1 | /* 2 | This file is for base element styles, like: 3 | 4 | - Any @font-face declarations needed custom web fonts. 5 | - Default font-family on the body element. 6 | - Default foreground, background, and link colors. 7 | - Global CSS variables (declared on :root), such as color palette. 8 | */ 9 | -------------------------------------------------------------------------------- /examples/vite/app/frontend/stylesheets/index.css: -------------------------------------------------------------------------------- 1 | @import "modern-normalize"; 2 | @import "reset"; 3 | @import "base"; 4 | -------------------------------------------------------------------------------- /examples/vite/app/frontend/stylesheets/reset.css: -------------------------------------------------------------------------------- 1 | :root { 2 | line-height: 1.5; 3 | -webkit-font-smoothing: antialiased; 4 | } 5 | 6 | h1, 7 | h2, 8 | h3, 9 | h4, 10 | h5, 11 | figure, 12 | p, 13 | ol, 14 | ul { 15 | margin: 0; 16 | } 17 | 18 | ol, 19 | ul { 20 | list-style: none; 21 | padding-inline: 0; 22 | } 23 | 24 | h1, 25 | h2, 26 | h3, 27 | h4, 28 | h5 { 29 | font-size: inherit; 30 | font-weight: inherit; 31 | } 32 | 33 | img { 34 | display: block; 35 | max-inline-size: 100%; 36 | } 37 | -------------------------------------------------------------------------------- /examples/vite/app/helpers/application_helper.rb: -------------------------------------------------------------------------------- 1 | module ApplicationHelper 2 | end 3 | -------------------------------------------------------------------------------- /examples/vite/app/helpers/inline_svg_helper.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | module InlineSvgHelper 4 | def inline_svg_tag(filename, title: nil) 5 | svg = ViteInlineSvgFileLoader.named(filename) 6 | svg = svg.sub(/\A/, safe_join(['\0', "\n", tag.title(title)])) if title.present? 8 | 9 | svg.strip.html_safe # rubocop:disable Rails/OutputSafety 10 | end 11 | end 12 | -------------------------------------------------------------------------------- /examples/vite/app/jobs/application_job.rb: -------------------------------------------------------------------------------- 1 | class ApplicationJob < ActiveJob::Base 2 | # Automatically retry jobs that encountered a deadlock 3 | # retry_on ActiveRecord::Deadlocked 4 | 5 | # Most jobs are safe to ignore if the underlying records are no longer available 6 | # discard_on ActiveJob::DeserializationError 7 | end 8 | -------------------------------------------------------------------------------- /examples/vite/app/mailers/application_mailer.rb: -------------------------------------------------------------------------------- 1 | class ApplicationMailer < ActionMailer::Base 2 | default from: "from@example.com" 3 | layout "mailer" 4 | end 5 | -------------------------------------------------------------------------------- /examples/vite/app/models/application_record.rb: -------------------------------------------------------------------------------- 1 | class ApplicationRecord < ActiveRecord::Base 2 | primary_abstract_class 3 | end 4 | -------------------------------------------------------------------------------- /examples/vite/app/models/concerns/.keep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mattbrictson/nextgen/c3a0ac5fb693be54309d2d9bb363fb27550e5056/examples/vite/app/models/concerns/.keep -------------------------------------------------------------------------------- /examples/vite/app/views/home/index.html.erb: -------------------------------------------------------------------------------- 1 | <% provide(:title, "Home") %> 2 |

Find me in app/views/home/index.html.erb

3 |

Stimulus says,

4 | -------------------------------------------------------------------------------- /examples/vite/app/views/layouts/mailer.html.erb: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 8 | 9 | 10 | 11 | <%= yield %> 12 | 13 | 14 | -------------------------------------------------------------------------------- /examples/vite/app/views/layouts/mailer.text.erb: -------------------------------------------------------------------------------- 1 | <%= yield %> 2 | -------------------------------------------------------------------------------- /examples/vite/app/views/pwa/manifest.json.erb: -------------------------------------------------------------------------------- 1 | { 2 | "name": "ViteExample", 3 | "icons": [ 4 | { 5 | "src": "/icon.png", 6 | "type": "image/png", 7 | "sizes": "512x512" 8 | }, 9 | { 10 | "src": "/icon.png", 11 | "type": "image/png", 12 | "sizes": "512x512", 13 | "purpose": "maskable" 14 | } 15 | ], 16 | "start_url": "/", 17 | "display": "standalone", 18 | "scope": "/", 19 | "description": "ViteExample.", 20 | "theme_color": "red", 21 | "background_color": "red" 22 | } 23 | -------------------------------------------------------------------------------- /examples/vite/app/views/pwa/service-worker.js: -------------------------------------------------------------------------------- 1 | // Add a service worker for processing Web Push notifications: 2 | // 3 | // self.addEventListener("push", async (event) => { 4 | // const { title, options } = await event.data.json() 5 | // event.waitUntil(self.registration.showNotification(title, options)) 6 | // }) 7 | // 8 | // self.addEventListener("notificationclick", function(event) { 9 | // event.notification.close() 10 | // event.waitUntil( 11 | // clients.matchAll({ type: "window" }).then((clientList) => { 12 | // for (let i = 0; i < clientList.length; i++) { 13 | // let client = clientList[i] 14 | // let clientPath = (new URL(client.url)).pathname 15 | // 16 | // if (clientPath == event.notification.data.path && "focus" in client) { 17 | // return client.focus() 18 | // } 19 | // } 20 | // 21 | // if (clients.openWindow) { 22 | // return clients.openWindow(event.notification.data.path) 23 | // } 24 | // }) 25 | // ) 26 | // }) 27 | -------------------------------------------------------------------------------- /examples/vite/bin/brakeman: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env ruby 2 | require "rubygems" 3 | require "bundler/setup" 4 | 5 | ARGV.unshift("--ensure-latest") 6 | 7 | load Gem.bin_path("brakeman", "brakeman") 8 | -------------------------------------------------------------------------------- /examples/vite/bin/dev: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env ruby 2 | # frozen_string_literal: true 3 | 4 | exec "npx", "run-pty", "run-pty.json", *ARGV 5 | -------------------------------------------------------------------------------- /examples/vite/bin/docker-entrypoint: -------------------------------------------------------------------------------- 1 | #!/bin/bash -e 2 | 3 | # Enable jemalloc for reduced memory usage and latency. 4 | if [ -z "${LD_PRELOAD+x}" ]; then 5 | LD_PRELOAD=$(find /usr/lib -name libjemalloc.so.2 -print -quit) 6 | export LD_PRELOAD 7 | fi 8 | 9 | # If running the rails server then create or migrate existing database 10 | if [ "${@: -2:1}" == "./bin/rails" ] && [ "${@: -1:1}" == "server" ]; then 11 | ./bin/rails db:prepare 12 | fi 13 | 14 | exec "${@}" 15 | -------------------------------------------------------------------------------- /examples/vite/bin/jobs: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env ruby 2 | 3 | require_relative "../config/environment" 4 | require "solid_queue/cli" 5 | 6 | SolidQueue::Cli.start(ARGV) 7 | -------------------------------------------------------------------------------- /examples/vite/bin/kamal: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env ruby 2 | # frozen_string_literal: true 3 | 4 | # 5 | # This file was generated by Bundler. 6 | # 7 | # The application 'kamal' 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("kamal", "kamal") 28 | -------------------------------------------------------------------------------- /examples/vite/bin/rails: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env ruby 2 | APP_PATH = File.expand_path("../config/application", __dir__) 3 | require_relative "../config/boot" 4 | require "rails/commands" 5 | -------------------------------------------------------------------------------- /examples/vite/bin/rake: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env ruby 2 | require_relative "../config/boot" 3 | require "rake" 4 | Rake.application.run 5 | -------------------------------------------------------------------------------- /examples/vite/bin/rubocop: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env ruby 2 | require "rubygems" 3 | require "bundler/setup" 4 | 5 | # explicit rubocop config increases performance slightly while avoiding config confusion. 6 | ARGV.unshift("--config", File.expand_path("../.rubocop.yml", __dir__)) 7 | 8 | load Gem.bin_path("rubocop", "rubocop") 9 | -------------------------------------------------------------------------------- /examples/vite/bin/thrust: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env ruby 2 | require "rubygems" 3 | require "bundler/setup" 4 | 5 | load Gem.bin_path("thruster", "thrust") 6 | -------------------------------------------------------------------------------- /examples/vite/bin/vite: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env ruby 2 | # frozen_string_literal: true 3 | 4 | # 5 | # This file was generated by Bundler. 6 | # 7 | # The application 'vite' 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("vite_ruby", "vite") 28 | -------------------------------------------------------------------------------- /examples/vite/config.ru: -------------------------------------------------------------------------------- 1 | # This file is used by Rack-based servers to start the application. 2 | 3 | require_relative "config/environment" 4 | 5 | run Rails.application 6 | Rails.application.load_server 7 | -------------------------------------------------------------------------------- /examples/vite/config/boot.rb: -------------------------------------------------------------------------------- 1 | ENV["BUNDLE_GEMFILE"] ||= File.expand_path("../Gemfile", __dir__) 2 | 3 | require "bundler/setup" # Set up gems listed in the Gemfile. 4 | require "bootsnap/setup" # Speed up boot time by caching expensive operations. 5 | -------------------------------------------------------------------------------- /examples/vite/config/cable.yml: -------------------------------------------------------------------------------- 1 | # Async adapter only works within the same process, so for manually triggering cable updates from a console, 2 | # and seeing results in the browser, you must do so from the web console (running inside the dev process), 3 | # not a terminal started via bin/rails console! Add "console" to any action or any ERB template view 4 | # to make the web console appear. 5 | development: 6 | adapter: async 7 | 8 | test: 9 | adapter: test 10 | 11 | production: 12 | adapter: solid_cable 13 | connects_to: 14 | database: 15 | writing: cable 16 | polling_interval: 0.1.seconds 17 | message_retention: 1.day 18 | -------------------------------------------------------------------------------- /examples/vite/config/cache.yml: -------------------------------------------------------------------------------- 1 | default: &default 2 | store_options: 3 | # Cap age of oldest cache entry to fulfill retention policies 4 | # max_age: <%= 60.days.to_i %> 5 | max_size: <%= 256.megabytes %> 6 | namespace: <%= Rails.env %> 7 | 8 | development: 9 | <<: *default 10 | 11 | test: 12 | <<: *default 13 | 14 | production: 15 | database: cache 16 | <<: *default 17 | -------------------------------------------------------------------------------- /examples/vite/config/credentials.yml.enc: -------------------------------------------------------------------------------- 1 | CxQVwXExUcT2FoyHkT4ncMI8AkbiAYoNnd8RBeG+frC8f+UP5OdkrFRFUcaC4puxpvkYdcYSvwFf47zqRbe6jqCtxjSEVBWs7GKHiK4O/nLj0WgaizX+OT2gCvvdN3CxaKbSyiAcSNj5jd7bMUG+3mEnZ0IutA3gcHVt89yKrJe4FFR40Y2lNhrJOkJlsIkeOAD+DMQpOC9tx01ojiMf5KvqNtZjI9cEAYTHrs3YKcQGgKuGw4c8QsUvqSgvvyr5u8wtROYpL2wyYzwqF1PEpI5N6DMLACN1VvUmllY8jgW/F08nKvgl3qdMewjeSHBDkGecysGyHE9ZJBohl6Z7tTjinAG8QJ0he4Mauhf99zNNrBMVFANwDtC18DElOD8U2ceIM35hTmrlzE+Of79+SxNVaQf26FPqiaDvvmDRTr909WqmJL54sEugKBwwXq1KX0nW13hcvd3FdnJYGGz2mtgzwj3if5kqcxtSa2PsLEQ/s/3CGoJCq87b--ORUolQXfGBVF/Di0--3/mN4wADl2PQmCcBlKgX8A== -------------------------------------------------------------------------------- /examples/vite/config/environment.rb: -------------------------------------------------------------------------------- 1 | # Load the Rails application. 2 | require_relative "application" 3 | 4 | # Initialize the Rails application. 5 | Rails.application.initialize! 6 | -------------------------------------------------------------------------------- /examples/vite/config/initializers/filter_parameter_logging.rb: -------------------------------------------------------------------------------- 1 | # Be sure to restart your server when you modify this file. 2 | 3 | # Configure parameters to be partially matched (e.g. passw matches password) and filtered from the log file. 4 | # Use this to limit dissemination of sensitive information. 5 | # See the ActiveSupport::ParameterFilter documentation for supported notations and behaviors. 6 | Rails.application.config.filter_parameters += [ 7 | :passw, :email, :secret, :token, :_key, :crypt, :salt, :certificate, :otp, :ssn, :cvv, :cvc 8 | ] 9 | -------------------------------------------------------------------------------- /examples/vite/config/initializers/generators.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | Rails.application.config.generators do |g| 4 | # Disable generators we don't need. 5 | g.javascripts false 6 | g.stylesheets false 7 | end 8 | -------------------------------------------------------------------------------- /examples/vite/config/initializers/inflections.rb: -------------------------------------------------------------------------------- 1 | # Be sure to restart your server when you modify this file. 2 | 3 | # Add new inflection rules using the following format. Inflections 4 | # are locale specific, and you may define rules for as many different 5 | # locales as you wish. All of these examples are active by default: 6 | # ActiveSupport::Inflector.inflections(:en) do |inflect| 7 | # inflect.plural /^(ox)$/i, "\\1en" 8 | # inflect.singular /^(ox)en/i, "\\1" 9 | # inflect.irregular "person", "people" 10 | # inflect.uncountable %w( fish sheep ) 11 | # end 12 | 13 | # These inflection rules are supported but not enabled by default: 14 | # ActiveSupport::Inflector.inflections(:en) do |inflect| 15 | # inflect.acronym "RESTful" 16 | # end 17 | -------------------------------------------------------------------------------- /examples/vite/config/queue.yml: -------------------------------------------------------------------------------- 1 | default: &default 2 | dispatchers: 3 | - polling_interval: 1 4 | batch_size: 500 5 | workers: 6 | - queues: "*" 7 | threads: 3 8 | processes: <%= ENV.fetch("JOB_CONCURRENCY", 1) %> 9 | polling_interval: 0.1 10 | 11 | development: 12 | <<: *default 13 | 14 | test: 15 | <<: *default 16 | 17 | production: 18 | <<: *default 19 | -------------------------------------------------------------------------------- /examples/vite/config/recurring.yml: -------------------------------------------------------------------------------- 1 | # production: 2 | # periodic_cleanup: 3 | # class: CleanSoftDeletedRecordsJob 4 | # queue: background 5 | # args: [ 1000, { batch_size: 500 } ] 6 | # schedule: every hour 7 | # periodic_command: 8 | # command: "SoftDeletedRecord.due.delete_all" 9 | # priority: 2 10 | # schedule: at 5am every day 11 | -------------------------------------------------------------------------------- /examples/vite/config/routes.rb: -------------------------------------------------------------------------------- 1 | Rails.application.routes.draw do 2 | root "home#index" 3 | # Define your application routes per the DSL in https://guides.rubyonrails.org/routing.html 4 | 5 | # Reveal health status on /up that returns 200 if the app boots with no exceptions, otherwise 500. 6 | # Can be used by load balancers and uptime monitors to verify that the app is live. 7 | get "up" => "rails/health#show", as: :rails_health_check 8 | 9 | # Render dynamic PWA files from app/views/pwa/* (remember to link manifest in application.html.erb) 10 | # get "manifest" => "rails/pwa#manifest", as: :pwa_manifest 11 | # get "service-worker" => "rails/pwa#service_worker", as: :pwa_service_worker 12 | 13 | # Defines the root path route ("/") 14 | # root "posts#index" 15 | end 16 | -------------------------------------------------------------------------------- /examples/vite/config/vite.json: -------------------------------------------------------------------------------- 1 | { 2 | "all": { 3 | "sourceCodeDir": "app/frontend", 4 | "watchAdditionalPaths": [] 5 | }, 6 | "development": { 7 | "autoBuild": true, 8 | "publicOutputDir": "vite-dev", 9 | "port": 3036 10 | }, 11 | "test": { 12 | "autoBuild": false, 13 | "publicOutputDir": "vite-test", 14 | "port": 3037 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /examples/vite/db/cable_schema.rb: -------------------------------------------------------------------------------- 1 | ActiveRecord::Schema[7.1].define(version: 1) do 2 | create_table "solid_cable_messages", force: :cascade do |t| 3 | t.binary "channel", limit: 1024, null: false 4 | t.binary "payload", limit: 536870912, null: false 5 | t.datetime "created_at", null: false 6 | t.integer "channel_hash", limit: 8, null: false 7 | t.index ["channel"], name: "index_solid_cable_messages_on_channel" 8 | t.index ["channel_hash"], name: "index_solid_cable_messages_on_channel_hash" 9 | t.index ["created_at"], name: "index_solid_cable_messages_on_created_at" 10 | end 11 | end 12 | -------------------------------------------------------------------------------- /examples/vite/db/cache_schema.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | ActiveRecord::Schema[7.2].define(version: 1) do 4 | create_table "solid_cache_entries", force: :cascade do |t| 5 | t.binary "key", limit: 1024, null: false 6 | t.binary "value", limit: 536870912, null: false 7 | t.datetime "created_at", null: false 8 | t.integer "key_hash", limit: 8, null: false 9 | t.integer "byte_size", limit: 4, null: false 10 | t.index ["byte_size"], name: "index_solid_cache_entries_on_byte_size" 11 | t.index ["key_hash", "byte_size"], name: "index_solid_cache_entries_on_key_hash_and_byte_size" 12 | t.index ["key_hash"], name: "index_solid_cache_entries_on_key_hash", unique: true 13 | end 14 | end 15 | -------------------------------------------------------------------------------- /examples/vite/db/schema.rb: -------------------------------------------------------------------------------- 1 | # This file is auto-generated from the current state of the database. Instead 2 | # of editing this file, please use the migrations feature of Active Record to 3 | # incrementally modify your database, and then regenerate this schema definition. 4 | # 5 | # This file is the source Rails uses to define your schema when running `bin/rails 6 | # db:schema:load`. When creating a new database, `bin/rails db:schema:load` tends to 7 | # be faster and is potentially less error prone than running all of your 8 | # migrations from scratch. Old migrations may fail to apply correctly if those 9 | # migrations use external dependencies or application code. 10 | # 11 | # It's strongly recommended that you check this file into your version control system. 12 | 13 | ActiveRecord::Schema[8.0].define(version: 0) do 14 | end 15 | -------------------------------------------------------------------------------- /examples/vite/db/seeds.rb: -------------------------------------------------------------------------------- 1 | # This file should ensure the existence of records required to run the application in every environment (production, 2 | # development, test). The code here should be idempotent so that it can be executed at any point in every environment. 3 | # The data can then be loaded with the bin/rails db:seed command (or created alongside the database with db:setup). 4 | # 5 | # Example: 6 | # 7 | # ["Action", "Comedy", "Drama", "Horror"].each do |genre_name| 8 | # MovieGenre.find_or_create_by!(name: genre_name) 9 | # end 10 | -------------------------------------------------------------------------------- /examples/vite/lib/tasks/.keep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mattbrictson/nextgen/c3a0ac5fb693be54309d2d9bb363fb27550e5056/examples/vite/lib/tasks/.keep -------------------------------------------------------------------------------- /examples/vite/lib/vite_inline_svg_file_loader.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | module ViteInlineSvgFileLoader 4 | class << self 5 | def named(filename) 6 | vite = ViteRuby.instance 7 | vite_asset_path = vite.manifest.path_for(filename) 8 | 9 | if vite.dev_server_running? 10 | fetch_from_dev_server(vite_asset_path) 11 | else 12 | Rails.public_path.join(vite_asset_path.sub(%r{^/}, "")).read 13 | end 14 | end 15 | 16 | private 17 | 18 | def fetch_from_dev_server(path) 19 | config = ViteRuby.config 20 | dev_server_uri = URI("#{config.protocol}://#{config.host_with_port}#{path}") 21 | response = Net::HTTP.get_response(dev_server_uri) 22 | raise "Failed to load inline SVG from #{dev_server_uri}" unless response.is_a?(Net::HTTPSuccess) 23 | 24 | response.body 25 | end 26 | end 27 | end 28 | -------------------------------------------------------------------------------- /examples/vite/log/.keep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mattbrictson/nextgen/c3a0ac5fb693be54309d2d9bb363fb27550e5056/examples/vite/log/.keep -------------------------------------------------------------------------------- /examples/vite/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "private": true, 3 | "type": "module", 4 | "engines": { 5 | "node": "^20.9.0 || >= 22.0.0" 6 | }, 7 | "scripts": {}, 8 | "dependencies": { 9 | "@hotwired/stimulus": "^3.2.2", 10 | "@hotwired/turbo-rails": "^8.0.12", 11 | "autoprefixer": "^10.4.14", 12 | "modern-normalize": "^3.0.0", 13 | "postcss": "^8.4.24", 14 | "rollup": "^4.2.0", 15 | "stimulus-vite-helpers": "^3.1.0", 16 | "vite": "^5.0.0", 17 | "vite-plugin-rails": "^0.5.0" 18 | }, 19 | "devDependencies": { 20 | "run-pty": "^5" 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /examples/vite/postcss.config.cjs: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | plugins: [require("autoprefixer")], 3 | }; 4 | -------------------------------------------------------------------------------- /examples/vite/public/icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mattbrictson/nextgen/c3a0ac5fb693be54309d2d9bb363fb27550e5056/examples/vite/public/icon.png -------------------------------------------------------------------------------- /examples/vite/public/icon.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /examples/vite/public/robots.txt: -------------------------------------------------------------------------------- 1 | # See https://www.robotstxt.org/robotstxt.html for documentation on how to use the robots.txt file 2 | -------------------------------------------------------------------------------- /examples/vite/run-pty.json: -------------------------------------------------------------------------------- 1 | [ 2 | { 3 | "command": ["bin/rails", "server"], 4 | "status": { 5 | "Listening on": null 6 | }, 7 | "defaultStatus": ["⏳", "S"] 8 | }, 9 | { 10 | "command": ["bin/vite", "dev"], 11 | "status": { 12 | "ready in": null 13 | }, 14 | "defaultStatus": ["⏳", "S"] 15 | } 16 | ] 17 | -------------------------------------------------------------------------------- /examples/vite/script/.keep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mattbrictson/nextgen/c3a0ac5fb693be54309d2d9bb363fb27550e5056/examples/vite/script/.keep -------------------------------------------------------------------------------- /examples/vite/storage/.keep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mattbrictson/nextgen/c3a0ac5fb693be54309d2d9bb363fb27550e5056/examples/vite/storage/.keep -------------------------------------------------------------------------------- /examples/vite/test/application_system_test_case.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | require "test_helper" 4 | require "vite_helper" 5 | 6 | class ApplicationSystemTestCase < ActionDispatch::SystemTestCase 7 | driven_by :selenium, 8 | using: (ENV["SHOW_BROWSER"] ? :chrome : :headless_chrome), 9 | screen_size: [1400, 1400] do |options| 10 | # Allows running in Docker 11 | options.add_argument("--disable-dev-shm-usage") 12 | options.add_argument("--no-sandbox") 13 | 14 | # Fixes slowdowns on macOS 15 | options.add_argument("--disable-gpu") 16 | end 17 | end 18 | -------------------------------------------------------------------------------- /examples/vite/test/controllers/.keep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mattbrictson/nextgen/c3a0ac5fb693be54309d2d9bb363fb27550e5056/examples/vite/test/controllers/.keep -------------------------------------------------------------------------------- /examples/vite/test/fixtures/files/.keep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mattbrictson/nextgen/c3a0ac5fb693be54309d2d9bb363fb27550e5056/examples/vite/test/fixtures/files/.keep -------------------------------------------------------------------------------- /examples/vite/test/helpers/.keep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mattbrictson/nextgen/c3a0ac5fb693be54309d2d9bb363fb27550e5056/examples/vite/test/helpers/.keep -------------------------------------------------------------------------------- /examples/vite/test/integration/.keep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mattbrictson/nextgen/c3a0ac5fb693be54309d2d9bb363fb27550e5056/examples/vite/test/integration/.keep -------------------------------------------------------------------------------- /examples/vite/test/mailers/.keep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mattbrictson/nextgen/c3a0ac5fb693be54309d2d9bb363fb27550e5056/examples/vite/test/mailers/.keep -------------------------------------------------------------------------------- /examples/vite/test/models/.keep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mattbrictson/nextgen/c3a0ac5fb693be54309d2d9bb363fb27550e5056/examples/vite/test/models/.keep -------------------------------------------------------------------------------- /examples/vite/test/support/capybara.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | ActiveSupport.on_load(:action_dispatch_system_test_case) do 4 | require "capybara" 5 | require "capybara/rails" 6 | 7 | Capybara.configure do |config| 8 | config.default_max_wait_time = 2 9 | config.save_path = "tmp/screenshots" 10 | config.enable_aria_label = true 11 | config.server = :puma, {Silent: true} 12 | config.test_id = "data-testid" 13 | end 14 | end 15 | -------------------------------------------------------------------------------- /examples/vite/test/support/mailer.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | ActiveSupport.on_load(:active_support_test_case) do 4 | setup { ActionMailer::Base.deliveries.clear } 5 | end 6 | -------------------------------------------------------------------------------- /examples/vite/test/system/.keep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mattbrictson/nextgen/c3a0ac5fb693be54309d2d9bb363fb27550e5056/examples/vite/test/system/.keep -------------------------------------------------------------------------------- /examples/vite/test/test_helper.rb: -------------------------------------------------------------------------------- 1 | ENV["RAILS_ENV"] ||= "test" 2 | require_relative "../config/environment" 3 | require "rails/test_help" 4 | 5 | module ActiveSupport 6 | class TestCase 7 | # Run tests in parallel with specified workers 8 | parallelize(workers: :number_of_processors) 9 | 10 | # Setup all fixtures in test/fixtures/*.yml for all tests in alphabetical order. 11 | fixtures :all 12 | 13 | # Add more helper methods to be used by all tests here... 14 | end 15 | end 16 | 17 | Dir[File.expand_path("support/**/*.rb", __dir__)].sort.each { |rb| require(rb) } 18 | -------------------------------------------------------------------------------- /examples/vite/test/vite_helper.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | return if ViteRuby.config.auto_build 4 | 5 | # Compile assets once at the start of testing 6 | require "benchmark" 7 | seconds = Benchmark.realtime { ViteRuby.commands.build } 8 | puts format("Built Vite assets (%.1fms)", seconds * 1_000) 9 | -------------------------------------------------------------------------------- /examples/vite/tmp/.keep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mattbrictson/nextgen/c3a0ac5fb693be54309d2d9bb363fb27550e5056/examples/vite/tmp/.keep -------------------------------------------------------------------------------- /examples/vite/tmp/pids/.keep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mattbrictson/nextgen/c3a0ac5fb693be54309d2d9bb363fb27550e5056/examples/vite/tmp/pids/.keep -------------------------------------------------------------------------------- /examples/vite/tmp/storage/.keep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mattbrictson/nextgen/c3a0ac5fb693be54309d2d9bb363fb27550e5056/examples/vite/tmp/storage/.keep -------------------------------------------------------------------------------- /examples/vite/vendor/.keep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mattbrictson/nextgen/c3a0ac5fb693be54309d2d9bb363fb27550e5056/examples/vite/vendor/.keep -------------------------------------------------------------------------------- /examples/vite/vite.config.ts: -------------------------------------------------------------------------------- 1 | import { defineConfig } from 'vite' 2 | import ViteRails from "vite-plugin-rails" 3 | 4 | export default defineConfig({ 5 | plugins: [ 6 | ViteRails({ 7 | envVars: { RAILS_ENV: "development" }, 8 | envOptions: { defineOn: "import.meta.env" }, 9 | fullReload: { 10 | additionalPaths: [], 11 | }, 12 | }), 13 | ], 14 | }) 15 | -------------------------------------------------------------------------------- /exe/nextgen: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env ruby 2 | # frozen_string_literal: true 3 | 4 | require "nextgen" 5 | 6 | # Work around an "unresolved or ambiguous specs" warning when CLI is run via `gem exec` 7 | # https://github.com/rubygems/rubygems/issues/6914 8 | at_exit do 9 | Gem.finish_resolve 10 | rescue Exception # rubocop:disable Lint/RescueException 11 | # ignore 12 | end 13 | 14 | Nextgen::CLI.start 15 | -------------------------------------------------------------------------------- /lib/nextgen.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | require "pathname" 4 | require "zeitwerk" 5 | 6 | loader = Zeitwerk::Loader.for_gem 7 | loader.ignore("#{__dir__}/nextgen/generators") 8 | loader.inflector.inflect("cli" => "CLI") 9 | loader.setup 10 | 11 | module Nextgen 12 | def self.generators_path 13 | Pathname.new(__dir__).join("nextgen/generators") 14 | end 15 | 16 | def self.template_path 17 | Pathname.new(__dir__).join("../template") 18 | end 19 | end 20 | -------------------------------------------------------------------------------- /lib/nextgen/cli.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | require "thor" 4 | 5 | module Nextgen 6 | class CLI < Thor 7 | extend ThorExtensions 8 | 9 | map %w[-v --version] => "version" 10 | 11 | desc "create APP_PATH", "Generate a Rails app interactively in APP_PATH" 12 | def create(app_path) 13 | Commands::Create.run(app_path, options) 14 | end 15 | 16 | desc "version", "Display nextgen version", hide: true 17 | def version 18 | say "nextgen/#{VERSION} #{RUBY_DESCRIPTION}" 19 | end 20 | end 21 | end 22 | -------------------------------------------------------------------------------- /lib/nextgen/ext/prompt/list.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | require "tty-prompt" 4 | require "tty-screen" 5 | 6 | module Nextgen::Ext 7 | module Prompt::List 8 | def initialize(...) 9 | super 10 | @per_page ||= [TTY::Prompt::Paginator::DEFAULT_PAGE_SIZE, TTY::Screen.height.to_i - 3].max 11 | end 12 | end 13 | end 14 | 15 | TTY::Prompt::List.prepend(Nextgen::Ext::Prompt::List) 16 | -------------------------------------------------------------------------------- /lib/nextgen/ext/prompt/multilist.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | require "tty-prompt" 4 | 5 | module Nextgen::Ext 6 | module Prompt::Multilist 7 | private 8 | 9 | def selected_names 10 | return "" unless @done 11 | return super if @selected.size < 3 12 | 13 | @selected.first.name + " + #{@selected.size - 1} more" 14 | end 15 | end 16 | end 17 | 18 | TTY::Prompt::MultiList.prepend(Nextgen::Ext::Prompt::Multilist) 19 | -------------------------------------------------------------------------------- /lib/nextgen/generators/action_mailer.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | copy_test_support_file "mailer.rb" 4 | if minitest? 5 | empty_directory_with_keep_file "test/mailers" 6 | elsif rspec? 7 | empty_directory_with_keep_file "spec/mailers" 8 | end 9 | -------------------------------------------------------------------------------- /lib/nextgen/generators/annotaterb.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | say_git "Install the annotaterb gem" 4 | install_gem "annotaterb", group: :development 5 | 6 | say_git "Run the annotaterb installer" 7 | generate "annotate_rb:install" 8 | -------------------------------------------------------------------------------- /lib/nextgen/generators/basic_auth.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | document_deploy_var "BASIC_AUTH_PASSWORD" 4 | document_deploy_var "BASIC_AUTH_USERNAME", 5 | "If this and `BASIC_AUTH_PASSWORD` are present, visitors must use these credentials to access the app" 6 | copy_file "app/controllers/concerns/basic_auth.rb" 7 | inject_into_class "app/controllers/application_controller.rb", "ApplicationController", " include BasicAuth\n" 8 | -------------------------------------------------------------------------------- /lib/nextgen/generators/bundler_audit.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | install_gem "bundler-audit", group: :development, require: false 4 | binstub "bundler-audit" 5 | 6 | if File.exist?(".github/workflows/ci.yml") 7 | say_git "Add bundle-audit job to CI workflow" 8 | inject_into_file ".github/workflows/ci.yml", <<-YAML, after: /^jobs:\n/ 9 | scan_gems: 10 | runs-on: ubuntu-latest 11 | 12 | steps: 13 | - name: Checkout code 14 | uses: actions/checkout@v5 15 | 16 | - name: Set up Ruby 17 | uses: ruby/setup-ruby@v1 18 | with: 19 | ruby-version: .ruby-version 20 | bundler-cache: true 21 | 22 | - name: Scan for security vulnerabilities in Ruby dependencies 23 | run: bundle exec bundle-audit check --update -v 24 | 25 | YAML 26 | end 27 | -------------------------------------------------------------------------------- /lib/nextgen/generators/capybara_lockstep.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | install_gem "capybara-lockstep", group: :test, require: false 4 | 5 | inject_into_file "app/views/layouts/application.html.erb", 6 | "\n <%= capybara_lockstep if defined?(Capybara::Lockstep) %>", 7 | after: /= 3.0", group: %i[development test] 4 | copy_file ".env.sample" 5 | gitignore "/.env*", "!/.env.sample" 6 | -------------------------------------------------------------------------------- /lib/nextgen/generators/erb_lint.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | say_git "Install erb_lint" 4 | install_gem "erb_lint", group: :development, require: false 5 | binstub "erb_lint" 6 | template ".erb_lint.yml.tt" 7 | 8 | say_git "Add erb_lint to default rake task" 9 | copy_file "lib/tasks/erb_lint.rake" 10 | add_lint_task "erb_lint" 11 | 12 | if File.exist?(".github/workflows/ci.yml") 13 | say_git "Add erb_lint job to CI workflow" 14 | inject_into_file ".github/workflows/ci.yml", <<-YAML, after: /^jobs:\n/ 15 | erb_lint: 16 | runs-on: ubuntu-latest 17 | steps: 18 | - name: Checkout code 19 | uses: actions/checkout@v5 20 | 21 | - name: Set up Ruby 22 | uses: ruby/setup-ruby@v1 23 | with: 24 | ruby-version: .ruby-version 25 | bundler-cache: true 26 | 27 | - name: Lint ERB with erb_lint 28 | run: bin/erb_lint --lint-all 29 | 30 | YAML 31 | end 32 | 33 | say_git "Auto-correct any existing issues" 34 | run "bin/erb_lint --lint-all -a", capture: true 35 | -------------------------------------------------------------------------------- /lib/nextgen/generators/factory_bot_rails.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | say_git "Install factory_bot_rails" 4 | install_gem "factory_bot_rails", group: %i[development test] 5 | 6 | say_git "Include factory_bot methods in tests" 7 | copy_test_support_file "factory_bot.rb" 8 | 9 | say_git "Replace fixtures with factories in generators" 10 | if minitest? 11 | inject_into_file "config/initializers/generators.rb", <<~RUBY, after: "Rails.application.config.generators do |g|\n" 12 | g.test_framework :test_unit, fixture: false, fixture_replacement: :factory_bot 13 | RUBY 14 | end 15 | inject_into_file "config/initializers/generators.rb", <<~RUBY, after: "Rails.application.config.generators do |g|\n" 16 | # Generate "users_factory.rb" instead of "users.rb" 17 | g.factory_bot suffix: "factory" 18 | RUBY 19 | -------------------------------------------------------------------------------- /lib/nextgen/generators/git_safe.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | if Dir.exist?(".git") 4 | say_git "Mark project as trusted so bin/ can be added to PATH" 5 | empty_directory ".git/safe" 6 | end 7 | -------------------------------------------------------------------------------- /lib/nextgen/generators/github_pr_template.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | template ".github/PULL_REQUEST_TEMPLATE.md.tt" 4 | -------------------------------------------------------------------------------- /lib/nextgen/generators/good_migrations.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | install_gem "good_migrations" 4 | -------------------------------------------------------------------------------- /lib/nextgen/generators/home_controller.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | copy_file "app/controllers/home_controller.rb" 4 | template "app/views/home/index.html.erb.tt" 5 | route 'root "home#index"' 6 | -------------------------------------------------------------------------------- /lib/nextgen/generators/initial_git_commit.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | commit_msg = "tmp/initial_nextgen_commit" 4 | return unless git_working? && File.exist?(commit_msg) 5 | 6 | gitignore "node_modules/" if Dir.exist?("node_modules") 7 | git_commit_all(File.read(commit_msg)) 8 | -------------------------------------------------------------------------------- /lib/nextgen/generators/letter_opener.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | say_git "Install letter_opener" 4 | install_gem "letter_opener", group: :development 5 | 6 | say_git "Configure Action Mailer to use letter_opener" 7 | insert_into_file "config/environments/development.rb", <<-RUBY, after: "raise_delivery_errors = false\n" 8 | 9 | config.action_mailer.delivery_method = :letter_opener 10 | RUBY 11 | -------------------------------------------------------------------------------- /lib/nextgen/generators/mocha.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | install_gem "mocha", group: :test 4 | copy_test_support_file "mocha.rb" 5 | -------------------------------------------------------------------------------- /lib/nextgen/generators/node.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | copy_file "package.json" unless File.exist?("package.json") 4 | inject_into_file "README.md", "\n- Node 20 (LTS) or newer\n- Yarn 1.x (classic)", after: /^- Ruby.*$/ 5 | inject_into_file "README.md", "\nbrew install node\nbrew install yarn", after: /^brew install rbenv.*$/ 6 | gitignore "node_modules/" 7 | -------------------------------------------------------------------------------- /lib/nextgen/generators/npm.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | remove_file "yarn.lock" 4 | run! "npm install --fund=false --audit=false" 5 | 6 | gsub_file "README.md", "\n- Yarn 1.x (classic)", "" 7 | gsub_file "README.md", "\nbrew install yarn", "" 8 | 9 | gsub_file "Procfile.dev", "yarn build", "npm run build --" if File.exist?("Procfile.dev") 10 | 11 | if File.exist?("Dockerfile") 12 | gsub_file "Dockerfile", /^\s*ARG YARN_VERSION.*\n/, "" 13 | gsub_file "Dockerfile", /^\s*npm install -g yarn.*\n/, "" 14 | gsub_file "Dockerfile", "yarn.lock", "package-lock.json" 15 | gsub_file "Dockerfile", /RUN yarn install.*/, "RUN npm ci" 16 | end 17 | -------------------------------------------------------------------------------- /lib/nextgen/generators/open_browser_on_start.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | say_git "Install launchy" 4 | install_gem "launchy", group: %i[development test] 5 | 6 | say_git "Configure puma to open browser on startup" 7 | copy_file "lib/puma/plugin/open.rb" 8 | append_to_file "config/puma.rb", <<~RUBY 9 | 10 | # Automatically open the browser when in development 11 | require_relative "../lib/puma/plugin/open" 12 | plugin :open 13 | RUBY 14 | prevent_autoload_lib "puma/plugin" 15 | -------------------------------------------------------------------------------- /lib/nextgen/generators/overcommit.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | template ".overcommit.yml" 4 | -------------------------------------------------------------------------------- /lib/nextgen/generators/pgcli_rails.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | install_gem "pgcli-rails", group: :development 4 | -------------------------------------------------------------------------------- /lib/nextgen/generators/rack_canonical_host.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | say_git "Install rack-canonical-host" 4 | install_gem "rack-canonical-host" 5 | 6 | say_git "Use RAILS_HOSTNAME env var" 7 | document_deploy_var "RAILS_HOSTNAME", "Redirect all requests to the specified canonical hostname" 8 | insert_into_file "config.ru", 9 | %(use Rack::CanonicalHost, ENV.fetch("RAILS_HOSTNAME", nil) if ENV["RAILS_HOSTNAME"].present?\n), 10 | before: /^run Rails.application/ 11 | 12 | gsub_file "config/environments/production.rb", 13 | /\bhost: "example\.com"/, 14 | 'host: ENV.fetch("RAILS_HOSTNAME", "example.com")' 15 | -------------------------------------------------------------------------------- /lib/nextgen/generators/rack_mini_profiler.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | install_gem "rack-mini-profiler", group: :development 4 | copy_file "config/initializers/rack_mini_profiler.rb" if File.read("Gemfile").match?(/^\s*gem ['"]turbo-rails['"]/) 5 | -------------------------------------------------------------------------------- /lib/nextgen/generators/rspec_rails.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | say_git "Install the rspec-rails gem" 4 | install_gem "rspec-rails", group: %i[development test] 5 | 6 | say_git "Run the rspec installer" 7 | generate "rspec:install" 8 | gitignore "/spec/examples.txt" 9 | binstub "rspec-core" 10 | 11 | say_git "Disable auto-generation of routing and view specs" 12 | inject_into_file "config/initializers/generators.rb", <<~RUBY, after: "g.stylesheets false\n" 13 | g.routing_specs false 14 | g.view_specs false 15 | RUBY 16 | 17 | say_git "Add spec to default rake task" 18 | inject_into_file "Rakefile", "spec", after: /task default: %w\[/ 19 | 20 | say_git "Enable auto-loading of the spec/support directory" 21 | uncomment_lines("spec/rails_helper.rb", /Dir\[Rails.root.join/) 22 | -------------------------------------------------------------------------------- /lib/nextgen/generators/rspec_system_testing.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | install_gems "capybara", "selenium-webdriver", group: :test, require: false 4 | copy_test_support_file "capybara.rb.tt" 5 | copy_test_support_file "system.rb" 6 | 7 | copy_file "lib/templates/rspec/system/system_spec.rb" 8 | prevent_autoload_lib "templates" 9 | -------------------------------------------------------------------------------- /lib/nextgen/generators/shoulda.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | say_git "Install shoulda gems" 4 | install_gem "shoulda-context", group: :test if minitest? 5 | install_gem "shoulda-matchers", group: :test 6 | 7 | say_git "Include shoulda methods in tests" 8 | copy_test_support_file "shoulda.rb" 9 | -------------------------------------------------------------------------------- /lib/nextgen/generators/staging.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | copy_file "config/environments/staging.rb" 4 | gsub_file "DEPLOYMENT.md", '"production"', '"production" or "staging"' if File.exist?("DEPLOYMENT.md") 5 | 6 | %w[config/cable.yml config/database.yml].each do |file| 7 | next unless File.exist?(file) 8 | 9 | config_yml = File.read(file) 10 | config_yml.sub!(/^production:\n( .*\n)+/) do |match| 11 | match + "\n" + match.gsub("production", "staging") 12 | end 13 | File.write(file, config_yml) 14 | end 15 | -------------------------------------------------------------------------------- /lib/nextgen/generators/thor.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | copy_file "Thorfile" 4 | binstub "thor" 5 | -------------------------------------------------------------------------------- /lib/nextgen/generators/tomo.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | say_git "Install the tomo gem in the :development group, with a binstub" 4 | install_gem "tomo", version: "~> 1.18", group: :development, require: false 5 | binstub "tomo" 6 | 7 | say_git "Initialize the tomo config file" 8 | if File.exist?(".tomo/config.rb") 9 | say_status :skip, ".tomo/config.rb exists", :blue 10 | else 11 | bundle_command! "exec tomo init" 12 | end 13 | -------------------------------------------------------------------------------- /lib/nextgen/generators/vcr.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | install_gems "vcr", "webmock", group: :test 4 | copy_test_support_file "vcr.rb.tt" 5 | copy_test_support_file "webmock.rb" 6 | append_to_file ".gitattributes", <<~GITATTRS if File.exist?(".gitattributes") 7 | 8 | # Mark VCR cassettes as having been generated. 9 | #{rspec? ? "spec" : "test"}/cassettes/* linguist-generated 10 | GITATTRS 11 | -------------------------------------------------------------------------------- /lib/nextgen/rails_command.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | require "rails/version" 4 | 5 | module Nextgen 6 | module RailsCommand 7 | class << self 8 | def run(*args, raise_on_error: true) 9 | command = "rails", "_#{::Rails.version}_", *args 10 | say_status :run, *command.join(" ") 11 | with_original_bundler_env do 12 | system(*command, exception: raise_on_error) 13 | end 14 | end 15 | 16 | private 17 | 18 | def say_status(...) 19 | Thor::Base.shell.new.say_status(...) 20 | end 21 | 22 | def with_original_bundler_env(&) 23 | return yield unless defined?(Bundler) 24 | 25 | Bundler.with_original_env(&) 26 | end 27 | end 28 | end 29 | end 30 | -------------------------------------------------------------------------------- /lib/nextgen/version.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | module Nextgen 4 | VERSION = "0.36.0" 5 | end 6 | -------------------------------------------------------------------------------- /template/.editorconfig: -------------------------------------------------------------------------------- 1 | # https://editorconfig.org 2 | 3 | root = true 4 | 5 | [*] 6 | charset = utf-8 7 | indent_style = space 8 | indent_size = 2 9 | end_of_line = lf 10 | insert_final_newline = true 11 | trim_trailing_whitespace = true 12 | 13 | [Makefile] 14 | indent_style = tab 15 | -------------------------------------------------------------------------------- /template/.env.sample: -------------------------------------------------------------------------------- 1 | # These environment variables are needed to run the app locally. 2 | # Copy these into a file named .env to have them loaded automatically. 3 | -------------------------------------------------------------------------------- /template/.erb_lint.yml.tt: -------------------------------------------------------------------------------- 1 | --- 2 | EnableDefaultLinters: true 3 | exclude: 4 | - "node_modules/**/*" 5 | - "vendor/**/*" 6 | linters: 7 | ErbSafety: 8 | enabled: true 9 | <% if File.exist?(".rubocop.yml") -%> 10 | Rubocop: 11 | enabled: true 12 | rubocop_config: 13 | inherit_from: 14 | - .rubocop.yml 15 | Layout/InitialIndentation: 16 | Enabled: false 17 | Layout/TrailingEmptyLines: 18 | Enabled: false 19 | Lint/UselessAssignment: 20 | Enabled: false 21 | Naming/FileName: 22 | Enabled: false 23 | Rails/OutputSafety: 24 | Enabled: false 25 | Style/FrozenStringLiteralComment: 26 | Enabled: false 27 | <% end -%> 28 | -------------------------------------------------------------------------------- /template/.github/PULL_REQUEST_TEMPLATE.md.tt: -------------------------------------------------------------------------------- 1 | Problem 2 | ======= 3 | 4 | 5 | 6 | 7 | 8 | Solution 9 | ======== 10 | 11 | Steps to verify 12 | --------------- 13 | 14 | 1. step 15 | 1. step 16 | 1. step 17 | <% if File.exist?("app/views/layouts/application.html.erb") -%> 18 | 19 | Screenshots 20 | ----------- 21 | <% end -%> 22 | -------------------------------------------------------------------------------- /template/.prettierrc.cjs: -------------------------------------------------------------------------------- 1 | /** @type {import("prettier").Config} */ 2 | 3 | module.exports = { 4 | tabWidth: 2, 5 | useTabs: false, 6 | }; 7 | -------------------------------------------------------------------------------- /template/DEPLOYMENT.md: -------------------------------------------------------------------------------- 1 | # Deployment 2 | 3 | ## Environment variables 4 | 5 | These environment variables affect how the app functions when deployed in production. 6 | 7 | - `RAILS_DISABLE_SSL` - Disable HSTS and secure cookies 8 | - `RAILS_ENV` **REQUIRED** - "production" 9 | - `RAILS_MAX_THREADS` - Number of threads per Puma process (default: 3) 10 | - `SECRET_KEY_BASE` **REQUIRED** - Unique, secret key used to encrypt and sign cookies and other sensitive data 11 | - `WEB_CONCURRENCY` - Number of Puma processes (default: 1) 12 | -------------------------------------------------------------------------------- /template/Procfile.tt: -------------------------------------------------------------------------------- 1 | web: bundle exec puma -C config/puma.rb 2 | <% if File.exist?("config/database.yml") -%> 3 | release: bundle exec rake db:migrate 4 | <% end -%> 5 | -------------------------------------------------------------------------------- /template/Thorfile: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | require_relative "config/environment" unless %w[-h --help help -T list -v version].include?(ARGV.first) 4 | 5 | class << Thor 6 | def exit_on_failure? 7 | true 8 | end 9 | end 10 | -------------------------------------------------------------------------------- /template/app/controllers/concerns/basic_auth.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | module BasicAuth 4 | extend ActiveSupport::Concern 5 | 6 | included do 7 | before_action :require_basic_auth 8 | end 9 | 10 | private 11 | 12 | def require_basic_auth 13 | expected_username = ENV.fetch("BASIC_AUTH_USERNAME", nil) 14 | expected_password = ENV.fetch("BASIC_AUTH_PASSWORD", nil) 15 | return true if expected_username.blank? || expected_password.blank? 16 | 17 | authenticate_or_request_with_http_basic do |username, password| 18 | ActiveSupport::SecurityUtils.secure_compare(username, expected_username) & 19 | ActiveSupport::SecurityUtils.secure_compare(password, expected_password) 20 | end 21 | end 22 | end 23 | -------------------------------------------------------------------------------- /template/app/controllers/home_controller.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | class HomeController < ApplicationController 4 | def index 5 | end 6 | end 7 | -------------------------------------------------------------------------------- /template/app/frontend/controllers/index.js: -------------------------------------------------------------------------------- 1 | import { application } from "./application"; 2 | import { registerControllers } from "stimulus-vite-helpers"; 3 | 4 | const controllers = import.meta.glob("./**/*_controller.js", { eager: true }); 5 | registerControllers(application, controllers); 6 | -------------------------------------------------------------------------------- /template/app/frontend/images/example.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /template/app/frontend/stylesheets/base.css: -------------------------------------------------------------------------------- 1 | /* 2 | This file is for base element styles, like: 3 | 4 | - Any @font-face declarations needed custom web fonts. 5 | - Default font-family on the body element. 6 | - Default foreground, background, and link colors. 7 | - Global CSS variables (declared on :root), such as color palette. 8 | */ 9 | -------------------------------------------------------------------------------- /template/app/frontend/stylesheets/index.css: -------------------------------------------------------------------------------- 1 | @import "modern-normalize"; 2 | @import "reset"; 3 | @import "base"; 4 | -------------------------------------------------------------------------------- /template/app/frontend/stylesheets/reset.css: -------------------------------------------------------------------------------- 1 | :root { 2 | line-height: 1.5; 3 | -webkit-font-smoothing: antialiased; 4 | } 5 | 6 | h1, 7 | h2, 8 | h3, 9 | h4, 10 | h5, 11 | figure, 12 | p, 13 | ol, 14 | ul { 15 | margin: 0; 16 | } 17 | 18 | ol, 19 | ul { 20 | list-style: none; 21 | padding-inline: 0; 22 | } 23 | 24 | h1, 25 | h2, 26 | h3, 27 | h4, 28 | h5 { 29 | font-size: inherit; 30 | font-weight: inherit; 31 | } 32 | 33 | img { 34 | display: block; 35 | max-inline-size: 100%; 36 | } 37 | -------------------------------------------------------------------------------- /template/app/helpers/inline_svg_helper.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | module InlineSvgHelper 4 | def inline_svg_tag(filename, title: nil) 5 | svg = ViteInlineSvgFileLoader.named(filename) 6 | svg = svg.sub(/\A/, safe_join(['\0', "\n", tag.title(title)])) if title.present? 8 | 9 | svg.strip.html_safe # rubocop:disable Rails/OutputSafety 10 | end 11 | end 12 | -------------------------------------------------------------------------------- /template/app/views/home/index.html.erb.tt: -------------------------------------------------------------------------------- 1 | <%% provide(:title, "Home") %> 2 |

Find me in app/views/home/index.html.erb

3 | <% if File.exist?("package.json") && File.read("package.json").match?(%r{@hotwired/stimulus}) -%> 4 |

Stimulus says,

5 | <% end -%> 6 | -------------------------------------------------------------------------------- /template/bin/dev: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env ruby 2 | # frozen_string_literal: true 3 | 4 | exec "./bin/rails", "server", *ARGV 5 | -------------------------------------------------------------------------------- /template/bin/dev-node: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env ruby 2 | # frozen_string_literal: true 3 | 4 | exec "npx", "run-pty", "run-pty.json", *ARGV 5 | -------------------------------------------------------------------------------- /template/config/environments/staging.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | # The staging environment is based on production 4 | require_relative "production" 5 | -------------------------------------------------------------------------------- /template/config/initializers/generators.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | Rails.application.config.generators do |g| 4 | # Disable generators we don't need. 5 | g.javascripts false 6 | g.stylesheets false 7 | end 8 | -------------------------------------------------------------------------------- /template/config/initializers/rack_mini_profiler.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | return unless defined?(Rack::MiniProfiler) 4 | 5 | # https://github.com/MiniProfiler/rack-mini-profiler#configuration-options 6 | Rack::MiniProfiler.config.enable_hotwire_turbo_drive_support = true 7 | -------------------------------------------------------------------------------- /template/config/sidekiq.yml: -------------------------------------------------------------------------------- 1 | --- 2 | :queues: 3 | - default 4 | 5 | :concurrency: <%= ENV["SIDEKIQ_CONCURRENCY"] || ENV["RAILS_MAX_THREADS"] || 5 %> 6 | -------------------------------------------------------------------------------- /template/eslint.config.js: -------------------------------------------------------------------------------- 1 | /** @type {import("@types/eslint").Linter.Config */ 2 | 3 | import globals from "globals"; 4 | import js from "@eslint/js"; 5 | import eslintPluginPrettierRecommended from "eslint-plugin-prettier/recommended"; 6 | 7 | export default [ 8 | js.configs.recommended, 9 | eslintPluginPrettierRecommended, 10 | { 11 | languageOptions: { 12 | ecmaVersion: 2022, 13 | sourceType: "module", 14 | globals: { 15 | ...globals.browser, 16 | ...globals.es2021, 17 | }, 18 | }, 19 | rules: { 20 | "no-unused-vars": [ 21 | "error", 22 | { 23 | args: "after-used", 24 | argsIgnorePattern: "^_", 25 | varsIgnorePattern: "^_", 26 | }, 27 | ], 28 | "no-var": "error", 29 | "prettier/prettier": "error", 30 | }, 31 | }, 32 | ]; 33 | -------------------------------------------------------------------------------- /template/lib/puma/plugin/open.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | require "puma/plugin" 4 | 5 | Puma::Plugin.create do 6 | def start(launcher) 7 | return unless defined?(Rails) && defined?(Launchy) 8 | return unless Rails.env.development? 9 | 10 | binding = launcher.options[:binds].grep(/^tcp|ssl/).first 11 | return if binding.nil? 12 | 13 | url = binding.sub(/^tcp/, "http").sub(/^ssl/, "https").sub("0.0.0.0", "localhost") 14 | Launchy.open(url) 15 | end 16 | end 17 | -------------------------------------------------------------------------------- /template/lib/tasks/erb_lint.rake: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | desc "Run erb_lint" 4 | task :erb_lint do 5 | sh "bin/erb_lint --lint-all" 6 | end 7 | 8 | namespace :erb_lint do 9 | desc "Autocorrect erb_lint offenses" 10 | task :autocorrect do 11 | sh "bin/erb_lint --lint-all -a" 12 | end 13 | end 14 | -------------------------------------------------------------------------------- /template/lib/tasks/eslint.rake.tt: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | desc "Run ESLint" 4 | task :eslint do 5 | sh "<%= js_package_manager %> run lint:js" 6 | end 7 | 8 | namespace :eslint do 9 | desc "Autocorrect ESLint offenses" 10 | task :autocorrect do 11 | sh "<%= js_package_manager %> run fix:js" 12 | end 13 | end 14 | -------------------------------------------------------------------------------- /template/lib/tasks/rubocop.rake: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | return unless Gem.loaded_specs.key?("rubocop") 4 | 5 | require "rubocop/rake_task" 6 | RuboCop::RakeTask.new(:rubocop) do |task| 7 | task.options.push "-c", ".rubocop.yml" 8 | end 9 | -------------------------------------------------------------------------------- /template/lib/tasks/stylelint.rake.tt: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | desc "Run Stylelint" 4 | task :stylelint do 5 | sh "<%= js_package_manager %> run lint:css" 6 | end 7 | 8 | namespace :stylelint do 9 | desc "Autocorrect Stylelint offenses" 10 | task :autocorrect do 11 | sh "<%= js_package_manager %> run fix:css" 12 | end 13 | end 14 | -------------------------------------------------------------------------------- /template/lib/templates/rspec/system/system_spec.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | require "rails_helper" 4 | 5 | RSpec.describe "<%= class_name %>" do 6 | pending "add some scenarios (or delete) #{__FILE__}" 7 | 8 | # it "renders a message on the home page" do 9 | # visit "/" 10 | # expect(page).to have_content("Hello, world!") 11 | # end 12 | end 13 | -------------------------------------------------------------------------------- /template/lib/vite_inline_svg_file_loader.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | module ViteInlineSvgFileLoader 4 | class << self 5 | def named(filename) 6 | vite = ViteRuby.instance 7 | vite_asset_path = vite.manifest.path_for(filename) 8 | 9 | if vite.dev_server_running? 10 | fetch_from_dev_server(vite_asset_path) 11 | else 12 | Rails.public_path.join(vite_asset_path.sub(%r{^/}, "")).read 13 | end 14 | end 15 | 16 | private 17 | 18 | def fetch_from_dev_server(path) 19 | config = ViteRuby.config 20 | dev_server_uri = URI("#{config.protocol}://#{config.host_with_port}#{path}") 21 | response = Net::HTTP.get_response(dev_server_uri) 22 | raise "Failed to load inline SVG from #{dev_server_uri}" unless response.is_a?(Net::HTTPSuccess) 23 | 24 | response.body 25 | end 26 | end 27 | end 28 | -------------------------------------------------------------------------------- /template/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "private": true, 3 | "type": "module", 4 | "engines": { 5 | "node": "^20.9.0 || >= 22.0.0" 6 | } 7 | } 8 | -------------------------------------------------------------------------------- /template/postcss.config.cjs: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | plugins: [require("autoprefixer")], 3 | }; 4 | -------------------------------------------------------------------------------- /template/run-pty.json: -------------------------------------------------------------------------------- 1 | [ 2 | { 3 | "command": ["bin/rails", "server"], 4 | "status": { 5 | "Listening on": null 6 | }, 7 | "defaultStatus": ["⏳", "S"] 8 | }, 9 | { 10 | "command": ["bin/vite", "dev"], 11 | "status": { 12 | "ready in": null 13 | }, 14 | "defaultStatus": ["⏳", "S"] 15 | } 16 | ] 17 | -------------------------------------------------------------------------------- /template/spec/support/factory_bot.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | RSpec.configure do |config| 4 | config.include FactoryBot::Syntax::Methods 5 | end 6 | -------------------------------------------------------------------------------- /template/spec/support/mailer.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | RSpec.configure do |config| 4 | config.before(:each) do 5 | ActionMailer::Base.deliveries.clear 6 | end 7 | end 8 | -------------------------------------------------------------------------------- /template/spec/support/shoulda.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | Shoulda::Matchers.configure do |config| 4 | config.integrate do |with| 5 | with.test_framework :rspec 6 | with.library :rails 7 | end 8 | end 9 | -------------------------------------------------------------------------------- /template/spec/support/system.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | RSpec.configure do |config| 4 | config.before(:each, type: :system) do 5 | driven_by :selenium, 6 | using: (ENV["SHOW_BROWSER"] ? :chrome : :headless_chrome), 7 | screen_size: [1400, 1400] do |options| 8 | # Allows running in Docker 9 | options.add_argument("--disable-dev-shm-usage") 10 | options.add_argument("--no-sandbox") 11 | 12 | # Fixes slowdowns on macOS 13 | options.add_argument("--disable-gpu") 14 | end 15 | end 16 | end 17 | -------------------------------------------------------------------------------- /template/spec/support/webmock.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | require "webmock/rspec" 4 | -------------------------------------------------------------------------------- /template/test/application_system_test_case.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | require "test_helper" 4 | 5 | class ApplicationSystemTestCase < ActionDispatch::SystemTestCase 6 | driven_by :selenium, 7 | using: (ENV["SHOW_BROWSER"] ? :chrome : :headless_chrome), 8 | screen_size: [1400, 1400] do |options| 9 | # Allows running in Docker 10 | options.add_argument("--disable-dev-shm-usage") 11 | options.add_argument("--no-sandbox") 12 | 13 | # Fixes slowdowns on macOS 14 | options.add_argument("--disable-gpu") 15 | end 16 | end 17 | -------------------------------------------------------------------------------- /template/test/support/capybara.rb.tt: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | ActiveSupport.on_load(:action_dispatch_system_test_case) do 4 | require "capybara" 5 | require "capybara/rails" 6 | <% if rspec? -%> 7 | require "capybara/rspec" 8 | <% end -%> 9 | 10 | Capybara.configure do |config| 11 | config.default_max_wait_time = 2 12 | config.save_path = "tmp/screenshots" 13 | config.enable_aria_label = true 14 | config.server = :puma, {Silent: true} 15 | config.test_id = "data-testid" 16 | end 17 | end 18 | -------------------------------------------------------------------------------- /template/test/support/factory_bot.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | ActiveSupport.on_load(:active_support_test_case) do 4 | include FactoryBot::Syntax::Methods 5 | end 6 | -------------------------------------------------------------------------------- /template/test/support/mailer.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | ActiveSupport.on_load(:active_support_test_case) do 4 | setup { ActionMailer::Base.deliveries.clear } 5 | end 6 | -------------------------------------------------------------------------------- /template/test/support/mocha.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | require "mocha/minitest" 4 | 5 | # Reference: https://rubydoc.info/gems/mocha/Mocha/Configuration 6 | Mocha.configure do |config| 7 | config.strict_keyword_argument_matching = true 8 | config.stubbing_non_existent_method = :prevent 9 | end 10 | -------------------------------------------------------------------------------- /template/test/support/shoulda.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | Shoulda::Matchers.configure do |config| 4 | config.integrate do |with| 5 | with.test_framework :minitest 6 | with.library :rails 7 | end 8 | end 9 | -------------------------------------------------------------------------------- /template/test/support/webmock.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | require "webmock/minitest" 4 | -------------------------------------------------------------------------------- /template/test/vite_helper.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | return if ViteRuby.config.auto_build 4 | 5 | # Compile assets once at the start of testing 6 | require "benchmark" 7 | seconds = Benchmark.realtime { ViteRuby.commands.build } 8 | puts format("Built Vite assets (%.1fms)", seconds * 1_000) 9 | -------------------------------------------------------------------------------- /test/integration/generators/github_pr_template_test.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | require_relative "test_case" 4 | 5 | class Nextgen::Generators::GithubPrTemplateTest < Nextgen::Generators::TestCase 6 | destination File.join(Dir.tmpdir, "test_#{SecureRandom.hex(8)}") 7 | setup :prepare_destination 8 | 9 | test "creates a .github/PULL_REQUEST_TEMPLATE.md file" do 10 | apply_generator 11 | assert_file ".github/PULL_REQUEST_TEMPLATE.md" 12 | end 13 | end 14 | -------------------------------------------------------------------------------- /test/integration/generators/mocha_test.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | require_relative "test_case" 4 | 5 | class Nextgen::Generators::MochaTest < Nextgen::Generators::TestCase 6 | destination File.join(Dir.tmpdir, "test_#{SecureRandom.hex(8)}") 7 | setup :prepare_destination 8 | setup :empty_destination_gemfile 9 | 10 | test "installs mocha gem" do 11 | apply_generator 12 | 13 | assert_file "Gemfile", /#{Regexp.quote(<<~GEMFILE)}/ 14 | group :test do 15 | gem "mocha" 16 | end 17 | GEMFILE 18 | end 19 | 20 | test "creates a test/support/mocha.rb file, assuming minitest is present" do 21 | Dir.chdir(destination_root) do 22 | FileUtils.mkdir_p("test") 23 | FileUtils.touch("test/test_helper.rb") 24 | end 25 | 26 | apply_generator 27 | assert_file "test/support/mocha.rb" 28 | end 29 | end 30 | -------------------------------------------------------------------------------- /test/nextgen_test.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | require "test_helper" 4 | 5 | class NextgenTest < Minitest::Test 6 | def test_that_it_has_a_version_number 7 | refute_nil ::Nextgen::VERSION 8 | end 9 | end 10 | -------------------------------------------------------------------------------- /test/test_helper.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | $LOAD_PATH.unshift File.expand_path("../lib", __dir__) 4 | require "nextgen" 5 | 6 | require "minitest" 7 | require "webmock/minitest" 8 | require "minitest/autorun" 9 | --------------------------------------------------------------------------------