voyage 1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (93) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +5 -0
  3. data/.ruby-version +1 -0
  4. data/.travis.yml +11 -0
  5. data/CONTRIBUTING.md +54 -0
  6. data/Gemfile +3 -0
  7. data/LICENSE +21 -0
  8. data/NEWS.md +510 -0
  9. data/README.md +233 -0
  10. data/RELEASING.md +19 -0
  11. data/Rakefile +8 -0
  12. data/USAGE +13 -0
  13. data/bin/rake +16 -0
  14. data/bin/rspec +16 -0
  15. data/bin/setup +13 -0
  16. data/bin/suspenders +23 -0
  17. data/bin/voyage +20 -0
  18. data/lib/suspenders.rb +6 -0
  19. data/lib/suspenders/actions.rb +33 -0
  20. data/lib/suspenders/adapters/heroku.rb +127 -0
  21. data/lib/suspenders/app_builder.rb +486 -0
  22. data/lib/suspenders/generators/app_generator.rb +287 -0
  23. data/lib/suspenders/generators/static_generator.rb +9 -0
  24. data/lib/suspenders/version.rb +8 -0
  25. data/lib/voyage.rb +9 -0
  26. data/lib/voyage/app_builder.rb +469 -0
  27. data/lib/voyage/generators/app_generator.rb +118 -0
  28. data/lib/voyage/templates/Gemfile.erb +118 -0
  29. data/lib/voyage/templates/README.md.erb +28 -0
  30. data/lib/voyage/templates/about.html.erb +1 -0
  31. data/lib/voyage/templates/application.js +19 -0
  32. data/lib/voyage/templates/config_locales_en.yml.erb +25 -0
  33. data/lib/voyage/templates/controller_helpers.rb +14 -0
  34. data/lib/voyage/templates/custom_cancan_matchers.rb +54 -0
  35. data/lib/voyage/templates/rails_helper.rb.erb +99 -0
  36. data/lib/voyage/templates/seeder.rb.erb +46 -0
  37. data/lib/voyage/templates/seeds.rb.erb +50 -0
  38. data/lib/voyage/templates/simplecov.rb +31 -0
  39. data/lib/voyage/templates/users_index.html.slim.erb +25 -0
  40. data/lib/voyage/templates/welcome.html.erb +11 -0
  41. data/lib/voyage/version.rb +8 -0
  42. data/spec/adapters/heroku_spec.rb +57 -0
  43. data/spec/fakes/bin/heroku +5 -0
  44. data/spec/fakes/bin/hub +5 -0
  45. data/spec/features/cli_help_spec.rb +36 -0
  46. data/spec/features/github_spec.rb +16 -0
  47. data/spec/features/heroku_spec.rb +75 -0
  48. data/spec/features/new_project_spec.rb +270 -0
  49. data/spec/spec_helper.rb +20 -0
  50. data/spec/support/fake_github.rb +21 -0
  51. data/spec/support/fake_heroku.rb +53 -0
  52. data/spec/support/suspenders.rb +83 -0
  53. data/suspenders.gemspec +34 -0
  54. data/templates/Gemfile.erb +64 -0
  55. data/templates/Procfile +2 -0
  56. data/templates/README.md.erb +28 -0
  57. data/templates/_analytics.html.erb +7 -0
  58. data/templates/_css_overrides.html.erb +7 -0
  59. data/templates/_flashes.html.erb +7 -0
  60. data/templates/_javascript.html.erb +12 -0
  61. data/templates/action_mailer.rb +5 -0
  62. data/templates/app.json.erb +42 -0
  63. data/templates/application.scss +9 -0
  64. data/templates/bin_deploy +12 -0
  65. data/templates/bin_setup +21 -0
  66. data/templates/bin_setup_review_app.erb +19 -0
  67. data/templates/browserslist +3 -0
  68. data/templates/bundler_audit.rake +12 -0
  69. data/templates/capybara_webkit.rb +5 -0
  70. data/templates/circle.yml.erb +6 -0
  71. data/templates/config_locales_en.yml.erb +19 -0
  72. data/templates/database_cleaner_rspec.rb +21 -0
  73. data/templates/dev.rake +12 -0
  74. data/templates/dotfiles/.ctags +2 -0
  75. data/templates/dotfiles/.env +13 -0
  76. data/templates/errors.rb +34 -0
  77. data/templates/factories.rb +2 -0
  78. data/templates/factory_girl_rspec.rb +3 -0
  79. data/templates/flashes_helper.rb +5 -0
  80. data/templates/hound.yml +14 -0
  81. data/templates/i18n.rb +3 -0
  82. data/templates/json_encoding.rb +1 -0
  83. data/templates/postgresql_database.yml.erb +21 -0
  84. data/templates/puma.rb +28 -0
  85. data/templates/rack_mini_profiler.rb +5 -0
  86. data/templates/rails_helper.rb +22 -0
  87. data/templates/secrets.yml +14 -0
  88. data/templates/shoulda_matchers_config_rspec.rb +6 -0
  89. data/templates/smtp.rb +13 -0
  90. data/templates/spec_helper.rb +29 -0
  91. data/templates/suspenders_gitignore +13 -0
  92. data/templates/suspenders_layout.html.erb.erb +22 -0
  93. metadata +207 -0
