anadea-spark 0.2.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 (59) 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/CONTRIBUTING.md +32 -0
  6. data/Gemfile +3 -0
  7. data/LICENSE +21 -0
  8. data/NEWS.md +8 -0
  9. data/README.md +154 -0
  10. data/Rakefile +11 -0
  11. data/anadea-spark.gemspec +35 -0
  12. data/bin/rake +16 -0
  13. data/bin/rspec +16 -0
  14. data/bin/setup +9 -0
  15. data/bin/spark +13 -0
  16. data/lib/spark.rb +4 -0
  17. data/lib/spark/actions.rb +33 -0
  18. data/lib/spark/app_builder.rb +373 -0
  19. data/lib/spark/generators/app_generator.rb +204 -0
  20. data/lib/spark/version.rb +5 -0
  21. data/spec/features/new_project_spec.rb +136 -0
  22. data/spec/spec_helper.rb +34 -0
  23. data/spec/support/spark.rb +51 -0
  24. data/templates/Gemfile.erb +53 -0
  25. data/templates/Procfile +2 -0
  26. data/templates/README.md.erb +14 -0
  27. data/templates/assets/application.css.scss +4 -0
  28. data/templates/assets/application.js +3 -0
  29. data/templates/bin/setup.erb +30 -0
  30. data/templates/config/application.yml.sample +3 -0
  31. data/templates/config/i18n_tasks.yml +13 -0
  32. data/templates/config/initializers/disable_xml_params.rb +3 -0
  33. data/templates/config/initializers/errors.rb +34 -0
  34. data/templates/config/initializers/exception_notification.rb.erb +8 -0
  35. data/templates/config/initializers/json_encoding.rb +1 -0
  36. data/templates/config/initializers/mail_interceptor.rb +4 -0
  37. data/templates/config/initializers/rack_timeout.rb +1 -0
  38. data/templates/config/locales_en.yml.erb +19 -0
  39. data/templates/config/newrelic.yml.erb +30 -0
  40. data/templates/config/postgresql_database.yml.erb +12 -0
  41. data/templates/config/rails_secrets.yml +11 -0
  42. data/templates/dot_gitignore +15 -0
  43. data/templates/spec/rails_helper.rb +23 -0
  44. data/templates/spec/spec_helper.rb +32 -0
  45. data/templates/spec/support/action_mailer.rb +5 -0
  46. data/templates/spec/support/database_cleaner_rspec.rb +21 -0
  47. data/templates/spec/support/factory_girl_rspec.rb +3 -0
  48. data/templates/spec/support/i18n.rb +3 -0
  49. data/templates/tasks/bundler_audit.rake +12 -0
  50. data/templates/tasks/development_seeds.rake +12 -0
  51. data/templates/views/application/_analytics.html.haml +11 -0
  52. data/templates/views/application/_flashes.html.haml +4 -0
  53. data/templates/views/application/_footer.html.haml +9 -0
  54. data/templates/views/application/_javascript.html.haml +8 -0
  55. data/templates/views/application/_navigation.html.haml +12 -0
  56. data/templates/views/application/_navigation_links.html.haml +2 -0
  57. data/templates/views/layouts/application.html.haml +23 -0
  58. data/templates/views/pages/home.html.haml +4 -0
  59. metadata +178 -0
