Class: HotGlue::InstallGenerator

Inherits:
Rails::Generators::Base
  • Object
show all
Defined in:
lib/generators/hot_glue/install_generator.rb

Instance Method Summary collapse

Constructor Details

#initialize(*args) ⇒ InstallGenerator

Returns a new instance of InstallGenerator.

Signature:

  • nodoc:



22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
# File 'lib/generators/hot_glue/install_generator.rb', line 22

def initialize(*args) #:nodoc:
  super
  layout = options['layout'] || "hotglue"
  @theme =  options['theme']
  if layout == "hotglue" && options['theme'].nil?
    puts "You have selected to install Hot Glue without a theme. You can either use the --layout=bootstrap to install NO HOT GLUE THEME, or to use a Hot Glue theme please choose: like_boostrap, like_menlo_park, like_cupertino, like_mountain_view, dark_knight"
    return
  end

  if layout == 'boostrap'
    puts "IMPORTANT: You have selected to install Hot Glue with Bootstrap layout.` "
  end


  @markup = options['markup'] || "erb"
  copy_file "erb/_flash_notices.erb", "#{filepath_prefix}app/views/layouts/_flash_notices.erb"

  begin
    if Rails.version.split(".")[0].to_i == 6
      app_js_contents = File.read("app/javascript/packs/application.js")
      if app_js_contents.include?("import Turbolinks from \"turbolinks\"")
        app_js_contents.gsub!("import Turbolinks from \"turbolinks\"", "import { Turbo } from \"@hotwired/turbo-rails\"")
        puts "  HOTGLUE --> fixed packs/application.js: swapping old Turbolinks syntas for new Turbo-Rails syntax [ import { Turbo } from \"@hotwired/turbo-rails\" ] "
      end

      if app_js_contents.include?("Turbolinks.start()")
        app_js_contents.gsub!("Turbolinks.start()", "Turbo.start()")
        puts "  HOTGLUE --> fixed packs/application.js: swapping old Turbolinks syntas for new Turbo-Rails syntax[ Turbolinks.start() ] "
      end
      File.write("app/javascript/packs/application.js", app_js_contents)
    end
  rescue StandardError => e
    puts "WARNING: error writing to app/javascript/packs/application.js --- #{e.message}"
  end



  begin
    gemfile_contents = File.read("Gemfile")
    if !gemfile_contents.include?("rspec-retry")
      gemfile_contents.gsub!(/^group :test do/, "group :test do\n  gem \"rspec-retry\"")
      File.write("Gemfile", gemfile_contents)
      puts "  HOTGLUE --> added to Gemfile: `gem \"rspec-retry\"` -- run `bundle install`  "
    end
  rescue StandardError => e
    puts "WARNING: error writing to Gemfile --- #{e.message}"
  end

  begin
    rails_helper_contents = File.read("#{filepath_prefix}spec/rails_helper.rb")
    if !rails_helper_contents.include?("Capybara.default_driver =")
      rails_helper_contents << "\nCapybara.default_driver = :selenium_chrome_headless "
      puts "  HOTGLUE --> added to spec/rails_helper.rb: `Capybara.default_driver = :selenium_chrome_headless`  "
    end

    if !rails_helper_contents.include?("Capybara.default_max_wait_time")
      rails_helper_contents << "\n\n# Default of 2s is too tight for headless Chrome + Devise + Turbo page\n# renders under load, causing sporadic false-negative waits.\nCapybara.default_max_wait_time = 5\n"
      puts "  HOTGLUE --> added to spec/rails_helper.rb: `Capybara.default_max_wait_time = 5`  "
    end

    if !rails_helper_contents.include?("include FactoryBot::Syntax::Methods")
      rails_helper_contents.gsub!("RSpec.configure do |config|", "RSpec.configure do |config| \n
config.include FactoryBot::Syntax::Methods
  ")
      puts "  HOTGLUE --> added to #{filepath_prefix}spec/rails_helper.rb: `config.include FactoryBot::Syntax::Methods`  "
    end

    if !rails_helper_contents.include?("type: :system) do")
      rails_helper_contents.gsub!("RSpec.configure do |config|", "RSpec.configure do |config| \n
# spec/system specs run through ActionDispatch::SystemTestCase, which shares
# the DB connection between the test thread and the in-process Puma server
# thread. Plain :feature specs with a real Selenium driver don't get this,
# which causes intermittent \"record not visible to the server thread\"
# failures (e.g. login appearing to fail right after the user was created).
#
# We use :chrome (not Rails' :headless_chrome) because
# ActionDispatch::SystemTesting::Browser hardcodes the legacy `--headless`
# flag. Legacy headless Chrome runs a materially different rendering/input
# pipeline than real Chrome and has known bugs where a native click never
# reaches the page. `--headless=new` (Chrome 109+) doesn't have this problem.
config.before(:each, type: :system) do
  driven_by :selenium, using: :chrome, screen_size: [1366, 1200] do |options|
    options.add_argument(\"--headless=new\")
  end
end

# Real-browser system specs still hit transient, infrastructure-level
# flakiness that has nothing to do with application correctness (a click
# occasionally dropped by the browser, a Turbo navigation racing a
# Capybara content read into an error Capybara doesn't retry on its own).
# Retrying the whole example -- rather than chasing each transient error
# class individually -- is the standard fix for this. rspec-retry
# re-instantiates the example group on retry so `let`/`let!` factories
# actually re-run instead of reusing stale memoized state.
config.verbose_retry = true
config.default_retry_count = 3
config.retry_callback = proc { Capybara.reset_sessions! }
config.around(:each, type: :system) do |example|
  example.run_with_retry retry: 3
end
  ")
      puts "  HOTGLUE --> added to #{filepath_prefix}spec/rails_helper.rb: `config.before(:each, type: :system) { driven_by :selenium, using: :chrome, --headless=new }` and rspec-retry config  "
    end

    if ! rails_helper_contents.include?("require 'support/capybara_login.rb'")
      rails_helper_contents.gsub!("require 'rspec/rails'","require 'rspec/rails' \nrequire 'rspec/retry' \nrequire 'support/capybara_login.rb'")
      puts "  HOTGLUE --> added to spec/rails_helper.rb: `require 'rspec/retry'` and `require 'support/capybara_login.rb'`  "
    end
    File.write("#{filepath_prefix}spec/rails_helper.rb", rails_helper_contents)

  rescue StandardError => e
    puts "WARNING: error writing to spec/rails_helper --- #{e.message}"
  end


  begin
    application_layout_contents = File.read("app/views/layouts/application.html.erb")

    if !application_layout_contents.include?("render partial: 'layouts/flash_notices'")
      application_layout_contents.gsub!("<body>", "<body>\n
  <%= render partial: 'layouts/flash_notices' %>
  ")
      File.write("app/views/layouts/application.html.erb", application_layout_contents)
      puts "  HOTGLUE --> added to app/views/layouts/application.html.erb: `<%= render partial: 'layouts/flash_notices' %>`  "
    end
  rescue StandardError => e
    puts "WARNING: error writing to app/views/layouts/application.html.erb --- #{e.message}"
  end


  begin
    if layout == "hotglue"
      theme_location = "themes/hotglue_scaffold_#{@theme}.scss"
      theme_file = "hotglue_scaffold_#{@theme}.scss"

      copy_file theme_location, "#{filepath_prefix}app/assets/stylesheets/#{theme_file}"

      application_scss = File.read("app/assets/stylesheets/application.scss")

      if !application_scss.include?("@import '#{theme_file}';")
      application_scss << ( "\n @import '#{theme_file}'; ")
        File.write("app/assets/stylesheets/application.scss", application_scss)
        puts "  HOTGLUE --> added to app/assets/stylesheets/application.scss: @import '#{theme_file}' "
      else
        puts "  HOTGLUE --> already found theme in app/assets/stylesheets/application.scss: @import '#{theme_file}' "
      end
    end
  rescue StandardError => e
    puts "WARNING: error writing to app/assets/stylesheets/application.scss --- #{e.message}"
  end



  begin
    if !File.exist?("#{filepath_prefix}config/hot_glue.yml")
      yaml = {layout: layout,
              markup: @markup}.to_yaml
      File.write("#{filepath_prefix}config/hot_glue.yml", yaml)

    end
  rescue StandardError => e
    puts "WARNING: error writing to config/hot_glue.yml --- #{e.message}"
  end


  begin
    if !File.exist?("#{filepath_prefix}spec/support/capybara_login.rb")
      copy_file "capybara_login.rb", "#{filepath_prefix}spec/support/capybara_login.rb"
    end
  rescue StandardError => e
    puts "WARNING: error writing to #{Rails.env.test? ? 'spec/dummmy/' : ''}spec/support/capybara_login.rb --- #{e.message}"
  end

end

Instance Method Details

#filepath_prefixObject



17
18
19
# File 'lib/generators/hot_glue/install_generator.rb', line 17

def filepath_prefix
  'spec/dummy/' if $INTERNAL_SPECS
end