-
Notifications
You must be signed in to change notification settings - Fork 1
/
template_v5_rspec_dev_tools.rb
274 lines (216 loc) · 9.96 KB
/
template_v5_rspec_dev_tools.rb
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
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
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
require 'pry-byebug'
# For Rails 4.x, 5.x
# Style Note: using "sqiggly" heredocs for proper indentation of file contents: http://ruby-doc.org/core-2.3.0/doc/syntax/literals_rdoc.html#label-Here+Documents
# Updates AppGenerator, provides helper methods
class Rails::Generators::AppGenerator
def add_bootstrap_with_query
return unless yes?("Would you like to install bootstrap-sass? (y/n)")
add_gem 'bootstrap-sass' do
unless File.exists?('app/assets/stylesheets/application.scss')
run 'mv app/assets/stylesheets/application.css app/assets/stylesheets/application.scss'
end
app_stylesheet_file_contents = <<~FILE_CONTENTS
// "bootstrap-sprockets" must be imported before "bootstrap" and "bootstrap/variables"
@import "bootstrap-sprockets";
@import "bootstrap";
// TODO: we recommend converting any `*=require...` statements to @import
FILE_CONTENTS
append_to_file('app/assets/stylesheets/application.scss',app_stylesheet_file_contents)
app_javascript_file_contents = <<~FILE_CONTENTS
fail("TODO: Move `require bootstrap-sprockets` just after jquery")
//= require bootstrap-sprockets
FILE_CONTENTS
append_to_file('app/assets/javascripts/application.js', app_javascript_file_contents)
end
add_gem 'simple_form', {}, 'simple_form:install --bootstrap'
add_gem 'bh' # bootstrap helpers
end
def add_capistrano_with_query
return unless yes?("Would you like to install capistrano? (y/n)")
add_gem 'capistrano-rails' do
git_commit('capistrano: Install/generate files.') do
run 'bundle exec cap install' # capistrano's "generator"
end
git_commit('capistrano: configure for rails') do
capfile_rails_contents = <<~FILE_CONTENTS
# Require everything for rails (bundler, rails/assets, and rails/migrations)
require 'capistrano/rails'
# Or require just what you need
FILE_CONTENTS
inject_into_file 'Capfile', before: "# require 'capistrano/rvm'" do
capfile_rails_contents
end
inject_into_file 'config/deploy.rb', after: /# ask .branch/ do
%(set :branch, ENV['BRANCH'] || :master)
end
end
end
if yes?("Will you deploy to passenger? (y/n)")
add_gem('capistrano-passenger') do
uncomment_lines 'Capfile', %r(require 'capistrano/passenger)
end
end
end
def add_database_cleaner
add_gem 'database_cleaner', { require: false, group: non_production_groups } do
# enclose heredoc marker in single tics to delay string interpolation until file is processed
seed_file_contents = <<~'FILE_CONTENTS'
require 'database_cleaner'
unless ENV['FORCE_SEED'] || Rails.env.development? || Rails.env.test?
fail "Safety net: If you really want to seed the '#{Rails.env}' database, use FORCE_SEED=true"
end
puts "Cleaning db, via truncation..."
do_not_truncate = %w[] # add tables to ignore, e.g. users
DatabaseCleaner.clean_with :truncation, :except => do_not_truncate
FILE_CONTENTS
append_to_file('db/seeds.rb', seed_file_contents)
end
end
def add_devise_with_query
return unless yes?("Would you like to install Devise? (y/n)")
git_commit('devise: Install/configure environment.') do
gem "devise"
generate "devise:install"
# follow devise configuration instructions
environment %q(default_url_options = ENV.fetch('default_url_options', {host: 'localhost', port: 3000})), env: 'development'
environment %q(config.action_mailer.default_url_options = default_url_options), env: 'development'
environment %q(fail("TODO: Configure default_url_options.")), env: 'production'
environment %q(config.action_mailer.default_url_options = {host: "http://yourwebsite.example.com"}), env: 'production'
route "#TODO: set root route (required by Devise)"
route "root to: 'home#index' # req'd by devise"
# enclose heredoc marker in single tics to delay string interpolation until file is processed
flash_messages_file_contents = <<~'FILE_CONTENTS'
- fail("TODO: render this partial in app/views/layouts/application.html.haml")
-# TODO: update for bootstrap, dismissable
-# An example: https://gist.github.com/roberto/3344628
%section#flashMessages.row
-flash.each do |key, value|
%p.flash{class: "alert-#{key}"}= value
FILE_CONTENTS
file 'app/views/layouts/_flash_messages.html.haml', flash_messages_file_contents
end
model_name = ask('What would you like the user model to be called? [User]')
model_name = 'User' if model_name.blank?
git_commit("devise: configure for #{model_name}") do
generate 'devise', model_name
rails_command 'db:migrate'
end
end
# adds AND commits the gem, including generator commands
def add_gem(gem_name, gem_options={}, generator_command=nil, &block)
message = "Installed"
gem gem_name, gem_options
run_install
if generator_command || block_given?
message += ' and configured.'
end
if generator_command
message += "\n\n- #{generator_command}"
generate generator_command
end
yield if block_given?
git add: "."
git commit: %Q{ -m "#{gem_name}: #{message}" }
end
# asks if user wants to install the gem
def add_gem_with_query(gem_name, gem_options={}, generator_command=nil, &block)
if yes?("Would you like to install #{gem_name}? (y/n)")
add_gem(gem_name, gem_options, generator_command, &block)
end
end
def app_name
File.dirname(__FILE__)
end
def append_to_readme(message)
append_to_file 'README.md', message
end
# "block" version of git commit.
# Groups changes under the message describing the change.
def git_commit(message)
yield
git add: '.'
git commit: %{ -m #{message.inspect} }
end
def non_production_groups
[:development, :test]
end
def run_install
run 'bundle install --quiet --retry=3'
end
# generate, configure, and commit
def setup(gem_name, generator_command)
message = "#{gem_name}: $ rails #{generator_command}"
generate generator_command
yield if block_given?
git add: "."
git commit: %Q{ -m "#{message}" }
end
end
git :init
run_install
rails_command 'db:setup'
git add: "."
message = "Initial commit. Generated app. Setup database (create, migrate, seed)."
message += "\n- $ rails #{ARGV.join(' ')}"
git commit: %Q(-m "#{message}")
## Spec Tools
append_to_readme "\n\n## Specs"
add_gem 'rspec-rails', { group: non_production_groups }, 'rspec:install' do
append_to_file('spec/spec_helper.rb', 'fail("TODO: Uncomment the suggested configuration items.")')
append_to_readme("\n- `$ rspec`, see: https://github.com/rspec/rspec-rails")
end
add_database_cleaner
add_gem 'factory_bot_rails', { require: false, group: non_production_groups } do
append_to_readme("\n- Factory Bot ♥ Rails, see: [Getting Started](https://github.com/thoughtbot/factory_bot/blob/master/GETTING_STARTED.md)")
end
add_gem 'faker', { require: false, group: non_production_groups } do
append_to_readme("\n- [Faker](https://github.com/stympy/faker): generate fake data such as names, addresses, and BossaNova artists.")
end
append_to_readme "\n\n## Debugging"
add_gem 'pry-byebug', { platform: :mri, group: non_production_groups } do
# Call 'debug', 'byebug', or 'binding.pry' anywhere in the code to stop execution and get a debugger console
append_to_readme("\n- Both pry and debugger are supported (via pry-byebug).\n- add `debugger` or `binding.pry`")
end
add_gem 'pry-rails', { platform: :mri, group: non_production_groups } # Rails >= 3 pry initializer (enables 'reload!' and more!)
add_gem 'haml-rails', {}, 'haml:application_layout' do
run "rm 'app/views/layouts/application.html.erb'"
end
add_gem 'figaro' do
run 'bundle exec figaro install'
append_to_readme("\n\n## Configured via [Figaro](https://github.com/laserlemon/figaro)\n- see `config/application.yml`")
end
add_gem 'rack-heartbeat' do
# provides heartbeat endpoint w/o rails render stack.
append_to_readme("\n\n## Monitoring\n- Use `/heartbeat` for app monitoring services.\n- via [rack-heartbeat](https://github.com/imajes/rack-heartbeat)")
end
add_gem 'awesome_print', { require: false, group: non_production_groups } # pretty formatting in rails console
## >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
## Begin optional gems
append_to_readme "\n\n## Optional gems"
add_bootstrap_with_query
add_capistrano_with_query
add_devise_with_query
add_gem_with_query 'guard-rspec', { require: false, group: :development } do
run `bundle exec guard init rspec`
append_to_readme("\n- Autospec with `$ guard`")
end
add_gem_with_query 'blazer', { group: :development } do
run `rails g blazer:install && rake db:migrate`
# append_to_file('spec/spec_helper.rb', 'fail("TODO: Uncomment the suggested configuration items.")')
append_to_file('config/routes.rb', 'fail("TODO: move the `mount Blazer...` code.")')
append_to_file('config/routes.rb', 'mount Blazer::Engine, at: "blazer"')
append_to_readme("\n- [Blazer](https://github.com/ankane/blazer) is a database query tool, available at `/blazer`.")
end
add_gem_with_query 'whenever', { require: false } do # manages cron
run `wheneverize .`
append_to_readme("\n\n## Cron\n\n- managed by whenever gem via `config/schedule.rb`.\n- see: https://github.com/javan/whenever")
end
add_gem_with_query 'meta_request', { group: non_production_groups} do # supports a Chrome extension for Rails development
append_to_readme("\n\n## Debugging\n\n- meta_request works with rails_panel to provide a tab in Chrome Dev Tools (https://github.com/dejan/rails_panel).")
end
add_gem_with_query 'sandi_meter', { require: false, group: non_production_groups } # Sandi Metz' rules
after_bundle do
git add: "."
git commit: %Q{ -m "Last template commit. spring binstubs\n\n- $ bundle exec spring binstub --all" }
append_to_file 'Gemfile', "\n\nfail 'TODO: Regorganize and sort this generated Gemfile.'"
end