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,20 @@
1
+ # frozen_string_literal: true
2
+ module Onotole
3
+ COLOR_OFF = "\033[0m"
4
+ BLACK = "\033[30m"
5
+ RED = "\033[31m"
6
+ GREEN = "\033[32m"
7
+ YELLOW = "\033[33m"
8
+ BLUE = "\033[34m"
9
+ MAGENTA = "\033[35m"
10
+ CYAN = "\033[36m"
11
+ WHITE = "\033[37m"
12
+ BOLDBLACK = "\033[1m\033[30m"
13
+ BOLDRED = "\033[1m\033[31m"
14
+ BOLDGREEN = "\033[1m\033[32m"
15
+ BOLDYELLOW = "\033[1m\033[33m"
16
+ BOLDBLUE = "\033[1m\033[34m"
17
+ BOLDMAGENTA = "\033[1m\033[35m"
18
+ BOLDCYAN = "\033[1m\033[36m"
19
+ BOLDWHITE = "\033[1m\033[37m"
20
+ end
@@ -0,0 +1,299 @@
1
+ require 'rails/generators'
2
+ require 'rails/generators/rails/app/app_generator'
3
+ module Onotole
4
+ class AppGenerator < Rails::Generators::AppGenerator
5
+ def self.start
6
+ class_option :database, type: :string, aliases: '-d', default: 'postgresql',
7
+ desc: "Configure for selected database (options: #{DATABASES.join('/')})"
8
+
9
+ class_option :heroku, type: :boolean, aliases: '-H', default: false,
10
+ desc: 'Create staging and production Heroku apps'
11
+
12
+ class_option :heroku_flags, type: :string, default: '',
13
+ desc: 'Set extra Heroku flags'
14
+
15
+ class_option :github, type: :string, aliases: '-G', default: nil,
16
+ desc: 'Create Github repository and add remote origin pointed to repo'
17
+
18
+ class_option :skip_test_unit, type: :boolean, aliases: '-T', default: true,
19
+ desc: 'Skip Test::Unit files'
20
+
21
+ class_option :skip_turbolinks, type: :boolean, default: true,
22
+ desc: 'Skip turbolinks gem'
23
+
24
+ class_option :skip_bundle, type: :boolean, aliases: '-B', default: true,
25
+ desc: "Don't run bundle install"
26
+
27
+ class_option :user_gems, type: :boolean, aliases: '-c', default: false,
28
+ desc: 'Ask user for gem choice'
29
+
30
+ class_option :clean_comments, type: :boolean, aliases: '--clean_comments', default: false,
31
+ desc: 'Clean up comments in config & routes files'
32
+
33
+ GEMPROCLIST.each do |g|
34
+ class_option g.to_sym, type: :boolean, aliases: "--#{g}", default: false,
35
+ desc: "#{g.to_s.humanize} gem install"
36
+ end
37
+ super
38
+ end
39
+
40
+ def finish_template
41
+ invoke :onotole_customization
42
+ super
43
+ end
44
+
45
+ def onotole_customization
46
+ invoke :customize_gemfile
47
+ invoke :custom_gems_setup
48
+ # invoke :bundler_stubs_install
49
+ invoke :setup_git
50
+ invoke :bundleinstall
51
+ invoke :setup_development_environment
52
+ invoke :setup_test_environment
53
+ invoke :setup_production_environment
54
+ invoke :setup_staging_environment
55
+ invoke :setup_secret_token
56
+ invoke :configure_app
57
+ # invoke :create_onotole_views
58
+ # invoke :setup_stylesheets
59
+ # invoke :install_bitters
60
+ # invoke :install_refills
61
+ invoke :copy_miscellaneous_files
62
+ invoke :customize_error_pages
63
+ invoke :remove_config_comment_lines
64
+ invoke :remove_routes_comment_lines
65
+ invoke :setup_dotfiles
66
+ invoke :post_init
67
+ invoke :setup_gitignore
68
+ invoke :setup_database
69
+ invoke :create_heroku_apps
70
+ invoke :create_github_repo
71
+ invoke :setup_segment
72
+ invoke :setup_spring
73
+ invoke :git_first_commit
74
+ invoke :outro
75
+ end
76
+
77
+ def customize_gemfile
78
+ build :replace_gemfile
79
+ build :set_ruby_to_version_being_used
80
+
81
+ build :set_up_heroku_specific_gems if options[:heroku]
82
+ end
83
+
84
+ def custom_gems_setup
85
+ if options[:user_gems]
86
+ build :users_gems
87
+ else
88
+ build :user_gems_from_args_or_default_set
89
+ end
90
+ end
91
+
92
+ def bundleinstall
93
+ bundle_command 'install'
94
+ build :install_user_gems_from_github
95
+ build :configure_simple_form
96
+ end
97
+
98
+ def setup_database
99
+ say 'Setting up database'
100
+
101
+ build :use_postgres_config_template if 'postgresql' == options[:database]
102
+
103
+ build :create_database
104
+ end
105
+
106
+ def setup_development_environment
107
+ say 'Setting up the development environment'
108
+ build :raise_on_missing_assets_in_test
109
+ build :raise_on_delivery_errors
110
+ build :set_test_delivery_method
111
+ build :add_bullet_gem_configuration
112
+ build :raise_on_unpermitted_parameters
113
+ build :provide_setup_script
114
+ build :provide_dev_prime_task
115
+ build :configure_generators
116
+ build :configure_i18n_for_missing_translations
117
+ build :configure_quiet_assets
118
+ end
119
+
120
+ def setup_test_environment
121
+ say 'Setting up the test environment'
122
+ build :set_up_factory_girl_for_rspec
123
+ build :generate_factories_file
124
+ # build :set_up_hound
125
+ build :generate_rspec
126
+ build :configure_rspec
127
+ build :configure_background_jobs_for_rspec
128
+ build :enable_database_cleaner
129
+ build :provide_shoulda_matchers_config
130
+ build :configure_spec_support_features
131
+ build :configure_ci
132
+ build :configure_i18n_for_test_environment
133
+ build :configure_action_mailer_in_specs
134
+ build :configure_capybara_webkit
135
+ end
136
+
137
+ def setup_production_environment
138
+ say 'Setting up the production environment'
139
+ build :configure_newrelic
140
+ build :configure_smtp
141
+ build :configure_rack_timeout
142
+ build :enable_rack_canonical_host
143
+ build :enable_rack_deflater
144
+ build :setup_asset_host
145
+ end
146
+
147
+ def setup_staging_environment
148
+ say 'Setting up the staging environment'
149
+ build :setup_staging_environment
150
+ end
151
+
152
+ def setup_secret_token
153
+ say 'Moving secret token out of version control'
154
+ build :setup_secret_token
155
+ end
156
+
157
+ # def create_onotole_views
158
+ # say 'Creating onotole views'
159
+ # build :create_partials_directory
160
+ # build :create_shared_flashes
161
+ # build :create_shared_javascripts
162
+ # build :create_application_layout
163
+ # end
164
+
165
+ def configure_app
166
+ say 'Configuring app'
167
+ build :configure_action_mailer
168
+ build :configure_active_job
169
+ build :configure_time_formats
170
+ build :disable_xml_params
171
+ build :fix_i18n_deprecation_warning
172
+ build :setup_default_rake_task
173
+ build :configure_puma
174
+ build :set_up_forego
175
+ end
176
+
177
+ # def setup_stylesheets
178
+ # say 'Set up stylesheets'
179
+ # build :setup_stylesheets
180
+ # end
181
+
182
+ # def install_bitters
183
+ # say 'Install Bitters'
184
+ # build :install_bitters
185
+ # end
186
+
187
+ # def install_refills
188
+ # say "Install Refills"
189
+ # build :install_refills
190
+ # end
191
+
192
+ def setup_git
193
+ unless options[:skip_git]
194
+ say 'Initializing git'
195
+ invoke :init_git
196
+ end
197
+ end
198
+
199
+ def setup_gitignore
200
+ unless options[:skip_git]
201
+ say 'Replace .gitignore'
202
+ invoke :setup_gitignore
203
+ end
204
+ end
205
+
206
+ def git_first_commit
207
+ invoke :git_init_commit unless options[:skip_git]
208
+ end
209
+
210
+ def create_heroku_apps
211
+ if options[:heroku]
212
+ say 'Creating Heroku apps'
213
+ build :create_heroku_apps, options[:heroku_flags]
214
+ build :provide_review_apps_setup_script
215
+ build :set_heroku_serve_static_files
216
+ build :set_heroku_remotes
217
+ build :set_heroku_rails_secrets
218
+ build :create_heroku_pipelines_config_file
219
+ build :create_heroku_pipeline
220
+ build :provide_deploy_script
221
+ build :configure_automatic_deployment
222
+ end
223
+ end
224
+
225
+ def create_github_repo
226
+ if !options[:skip_git] && options[:github]
227
+ say 'Creating Github repo'
228
+ build :create_github_repo, options[:github]
229
+ end
230
+ end
231
+
232
+ def setup_segment
233
+ say 'Setting up Segment'
234
+ build :setup_segment
235
+ end
236
+
237
+ def setup_dotfiles
238
+ build :copy_dotfiles
239
+ end
240
+
241
+ def setup_gitignore
242
+ build :gitignore_files
243
+ end
244
+
245
+ def git_init_commit
246
+ build :git_init_commit
247
+ end
248
+
249
+ def setup_spring
250
+ say 'Springifying binstubs'
251
+ build :setup_spring
252
+ end
253
+
254
+ def init_git
255
+ build :init_git
256
+ end
257
+
258
+ # def bundler_stubs_install
259
+ # say 'Bundler stubs install'
260
+ # build :rvm_bundler_stubs_install
261
+ # end
262
+
263
+ def copy_miscellaneous_files
264
+ say 'Copying miscellaneous support files'
265
+ build :copy_miscellaneous_files
266
+ end
267
+
268
+ def customize_error_pages
269
+ say 'Customizing the 500/404/422 pages'
270
+ build :customize_error_pages
271
+ end
272
+
273
+ def remove_config_comment_lines
274
+ build :remove_config_comment_lines if options[:clean_comments] == true
275
+ end
276
+
277
+ def remove_routes_comment_lines
278
+ build :remove_routes_comment_lines if options[:clean_comments] == true
279
+ end
280
+
281
+ def outro
282
+ build :show_goodbye_message
283
+ end
284
+
285
+ def post_init
286
+ build :post_init
287
+ end
288
+
289
+ protected
290
+
291
+ def get_builder_class
292
+ Onotole::AppBuilder
293
+ end
294
+
295
+ def using_active_record?
296
+ !options[:skip_active_record]
297
+ end
298
+ end
299
+ end
@@ -0,0 +1,6 @@
1
+ # frozen_string_literal: true
2
+ module Onotole
3
+ RAILS_VERSION = '~> 4.2.0'
4
+ RUBY_VERSION = IO.read("#{File.dirname(__FILE__)}/../../.ruby-version").strip
5
+ VERSION = '1.0.0'
6
+ end
@@ -0,0 +1,33 @@
1
+ # -*- encoding: utf-8 -*-
2
+ $LOAD_PATH.push File.expand_path('../lib', __FILE__)
3
+ require 'onotole/version'
4
+ require 'date'
5
+
6
+ Gem::Specification.new do |s|
7
+ s.required_ruby_version = ">= #{Onotole::RUBY_VERSION}"
8
+ s.authors = %w(kvokka thoughtbot)
9
+ s.date = Date.today.strftime('%Y-%m-%d')
10
+
11
+ s.description = <<-HERE
12
+ Onotole is a base Rails project that you can upgrade. Use Onotole if you're in a
13
+ rush to build something amazing, Onotole knows what to do and gives Intellect +1!
14
+ HERE
15
+
16
+ s.email = 'root_p@mail.ru'
17
+ s.executables = ['onotole']
18
+ s.extra_rdoc_files = %w(README.md LICENSE)
19
+ s.files = `git ls-files`.split("\n")
20
+ s.homepage = 'http://github.com/kvokka/onotole'
21
+ s.license = 'MIT'
22
+ s.name = 'onotole'
23
+ s.rdoc_options = ['--charset=UTF-8']
24
+ s.require_paths = ['lib']
25
+ s.summary = 'Generate a Rails app using Onotole knowledge with kvokka fingers.'
26
+ s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
27
+ s.version = Onotole::VERSION
28
+
29
+ s.add_dependency 'bundler', '~> 1.3'
30
+ s.add_dependency 'rails', Onotole::RAILS_VERSION
31
+
32
+ s.add_development_dependency 'rspec', '~> 3.2'
33
+ end
@@ -0,0 +1,52 @@
1
+ require 'spec_helper'
2
+
3
+ module Onotole
4
+ module Adapters
5
+ RSpec.describe Heroku do
6
+ it 'sets the heroku remotes' do
7
+ setup_file = 'bin/setup'
8
+ app_builder = double(app_name: app_name)
9
+ allow(app_builder).to receive(:append_file)
10
+
11
+ Heroku.new(app_builder).set_heroku_remotes
12
+
13
+ expect(app_builder).to have_received(:append_file)
14
+ .with(setup_file, /heroku join --app #{app_name.dasherize}-production/)
15
+ expect(app_builder).to have_received(:append_file)
16
+ .with(setup_file, /heroku join --app #{app_name.dasherize}-staging/)
17
+ end
18
+
19
+ it 'sets up the heroku specific gems' do
20
+ app_builder = double(app_name: app_name)
21
+ allow(app_builder).to receive(:inject_into_file)
22
+
23
+ Heroku.new(app_builder).set_up_heroku_specific_gems
24
+
25
+ expect(app_builder).to have_received(:inject_into_file)
26
+ .with('Gemfile', /rails_stdout_logging/, anything)
27
+ end
28
+
29
+ it 'sets the heroku rails secrets' do
30
+ app_builder = double(app_name: app_name)
31
+ allow(app_builder).to receive(:run)
32
+
33
+ Heroku.new(app_builder).set_heroku_rails_secrets
34
+
35
+ expect(app_builder).to(
36
+ have_configured_var('staging', 'SECRET_KEY_BASE')
37
+ )
38
+ expect(app_builder).to(
39
+ have_configured_var('production', 'SECRET_KEY_BASE')
40
+ )
41
+ end
42
+
43
+ def app_name
44
+ OnotoleTestHelpers::APP_NAME
45
+ end
46
+
47
+ def have_configured_var(remote_name, var)
48
+ have_received(:run).with(/config:add #{var}=.+ --remote #{remote_name}/)
49
+ end
50
+ end
51
+ end
52
+ end
@@ -0,0 +1,5 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require File.expand_path(File.join('..', '..', 'support', 'fake_heroku'), File.dirname(__FILE__))
4
+
5
+ FakeHeroku.new(ARGV).run!
@@ -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,15 @@
1
+ require 'spec_helper'
2
+
3
+ RSpec.describe 'GitHub' do
4
+ before do
5
+ drop_dummy_database
6
+ remove_project_directory
7
+ end
8
+
9
+ it 'suspends a project with --github option' do
10
+ repo_name = 'test'
11
+ run_onotole("--github=#{repo_name}")
12
+
13
+ expect(FakeGithub).to have_created_repo(repo_name)
14
+ end
15
+ end
@@ -0,0 +1,93 @@
1
+ require 'spec_helper'
2
+
3
+ RSpec.describe 'Heroku' do
4
+ context '--heroku' do
5
+ before(:all) do
6
+ clean_up
7
+ run_onotole('--heroku=true')
8
+ end
9
+
10
+ it 'suspends a project for Heroku' do
11
+ app_name = OnotoleTestHelpers::APP_NAME.dasherize
12
+
13
+ expect(FakeHeroku).to(
14
+ have_gem_included(project_path, 'rails_stdout_logging')
15
+ )
16
+ expect(FakeHeroku).to have_created_app_for('staging')
17
+ expect(FakeHeroku).to have_created_app_for('production')
18
+ expect(FakeHeroku).to have_configured_vars('staging', 'SECRET_KEY_BASE')
19
+ expect(FakeHeroku).to have_configured_vars(
20
+ 'production',
21
+ 'SECRET_KEY_BASE'
22
+ )
23
+ expect(FakeHeroku).to have_setup_pipeline_for(app_name)
24
+
25
+ bin_setup_path = "#{project_path}/bin/setup"
26
+ bin_setup = IO.read(bin_setup_path)
27
+
28
+ expect(bin_setup).to include("heroku join --app #{app_name}-production")
29
+ expect(bin_setup).to include("heroku join --app #{app_name}-staging")
30
+ expect(bin_setup).to include('git config heroku.remote staging')
31
+ expect(File.stat(bin_setup_path)).to be_executable
32
+
33
+ bin_setup_path = "#{project_path}/bin/setup_review_app"
34
+ bin_setup = IO.read(bin_setup_path)
35
+
36
+ expect(bin_setup).to include("heroku run rake db:migrate --app #{app_name}-staging-pr-$1")
37
+ expect(bin_setup).to include("heroku ps:scale worker=1 --app #{app_name}-staging-pr-$1")
38
+ expect(bin_setup).to include("heroku restart --app #{app_name}-staging-pr-$1")
39
+ expect(File.stat(bin_setup_path)).to be_executable
40
+
41
+ bin_deploy_path = "#{project_path}/bin/deploy"
42
+ bin_deploy = IO.read(bin_deploy_path)
43
+
44
+ expect(bin_deploy).to include('heroku run rake db:migrate')
45
+ expect(File.stat(bin_deploy_path)).to be_executable
46
+
47
+ readme = IO.read("#{project_path}/README.md")
48
+
49
+ expect(readme).to include('./bin/deploy staging')
50
+ expect(readme).to include('./bin/deploy production')
51
+
52
+ circle_yml_path = "#{project_path}/circle.yml"
53
+ circle_yml = IO.read(circle_yml_path)
54
+
55
+ expect(circle_yml).to include <<-YML.strip_heredoc
56
+ deployment:
57
+ staging:
58
+ branch: master
59
+ commands:
60
+ - bin/deploy staging
61
+ YML
62
+ end
63
+
64
+ it 'adds app.json file' do
65
+ expect(File).to exist("#{project_path}/app.json")
66
+ end
67
+
68
+ it 'includes application name in app.json file' do
69
+ app_json_file = IO.read("#{project_path}/app.json")
70
+ app_name = OnotoleTestHelpers::APP_NAME.dasherize
71
+
72
+ expect(app_json_file).to match(/"name":"#{app_name}"/)
73
+ end
74
+ end
75
+
76
+ context '--heroku with region flag' do
77
+ before(:all) do
78
+ clean_up
79
+ run_onotole(%(--heroku=true --heroku-flags="--region eu"))
80
+ end
81
+
82
+ it 'suspends a project with extra Heroku flags' do
83
+ expect(FakeHeroku).to have_created_app_for('staging', '--region eu')
84
+ expect(FakeHeroku).to have_created_app_for('production', '--region eu')
85
+ end
86
+ end
87
+
88
+ def clean_up
89
+ drop_dummy_database
90
+ remove_project_directory
91
+ FakeHeroku.clear!
92
+ end
93
+ end