onotole 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 (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)