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.
- checksums.yaml +7 -0
- data/.gitignore +4 -0
- data/.ruby-version +1 -0
- data/CONTRIBUTING.md +43 -0
- data/Gemfile +3 -0
- data/Gemfile.lock +139 -0
- data/LICENSE +21 -0
- data/NEWS.md +351 -0
- data/README.md +166 -0
- data/Rakefile +8 -0
- data/bin/brace +18 -0
- data/bin/rake +16 -0
- data/bin/rspec +16 -0
- data/bin/setup +13 -0
- data/brace.gemspec +35 -0
- data/lib/brace.rb +4 -0
- data/lib/brace/actions.rb +25 -0
- data/lib/brace/app_builder.rb +469 -0
- data/lib/brace/generators/app_generator.rb +248 -0
- data/lib/brace/version.rb +6 -0
- data/spec/fakes/bin/heroku +5 -0
- data/spec/fakes/bin/hub +5 -0
- data/spec/features/github_spec.rb +10 -0
- data/spec/features/heroku_spec.rb +40 -0
- data/spec/features/new_project_spec.rb +115 -0
- data/spec/spec_helper.rb +24 -0
- data/spec/support/braces.rb +49 -0
- data/spec/support/fake_github.rb +21 -0
- data/spec/support/fake_heroku.rb +43 -0
- data/templates/Gemfile.erb +88 -0
- data/templates/Procfile +2 -0
- data/templates/README.md.erb +32 -0
- data/templates/_analytics.html.erb +7 -0
- data/templates/_javascript.html.erb +12 -0
- data/templates/action_mailer.rb +5 -0
- data/templates/application.css.scss +8 -0
- data/templates/bin_deploy +12 -0
- data/templates/bin_setup.erb +36 -0
- data/templates/brace_gitignore +14 -0
- data/templates/brace_layout.html.slim.erb +15 -0
- data/templates/bundler_audit.rake +12 -0
- data/templates/config_i18n_tasks.yml +13 -0
- data/templates/config_locales_en.yml.erb +19 -0
- data/templates/database_cleaner_rspec.rb +21 -0
- data/templates/development_seeds.rb +12 -0
- data/templates/devise_rspec.rb +3 -0
- data/templates/disable_xml_params.rb +3 -0
- data/templates/errors.rb +34 -0
- data/templates/factory_girl_rspec.rb +3 -0
- data/templates/i18n.rb +3 -0
- data/templates/json_encoding.rb +1 -0
- data/templates/newrelic.yml.erb +34 -0
- data/templates/postgresql_database.yml.erb +12 -0
- data/templates/rack_timeout.rb +1 -0
- data/templates/rails_helper.rb +22 -0
- data/templates/redis.rb +10 -0
- data/templates/sample.env +5 -0
- data/templates/secrets.yml +14 -0
- data/templates/sidekiq.rb +7 -0
- data/templates/sidekiq_rspec.rb +7 -0
- data/templates/smtp.rb +9 -0
- data/templates/spec_helper.rb +16 -0
- data/templates/stripe.rb +1 -0
- data/templates/vcr_helper.rb +12 -0
- metadata +197 -0
data/README.md
ADDED
@@ -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.
|
data/Rakefile
ADDED
data/bin/brace
ADDED
@@ -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
|
data/bin/rake
ADDED
@@ -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')
|
data/bin/rspec
ADDED
@@ -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')
|
data/bin/setup
ADDED
@@ -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
|
data/brace.gemspec
ADDED
@@ -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
|
data/lib/brace.rb
ADDED
@@ -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
|