bowties 2.0.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 (68) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +4 -0
  3. data/.rspec +1 -0
  4. data/.ruby-gemset +1 -0
  5. data/.ruby-version +1 -0
  6. data/CONTRIBUTING.md +43 -0
  7. data/Gemfile +3 -0
  8. data/Gemfile.lock +129 -0
  9. data/LICENSE +21 -0
  10. data/NEWS.md +405 -0
  11. data/README.md +219 -0
  12. data/Rakefile +8 -0
  13. data/bin/bowties +18 -0
  14. data/bin/rake +16 -0
  15. data/bin/rspec +16 -0
  16. data/bin/setup +13 -0
  17. data/bowties.gemspec +34 -0
  18. data/circle.yml +6 -0
  19. data/lib/bowties.rb +4 -0
  20. data/lib/bowties/actions.rb +33 -0
  21. data/lib/bowties/app_builder.rb +499 -0
  22. data/lib/bowties/generators/app_generator.rb +238 -0
  23. data/lib/bowties/version.rb +5 -0
  24. data/spec/fakes/bin/heroku +5 -0
  25. data/spec/fakes/bin/hub +5 -0
  26. data/spec/features/github_spec.rb +15 -0
  27. data/spec/features/heroku_spec.rb +46 -0
  28. data/spec/features/new_project_spec.rb +135 -0
  29. data/spec/spec_helper.rb +20 -0
  30. data/spec/support/bowties.rb +48 -0
  31. data/spec/support/fake_github.rb +21 -0
  32. data/spec/support/fake_heroku.rb +43 -0
  33. data/templates/Gemfile.erb +58 -0
  34. data/templates/Procfile +2 -0
  35. data/templates/README.md.erb +32 -0
  36. data/templates/_analytics.html.erb +7 -0
  37. data/templates/_flashes.html.erb +7 -0
  38. data/templates/_javascript.html.erb +12 -0
  39. data/templates/action_mailer.rb +5 -0
  40. data/templates/application.scss +8 -0
  41. data/templates/bin_deploy +12 -0
  42. data/templates/bin_setup.erb +36 -0
  43. data/templates/browserslist +4 -0
  44. data/templates/bundler_audit.rake +12 -0
  45. data/templates/circle.yml.erb +8 -0
  46. data/templates/config_i18n_tasks.yml +13 -0
  47. data/templates/config_locales_en.yml.erb +19 -0
  48. data/templates/database_cleaner_rspec.rb +21 -0
  49. data/templates/development_seeds.rb +12 -0
  50. data/templates/disable_xml_params.rb +3 -0
  51. data/templates/errors.rb +34 -0
  52. data/templates/factory_girl_rspec.rb +3 -0
  53. data/templates/flashes_helper.rb +5 -0
  54. data/templates/hound.yml +17 -0
  55. data/templates/i18n.rb +3 -0
  56. data/templates/json_encoding.rb +1 -0
  57. data/templates/newrelic.yml.erb +34 -0
  58. data/templates/postgresql_database.yml.erb +12 -0
  59. data/templates/rails_helper.rb +23 -0
  60. data/templates/sample.env +6 -0
  61. data/templates/secrets.yml +14 -0
  62. data/templates/smtp.rb +9 -0
  63. data/templates/spec_helper.rb +23 -0
  64. data/templates/staging.rb +5 -0
  65. data/templates/suspenders_gitignore +14 -0
  66. data/templates/suspenders_layout.html.erb.erb +21 -0
  67. data/templates/unicorn.rb +30 -0
  68. metadata +181 -0