@@ -0,0 +1,486 @@
1
+ require "forwardable"
2
+
3
+ module Suspenders
4
+ class AppBuilder < Rails::AppBuilder
5
+ include Suspenders::Actions
6
+ extend Forwardable
7
+
8
+ def_delegators :heroku_adapter,
9
+ :create_heroku_application_manifest_file,
10
+ :create_heroku_pipeline,
11
+ :create_production_heroku_app,
12
+ :create_staging_heroku_app,
13
+ :create_review_apps_setup_script,
14
+ :set_heroku_rails_secrets,
15
+ :set_heroku_remotes,
16
+ :set_heroku_application_host,
17
+ :set_heroku_serve_static_files
18
+
19
+ def readme
20
+ template 'README.md.erb', 'README.md'
21
+ end
22
+
23
+ def gitignore
24
+ copy_file "suspenders_gitignore", ".gitignore"
25
+ end
26
+
27
+ def gemfile
28
+ template "Gemfile.erb", "Gemfile"
29
+ end
30
+
31
+ def setup_rack_mini_profiler
32
+ copy_file(
33
+ "rack_mini_profiler.rb",
34
+ "config/initializers/rack_mini_profiler.rb",
35
+ )
36
+ end
37
+
38
+ def raise_on_missing_assets_in_test
39
+ configure_environment "test", "config.assets.raise_runtime_errors = true"
40
+ end
41
+
42
+ def raise_on_delivery_errors
43
+ replace_in_file 'config/environments/development.rb',
44
+ 'raise_delivery_errors = false', 'raise_delivery_errors = true'
45
+ end
46
+
47
+ def set_test_delivery_method
48
+ inject_into_file(
49
+ "config/environments/development.rb",
50
+ "\n config.action_mailer.delivery_method = :file",
51
+ after: "config.action_mailer.raise_delivery_errors = true",
52
+ )
53
+ end
54
+
55
+ def add_bullet_gem_configuration
56
+ config = <<-RUBY
57
+ config.after_initialize do
58
+ Bullet.enable = true
59
+ Bullet.bullet_logger = true
60
+ Bullet.rails_logger = true
61
+ end
62
+
63
+ RUBY
64
+
65
+ inject_into_file(
66
+ "config/environments/development.rb",
67
+ config,
68
+ after: "config.action_mailer.raise_delivery_errors = true\n",
69
+ )
70
+ end
71
+
72
+ def raise_on_unpermitted_parameters
73
+ config = <<-RUBY
74
+ config.action_controller.action_on_unpermitted_parameters = :raise
75
+ RUBY
76
+
77
+ inject_into_class "config/application.rb", "Application", config
78
+ end
79
+
80
+ def configure_quiet_assets
81
+ config = <<-RUBY
82
+ config.quiet_assets = true
83
+ RUBY
84
+
85
+ inject_into_class "config/application.rb", "Application", config
86
+ end
87
+
88
+ def provide_setup_script
89
+ template "bin_setup", "bin/setup", force: true
90
+ run "chmod a+x bin/setup"
91
+ end
92
+
93
+ def provide_dev_prime_task
94
+ copy_file 'dev.rake', 'lib/tasks/dev.rake'
95
+ end
96
+
97
+ def configure_generators
98
+ config = <<-RUBY
99
+
100
+ config.generators do |generate|
101
+ generate.helper false
102
+ generate.javascript_engine false
103
+ generate.request_specs false
104
+ generate.routing_specs false
105
+ generate.stylesheets false
106
+ generate.test_framework :rspec
107
+ generate.view_specs false
108
+ end
109
+
110
+ RUBY
111
+
112
+ inject_into_class 'config/application.rb', 'Application', config
113
+ end
114
+
115
+ def set_up_factory_girl_for_rspec
116
+ copy_file 'factory_girl_rspec.rb', 'spec/support/factory_girl.rb'
117
+ end
118
+
119
+ def generate_factories_file
120
+ copy_file "factories.rb", "spec/factories.rb"
121
+ end
122
+
123
+ def set_up_hound
124
+ copy_file "hound.yml", ".hound.yml"
125
+ end
126
+
127
+ def configure_smtp
128
+ copy_file 'smtp.rb', 'config/smtp.rb'
129
+
130
+ prepend_file 'config/environments/production.rb',
131
+ %{require Rails.root.join("config/smtp")\n}
132
+
133
+ config = <<-RUBY
134
+
135
+ config.action_mailer.delivery_method = :smtp
136
+ config.action_mailer.smtp_settings = SMTP_SETTINGS
137
+ RUBY
138
+
139
+ inject_into_file 'config/environments/production.rb', config,
140
+ after: "config.action_mailer.raise_delivery_errors = false"
141
+ end
142
+
143
+ def enable_rack_canonical_host
144
+ config = <<-RUBY
145
+ if ENV.fetch("HEROKU_APP_NAME", "").include?("staging-pr-")
146
+ ENV["APPLICATION_HOST"] = ENV["HEROKU_APP_NAME"] + ".herokuapp.com"
147
+ end
148
+
149
+ config.middleware.use Rack::CanonicalHost, ENV.fetch("APPLICATION_HOST")
150
+ RUBY
151
+
152
+ configure_environment "production", config
153
+ end
154
+
155
+ def enable_rack_deflater
156
+ configure_environment "production", "config.middleware.use Rack::Deflater"
157
+ end
158
+
159
+ def setup_asset_host
160
+ replace_in_file 'config/environments/production.rb',
161
+ "# config.action_controller.asset_host = 'http://assets.example.com'",
162
+ 'config.action_controller.asset_host = ENV.fetch("ASSET_HOST", ENV.fetch("APPLICATION_HOST"))'
163
+
164
+ replace_in_file 'config/initializers/assets.rb',
165
+ "config.assets.version = '1.0'",
166
+ 'config.assets.version = (ENV["ASSETS_VERSION"] || "1.0")'
167
+
168
+ configure_environment(
169
+ "production",
170
+ 'config.static_cache_control = "public, max-age=31557600"',
171
+ )
172
+ end
173
+
174
+ def setup_secret_token
175
+ template 'secrets.yml', 'config/secrets.yml', force: true
176
+ end
177
+
178
+ def disallow_wrapping_parameters
179
+ remove_file "config/initializers/wrap_parameters.rb"
180
+ end
181
+
182
+ def create_partials_directory
183
+ empty_directory 'app/views/application'
184
+ end
185
+
186
+ def create_shared_flashes
187
+ copy_file "_flashes.html.erb", "app/views/application/_flashes.html.erb"
188
+ copy_file "flashes_helper.rb", "app/helpers/flashes_helper.rb"
189
+ end
190
+
191
+ def create_shared_javascripts
192
+ copy_file '_javascript.html.erb', 'app/views/application/_javascript.html.erb'
193
+ end
194
+
195
+ def create_shared_css_overrides
196
+ copy_file(
197
+ "_css_overrides.html.erb",
198
+ "app/views/application/_css_overrides.html.erb",
199
+ )
200
+ end
201
+
202
+ def create_application_layout
203
+ template 'suspenders_layout.html.erb.erb',
204
+ 'app/views/layouts/application.html.erb',
205
+ force: true
206
+ end
207
+
208
+ def use_postgres_config_template
209
+ template 'postgresql_database.yml.erb', 'config/database.yml',
210
+ force: true
211
+ end
212
+
213
+ def create_database
214
+ bundle_command 'exec rake db:create db:migrate'
215
+ end
216
+
217
+ def replace_gemfile(path)
218
+ template 'Gemfile.erb', 'Gemfile', force: true do |content|
219
+ if path
220
+ content.gsub(%r{gem .suspenders.}) { |s| %{#{s}, path: "#{path}"} }
221
+ else
222
+ content
223
+ end
224
+ end
225
+ end
226
+
227
+ def set_ruby_to_version_being_used
228
+ create_file '.ruby-version', "#{Suspenders::RUBY_VERSION}\n"
229
+ end
230
+
231
+ def enable_database_cleaner
232
+ copy_file 'database_cleaner_rspec.rb', 'spec/support/database_cleaner.rb'
233
+ end
234
+
235
+ def provide_shoulda_matchers_config
236
+ copy_file(
237
+ "shoulda_matchers_config_rspec.rb",
238
+ "spec/support/shoulda_matchers.rb"
239
+ )
240
+ end
241
+
242
+ def configure_spec_support_features
243
+ empty_directory_with_keep_file 'spec/features'
244
+ empty_directory_with_keep_file 'spec/support/features'
245
+ end
246
+
247
+ def configure_rspec
248
+ remove_file "spec/rails_helper.rb"
249
+ remove_file "spec/spec_helper.rb"
250
+ copy_file "rails_helper.rb", "spec/rails_helper.rb"
251
+ copy_file "spec_helper.rb", "spec/spec_helper.rb"
252
+ end
253
+
254
+ def configure_ci
255
+ template "circle.yml.erb", "circle.yml"
256
+ end
257
+
258
+ def configure_i18n_for_test_environment
259
+ copy_file "i18n.rb", "spec/support/i18n.rb"
260
+ end
261
+
262
+ def configure_i18n_for_missing_translations
263
+ raise_on_missing_translations_in("development")
264
+ raise_on_missing_translations_in("test")
265
+ end
266
+
267
+ def configure_background_jobs_for_rspec
268
+ run 'rails g delayed_job:active_record'
269
+ end
270
+
271
+ def configure_action_mailer_in_specs
272
+ copy_file 'action_mailer.rb', 'spec/support/action_mailer.rb'
273
+ end
274
+
275
+ def configure_capybara_webkit
276
+ copy_file "capybara_webkit.rb", "spec/support/capybara_webkit.rb"
277
+ end
278
+
279
+ def configure_time_formats
280
+ remove_file "config/locales/en.yml"
281
+ template "config_locales_en.yml.erb", "config/locales/en.yml"
282
+ end
283
+
284
+ def configure_rack_timeout
285
+ rack_timeout_config = <<-RUBY
286
+ Rack::Timeout.timeout = (ENV["RACK_TIMEOUT"] || 10).to_i
287
+ RUBY
288
+
289
+ append_file "config/environments/production.rb", rack_timeout_config
290
+ end
291
+
292
+ def configure_simple_form
293
+ bundle_command "exec rails generate simple_form:install"
294
+ end
295
+
296
+ def configure_action_mailer
297
+ action_mailer_host "development", %{"localhost:3000"}
298
+ action_mailer_host "test", %{"www.example.com"}
299
+ action_mailer_host "production", %{ENV.fetch("APPLICATION_HOST")}
300
+ end
301
+
302
+ def configure_active_job
303
+ configure_application_file(
304
+ "config.active_job.queue_adapter = :delayed_job"
305
+ )
306
+ configure_environment "test", "config.active_job.queue_adapter = :inline"
307
+ end
308
+
309
+ def generate_rspec
310
+ generate 'rspec:install'
311
+ end
312
+
313
+ def configure_puma
314
+ copy_file "puma.rb", "config/puma.rb"
315
+ end
316
+
317
+ def set_up_forego
318
+ copy_file "Procfile", "Procfile"
319
+ end
320
+
321
+ def setup_stylesheets
322
+ remove_file "app/assets/stylesheets/application.css"
323
+ copy_file "application.scss",
324
+ "app/assets/stylesheets/application.scss"
325
+ end
326
+
327
+ def install_refills
328
+ generate "refills:import", "flashes"
329
+ remove_dir "app/views/refills"
330
+ end
331
+
332
+ def install_bitters
333
+ run "bitters install --path app/assets/stylesheets"
334
+ end
335
+
336
+ def setup_default_directories
337
+ [
338
+ 'app/views/pages',
339
+ 'spec/lib',
340
+ 'spec/controllers',
341
+ 'spec/helpers',
342
+ 'spec/support/matchers',
343
+ 'spec/support/mixins',
344
+ 'spec/support/shared_examples'
345
+ ].each do |dir|
346
+ empty_directory_with_keep_file dir
347
+ end
348
+ end
349
+
350
+ def copy_dotfiles
351
+ directory("dotfiles", ".")
352
+ end
353
+
354
+ def init_git
355
+ run 'git init'
356
+ end
357
+
358
+ def create_heroku_apps(flags)
359
+ create_staging_heroku_app(flags)
360
+ create_production_heroku_app(flags)
361
+ end
362
+
363
+ def create_deploy_script
364
+ copy_file "bin_deploy", "bin/deploy"
365
+
366
+ instructions = <<-MARKDOWN
367
+
368
+ ## Deploying
369
+
370
+ If you have previously run the `./bin/setup` script,
371
+ you can deploy to staging and production with:
372
+
373
+ $ ./bin/deploy staging
374
+ $ ./bin/deploy production
375
+ MARKDOWN
376
+
377
+ append_file "README.md", instructions
378
+ run "chmod a+x bin/deploy"
379
+ end
380
+
381
+ def configure_automatic_deployment
382
+ deploy_command = <<-YML.strip_heredoc
383
+ deployment:
384
+ staging:
385
+ branch: master
386
+ commands:
387
+ - bin/deploy staging
388
+ YML
389
+
390
+ append_file "circle.yml", deploy_command
391
+ end
392
+
393
+ def create_github_repo(repo_name)
394
+ run "hub create #{repo_name}"
395
+ end
396
+
397
+ def setup_segment
398
+ copy_file '_analytics.html.erb',
399
+ 'app/views/application/_analytics.html.erb'
400
+ end
401
+
402
+ def setup_bundler_audit
403
+ copy_file "bundler_audit.rake", "lib/tasks/bundler_audit.rake"
404
+ append_file "Rakefile", %{\ntask default: "bundler:audit"\n}
405
+ end
406
+
407
+ def setup_spring
408
+ bundle_command "exec spring binstub --all"
409
+ end
410
+
411
+ def copy_miscellaneous_files
412
+ copy_file "browserslist", "browserslist"
413
+ copy_file "errors.rb", "config/initializers/errors.rb"
414
+ copy_file "json_encoding.rb", "config/initializers/json_encoding.rb"
415
+ end
416
+
417
+ def customize_error_pages
418
+ meta_tags =<<-EOS
419
+ <meta charset="utf-8" />
420
+ <meta name="ROBOTS" content="NOODP" />
421
+ <meta name="viewport" content="initial-scale=1" />
422
+ EOS
423
+
424
+ %w(500 404 422).each do |page|
425
+ inject_into_file "public/#{page}.html", meta_tags, after: "<head>\n"
426
+ replace_in_file "public/#{page}.html", /<!--.+-->\n/, ''
427
+ end
428
+ end
429
+
430
+ def remove_config_comment_lines
431
+ config_files = [
432
+ "application.rb",
433
+ "environment.rb",
434
+ "environments/development.rb",
435
+ "environments/production.rb",
436
+ "environments/test.rb",
437
+ ]
438
+
439
+ config_files.each do |config_file|
440
+ path = File.join(destination_root, "config/#{config_file}")
441
+
442
+ accepted_content = File.readlines(path).reject do |line|
443
+ line =~ /^.*#.*$/ || line =~ /^$\n/
444
+ end
445
+
446
+ File.open(path, "w") do |file|
447
+ accepted_content.each { |line| file.puts line }
448
+ end
449
+ end
450
+ end
451
+
452
+ def remove_routes_comment_lines
453
+ replace_in_file 'config/routes.rb',
454
+ /Rails\.application\.routes\.draw do.*end/m,
455
+ "Rails.application.routes.draw do\nend"
456
+ end
457
+
458
+ def setup_default_rake_task
459
+ append_file 'Rakefile' do
460
+ <<-EOS
461
+ task(:default).clear
462
+ task default: [:spec]
463
+
464
+ if defined? RSpec
465
+ task(:spec).clear
466
+ RSpec::Core::RakeTask.new(:spec) do |t|
467
+ t.verbose = false
468
+ end
469
+ end
470
+ EOS
471
+ end
472
+ end
473
+
474
+ private
475
+
476
+ def raise_on_missing_translations_in(environment)
477
+ config = 'config.action_view.raise_on_missing_translations = true'
478
+
479
+ uncomment_lines("config/environments/#{environment}.rb", config)
480
+ end
481
+
482
+ def heroku_adapter
483
+ @heroku_adapter ||= Adapters::Heroku.new(self)
484
+ end
485
+ end
486
+ end