Skip to content

Commit

Permalink
Dynamically generate README (#1187)
Browse files Browse the repository at this point in the history
Create README based off the `desc` of the generators.

We chose to create a custom class instead of a traditional generator
because this script is intended to be run in the [application
template][] as a Rake task. It is not intended to be run as a standalone
generator, since it only makes sense to be run on concert with
`suspenders:install:web`.

Updates all generator descriptions to use Herdoc syntax to ensure
consistent line breaks.

A follow-up commit will update the descriptions to work better in a
README.

[application template]: https://guides.rubyonrails.org/rails_application_templates.html
  • Loading branch information
stevepolitodesign authored Apr 13, 2024
1 parent 473e483 commit 08be1dd
Show file tree
Hide file tree
Showing 23 changed files with 277 additions and 26 deletions.
4 changes: 3 additions & 1 deletion lib/generators/suspenders/accessibility_generator.rb
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,9 @@ module Generators
class AccessibilityGenerator < Rails::Generators::Base
include Suspenders::Generators::APIAppUnsupported

desc "Installs capybara_accessibility_audit and capybara_accessible_selectors"
desc <<~MARKDOWN
Installs capybara_accessibility_audit and capybara_accessible_selectors"
MARKDOWN

def add_capybara_gems
gem_group :test do
Expand Down
4 changes: 2 additions & 2 deletions lib/generators/suspenders/advisories_generator.rb
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,12 @@ module Suspenders
module Generators
class AdvisoriesGenerator < Rails::Generators::Base
source_root File.expand_path("../../templates/advisories", __FILE__)
desc(<<~TEXT)
desc <<~MARKDOWN
Show security advisories during development.
Uses the `bundler-audit` gem to update the local security database and
show any relevant issues with the app's dependencies via a Rake task.
TEXT
MARKDOWN

def add_bundler_audit
gem_group :development, :test do
Expand Down
4 changes: 3 additions & 1 deletion lib/generators/suspenders/ci_generator.rb
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,9 @@ class CiGenerator < Rails::Generators::Base
include Suspenders::Generators::Helpers

source_root File.expand_path("../../templates/ci", __FILE__)
desc "Creates CI files for GitHub Actions"
desc <<~MARKDOWN
Creates CI files for GitHub Actions
MARKDOWN

def ci_files
empty_directory ".github/workflows"
Expand Down
4 changes: 2 additions & 2 deletions lib/generators/suspenders/email_generator.rb
Original file line number Diff line number Diff line change
Expand Up @@ -2,15 +2,15 @@ module Suspenders
module Generators
class EmailGenerator < Rails::Generators::Base
source_root File.expand_path("../../templates/email", __FILE__)
desc <<~TEXT
desc <<~MARKDOWN
Intercepts emails in non-production environments by setting `INTERCEPTOR_ADDRESSES`.
```sh
INTERCEPTOR_ADDRESSES="[email protected],[email protected]" bin/rails s
```
Configures `default_url_options` in `test` and `development`.
TEXT
MARKDOWN

def create_email_interceptor
copy_file "email_interceptor.rb", "app/mailers/email_interceptor.rb"
Expand Down
4 changes: 2 additions & 2 deletions lib/generators/suspenders/factories_generator.rb
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ class FactoriesGenerator < Rails::Generators::Base
include Suspenders::Generators::Helpers

source_root File.expand_path("../../templates/factories", __FILE__)
desc <<~TEXT
desc <<~MARKDOWN
Build test data with clarity and ease.
This uses FactoryBot to help you define dummy and test data for your test
Expand All @@ -17,7 +17,7 @@ class FactoriesGenerator < Rails::Generators::Base
definitions.
Supports the default test suite and RSpec.
TEXT
MARKDOWN

def add_factory_bot
gem_group :development, :test do
Expand Down
4 changes: 3 additions & 1 deletion lib/generators/suspenders/inline_svg_generator.rb
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,9 @@ module Generators
class InlineSvgGenerator < Rails::Generators::Base
include Suspenders::Generators::APIAppUnsupported
source_root File.expand_path("../../templates/inline_svg", __FILE__)
desc "Render SVG images inline, as a potential performance improvement for the viewer."
desc <<~MARKDOWN
Render SVG images inline, as a potential performance improvement for the viewer.
MARKDOWN

def add_inline_svg_gem
gem "inline_svg"
Expand Down
4 changes: 3 additions & 1 deletion lib/generators/suspenders/jobs_generator.rb
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,9 @@ module Suspenders
module Generators
class JobsGenerator < Rails::Generators::Base
source_root File.expand_path("../../templates/active_job", __FILE__)
desc "Installs Sidekiq for background job processing."
desc <<~MARKDOWN
Installs Sidekiq for background job processing.
MARKDOWN

def add_sidekiq_gem
gem "sidekiq"
Expand Down
4 changes: 3 additions & 1 deletion lib/generators/suspenders/lint_generator.rb
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,9 @@ class LintGenerator < Rails::Generators::Base
include Suspenders::Generators::Helpers

source_root File.expand_path("../../templates/lint", __FILE__)
desc "Creates a holistic linting solution that covers JavaScript, CSS, Ruby and ERB."
desc <<~MARKDOWN
Creates a holistic linting solution that covers JavaScript, CSS, Ruby and ERB.
MARKDOWN

def check_package_json
unless File.exist? Rails.root.join("package.json")
Expand Down
4 changes: 3 additions & 1 deletion lib/generators/suspenders/prerequisites_generator.rb
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,9 @@ module Generators
class PrerequisitesGenerator < Rails::Generators::Base
source_root File.expand_path("../../templates/prerequisites", __FILE__)

desc "Configures prerequisites. Currently Node."
desc <<~MARKDOWN
Configures prerequisites. Currently Node.
MARKDOWN

def node_version
template "node-version", ".node-version"
Expand Down
4 changes: 2 additions & 2 deletions lib/generators/suspenders/rake_generator.rb
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,10 @@ module Suspenders
module Generators
class RakeGenerator < Rails::Generators::Base
source_root File.expand_path("../../templates/rake", __FILE__)
desc(<<~TEXT)
desc <<~MARKDOWN
Configures the default Rake task to audit and lint the codebase with
`bundler-audit` and `standard`, in addition to running the test suite.
TEXT
MARKDOWN

def configure_default_rake_task
append_to_file "Rakefile", <<~RUBY
Expand Down
4 changes: 2 additions & 2 deletions lib/generators/suspenders/setup_generator.rb
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,13 @@ module Suspenders
module Generators
class SetupGenerator < Rails::Generators::Base
source_root File.expand_path("../../templates/setup", __FILE__)
desc <<~TEXT
desc <<~MARKDOWN
A holistic setup script.
```sh
bin/setup
```
TEXT
MARKDOWN

def replace_bin_setup
copy_file "bin_setup.rb", "bin/setup", force: true
Expand Down
4 changes: 2 additions & 2 deletions lib/generators/suspenders/styles_generator.rb
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,11 @@ module Generators
class StylesGenerator < Rails::Generators::Base
include Suspenders::Generators::APIAppUnsupported

desc <<~TEXT
desc <<~MARKDOWN
Configures application to use PostCSS via cssbundling-rails.
Adds modern-normalize, and style sheet structure.
TEXT
MARKDOWN

def add_cssbundling_rails_gem
gem "cssbundling-rails"
Expand Down
4 changes: 2 additions & 2 deletions lib/generators/suspenders/tasks_generator.rb
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,11 @@ module Suspenders
module Generators
class TasksGenerator < Rails::Generators::Base
source_root File.expand_path("../../templates/tasks", __FILE__)
desc <<~TEXT
desc <<~MARKDOWN
Creates local Rake tasks for development
bin/rails dev:prime # Sample data for local development environment
TEXT
MARKDOWN

def create_dev_rake
if Bundler.rubygems.find_name("factory_bot").any?
Expand Down
4 changes: 3 additions & 1 deletion lib/generators/suspenders/testing_generator.rb
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,9 @@ module Suspenders
module Generators
class TestingGenerator < Rails::Generators::Base
source_root File.expand_path("../../templates/testing", __FILE__)
desc "Set up the project for an in-depth test-driven development workflow."
desc <<~MARKDOWN
Set up the project for an in-depth test-driven development workflow.
MARKDOWN

def add_gems
gem_group :development, :test do
Expand Down
4 changes: 3 additions & 1 deletion lib/generators/suspenders/views_generator.rb
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,9 @@ module Generators
class ViewsGenerator < Rails::Generators::Base
include Suspenders::Generators::APIAppUnsupported

desc "Configures flash messages, page titles and the document lang. Disables Turbo's InstantClick."
desc <<~MARKDOWN
Configures flash messages, page titles and the document lang. Disables Turbo's InstantClick.
MARKDOWN
source_root File.expand_path("../../templates/views", __FILE__)

def install_gems
Expand Down
1 change: 1 addition & 0 deletions lib/suspenders.rb
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
require "suspenders/railtie"
require "suspenders/generators"
require "suspenders/cleanup/organize_gemfile"
require "suspenders/cleanup/generate_readme"

module Suspenders
# Your code goes here...
Expand Down
151 changes: 151 additions & 0 deletions lib/suspenders/cleanup/generate_readme.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,151 @@
require "rails/generators"
require_relative "../../generators/suspenders/environments/development_generator"
require_relative "../../generators/suspenders/environments/test_generator"
require_relative "../../generators/suspenders/environments/production_generator"
require_relative "../../generators/suspenders/accessibility_generator"
require_relative "../../generators/suspenders/advisories_generator"
require_relative "../../generators/suspenders/email_generator"
require_relative "../../generators/suspenders/factories_generator"
require_relative "../../generators/suspenders/inline_svg_generator"
require_relative "../../generators/suspenders/jobs_generator"
require_relative "../../generators/suspenders/lint_generator"
require_relative "../../generators/suspenders/styles_generator"
require_relative "../../generators/suspenders/testing_generator"
require_relative "../../generators/suspenders/views_generator"

module Suspenders
module Cleanup
class GenerateReadme
def self.perform(readme, app_name)
new(readme, app_name).perform
end

attr_reader :readme, :app_name

def initialize(readme, app_name)
@readme = readme
@app_name = app_name
end

def perform
File.open(readme, "w+") do |file|
@file = file

heading app_name, level: 1

prerequisites

local_development

heading "Configuration", level: 2

heading "Test", level: 3
description_for Suspenders::Generators::Environments::TestGenerator

heading "Development", level: 3
description_for Suspenders::Generators::Environments::DevelopmentGenerator

heading "Production", level: 3
description_for Suspenders::Generators::Environments::ProductionGenerator

heading "Linting", level: 3
description_for Suspenders::Generators::LintGenerator

heading "Testing", level: 2
description_for Suspenders::Generators::TestingGenerator

heading "Factories", level: 3
description_for Suspenders::Generators::FactoriesGenerator

heading "Accessibility", level: 2
description_for Suspenders::Generators::AccessibilityGenerator

heading "Advisories", level: 2
description_for Suspenders::Generators::AdvisoriesGenerator

heading "Mailers", level: 2
description_for Suspenders::Generators::EmailGenerator

heading "Jobs", level: 2
description_for Suspenders::Generators::JobsGenerator

heading "Layout and Assets", level: 2

heading "Stylesheets", level: 3
description_for Suspenders::Generators::StylesGenerator

heading "Inline SVG", level: 3
description_for Suspenders::Generators::InlineSvgGenerator

heading "Layout", level: 3
description_for Suspenders::Generators::ViewsGenerator
end
end

private

def new_line
@file.write "\n"
end

def heading(text, level:)
@file.write "#{"#" * level} #{text}\n"
new_line
end

def description_for(generator)
@file.write generator.desc
new_line
end

def local_development
@file.write <<~MARKDOWN
## Local Development
### Initial Setup
```
bin/setup
```
### Running the Development Server
```
bin/rails dev
```
### Seed Data
- Use `db/seeds.rb` to create records that need to exist in all environments.
- Use `lib/tasks/dev.rake` to create records that only need to exist in development.
Running `bin/setup` will run `dev:prime`.
### Tasks
- Use `bin/rails suspenders:db:migrate` to run [database migrations][]. This script ensures they are [reversible][].
- Use `bin/rails suspenders:cleanup:organize_gemfile` to automatically organize the project's Gemfile.
- Use `bin/rails default` to run the default Rake task. This will do the following:
- Run the test suite.
- Run a Ruby and ERB linter.
- Scan the Ruby codebase for any dependecy vulnerabilities.
[database migrations]: https://edgeguides.rubyonrails.org/active_record_migrations.html#running-migrations
[reversible]: https://edgeguides.rubyonrails.org/active_record_migrations.html#making-the-irreversible-possible
MARKDOWN
end

def prerequisites
heading "Prerequisites", level: 2

@file.write <<~MARKDOWN
Ruby: `#{Suspenders::MINIMUM_RUBY_VERSION}`
Node: `#{Suspenders::NODE_LTS_VERSION}`
MARKDOWN

new_line
end
end
end
end
5 changes: 5 additions & 0 deletions lib/tasks/suspenders.rake
Original file line number Diff line number Diff line change
Expand Up @@ -28,5 +28,10 @@ namespace :suspenders do
task :organize_gemfile do
Suspenders::Cleanup::OrganizeGemfile.perform(Rails.root.join("Gemfile"))
end

desc "Generate README"
task :generate_readme do
Suspenders::Cleanup::GenerateReadme.perform(Rails.root.join("README.md"), Rails.application.class.module_parent_name)
end
end
end
2 changes: 1 addition & 1 deletion test/generators/suspenders/accessibility_generator_test.rb
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,7 @@ class AccessibilityGeneratorTest < Rails::Generators::TestCase
test "generator has a description" do
description = "Installs capybara_accessibility_audit and capybara_accessible_selectors"

assert_equal description, Suspenders::Generators::AccessibilityGenerator.desc
assert_match description, Suspenders::Generators::AccessibilityGenerator.desc
end

private
Expand Down
2 changes: 1 addition & 1 deletion test/generators/suspenders/inline_svg_generator_test.rb
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,7 @@ class InlinveSvgGeneratorTest < Rails::Generators::TestCase
test "generator has a description" do
description = "Render SVG images inline, as a potential performance improvement for the viewer."

assert_equal description, Suspenders::Generators::InlineSvgGenerator.desc
assert_match description, Suspenders::Generators::InlineSvgGenerator.desc
end

test "configures raising an error when an SVG file is not found" do
Expand Down
2 changes: 1 addition & 1 deletion test/generators/suspenders/jobs_generator_test.rb
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ class JobsGeneratorTest < Rails::Generators::TestCase
test "generator has a description" do
description = "Installs Sidekiq for background job processing."

assert_equal description, Suspenders::Generators::JobsGenerator.desc
assert_match description, Suspenders::Generators::JobsGenerator.desc
end

test "configures ActiveJob logging" do
Expand Down
Loading

0 comments on commit 08be1dd

Please sign in to comment.