armadura 0.1.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 (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