-
-
Notifications
You must be signed in to change notification settings - Fork 529
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Introduce
suspenders:cleanup:organize_gemfile
task (#1181)
Introduce `Suspenders::Cleanup::OrganizeGemfile` class and corresponding task in an effort to reduce duplicate groups in the modified Gemfile. This is because the [gem_group][] method does not modify existing groups. I've opened [#49512][] in an effort to fix this, but until then, this task will suffice. This class is designed to be run after `suspenders:install:web`, and does not account for all edge cases. For example, it assumes gems are grouped by symbols (i.e. :test and not "test"), and does not account for inline syntax: ```ruby gem 'my-gem', group: [:cucumber, :test] ``` We could consider extracting this into a Gem (with a fun name, of course. Maybe "Polish"), but for now, I think this simple procedural code if just fine. Additionally, this commit removes duplicate Rake task that was generated with the plugin. [gem_group]: https://api.rubyonrails.org/classes/Rails/Generators/Actions.html#method-i-gem_group [#49512]: rails/rails#49512
- Loading branch information
1 parent
f76fb25
commit f6c6f45
Showing
9 changed files
with
353 additions
and
4 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
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,134 @@ | ||
module Suspenders | ||
module Cleanup | ||
class OrganizeGemfile | ||
def self.perform(gemfile) | ||
new(gemfile).perform | ||
end | ||
|
||
attr_reader :gemfile, :current_lines, :new_lines, :new_line_markers, | ||
:current_group, :gem_groups | ||
|
||
def initialize(gemfile) | ||
@gemfile = gemfile | ||
|
||
@current_lines = File.read(gemfile).lines | ||
@new_lines = [] | ||
@new_line_markers = [] | ||
|
||
@current_group = nil | ||
@gem_groups = {} | ||
end | ||
|
||
def perform | ||
remove_line_breaks | ||
sort_gems_and_groups | ||
add_gem_groups_to_gemfile | ||
add_line_breaks | ||
cleanup | ||
|
||
File.open(gemfile, "w+") { _1.write new_lines.join } | ||
end | ||
|
||
private | ||
|
||
def remove_line_breaks | ||
current_lines.delete("\n") | ||
end | ||
|
||
def sort_gems_and_groups | ||
current_lines.each do |line| | ||
if line.starts_with?(/group/) | ||
@current_group = line | ||
end | ||
|
||
# Consolidate gem groups | ||
if current_group | ||
if line.starts_with?(/end/) | ||
@current_group = nil | ||
elsif !line.starts_with?(/group/) | ||
gem_groups[current_group] ||= [] | ||
gem_groups[current_group] << line | ||
end | ||
# Add non-grouped gems | ||
elsif !line.starts_with?(/\n/) | ||
new_lines << line | ||
@current_group = nil | ||
end | ||
end | ||
end | ||
|
||
def add_gem_groups_to_gemfile | ||
gem_groups.keys.each do |group| | ||
gems = gem_groups[group] | ||
|
||
gems.each_with_index do |gem, index| | ||
if index == 0 | ||
new_lines << group | ||
end | ||
|
||
new_lines << gem | ||
|
||
if gems.size == (index + 1) | ||
new_lines << "end\n" | ||
end | ||
end | ||
end | ||
end | ||
|
||
def add_line_breaks | ||
new_lines.each_with_index do |line, index| | ||
previous_line = new_lines[index - 1] if index > 0 | ||
next_line = new_lines[index + 1] | ||
marker = index + 1 | ||
|
||
# Add line break if it's a gem and the next line is commented out | ||
if (line.starts_with?(/\s*gem/) || line.starts_with?(/\s*\#\s*gem/)) && next_line&.starts_with?(/\s*\#/) | ||
new_line_markers << marker | ||
end | ||
|
||
# Add line break if it's a commented out gem and the next line is a gem | ||
if line.starts_with?(/\s*\#\s*gem/) && next_line&.starts_with?(/\s*gem/) | ||
new_line_markers << marker | ||
end | ||
|
||
# Add line break if it's a gem with a comment and the next line is a gem | ||
if previous_line&.starts_with?(/\s*\#/) \ | ||
&& line.starts_with?(/\s*gem/) \ | ||
&& next_line&.starts_with?(/\s*gem/) \ | ||
&& !previous_line.starts_with?(/\s*\#\s*gem/) | ||
new_line_markers << marker | ||
end | ||
|
||
# Add a line break if it's /end/ | ||
if line.starts_with?(/end/) | ||
new_line_markers << marker | ||
end | ||
|
||
# Add a line break if it's a gem and the next line is a group | ||
if line.starts_with?(/gem/) && next_line&.starts_with?(/group/) | ||
new_line_markers << marker | ||
end | ||
|
||
# Add line break if it's /source/ or /ruby/ | ||
if line.starts_with?(/\w/) && !line.starts_with?(/\s*(gem|group|end)/) | ||
new_line_markers << marker | ||
end | ||
end | ||
|
||
new_line_markers.each_with_index do |marker, index| | ||
# Each time we insert, the original marker if off by 1 | ||
marker_offset = marker + index | ||
|
||
new_lines.insert(marker_offset, "\n") | ||
end | ||
end | ||
|
||
def cleanup | ||
# Remove last line | ||
if /\n/.match?(new_lines.last) | ||
new_lines.pop | ||
end | ||
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 was deleted.
Oops, something went wrong.
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,85 @@ | ||
source "https://rubygems.org" | ||
|
||
ruby "3.3.0" | ||
|
||
# Bundle edge Rails instead: gem "rails", github: "rails/rails", branch: "main" | ||
gem "rails", "~> 7.1.3", ">= 7.1.3.2" | ||
|
||
# The original asset pipeline for Rails [https://github.com/rails/sprockets-rails] | ||
gem "sprockets-rails" | ||
|
||
# Use postgresql as the database for Active Record | ||
gem "pg", "~> 1.1" | ||
|
||
# Use the Puma web server [https://github.com/puma/puma] | ||
gem "puma", ">= 5.0" | ||
|
||
# Use JavaScript with ESM import maps [https://github.com/rails/importmap-rails] | ||
gem "importmap-rails" | ||
|
||
# Hotwire's SPA-like page accelerator [https://turbo.hotwired.dev] | ||
gem "turbo-rails" | ||
|
||
# Hotwire's modest JavaScript framework [https://stimulus.hotwired.dev] | ||
gem "stimulus-rails" | ||
|
||
# Build JSON APIs with ease [https://github.com/rails/jbuilder] | ||
gem "jbuilder" | ||
|
||
# Use Redis adapter to run Action Cable in production | ||
gem "redis", ">= 4.0.1" | ||
|
||
# Use Kredis to get higher-level data types in Redis [https://github.com/rails/kredis] | ||
# gem "kredis" | ||
|
||
# Use Active Model has_secure_password [https://guides.rubyonrails.org/active_model_basics.html#securepassword] | ||
# gem "bcrypt", "~> 3.1.7" | ||
|
||
# Windows does not include zoneinfo files, so bundle the tzinfo-data gem | ||
gem "tzinfo-data", platforms: %i[windows jruby] | ||
|
||
# Reduces boot times through caching; required in config/boot.rb | ||
gem "bootsnap", require: false | ||
|
||
# Use Active Storage variants [https://guides.rubyonrails.org/active_storage_overview.html#transforming-images] | ||
# gem "image_processing", "~> 1.2" | ||
|
||
gem "cssbundling-rails" | ||
gem "inline_svg" | ||
gem "sidekiq" | ||
gem "title" | ||
|
||
group :development, :test do | ||
# See https://guides.rubyonrails.org/debugging_rails_applications.html#debugging-with-the-debug-gem | ||
gem "debug", platforms: %i[mri windows] | ||
|
||
gem "suspenders", github: "thoughtbot/suspenders", branch: "suspenders-3-0-0-web-generator" | ||
gem "bundler-audit", ">= 0.7.0", require: false | ||
gem "factory_bot_rails" | ||
gem "rspec-rails", "~> 6.1.0" | ||
gem "better_html", require: false | ||
gem "erb_lint", require: false | ||
gem "erblint-github", require: false | ||
gem "standard" | ||
end | ||
|
||
group :development do | ||
# Use console on exceptions pages [https://github.com/rails/web-console] | ||
gem "web-console" | ||
|
||
# Add speed badges [https://github.com/MiniProfiler/rack-mini-profiler] | ||
# gem "rack-mini-profiler" | ||
|
||
# Speed up commands on slow machines / big apps [https://github.com/rails/spring] | ||
# gem "spring" | ||
end | ||
|
||
group :test do | ||
gem "capybara_accessibility_audit" | ||
gem "capybara_accessible_selectors", github: "citizensadvice/capybara_accessible_selectors" | ||
gem "capybara" | ||
gem "action_dispatch-testing-integration-capybara", github: "thoughtbot/action_dispatch-testing-integration-capybara", tag: "v0.1.1", require: "action_dispatch/testing/integration/capybara/rspec" | ||
gem "selenium-webdriver" | ||
gem "shoulda-matchers", "~> 6.0" | ||
gem "webmock" | ||
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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,101 @@ | ||
source "https://rubygems.org" | ||
|
||
ruby "3.3.0" | ||
|
||
# Bundle edge Rails instead: gem "rails", github: "rails/rails", branch: "main" | ||
gem "rails", "~> 7.1.3", ">= 7.1.3.2" | ||
|
||
# The original asset pipeline for Rails [https://github.com/rails/sprockets-rails] | ||
gem "sprockets-rails" | ||
|
||
# Use postgresql as the database for Active Record | ||
gem "pg", "~> 1.1" | ||
|
||
# Use the Puma web server [https://github.com/puma/puma] | ||
gem "puma", ">= 5.0" | ||
|
||
# Use JavaScript with ESM import maps [https://github.com/rails/importmap-rails] | ||
gem "importmap-rails" | ||
|
||
# Hotwire's SPA-like page accelerator [https://turbo.hotwired.dev] | ||
gem "turbo-rails" | ||
|
||
# Hotwire's modest JavaScript framework [https://stimulus.hotwired.dev] | ||
gem "stimulus-rails" | ||
|
||
# Build JSON APIs with ease [https://github.com/rails/jbuilder] | ||
gem "jbuilder" | ||
|
||
# Use Redis adapter to run Action Cable in production | ||
gem "redis", ">= 4.0.1" | ||
|
||
# Use Kredis to get higher-level data types in Redis [https://github.com/rails/kredis] | ||
# gem "kredis" | ||
|
||
# Use Active Model has_secure_password [https://guides.rubyonrails.org/active_model_basics.html#securepassword] | ||
# gem "bcrypt", "~> 3.1.7" | ||
|
||
# Windows does not include zoneinfo files, so bundle the tzinfo-data gem | ||
gem "tzinfo-data", platforms: %i[windows jruby] | ||
|
||
# Reduces boot times through caching; required in config/boot.rb | ||
gem "bootsnap", require: false | ||
|
||
# Use Active Storage variants [https://guides.rubyonrails.org/active_storage_overview.html#transforming-images] | ||
# gem "image_processing", "~> 1.2" | ||
|
||
group :development, :test do | ||
# See https://guides.rubyonrails.org/debugging_rails_applications.html#debugging-with-the-debug-gem | ||
gem "debug", platforms: %i[mri windows] | ||
end | ||
|
||
group :development do | ||
# Use console on exceptions pages [https://github.com/rails/web-console] | ||
gem "web-console" | ||
|
||
# Add speed badges [https://github.com/MiniProfiler/rack-mini-profiler] | ||
# gem "rack-mini-profiler" | ||
|
||
# Speed up commands on slow machines / big apps [https://github.com/rails/spring] | ||
# gem "spring" | ||
end | ||
|
||
group :development, :test do | ||
gem "suspenders", github: "thoughtbot/suspenders", branch: "suspenders-3-0-0-web-generator" | ||
end | ||
|
||
group :test do | ||
gem "capybara_accessibility_audit" | ||
gem "capybara_accessible_selectors", github: "citizensadvice/capybara_accessible_selectors" | ||
end | ||
gem "cssbundling-rails" | ||
|
||
group :development, :test do | ||
gem "bundler-audit", ">= 0.7.0", require: false | ||
end | ||
gem "inline_svg" | ||
|
||
group :development, :test do | ||
gem "factory_bot_rails" | ||
end | ||
gem "sidekiq" | ||
gem "title" | ||
|
||
group :development, :test do | ||
gem "rspec-rails", "~> 6.1.0" | ||
end | ||
|
||
group :test do | ||
gem "capybara" | ||
gem "action_dispatch-testing-integration-capybara", github: "thoughtbot/action_dispatch-testing-integration-capybara", tag: "v0.1.1", require: "action_dispatch/testing/integration/capybara/rspec" | ||
gem "selenium-webdriver" | ||
gem "shoulda-matchers", "~> 6.0" | ||
gem "webmock" | ||
end | ||
|
||
group :development, :test do | ||
gem "better_html", require: false | ||
gem "erb_lint", require: false | ||
gem "erblint-github", require: false | ||
gem "standard" | ||
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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,23 @@ | ||
require "test_helper" | ||
require "tempfile" | ||
require_relative "../../../lib/suspenders/cleanup/organize_gemfile" | ||
|
||
module Suspenders | ||
module Cleanup | ||
class OrganizeGemfileTest < ActiveSupport::TestCase | ||
test "organizes Gemfile by group" do | ||
original = file_fixture("gemfile_messy").read | ||
modified = file_fixture("gemfile_clean").read | ||
|
||
Tempfile.create "Gemfile" do |gemfile| | ||
gemfile.write original | ||
gemfile.rewind | ||
|
||
Suspenders::Cleanup::OrganizeGemfile.perform(gemfile.path) | ||
|
||
assert_equal modified, gemfile.read | ||
end | ||
end | ||
end | ||
end | ||
end |