@@ -0,0 +1,219 @@
1
+ # Bowties [![Circle CI](https://circleci.com/gh/wizarddevelopment/bowties.svg?style=svg&circle-token=6964ba6efdd78b60433f87886907afac1ea96b58)](https://circleci.com/gh/wizarddevelopment/bowties)
2
+
3
+ Bowties is the base Rails application used at [Wizard Development](http://www.wizarddevelopment.com) forked from the wonderful [suspenders](https://github.com/thoughtbot/suspenders) project in use at
4
+ [thoughtbot](http://thoughtbot.com).
5
+
6
+ ## Why Fork?
7
+ We work a bit differently. Suspenders has the defaults that makes sense for thoughtbot and Bowties has defaults that make sense for us. You can find our current best practices in our [development guides](https://github.com/wizarddevelopment/guides).
8
+
9
+ ## Installation
10
+
11
+ First install the Bowties gem:
12
+
13
+ gem install bowties
14
+
15
+ Then run:
16
+
17
+ bowties projectname
18
+
19
+ This will create a Rails app in `projectname` using the latest version of Rails.
20
+
21
+ ## Gemfile
22
+
23
+ To see the latest and greatest gems, look at Bowties'
24
+ [Gemfile](templates/Gemfile.erb), which will be appended to the default
25
+ generated projectname/Gemfile.
26
+
27
+ It includes application gems like:
28
+
29
+ * [Airbrake](https://github.com/airbrake/airbrake) for exception notification
30
+ * [Autoprefixer Rails](https://github.com/ai/autoprefixer-rails) for CSS vendor prefixes
31
+ * [Bourbon](https://github.com/thoughtbot/bourbon) for Sass mixins
32
+ * [Bitters](https://github.com/thoughtbot/bitters) for scaffold application styles
33
+ * [Delayed Job](https://github.com/collectiveidea/delayed_job) for background
34
+ processing
35
+ * [Email Validator](https://github.com/balexand/email_validator) for email
36
+ validation
37
+ * [Flutie](https://github.com/thoughtbot/flutie) for `page_title` and `body_class` view
38
+ helpers
39
+ * [High Voltage](https://github.com/thoughtbot/high_voltage) for static pages
40
+ * [jQuery Rails](https://github.com/rails/jquery-rails) for jQuery
41
+ * [Neat](https://github.com/thoughtbot/neat) for semantic grids
42
+ * [New Relic RPM](https://github.com/newrelic/rpm) for monitoring performance
43
+ * [Normalize](https://necolas.github.io/normalize.css/) for resetting browser styles
44
+ * [Postgres](https://github.com/ged/ruby-pg) for access to the Postgres database
45
+ * [Rack Canonical Host](https://github.com/tylerhunt/rack-canonical-host) to
46
+ ensure all requests are served from the same domain
47
+ * [Rack Timeout](https://github.com/kch/rack-timeout) to abort requests that are
48
+ taking too long
49
+ * [Recipient Interceptor](https://github.com/croaky/recipient_interceptor) to
50
+ avoid accidentally sending emails to real people from staging
51
+ * [Refills](https://github.com/thoughtbot/refills) for “copy-paste” components
52
+ and patterns based on Bourbon, Neat and Bitters
53
+ * [Simple Form](https://github.com/plataformatec/simple_form) for form markup
54
+ and style
55
+ * [Title](https://github.com/calebthompson/title) for storing titles in
56
+ translations
57
+ * [Unicorn](https://github.com/defunkt/unicorn) to serve HTTP requests
58
+
59
+ And development gems like:
60
+
61
+ * [Dotenv](https://github.com/bkeepers/dotenv) for loading environment variables
62
+ * [Pry Rails](https://github.com/rweng/pry-rails) for interactively exploring
63
+ objects
64
+ * [ByeBug](https://github.com/deivid-rodriguez/byebug) for interactively
65
+ debugging behavior
66
+ * [Bundler Audit](https://github.com/rubysec/bundler-audit) for scanning the
67
+ Gemfile for insecure dependencies based on published CVEs
68
+ * [Spring](https://github.com/rails/spring) for fast Rails actions via
69
+ pre-loading
70
+ * [Web Console](https://github.com/rails/web-console) for better debugging via
71
+ in-browser IRB consoles.
72
+
73
+ And testing gems like:
74
+
75
+ * [Capybara](https://github.com/jnicklas/capybara) and
76
+ [Capybara Webkit](https://github.com/thoughtbot/capybara-webkit) for
77
+ integration testing
78
+ * [Factory Girl](https://github.com/thoughtbot/factory_girl) for test data
79
+ * [Formulaic](https://github.com/thoughtbot/formulaic) for integration testing
80
+ HTML forms
81
+ * [RSpec](https://github.com/rspec/rspec) for unit testing
82
+ * [RSpec Mocks](https://github.com/rspec/rspec-mocks) for stubbing and spying
83
+ * [Shoulda Matchers](https://github.com/thoughtbot/shoulda-matchers) for common
84
+ RSpec matchers
85
+ * [Timecop](https://github.com/jtrupiano/timecop-console) for testing time
86
+
87
+ ## Other goodies
88
+
89
+ Bowties also comes with:
90
+
91
+ * The [`./bin/setup`][setup] convention for new developer setup
92
+ * The `./bin/deploy` convention for deploying to Heroku
93
+ * Rails' flashes set up and in application layout
94
+ * A few nice time formats set up for localization
95
+ * `Rack::Deflater` to [compress responses with Gzip][compress]
96
+ * A [low database connection pool limit][pool]
97
+ * [Safe binstubs][binstub]
98
+ * [t() and l() in specs without prefixing with I18n][i18n]
99
+ * An automatically-created `SECRET_KEY_BASE` environment variable in all
100
+ environments
101
+ * Configuration for [CircleCI][circle] Continuous Integration (tests)
102
+ * Configuration for [Hound][hound] Continuous Integration (style)
103
+ * The analytics adapter [Segment][segment] (and therefore config for Google
104
+ Analytics, Intercom, Facebook Ads, Twitter Ads, etc.)
105
+
106
+ [setup]: http://robots.thoughtbot.com/bin-setup
107
+ [compress]: http://robots.thoughtbot.com/content-compression-with-rack-deflater/
108
+ [pool]: https://devcenter.heroku.com/articles/concurrency-and-database-connections
109
+ [binstub]: https://github.com/thoughtbot/suspenders/pull/282
110
+ [i18n]: https://github.com/thoughtbot/suspenders/pull/304
111
+ [circle]: https://circleci.com/docs
112
+ [hound]: https://houndci.com
113
+ [segment]: https://segment.com
114
+
115
+ ## Heroku
116
+
117
+ You can optionally create Heroku staging and production apps:
118
+
119
+ bowties app --heroku true
120
+
121
+ This:
122
+
123
+ * Creates a staging and production Heroku app
124
+ * Sets them as `staging` and `production` Git remotes
125
+ * Configures staging with `RACK_ENV` and `RAILS_ENV` environment variables set
126
+ to `staging`
127
+ * Adds the [Rails Stdout Logging][logging-gem] gem
128
+ to configure the app to log to standard out,
129
+ which is how [Heroku's logging][heroku-logging] works.
130
+
131
+ [logging-gem]: https://github.com/heroku/rails_stdout_logging
132
+ [heroku-logging]: https://devcenter.heroku.com/articles/logging#writing-to-your-log
133
+
134
+ You can optionally specify alternate Heroku flags:
135
+
136
+ bowties app \
137
+ --heroku true \
138
+ --heroku-flags "--region eu --addons newrelic,sendgrid,ssl"
139
+
140
+ See all possible Heroku flags:
141
+
142
+ heroku help create
143
+
144
+ ## Git
145
+
146
+ This will initialize a new git repository for your Rails app. You can
147
+ bypass this with the `--skip-git` option:
148
+
149
+ bowties app --skip-git true
150
+
151
+ ## GitHub
152
+
153
+ You can optionally create a GitHub repository for the suspended Rails app. It
154
+ requires that you have [Hub](https://github.com/github/hub) on your system:
155
+
156
+ curl http://hub.github.com/standalone -sLo ~/bin/hub && chmod +x ~/bin/hub
157
+ bowties app --github organization/project
158
+
159
+ This has the same effect as running:
160
+
161
+ hub create organization/project
162
+
163
+ ## Spring
164
+
165
+ Bowties uses [spring](https://github.com/rails/spring) by default.
166
+ It makes Rails applications load faster, but it might introduce confusing issues
167
+ around stale code not being refreshed.
168
+ If you think your application is running old code, run `spring stop`.
169
+ And if you'd rather not use spring, add `DISABLE_SPRING=1` to your login file.
170
+
171
+ ## Dependencies
172
+
173
+ Bowties requires the latest version of Ruby.
174
+
175
+ Some gems included in Bowties have native extensions. You should have GCC
176
+ installed on your machine before generating an app with Bowties.
177
+
178
+ Use [OS X GCC Installer](https://github.com/kennethreitz/osx-gcc-installer/) for
179
+ Snow Leopard (OS X 10.6).
180
+
181
+ Use [Command Line Tools for XCode](https://developer.apple.com/downloads/index.action)
182
+ for Lion (OS X 10.7) or Mountain Lion (OS X 10.8).
183
+
184
+ We use [Capybara Webkit](https://github.com/thoughtbot/capybara-webkit) for
185
+ full-stack JavaScript integration testing. It requires QT. Instructions for
186
+ installing QT are
187
+ [here](https://github.com/thoughtbot/capybara-webkit/wiki/Installing-Qt-and-compiling-capybara-webkit).
188
+
189
+ PostgreSQL needs to be installed and running for the `db:create` rake task.
190
+
191
+ ## Issues
192
+
193
+ If you have problems, please create a
194
+ [GitHub Issue](https://github.com/wizarddevelopment/bowties/issues).
195
+
196
+ ## Contributing
197
+
198
+ See [CONTRIBUTING.md](CONTRIBUTING.md).
199
+
200
+ Thank you, [contributors] and thoughtbot!
201
+
202
+ [contributors]: https://github.com/wizarddevelopment/bowties/graphs/contributors
203
+
204
+ ## License
205
+
206
+ Bowties is Copyright © 2015 Wizard Development.
207
+ It is free software,
208
+ and may be redistributed under the terms specified in the [LICENSE] file.
209
+
210
+ [LICENSE]: LICENSE
211
+
212
+ ## About Wizard Development
213
+
214
+ Bowties is maintained and funded by Wizard Development.
215
+
216
+ We love open source software!
217
+ We are [available for hire][hire].
218
+
219
+ [hire]: https://www.wizarddevelopment.com?utm_source=github
@@ -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 'bowties'
8
+
9
+ if ['create', '--create'].include? ARGV[0]
10
+ ARGV.shift
11
+ puts "[WARNING] the bowties create argument is deprecated. Just use `bowties #{ARGV.join}` instead"
12
+ end
13
+
14
+ templates_root = File.expand_path(File.join("..", "templates"), File.dirname(__FILE__))
15
+ Bowties::AppGenerator.source_root templates_root
16
+ Bowties::AppGenerator.source_paths << Rails::Generators::AppGenerator.source_root << templates_root
17
+
18
+ Bowties::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,34 @@
1
+ # -*- encoding: utf-8 -*-
2
+ $LOAD_PATH.push File.expand_path('../lib', __FILE__)
3
+ require 'bowties/version'
4
+ require 'date'
5
+
6
+ Gem::Specification.new do |s|
7
+ s.required_ruby_version = ">= #{Bowties::RUBY_VERSION}"
8
+ s.authors = ['Wizard Development']
9
+ s.date = Date.today.strftime('%Y-%m-%d')
10
+
11
+ s.description = <<-HERE
12
+ Bowties is a base Rails project that you can upgrade. It is used by
13
+ Wizard Development to get a jump start on a working app.
14
+ HERE
15
+
16
+ s.email = 'admin@wizarddevelopment.com'
17
+ s.executables = ['bowties']
18
+ s.extra_rdoc_files = %w(README.md LICENSE)
19
+ s.files = `git ls-files`.split("\n")
20
+ s.homepage = 'http://github.com/wizarddevelopment/bowties'
21
+ s.license = 'MIT'
22
+ s.name = 'bowties'
23
+ s.rdoc_options = ['--charset=UTF-8']
24
+ s.require_paths = ['lib']
25
+ s.summary = "Generate a Rails app using Wizard Development's best practices."
26
+ s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
27
+ s.version = Bowties::VERSION
28
+
29
+ s.add_dependency 'bitters', '~> 1.0.0'
30
+ s.add_dependency 'bundler', '~> 1.3'
31
+ s.add_dependency 'rails', Bowties::RAILS_VERSION
32
+
33
+ s.add_development_dependency 'rspec', '~> 3.2'
34
+ end
@@ -0,0 +1,6 @@
1
+ test:
2
+ pre:
3
+ - git config --global user.name 'Circle'
4
+ - git config --global user.email 'circle@example.com'
5
+ override:
6
+ - bundle exec rake
@@ -0,0 +1,4 @@
1
+ require 'bowties/version'
2
+ require 'bowties/generators/app_generator'
3
+ require 'bowties/actions'
4
+ require 'bowties/app_builder'
@@ -0,0 +1,33 @@
1
+ module Bowties
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_application_file(config)
18
+ inject_into_file(
19
+ "config/application.rb",
20
+ "\n\n #{config}",
21
+ before: "\n end"
22
+ )
23
+ end
24
+
25
+ def configure_environment(rails_env, config)
26
+ inject_into_file(
27
+ "config/environments/#{rails_env}.rb",
28
+ "\n\n #{config}",
29
+ before: "\nend"
30
+ )
31
+ end
32
+ end
33
+ end
@@ -0,0 +1,499 @@
1
+ module Bowties
2
+ class AppBuilder < Rails::AppBuilder
3
+ include Bowties::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.test_framework :rspec
49
+ generate.view_specs false
50
+ end
51
+
52
+ RUBY
53
+
54
+ inject_into_class 'config/application.rb', 'Application', config
55
+ end
56
+
57
+ def set_up_factory_girl_for_rspec
58
+ copy_file 'factory_girl_rspec.rb', 'spec/support/factory_girl.rb'
59
+ end
60
+
61
+ def set_up_hound
62
+ copy_file "hound.yml", ".hound.yml"
63
+ end
64
+
65
+ def configure_newrelic
66
+ template 'newrelic.yml.erb', 'config/newrelic.yml'
67
+ end
68
+
69
+ def configure_smtp
70
+ copy_file 'smtp.rb', 'config/smtp.rb'
71
+
72
+ prepend_file 'config/environments/production.rb',
73
+ %{require Rails.root.join("config/smtp")\n}
74
+
75
+ config = <<-RUBY
76
+
77
+ config.action_mailer.delivery_method = :smtp
78
+ config.action_mailer.smtp_settings = SMTP_SETTINGS
79
+ RUBY
80
+
81
+ inject_into_file 'config/environments/production.rb', config,
82
+ :after => 'config.action_mailer.raise_delivery_errors = false'
83
+ end
84
+
85
+ def enable_rack_canonical_host
86
+ config = <<-RUBY
87
+
88
+ # Ensure requests are only served from one, canonical host name
89
+ config.middleware.use Rack::CanonicalHost, ENV.fetch("HOST")
90
+ RUBY
91
+
92
+ inject_into_file(
93
+ "config/environments/production.rb",
94
+ config,
95
+ after: serve_static_files_line
96
+ )
97
+ end
98
+
99
+ def enable_rack_deflater
100
+ config = <<-RUBY
101
+
102
+ # Enable deflate / gzip compression of controller-generated responses
103
+ config.middleware.use Rack::Deflater
104
+ RUBY
105
+
106
+ inject_into_file(
107
+ "config/environments/production.rb",
108
+ config,
109
+ after: serve_static_files_line
110
+ )
111
+ end
112
+
113
+ def setup_asset_host
114
+ replace_in_file 'config/environments/production.rb',
115
+ "# config.action_controller.asset_host = 'http://assets.example.com'",
116
+ 'config.action_controller.asset_host = ENV.fetch("ASSET_HOST", ENV.fetch("HOST"))'
117
+
118
+ replace_in_file 'config/initializers/assets.rb',
119
+ "config.assets.version = '1.0'",
120
+ 'config.assets.version = (ENV["ASSETS_VERSION"] || "1.0")'
121
+
122
+ inject_into_file(
123
+ "config/environments/production.rb",
124
+ ' config.static_cache_control = "public, max-age=#{1.year.to_i}"',
125
+ after: serve_static_files_line
126
+ )
127
+ end
128
+
129
+ def setup_staging_environment
130
+ staging_file = 'config/environments/staging.rb'
131
+ copy_file 'staging.rb', staging_file
132
+
133
+ config = <<-RUBY
134
+
135
+ Rails.application.configure do
136
+ # ...
137
+ end
138
+ RUBY
139
+
140
+ append_file staging_file, config
141
+ end
142
+
143
+ def setup_secret_token
144
+ template 'secrets.yml', 'config/secrets.yml', force: true
145
+ end
146
+
147
+ def disallow_wrapping_parameters
148
+ remove_file "config/initializers/wrap_parameters.rb"
149
+ end
150
+
151
+ def create_partials_directory
152
+ empty_directory 'app/views/application'
153
+ end
154
+
155
+ def create_shared_flashes
156
+ copy_file "_flashes.html.erb", "app/views/application/_flashes.html.erb"
157
+ copy_file "flashes_helper.rb", "app/helpers/flashes_helper.rb"
158
+ end
159
+
160
+ def create_shared_javascripts
161
+ copy_file '_javascript.html.erb', 'app/views/application/_javascript.html.erb'
162
+ end
163
+
164
+ def create_application_layout
165
+ template 'suspenders_layout.html.erb.erb',
166
+ 'app/views/layouts/application.html.erb',
167
+ force: true
168
+ end
169
+
170
+ def use_postgres_config_template
171
+ template 'postgresql_database.yml.erb', 'config/database.yml',
172
+ force: true
173
+ end
174
+
175
+ def create_database
176
+ bundle_command 'exec rake db:create db:migrate'
177
+ end
178
+
179
+ def replace_gemfile
180
+ remove_file 'Gemfile'
181
+ template 'Gemfile.erb', 'Gemfile'
182
+ end
183
+
184
+ def set_ruby_to_version_being_used
185
+ create_file '.ruby-version', "#{Bowties::RUBY_VERSION}\n"
186
+ end
187
+
188
+ def setup_heroku_specific_gems
189
+ inject_into_file(
190
+ "Gemfile",
191
+ %{\n\s\sgem "rails_stdout_logging"},
192
+ after: /group :staging, :production do/
193
+ )
194
+ end
195
+
196
+ def enable_database_cleaner
197
+ copy_file 'database_cleaner_rspec.rb', 'spec/support/database_cleaner.rb'
198
+ end
199
+
200
+ def configure_spec_support_features
201
+ empty_directory_with_keep_file 'spec/features'
202
+ empty_directory_with_keep_file 'spec/support/features'
203
+ end
204
+
205
+ def configure_rspec
206
+ remove_file "spec/rails_helper.rb"
207
+ remove_file "spec/spec_helper.rb"
208
+ copy_file "rails_helper.rb", "spec/rails_helper.rb"
209
+ copy_file "spec_helper.rb", "spec/spec_helper.rb"
210
+ end
211
+
212
+ def configure_ci
213
+ template "circle.yml.erb", "circle.yml"
214
+ end
215
+
216
+ def configure_i18n_for_test_environment
217
+ copy_file "i18n.rb", "spec/support/i18n.rb"
218
+ end
219
+
220
+ def configure_i18n_for_missing_translations
221
+ raise_on_missing_translations_in("development")
222
+ raise_on_missing_translations_in("test")
223
+ end
224
+
225
+ def configure_i18n_tasks
226
+ run "cp $(i18n-tasks gem-path)/templates/rspec/i18n_spec.rb spec/"
227
+ copy_file "config_i18n_tasks.yml", "config/i18n-tasks.yml"
228
+ end
229
+
230
+ def configure_background_jobs_for_rspec
231
+ run 'rails g delayed_job:active_record'
232
+ end
233
+
234
+ def configure_action_mailer_in_specs
235
+ copy_file 'action_mailer.rb', 'spec/support/action_mailer.rb'
236
+ end
237
+
238
+ def configure_time_formats
239
+ remove_file "config/locales/en.yml"
240
+ template "config_locales_en.yml.erb", "config/locales/en.yml"
241
+ end
242
+
243
+ def configure_rack_timeout
244
+ rack_timeout_config = <<-RUBY
245
+ Rack::Timeout.timeout = (ENV["RACK_TIMEOUT"] || 10).to_i
246
+ RUBY
247
+
248
+ append_file "config/environments/production.rb", rack_timeout_config
249
+ end
250
+
251
+ def configure_simple_form
252
+ bundle_command "exec rails generate simple_form:install"
253
+ end
254
+
255
+ def configure_action_mailer
256
+ action_mailer_host "development", %{"localhost:#{port}"}
257
+ action_mailer_host "test", %{"www.example.com"}
258
+ action_mailer_host "staging", %{ENV.fetch("HOST")}
259
+ action_mailer_host "production", %{ENV.fetch("HOST")}
260
+ end
261
+
262
+ def configure_active_job
263
+ configure_application_file(
264
+ "config.active_job.queue_adapter = :delayed_job"
265
+ )
266
+ configure_environment "test", "config.active_job.queue_adapter = :inline"
267
+ end
268
+
269
+ def fix_i18n_deprecation_warning
270
+ config = <<-RUBY
271
+ config.i18n.enforce_available_locales = true
272
+ RUBY
273
+
274
+ inject_into_class 'config/application.rb', 'Application', config
275
+ end
276
+
277
+ def generate_rspec
278
+ generate 'rspec:install'
279
+ end
280
+
281
+ def configure_unicorn
282
+ copy_file 'unicorn.rb', 'config/unicorn.rb'
283
+ end
284
+
285
+ def setup_foreman
286
+ copy_file 'sample.env', '.sample.env'
287
+ copy_file 'Procfile', 'Procfile'
288
+ end
289
+
290
+ def setup_stylesheets
291
+ remove_file "app/assets/stylesheets/application.css"
292
+ copy_file "application.scss",
293
+ "app/assets/stylesheets/application.scss"
294
+ end
295
+
296
+ def install_refills
297
+ run "rails generate refills:import flashes"
298
+ run "rm app/views/refills/_flashes.html.erb"
299
+ run "rmdir app/views/refills"
300
+ end
301
+
302
+ def install_bitters
303
+ run "bitters install --path app/assets/stylesheets"
304
+ end
305
+
306
+ def gitignore_files
307
+ remove_file '.gitignore'
308
+ copy_file 'suspenders_gitignore', '.gitignore'
309
+ [
310
+ 'app/views/pages',
311
+ 'spec/lib',
312
+ 'spec/controllers',
313
+ 'spec/helpers',
314
+ 'spec/support/matchers',
315
+ 'spec/support/mixins',
316
+ 'spec/support/shared_examples'
317
+ ].each do |dir|
318
+ run "mkdir #{dir}"
319
+ run "touch #{dir}/.keep"
320
+ end
321
+ end
322
+
323
+ def init_git
324
+ run 'git init'
325
+ end
326
+
327
+ def create_staging_heroku_app(flags)
328
+ rack_env = "RACK_ENV=staging RAILS_ENV=staging"
329
+ app_name = heroku_app_name_for("staging")
330
+
331
+ run_heroku "create #{app_name} #{flags}", "staging"
332
+ run_heroku "config:add #{rack_env}", "staging"
333
+ end
334
+
335
+ def create_production_heroku_app(flags)
336
+ app_name = heroku_app_name_for("production")
337
+
338
+ run_heroku "create #{app_name} #{flags}", "production"
339
+ end
340
+
341
+ def create_heroku_apps(flags)
342
+ create_staging_heroku_app(flags)
343
+ create_production_heroku_app(flags)
344
+ end
345
+
346
+ def set_heroku_remotes
347
+ remotes = <<-SHELL
348
+
349
+ # Set up the staging and production apps.
350
+ #{join_heroku_app('staging')}
351
+ #{join_heroku_app('production')}
352
+ SHELL
353
+
354
+ append_file 'bin/setup', remotes
355
+ end
356
+
357
+ def join_heroku_app(environment)
358
+ heroku_app_name = heroku_app_name_for(environment)
359
+ <<-SHELL
360
+ if heroku join --app #{heroku_app_name} &> /dev/null; then
361
+ git remote add #{environment} git@heroku.com:#{heroku_app_name}.git || true
362
+ printf 'You are a collaborator on the "#{heroku_app_name}" Heroku app\n'
363
+ else
364
+ printf 'Ask for access to the "#{heroku_app_name}" Heroku app\n'
365
+ fi
366
+ SHELL
367
+ end
368
+
369
+ def set_heroku_rails_secrets
370
+ %w(staging production).each do |environment|
371
+ run_heroku "config:add SECRET_KEY_BASE=#{generate_secret}", environment
372
+ end
373
+ end
374
+
375
+ def set_heroku_serve_static_files
376
+ %w(staging production).each do |environment|
377
+ run_heroku "config:add RAILS_SERVE_STATIC_FILES=true", environment
378
+ end
379
+ end
380
+
381
+ def provide_deploy_script
382
+ copy_file "bin_deploy", "bin/deploy"
383
+
384
+ instructions = <<-MARKDOWN
385
+
386
+ ## Deploying
387
+
388
+ If you have previously run the `./bin/setup` script,
389
+ you can deploy to staging and production with:
390
+
391
+ $ ./bin/deploy staging
392
+ $ ./bin/deploy production
393
+ MARKDOWN
394
+
395
+ append_file "README.md", instructions
396
+ run "chmod a+x bin/deploy"
397
+ end
398
+
399
+ def create_github_repo(repo_name)
400
+ path_addition = override_path_for_tests
401
+ run "#{path_addition} hub create #{repo_name}"
402
+ end
403
+
404
+ def setup_segment
405
+ copy_file '_analytics.html.erb',
406
+ 'app/views/application/_analytics.html.erb'
407
+ end
408
+
409
+ def setup_bundler_audit
410
+ copy_file "bundler_audit.rake", "lib/tasks/bundler_audit.rake"
411
+ append_file "Rakefile", %{\ntask default: "bundler:audit"\n}
412
+ end
413
+
414
+ def setup_spring
415
+ bundle_command "exec spring binstub --all"
416
+ end
417
+
418
+ def copy_miscellaneous_files
419
+ copy_file "browserslist", "browserslist"
420
+ copy_file "errors.rb", "config/initializers/errors.rb"
421
+ copy_file "json_encoding.rb", "config/initializers/json_encoding.rb"
422
+ end
423
+
424
+ def customize_error_pages
425
+ meta_tags =<<-EOS
426
+ <meta charset="utf-8" />
427
+ <meta name="ROBOTS" content="NOODP" />
428
+ <meta name="viewport" content="initial-scale=1" />
429
+ EOS
430
+
431
+ %w(500 404 422).each do |page|
432
+ inject_into_file "public/#{page}.html", meta_tags, :after => "<head>\n"
433
+ replace_in_file "public/#{page}.html", /<!--.+-->\n/, ''
434
+ end
435
+ end
436
+
437
+ def remove_routes_comment_lines
438
+ replace_in_file 'config/routes.rb',
439
+ /Rails\.application\.routes\.draw do.*end/m,
440
+ "Rails.application.routes.draw do\nend"
441
+ end
442
+
443
+ def disable_xml_params
444
+ copy_file 'disable_xml_params.rb', 'config/initializers/disable_xml_params.rb'
445
+ end
446
+
447
+ def setup_default_rake_task
448
+ append_file 'Rakefile' do
449
+ <<-EOS
450
+ task(:default).clear
451
+ task default: [:spec]
452
+
453
+ if defined? RSpec
454
+ task(:spec).clear
455
+ RSpec::Core::RakeTask.new(:spec) do |t|
456
+ t.verbose = false
457
+ end
458
+ end
459
+ EOS
460
+ end
461
+ end
462
+
463
+ private
464
+
465
+ def raise_on_missing_translations_in(environment)
466
+ config = 'config.action_view.raise_on_missing_translations = true'
467
+
468
+ uncomment_lines("config/environments/#{environment}.rb", config)
469
+ end
470
+
471
+ def override_path_for_tests
472
+ if ENV['TESTING']
473
+ support_bin = File.expand_path(File.join('..', '..', 'spec', 'fakes', 'bin'))
474
+ "PATH=#{support_bin}:$PATH"
475
+ end
476
+ end
477
+
478
+ def run_heroku(command, environment)
479
+ path_addition = override_path_for_tests
480
+ run "#{path_addition} heroku #{command} --remote #{environment}"
481
+ end
482
+
483
+ def generate_secret
484
+ SecureRandom.hex(64)
485
+ end
486
+
487
+ def port
488
+ @port ||= [3000, 4000, 5000, 7000, 8000, 9000].sample
489
+ end
490
+
491
+ def serve_static_files_line
492
+ "config.serve_static_files = ENV['RAILS_SERVE_STATIC_FILES'].present?\n"
493
+ end
494
+
495
+ def heroku_app_name_for(environment)
496
+ "#{app_name.dasherize}-#{environment}"
497
+ end
498
+ end
499
+ end