onotole 1.0.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (81) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +6 -0
  3. data/.rubocop.yml +44 -0
  4. data/.ruby-version +1 -0
  5. data/.travis.yml +11 -0
  6. data/Gemfile +3 -0
  7. data/Guardfile +60 -0
  8. data/LICENSE +19 -0
  9. data/README.md +288 -0
  10. data/Rakefile +8 -0
  11. data/bin/onotole +35 -0
  12. data/bin/rake +16 -0
  13. data/bin/rspec +16 -0
  14. data/bin/setup +13 -0
  15. data/lib/onotole.rb +6 -0
  16. data/lib/onotole/actions.rb +33 -0
  17. data/lib/onotole/adapters/heroku.rb +125 -0
  18. data/lib/onotole/add_user_gems/after_install_patch.rb +119 -0
  19. data/lib/onotole/add_user_gems/before_bundle_patch.rb +137 -0
  20. data/lib/onotole/add_user_gems/edit_menu_questions.rb +80 -0
  21. data/lib/onotole/add_user_gems/user_gems_menu_questions.rb +17 -0
  22. data/lib/onotole/app_builder.rb +678 -0
  23. data/lib/onotole/colors.rb +20 -0
  24. data/lib/onotole/generators/app_generator.rb +299 -0
  25. data/lib/onotole/version.rb +6 -0
  26. data/onotole.gemspec +33 -0
  27. data/spec/adapters/heroku_spec.rb +52 -0
  28. data/spec/fakes/bin/heroku +5 -0
  29. data/spec/fakes/bin/hub +5 -0
  30. data/spec/features/github_spec.rb +15 -0
  31. data/spec/features/heroku_spec.rb +93 -0
  32. data/spec/features/new_project_spec.rb +204 -0
  33. data/spec/spec_helper.rb +20 -0
  34. data/spec/support/fake_github.rb +21 -0
  35. data/spec/support/fake_heroku.rb +51 -0
  36. data/spec/support/onotole.rb +59 -0
  37. data/templates/Gemfile.erb +61 -0
  38. data/templates/Procfile +2 -0
  39. data/templates/README.md.erb +30 -0
  40. data/templates/_analytics.html.erb +7 -0
  41. data/templates/_flashes.html.erb +7 -0
  42. data/templates/_javascript.html.erb +12 -0
  43. data/templates/action_mailer.rb +5 -0
  44. data/templates/app.json.erb +39 -0
  45. data/templates/application.scss +1 -0
  46. data/templates/bin_deploy +12 -0
  47. data/templates/bin_setup +21 -0
  48. data/templates/bin_setup_review_app.erb +19 -0
  49. data/templates/browserslist +4 -0
  50. data/templates/bundler_audit.rake +12 -0
  51. data/templates/capybara_webkit.rb +3 -0
  52. data/templates/circle.yml.erb +6 -0
  53. data/templates/config_locales_en.yml.erb +19 -0
  54. data/templates/database_cleaner_rspec.rb +22 -0
  55. data/templates/dev.rake +12 -0
  56. data/templates/devise_rspec.rb +3 -0
  57. data/templates/disable_xml_params.rb +1 -0
  58. data/templates/dotfiles/.ctags +2 -0
  59. data/templates/dotfiles/.env +13 -0
  60. data/templates/dotfiles/.rspec +3 -0
  61. data/templates/errors.rb +34 -0
  62. data/templates/factories.rb +2 -0
  63. data/templates/factory_girl_rspec.rb +3 -0
  64. data/templates/flashes_helper.rb +5 -0
  65. data/templates/gitignore_file +18 -0
  66. data/templates/hound.yml +17 -0
  67. data/templates/i18n.rb +3 -0
  68. data/templates/json_encoding.rb +1 -0
  69. data/templates/newrelic.yml.erb +34 -0
  70. data/templates/onotole_layout.html.erb.erb +21 -0
  71. data/templates/postgresql_database.yml.erb +22 -0
  72. data/templates/puma.rb +28 -0
  73. data/templates/rails_helper.rb +22 -0
  74. data/templates/rubocop.yml +44 -0
  75. data/templates/secrets.yml +14 -0
  76. data/templates/shoulda_matchers_config_rspec.rb +6 -0
  77. data/templates/smtp.rb +9 -0
  78. data/templates/spec_helper.rb +23 -0
  79. data/templates/staging.rb +5 -0
  80. data/templates/tinymce.yml +6 -0
  81. metadata +172 -0
