armadura 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (75) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +5 -0
  3. data/.ruby-version +1 -0
  4. data/.travis.yml +11 -0
  5. data/Gemfile +3 -0
  6. data/LICENSE +19 -0
  7. data/README.md +218 -0
  8. data/Rakefile +8 -0
  9. data/USAGE +9 -0
  10. data/armadura.gemspec +29 -0
  11. data/bin/armadura +23 -0
  12. data/bin/rake +16 -0
  13. data/bin/rspec +16 -0
  14. data/bin/setup +13 -0
  15. data/lib/armadura.rb +7 -0
  16. data/lib/armadura/actions.rb +33 -0
  17. data/lib/armadura/adapters/heroku.rb +118 -0
  18. data/lib/armadura/app_builder.rb +484 -0
  19. data/lib/armadura/generators/app_generator.rb +245 -0
  20. data/lib/armadura/generators/static_generator.rb +10 -0
  21. data/lib/armadura/generators/stylesheet_base_generator.rb +37 -0
  22. data/lib/armadura/version.rb +8 -0
  23. data/spec/adapters/heroku_spec.rb +57 -0
  24. data/spec/fakes/bin/heroku +5 -0
  25. data/spec/fakes/bin/hub +5 -0
  26. data/spec/features/cli_help_spec.rb +36 -0
  27. data/spec/features/github_spec.rb +16 -0
  28. data/spec/features/heroku_spec.rb +75 -0
  29. data/spec/features/new_project_spec.rb +295 -0
  30. data/spec/features/sidekiq_spec.rb +30 -0
  31. data/spec/spec_helper.rb +20 -0
  32. data/spec/support/armadura.rb +83 -0
  33. data/spec/support/fake_github.rb +21 -0
  34. data/spec/support/fake_heroku.rb +53 -0
  35. data/templates/Gemfile.erb +60 -0
  36. data/templates/Procfile +2 -0
  37. data/templates/README.md.erb +28 -0
  38. data/templates/_analytics.html.erb +7 -0
  39. data/templates/_css_overrides.html.erb +7 -0
  40. data/templates/_flashes.html.erb +7 -0
  41. data/templates/_javascript.html.erb +12 -0
  42. data/templates/action_mailer.rb +5 -0
  43. data/templates/app.json.erb +39 -0
  44. data/templates/application.scss +9 -0
  45. data/templates/armadura_gitignore +14 -0
  46. data/templates/armadura_layout.html.erb.erb +22 -0
  47. data/templates/bin_deploy +12 -0
  48. data/templates/bin_setup +22 -0
  49. data/templates/bin_setup_review_app.erb +19 -0
  50. data/templates/browserslist +3 -0
  51. data/templates/bundler_audit.rake +12 -0
  52. data/templates/capybara_webkit.rb +5 -0
  53. data/templates/circle.yml.erb +6 -0
  54. data/templates/config_locales_en.yml.erb +19 -0
  55. data/templates/database_cleaner_rspec.rb +21 -0
  56. data/templates/dev.rake +12 -0
  57. data/templates/dotfiles/.ctags +2 -0
  58. data/templates/dotfiles/.env +14 -0
  59. data/templates/errors.rb +34 -0
  60. data/templates/factories.rb +2 -0
  61. data/templates/factory_girl_rspec.rb +3 -0
  62. data/templates/flashes_helper.rb +5 -0
  63. data/templates/hound.yml +14 -0
  64. data/templates/i18n.rb +3 -0
  65. data/templates/json_encoding.rb +1 -0
  66. data/templates/postgresql_database.yml.erb +21 -0
  67. data/templates/puma.rb +28 -0
  68. data/templates/rack_mini_profiler.rb +5 -0
  69. data/templates/rails_helper.rb +22 -0
  70. data/templates/secrets.yml +14 -0
  71. data/templates/shoulda_matchers_config_rspec.rb +6 -0
  72. data/templates/sidekiq.yml +6 -0
  73. data/templates/smtp.rb +13 -0
  74. data/templates/spec_helper.rb +29 -0
  75. metadata +188 -0
