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,238 @@
1
+ require 'rails/generators'
2
+ require 'rails/generators/rails/app/app_generator'
3
+
4
+ module Bowties
5
+ class AppGenerator < Rails::Generators::AppGenerator
6
+ class_option :database, type: :string, aliases: "-d", default: "postgresql",
7
+ desc: "Configure for selected database (options: #{DATABASES.join("/")})"
8
+
9
+ class_option :heroku, type: :boolean, aliases: "-H", default: false,
10
+ desc: "Create staging and production Heroku apps"
11
+
12
+ class_option :heroku_flags, type: :string, default: "",
13
+ desc: "Set extra Heroku flags"
14
+
15
+ class_option :github, type: :string, aliases: "-G", default: nil,
16
+ desc: "Create Github repository and add remote origin pointed to repo"
17
+
18
+ class_option :skip_test_unit, type: :boolean, aliases: "-T", default: true,
19
+ desc: "Skip Test::Unit files"
20
+
21
+ class_option :skip_turbolinks, type: :boolean, default: true,
22
+ desc: "Skip turbolinks gem"
23
+
24
+ class_option :skip_bundle, type: :boolean, aliases: "-B", default: true,
25
+ desc: "Don't run bundle install"
26
+
27
+ def finish_template
28
+ invoke :bowties_customization
29
+ super
30
+ end
31
+
32
+ def bowties_customization
33
+ invoke :customize_gemfile
34
+ invoke :setup_development_environment
35
+ invoke :setup_test_environment
36
+ invoke :setup_production_environment
37
+ invoke :setup_staging_environment
38
+ invoke :setup_secret_token
39
+ invoke :create_bowties_views
40
+ invoke :configure_app
41
+ invoke :setup_stylesheets
42
+ invoke :install_bitters
43
+ invoke :install_refills
44
+ invoke :copy_miscellaneous_files
45
+ invoke :customize_error_pages
46
+ invoke :remove_routes_comment_lines
47
+ invoke :setup_git
48
+ invoke :setup_database
49
+ invoke :create_heroku_apps
50
+ invoke :create_github_repo
51
+ invoke :setup_segment
52
+ invoke :setup_bundler_audit
53
+ invoke :setup_spring
54
+ invoke :outro
55
+ end
56
+
57
+ def customize_gemfile
58
+ build :replace_gemfile
59
+ build :set_ruby_to_version_being_used
60
+
61
+ if options[:heroku]
62
+ build :setup_heroku_specific_gems
63
+ end
64
+
65
+ bundle_command 'install'
66
+ end
67
+
68
+ def setup_database
69
+ say 'Setting up database'
70
+
71
+ if 'postgresql' == options[:database]
72
+ build :use_postgres_config_template
73
+ end
74
+
75
+ build :create_database
76
+ end
77
+
78
+ def setup_development_environment
79
+ say 'Setting up the development environment'
80
+ build :raise_on_delivery_errors
81
+ build :set_test_delivery_method
82
+ build :raise_on_unpermitted_parameters
83
+ build :provide_setup_script
84
+ build :provide_dev_prime_task
85
+ build :configure_generators
86
+ build :configure_i18n_for_missing_translations
87
+ end
88
+
89
+ def setup_test_environment
90
+ say 'Setting up the test environment'
91
+ build :set_up_factory_girl_for_rspec
92
+ build :set_up_hound
93
+ build :generate_rspec
94
+ build :configure_rspec
95
+ build :configure_background_jobs_for_rspec
96
+ build :enable_database_cleaner
97
+ build :configure_spec_support_features
98
+ build :configure_ci
99
+ build :configure_i18n_for_test_environment
100
+ build :configure_i18n_tasks
101
+ build :configure_action_mailer_in_specs
102
+ end
103
+
104
+ def setup_production_environment
105
+ say 'Setting up the production environment'
106
+ build :configure_newrelic
107
+ build :configure_smtp
108
+ build :configure_rack_timeout
109
+ build :enable_rack_canonical_host
110
+ build :enable_rack_deflater
111
+ build :setup_asset_host
112
+ end
113
+
114
+ def setup_staging_environment
115
+ say 'Setting up the staging environment'
116
+ build :setup_staging_environment
117
+ end
118
+
119
+ def setup_secret_token
120
+ say 'Moving secret token out of version control'
121
+ build :setup_secret_token
122
+ end
123
+
124
+ def create_bowties_views
125
+ say 'Creating bowties views'
126
+ build :create_partials_directory
127
+ build :create_shared_flashes
128
+ build :create_shared_javascripts
129
+ build :create_application_layout
130
+ end
131
+
132
+ def configure_app
133
+ say 'Configuring app'
134
+ build :configure_action_mailer
135
+ build :configure_active_job
136
+ build :configure_time_formats
137
+ build :configure_simple_form
138
+ build :disable_xml_params
139
+ build :fix_i18n_deprecation_warning
140
+ build :setup_default_rake_task
141
+ build :configure_unicorn
142
+ build :setup_foreman
143
+ end
144
+
145
+ def setup_stylesheets
146
+ say 'Set up stylesheets'
147
+ build :setup_stylesheets
148
+ end
149
+
150
+ def install_bitters
151
+ say 'Install Bitters'
152
+ build :install_bitters
153
+ end
154
+
155
+ def install_refills
156
+ say "Install Refills"
157
+ build :install_refills
158
+ end
159
+
160
+ def setup_git
161
+ if !options[:skip_git]
162
+ say 'Initializing git'
163
+ invoke :setup_gitignore
164
+ invoke :init_git
165
+ end
166
+ end
167
+
168
+ def create_heroku_apps
169
+ if options[:heroku]
170
+ say "Creating Heroku apps"
171
+ build :create_heroku_apps, options[:heroku_flags]
172
+ build :set_heroku_serve_static_files
173
+ build :set_heroku_remotes
174
+ build :set_heroku_rails_secrets
175
+ build :provide_deploy_script
176
+ end
177
+ end
178
+
179
+ def create_github_repo
180
+ if !options[:skip_git] && options[:github]
181
+ say 'Creating Github repo'
182
+ build :create_github_repo, options[:github]
183
+ end
184
+ end
185
+
186
+ def setup_segment
187
+ say 'Setting up Segment'
188
+ build :setup_segment
189
+ end
190
+
191
+ def setup_gitignore
192
+ build :gitignore_files
193
+ end
194
+
195
+ def setup_bundler_audit
196
+ say "Setting up bundler-audit"
197
+ build :setup_bundler_audit
198
+ end
199
+
200
+ def setup_spring
201
+ say "Springifying binstubs"
202
+ build :setup_spring
203
+ end
204
+
205
+ def init_git
206
+ build :init_git
207
+ end
208
+
209
+ def copy_miscellaneous_files
210
+ say 'Copying miscellaneous support files'
211
+ build :copy_miscellaneous_files
212
+ end
213
+
214
+ def customize_error_pages
215
+ say 'Customizing the 500/404/422 pages'
216
+ build :customize_error_pages
217
+ end
218
+
219
+ def remove_routes_comment_lines
220
+ build :remove_routes_comment_lines
221
+ end
222
+
223
+ def outro
224
+ say 'Congratulations! You just pulled our bowties.'
225
+ say "Remember to run 'rails generate airbrake' with your API key."
226
+ end
227
+
228
+ protected
229
+
230
+ def get_builder_class
231
+ Bowties::AppBuilder
232
+ end
233
+
234
+ def using_active_record?
235
+ !options[:skip_active_record]
236
+ end
237
+ end
238
+ end
@@ -0,0 +1,5 @@
1
+ module Bowties
2
+ RAILS_VERSION = "~> 4.2.0"
3
+ RUBY_VERSION = IO.read("#{File.dirname(__FILE__)}/../../.ruby-version").strip
4
+ VERSION = "2.0.0"
5
+ end
@@ -0,0 +1,5 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require File.expand_path(File.join('..', '..', 'support', 'fake_heroku'), File.dirname(__FILE__))
4
+
5
+ FakeHeroku.new(ARGV).run!
@@ -0,0 +1,5 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require File.expand_path(File.join('..', '..', 'support', 'fake_github'), File.dirname(__FILE__))
4
+
5
+ FakeGithub.new(ARGV).run!
@@ -0,0 +1,15 @@
1
+ require "spec_helper"
2
+
3
+ RSpec.describe "GitHub" do
4
+ before do
5
+ drop_dummy_database
6
+ remove_project_directory
7
+ end
8
+
9
+ it "suspends a project with --github option" do
10
+ repo_name = 'test'
11
+ run_bowties("--github=#{repo_name}")
12
+
13
+ expect(FakeGithub).to have_created_repo(repo_name)
14
+ end
15
+ end
@@ -0,0 +1,46 @@
1
+ require "spec_helper"
2
+
3
+ RSpec.describe "Heroku" do
4
+ before do
5
+ drop_dummy_database
6
+ remove_project_directory
7
+ end
8
+
9
+ it "suspends a project for Heroku" do
10
+ run_bowties("--heroku=true")
11
+
12
+ expect(FakeHeroku).to(
13
+ have_gem_included(project_path, "rails_stdout_logging")
14
+ )
15
+ expect(FakeHeroku).to have_created_app_for("staging")
16
+ expect(FakeHeroku).to have_created_app_for("production")
17
+ expect(FakeHeroku).to have_configured_vars("staging", "SECRET_KEY_BASE")
18
+ expect(FakeHeroku).to have_configured_vars("production", "SECRET_KEY_BASE")
19
+
20
+ bin_setup_path = "#{project_path}/bin/setup"
21
+ bin_setup = IO.read(bin_setup_path)
22
+ app_name = BowtiesTestHelpers::APP_NAME.dasherize
23
+
24
+ expect(bin_setup).to include("heroku join --app #{app_name}-production")
25
+ expect(bin_setup).to include("heroku join --app #{app_name}-staging")
26
+ expect(File.stat(bin_setup_path)).to be_executable
27
+
28
+ bin_deploy_path = "#{project_path}/bin/deploy"
29
+ bin_deploy = IO.read(bin_deploy_path)
30
+
31
+ expect(bin_deploy).to include("heroku run rake db:migrate")
32
+ expect(File.stat(bin_deploy_path)).to be_executable
33
+
34
+ readme = IO.read("#{project_path}/README.md")
35
+
36
+ expect(readme).to include("./bin/deploy staging")
37
+ expect(readme).to include("./bin/deploy production")
38
+ end
39
+
40
+ it "suspends a project with extra Heroku flags" do
41
+ run_bowties(%{--heroku=true --heroku-flags="--region eu"})
42
+
43
+ expect(FakeHeroku).to have_created_app_for("staging", "--region eu")
44
+ expect(FakeHeroku).to have_created_app_for("production", "--region eu")
45
+ end
46
+ end
@@ -0,0 +1,135 @@
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_bowties
8
+ end
9
+
10
+ it "ensures project specs pass" do
11
+ Dir.chdir(project_path) do
12
+ Bundler.with_clean_env do
13
+ expect(`rake`).to include('0 failures')
14
+ end
15
+ end
16
+ end
17
+
18
+ it "inherits staging config from production" do
19
+ staging_file = IO.read("#{project_path}/config/environments/staging.rb")
20
+ config_stub = "Rails.application.configure do"
21
+
22
+ expect(staging_file).to match(/^require_relative "production"/)
23
+ expect(staging_file).to match(/#{config_stub}/), staging_file
24
+ end
25
+
26
+ it "creates .ruby-version from bowties .ruby-version" do
27
+ ruby_version_file = IO.read("#{project_path}/.ruby-version")
28
+
29
+ expect(ruby_version_file).to eq "#{RUBY_VERSION}\n"
30
+ end
31
+
32
+ it "loads secret_key_base from env" do
33
+ secrets_file = IO.read("#{project_path}/config/secrets.yml")
34
+
35
+ expect(secrets_file).to match(/secret_key_base: <%= ENV\["SECRET_KEY_BASE"\] %>/)
36
+ end
37
+
38
+ it "adds support file for action mailer" do
39
+ expect(File).to exist("#{project_path}/spec/support/action_mailer.rb")
40
+ end
41
+
42
+ it "adds support file for i18n" do
43
+ expect(File).to exist("#{project_path}/spec/support/i18n.rb")
44
+ end
45
+
46
+ it "creates good default .hound.yml" do
47
+ hound_config_file = IO.read("#{project_path}/.hound.yml")
48
+
49
+ expect(hound_config_file).to include "enabled: true"
50
+ end
51
+
52
+ it "ensures newrelic.yml reads NewRelic license from env" do
53
+ newrelic_file = IO.read("#{project_path}/config/newrelic.yml")
54
+
55
+ expect(newrelic_file).to match(
56
+ /license_key: "<%= ENV\["NEW_RELIC_LICENSE_KEY"\] %>"/
57
+ )
58
+ end
59
+
60
+ it "records pageviews through Segment if ENV variable set" do
61
+ expect(analytics_partial).
62
+ to include(%{<% if ENV["SEGMENT_KEY"] %>})
63
+ expect(analytics_partial).
64
+ to include(%{window.analytics.load("<%= ENV["SEGMENT_KEY"] %>");})
65
+ end
66
+
67
+ it "raises on unpermitted parameters in all environments" do
68
+ result = IO.read("#{project_path}/config/application.rb")
69
+
70
+ expect(result).to match(
71
+ /^ +config.action_controller.action_on_unpermitted_parameters = :raise$/
72
+ )
73
+ end
74
+
75
+ it "raises on missing translations in development and test" do
76
+ %w[development test].each do |environment|
77
+ environment_file =
78
+ IO.read("#{project_path}/config/environments/#{environment}.rb")
79
+ expect(environment_file).to match(
80
+ /^ +config.action_view.raise_on_missing_translations = true$/
81
+ )
82
+ end
83
+ end
84
+
85
+ it "adds specs for missing or unused translations" do
86
+ expect(File).to exist("#{project_path}/spec/i18n_spec.rb")
87
+ end
88
+
89
+ it "configs i18n-tasks" do
90
+ expect(File).to exist("#{project_path}/config/i18n-tasks.yml")
91
+ end
92
+
93
+ it "evaluates en.yml.erb" do
94
+ locales_en_file = IO.read("#{project_path}/config/locales/en.yml")
95
+ app_name = BowtiesTestHelpers::APP_NAME
96
+
97
+ expect(locales_en_file).to match(/application: #{app_name.humanize}/)
98
+ end
99
+
100
+ it "configs simple_form" do
101
+ expect(File).to exist("#{project_path}/config/initializers/simple_form.rb")
102
+ end
103
+
104
+ it "configs :test email delivery method for development" do
105
+ dev_env_file = IO.read("#{project_path}/config/environments/development.rb")
106
+ expect(dev_env_file).
107
+ to match(/^ +config.action_mailer.delivery_method = :test$/)
108
+ end
109
+
110
+ it "configs active job queue adapter" do
111
+ application_config = IO.read("#{project_path}/config/application.rb")
112
+ test_config = IO.read("#{project_path}/config/environments/test.rb")
113
+
114
+ expect(application_config).to match(
115
+ /^ +config.active_job.queue_adapter = :delayed_job$/
116
+ )
117
+ expect(test_config).to match(
118
+ /^ +config.active_job.queue_adapter = :inline$/
119
+ )
120
+ end
121
+
122
+ it "adds spring to binstubs" do
123
+ expect(File).to exist("#{project_path}/bin/spring")
124
+
125
+ spring_line = /^ +load File.expand_path\("\.\.\/spring", __FILE__\)$/
126
+ bin_stubs = %w(rake rails rspec)
127
+ bin_stubs.each do |bin_stub|
128
+ expect(IO.read("#{project_path}/bin/#{bin_stub}")).to match(spring_line)
129
+ end
130
+ end
131
+
132
+ def analytics_partial
133
+ IO.read("#{project_path}/app/views/application/_analytics.html.erb")
134
+ end
135
+ end