@@ -0,0 +1,204 @@
1
+ require 'rails/generators'
2
+ require 'rails/generators/rails/app/app_generator'
3
+
4
+ module Spark
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 :skip_test_unit, type: :boolean, aliases: "-T", default: true,
10
+ desc: "Skip Test::Unit files"
11
+
12
+ class_option :skip_turbolinks, type: :boolean, default: true,
13
+ desc: "Skip turbolinks gem"
14
+
15
+ class_option :skip_bundle, type: :boolean, aliases: "-B", default: true,
16
+ desc: "Don't run bundle install"
17
+
18
+ def finish_template
19
+ invoke :spark_customization
20
+ super
21
+ invoke :run_bin_setup
22
+ end
23
+
24
+ def spark_customization
25
+ invoke :customize_gemfile
26
+ invoke :setup_secret_token
27
+ invoke :create_spark_views
28
+ invoke :configure_app
29
+ invoke :setup_development_environment
30
+ invoke :setup_test_environment
31
+ invoke :setup_production_environment
32
+ invoke :setup_assets
33
+ invoke :configure_mail_interceptor
34
+ invoke :copy_miscellaneous_files
35
+ invoke :customize_error_pages
36
+ invoke :remove_routes_comment_lines
37
+ invoke :add_root_route
38
+ invoke :setup_git
39
+ invoke :setup_database
40
+ invoke :setup_bundler_audit
41
+ invoke :outro
42
+ end
43
+
44
+ def customize_gemfile
45
+ build :replace_gemfile
46
+ build :set_ruby_to_version_being_used
47
+
48
+ bundle_command 'install'
49
+ end
50
+
51
+ def setup_database
52
+ say 'Setting up database'
53
+
54
+ if 'postgresql' == options[:database]
55
+ build :use_postgres_config_template
56
+ end
57
+
58
+ build :create_database
59
+ end
60
+
61
+ def setup_development_environment
62
+ say 'Setting up the development environment'
63
+ build :raise_on_delivery_errors
64
+ build :set_test_delivery_method
65
+ build :raise_on_unpermitted_parameters
66
+ build :provide_setup_script
67
+ build :provide_dev_prime_task
68
+ build :configure_generators
69
+ build :configure_i18n_for_missing_translations
70
+ end
71
+
72
+ def setup_test_environment
73
+ say 'Setting up the test environment'
74
+ build :set_up_factory_girl_for_rspec
75
+ build :generate_rspec
76
+ build :configure_rspec
77
+ build :configure_background_jobs_for_rspec
78
+ build :enable_database_cleaner
79
+ build :configure_spec_support_features
80
+ build :configure_i18n_for_test_environment
81
+ build :configure_i18n_tasks
82
+ build :configure_action_mailer_in_specs
83
+ end
84
+
85
+ def setup_production_environment
86
+ say 'Setting up the production environment'
87
+ build :configure_exception_notification
88
+ build :configure_smtp
89
+ build :enable_rack_deflater
90
+ build :setup_asset_host
91
+ end
92
+
93
+ def setup_staging_environment
94
+ say 'Setting up the staging environment'
95
+ build :setup_staging_environment
96
+ end
97
+
98
+ def setup_secret_token
99
+ say 'Moving secret token out of version control'
100
+ build :setup_secret_token
101
+ end
102
+
103
+ def create_spark_views
104
+ say 'Creating spark views'
105
+ build :create_partials
106
+ build :create_application_layout
107
+ build :create_home_page
108
+ end
109
+
110
+ def configure_app
111
+ say 'Configuring app'
112
+ build :setup_figaro
113
+ build :configure_action_mailer
114
+ build :configure_active_job
115
+ build :configure_time_formats
116
+ build :configure_rack_timeout
117
+ build :configure_simple_form
118
+ build :disable_xml_params
119
+ build :fix_i18n_deprecation_warning
120
+ build :setup_default_rake_task
121
+ build :configure_puma
122
+ build :setup_foreman
123
+ end
124
+
125
+ def setup_assets
126
+ say 'Set up assets'
127
+ build :setup_stylesheets
128
+ build :setup_javascripts
129
+ end
130
+
131
+ def configure_mail_interceptor
132
+ say 'Configure mail interceptor'
133
+ build :configure_mail_interceptor
134
+ end
135
+
136
+ def setup_git
137
+ if !options[:skip_git]
138
+ say 'Initializing git'
139
+ invoke :setup_gitignore
140
+ invoke :init_git
141
+ end
142
+ end
143
+
144
+ def create_heroku_apps
145
+ if options[:heroku]
146
+ say "Creating Heroku apps"
147
+ build :create_heroku_apps, options[:heroku_flags]
148
+ build :set_heroku_serve_static_files
149
+ build :set_heroku_remotes
150
+ build :set_heroku_rails_secrets
151
+ build :provide_deploy_script
152
+ end
153
+ end
154
+
155
+ def setup_gitignore
156
+ build :gitignore_files
157
+ end
158
+
159
+ def setup_bundler_audit
160
+ say "Setting up bundler-audit"
161
+ build :setup_bundler_audit
162
+ end
163
+
164
+ def init_git
165
+ build :init_git
166
+ end
167
+
168
+ def copy_miscellaneous_files
169
+ say 'Copying miscellaneous support files'
170
+ build :copy_miscellaneous_files
171
+ end
172
+
173
+ def customize_error_pages
174
+ say 'Customizing the 500/404/422 pages'
175
+ build :customize_error_pages
176
+ end
177
+
178
+ def remove_routes_comment_lines
179
+ build :remove_routes_comment_lines
180
+ end
181
+
182
+ def add_root_route
183
+ build :add_root_route
184
+ end
185
+
186
+ def run_bin_setup
187
+ build :run_bin_setup
188
+ end
189
+
190
+ def outro
191
+ say 'Congratulations! Now start creating a great app.'
192
+ end
193
+
194
+ protected
195
+
196
+ def get_builder_class
197
+ Spark::AppBuilder
198
+ end
199
+
200
+ def using_active_record?
201
+ !options[:skip_active_record]
202
+ end
203
+ end
204
+ end
@@ -0,0 +1,5 @@
1
+ module Spark
2
+ RAILS_VERSION = "4.2.1"
3
+ RUBY_VERSION = IO.read("#{File.dirname(__FILE__)}/../../.ruby-version").strip
4
+ VERSION = "0.2.0"
5
+ end
@@ -0,0 +1,136 @@
1
+ require 'spec_helper'
2
+
3
+ RSpec.feature 'Build a new project with default configuration' do
4
+ scenario 'specs pass', :smoke do
5
+ run_generator
6
+
7
+ Dir.chdir(project_path) do
8
+ Bundler.with_clean_env do
9
+ expect(`rake`).to include('0 failures')
10
+ end
11
+ end
12
+ end
13
+
14
+ scenario 'generated .ruby-version is pulled from gem .ruby-version' do
15
+ run_generator
16
+
17
+ ruby_version_file = IO.read("#{project_path}/.ruby-version")
18
+
19
+ expect(ruby_version_file).to eq "#{RUBY_VERSION}\n"
20
+ end
21
+
22
+ scenario 'secrets.yml reads secret from env' do
23
+ run_generator
24
+
25
+ secrets_file = IO.read("#{project_path}/config/secrets.yml")
26
+
27
+ expect(secrets_file).to match(/secret_key_base: <%= ENV\["SECRET_KEY_BASE"\] %>/)
28
+ end
29
+
30
+ scenario 'action mailer support file is added' do
31
+ run_generator
32
+
33
+ expect(File).to exist("#{project_path}/spec/support/action_mailer.rb")
34
+ end
35
+
36
+ scenario "i18n support file is added" do
37
+ run_generator
38
+
39
+ expect(File).to exist("#{project_path}/spec/support/i18n.rb")
40
+ end
41
+
42
+ scenario 'exception notification reads mail address from ENV' do
43
+ run_generator
44
+
45
+ exception_notification_file =
46
+ IO.read("#{project_path}/config/initializers/exception_notification.rb")
47
+
48
+ expect(exception_notification_file).to match(
49
+ /exception_recipients: ENV\["MAIL_ERRORS_TO"\]/
50
+ )
51
+ end
52
+
53
+ scenario 'records pageviews through Google Analytics if ENV variable set' do
54
+ run_generator
55
+
56
+ expect(analytics_partial).
57
+ to include(%{- if ENV.key?("GOOGLE_ANALYTICS_KEY")})
58
+ expect(analytics_partial).
59
+ to include(%{_gaq.push(['_setAccount', '\#{ENV["GOOGLE_ANALYTICS_KEY"]}']);})
60
+ end
61
+
62
+ scenario "raises on unpermitted parameters in all environments" do
63
+ run_generator
64
+
65
+ result = IO.read("#{project_path}/config/application.rb")
66
+
67
+ expect(result).to match(
68
+ /^ +config.action_controller.action_on_unpermitted_parameters = :raise$/
69
+ )
70
+ end
71
+
72
+ scenario "raises on missing translations in development and test" do
73
+ run_generator
74
+
75
+ %w[development test].each do |environment|
76
+ environment_file =
77
+ IO.read("#{project_path}/config/environments/#{environment}.rb")
78
+ expect(environment_file).to match(
79
+ /^ +config.action_view.raise_on_missing_translations = true$/
80
+ )
81
+ end
82
+ end
83
+
84
+ scenario "specs for missing or unused translations" do
85
+ run_generator
86
+
87
+ expect(File).to exist("#{project_path}/spec/i18n_spec.rb")
88
+ end
89
+
90
+ scenario "config file for i18n tasks" do
91
+ run_generator
92
+
93
+ expect(File).to exist("#{project_path}/config/i18n-tasks.yml")
94
+ end
95
+
96
+ scenario "generated en.yml is evaluated" do
97
+ run_generator
98
+
99
+ locales_en_file = IO.read("#{project_path}/config/locales/en.yml")
100
+ app_name = TestHelpers::APP_NAME
101
+
102
+ expect(locales_en_file).to match(/application: #{app_name.humanize}/)
103
+ end
104
+
105
+ scenario "config simple_form" do
106
+ run_generator
107
+
108
+ expect(File).to exist("#{project_path}/config/initializers/simple_form.rb")
109
+ end
110
+
111
+ scenario "config :smtp email delivery method for development" do
112
+ run_generator
113
+
114
+ dev_env_file = IO.read("#{project_path}/config/environments/development.rb")
115
+ expect(dev_env_file).
116
+ to match(/^ +config.action_mailer.delivery_method = :smtp$/)
117
+ end
118
+
119
+ scenario "config active job queue adapter" do
120
+ run_generator
121
+
122
+ application_config = IO.read("#{project_path}/config/application.rb")
123
+ test_config = IO.read("#{project_path}/config/environments/test.rb")
124
+
125
+ expect(application_config).to match(
126
+ /^ +config.active_job.queue_adapter = :delayed_job$/
127
+ )
128
+ expect(test_config).to match(
129
+ /^ +config.active_job.queue_adapter = :inline$/
130
+ )
131
+ end
132
+
133
+ def analytics_partial
134
+ IO.read("#{project_path}/app/views/application/_analytics.html.haml")
135
+ end
136
+ end
@@ -0,0 +1,34 @@
1
+ require 'capybara/rspec'
2
+ require 'bundler/setup'
3
+
4
+ Bundler.require(:default, :test)
5
+
6
+ require (Pathname.new(__FILE__).dirname + '../lib/spark').expand_path
7
+
8
+ Dir['./spec/support/**/*.rb'].each { |file| require file }
9
+
10
+ RSpec.configure do |config|
11
+ config.include TestHelpers
12
+
13
+ config.filter_run :focus
14
+ config.run_all_when_everything_filtered = true
15
+ config.disable_monkey_patching!
16
+
17
+ if config.files_to_run.one?
18
+ config.default_formatter = 'doc'
19
+ end
20
+
21
+ config.order = :random
22
+ Kernel.srand config.seed
23
+
24
+ config.before(:all) do
25
+ drop_dummy_database
26
+ recreate_tmp_directory
27
+ end
28
+
29
+ config.before(:each) do
30
+ drop_dummy_database
31
+ remove_project_directory
32
+ end
33
+
34
+ end
@@ -0,0 +1,51 @@
1
+ module TestHelpers
2
+ APP_NAME = "dummy_app"
3
+
4
+ def remove_project_directory
5
+ FileUtils.rm_rf(project_path)
6
+ end
7
+
8
+ def recreate_tmp_directory
9
+ FileUtils.rm_rf(project_path)
10
+ FileUtils.mkdir_p(tmp_path)
11
+ end
12
+
13
+ def run_generator(arguments = nil)
14
+ Dir.chdir(tmp_path) do
15
+ Bundler.with_clean_env do
16
+ ENV['TESTING'] = '1'
17
+
18
+ %x(#{generator_bin} #{APP_NAME} #{arguments})
19
+ fail 'Application generation failed' unless $?.exitstatus == 0
20
+ end
21
+ end
22
+ end
23
+
24
+ def drop_dummy_database
25
+ if File.exist?(project_path)
26
+ Dir.chdir(project_path) do
27
+ Bundler.with_clean_env do
28
+ `rake db:drop`
29
+ end
30
+ end
31
+ end
32
+ end
33
+
34
+ def project_path
35
+ @project_path ||= Pathname.new("#{tmp_path}/#{APP_NAME}")
36
+ end
37
+
38
+ private
39
+
40
+ def tmp_path
41
+ @tmp_path ||= Pathname.new("#{root_path}/tmp")
42
+ end
43
+
44
+ def generator_bin
45
+ File.join(root_path, 'bin', 'spark')
46
+ end
47
+
48
+ def root_path
49
+ File.expand_path('../../../', __FILE__)
50
+ end
51
+ end
@@ -0,0 +1,53 @@
1
+ source "https://rubygems.org"
2
+
3
+ ruby "<%= Spark::RUBY_VERSION %>"
4
+
5
+ gem "bootstrap-sass", "~> 3.3.4"
6
+ gem "coffee-rails", "~> 4.1.0"
7
+ gem "delayed_job_active_record"
8
+ gem "email_validator"
9
+ gem "exception_notification"
10
+ gem "figaro"
11
+ gem "haml-rails"
12
+ gem "high_voltage"
13
+ gem "i18n-tasks"
14
+ gem "jquery-rails"
15
+ gem "pg"
16
+ gem "puma"
17
+ gem "rack-timeout"
18
+ gem "rails", "<%= Spark::RAILS_VERSION %>"
19
+ gem "recipient_interceptor"
20
+ gem "sass-rails", "~> 5.0"
21
+ gem "simple_form"
22
+ gem "title"
23
+ gem "uglifier"
24
+
25
+ group :development do
26
+ gem "spring"
27
+ gem "spring-commands-rspec"
28
+ gem "web-console"
29
+ end
30
+
31
+ group :development, :test do
32
+ gem "awesome_print"
33
+ gem "bundler-audit", require: false
34
+ gem "byebug"
35
+ gem "factory_girl_rails"
36
+ gem "pry-rails"
37
+ gem "rspec-rails", "~> 3.1.0"
38
+ end
39
+
40
+ group :test do
41
+ gem "database_cleaner"
42
+ gem "formulaic"
43
+ gem "launchy"
44
+ gem "poltergeist"
45
+ gem "shoulda-matchers", require: false
46
+ gem "simplecov", require: false
47
+ gem "timecop"
48
+ gem "webmock"
49
+ end
50
+
51
+ group :production do
52
+ gem "rails_12factor"
53
+ end