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,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