underlay 1.50.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (86) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +5 -0
  3. data/.rubocop.yml +87 -0
  4. data/.ruby-version +1 -0
  5. data/CONTRIBUTING.md +46 -0
  6. data/Gemfile +5 -0
  7. data/LICENSE +21 -0
  8. data/README.md +218 -0
  9. data/RELEASING.md +16 -0
  10. data/Rakefile +10 -0
  11. data/USAGE +13 -0
  12. data/bin/rake +18 -0
  13. data/bin/rspec +18 -0
  14. data/bin/setup +13 -0
  15. data/bin/underlay +29 -0
  16. data/circle.yml +3 -0
  17. data/lib/underlay/actions.rb +41 -0
  18. data/lib/underlay/adapters/heroku.rb +133 -0
  19. data/lib/underlay/app_builder.rb +556 -0
  20. data/lib/underlay/generators/app_generator.rb +280 -0
  21. data/lib/underlay/generators/enforce_ssl_generator.rb +14 -0
  22. data/lib/underlay/generators/initialize_active_job_generator.rb +21 -0
  23. data/lib/underlay/generators/static_generator.rb +12 -0
  24. data/lib/underlay/generators/stylesheet_base_generator.rb +36 -0
  25. data/lib/underlay/version.rb +10 -0
  26. data/lib/underlay.rb +11 -0
  27. data/spec/adapters/heroku_spec.rb +78 -0
  28. data/spec/fakes/bin/heroku +9 -0
  29. data/spec/fakes/bin/hub +9 -0
  30. data/spec/features/cli_help_spec.rb +38 -0
  31. data/spec/features/github_spec.rb +18 -0
  32. data/spec/features/heroku_spec.rb +72 -0
  33. data/spec/features/new_project_spec.rb +308 -0
  34. data/spec/spec_helper.rb +22 -0
  35. data/spec/support/fake_github.rb +26 -0
  36. data/spec/support/fake_heroku.rb +58 -0
  37. data/spec/support/underlay.rb +100 -0
  38. data/templates/Gemfile.erb +81 -0
  39. data/templates/Procfile +2 -0
  40. data/templates/README.md.erb +21 -0
  41. data/templates/_analytics.html.slim +10 -0
  42. data/templates/_css_overrides.html.slim +5 -0
  43. data/templates/_flashes.html.slim +8 -0
  44. data/templates/_flashes.scss +21 -0
  45. data/templates/_javascript.html.slim +10 -0
  46. data/templates/action_mailer.rb +7 -0
  47. data/templates/active_job.rb +15 -0
  48. data/templates/app.json.erb +45 -0
  49. data/templates/application.example.yml +19 -0
  50. data/templates/application.scss +5 -0
  51. data/templates/bin_deploy +12 -0
  52. data/templates/bin_rake +12 -0
  53. data/templates/bin_setup +31 -0
  54. data/templates/bin_setup_review_app.erb +22 -0
  55. data/templates/bin_update +26 -0
  56. data/templates/browserslist +3 -0
  57. data/templates/bundler_audit.rake +6 -0
  58. data/templates/capybara.rb +22 -0
  59. data/templates/circle.yml.erb +38 -0
  60. data/templates/config_locales_en.yml.erb +19 -0
  61. data/templates/database_cleaner_rspec.rb +23 -0
  62. data/templates/dev.rake +14 -0
  63. data/templates/dvelp_gitignore +18 -0
  64. data/templates/dvelp_layout.html.slim +17 -0
  65. data/templates/errors.rb +36 -0
  66. data/templates/factories.rb +4 -0
  67. data/templates/factory_bot_rspec.rb +5 -0
  68. data/templates/flashes_helper.rb +7 -0
  69. data/templates/i18n.rb +5 -0
  70. data/templates/json_encoding.rb +3 -0
  71. data/templates/lograge.rb +11 -0
  72. data/templates/postgresql_database.yml.erb +19 -0
  73. data/templates/puma.rb +14 -0
  74. data/templates/rack_mini_profiler.rb +7 -0
  75. data/templates/rails_helper.rb +27 -0
  76. data/templates/rubocop.yml.erb +85 -0
  77. data/templates/scss-lint.yml.erb +167 -0
  78. data/templates/secrets.yml +8 -0
  79. data/templates/sentry.rb +6 -0
  80. data/templates/shoulda_matchers_config_rspec.rb +8 -0
  81. data/templates/sidekiq.yml +3 -0
  82. data/templates/slim-lint.yml.erb +28 -0
  83. data/templates/smtp.rb +15 -0
  84. data/templates/spec_helper.rb +35 -0
  85. data/underlay.gemspec +33 -0
  86. metadata +187 -0
