-
-
Notifications
You must be signed in to change notification settings - Fork 530
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Introduce
suspenders:styles
generator (#1145)
Configures applications to use [PostCSS][1] or [Tailwind][2] via [cssbundling-rails][3]. Defaults to `PostCSS` with [modern-normalize][8], with the option to override via `--css=tailwind`. These options were pulled from the [supported list of options][4] in Rails. Also creates additional stylesheets if using PostCSS. We choose to use [cssbundling-rails][4] instead of [dartsass-rails][5] or [tailwindcss-rails][6] (or even just css) because we want to rely on Node to process the CSS. Although we could have chosen to avoid using Node altogether, we feel it's better to support it since we'll need it for additional generators, like [StyleLintGenerator][7], and to support [modern-normalize][8]. Updates `within_api_only_app` by allowing support to conditionally comment out the api configuration. This provided and opportunity to clean up existing setup steps. [1]: https://postcss.org [2]: https://tailwindcss.com [3]: https://github.com/rails/cssbundling-rails [4]: https://github.com/rails/rails/blob/438cad462638b02210fc48b700c29dcd0428a8b7/railties/lib/rails/generators/app_base.rb#L22 [5]: https://github.com/rails/dartsass-rails [6]: https://github.com/rails/tailwindcss-rails [7]: https://github.com/thoughtbot/suspenders/blob/main/lib/suspenders/generators/stylelint_generator.rb [8]: https://github.com/sindresorhus/modern-normalize [9]: https://tailwindcss.com/docs/functions-and-directives#layer
- Loading branch information
1 parent
f1960f1
commit d8cf034
Showing
7 changed files
with
304 additions
and
14 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,60 @@ | ||
module Suspenders | ||
module Generators | ||
class StylesGenerator < Rails::Generators::Base | ||
include Suspenders::Generators::APIAppUnsupported | ||
|
||
CSS_OPTIONS = %w[tailwind postcss].freeze | ||
|
||
class_option :css, enum: CSS_OPTIONS, default: "postcss" | ||
desc <<~TEXT | ||
Configures applications to use PostCSS or Tailwind via cssbundling-rails. | ||
Defaults to PostCSS with modern-normalize, with the option to override via | ||
--css=tailwind. | ||
Also creates a directory structure to store additional stylesheets if using | ||
PostCSS. | ||
TEXT | ||
|
||
def add_cssbundling_rails_gem | ||
gem "cssbundling-rails" | ||
|
||
Bundler.with_unbundled_env { run "bundle install" } | ||
run "bin/rails css:install:#{css}" | ||
end | ||
|
||
def build_directory_structure | ||
return if is_tailwind? | ||
|
||
create_file "app/assets/stylesheets/base.css" | ||
create_file "app/assets/stylesheets/components.css" | ||
create_file "app/assets/stylesheets/utilities.css" | ||
end | ||
|
||
# Modify if https://github.com/rails/cssbundling-rails/pull/139 is merged | ||
def configure_application_stylesheet | ||
return if is_tailwind? | ||
|
||
run "yarn add modern-normalize" | ||
|
||
append_to_file "app/assets/stylesheets/application.postcss.css" do | ||
<<~TEXT | ||
@import "modern-normalize"; | ||
@import "base.css"; | ||
@import "components.css"; | ||
@import "utilities.css"; | ||
TEXT | ||
end | ||
end | ||
|
||
private | ||
|
||
def css | ||
@css ||= options["css"] | ||
end | ||
|
||
def is_tailwind? | ||
css == "tailwind" | ||
end | ||
end | ||
end | ||
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,213 @@ | ||
require "test_helper" | ||
require "generators/suspenders/styles_generator" | ||
|
||
module Suspenders | ||
module Generators | ||
class StylesGenerator::DefaultTest < Rails::Generators::TestCase | ||
include Suspenders::TestHelpers | ||
|
||
tests Suspenders::Generators::StylesGenerator | ||
destination Rails.root | ||
setup :prepare_destination | ||
teardown :restore_destination | ||
|
||
test "raises if API only application" do | ||
within_api_only_app do | ||
assert_raises Suspenders::Generators::APIAppUnsupported::Error do | ||
run_generator | ||
end | ||
end | ||
end | ||
|
||
test "does not raise if API configuration is commented out" do | ||
within_api_only_app(commented_out: true) do | ||
run_generator | ||
end | ||
end | ||
|
||
test "adds gems to Gemfile" do | ||
run_generator | ||
|
||
assert_file app_root("Gemfile") do |file| | ||
assert_match "cssbundling-rails", file | ||
end | ||
end | ||
|
||
test "installs gems with Bundler" do | ||
output = run_generator | ||
|
||
assert_match(/bundle install/, output) | ||
end | ||
|
||
test "runs install script" do | ||
output = run_generator | ||
|
||
assert_match(/bin\/rails css:install:postcss/, output) | ||
end | ||
|
||
test "generator has a description" do | ||
description = <<~TEXT | ||
Configures applications to use PostCSS or Tailwind via cssbundling-rails. | ||
Defaults to PostCSS with modern-normalize, with the option to override via | ||
--css=tailwind. | ||
Also creates a directory structure to store additional stylesheets if using | ||
PostCSS. | ||
TEXT | ||
|
||
assert_equal description, generator_class.desc | ||
end | ||
|
||
private | ||
|
||
def prepare_destination | ||
touch "Gemfile" | ||
touch "app/assets/stylesheets/application.postcss.css" | ||
end | ||
|
||
def restore_destination | ||
remove_file_if_exists "Gemfile" | ||
remove_file_if_exists "package.json", root: true | ||
remove_file_if_exists "yarn.lock", root: true | ||
remove_file_if_exists "app/assets/stylesheets/application.postcss.css" | ||
remove_file_if_exists "app/assets/stylesheets/base.css" | ||
remove_file_if_exists "app/assets/stylesheets/components.css" | ||
remove_file_if_exists "app/assets/stylesheets/utilities.css" | ||
end | ||
end | ||
|
||
class StylesGenerator::ClassOptionTest < Rails::Generators::TestCase | ||
include Suspenders::TestHelpers | ||
|
||
tests Suspenders::Generators::StylesGenerator | ||
destination Rails.root | ||
setup :prepare_destination | ||
teardown :restore_destination | ||
|
||
test "has a css option" do | ||
option = generator_class.class_options[:css] | ||
|
||
assert_equal :string, option.type | ||
assert_not option.required | ||
assert_equal %w[tailwind postcss], option.enum | ||
assert_equal "postcss", option.default | ||
end | ||
|
||
test "raises if css option is unsupported" do | ||
output = capture(:stderr) { run_generator %w[--css=unknown] } | ||
|
||
assert_match(/Expected '--css' to be one of/, output) | ||
end | ||
|
||
private | ||
|
||
def prepare_destination | ||
touch "Gemfile" | ||
end | ||
|
||
def restore_destination | ||
remove_file_if_exists "Gemfile" | ||
remove_file_if_exists "package.json", root: true | ||
remove_file_if_exists "yarn.lock", root: true | ||
remove_file_if_exists "app/assets/stylesheets/application.postcss.css" | ||
remove_file_if_exists "app/assets/stylesheets/base.css" | ||
remove_file_if_exists "app/assets/stylesheets/components.css" | ||
remove_file_if_exists "app/assets/stylesheets/utilities.css" | ||
end | ||
end | ||
|
||
class StylesGenerator::TailwindTest < Rails::Generators::TestCase | ||
include Suspenders::TestHelpers | ||
|
||
tests Suspenders::Generators::StylesGenerator | ||
destination Rails.root | ||
setup :prepare_destination | ||
teardown :restore_destination | ||
|
||
test "runs install script" do | ||
output = run_generator %w[--css=tailwind] | ||
|
||
assert_match(/bin\/rails css:install:tailwind/, output) | ||
end | ||
|
||
test "does not install normalize" do | ||
output = run_generator %w[--css=tailwind] | ||
|
||
assert_no_match(/add.*modern-normalize/, output) | ||
end | ||
|
||
test "does not create directory structure" do | ||
run_generator %w[--css=tailwind] | ||
|
||
assert_no_file app_root("app/assets/stylesheets/base.css") | ||
assert_no_file app_root("app/assets/stylesheets/components.css") | ||
assert_no_file app_root("app/assets/stylesheets/utilities.css") | ||
end | ||
|
||
private | ||
|
||
def prepare_destination | ||
touch "Gemfile" | ||
end | ||
|
||
def restore_destination | ||
remove_file_if_exists "Gemfile" | ||
remove_file_if_exists "package.json", root: true | ||
remove_file_if_exists "yarn.lock", root: true | ||
remove_file_if_exists "app/assets/stylesheets/base.css" | ||
remove_file_if_exists "app/assets/stylesheets/components.css" | ||
remove_file_if_exists "app/assets/stylesheets/utilities.css" | ||
end | ||
end | ||
|
||
class StylesGenerator::PostCssTest < Rails::Generators::TestCase | ||
include Suspenders::TestHelpers | ||
|
||
tests Suspenders::Generators::StylesGenerator | ||
destination Rails.root | ||
setup :prepare_destination | ||
teardown :restore_destination | ||
|
||
test "installs normalize and imports style sheets" do | ||
output = run_generator %w[--css=postcss] | ||
application_stylesheet = <<~TEXT | ||
@import "modern-normalize"; | ||
@import "base.css"; | ||
@import "components.css"; | ||
@import "utilities.css"; | ||
TEXT | ||
|
||
assert_match(/add.*modern-normalize/, output) | ||
|
||
assert_file app_root("app/assets/stylesheets/application.postcss.css") do |file| | ||
assert_equal application_stylesheet, file | ||
end | ||
end | ||
|
||
test "creates directory structure" do | ||
run_generator | ||
|
||
assert_file app_root("app/assets/stylesheets/base.css") | ||
assert_file app_root("app/assets/stylesheets/components.css") | ||
assert_file app_root("app/assets/stylesheets/utilities.css") | ||
end | ||
|
||
private | ||
|
||
def prepare_destination | ||
touch "Gemfile" | ||
touch "app/assets/stylesheets/application.postcss.css" | ||
end | ||
|
||
def restore_destination | ||
remove_file_if_exists "Gemfile" | ||
remove_file_if_exists "package.json", root: true | ||
remove_file_if_exists "yarn.lock", root: true | ||
remove_file_if_exists "app/assets/stylesheets/application.postcss.css" | ||
remove_file_if_exists "app/assets/stylesheets/base.css" | ||
remove_file_if_exists "app/assets/stylesheets/components.css" | ||
remove_file_if_exists "app/assets/stylesheets/utilities.css" | ||
end | ||
end | ||
end | ||
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters