Skip to content

Commit

Permalink
Introduce suspenders:setup generator
Browse files Browse the repository at this point in the history
Replaces the [default setup script][] provided by Rails. The trade-off
being that the implementation is simple, but the cost is we risk
drifting from Rails. After attempting to use [gsub_file][] and
[insert_into_file][], it felt simpler to just override the file
completely.

Uses [Homebrew Bundle][] in combination with [asdf][] to install system
and tool dependencies locally.

Re-introduces [dev:prime][] to seed development data on top of [seed][]
data necessary for production.

Allow caller to wipe the database clean by setting `WIPE_DATABASE=true`
before running `bin/setup.

Additionally, we [setup the test environment][] to avoid issues with
asset compilation.

[default setup script]: https://github.com/rails/rails/blob/main/railties/lib/rails/generators/rails/app/templates/bin/setup.tt
[gsub_file]: https://rubydoc.info/gems/thor/Thor/Actions#gsub_file-instance_method
[insert_into_file]: https://rubydoc.info/gems/thor/Thor/Actions#insert_into_file-instance_method
[Homebrew Bundle]: https://github.com/Homebrew/homebrew-bundle
[asdf]: https://asdf-vm.com
[dev:prime]: https://thoughtbot.com/blog/priming-the-pump
[seed]: https://guides.rubyonrails.org/active_record_migrations.html#migrations-and-seed-data
[setup the test environment]: https://github.com/rails/rails/pull/47719/files
  • Loading branch information
stevepolitodesign committed Feb 5, 2024
1 parent 51dcd4b commit b5b4412
Show file tree
Hide file tree
Showing 7 changed files with 212 additions and 0 deletions.
1 change: 1 addition & 0 deletions NEWS.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ Unreleased
* Introduce `suspenders:lint` generator
* Introduce `suspenders:rake` generator
* Introduce `suspenders:views` generator
* Introduce `suspenders:setup` generator

20230113.0 (January, 13, 2023)

Expand Down
14 changes: 14 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -134,6 +134,20 @@ document [lang][].
[title]: https://github.com/calebhearth/title
[lang]: https://developer.mozilla.org/en-US/docs/Web/HTML/Global_attributes/lang

### Setup

A holistic setup script.

```sh
bin/setup
```

or

```sh
WIPE_DATABASE=true bin/setup
```

## Contributing

See the [CONTRIBUTING] document.
Expand Down
32 changes: 32 additions & 0 deletions lib/generators/suspenders/setup_generator.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
module Suspenders
module Generators
class SetupGenerator < Rails::Generators::Base
source_root File.expand_path("../../templates/setup", __FILE__)
desc <<~TEXT
A holistic setup script.
```sh
bin/setup
```
or
```sh
WIPE_DATABASE=true bin/setup
```
TEXT

def create_brewfile
copy_file "brewfile", "Brewfile"
end

def create_dev_prime
copy_file "dev_prime.rb", "lib/tasks/dev.rake"
end

def replace_bin_setup
copy_file "bin_setup.rb", "bin/setup", force: true
end
end
end
end
56 changes: 56 additions & 0 deletions lib/generators/templates/setup/bin_setup.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
#!/usr/bin/env ruby
require "fileutils"
require "open3"

# path to your application root.
APP_ROOT = File.expand_path("..", __dir__)

def system!(*args)
system(*args, exception: true)
end

FileUtils.chdir APP_ROOT do
if ENV["CI"].nil?
puts "\n== Installing Homebrew Bundle from Brewfile =="
system! "brew bundle"

puts "\n== Starting postgresql@15 =="
system! "brew services restart postgresql@15"

puts "\n== Starting redis =="
system! "brew services restart redis"

_, _, status = Open3.capture3("which asdf")
if status.success?
puts "== Installing tool dependecies via asdf =="
system! "asdf plugin-add nodejs https://github.com/asdf-vm/asdf-nodejs"
system! "asdf plugin-add ruby https://github.com/asdf-vm/asdf-ruby"
system! "asdf plugin-add yarn https://github.com/twuni/asdf-yarn"
system! "asdf plugin-update --all"
system! "asdf install"
end
end

puts "== Installing dependencies =="
system! "gem install bundler --conservative"
system("bundle check") || system!("bundle install")
system("yarn install --check-files") if File.exist?("package.json")

puts "\n== Preparing database and adding development seed data =="
if ENV["WIPE_DATABASE"] == true
system! "bin/rails db:reset dev:prime"
else
system! "bin/rails dev:prime"
end

# https://github.com/rails/rails/pull/47719/files
puts "\n== Setup test environment =="
system! "bin/rails test:prepare"
system! "bin/rails db:prepare"

puts "\n== Removing old logs and tempfiles =="
system! "bin/rails log:clear tmp:clear"

puts "\n== Restarting application server =="
system! "bin/rails restart"
end
9 changes: 9 additions & 0 deletions lib/generators/templates/setup/brewfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
# https://formulae.brew.sh/formula/vips
brew "vips"

# https://formulae.brew.sh/formula/redis
brew "redis"

# https://formulae.brew.sh/formula/postgresql@15
# Change version to match production
brew "postgresql@15"
12 changes: 12 additions & 0 deletions lib/generators/templates/setup/dev_prime.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
if Rails.env.development? || Rails.env.test?
require "factory_bot"

namespace :dev do
desc "Sample data for local development environment"
task prime: "db:setup" do
include FactoryBot::Syntax::Methods

# create(:user, email: "[email protected]", password: "password")
end
end
end
88 changes: 88 additions & 0 deletions test/generators/suspenders/setup_generator_test.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,88 @@
require "test_helper"
require "generators/suspenders/setup_generator"

module Suspenders
module Generators
class SetupGeneratorTest < Rails::Generators::TestCase
include Suspenders::TestHelpers

tests Suspenders::Generators::SetupGenerator
destination Rails.root
setup :prepare_destination
teardown :restore_destination

test "creates Brewfile" do
expected = <<~TEXT
# https://formulae.brew.sh/formula/vips
brew "vips"
# https://formulae.brew.sh/formula/redis
brew "redis"
# https://formulae.brew.sh/formula/postgresql@15
# Change version to match production
brew "postgresql@15"
TEXT

run_generator

assert_file app_root("Brewfile") do |file|
assert_equal expected, file
end
end

test "modifies bin/setup" do
expected = bin_setup

run_generator

assert_file app_root("bin/setup") do |file|
assert_equal expected, file
end
end

test "creates dev:prime task" do
expected = <<~RUBY
if Rails.env.development? || Rails.env.test?
require "factory_bot"
namespace :dev do
desc "Sample data for local development environment"
task prime: "db:setup" do
include FactoryBot::Syntax::Methods
# create(:user, email: "[email protected]", password: "password")
end
end
end
RUBY

run_generator

assert_file app_root("lib/tasks/dev.rake") do |file|
assert_equal expected, file
end
end

test "has a custom description" do
assert_no_match /Description:/, generator_class.desc
end

private

def prepare_destination
backup_file "bin/setup"
end

def restore_destination
remove_file_if_exists "Brewfile"
restore_file "bin/setup"
remove_dir_if_exists "lib/tasks"
end

def bin_setup
File.read("./lib/generators/templates/setup/bin_setup.rb")
end
end
end
end

0 comments on commit b5b4412

Please sign in to comment.