@@ -0,0 +1,308 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'spec_helper'
4
+
5
+ RSpec.describe 'Suspend a new project with default configuration' do
6
+ before(:all) do
7
+ drop_dummy_database
8
+ remove_project_directory
9
+ run_underlay
10
+ setup_app_dependencies
11
+ end
12
+
13
+ it 'uses custom Gemfile' do
14
+ gemfile_file = IO.read("#{project_path}/Gemfile")
15
+ expect(gemfile_file).to match(
16
+ /^ruby "#{Underlay::RUBY_VERSION}"$/
17
+ )
18
+ expect(gemfile_file).to match(
19
+ /^gem "autoprefixer-rails"$/
20
+ )
21
+ expect(gemfile_file).to match(
22
+ /^gem "rails", "#{Underlay::RAILS_VERSION}"$/
23
+ )
24
+ end
25
+
26
+ it 'ensures project specs pass' do
27
+ Dir.chdir(project_path) do
28
+ Bundler.with_clean_env do
29
+ expect(`rake`).to include('0 failures')
30
+ end
31
+ end
32
+ end
33
+
34
+ it 'includes the bundle:audit task' do
35
+ Dir.chdir(project_path) do
36
+ Bundler.with_clean_env do
37
+ expect(`rails -T`).to include('rails bundle:audit')
38
+ end
39
+ end
40
+ end
41
+
42
+ it 'creates .ruby-version from Underlay .ruby-version' do
43
+ ruby_version_file = IO.read("#{project_path}/.ruby-version")
44
+
45
+ expect(ruby_version_file).to eq "#{RUBY_VERSION}\n"
46
+ end
47
+
48
+ it "doesn't generate test directory" do
49
+ expect(File).not_to exist("#{project_path}/test")
50
+ end
51
+
52
+ it 'loads secret_key_base from env' do
53
+ secrets_file = IO.read("#{project_path}/config/secrets.yml")
54
+
55
+ expect(secrets_file)
56
+ .to match(/secret_key_base: <%= ENV\["SECRET_KEY_BASE"\] %>/)
57
+ end
58
+
59
+ it 'adds bin/setup file' do
60
+ expect(File).to exist("#{project_path}/bin/setup")
61
+ end
62
+
63
+ it 'makes bin/setup executable' do
64
+ bin_setup_path = "#{project_path}/bin/setup"
65
+
66
+ expect(File.stat(bin_setup_path)).to be_executable
67
+ end
68
+
69
+ it 'adds support file for action mailer' do
70
+ expect(File).to exist("#{project_path}/spec/support/action_mailer.rb")
71
+ end
72
+
73
+ it 'configures capybara' do
74
+ expect(File).to exist("#{project_path}/spec/support/capybara.rb")
75
+ end
76
+
77
+ it 'adds support file for i18n' do
78
+ expect(File).to exist("#{project_path}/spec/support/i18n.rb")
79
+ end
80
+
81
+ it 'ensures Gemfile contains `rack-mini-profiler`' do
82
+ gemfile = IO.read("#{project_path}/Gemfile")
83
+
84
+ expect(gemfile).to include %(gem "rack-mini-profiler", require: false)
85
+ end
86
+
87
+ it 'initializes ActiveJob to avoid memory bloat' do
88
+ expect(File)
89
+ .to exist("#{project_path}/config/initializers/active_job.rb")
90
+ end
91
+
92
+ it 'creates a rack-mini-profiler initializer' do
93
+ expect(File)
94
+ .to exist("#{project_path}/config/initializers/rack_mini_profiler.rb")
95
+ end
96
+
97
+ it 'records pageviews through Google Tag Manager if ENV variable set' do
98
+ expect(analytics_partial).to include(%(if ENV['GOOGLE_TAG_ID']))
99
+ expect(analytics_partial).to include(
100
+ "https://www.googletagmanager.com/ns.html?id=\#{ENV['GOOGLE_TAG_ID']}"
101
+ )
102
+ end
103
+
104
+ it 'raises on unpermitted parameters in all environments' do
105
+ result = IO.read("#{project_path}/config/application.rb")
106
+
107
+ expect(result).to match(
108
+ /^ +config.action_controller.action_on_unpermitted_parameters = :raise$/
109
+ )
110
+ end
111
+
112
+ it 'adds explicit quiet_assets configuration' do
113
+ result = IO.read("#{project_path}/config/application.rb")
114
+
115
+ expect(result).to match(/^ +config.assets.quiet = true$/)
116
+ end
117
+
118
+ it 'configures public_file_server.headers in production' do
119
+ expect(production_config).to match(
120
+ /^ +config.public_file_server.headers = {\n +"Cache-Control" => "public,/
121
+ )
122
+ end
123
+
124
+ it 'configures production environment to enforce SSL' do
125
+ expect(production_config).to match(
126
+ /^ +config.force_ssl = true/
127
+ )
128
+ end
129
+
130
+ it 'raises on missing translations in development and test' do
131
+ [development_config, test_config].each do |environment_file|
132
+ expect(environment_file).to match(
133
+ /^ +config.action_view.raise_on_missing_translations = true$/
134
+ )
135
+ end
136
+ end
137
+
138
+ it 'evaluates en.yml.erb' do
139
+ locales_en_file = IO.read("#{project_path}/config/locales/en.yml")
140
+
141
+ expect(locales_en_file).to match(/application: #{app_name.humanize}/)
142
+ end
143
+
144
+ it 'configs simple_form' do
145
+ expect(File).to exist("#{project_path}/config/initializers/simple_form.rb")
146
+ end
147
+
148
+ it 'configs :test email delivery method for development' do
149
+ expect(development_config)
150
+ .to match(/^ +config.action_mailer.delivery_method = :file$/)
151
+ end
152
+
153
+ it 'sets action mailer default host and asset host' do
154
+ config_key = 'config\.action_mailer\.asset_host'
155
+ config_value =
156
+ %q{ENV\.fetch\("ASSET_HOST", ENV\.fetch\("APPLICATION_HOST"\)\)}
157
+ expect(production_config).to match(/#{config_key} = #{config_value}/)
158
+ end
159
+
160
+ it 'uses APPLICATION_HOST, not HOST in the production config' do
161
+ expect(production_config).to match(/"APPLICATION_HOST"/)
162
+ expect(production_config).not_to match(/"HOST"/)
163
+ end
164
+
165
+ it 'configures email interceptor in smtp config' do
166
+ smtp_file = IO.read("#{project_path}/config/smtp.rb")
167
+ expect(smtp_file)
168
+ .to match(/RecipientInterceptor.new\(ENV\["EMAIL_RECIPIENTS"\]\)/)
169
+ end
170
+
171
+ it 'configures language in html element' do
172
+ layout_path = '/app/views/layouts/application.html.slim'
173
+ layout_file = IO.read("#{project_path}#{layout_path}")
174
+ expect(layout_file).to match(/html lang="\#{I18n.locale}\"/)
175
+ end
176
+
177
+ it 'configs active job queue adapter' do
178
+ application_config = IO.read("#{project_path}/config/application.rb")
179
+
180
+ expect(application_config).to match(
181
+ /^ +config.active_job.queue_adapter = :sidekiq$/
182
+ )
183
+ expect(test_config).to match(
184
+ /^ +config.active_job.queue_adapter = :inline$/
185
+ )
186
+ expect(File).to exist("#{project_path}/config/sidekiq.yml")
187
+ end
188
+
189
+ it 'configs bullet gem in development' do
190
+ expect(development_config).to match(/^ +Bullet.enable = true$/)
191
+ expect(development_config).to match(/^ +Bullet.bullet_logger = true$/)
192
+ expect(development_config).to match(/^ +Bullet.rails_logger = true$/)
193
+ end
194
+
195
+ it 'configs missing assets to raise in test' do
196
+ expect(test_config).to match(
197
+ /^ +config.assets.raise_runtime_errors = true$/
198
+ )
199
+ end
200
+
201
+ it 'adds spring to binstubs' do
202
+ expect(File).to exist("#{project_path}/bin/spring")
203
+
204
+ bin_stubs = %w[rake rails rspec]
205
+ bin_stubs.each do |bin_stub|
206
+ expect(IO.read("#{project_path}/bin/#{bin_stub}")).to match(/spring/)
207
+ end
208
+ end
209
+
210
+ it 'removes comments and extra newlines from config files' do
211
+ config_files = [
212
+ IO.read("#{project_path}/config/application.rb"),
213
+ IO.read("#{project_path}/config/environment.rb"),
214
+ development_config,
215
+ test_config,
216
+ production_config
217
+ ]
218
+
219
+ config_files.each do |file|
220
+ expect(file).not_to match(/.*#.*/)
221
+ expect(file).not_to match(/^$\n/)
222
+ end
223
+ end
224
+
225
+ it 'copies factories.rb' do
226
+ expect(File).to exist("#{project_path}/spec/factories.rb")
227
+ end
228
+
229
+ it 'creates review apps setup script' do
230
+ bin_setup_path = "#{project_path}/bin/setup_review_app"
231
+ bin_setup = IO.read(bin_setup_path)
232
+
233
+ expect(bin_setup).to include(
234
+ "PARENT_APP_NAME=#{app_name.dasherize}-staging"
235
+ )
236
+ expect(bin_setup).to include("APP_NAME=#{app_name.dasherize}-staging-pr-$1")
237
+ expect(bin_setup)
238
+ .to include('heroku run rails db:migrate --exit-code --app $APP_NAME')
239
+ expect(bin_setup).to include('heroku ps:scale worker=1 --app $APP_NAME')
240
+ expect(bin_setup).to include('heroku restart --app $APP_NAME')
241
+
242
+ expect(File.stat(bin_setup_path)).to be_executable
243
+ end
244
+
245
+ it 'creates deploy script' do
246
+ bin_deploy_path = "#{project_path}/bin/deploy"
247
+ bin_deploy = IO.read(bin_deploy_path)
248
+
249
+ expect(bin_deploy).to include('heroku run rails db:migrate --exit-code')
250
+ expect(File.stat(bin_deploy_path)).to be_executable
251
+ end
252
+
253
+ it 'creates heroku application manifest file with application name in it' do
254
+ app_json_file = IO.read("#{project_path}/app.json")
255
+
256
+ expect(app_json_file).to match(/"name":"#{app_name.dasherize}"/)
257
+ end
258
+
259
+ def app_name
260
+ UnderlayTestHelpers::APP_NAME
261
+ end
262
+
263
+ it 'adds high_voltage' do
264
+ gemfile = IO.read("#{project_path}/Gemfile")
265
+ expect(gemfile).to match(/high_voltage/)
266
+ end
267
+
268
+ it 'configures flashes' do
269
+ flashes_path = %w[app assets stylesheets partials _flashes.scss]
270
+ expect(read_project_file(flashes_path)).to match(/\.flash-alert/m)
271
+
272
+ app_css = read_project_file(%w[app assets stylesheets application.scss])
273
+ expect(app_css).to match(%r{normalize\.css\/normalize\.css/})
274
+ expect(app_css).to match(%r{partials\/_flashes.scss/})
275
+ end
276
+
277
+ it "doesn't use turbolinks" do
278
+ app_js = read_project_file(%w[app assets javascripts application.js])
279
+ expect(app_js).not_to match(/turbolinks/)
280
+ end
281
+
282
+ it 'configures Timecop safe mode' do
283
+ spec_helper = read_project_file(%w[spec spec_helper.rb])
284
+ expect(spec_helper).to match(/Timecop.safe_mode = true/)
285
+ end
286
+
287
+ def development_config
288
+ @development_config ||=
289
+ read_project_file %w[config environments development.rb]
290
+ end
291
+
292
+ def test_config
293
+ @test_config ||= read_project_file %w[config environments test.rb]
294
+ end
295
+
296
+ def production_config
297
+ @production_config ||=
298
+ read_project_file %w[config environments production.rb]
299
+ end
300
+
301
+ def analytics_partial
302
+ IO.read("#{project_path}/app/views/application/_analytics.html.slim")
303
+ end
304
+
305
+ def read_project_file(path)
306
+ IO.read(File.join(project_path, *path))
307
+ end
308
+ end
@@ -0,0 +1,22 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'bundler/setup'
4
+
5
+ Bundler.require(:default, :test)
6
+
7
+ require(Pathname.new(__FILE__).dirname + '../lib/underlay').expand_path
8
+
9
+ Dir['./spec/support/**/*.rb'].each { |file| require file }
10
+
11
+ RSpec.configure do |config|
12
+ config.include UnderlayTestHelpers
13
+
14
+ config.before(:all) do
15
+ add_fakes_to_path
16
+ create_tmp_directory
17
+ end
18
+
19
+ config.before(:each) do
20
+ FakeGithub.clear!
21
+ end
22
+ end
@@ -0,0 +1,26 @@
1
+ # frozen_string_literal: true
2
+
3
+ class FakeGithub
4
+ RECORDER = File.expand_path(
5
+ File.join('..', '..', 'tmp', 'hub_commands'),
6
+ File.dirname(__FILE__)
7
+ )
8
+
9
+ def initialize(args)
10
+ @args = args
11
+ end
12
+
13
+ def run!
14
+ File.open(RECORDER, 'a') do |file|
15
+ file.write @args.join(' ')
16
+ end
17
+ end
18
+
19
+ def self.clear!
20
+ FileUtils.rm_rf RECORDER
21
+ end
22
+
23
+ def self.has_created_repo?(repo_name)
24
+ File.read(RECORDER) == "create #{repo_name}"
25
+ end
26
+ end
@@ -0,0 +1,58 @@
1
+ # frozen_string_literal: true
2
+
3
+ class FakeHeroku
4
+ RECORDER = File.expand_path(
5
+ File.join('..', '..', 'tmp', 'heroku_commands'),
6
+ File.dirname(__FILE__)
7
+ )
8
+
9
+ def initialize(args)
10
+ @args = args
11
+ end
12
+
13
+ def run!
14
+ if @args.first == 'help'
15
+ puts 'pipelines # manage collections of apps in pipelines'
16
+ end
17
+ File.open(RECORDER, 'a') do |file|
18
+ file.puts @args.join(' ')
19
+ end
20
+ end
21
+
22
+ def self.clear!
23
+ FileUtils.rm_rf RECORDER
24
+ end
25
+
26
+ def self.has_gem_included?(project_path, gem_name)
27
+ gemfile = File.open(File.join(project_path, 'Gemfile'), 'a')
28
+
29
+ File.foreach(gemfile).any? do |line|
30
+ line.match(/#{Regexp.quote(gem_name)}/)
31
+ end
32
+ end
33
+
34
+ def self.has_created_app_for?(environment, flags = nil)
35
+ app_name = "#{UnderlayTestHelpers::APP_NAME.dasherize}-#{environment}"
36
+
37
+ command = if flags
38
+ "create #{app_name} #{flags} --remote #{environment}\n"
39
+ else
40
+ "create #{app_name} --remote #{environment}\n"
41
+ end
42
+
43
+ File.foreach(RECORDER).any? { |line| line == command }
44
+ end
45
+
46
+ def self.has_configured_vars?(remote_name, var)
47
+ commands_ran =~ /^config:add #{var}=.+ --remote #{remote_name}\n/
48
+ end
49
+
50
+ def self.has_setup_pipeline_for?(app_name)
51
+ commands_ran =~ /^pipelines:create #{app_name} -a #{app_name}-staging --stage staging/ &&
52
+ commands_ran =~ /^pipelines:add #{app_name} -a #{app_name}-production --stage production/
53
+ end
54
+
55
+ def self.commands_ran
56
+ @commands_ran ||= File.read(RECORDER)
57
+ end
58
+ end
@@ -0,0 +1,100 @@
1
+ # frozen_string_literal: true
2
+
3
+ module UnderlayTestHelpers
4
+ APP_NAME = 'dummy_app'
5
+
6
+ def remove_project_directory
7
+ FileUtils.rm_rf(project_path)
8
+ end
9
+
10
+ def create_tmp_directory
11
+ FileUtils.mkdir_p(tmp_path)
12
+ end
13
+
14
+ def run_underlay(arguments = nil)
15
+ arguments = "--path=#{root_path} #{arguments}"
16
+ Dir.chdir(tmp_path) do
17
+ Bundler.with_clean_env do
18
+ add_fakes_to_path
19
+ `
20
+ #{underlay_bin} #{APP_NAME} #{arguments}
21
+ `
22
+ Dir.chdir(APP_NAME) do
23
+ with_env('HOME', tmp_path) do
24
+ `git add .`
25
+ `git commit -m 'Initial commit'`
26
+ end
27
+ end
28
+ end
29
+ end
30
+ end
31
+
32
+ def underlay_help_command
33
+ Dir.chdir(tmp_path) do
34
+ Bundler.with_clean_env do
35
+ `
36
+ #{underlay_bin} -h
37
+ `
38
+ end
39
+ end
40
+ end
41
+
42
+ def setup_app_dependencies
43
+ if File.exist?(project_path)
44
+ Dir.chdir(project_path) do
45
+ Bundler.with_clean_env do
46
+ `bundle check || bundle install`
47
+ end
48
+ end
49
+ end
50
+ end
51
+
52
+ def drop_dummy_database
53
+ if File.exist?(project_path)
54
+ Dir.chdir(project_path) do
55
+ Bundler.with_clean_env do
56
+ `rails db:drop`
57
+ end
58
+ end
59
+ end
60
+ end
61
+
62
+ def add_fakes_to_path
63
+ ENV['PATH'] = "#{support_bin}:#{ENV['PATH']}"
64
+ end
65
+
66
+ def project_path
67
+ @project_path ||= Pathname.new("#{tmp_path}/#{APP_NAME}")
68
+ end
69
+
70
+ def usage_file
71
+ @usage_file ||= File.join(root_path, 'USAGE')
72
+ end
73
+
74
+ private
75
+
76
+ def tmp_path
77
+ @tmp_path ||= Pathname.new("#{root_path}/tmp")
78
+ end
79
+
80
+ def underlay_bin
81
+ File.join(root_path, 'bin', 'underlay')
82
+ end
83
+
84
+ def support_bin
85
+ File.join(root_path, 'spec', 'fakes', 'bin')
86
+ end
87
+
88
+ def root_path
89
+ File.expand_path('../..', __dir__)
90
+ end
91
+
92
+ def with_env(name, new_value)
93
+ prior = ENV[name]
94
+ ENV[name] = new_value.to_s
95
+
96
+ yield
97
+ ensure
98
+ ENV[name] = prior
99
+ end
100
+ end
@@ -0,0 +1,81 @@
1
+ # frozen_string_literal: true
2
+
3
+ source 'https://rubygems.org'
4
+
5
+ git_source(:github) do |repo_name|
6
+ repo_name = "#{repo_name}/#{repo_name}" unless repo_name.include?('/')
7
+ "https://github.com/#{repo_name}.git"
8
+ end
9
+
10
+ ruby '<%= Underlay::RUBY_VERSION %>'
11
+
12
+ <% unless options[:api] -%>
13
+ gem 'autoprefixer-rails'
14
+ gem 'flutie'
15
+ gem 'jquery-rails'
16
+ gem 'sass-rails', '~> 5.0'
17
+ gem 'simple_form'
18
+ gem 'slim'
19
+ gem 'sprockets', '>= 3.0.0'
20
+ gem 'uglifier'
21
+ <% end -%>
22
+ gem 'figaro'
23
+ gem 'lograge'
24
+ gem 'pg'
25
+ gem 'puma'
26
+ gem 'rack-canonical-host'
27
+ gem 'rails', '<%= Underlay::RAILS_VERSION %>'
28
+ gem 'recipient_interceptor'
29
+ gem 'sentry-raven'
30
+ gem 'sidekiq'
31
+ gem 'skylight'
32
+ <% if options[:twilio_base] -%>
33
+ gem 'twilio_base', '~> 0.3.7', git: 'https://github.com/DVELP/twilio_base'
34
+ <% end -%>
35
+ <% if options[:webpack] %>
36
+ gem 'webpacker'
37
+ <% end -%>
38
+
39
+ group :development do
40
+ gem 'listen'
41
+ gem 'rack-mini-profiler', require: false
42
+ gem 'spring'
43
+ gem 'spring-commands-rspec'
44
+ <% unless options[:api] -%>
45
+ gem 'web-console'
46
+ <% end -%>
47
+ end
48
+
49
+ group :development, :test do
50
+ gem 'awesome_print'
51
+ gem 'bullet'
52
+ gem 'bundler-audit', '>= 0.5.0', require: false
53
+ gem 'factory_bot_rails'
54
+ gem 'pry-byebug'
55
+ gem 'pry-rails'
56
+ gem 'rspec-rails', '~> 3.6'
57
+ gem 'rubocop', require: false
58
+ <% unless options[:api] -%>
59
+ gem 'scss_lint', require: false
60
+ gem 'slim_lint', require: false
61
+ <% end -%>
62
+ end
63
+
64
+ group :test do
65
+ <% unless options[:api] %>
66
+ gem 'capybara'
67
+ gem 'formulaic'
68
+ gem 'phantomjs'
69
+ gem 'poltergeist'
70
+ <% end -%>
71
+ gem 'database_cleaner'
72
+ gem 'launchy'
73
+ gem 'shoulda-matchers'
74
+ gem 'simplecov', require: false
75
+ gem 'timecop'
76
+ gem 'webmock'
77
+ end
78
+
79
+ group :production do
80
+ gem 'rack-timeout'
81
+ end
@@ -0,0 +1,2 @@
1
+ web: bundle exec puma -p $PORT -C ./config/puma.rb
2
+ worker: bundle exec sidekiq -v
@@ -0,0 +1,21 @@
1
+ # <%= app_name.humanize %>
2
+
3
+ ## Getting Started
4
+ Run the setup script to install dependencies and get the app running on your machine
5
+ :
6
+ % ./bin/setup
7
+
8
+ After setting up, you can run the application using [Heroku Local]:
9
+
10
+ % heroku local
11
+
12
+ Learn more about [Heroku Local](https://devcenter.heroku.com/articles/heroku-local)
13
+
14
+ ## Guidelines
15
+ Use the following guide for programming well, programming in style and getting things done:
16
+
17
+ * [DVELP Cookbook](https://github.com/DVELP/cookbook)
18
+
19
+ ## Specs & Linting
20
+ CI is setup to run both linting and rspec. To avoid unnecessary delay with code
21
+ reviews ensure you run `bin/rake` before raising a pull request.
@@ -0,0 +1,10 @@
1
+ - if ENV['GOOGLE_TAG_ID']
2
+ /! Google Tag Manager (noscript)
3
+ noscript
4
+ iframe{
5
+ src="https://www.googletagmanager.com/ns.html?id=#{ENV['GOOGLE_TAG_ID'}"
6
+ height="0"
7
+ width="0"
8
+ style="display:none;visibility:hidden"
9
+ }
10
+ /! End Google Tag Manager (noscript)
@@ -0,0 +1,5 @@
1
+ - if Rails.env.test?
2
+ style type="text/css"
3
+ * {
4
+ transition-property: none !important;
5
+ }
@@ -0,0 +1,8 @@
1
+ - if user_facing_flashes.any?
2
+ .notification-wrap
3
+ - user_facing_flashes.each do |alert_type, msg|
4
+ .notification class=(alert_type + ' js-flash-alert')
5
+ .notification-body
6
+ = msg
7
+ = link_to(sprite_tag('cross', class: 'svgIcon'), '#',
8
+ class: 'notification-close js-flash-alert-close')
@@ -0,0 +1,21 @@
1
+ .flash-alert {
2
+ border-radius: 5px;
3
+ height: 60px;
4
+ margin: rem-calc(20 0);
5
+ position: relative;
6
+ transition: height 0.8s ease, opacity 0.4s ease;
7
+ }
8
+ .flash-alert.is-transparent {
9
+ height: 0;
10
+ margin: 0;
11
+ opacity: 0;
12
+ }
13
+ .flash-alert p {
14
+ padding: rem-calc(20);
15
+ }
16
+ .flash-alert-close {
17
+ cursor: pointer;
18
+ position: absolute;
19
+ right: rem-calc(35);
20
+ top: rem-calc(20);
21
+ }
@@ -0,0 +1,10 @@
1
+ = javascript_include_tag :application
2
+
3
+ = yield :javascript
4
+
5
+ = render "analytics"
6
+
7
+ - if Rails.env.test?
8
+ = javascript_tag do
9
+ $.fx.off = true;
10
+ $.ajaxSetup({ async: false });
@@ -0,0 +1,7 @@
1
+ # frozen_string_literal: true
2
+
3
+ RSpec.configure do |config|
4
+ config.before(:each) do
5
+ ActionMailer::Base.deliveries.clear
6
+ end
7
+ end