@@ -0,0 +1,204 @@
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_onotole
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 Onotole .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 'copies dotfiles' do
33
+ %w(.ctags .env).each do |dotfile|
34
+ expect(File).to exist("#{project_path}/#{dotfile}")
35
+ end
36
+ end
37
+
38
+ it 'loads secret_key_base from env' do
39
+ secrets_file = IO.read("#{project_path}/config/secrets.yml")
40
+
41
+ expect(secrets_file).to match(/secret_key_base: <%= ENV\["SECRET_KEY_BASE"\] %>/)
42
+ end
43
+
44
+ it 'adds bin/setup file' do
45
+ expect(File).to exist("#{project_path}/bin/setup")
46
+ end
47
+
48
+ it 'makes bin/setup executable' do
49
+ bin_setup_path = "#{project_path}/bin/setup"
50
+
51
+ expect(File.stat(bin_setup_path)).to be_executable
52
+ end
53
+
54
+ it 'adds support file for action mailer' do
55
+ expect(File).to exist("#{project_path}/spec/support/action_mailer.rb")
56
+ end
57
+
58
+ it 'configures capybara-webkit' do
59
+ expect(File).to exist("#{project_path}/spec/support/capybara_webkit.rb")
60
+ end
61
+
62
+ it 'adds support file for i18n' do
63
+ expect(File).to exist("#{project_path}/spec/support/i18n.rb")
64
+ end
65
+
66
+ # it 'creates good default .hound.yml' do
67
+ # hound_config_file = IO.read("#{project_path}/.hound.yml")
68
+
69
+ # expect(hound_config_file).to include 'enabled: true'
70
+ # end
71
+
72
+ it 'ensures newrelic.yml reads NewRelic license from env' do
73
+ newrelic_file = IO.read("#{project_path}/config/newrelic.yml")
74
+
75
+ expect(newrelic_file).to match(
76
+ /license_key: "<%= ENV\["NEW_RELIC_LICENSE_KEY"\] %>"/
77
+ )
78
+ end
79
+
80
+ it 'records pageviews through Segment if ENV variable set' do
81
+ expect(analytics_partial)
82
+ .to include(%(<% if ENV["SEGMENT_KEY"] %>))
83
+ expect(analytics_partial)
84
+ .to include(%{window.analytics.load("<%= ENV["SEGMENT_KEY"] %>");})
85
+ end
86
+
87
+ it 'raises on unpermitted parameters in all environments' do
88
+ result = IO.read("#{project_path}/config/application.rb")
89
+
90
+ expect(result).to match(
91
+ /^\s+config.action_controller.action_on_unpermitted_parameters = :raise/
92
+ )
93
+ end
94
+
95
+ it 'adds explicit quiet_assets configuration' do
96
+ result = IO.read("#{project_path}/config/application.rb")
97
+
98
+ expect(result).to match(
99
+ /^ +config.quiet_assets = true$/
100
+ )
101
+ end
102
+
103
+ it 'raises on missing translations in development and test' do
104
+ %w(development test).each do |environment|
105
+ environment_file =
106
+ IO.read("#{project_path}/config/environments/#{environment}.rb")
107
+ expect(environment_file).to match(
108
+ /^ +config.action_view.raise_on_missing_translations = true$/
109
+ )
110
+ end
111
+ end
112
+
113
+ it 'evaluates en.yml.erb' do
114
+ locales_en_file = IO.read("#{project_path}/config/locales/en.yml")
115
+
116
+ expect(locales_en_file).to match(/application: #{app_name.humanize}/)
117
+ end
118
+
119
+ it 'configs simple_form' do
120
+ expect(File).to exist("#{project_path}/config/initializers/simple_form.rb")
121
+ end
122
+
123
+ it 'configs :test email delivery method for development' do
124
+ dev_env_file = IO.read("#{project_path}/config/environments/development.rb")
125
+ expect(dev_env_file)
126
+ .to match(/^ +config.action_mailer.delivery_method = :test$/)
127
+ end
128
+
129
+ it 'uses APPLICATION_HOST, not HOST in the production config' do
130
+ prod_env_file = IO.read("#{project_path}/config/environments/production.rb")
131
+ expect(prod_env_file).to match(/("|')APPLICATION_HOST("|')/)
132
+ expect(prod_env_file).not_to match(/("|')HOST("|')/)
133
+ end
134
+
135
+ # it 'configures language in html element' do
136
+ # layout_path = '/app/views/layouts/application.html.erb'
137
+ # layout_file = IO.read("#{project_path}#{layout_path}")
138
+ # expect(layout_file).to match(/<html lang=("|')en("|')>/)
139
+ # end
140
+
141
+ it 'configs active job queue adapter' do
142
+ application_config = IO.read("#{project_path}/config/application.rb")
143
+ test_config = IO.read("#{project_path}/config/environments/test.rb")
144
+
145
+ expect(application_config).to match(
146
+ /^ +config.active_job.queue_adapter = :delayed_job$/
147
+ )
148
+ expect(test_config).to match(
149
+ /^ +config.active_job.queue_adapter = :inline$/
150
+ )
151
+ end
152
+
153
+ it 'configs bullet gem in development' do
154
+ test_config = IO.read("#{project_path}/config/environments/development.rb")
155
+
156
+ expect(test_config).to match /^ +Bullet.enable = true$/
157
+ expect(test_config).to match /^ +Bullet.bullet_logger = true$/
158
+ expect(test_config).to match /^ +Bullet.rails_logger = true$/
159
+ end
160
+
161
+ it 'configs missing assets to raise in test' do
162
+ test_config = IO.read("#{project_path}/config/environments/test.rb")
163
+
164
+ expect(test_config).to match(
165
+ /^ +config.assets.raise_runtime_errors = true$/
166
+ )
167
+ end
168
+
169
+ it 'adds spring to binstubs' do
170
+ expect(File).to exist("#{project_path}/bin/spring")
171
+
172
+ bin_stubs = %w(rake rails rspec)
173
+ bin_stubs.each do |bin_stub|
174
+ expect(IO.read("#{project_path}/bin/#{bin_stub}")).to match(/spring/)
175
+ end
176
+ end
177
+
178
+ it 'removes comments and extra newlines from config files' do
179
+ config_files = [
180
+ IO.read("#{project_path}/config/application.rb"),
181
+ IO.read("#{project_path}/config/environment.rb"),
182
+ IO.read("#{project_path}/config/environments/development.rb"),
183
+ IO.read("#{project_path}/config/environments/production.rb"),
184
+ IO.read("#{project_path}/config/environments/test.rb")
185
+ ]
186
+
187
+ config_files.each do |file|
188
+ expect(file).not_to match(/.*\s#.*/)
189
+ expect(file).not_to match(/^$\n/)
190
+ end
191
+ end
192
+
193
+ it 'copies factories.rb' do
194
+ expect(File).to exist("#{project_path}/spec/factories.rb")
195
+ end
196
+
197
+ def app_name
198
+ OnotoleTestHelpers::APP_NAME
199
+ end
200
+
201
+ def analytics_partial
202
+ IO.read("#{project_path}/app/views/application/_analytics.html.erb")
203
+ end
204
+ end
@@ -0,0 +1,20 @@
1
+ require 'bundler/setup'
2
+
3
+ Bundler.require(:default, :test)
4
+
5
+ require (Pathname.new(__FILE__).dirname + '../lib/onotole').expand_path
6
+
7
+ Dir['./spec/support/**/*.rb'].each { |file| require file }
8
+
9
+ RSpec.configure do |config|
10
+ config.include OnotoleTestHelpers
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,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
@@ -0,0 +1,51 @@
1
+ class FakeHeroku
2
+ RECORDER = File.expand_path(File.join('..', '..', 'tmp', 'heroku_commands'), File.dirname(__FILE__))
3
+
4
+ def initialize(args)
5
+ @args = args
6
+ end
7
+
8
+ def run!
9
+ puts 'heroku-pipelines@0.29.0' if @args.first == 'plugins'
10
+ File.open(RECORDER, 'a') do |file|
11
+ file.puts @args.join(' ')
12
+ end
13
+ end
14
+
15
+ def self.clear!
16
+ FileUtils.rm_rf RECORDER
17
+ end
18
+
19
+ def self.has_gem_included?(project_path, gem_name)
20
+ gemfile = File.open(File.join(project_path, 'Gemfile'), 'a')
21
+
22
+ File.foreach(gemfile).any? do |line|
23
+ line.match(/#{Regexp.quote(gem_name)}/)
24
+ end
25
+ end
26
+
27
+ def self.has_created_app_for?(environment, flags = nil)
28
+ app_name = "#{OnotoleTestHelpers::APP_NAME.dasherize}-#{environment}"
29
+
30
+ command = if flags
31
+ "create #{app_name} #{flags} --remote #{environment}\n"
32
+ else
33
+ "create #{app_name} --remote #{environment}\n"
34
+ end
35
+
36
+ File.foreach(RECORDER).any? { |line| line == command }
37
+ end
38
+
39
+ def self.has_configured_vars?(remote_name, var)
40
+ commands_ran =~ /^config:add #{var}=.+ --remote #{remote_name}\n/
41
+ end
42
+
43
+ def self.has_setup_pipeline_for?(app_name)
44
+ commands_ran =~ /^pipelines:create #{app_name} -a #{app_name}-staging --stage staging/ &&
45
+ commands_ran =~ /^pipelines:add #{app_name} -a #{app_name}-production --stage production/
46
+ end
47
+
48
+ def self.commands_ran
49
+ @commands_ran ||= File.read(RECORDER)
50
+ end
51
+ end
@@ -0,0 +1,59 @@
1
+ # frozen_string_literal: true
2
+ module OnotoleTestHelpers
3
+ APP_NAME = 'dummy_app'
4
+
5
+ def remove_project_directory
6
+ FileUtils.rm_rf(project_path)
7
+ end
8
+
9
+ def create_tmp_directory
10
+ FileUtils.mkdir_p(tmp_path)
11
+ end
12
+
13
+ def run_onotole(arguments = nil)
14
+ Dir.chdir(tmp_path) do
15
+ Bundler.with_clean_env do
16
+ add_fakes_to_path
17
+ `
18
+ #{onotole_bin} #{APP_NAME} #{arguments}
19
+ `
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 add_fakes_to_path
35
+ ENV['PATH'] = "#{support_bin}:#{ENV['PATH']}"
36
+ end
37
+
38
+ def project_path
39
+ @project_path ||= Pathname.new("#{tmp_path}/#{APP_NAME}")
40
+ end
41
+
42
+ private
43
+
44
+ def tmp_path
45
+ @tmp_path ||= Pathname.new("#{root_path}/tmp")
46
+ end
47
+
48
+ def onotole_bin
49
+ File.join(root_path, 'bin', 'onotole')
50
+ end
51
+
52
+ def support_bin
53
+ File.join(root_path, 'spec', 'fakes', 'bin')
54
+ end
55
+
56
+ def root_path
57
+ File.expand_path('../../../', __FILE__)
58
+ end
59
+ end
@@ -0,0 +1,61 @@
1
+ source "https://rubygems.org"
2
+
3
+ ruby "<%= Onotole::RUBY_VERSION %>"
4
+
5
+ gem "autoprefixer-rails"
6
+ gem "coffee-rails", "~> 4.1.0"
7
+ gem "delayed_job_active_record"
8
+ gem "flutie"
9
+ gem "high_voltage"
10
+ gem "jquery-rails"
11
+ gem 'normalize-rails', '~> 3.0.0'
12
+ gem 'newrelic_rpm'
13
+ gem "pg"
14
+ gem "puma"
15
+ gem "rack-canonical-host"
16
+ gem "rails", "<%= Onotole::RAILS_VERSION %>"
17
+ gem "sass-rails", "~> 5.0"
18
+ gem "simple_form"
19
+ gem "title"
20
+ gem "uglifier"
21
+ gem "therubyracer"
22
+ # user_choice
23
+
24
+ group :development do
25
+ gem "quiet_assets"
26
+ gem "spring"
27
+ gem "spring-commands-rspec"
28
+ gem "web-console"
29
+ end
30
+
31
+ group :development, :test do
32
+ gem "awesome_print", :require=>"ap"
33
+ gem "hirb"
34
+ gem "bullet"
35
+ gem "bundler-audit", require: false
36
+ gem "dotenv-rails"
37
+ gem "factory_girl_rails"
38
+ gem "pry-byebug"
39
+ gem "pry-rails"
40
+ gem 'pry-doc'
41
+ gem 'pry-rescue'
42
+ gem 'pry-state'
43
+ gem 'better_errors'
44
+ gem "rspec-rails", "~> 3.4.0"
45
+ gem 'fuubar'
46
+ end
47
+
48
+ group :test do
49
+ gem "capybara-webkit"
50
+ gem "database_cleaner"
51
+ gem "formulaic"
52
+ gem "launchy"
53
+ gem "shoulda-matchers"
54
+ gem "simplecov", require: false
55
+ gem "timecop"
56
+ gem "webmock"
57
+ end
58
+
59
+ group :staging, :production do
60
+ gem "rack-timeout"
61
+ end
@@ -0,0 +1,2 @@
1
+ web: bundle exec puma -p $PORT -C ./config/puma.rb
2
+ worker: bundle exec rake jobs:work
@@ -0,0 +1,30 @@
1
+ # <%= app_name.humanize %>
2
+
3
+ ## Onotole helped!
4
+
5
+ ## Getting Started
6
+
7
+ After you have cloned this repo, run this setup script to set up your machine
8
+ with the necessary dependencies to run and test this app:
9
+
10
+ % ./bin/setup
11
+
12
+ It assumes you have a machine equipped with Ruby, Postgres, etc. If not, set up
13
+ your machine with [this script].
14
+
15
+ [this script]: https://github.com/thoughtbot/laptop
16
+
17
+ After setting up, you can run the application using [Heroku Local]:
18
+
19
+ % heroku local
20
+
21
+ [Heroku Local]: https://devcenter.heroku.com/articles/heroku-local
22
+
23
+ ## Guidelines
24
+
25
+ Use the following guides for getting things done, programming well, and
26
+ programming in style.
27
+
28
+ * [Protocol](http://github.com/thoughtbot/guides/blob/master/protocol)
29
+ * [Best Practices](http://github.com/thoughtbot/guides/blob/master/best-practices)
30
+ * [Style](http://github.com/thoughtbot/guides/blob/master/style)