brace 0.0.1

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 (65) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +4 -0
  3. data/.ruby-version +1 -0
  4. data/CONTRIBUTING.md +43 -0
  5. data/Gemfile +3 -0
  6. data/Gemfile.lock +139 -0
  7. data/LICENSE +21 -0
  8. data/NEWS.md +351 -0
  9. data/README.md +166 -0
  10. data/Rakefile +8 -0
  11. data/bin/brace +18 -0
  12. data/bin/rake +16 -0
  13. data/bin/rspec +16 -0
  14. data/bin/setup +13 -0
  15. data/brace.gemspec +35 -0
  16. data/lib/brace.rb +4 -0
  17. data/lib/brace/actions.rb +25 -0
  18. data/lib/brace/app_builder.rb +469 -0
  19. data/lib/brace/generators/app_generator.rb +248 -0
  20. data/lib/brace/version.rb +6 -0
  21. data/spec/fakes/bin/heroku +5 -0
  22. data/spec/fakes/bin/hub +5 -0
  23. data/spec/features/github_spec.rb +10 -0
  24. data/spec/features/heroku_spec.rb +40 -0
  25. data/spec/features/new_project_spec.rb +115 -0
  26. data/spec/spec_helper.rb +24 -0
  27. data/spec/support/braces.rb +49 -0
  28. data/spec/support/fake_github.rb +21 -0
  29. data/spec/support/fake_heroku.rb +43 -0
  30. data/templates/Gemfile.erb +88 -0
  31. data/templates/Procfile +2 -0
  32. data/templates/README.md.erb +32 -0
  33. data/templates/_analytics.html.erb +7 -0
  34. data/templates/_javascript.html.erb +12 -0
  35. data/templates/action_mailer.rb +5 -0
  36. data/templates/application.css.scss +8 -0
  37. data/templates/bin_deploy +12 -0
  38. data/templates/bin_setup.erb +36 -0
  39. data/templates/brace_gitignore +14 -0
  40. data/templates/brace_layout.html.slim.erb +15 -0
  41. data/templates/bundler_audit.rake +12 -0
  42. data/templates/config_i18n_tasks.yml +13 -0
  43. data/templates/config_locales_en.yml.erb +19 -0
  44. data/templates/database_cleaner_rspec.rb +21 -0
  45. data/templates/development_seeds.rb +12 -0
  46. data/templates/devise_rspec.rb +3 -0
  47. data/templates/disable_xml_params.rb +3 -0
  48. data/templates/errors.rb +34 -0
  49. data/templates/factory_girl_rspec.rb +3 -0
  50. data/templates/i18n.rb +3 -0
  51. data/templates/json_encoding.rb +1 -0
  52. data/templates/newrelic.yml.erb +34 -0
  53. data/templates/postgresql_database.yml.erb +12 -0
  54. data/templates/rack_timeout.rb +1 -0
  55. data/templates/rails_helper.rb +22 -0
  56. data/templates/redis.rb +10 -0
  57. data/templates/sample.env +5 -0
  58. data/templates/secrets.yml +14 -0
  59. data/templates/sidekiq.rb +7 -0
  60. data/templates/sidekiq_rspec.rb +7 -0
  61. data/templates/smtp.rb +9 -0
  62. data/templates/spec_helper.rb +16 -0
  63. data/templates/stripe.rb +1 -0
  64. data/templates/vcr_helper.rb +12 -0
  65. metadata +197 -0
