brace 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
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