@@ -0,0 +1,295 @@
1
+ require "spec_helper"
2
+
3
+ RSpec.describe "Suspend a new project with default configuration" do
4
+ before(:all) do
5
+ drop_dummy_database
6
+ remove_project_directory
7
+ run_armadura
8
+ setup_app_dependencies
9
+ end
10
+
11
+ it "uses custom Gemfile" do
12
+ gemfile_file = IO.read("#{project_path}/Gemfile")
13
+ expect(gemfile_file).to match(
14
+ /^ruby "#{Armadura::RUBY_VERSION}"$/,
15
+ )
16
+ expect(gemfile_file).to match(
17
+ /^gem "autoprefixer-rails"$/,
18
+ )
19
+ expect(gemfile_file).to match(
20
+ /^gem "rails", "#{Armadura::RAILS_VERSION}"$/,
21
+ )
22
+ end
23
+
24
+ it "ensures project specs pass" do
25
+ Dir.chdir(project_path) do
26
+ Bundler.with_clean_env do
27
+ expect(`rake`).to include('0 failures')
28
+ end
29
+ end
30
+ end
31
+
32
+ it "creates .ruby-version from Armadura .ruby-version" do
33
+ ruby_version_file = IO.read("#{project_path}/.ruby-version")
34
+
35
+ expect(ruby_version_file).to eq "#{RUBY_VERSION}\n"
36
+ end
37
+
38
+ it "copies dotfiles" do
39
+ %w[.ctags .env].each do |dotfile|
40
+ expect(File).to exist("#{project_path}/#{dotfile}")
41
+ end
42
+ end
43
+
44
+ it "loads secret_key_base from env" do
45
+ secrets_file = IO.read("#{project_path}/config/secrets.yml")
46
+
47
+ expect(secrets_file).
48
+ to match(/secret_key_base: <%= ENV\["SECRET_KEY_BASE"\] %>/)
49
+ end
50
+
51
+ it "adds bin/setup file" do
52
+ expect(File).to exist("#{project_path}/bin/setup")
53
+ end
54
+
55
+ it "makes bin/setup executable" do
56
+ bin_setup_path = "#{project_path}/bin/setup"
57
+
58
+ expect(File.stat(bin_setup_path)).to be_executable
59
+ end
60
+
61
+ it "adds support file for action mailer" do
62
+ expect(File).to exist("#{project_path}/spec/support/action_mailer.rb")
63
+ end
64
+
65
+ it "configures capybara-webkit" do
66
+ expect(File).to exist("#{project_path}/spec/support/capybara_webkit.rb")
67
+ end
68
+
69
+ it "adds support file for i18n" do
70
+ expect(File).to exist("#{project_path}/spec/support/i18n.rb")
71
+ end
72
+
73
+ it "creates good default .hound.yml" do
74
+ hound_config_file = IO.read("#{project_path}/.hound.yml")
75
+
76
+ expect(hound_config_file).to include "enabled: true"
77
+ end
78
+
79
+ it "ensures Gemfile contains `rack-mini-profiler`" do
80
+ gemfile = IO.read("#{project_path}/Gemfile")
81
+
82
+ expect(gemfile).to include %{gem "rack-mini-profiler", require: false}
83
+ end
84
+
85
+ it "ensures .sample.env defaults to RACK_MINI_PROFILER=0" do
86
+ env = IO.read("#{project_path}/.env")
87
+
88
+ expect(env).to include "RACK_MINI_PROFILER=0"
89
+ end
90
+
91
+ it "creates a rack-mini-profiler initializer" do
92
+ expect(File).
93
+ to exist("#{project_path}/config/initializers/rack_mini_profiler.rb")
94
+ end
95
+
96
+ it "records pageviews through Segment if ENV variable set" do
97
+ expect(analytics_partial).
98
+ to include(%{<% if ENV["SEGMENT_KEY"] %>})
99
+ expect(analytics_partial).
100
+ to include(%{window.analytics.load("<%= ENV["SEGMENT_KEY"] %>");})
101
+ end
102
+
103
+ it "raises on unpermitted parameters in all environments" do
104
+ result = IO.read("#{project_path}/config/application.rb")
105
+
106
+ expect(result).to match(
107
+ /^ +config.action_controller.action_on_unpermitted_parameters = :raise$/
108
+ )
109
+ end
110
+
111
+ it "adds explicit quiet_assets configuration" do
112
+ result = IO.read("#{project_path}/config/application.rb")
113
+
114
+ expect(result).to match(/^ +config.assets.quiet = true$/)
115
+ end
116
+
117
+ it "configures public_file_server.headers in production" do
118
+ expect(production_config).to match(
119
+ /^ +config.public_file_server.headers = {\n +"Cache-Control" => "public,/,
120
+ )
121
+ end
122
+
123
+ it "raises on missing translations in development and test" do
124
+ [development_config, test_config].each do |environment_file|
125
+ expect(environment_file).to match(
126
+ /^ +config.action_view.raise_on_missing_translations = true$/
127
+ )
128
+ end
129
+ end
130
+
131
+ it "evaluates en.yml.erb" do
132
+ locales_en_file = IO.read("#{project_path}/config/locales/en.yml")
133
+
134
+ expect(locales_en_file).to match(/application: #{app_name.humanize}/)
135
+ end
136
+
137
+ it "configs simple_form" do
138
+ expect(File).to exist("#{project_path}/config/initializers/simple_form.rb")
139
+ end
140
+
141
+ it "configs :test email delivery method for development" do
142
+ expect(development_config).
143
+ to match(/^ +config.action_mailer.delivery_method = :file$/)
144
+ end
145
+
146
+ it "uses APPLICATION_HOST, not HOST in the production config" do
147
+ expect(production_config).to match(/"APPLICATION_HOST"/)
148
+ expect(production_config).not_to match(/"HOST"/)
149
+ end
150
+
151
+ it "configures email interceptor in smtp config" do
152
+ smtp_file = IO.read("#{project_path}/config/smtp.rb")
153
+ expect(smtp_file).
154
+ to match(/RecipientInterceptor.new\(ENV\["EMAIL_RECIPIENTS"\]\)/)
155
+ end
156
+
157
+ it "configures language in html element" do
158
+ layout_path = "/app/views/layouts/application.html.erb"
159
+ layout_file = IO.read("#{project_path}#{layout_path}")
160
+ expect(layout_file).to match(/<html lang="en">/)
161
+ end
162
+
163
+ it "configures the test environment to process queues inline" do
164
+ test_config = IO.read("#{project_path}/config/environments/test.rb")
165
+
166
+ expect(test_config).to match(
167
+ "config.active_job.queue_adapter = :inline"
168
+ )
169
+ end
170
+
171
+ it "configs bullet gem in development" do
172
+ expect(development_config).to match /^ +Bullet.enable = true$/
173
+ expect(development_config).to match /^ +Bullet.bullet_logger = true$/
174
+ expect(development_config).to match /^ +Bullet.rails_logger = true$/
175
+ end
176
+
177
+ it "configs missing assets to raise in test" do
178
+ expect(test_config).to match(
179
+ /^ +config.assets.raise_runtime_errors = true$/,
180
+ )
181
+ end
182
+
183
+ it "adds spring to binstubs" do
184
+ expect(File).to exist("#{project_path}/bin/spring")
185
+
186
+ bin_stubs = %w(rake rails rspec)
187
+ bin_stubs.each do |bin_stub|
188
+ expect(IO.read("#{project_path}/bin/#{bin_stub}")).to match(/spring/)
189
+ end
190
+ end
191
+
192
+ it "removes comments and extra newlines from config files" do
193
+ config_files = [
194
+ IO.read("#{project_path}/config/application.rb"),
195
+ IO.read("#{project_path}/config/environment.rb"),
196
+ development_config,
197
+ test_config,
198
+ production_config,
199
+ ]
200
+
201
+ config_files.each do |file|
202
+ expect(file).not_to match(/.*#.*/)
203
+ expect(file).not_to match(/^$\n/)
204
+ end
205
+ end
206
+
207
+ it "copies factories.rb" do
208
+ expect(File).to exist("#{project_path}/spec/factories.rb")
209
+ end
210
+
211
+ it "creates review apps setup script" do
212
+ bin_setup_path = "#{project_path}/bin/setup_review_app"
213
+ bin_setup = IO.read(bin_setup_path)
214
+
215
+ expect(bin_setup).to include("heroku run rake db:migrate --exit-code "\
216
+ "--app #{app_name.dasherize}-staging-pr-$1")
217
+ expect(bin_setup).to include("heroku ps:scale worker=1 "\
218
+ "--app #{app_name.dasherize}-staging-pr-$1")
219
+ expect(bin_setup).to include("heroku restart "\
220
+ "--app #{app_name.dasherize}-staging-pr-$1")
221
+ expect(File.stat(bin_setup_path)).to be_executable
222
+ end
223
+
224
+ it "creates deploy script" do
225
+ bin_deploy_path = "#{project_path}/bin/deploy"
226
+ bin_deploy = IO.read(bin_deploy_path)
227
+
228
+ expect(bin_deploy).to include("heroku run rake db:migrate --exit-code")
229
+ expect(File.stat(bin_deploy_path)).to be_executable
230
+ end
231
+
232
+ it "creates heroku application manifest file with application name in it" do
233
+ app_json_file = IO.read("#{project_path}/app.json")
234
+
235
+ expect(app_json_file).to match(/"name":"#{app_name.dasherize}"/)
236
+ end
237
+
238
+ it "sets up heroku specific gems" do
239
+ gemfile_file = IO.read("#{project_path}/Gemfile")
240
+
241
+ expect(gemfile_file).to include %{gem "rails_stdout_logging"}
242
+ end
243
+
244
+ def app_name
245
+ ArmaduraTestHelpers::APP_NAME
246
+ end
247
+
248
+ it "adds high_voltage" do
249
+ gemfile = IO.read("#{project_path}/Gemfile")
250
+ expect(gemfile).to match(/high_voltage/)
251
+ end
252
+
253
+ it "adds and configures bourbon, neat, and refills" do
254
+ gemfile = read_project_file("Gemfile")
255
+
256
+ expect(gemfile).to match(/bourbon/)
257
+ expect(gemfile).to match(/neat/)
258
+ expect(gemfile).to match(/refills/)
259
+ end
260
+
261
+ it "configures bourbon, neat, and refills" do
262
+ flashes_path = %w(app assets stylesheets refills _flashes.scss)
263
+ expect(read_project_file(flashes_path)).to match(/\$flashes/m)
264
+
265
+ app_css = read_project_file(%w(app assets stylesheets application.scss))
266
+ expect(app_css).to match(/normalize-rails.*bourbon.*neat.*base.*refills/m)
267
+ end
268
+
269
+ it "doesn't use turbolinks" do
270
+ app_js = read_project_file(%w(app assets javascripts application.js))
271
+ expect(app_js).not_to match(/turbolinks/)
272
+ end
273
+
274
+ def development_config
275
+ @_development_config ||=
276
+ read_project_file %w(config environments development.rb)
277
+ end
278
+
279
+ def test_config
280
+ @_test_config ||= read_project_file %w(config environments test.rb)
281
+ end
282
+
283
+ def production_config
284
+ @_production_config ||=
285
+ read_project_file %w(config environments production.rb)
286
+ end
287
+
288
+ def analytics_partial
289
+ IO.read("#{project_path}/app/views/application/_analytics.html.erb")
290
+ end
291
+
292
+ def read_project_file(path)
293
+ IO.read(File.join(project_path, *path))
294
+ end
295
+ end
@@ -0,0 +1,30 @@
1
+ require "spec_helper"
2
+
3
+ RSpec.describe "Sidekiq" do
4
+ before(:all) do
5
+ drop_dummy_database
6
+ remove_project_directory
7
+ run_armadura
8
+ setup_app_dependencies
9
+ end
10
+
11
+ it "adds Sidekiq to the Gemfile" do
12
+ gemfile = IO.read("#{project_path}/Gemfile")
13
+ expect(gemfile).to include("sidekiq")
14
+ end
15
+
16
+ it "creates a config/sidekiq.yml file configured with the default and mailers queues" do
17
+ sidekiq_config_file = "#{project_path}/config/sidekiq.yml"
18
+ expect(File.exist?(sidekiq_config_file)).to be true
19
+ expect(File.read(sidekiq_config_file)).to include "- default"
20
+ expect(File.read(sidekiq_config_file)).to include "- mailers"
21
+ end
22
+
23
+ it "configures ActiveJob to use Sidekiq" do
24
+ application_config = IO.read("#{project_path}/config/application.rb")
25
+
26
+ expect(application_config).to include(
27
+ "config.active_job.queue_adapter = :sidekiq"
28
+ )
29
+ end
30
+ end
@@ -0,0 +1,20 @@
1
+ require 'bundler/setup'
2
+
3
+ Bundler.require(:default, :test)
4
+
5
+ require (Pathname.new(__FILE__).dirname + '../lib/armadura').expand_path
6
+
7
+ Dir['./spec/support/**/*.rb'].each { |file| require file }
8
+
9
+ RSpec.configure do |config|
10
+ config.include ArmaduraTestHelpers
11
+
12
+ config.before(:all) do
13
+ add_fakes_to_path
14
+ create_tmp_directory
15
+ end
16
+
17
+ config.before(:each) do
18
+ FakeGithub.clear!
19
+ end
20
+ end
@@ -0,0 +1,83 @@
1
+ module ArmaduraTestHelpers
2
+ APP_NAME = "dummy_app"
3
+
4
+ def remove_project_directory
5
+ FileUtils.rm_rf(project_path)
6
+ end
7
+
8
+ def create_tmp_directory
9
+ FileUtils.mkdir_p(tmp_path)
10
+ end
11
+
12
+ def run_armadura(arguments = nil)
13
+ arguments = "--path=#{root_path} #{arguments}"
14
+ Dir.chdir(tmp_path) do
15
+ Bundler.with_clean_env do
16
+ add_fakes_to_path
17
+ `
18
+ #{armadura_bin} #{APP_NAME} #{arguments}
19
+ `
20
+ end
21
+ end
22
+ end
23
+
24
+ def armadura_help_command
25
+ Dir.chdir(tmp_path) do
26
+ Bundler.with_clean_env do
27
+ `
28
+ #{armadura_bin} -h
29
+ `
30
+ end
31
+ end
32
+ end
33
+
34
+ def setup_app_dependencies
35
+ if File.exist?(project_path)
36
+ Dir.chdir(project_path) do
37
+ Bundler.with_clean_env do
38
+ `bundle check || bundle install`
39
+ end
40
+ end
41
+ end
42
+ end
43
+
44
+ def drop_dummy_database
45
+ if File.exist?(project_path)
46
+ Dir.chdir(project_path) do
47
+ Bundler.with_clean_env do
48
+ `rake db:drop`
49
+ end
50
+ end
51
+ end
52
+ end
53
+
54
+ def add_fakes_to_path
55
+ ENV["PATH"] = "#{support_bin}:#{ENV['PATH']}"
56
+ end
57
+
58
+ def project_path
59
+ @project_path ||= Pathname.new("#{tmp_path}/#{APP_NAME}")
60
+ end
61
+
62
+ def usage_file
63
+ @usage_path ||= File.join(root_path, "USAGE")
64
+ end
65
+
66
+ private
67
+
68
+ def tmp_path
69
+ @tmp_path ||= Pathname.new("#{root_path}/tmp")
70
+ end
71
+
72
+ def armadura_bin
73
+ File.join(root_path, 'bin', 'armadura')
74
+ end
75
+
76
+ def support_bin
77
+ File.join(root_path, "spec", "fakes", "bin")
78
+ end
79
+
80
+ def root_path
81
+ File.expand_path('../../../', __FILE__)
82
+ end
83
+ end
@@ -0,0 +1,21 @@
1
+ class FakeGithub
2
+ RECORDER = File.expand_path(File.join('..', '..', 'tmp', 'hub_commands'), File.dirname(__FILE__))
3
+
4
+ def initialize(args)
5
+ @args = args
6
+ end
7
+
8
+ def run!
9
+ File.open(RECORDER, 'a') do |file|
10
+ file.write @args.join(' ')
11
+ end
12
+ end
13
+
14
+ def self.clear!
15
+ FileUtils.rm_rf RECORDER
16
+ end
17
+
18
+ def self.has_created_repo?(repo_name)
19
+ File.read(RECORDER) == "create #{repo_name}"
20
+ end
21
+ end