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,8 @@
1
+ require 'bundler/setup'
2
+ require 'bundler/gem_tasks'
3
+ require 'rspec/core/rake_task'
4
+
5
+ RSpec::Core::RakeTask.new(:rspec)
6
+
7
+ desc 'Run the test suite'
8
+ task default: :rspec
@@ -0,0 +1,35 @@
1
+ #!/usr/bin/env ruby
2
+ require 'pathname'
3
+
4
+ source_path = (Pathname.new(__FILE__).dirname + '../lib').expand_path
5
+ $LOAD_PATH << source_path
6
+
7
+ require 'onotole'
8
+ GEMPROCLIST = Onotole::AppBuilder.public_instance_methods.map(&:to_s)
9
+ .grep(/_gem$/)
10
+ .grep(/^add_/)
11
+ .map { |a| a[4..-5].to_sym }
12
+ .sort
13
+
14
+ DEFAULT_GEMSET = [:slim, :faker, :guard, :rubocop, :meta_request, :clean_comments, :responders].freeze
15
+
16
+ if ['-v', '--version'].include? ARGV[0]
17
+ puts Onotole::VERSION
18
+ exit 0
19
+ elsif ['--gems'].include? ARGV[0]
20
+ puts 'You can manually can add gems from the list like options'
21
+ puts "Onotole app_path [--gem1_name --gem2_name ...]\n\n"
22
+
23
+ GEMPROCLIST.map { |a| "--#{a}" }.each_with_index do |g, i|
24
+ puts if i % 4 == 0 && i > 1
25
+ print g.ljust(20)
26
+ end
27
+ puts
28
+ exit 0
29
+ end
30
+
31
+ templates_root = File.expand_path(File.join('..', 'templates'), File.dirname(__FILE__))
32
+ Onotole::AppGenerator.source_root templates_root
33
+ Onotole::AppGenerator.source_paths << Rails::Generators::AppGenerator.source_root << templates_root
34
+
35
+ Onotole::AppGenerator.start
@@ -0,0 +1,16 @@
1
+ #!/usr/bin/env ruby
2
+ #
3
+ # This file was generated by Bundler.
4
+ #
5
+ # The application 'rake' is installed as part of a gem, and
6
+ # this file is here to facilitate running it.
7
+ #
8
+
9
+ require 'pathname'
10
+ ENV['BUNDLE_GEMFILE'] ||= File.expand_path('../../Gemfile',
11
+ Pathname.new(__FILE__).realpath)
12
+
13
+ require 'rubygems'
14
+ require 'bundler/setup'
15
+
16
+ load Gem.bin_path('rake', 'rake')
@@ -0,0 +1,16 @@
1
+ #!/usr/bin/env ruby
2
+ #
3
+ # This file was generated by Bundler.
4
+ #
5
+ # The application 'rspec' is installed as part of a gem, and
6
+ # this file is here to facilitate running it.
7
+ #
8
+
9
+ require 'pathname'
10
+ ENV['BUNDLE_GEMFILE'] ||= File.expand_path('../../Gemfile',
11
+ Pathname.new(__FILE__).realpath)
12
+
13
+ require 'rubygems'
14
+ require 'bundler/setup'
15
+
16
+ load Gem.bin_path('rspec-core', 'rspec')
@@ -0,0 +1,13 @@
1
+ #!/bin/sh
2
+
3
+ # Run this script immediately after cloning the codebase.
4
+
5
+ # Exit if any subcommand fails
6
+ set -e
7
+
8
+ # Set up Ruby dependencies via Bundler
9
+ bundle install
10
+
11
+ # Add binstubs to PATH in ~/.zshenv like this:
12
+ # export PATH=".git/safe/../../bin:$PATH"
13
+ mkdir -p .git/safe
@@ -0,0 +1,6 @@
1
+ require 'onotole/version'
2
+ require 'onotole/colors'
3
+ require 'onotole/generators/app_generator'
4
+ require 'onotole/actions'
5
+ require 'onotole/adapters/heroku'
6
+ require 'onotole/app_builder'
@@ -0,0 +1,33 @@
1
+ module Onotole
2
+ module Actions
3
+ def replace_in_file(relative_path, find, replace, quiet_err = false)
4
+ path = File.join(destination_root, relative_path)
5
+ contents = IO.read(path)
6
+ unless contents.gsub!(find, replace)
7
+ raise "#{find.inspect} not found in #{relative_path}" if quiet_err == false
8
+ end
9
+ File.open(path, 'w') { |file| file.write(contents) }
10
+ end
11
+
12
+ def action_mailer_host(rails_env, host)
13
+ config = "config.action_mailer.default_url_options = { host: #{host} }"
14
+ configure_environment(rails_env, config)
15
+ end
16
+
17
+ def configure_application_file(config)
18
+ inject_into_file(
19
+ 'config/application.rb',
20
+ "\n\n #{config}",
21
+ before: "\n end"
22
+ )
23
+ end
24
+
25
+ def configure_environment(rails_env, config)
26
+ inject_into_file(
27
+ "config/environments/#{rails_env}.rb",
28
+ "\n\n #{config}",
29
+ before: "\nend"
30
+ )
31
+ end
32
+ end
33
+ end
@@ -0,0 +1,125 @@
1
+ module Onotole
2
+ module Adapters
3
+ class Heroku
4
+ def initialize(app_builder)
5
+ @app_builder = app_builder
6
+ end
7
+
8
+ def set_heroku_remotes
9
+ remotes = <<-SHELL.strip_heredoc
10
+ #{command_to_join_heroku_app('staging')}
11
+ #{command_to_join_heroku_app('production')}
12
+
13
+ git config heroku.remote staging
14
+ SHELL
15
+
16
+ app_builder.append_file 'bin/setup', remotes
17
+ end
18
+
19
+ def set_up_heroku_specific_gems
20
+ app_builder.inject_into_file(
21
+ 'Gemfile',
22
+ %(\n\s\sgem "rails_stdout_logging"),
23
+ after: /group :staging, :production do/
24
+ )
25
+ end
26
+
27
+ def create_staging_heroku_app(flags)
28
+ rack_env = 'RACK_ENV=staging RAILS_ENV=staging'
29
+ app_name = heroku_app_name_for('staging')
30
+
31
+ run_toolbelt_command "create #{app_name} #{flags}", 'staging'
32
+ run_toolbelt_command "config:add #{rack_env}", 'staging'
33
+ end
34
+
35
+ def create_production_heroku_app(flags)
36
+ app_name = heroku_app_name_for('production')
37
+
38
+ run_toolbelt_command "create #{app_name} #{flags}", 'production'
39
+ end
40
+
41
+ def set_heroku_rails_secrets
42
+ %w(staging production).each do |environment|
43
+ run_toolbelt_command(
44
+ "config:add SECRET_KEY_BASE=#{generate_secret}",
45
+ environment
46
+ )
47
+ end
48
+ end
49
+
50
+ def provide_review_apps_setup_script
51
+ app_builder.template(
52
+ 'bin_setup_review_app.erb',
53
+ 'bin/setup_review_app',
54
+ force: true
55
+ )
56
+ app_builder.run 'chmod a+x bin/setup_review_app'
57
+ end
58
+
59
+ def create_heroku_pipelines_config_file
60
+ app_builder.template 'app.json.erb', 'app.json'
61
+ end
62
+
63
+ def create_heroku_pipeline
64
+ pipelines_plugin = `heroku plugins | grep pipelines`
65
+ if pipelines_plugin.empty?
66
+ puts 'You need heroku pipelines plugin. Run: heroku plugins:install heroku-pipelines'
67
+ exit 1
68
+ end
69
+
70
+ heroku_app_name = app_builder.app_name.dasherize
71
+ run_toolbelt_command(
72
+ "pipelines:create #{heroku_app_name} \
73
+ -a #{heroku_app_name}-staging --stage staging",
74
+ 'staging'
75
+ )
76
+
77
+ run_toolbelt_command(
78
+ "pipelines:add #{heroku_app_name} \
79
+ -a #{heroku_app_name}-production --stage production",
80
+ 'production'
81
+ )
82
+ end
83
+
84
+ def set_heroku_serve_static_files
85
+ %w(staging production).each do |environment|
86
+ run_toolbelt_command(
87
+ 'config:add RAILS_SERVE_STATIC_FILES=true',
88
+ environment
89
+ )
90
+ end
91
+ end
92
+
93
+ private
94
+
95
+ attr_reader :app_builder
96
+
97
+ def command_to_join_heroku_app(environment)
98
+ heroku_app_name = heroku_app_name_for(environment)
99
+ <<-SHELL
100
+
101
+ if heroku join --app #{heroku_app_name} &> /dev/null; then
102
+ git remote add #{environment} git@heroku.com:#{heroku_app_name}.git || true
103
+ printf 'You are a collaborator on the "#{heroku_app_name}" Heroku app\n'
104
+ else
105
+ printf 'Ask for access to the "#{heroku_app_name}" Heroku app\n'
106
+ fi
107
+ SHELL
108
+ end
109
+
110
+ def heroku_app_name_for(environment)
111
+ "#{app_builder.app_name.dasherize}-#{environment}"
112
+ end
113
+
114
+ def generate_secret
115
+ SecureRandom.hex(64)
116
+ end
117
+
118
+ def run_toolbelt_command(command, environment)
119
+ app_builder.run(
120
+ "heroku #{command} --remote #{environment}"
121
+ )
122
+ end
123
+ end
124
+ end
125
+ end
@@ -0,0 +1,119 @@
1
+ module Onotole
2
+ module AfterInstallPatch
3
+ def post_init
4
+ install_queue = [:responders,
5
+ :guard,
6
+ :guard_rubocop,
7
+ :bootstrap3_sass,
8
+ :bootstrap3,
9
+ :devise,
10
+ :normalize,
11
+ :tinymce,
12
+ :rubocop,
13
+ :create_github_repo]
14
+ install_queue.each { |q| send "after_install_#{q}" }
15
+ delete_comments
16
+ end
17
+
18
+ def after_install_devise
19
+ generate 'devise:install' if user_choose? :devise
20
+ if AppBuilder.devise_model && user_choose?(:devise)
21
+ generate "devise #{AppBuilder.devise_model.titleize}"
22
+ inject_into_file('app/controllers/application_controller.rb',
23
+ "\nbefore_action :authenticate_#{AppBuilder.devise_model.titleize}!",
24
+ after: 'before_action :configure_permitted_parameters, if: :devise_controller?')
25
+ end
26
+ if user_choose?(:bootstrap3)
27
+ generate 'devise:views:bootstrap_templates'
28
+ else
29
+ generate 'devise:views'
30
+ end
31
+ end
32
+
33
+ def after_install_rubocop
34
+ if user_choose? :rubocop
35
+ t = <<-TEXT
36
+
37
+ if ENV['RAILS_ENV'] == 'test' || ENV['RAILS_ENV'] == 'development'
38
+ require 'rubocop/rake_task'
39
+ RuboCop::RakeTask.new
40
+ end
41
+ TEXT
42
+ append_file 'Rakefile', t
43
+ run 'rubocop -a'
44
+ end
45
+ end
46
+
47
+ def after_install_guard
48
+ if user_choose?(:guard)
49
+ run 'guard init'
50
+ replace_in_file 'Guardfile',
51
+ "guard 'puma' do",
52
+ 'guard :puma, port: 3000 do', quiet_err = true
53
+ end
54
+ end
55
+
56
+ def after_install_guard_rubocop
57
+ if user_choose?(:guard_rubocop) && user_choose?(:guard) && user_choose?(:rubocop)
58
+
59
+ cover_def_by 'Guardfile', 'guard :rubocop do', 'group :red_green_refactor, halt_on_fail: true do'
60
+ cover_def_by 'Guardfile', 'guard :rspec, ', 'group :red_green_refactor, halt_on_fail: true do'
61
+
62
+ replace_in_file 'Guardfile',
63
+ 'guard :rubocop do',
64
+ 'guard :rubocop, all_on_start: false do', quiet_err = true
65
+ replace_in_file 'Guardfile',
66
+ 'guard :rspec, cmd: "bundle exec rspec" do',
67
+ "guard :rspec, cmd: 'bundle exec rspec', failed_mode: :keep do", quiet_err = true
68
+ end
69
+ end
70
+
71
+ def after_install_bootstrap3_sass
72
+ if user_choose? :bootstrap3_sass
73
+ setup_stylesheets
74
+ AppBuilder.use_asset_pipelline = false
75
+ append_file(AppBuilder.app_file_scss,
76
+ "\n@import 'bootstrap-sprockets';\n@import 'bootstrap';")
77
+ inject_into_file(AppBuilder.js_file, "\n//= require bootstrap-sprockets",
78
+ after: '//= require jquery_ujs')
79
+ end
80
+ end
81
+
82
+ def after_install_bootstrap3
83
+ if user_choose? :bootstrap3
84
+ AppBuilder.use_asset_pipelline = true
85
+ remove_file 'app/views/layouts/application.html.erb'
86
+ generate 'bootstrap:install static'
87
+ generate 'bootstrap:layout'
88
+ inject_into_file('app/assets/stylesheets/bootstrap_and_overrides.css',
89
+ " =require devise_bootstrap_views\n",
90
+ before: ' */')
91
+ end
92
+ end
93
+
94
+ def after_install_normalize
95
+ if AppBuilder.use_asset_pipelline
96
+ inject_into_file(AppBuilder.app_file_css, " *= require normalize-rails\n",
97
+ after: " * file per style scope.\n *\n")
98
+ else
99
+ inject_into_file(AppBuilder.app_file_scss, "\n@import 'normalize-rails';",
100
+ after: '@charset "utf-8";')
101
+ end
102
+ end
103
+
104
+ def after_install_tinymce
105
+ if user_choose? :tinymce
106
+ inject_into_file(AppBuilder.js_file, "\n//= require tinymce-jquery",
107
+ after: '//= require jquery_ujs')
108
+ end
109
+ end
110
+
111
+ def after_install_responders
112
+ run('rails g responders:install') if user_choose? :responders
113
+ end
114
+
115
+ def after_install_create_github_repo
116
+ create_github_repo(app_name) if user_choose? :create_github_repo
117
+ end
118
+ end
119
+ end
@@ -0,0 +1,137 @@
1
+ module Onotole
2
+ module BeforeBundlePatch
3
+ def add_user_gems
4
+ GEMPROCLIST.each do |g|
5
+ send "add_#{g}_gem" if user_choose? g.to_sym
6
+ end
7
+ # add_foo_bar_gem if user_choose?(:foo) && user_choose?(:bar)
8
+ end
9
+
10
+ def add_haml_gem
11
+ inject_into_file('Gemfile', "\ngem 'haml-rails'", after: '# user_choice')
12
+ end
13
+
14
+ def add_dotenv_heroku_gem
15
+ inject_into_file('Gemfile', "\n gem 'dotenv-heroku'",
16
+ after: 'group :development do')
17
+ append_file 'Rakefile', %(\nrequire 'dotenv-heroku/tasks' if ENV['RAILS_ENV'] == 'test' || ENV['RAILS_ENV'] == 'development'\n)
18
+ end
19
+
20
+ def add_slim_gem
21
+ inject_into_file('Gemfile', "\ngem 'slim-rails'", after: '# user_choice')
22
+ inject_into_file('Gemfile', "\n gem 'html2slim'", after: 'group :development do')
23
+ end
24
+
25
+ def add_rails_db_gem
26
+ inject_into_file('Gemfile', "\n gem 'rails_db'\n gem 'axlsx_rails'",
27
+ after: 'group :development do')
28
+ end
29
+
30
+ def add_rubocop_gem
31
+ inject_into_file('Gemfile', "\n gem 'rubocop', require: false",
32
+ after: 'group :development do')
33
+ copy_file 'rubocop.yml', '.rubocop.yml'
34
+ end
35
+
36
+ def add_guard_gem
37
+ t = <<-TEXT.chomp
38
+
39
+ gem 'guard'
40
+ gem 'guard-livereload', '~> 2.4', require: false
41
+ gem 'guard-puma'
42
+ gem 'guard-migrate'
43
+ gem 'guard-rspec', require: false
44
+ gem 'guard-bundler', require: false
45
+ gem 'rb-inotify', github: 'kvokka/rb-inotify'
46
+ TEXT
47
+ inject_into_file('Gemfile', t, after: 'group :development do')
48
+ end
49
+
50
+ def add_guard_rubocop_gem
51
+ if user_choose?(:guard) && user_choose?(:rubocop)
52
+ inject_into_file('Gemfile', "\n gem 'guard-rubocop'",
53
+ after: 'group :development do')
54
+ else
55
+ say_color RED, 'You need Guard & Rubocop gems for this add-on'
56
+ end
57
+ end
58
+
59
+ def add_meta_request_gem
60
+ inject_into_file('Gemfile', "\n gem 'meta_request' # link for chrome add-on. https://chrome.google.com/webstore/detail/railspanel/gjpfobpafnhjhbajcjgccbbdofdckggg",
61
+ after: 'group :development do')
62
+ end
63
+
64
+ def add_faker_gem
65
+ inject_into_file('Gemfile', "\n gem 'faker'", after: 'group :development, :test do')
66
+ end
67
+
68
+ def add_bundler_audit_gem
69
+ copy_file 'bundler_audit.rake', 'lib/tasks/bundler_audit.rake'
70
+ append_file 'Rakefile', %(\ntask default: "bundler:audit"\n)
71
+ end
72
+
73
+ def add_bootstrap3_sass_gem
74
+ inject_into_file('Gemfile', "\ngem 'bootstrap-sass', '~> 3.3.6'",
75
+ after: '# user_choice')
76
+ end
77
+
78
+ def add_airbrake_gem
79
+ inject_into_file('Gemfile', "\ngem 'airbrake'",
80
+ after: '# user_choice')
81
+ end
82
+
83
+ def add_bootstrap3_gem
84
+ inject_into_file('Gemfile', "\ngem 'twitter-bootstrap-rails'",
85
+ after: '# user_choice')
86
+ inject_into_file('Gemfile', "\ngem 'devise-bootstrap-views'",
87
+ after: '# user_choice') if user_choose?(:devise)
88
+ end
89
+
90
+ def add_devise_gem
91
+ devise_conf = <<-TEXT
92
+
93
+ # v.3.5 syntax. will be deprecated in 4.0
94
+ def configure_permitted_parameters
95
+ devise_parameter_sanitizer.for(:sign_in) do |user_params|
96
+ user_params.permit(:email, :password)
97
+ end
98
+
99
+ devise_parameter_sanitizer.for(:sign_up) do |user_params|
100
+ user_params.permit(:email, :password, :password_confirmation)
101
+ end
102
+ end
103
+ protected :configure_permitted_parameters
104
+ TEXT
105
+ inject_into_file('Gemfile', "\ngem 'devise'", after: '# user_choice')
106
+ inject_into_file('app/controllers/application_controller.rb',
107
+ "\nbefore_action :configure_permitted_parameters, if: :devise_controller?",
108
+ after: 'class ApplicationController < ActionController::Base')
109
+
110
+ inject_into_file('app/controllers/application_controller.rb', devise_conf,
111
+ after: 'protect_from_forgery with: :exception')
112
+ copy_file 'devise_rspec.rb', 'spec/support/devise.rb'
113
+ end
114
+
115
+ def add_will_paginate_gem
116
+ inject_into_file('Gemfile', "\ngem 'will_paginate', '~> 3.0.6'",
117
+ after: '# user_choice')
118
+ inject_into_file('Gemfile', "\ngem 'will_paginate-bootstrap'",
119
+ after: '# user_choice') if user_choose?(:bootstrap3) ||
120
+ user_choose?(:bootstrap3_sass)
121
+ end
122
+
123
+ def add_responders_gem
124
+ inject_into_file('Gemfile', "\ngem 'responders'", after: '# user_choice')
125
+ end
126
+
127
+ def add_hirbunicode_gem
128
+ inject_into_file('Gemfile', "\ngem 'hirb-unicode'", after: '# user_choice')
129
+ end
130
+
131
+ def add_tinymce_gem
132
+ inject_into_file('Gemfile', "\ngem 'tinymce-rails'", after: '# user_choice')
133
+ inject_into_file('Gemfile', "\ngem 'tinymce-rails-langs'", after: '# user_choice')
134
+ copy_file 'tinymce.yml', 'config/tinymce.yml'
135
+ end
136
+ end
137
+ end