@@ -0,0 +1,166 @@
1
+ # Brace
2
+
3
+ Brace is a base Rails API application.
4
+
5
+ ## Installation
6
+
7
+ First install the brace gem:
8
+
9
+ gem install brace
10
+
11
+ Then run:
12
+
13
+ brace projectname
14
+
15
+ This will create a Rails API in `projectname`.
16
+
17
+ ## Gemfile
18
+
19
+ To see the latest and greatest gems, look at Brace's
20
+ [Gemfile](templates/Gemfile.erb), which will be appended to the default
21
+ generated projectname/Gemfile.
22
+
23
+ It includes application gems like:
24
+
25
+ * [Rollbar](https://github.com/rollbar/rollbar-gem) for exception notification
26
+ * [Bourbon](https://github.com/thoughtbot/bourbon) for Sass mixins
27
+ * [Bitters](https://github.com/thoughtbot/bitters) for scaffold application styles
28
+ * [Devise](https://github.com/plataformatec/devise) for user authentication
29
+ * [Stripe](https://github.com/stripe/stripe-ruby) for payments
30
+ * [Sidekiq](https://github.com/mperham/sidekiq) for background
31
+ processing
32
+ * [Email Validator](https://github.com/balexand/email_validator) for email
33
+ validation
34
+ * [High Voltage](https://github.com/thoughtbot/high_voltage) for static pages
35
+ * [jQuery Rails](https://github.com/rails/jquery-rails) for jQuery
36
+ * [React Rails](https://github.com/reactjs/react-rails) for React Components
37
+ * [Neat](https://github.com/thoughtbot/neat) for semantic grids
38
+ * [New Relic RPM](https://github.com/newrelic/rpm) for monitoring performance
39
+ * [Normalize](https://necolas.github.io/normalize.css/) for resetting browser styles
40
+ * [Postgres](https://github.com/ged/ruby-pg) for access to the Postgres database
41
+ * [Rack Timeout](https://github.com/kch/rack-timeout) to abort requests that are
42
+ taking too long
43
+ * [Refills](https://github.com/thoughtbot/refills) for “copy-paste” components
44
+ and patterns based on Bourbon, Neat and Bitters
45
+ * [Title](https://github.com/calebthompson/title) for storing titles in
46
+ translations
47
+ * [Puma](https://github.com/puma/puma) to serve HTTP requests
48
+
49
+ And development gems like:
50
+
51
+ * [Dotenv](https://github.com/bkeepers/dotenv) for loading environment variables
52
+ * [Pry Rails](https://github.com/rweng/pry-rails) for interactively exploring
53
+ objects
54
+ * [ByeBug](https://github.com/deivid-rodriguez/byebug) for interactively
55
+ debugging behavior
56
+ * [Bundler Audit](https://github.com/rubysec/bundler-audit) for scanning the
57
+ Gemfile for insecure dependencies based on published CVEs
58
+ * [Spring](https://github.com/rails/spring) for fast Rails actions via
59
+ pre-loading
60
+ * [Better Errors](https://github.com/charliesome/better_errors) for better debugging via
61
+ in-browser IRB consoles.
62
+
63
+ And testing gems like:
64
+
65
+ * [Factory Girl](https://github.com/thoughtbot/factory_girl) for test data
66
+ * [RSpec](https://github.com/rspec/rspec) for unit testing
67
+ * [RSpec Mocks](https://github.com/rspec/rspec-mocks) for stubbing and spying
68
+ * [Shoulda Matchers](https://github.com/thoughtbot/shoulda-matchers) for common
69
+ RSpec matchers
70
+ * [Timecop](https://github.com/jtrupiano/timecop-console) for testing time
71
+
72
+ ## Other goodies
73
+
74
+ Brace also comes with:
75
+
76
+ * The [`./bin/setup`][setup] convention for new developer setup
77
+ * The `./bin/deploy` convention for deploying to Heroku
78
+ * Rails' flashes set up and in application layout
79
+ * A few nice time formats set up for localization
80
+ * `Rack::Deflater` to [compress responses with Gzip][compress]
81
+ * A [low database connection pool limit][pool]
82
+ * [Safe binstubs][binstub]
83
+ * [t() and l() in specs without prefixing with I18n][i18n]
84
+ * An automatically-created `SECRET_KEY_BASE` environment variable in all
85
+ environments
86
+ * The analytics adapter [Segment][segment] (and therefore config for Google
87
+ Analytics, Intercom, Facebook Ads, Twitter Ads, etc.)
88
+
89
+ [setup]: http://robots.thoughtbot.com/bin-setup
90
+ [compress]: http://robots.thoughtbot.com/content-compression-with-rack-deflater/
91
+ [pool]: https://devcenter.heroku.com/articles/concurrency-and-database-connections
92
+ [binstub]: https://github.com/thoughtbot/brace/pull/282
93
+ [i18n]: https://github.com/thoughtbot/brace/pull/304
94
+ [segment]: https://segment.io
95
+
96
+ ## Heroku
97
+
98
+ You can optionally create Heroku staging and production apps:
99
+
100
+ brace app --heroku true
101
+
102
+ This:
103
+
104
+ * Creates a staging and production Heroku app
105
+ * Sets them as `staging` and `production` Git remotes
106
+ * Configures staging with `RACK_ENV` and `RAILS_ENV` environment variables set
107
+ to `staging`
108
+ * Adds the [Rails Stdout Logging][logging-gem] gem
109
+ to configure the app to log to standard out,
110
+ which is how [Heroku's logging][heroku-logging] works.
111
+
112
+ [logging-gem]: https://github.com/heroku/rails_stdout_logging
113
+ [heroku-logging]: https://devcenter.heroku.com/articles/logging#writing-to-your-log
114
+
115
+ You can optionally specify alternate Heroku flags:
116
+
117
+ brace app \
118
+ --heroku true \
119
+ --heroku-flags "--region eu --addons newrelic,pgbackups,sendgrid,ssl"
120
+
121
+ See all possible Heroku flags:
122
+
123
+ heroku help create
124
+
125
+ ## Git
126
+
127
+ This will initialize a new git repository for your Rails app. You can
128
+ bypass this with the `--skip-git` option:
129
+
130
+ brace app --skip-git true
131
+
132
+ ## GitHub
133
+
134
+ You can optionally create a GitHub repository for the suspended Rails app. It
135
+ requires that you have [Hub](https://github.com/github/hub) on your system:
136
+
137
+ curl http://hub.github.com/standalone -sLo ~/bin/hub && chmod +x ~/bin/hub
138
+ brace app --github organization/project
139
+
140
+ This has the same effect as running:
141
+
142
+ hub create organization/project
143
+
144
+ ## Dependencies
145
+
146
+ Brace requires the latest version of Ruby.
147
+
148
+ Some gems included in Brace have native extensions. You should have GCC
149
+ installed on your machine before generating an app with Brace.
150
+
151
+ Use [OS X GCC Installer](https://github.com/kennethreitz/osx-gcc-installer/) for
152
+ Snow Leopard (OS X 10.6).
153
+
154
+ Use [Command Line Tools for XCode](https://developer.apple.com/downloads/index.action)
155
+ for Lion (OS X 10.7) or Mountain Lion (OS X 10.8).
156
+
157
+ PostgreSQL needs to be installed and running for the `db:create` rake task.
158
+
159
+ ## Credits
160
+
161
+ Brace is an extension of [thoughtbot, inc](http://thoughtbot.com/community)'s [suspenders](https://github.com/thoughtbot/suspenders). Thanks thoughtbot for making a great Rails templating gem.
162
+
163
+ ## License
164
+
165
+ Brace is free software, and may be
166
+ redistributed under the terms specified in the LICENSE file.
@@ -0,0 +1,8 @@
1
+ require 'bundler/setup'
2
+ require 'bundler/gem_tasks'
3
+ require 'rspec/core/rake_task'
4
+
5
+ RSpec::Core::RakeTask.new(:rspec)
6
+
7
+ desc 'Run the test suite'
8
+ task :default => :rspec
@@ -0,0 +1,18 @@
1
+ #!/usr/bin/env ruby
2
+ require 'pathname'
3
+
4
+ source_path = (Pathname.new(__FILE__).dirname + '../lib').expand_path
5
+ $LOAD_PATH << source_path
6
+
7
+ require 'brace'
8
+
9
+ if ['create', '--create'].include? ARGV[0]
10
+ ARGV.shift
11
+ puts "[WARNING] the brace create argument is deprecated. Just use `brace #{ARGV.join}` instead"
12
+ end
13
+
14
+ templates_root = File.expand_path(File.join("..", "templates"), File.dirname(__FILE__))
15
+ Brace::AppGenerator.source_root templates_root
16
+ Brace::AppGenerator.source_paths << Rails::Generators::AppGenerator.source_root << templates_root
17
+
18
+ Brace::AppGenerator.start
@@ -0,0 +1,16 @@
1
+ #!/usr/bin/env ruby
2
+ #
3
+ # This file was generated by Bundler.
4
+ #
5
+ # The application 'rake' is installed as part of a gem, and
6
+ # this file is here to facilitate running it.
7
+ #
8
+
9
+ require 'pathname'
10
+ ENV['BUNDLE_GEMFILE'] ||= File.expand_path("../../Gemfile",
11
+ Pathname.new(__FILE__).realpath)
12
+
13
+ require 'rubygems'
14
+ require 'bundler/setup'
15
+
16
+ load Gem.bin_path('rake', 'rake')
@@ -0,0 +1,16 @@
1
+ #!/usr/bin/env ruby
2
+ #
3
+ # This file was generated by Bundler.
4
+ #
5
+ # The application 'rspec' is installed as part of a gem, and
6
+ # this file is here to facilitate running it.
7
+ #
8
+
9
+ require 'pathname'
10
+ ENV['BUNDLE_GEMFILE'] ||= File.expand_path("../../Gemfile",
11
+ Pathname.new(__FILE__).realpath)
12
+
13
+ require 'rubygems'
14
+ require 'bundler/setup'
15
+
16
+ load Gem.bin_path('rspec-core', 'rspec')
@@ -0,0 +1,13 @@
1
+ #!/usr/bin/env sh
2
+
3
+ # Run this script immediately after cloning the codebase.
4
+
5
+ # Exit if any subcommand fails
6
+ set -e
7
+
8
+ # Set up Ruby dependencies via Bundler
9
+ bundle install
10
+
11
+ # Add binstubs to PATH in ~/.zshenv like this:
12
+ # export PATH=".git/safe/../../bin:$PATH"
13
+ mkdir -p .git/safe
@@ -0,0 +1,35 @@
1
+ # -*- encoding: utf-8 -*-
2
+ $:.push File.expand_path('../lib', __FILE__)
3
+ require 'brace/version'
4
+ require 'date'
5
+
6
+ Gem::Specification.new do |s|
7
+ s.required_ruby_version = ">= #{Brace::RUBY_VERSION}"
8
+ s.authors = ['Harry Whelchel']
9
+ s.date = Date.today.strftime('%Y-%m-%d')
10
+
11
+ s.description = <<-HERE
12
+ Brace is a base Rails API project that you can upgrade. It is used by
13
+ me to get a jump start on a working app. Thanks thoughtbot for making Suspenders (https://github.com/thoughtbot/suspenders)!
14
+ HERE
15
+
16
+ s.email = 'harrywhelchel@gmail.com'
17
+ s.executables = ['brace']
18
+ s.extra_rdoc_files = %w[README.md LICENSE]
19
+ s.files = `git ls-files`.split("\n")
20
+ s.license = 'MIT'
21
+ s.summary = "Rails API template adapted from thoughtbot's Suspenders."
22
+ s.homepage = "https://github.com/hwhelchel/brace"
23
+ s.name = 'brace'
24
+ s.rdoc_options = ['--charset=UTF-8']
25
+ s.require_paths = ['lib']
26
+ s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
27
+ s.version = Brace::VERSION
28
+
29
+ s.add_dependency 'bitters', '~> 0.10.0'
30
+ s.add_dependency 'bundler', '~> 1.3'
31
+ s.add_dependency 'rails', Brace::RAILS_VERSION
32
+
33
+ s.add_development_dependency 'rspec', '~> 2.0'
34
+ s.add_development_dependency 'capybara', '~> 2.2', '>= 2.2.0'
35
+ end
@@ -0,0 +1,4 @@
1
+ require 'brace/version'
2
+ require 'brace/generators/app_generator'
3
+ require 'brace/actions'
4
+ require 'brace/app_builder'
@@ -0,0 +1,25 @@
1
+ module Brace
2
+ module Actions
3
+ def replace_in_file(relative_path, find, replace)
4
+ path = File.join(destination_root, relative_path)
5
+ contents = IO.read(path)
6
+ unless contents.gsub!(find, replace)
7
+ raise "#{find.inspect} not found in #{relative_path}"
8
+ end
9
+ File.open(path, "w") { |file| file.write(contents) }
10
+ end
11
+
12
+ def action_mailer_host(rails_env, host)
13
+ config = "config.action_mailer.default_url_options = { host: #{host} }"
14
+ configure_environment(rails_env, config)
15
+ end
16
+
17
+ def configure_environment(rails_env, config)
18
+ inject_into_file(
19
+ "config/environments/#{rails_env}.rb",
20
+ "\n\n #{config}",
21
+ before: "\nend"
22
+ )
23
+ end
24
+ end
25
+ end
@@ -0,0 +1,469 @@
1
+ module Brace
2
+ class AppBuilder < Rails::AppBuilder
3
+ include Brace::Actions
4
+
5
+ def readme
6
+ template 'README.md.erb', 'README.md'
7
+ end
8
+
9
+ def raise_on_delivery_errors
10
+ replace_in_file 'config/environments/development.rb',
11
+ 'raise_delivery_errors = false', 'raise_delivery_errors = true'
12
+ end
13
+
14
+ def set_test_delivery_method
15
+ inject_into_file(
16
+ "config/environments/development.rb",
17
+ "\n config.action_mailer.delivery_method = :test",
18
+ after: "config.action_mailer.raise_delivery_errors = true",
19
+ )
20
+ end
21
+
22
+ def raise_on_unpermitted_parameters
23
+ config = <<-RUBY
24
+ config.action_controller.action_on_unpermitted_parameters = :raise
25
+ RUBY
26
+
27
+ inject_into_class "config/application.rb", "Application", config
28
+ end
29
+
30
+ def provide_setup_script
31
+ template "bin_setup.erb", "bin/setup", port_number: port, force: true
32
+ run "chmod a+x bin/setup"
33
+ end
34
+
35
+ def provide_dev_prime_task
36
+ copy_file 'development_seeds.rb', 'lib/tasks/development_seeds.rake'
37
+ end
38
+
39
+ def configure_generators
40
+ config = <<-RUBY
41
+
42
+ config.generators do |generate|
43
+ generate.helper false
44
+ generate.javascript_engine false
45
+ generate.request_specs false
46
+ generate.routing_specs false
47
+ generate.stylesheets false
48
+ generate.javascripts false
49
+ generate.helper false
50
+ generate.template_engine :slim
51
+ generate.test_framework :rspec, fixture: true
52
+ generate.fixture_replacement :factory_girl
53
+ generate.view_specs false
54
+ end
55
+
56
+ RUBY
57
+
58
+ inject_into_class 'config/application.rb', 'Application', config
59
+ end
60
+
61
+ def configure_eager_load_paths
62
+ config = <<-RUBY
63
+ config.eager_load_paths += %W(\#{config.root}/lib)
64
+ RUBY
65
+
66
+ inject_into_class 'config/application.rb', 'Application', config
67
+ end
68
+
69
+ def configure_action_mailer_previews
70
+ config = <<-RUBY
71
+ config.action_mailer.preview_path = "\#{Rails.root}/spec/mailers/previews"
72
+ RUBY
73
+
74
+ inject_into_class 'config/application.rb', 'Application', config
75
+ end
76
+
77
+ def configure_action_mailer_development
78
+ config = <<-CONFIG
79
+ config.action_mailer.delivery_method = :file
80
+ config.action_mailer.default_url_options = { host: 'localhost', port: #{port} }
81
+ CONFIG
82
+
83
+ environment(config, env: 'development')
84
+ end
85
+
86
+ def configure_responders
87
+ application('config.app_generators.scaffold_controller :responders_controller')
88
+ end
89
+
90
+ def set_up_factory_girl_for_rspec
91
+ copy_file 'factory_girl_rspec.rb', 'spec/support/factory_girl.rb'
92
+ end
93
+
94
+ def set_up_devise_for_rspec
95
+ copy_file 'devise_rspec.rb', 'spec/support/devise.rb'
96
+ end
97
+
98
+ def configure_newrelic
99
+ template 'newrelic.yml.erb', 'config/newrelic.yml'
100
+ end
101
+
102
+ def configure_smtp
103
+ copy_file 'smtp.rb', 'config/smtp.rb'
104
+
105
+ prepend_file 'config/environments/production.rb',
106
+ %{require Rails.root.join("config/smtp")\n}
107
+
108
+ config = <<-RUBY
109
+
110
+ config.action_mailer.delivery_method = :smtp
111
+ config.action_mailer.smtp_settings = SMTP_SETTINGS
112
+ RUBY
113
+
114
+ inject_into_file 'config/environments/production.rb', config,
115
+ :after => 'config.action_mailer.raise_delivery_errors = false'
116
+ end
117
+
118
+ def enable_rack_deflater
119
+ config = <<-RUBY
120
+
121
+ # Enable deflate / gzip compression of controller-generated responses
122
+ config.middleware.use Rack::Deflater
123
+ RUBY
124
+
125
+ inject_into_file(
126
+ "config/environments/production.rb",
127
+ config,
128
+ after: serve_static_files_line
129
+ )
130
+ end
131
+
132
+ def setup_asset_host
133
+ replace_in_file 'config/environments/production.rb',
134
+ "# config.action_controller.asset_host = 'http://assets.example.com'",
135
+ 'config.action_controller.asset_host = ENV.fetch("ASSET_HOST", ENV.fetch("HOST"))'
136
+
137
+ replace_in_file 'config/initializers/assets.rb',
138
+ "config.assets.version = '1.0'",
139
+ 'config.assets.version = (ENV["ASSETS_VERSION"] || "1.0")'
140
+
141
+ inject_into_file(
142
+ "config/environments/production.rb",
143
+ ' config.static_cache_control = "public, max-age=#{1.year.to_i}"',
144
+ after: serve_static_files_line
145
+ )
146
+ end
147
+
148
+ def setup_secret_token
149
+ template 'secrets.yml', 'config/secrets.yml', force: true
150
+ end
151
+
152
+ def disallow_wrapping_parameters
153
+ remove_file "config/initializers/wrap_parameters.rb"
154
+ end
155
+
156
+ def create_partials_directory
157
+ empty_directory 'app/views/application'
158
+ end
159
+
160
+ def create_application_layout
161
+ template 'brace_layout.html.slim.erb',
162
+ 'app/views/layouts/application.html.slim',
163
+ force: true
164
+ end
165
+
166
+ def use_postgres_config_template
167
+ template 'postgresql_database.yml.erb', 'config/database.yml',
168
+ force: true
169
+ end
170
+
171
+ def create_database
172
+ bundle_command 'exec rake db:create db:migrate'
173
+ end
174
+
175
+ def replace_gemfile
176
+ remove_file 'Gemfile'
177
+ template 'Gemfile.erb', 'Gemfile'
178
+ end
179
+
180
+ def set_ruby_to_version_being_used
181
+ create_file '.ruby-version', "#{Brace::RUBY_VERSION}\n"
182
+ end
183
+
184
+ def setup_heroku_specific_gems
185
+ inject_into_file(
186
+ "Gemfile",
187
+ %{\n\s\sgem "rails_stdout_logging"},
188
+ after: /group :staging, :production do/
189
+ )
190
+ end
191
+
192
+ def enable_database_cleaner
193
+ copy_file 'database_cleaner_rspec.rb', 'spec/support/database_cleaner.rb'
194
+ end
195
+
196
+ def configure_spec_support_features
197
+ empty_directory_with_keep_file 'spec/features'
198
+ empty_directory_with_keep_file 'spec/support/features'
199
+ end
200
+
201
+ def configure_rspec
202
+ remove_file "spec/rails_helper.rb"
203
+ remove_file "spec/spec_helper.rb"
204
+ copy_file "rails_helper.rb", "spec/rails_helper.rb"
205
+ copy_file "spec_helper.rb", "spec/spec_helper.rb"
206
+ copy_file "vcr_helper.rb", "spec/vcr_helper.rb"
207
+ end
208
+
209
+ def configure_i18n_for_test_environment
210
+ copy_file "i18n.rb", "spec/support/i18n.rb"
211
+ end
212
+
213
+ def configure_i18n_for_missing_translations
214
+ raise_on_missing_translations_in("development")
215
+ raise_on_missing_translations_in("test")
216
+ end
217
+
218
+ def configure_i18n_tasks
219
+ run "cp $(i18n-tasks gem-path)/templates/rspec/i18n_spec.rb spec/"
220
+ copy_file "config_i18n_tasks.yml", "config/i18n-tasks.yml"
221
+ end
222
+
223
+ def configure_sidekiq_for_rspec
224
+ copy_file 'sidekiq_rspec.rb', 'spec/support/sidekiq.rb'
225
+ end
226
+
227
+ def configure_action_mailer_in_specs
228
+ copy_file 'action_mailer.rb', 'spec/support/action_mailer.rb'
229
+ end
230
+
231
+ def configure_time_formats
232
+ remove_file "config/locales/en.yml"
233
+ template "config_locales_en.yml.erb", "config/locales/en.yml"
234
+ end
235
+
236
+ def configure_rack_timeout
237
+ copy_file 'rack_timeout.rb', 'config/initializers/rack_timeout.rb'
238
+ end
239
+
240
+ def configure_action_mailer
241
+ action_mailer_host "development", %{"localhost:#{port}"}
242
+ action_mailer_host "test", %{"www.example.com"}
243
+ action_mailer_host "production", %{ENV.fetch("HOST")}
244
+ end
245
+
246
+ def fix_i18n_deprecation_warning
247
+ config = <<-RUBY
248
+ config.i18n.enforce_available_locales = true
249
+ RUBY
250
+
251
+ inject_into_class 'config/application.rb', 'Application', config
252
+ end
253
+
254
+ def generate_rspec
255
+ generate 'rspec:install'
256
+ end
257
+
258
+ def setup_foreman
259
+ copy_file 'sample.env', '.env'
260
+ copy_file 'Procfile', 'Procfile'
261
+ end
262
+
263
+ def setup_stylesheets
264
+ remove_file 'app/assets/stylesheets/application.css'
265
+ copy_file 'application.css.scss',
266
+ 'app/assets/stylesheets/application.css.scss'
267
+ end
268
+
269
+ def install_devise
270
+ generate 'devise:install'
271
+ route 'root to: "home#index"'
272
+ end
273
+
274
+ def install_bitters
275
+ run "bitters install --path app/assets/stylesheets"
276
+ end
277
+
278
+ def install_responders
279
+ generate 'responders:install'
280
+ end
281
+
282
+ def gitignore_files
283
+ remove_file '.gitignore'
284
+ copy_file 'brace_gitignore', '.gitignore'
285
+ [
286
+ 'app/views/pages',
287
+ 'spec/lib',
288
+ 'spec/controllers',
289
+ 'spec/helpers',
290
+ 'spec/support/matchers',
291
+ 'spec/support/mixins',
292
+ 'spec/support/shared_examples'
293
+ ].each do |dir|
294
+ run "mkdir #{dir}"
295
+ run "touch #{dir}/.keep"
296
+ end
297
+ end
298
+
299
+ def init_git
300
+ run 'git init'
301
+ end
302
+
303
+ def create_heroku_apps(flags)
304
+ rack_env = "RACK_ENV=staging RAILS_ENV=staging"
305
+ rails_serve_static_files = "RAILS_SERVE_STATIC_FILES=true"
306
+ staging_config = "#{rack_env} #{rails_serve_static_files}"
307
+ run_heroku "create #{app_name}-production #{flags}", "production"
308
+ run_heroku "create #{app_name}-staging #{flags}", "staging"
309
+ run_heroku "config:add #{staging_config}", "staging"
310
+ run_heroku "config:add #{rails_serve_static_files}", "production"
311
+ end
312
+
313
+ def set_heroku_remotes
314
+ remotes = <<-SHELL
315
+
316
+ # Set up the staging and production apps.
317
+ #{join_heroku_app('staging')}
318
+ #{join_heroku_app('production')}
319
+ SHELL
320
+
321
+ append_file 'bin/setup', remotes
322
+ end
323
+
324
+ def join_heroku_app(environment)
325
+ heroku_app_name = "#{app_name}-#{environment}"
326
+ <<-SHELL
327
+ if heroku join --app #{heroku_app_name} &> /dev/null; then
328
+ git remote add #{environment} git@heroku.com:#{heroku_app_name}.git || true
329
+ printf 'You are a collaborator on the "#{heroku_app_name}" Heroku app\n'
330
+ else
331
+ printf 'Ask for access to the "#{heroku_app_name}" Heroku app\n'
332
+ fi
333
+ SHELL
334
+ end
335
+
336
+ def set_heroku_rails_secrets
337
+ %w(staging production).each do |environment|
338
+ run_heroku "config:add SECRET_KEY_BASE=#{generate_secret}", environment
339
+ end
340
+ end
341
+
342
+ def set_memory_management_variable
343
+ %w(staging production).each do |environment|
344
+ run_heroku "config:add NEW_RELIC_AGGRESSIVE_KEEPALIVE=1", environment
345
+ end
346
+ end
347
+
348
+ def provide_deploy_script
349
+ copy_file "bin_deploy", "bin/deploy"
350
+
351
+ instructions = <<-MARKDOWN
352
+
353
+ ## Deploying
354
+
355
+ If you have previously run the `./bin/setup` script,
356
+ you can deploy to staging and production with:
357
+
358
+ $ ./bin/deploy staging
359
+ $ ./bin/deploy production
360
+ MARKDOWN
361
+
362
+ append_file "README.md", instructions
363
+ run "chmod a+x bin/deploy"
364
+ end
365
+
366
+ def create_github_repo(repo_name)
367
+ path_addition = override_path_for_tests
368
+ run "#{path_addition} hub create #{repo_name}"
369
+ end
370
+
371
+ def setup_segment_io
372
+ copy_file '_analytics.html.erb',
373
+ 'app/views/application/_analytics.html.erb'
374
+ end
375
+
376
+ def setup_bundler_audit
377
+ copy_file "bundler_audit.rake", "lib/tasks/bundler_audit.rake"
378
+ append_file "Rakefile", %{\ntask default: "bundler:audit"\n}
379
+ end
380
+
381
+ def copy_miscellaneous_files
382
+ copy_file "errors.rb", "config/initializers/errors.rb"
383
+ copy_file "json_encoding.rb", "config/initializers/json_encoding.rb"
384
+ end
385
+
386
+ def customize_error_pages
387
+ meta_tags =<<-EOS
388
+ <meta charset="utf-8" />
389
+ <meta name="ROBOTS" content="NOODP" />
390
+ <meta name="viewport" content="initial-scale=1" />
391
+ EOS
392
+
393
+ %w(500 404 422).each do |page|
394
+ inject_into_file "public/#{page}.html", meta_tags, :after => "<head>\n"
395
+ replace_in_file "public/#{page}.html", /<!--.+-->\n/, ''
396
+ end
397
+ end
398
+
399
+ def remove_routes_comment_lines
400
+ replace_in_file 'config/routes.rb',
401
+ /Rails\.application\.routes\.draw do.*end/m,
402
+ "Rails.application.routes.draw do\nend"
403
+ end
404
+
405
+ def disable_xml_params
406
+ copy_file 'disable_xml_params.rb', 'config/initializers/disable_xml_params.rb'
407
+ end
408
+
409
+ def setup_default_rake_task
410
+ append_file 'Rakefile' do
411
+ <<-EOS
412
+ task(:default).clear
413
+ task default: [:spec]
414
+
415
+ if defined? RSpec
416
+ task(:spec).clear
417
+ RSpec::Core::RakeTask.new(:spec) do |t|
418
+ t.verbose = false
419
+ end
420
+ end
421
+ EOS
422
+ end
423
+ end
424
+
425
+ def add_redis_initializer
426
+ copy_file 'redis.rb', 'config/initializers/redis.rb'
427
+ end
428
+
429
+ def add_sidekiq_initializer
430
+ copy_file 'sidekiq.rb', 'config/initializers/sidekiq.rb'
431
+ end
432
+
433
+ def add_stripe_initializer
434
+ copy_file 'stripe.rb', 'config/initializers/stripe.rb'
435
+ end
436
+
437
+ private
438
+
439
+ def raise_on_missing_translations_in(environment)
440
+ config = 'config.action_view.raise_on_missing_translations = true'
441
+
442
+ uncomment_lines("config/environments/#{environment}.rb", config)
443
+ end
444
+
445
+ def override_path_for_tests
446
+ if ENV['TESTING']
447
+ support_bin = File.expand_path(File.join('..', '..', 'spec', 'fakes', 'bin'))
448
+ "PATH=#{support_bin}:$PATH"
449
+ end
450
+ end
451
+
452
+ def run_heroku(command, environment)
453
+ path_addition = override_path_for_tests
454
+ run "#{path_addition} heroku #{command} --remote #{environment}"
455
+ end
456
+
457
+ def generate_secret
458
+ SecureRandom.hex(64)
459
+ end
460
+
461
+ def port
462
+ @port ||= [3000, 4000, 5000, 7000, 8000, 9000].sample
463
+ end
464
+
465
+ def serve_static_files_line
466
+ "config.serve_static_files = ENV['RAILS_SERVE_STATIC_FILES'].present?\n"
467
+ end
468
+ end
469
+ end