anadea-spark 0.2.0

Sign up to get free protection for your applications and to get access to all the features.
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