hitfox-suspenders 1.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 (56) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +4 -0
  3. data/.ruby-version +1 -0
  4. data/CONTRIBUTING.md +48 -0
  5. data/Gemfile +3 -0
  6. data/Gemfile.lock +139 -0
  7. data/LICENSE +21 -0
  8. data/NEWS.md +373 -0
  9. data/README.md +43 -0
  10. data/Rakefile +8 -0
  11. data/bin/hitfox-suspenders +18 -0
  12. data/bin/rake +16 -0
  13. data/bin/rspec +16 -0
  14. data/bin/setup +13 -0
  15. data/lib/suspenders/actions.rb +33 -0
  16. data/lib/suspenders/app_builder.rb +342 -0
  17. data/lib/suspenders/generators/app_generator.rb +196 -0
  18. data/lib/suspenders/version.rb +5 -0
  19. data/lib/suspenders.rb +4 -0
  20. data/spec/fakes/bin/hub +5 -0
  21. data/spec/features/github_spec.rb +10 -0
  22. data/spec/features/new_project_spec.rb +108 -0
  23. data/spec/spec_helper.rb +23 -0
  24. data/spec/support/fake_github.rb +21 -0
  25. data/spec/support/suspenders.rb +49 -0
  26. data/suspenders.gemspec +36 -0
  27. data/templates/Gemfile.erb +48 -0
  28. data/templates/README.md.erb +42 -0
  29. data/templates/_flashes.html.erb +7 -0
  30. data/templates/_javascript.html.erb +12 -0
  31. data/templates/action_mailer.rb +5 -0
  32. data/templates/application.css.scss +8 -0
  33. data/templates/bin_setup.erb +36 -0
  34. data/templates/bundler_audit.rake +12 -0
  35. data/templates/circle.yml +3 -0
  36. data/templates/config_i18n_tasks.yml +13 -0
  37. data/templates/config_locales_en.yml.erb +19 -0
  38. data/templates/database_cleaner_rspec.rb +21 -0
  39. data/templates/development_seeds.rb +12 -0
  40. data/templates/disable_xml_params.rb +3 -0
  41. data/templates/errors.rb +34 -0
  42. data/templates/factory_girl_rspec.rb +3 -0
  43. data/templates/flashes_helper.rb +5 -0
  44. data/templates/i18n.rb +3 -0
  45. data/templates/json_encoding.rb +1 -0
  46. data/templates/mandrill.rb +3 -0
  47. data/templates/postgresql_database.yml.erb +11 -0
  48. data/templates/rails_helper.rb +23 -0
  49. data/templates/sample.env +3 -0
  50. data/templates/secrets.yml +14 -0
  51. data/templates/spec_helper.rb +22 -0
  52. data/templates/staging.rb +5 -0
  53. data/templates/suspenders_gitignore +14 -0
  54. data/templates/suspenders_layout.html.erb.erb +21 -0
  55. data/templates/travis.yml.erb +21 -0
  56. metadata +187 -0
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
@@ -0,0 +1,33 @@
1
+ module Suspenders
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_application_file(config)
18
+ inject_into_file(
19
+ "config/application.rb",
20
+ "\n\n #{config}",
21
+ before: "\n end"
22
+ )
23
+ end
24
+
25
+ def configure_environment(rails_env, config)
26
+ inject_into_file(
27
+ "config/environments/#{rails_env}.rb",
28
+ "\n\n #{config}",
29
+ before: "\nend"
30
+ )
31
+ end
32
+ end
33
+ end
@@ -0,0 +1,342 @@
1
+ module Suspenders
2
+ class AppBuilder < Rails::AppBuilder
3
+ include Suspenders::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.test_framework :rspec
49
+ generate.view_specs false
50
+ end
51
+
52
+ RUBY
53
+
54
+ inject_into_class 'config/application.rb', 'Application', config
55
+ end
56
+
57
+ def set_up_factory_girl_for_rspec
58
+ copy_file 'factory_girl_rspec.rb', 'spec/support/factory_girl.rb'
59
+ end
60
+
61
+ def configure_mandrill
62
+ copy_file 'mandrill.rb', 'config/initializers/mandrill.rb'
63
+
64
+ config = <<-RUBY
65
+ config.action_mailer.delivery_method = :mandrill
66
+ RUBY
67
+
68
+ inject_into_file 'config/environments/production.rb', config,
69
+ :after => 'config.action_mailer.raise_delivery_errors = false'
70
+ end
71
+
72
+ def enable_rack_deflater
73
+ config = <<-RUBY
74
+
75
+ # Enable deflate / gzip compression of controller-generated responses
76
+ config.middleware.use Rack::Deflater
77
+ RUBY
78
+
79
+ inject_into_file(
80
+ "config/environments/production.rb",
81
+ config,
82
+ after: serve_static_files_line
83
+ )
84
+ end
85
+
86
+ def setup_staging_environment
87
+ staging_file = 'config/environments/staging.rb'
88
+ copy_file 'staging.rb', staging_file
89
+
90
+ config = <<-RUBY
91
+
92
+ Rails.application.configure do
93
+ config.secret_key_base = ENV["SECRET_KEY_BASE"]
94
+ end
95
+ RUBY
96
+
97
+ append_file staging_file, config
98
+ end
99
+
100
+ def setup_secret_token
101
+ template 'secrets.yml', 'config/secrets.yml', force: true
102
+
103
+ inject_into_file(
104
+ "config/environments/production.rb",
105
+ ' config.active_record.dump_schema_after_migration = false',
106
+ after: 'config.active_record.dump_schema_after_migration = false'
107
+ )
108
+ end
109
+
110
+ def disallow_wrapping_parameters
111
+ remove_file "config/initializers/wrap_parameters.rb"
112
+ end
113
+
114
+ def create_partials_directory
115
+ empty_directory 'app/views/application'
116
+ end
117
+
118
+ def create_shared_flashes
119
+ copy_file "_flashes.html.erb", "app/views/application/_flashes.html.erb"
120
+ copy_file "flashes_helper.rb", "app/helpers/flashes_helper.rb"
121
+ end
122
+
123
+ def create_shared_javascripts
124
+ copy_file '_javascript.html.erb', 'app/views/application/_javascript.html.erb'
125
+ end
126
+
127
+ def create_application_layout
128
+ template 'suspenders_layout.html.erb.erb',
129
+ 'app/views/layouts/application.html.erb',
130
+ force: true
131
+ end
132
+
133
+ def use_postgres_config_template
134
+ template 'postgresql_database.yml.erb', 'config/database.yml',
135
+ force: true
136
+ end
137
+
138
+ def create_database
139
+ bundle_command 'exec rake db:create db:migrate'
140
+ end
141
+
142
+ def replace_gemfile
143
+ remove_file 'Gemfile'
144
+ template 'Gemfile.erb', 'Gemfile'
145
+ end
146
+
147
+ def set_ruby_to_version_being_used
148
+ create_file '.ruby-version', "#{Suspenders::RUBY_VERSION}\n"
149
+ end
150
+
151
+ def enable_database_cleaner
152
+ copy_file 'database_cleaner_rspec.rb', 'spec/support/database_cleaner.rb'
153
+ end
154
+
155
+ def configure_spec_support_features
156
+ empty_directory_with_keep_file 'spec/features'
157
+ empty_directory_with_keep_file 'spec/support/features'
158
+ end
159
+
160
+ def configure_rspec
161
+ remove_file "spec/rails_helper.rb"
162
+ remove_file "spec/spec_helper.rb"
163
+ copy_file "rails_helper.rb", "spec/rails_helper.rb"
164
+ copy_file "spec_helper.rb", "spec/spec_helper.rb"
165
+ end
166
+
167
+ def configure_circleci
168
+ template 'circle.yml', 'circle.yml'
169
+ end
170
+
171
+ def configure_i18n_for_test_environment
172
+ copy_file "i18n.rb", "spec/support/i18n.rb"
173
+ end
174
+
175
+ def configure_i18n_for_missing_translations
176
+ raise_on_missing_translations_in("development")
177
+ raise_on_missing_translations_in("test")
178
+ end
179
+
180
+ def configure_i18n_tasks
181
+ run "cp $(i18n-tasks gem-path)/templates/rspec/i18n_spec.rb spec/"
182
+ copy_file "config_i18n_tasks.yml", "config/i18n-tasks.yml"
183
+ end
184
+
185
+ def configure_action_mailer_in_specs
186
+ copy_file 'action_mailer.rb', 'spec/support/action_mailer.rb'
187
+ end
188
+
189
+ def configure_time_formats
190
+ remove_file "config/locales/en.yml"
191
+ template "config_locales_en.yml.erb", "config/locales/en.yml"
192
+ end
193
+
194
+ def configure_rack_timeout
195
+ rack_timeout_config = <<-RUBY
196
+ Rack::Timeout.timeout = (ENV["RACK_TIMEOUT"] || 10).to_i
197
+ RUBY
198
+
199
+ append_file "config/environments/production.rb", rack_timeout_config
200
+ end
201
+
202
+ def configure_simple_form
203
+ bundle_command "exec rails generate simple_form:install"
204
+ end
205
+
206
+ def configure_action_mailer
207
+ action_mailer_host "development", %{"localhost:#{port}"}
208
+ action_mailer_host "test", %{"www.example.com"}
209
+ action_mailer_host "staging", %{ENV['WEB_ADDRESS_EXT']}
210
+ action_mailer_host "production", %{ENV['WEB_ADDRESS_EXT']}
211
+ end
212
+
213
+ def fix_i18n_deprecation_warning
214
+ config = <<-RUBY
215
+ config.i18n.enforce_available_locales = true
216
+ RUBY
217
+
218
+ inject_into_class 'config/application.rb', 'Application', config
219
+ end
220
+
221
+ def generate_rspec
222
+ generate 'rspec:install'
223
+ end
224
+
225
+ def setup_foreman
226
+ copy_file 'sample.env', '.sample.env'
227
+ end
228
+
229
+ def setup_stylesheets
230
+ remove_file 'app/assets/stylesheets/application.css'
231
+ copy_file 'application.css.scss',
232
+ 'app/assets/stylesheets/application.css.scss'
233
+ end
234
+
235
+ def install_bitters
236
+ run "bitters install --path app/assets/stylesheets"
237
+ end
238
+
239
+ def gitignore_files
240
+ remove_file '.gitignore'
241
+ copy_file 'suspenders_gitignore', '.gitignore'
242
+ [
243
+ 'app/views/pages',
244
+ 'spec/lib',
245
+ 'spec/controllers',
246
+ 'spec/helpers',
247
+ 'spec/support/matchers',
248
+ 'spec/support/mixins',
249
+ 'spec/support/shared_examples'
250
+ ].each do |dir|
251
+ run "mkdir #{dir}"
252
+ run "touch #{dir}/.keep"
253
+ end
254
+ end
255
+
256
+ def init_git
257
+ run 'git init'
258
+ end
259
+
260
+ def create_github_repo(repo_name)
261
+ path_addition = override_path_for_tests
262
+ run "#{path_addition} hub create #{repo_name}"
263
+ end
264
+
265
+ def setup_bundler_audit
266
+ copy_file "bundler_audit.rake", "lib/tasks/bundler_audit.rake"
267
+ append_file "Rakefile", %{\ntask default: "bundler:audit"\n}
268
+ end
269
+
270
+ def copy_miscellaneous_files
271
+ copy_file "errors.rb", "config/initializers/errors.rb"
272
+ copy_file "json_encoding.rb", "config/initializers/json_encoding.rb"
273
+ end
274
+
275
+ def customize_error_pages
276
+ meta_tags =<<-EOS
277
+ <meta charset="utf-8" />
278
+ <meta name="ROBOTS" content="NOODP" />
279
+ <meta name="viewport" content="initial-scale=1" />
280
+ EOS
281
+
282
+ %w(500 404 422).each do |page|
283
+ inject_into_file "public/#{page}.html", meta_tags, :after => "<head>\n"
284
+ replace_in_file "public/#{page}.html", /<!--.+-->\n/, ''
285
+ end
286
+ end
287
+
288
+ def remove_routes_comment_lines
289
+ replace_in_file 'config/routes.rb',
290
+ /Rails\.application\.routes\.draw do.*end/m,
291
+ "Rails.application.routes.draw do\nend"
292
+ end
293
+
294
+ def disable_xml_params
295
+ copy_file 'disable_xml_params.rb', 'config/initializers/disable_xml_params.rb'
296
+ end
297
+
298
+ def setup_default_rake_task
299
+ append_file 'Rakefile' do
300
+ <<-EOS
301
+ task(:default).clear
302
+ task default: [:spec]
303
+
304
+ if defined? RSpec
305
+ task(:spec).clear
306
+ RSpec::Core::RakeTask.new(:spec) do |t|
307
+ t.verbose = false
308
+ end
309
+ end
310
+ EOS
311
+ end
312
+ end
313
+
314
+ private
315
+
316
+ def raise_on_missing_translations_in(environment)
317
+ config = 'config.action_view.raise_on_missing_translations = true'
318
+
319
+ uncomment_lines("config/environments/#{environment}.rb", config)
320
+ end
321
+
322
+ def override_path_for_tests
323
+ if ENV['TESTING']
324
+ support_bin = File.expand_path(File.join('..', '..', 'spec', 'fakes', 'bin'))
325
+ "PATH=#{support_bin}:$PATH"
326
+ end
327
+ end
328
+
329
+ def generate_secret
330
+ SecureRandom.hex(64)
331
+ end
332
+
333
+ def port
334
+ @port ||= [3000, 4000, 5000, 7000, 8000, 9000].sample
335
+ end
336
+
337
+ def serve_static_files_line
338
+ "config.serve_static_files = ENV['RAILS_SERVE_STATIC_FILES'].present?\n"
339
+ end
340
+
341
+ end
342
+ end
@@ -0,0 +1,196 @@
1
+ require 'rails/generators'
2
+ require 'rails/generators/rails/app/app_generator'
3
+
4
+ module Suspenders
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 :github, type: :string, aliases: "-G", default: nil,
10
+ desc: "Create Github repository and add remote origin pointed to repo"
11
+
12
+ class_option :skip_test_unit, type: :boolean, aliases: "-T", default: true,
13
+ desc: "Skip Test::Unit files"
14
+
15
+ class_option :skip_turbolinks, type: :boolean, default: true,
16
+ desc: "Skip turbolinks gem"
17
+
18
+ class_option :skip_bundle, type: :boolean, aliases: "-B", default: true,
19
+ desc: "Don't run bundle install"
20
+
21
+ def finish_template
22
+ invoke :suspenders_customization
23
+ super
24
+ end
25
+
26
+ def suspenders_customization
27
+ invoke :customize_gemfile
28
+ invoke :setup_development_environment
29
+ invoke :setup_test_environment
30
+ invoke :setup_production_environment
31
+ invoke :setup_staging_environment
32
+ invoke :setup_secret_token
33
+ invoke :create_suspenders_views
34
+ invoke :configure_app
35
+ invoke :setup_stylesheets
36
+ invoke :install_bitters
37
+ invoke :copy_miscellaneous_files
38
+ invoke :customize_error_pages
39
+ invoke :remove_routes_comment_lines
40
+ invoke :setup_git
41
+ invoke :setup_database
42
+ invoke :create_github_repo
43
+ invoke :setup_bundler_audit
44
+ invoke :outro
45
+ end
46
+
47
+ def customize_gemfile
48
+ build :replace_gemfile
49
+ build :set_ruby_to_version_being_used
50
+
51
+ bundle_command 'install'
52
+ end
53
+
54
+ def setup_database
55
+ say 'Setting up database'
56
+
57
+ if 'postgresql' == options[:database]
58
+ build :use_postgres_config_template
59
+ end
60
+
61
+ build :create_database
62
+ end
63
+
64
+ def setup_development_environment
65
+ say 'Setting up the development environment'
66
+ build :raise_on_delivery_errors
67
+ build :set_test_delivery_method
68
+ build :raise_on_unpermitted_parameters
69
+ build :provide_setup_script
70
+ build :provide_dev_prime_task
71
+ build :configure_generators
72
+ build :configure_i18n_for_missing_translations
73
+ end
74
+
75
+ def setup_test_environment
76
+ say 'Setting up the test environment'
77
+ build :set_up_factory_girl_for_rspec
78
+ build :generate_rspec
79
+ build :configure_rspec
80
+ build :enable_database_cleaner
81
+ build :configure_spec_support_features
82
+ build :configure_circleci
83
+ build :configure_i18n_for_test_environment
84
+ build :configure_i18n_tasks
85
+ build :configure_action_mailer_in_specs
86
+ end
87
+
88
+ def setup_production_environment
89
+ say 'Setting up the production environment'
90
+ build :configure_mandrill
91
+ build :configure_rack_timeout
92
+ build :enable_rack_deflater
93
+ end
94
+
95
+ def setup_staging_environment
96
+ say 'Setting up the staging environment'
97
+ build :setup_staging_environment
98
+ end
99
+
100
+ def setup_secret_token
101
+ say 'Moving secret token out of version control'
102
+ build :setup_secret_token
103
+ end
104
+
105
+ def create_suspenders_views
106
+ say 'Creating suspenders views'
107
+ build :create_partials_directory
108
+ build :create_shared_flashes
109
+ build :create_shared_javascripts
110
+ build :create_application_layout
111
+ end
112
+
113
+ def configure_app
114
+ say 'Configuring app'
115
+ build :configure_action_mailer
116
+ build :configure_time_formats
117
+ build :configure_simple_form
118
+ build :disable_xml_params
119
+ build :fix_i18n_deprecation_warning
120
+ build :setup_default_rake_task
121
+ build :setup_foreman
122
+ end
123
+
124
+ def setup_stylesheets
125
+ say 'Set up stylesheets'
126
+ build :setup_stylesheets
127
+ end
128
+
129
+ def install_bitters
130
+ say 'Install Bitters'
131
+ build :install_bitters
132
+ end
133
+
134
+ def setup_git
135
+ if !options[:skip_git]
136
+ say 'Initializing git'
137
+ invoke :setup_gitignore
138
+ invoke :init_git
139
+ end
140
+ end
141
+
142
+ def create_github_repo
143
+ if !options[:skip_git] && options[:github]
144
+ say 'Creating Github repo'
145
+ build :create_github_repo, options[:github]
146
+ end
147
+ end
148
+
149
+ def setup_segment
150
+ say 'Setting up Segment'
151
+ build :setup_segment
152
+ end
153
+
154
+ def setup_gitignore
155
+ build :gitignore_files
156
+ end
157
+
158
+ def setup_bundler_audit
159
+ say "Setting up bundler-audit"
160
+ build :setup_bundler_audit
161
+ end
162
+
163
+ def init_git
164
+ build :init_git
165
+ end
166
+
167
+ def copy_miscellaneous_files
168
+ say 'Copying miscellaneous support files'
169
+ build :copy_miscellaneous_files
170
+ end
171
+
172
+ def customize_error_pages
173
+ say 'Customizing the 500/404/422 pages'
174
+ build :customize_error_pages
175
+ end
176
+
177
+ def remove_routes_comment_lines
178
+ build :remove_routes_comment_lines
179
+ end
180
+
181
+ def outro
182
+ say 'Congratulations! You just pulled our suspenders.'
183
+ say 'Please read through all of the items in the newly generated README for next steps.'
184
+ end
185
+
186
+ protected
187
+
188
+ def get_builder_class
189
+ Suspenders::AppBuilder
190
+ end
191
+
192
+ def using_active_record?
193
+ !options[:skip_active_record]
194
+ end
195
+ end
196
+ end
@@ -0,0 +1,5 @@
1
+ module Suspenders
2
+ RAILS_VERSION = "4.2.1"
3
+ RUBY_VERSION = IO.read("#{File.dirname(__FILE__)}/../../.ruby-version").strip
4
+ VERSION = "1.0.0"
5
+ end
data/lib/suspenders.rb ADDED
@@ -0,0 +1,4 @@
1
+ require 'suspenders/version'
2
+ require 'suspenders/generators/app_generator'
3
+ require 'suspenders/actions'
4
+ require 'suspenders/app_builder'
@@ -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,10 @@
1
+ require 'spec_helper'
2
+
3
+ feature 'GitHub' do
4
+ scenario 'Suspend a project with --github option' do
5
+ repo_name = 'test'
6
+ run_suspenders("--github=#{repo_name}")
7
+
8
+ expect(FakeGithub).to have_created_repo(repo_name)
9
+ end
10
+ end