gnarails 0.9.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (101) hide show
  1. checksums.yaml +7 -0
  2. data/.circleci/config.yml +227 -0
  3. data/.gitignore +5 -0
  4. data/.pronto.yml +2 -0
  5. data/.railsrc +2 -0
  6. data/.rspec +2 -0
  7. data/.rubocop.yml +3 -0
  8. data/.ruby-version +1 -0
  9. data/Brewfile +3 -0
  10. data/CHANGELOG.md +63 -0
  11. data/CODE_OF_CONDUCT.md +74 -0
  12. data/CONTRIBUTING.md +48 -0
  13. data/Gemfile +11 -0
  14. data/Gemfile.lock +213 -0
  15. data/LICENSE +21 -0
  16. data/README.md +136 -0
  17. data/Rakefile +6 -0
  18. data/bin/ci_pronto +6 -0
  19. data/bin/console +14 -0
  20. data/bin/generate-react-test-app.sh +2 -0
  21. data/bin/generate-test-app.sh +22 -0
  22. data/bin/setup +8 -0
  23. data/bin/test-setup.sh +8 -0
  24. data/exe/gnarails +4 -0
  25. data/gnarails.gemspec +34 -0
  26. data/gnarly.rb +395 -0
  27. data/lib/gnarails/cli/application.rb +192 -0
  28. data/lib/gnarails/version.rb +3 -0
  29. data/lib/gnarails.rb +8 -0
  30. data/templates/.circleci/config.yml +66 -0
  31. data/templates/.env.development +5 -0
  32. data/templates/.env.docker/.env.docker-standard +1 -0
  33. data/templates/.env.docker/.env.docker-webpack +2 -0
  34. data/templates/.env.docker-assets +1 -0
  35. data/templates/.env.test +5 -0
  36. data/templates/.gitignore +20 -0
  37. data/templates/.pronto.yml +2 -0
  38. data/templates/.rspec +3 -0
  39. data/templates/.rubocop.yml +3 -0
  40. data/templates/.ruby-version +1 -0
  41. data/templates/.scss-lint.yml +33 -0
  42. data/templates/Dockerfile +20 -0
  43. data/templates/Dockerfile-assets +24 -0
  44. data/templates/README.md +83 -0
  45. data/templates/database.yml +20 -0
  46. data/templates/docker-compose.yml/docker-compose-standard.yml +15 -0
  47. data/templates/docker-compose.yml/docker-compose-webpack.yml +26 -0
  48. data/templates/react/.babelrc +18 -0
  49. data/templates/react/.eslintrc.js +45 -0
  50. data/templates/react/controllers/home_controller.rb +4 -0
  51. data/templates/react/js/Router/Router.jsx +22 -0
  52. data/templates/react/js/Router/index.js +3 -0
  53. data/templates/react/js/api/index.js +17 -0
  54. data/templates/react/js/api/sessions.js +8 -0
  55. data/templates/react/js/app_constants/index.js +6 -0
  56. data/templates/react/js/components/App/App.jsx +15 -0
  57. data/templates/react/js/components/App/App.tests.jsx +15 -0
  58. data/templates/react/js/components/App/_styles.scss +3 -0
  59. data/templates/react/js/components/App/index.js +3 -0
  60. data/templates/react/js/index.scss +2 -0
  61. data/templates/react/js/packs/main.jsx +13 -0
  62. data/templates/react/js/redux/entity_getter.js +7 -0
  63. data/templates/react/js/redux/history.js +5 -0
  64. data/templates/react/js/redux/initial_state.js +5 -0
  65. data/templates/react/js/redux/middlewares/authentication_middleware/authentication_middleware.tests.js +109 -0
  66. data/templates/react/js/redux/middlewares/authentication_middleware/helpers.js +21 -0
  67. data/templates/react/js/redux/middlewares/authentication_middleware/helpers.tests.js +84 -0
  68. data/templates/react/js/redux/middlewares/authentication_middleware/index.js +20 -0
  69. data/templates/react/js/redux/middlewares/index.js +11 -0
  70. data/templates/react/js/redux/nodes/app/actions.js +36 -0
  71. data/templates/react/js/redux/nodes/app/config.js +12 -0
  72. data/templates/react/js/redux/nodes/app/reducer.js +35 -0
  73. data/templates/react/js/redux/nodes/app/reducer.tests.js +78 -0
  74. data/templates/react/js/redux/reducers.js +11 -0
  75. data/templates/react/js/redux/store.js +14 -0
  76. data/templates/react/js/storage.js +15 -0
  77. data/templates/react/js/styles/_variables.scss +1 -0
  78. data/templates/react/js/test/.setup.js +51 -0
  79. data/templates/react/js/test/connect_wrapper.jsx +28 -0
  80. data/templates/react/js/test/create_request_mock.js +29 -0
  81. data/templates/react/js/test/mock_store.js +12 -0
  82. data/templates/react/layout.html.erb +16 -0
  83. data/templates/react/rails_routes.rb +5 -0
  84. data/templates/react/views/home/default.html.erb +1 -0
  85. data/templates/script/brakeman +15 -0
  86. data/templates/script/ci_pronto +6 -0
  87. data/templates/spec/support/factory_bot.rb +5 -0
  88. data/templates/spec/support/system_test_configuration.rb +13 -0
  89. data/test-app/app/controllers/job_postings_controller.rb +5 -0
  90. data/test-app/app/models/comment.rb +3 -0
  91. data/test-app/app/models/job_posting.rb +20 -0
  92. data/test-app/app/views/job_postings/index.html.erb +23 -0
  93. data/test-app/app/views/layouts/application.html.erb +14 -0
  94. data/test-app/config/routes.rb +5 -0
  95. data/test-app/db/migrate/20170918002433_create_job_postings.rb +12 -0
  96. data/test-app/db/migrate/20170918002455_create_comments.rb +10 -0
  97. data/test-app/spec/factories/job_postings.rb +5 -0
  98. data/test-app/spec/models/job_posting_spec.rb +21 -0
  99. data/test-app/spec/requests/status_spec.rb +11 -0
  100. data/test-app/spec/system/viewing_all_job_postings_spec.rb +36 -0
  101. metadata +270 -0
data/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ The MIT License (MIT)
2
+
3
+ Copyright (c) 2018 The Gnar Company
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in
13
+ all copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
21
+ THE SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,136 @@
1
+ # Gnarails
2
+
3
+ Create a gnarly rails app, ready to go with all the base functionality you can
4
+ expect from any rails application developed by The Gnar Company.
5
+
6
+ ## Usage
7
+
8
+ This template relies on pronto, which needs [cmake](https://cmake.org/) installed.
9
+
10
+ ### Using the CLI
11
+
12
+ ```sh
13
+ $ gem install gnarails
14
+ $ gnarails new <APP_NAME>
15
+ ```
16
+
17
+ ### Using the template
18
+
19
+ If you want to reference the template directly and don't want to use the
20
+ gnarails CLI command, you may clone the project (or reference the template from
21
+ its HTTP location on github):
22
+
23
+ ```sh
24
+ $ rails new <APP_NAME> -m https://raw.githubusercontent.com/TheGnarCo/gnarails/master/gnarly.rb --skip-test-unit --database=postgresql
25
+ ```
26
+
27
+ A`.railsrc` is provided. If you'd like to symlink it to your home directory, it'll run `rails new` with the options to run with postgres and not including test-unit. This `.railsrc` can be personalized to include the `--template=path/to/gnarly.rb` option depending on where you locally store this repo if you'd like to use this template every time.
28
+
29
+ ## Usage with React
30
+
31
+ ### Using the CLI
32
+
33
+ ```sh
34
+ $ gem install gnarails
35
+ $ gnarails new <APP_NAME> --webpack=react
36
+ ```
37
+
38
+ ### Using the template
39
+
40
+ ```sh
41
+ $ rails new <APP_NAME> -m https://raw.githubusercontent.com/TheGnarCo/gnarails/master/gnarly.rb --skip-test-unit --database=postgresql --webpack=react
42
+ ```
43
+
44
+ ## Post-Install
45
+
46
+ ```sh
47
+ $ cd <APP_NAME>
48
+ $ bin/bundle
49
+ $ bin/rails db:create
50
+ $ bin/rails db:migrate
51
+ ```
52
+
53
+ _For React Apps_
54
+
55
+ ```sh
56
+ $ bin/yarn
57
+ $ bin/yarn test
58
+ ```
59
+
60
+ ### Setting up pronto on CI
61
+
62
+ Pronto can be used to comment on pull requests for various automated checks of
63
+ changes made in a particular diff. To complete the setup of this tool for your
64
+ repository, you must identify a github account that pronto will comment as on
65
+ every PR, and update the following:
66
+
67
+ * Generate a Personal Access Token from the github account.
68
+ - Settings > Developer settings > Personal access tokens > Generate new token.
69
+ - Use the repo name for the token description.
70
+ - Provide the repo scope.
71
+ - Generate the token.
72
+ - Store/copy the token temporarily.
73
+
74
+ * Store the token value in circle.
75
+ - Find the repo settings.
76
+ - Build Settings > Environment Variables.
77
+ - Add Variable.
78
+ - Name the variable `PRONTO_GITHUB_ACCESS_TOKEN` with the value from the previous Personal Access Token.
79
+
80
+ ## Usage with Docker
81
+
82
+ A `Dockerfile` and `docker-compose.yml` file are created by default. When run with `--webpack=react`,
83
+ there are two `Dockerfile`s: one for the Rails server and one for the assets server.
84
+
85
+ To use Docker, run:
86
+
87
+ ```sh
88
+ docker-compose build
89
+ ```
90
+
91
+ then set up the database:
92
+
93
+ ```sh
94
+ docker-compose run web rails db:create
95
+ docker-compose run web rails db:migrate
96
+ ```
97
+
98
+ finally, start the server and visit `localhost:3000`:
99
+
100
+ ```sh
101
+ docker-compose up
102
+ ```
103
+
104
+ ## Switching out Capybara Driver
105
+ If you'd like to not run your tests headless, for example, to troubleshoot an issue and see what's on the screen, modify the `driven_by` driver in `spec/support/system_test_configuration.rb` to use `:selenium_chrome` instead of `:selenium_chrome_headless`. After the change, this block should look as follows:
106
+
107
+ ```ruby
108
+ config.before(:each, type: :system, js: true) do
109
+ driven_by :selenium_chrome
110
+ end
111
+ ```
112
+
113
+ ## Running the Application
114
+
115
+ ```sh
116
+ $ bin/rails s
117
+ ```
118
+
119
+ _For React Apps_
120
+
121
+ In a separate terminal window/tab
122
+
123
+ ```sh
124
+ $ bin/yarn start
125
+ ```
126
+
127
+ Visit `localhost:3000` in your browser
128
+
129
+ ## About The Gnar Company
130
+
131
+ ![The Gnar Company](https://avatars0.githubusercontent.com/u/17011419?s=100&v=4)
132
+
133
+ The Gnar Company is a Boston-based development company that builds robust
134
+ web and mobile apps designed for the long haul.
135
+
136
+ For more information see [our website](https://www.thegnar.co/).
data/Rakefile ADDED
@@ -0,0 +1,6 @@
1
+ require "bundler/gem_tasks"
2
+ require "rspec/core/rake_task"
3
+
4
+ RSpec::Core::RakeTask.new(:spec)
5
+
6
+ task :default => :spec
data/bin/ci_pronto ADDED
@@ -0,0 +1,6 @@
1
+ #!/bin/bash
2
+ #
3
+ # Script for running pronto on CI
4
+ export PRONTO_PULL_REQUEST_ID=${CI_PULL_REQUEST##*/}
5
+
6
+ bundle exec pronto run -f text github_pr github_status -c origin/master
data/bin/console ADDED
@@ -0,0 +1,14 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require "bundler/setup"
4
+ require "gnarails"
5
+
6
+ # You can add fixtures and/or initialization code here to make experimenting
7
+ # with your gem easier. You can also use a different console, if you like.
8
+
9
+ # (If you use this, don't forget to add pry to your Gemfile!)
10
+ # require "pry"
11
+ # Pry.start
12
+
13
+ require "irb"
14
+ IRB.start(__FILE__)
@@ -0,0 +1,2 @@
1
+ #!/bin/bash
2
+ bundle exec exe/gnarails new rails-react-test-app --webpack=react
@@ -0,0 +1,22 @@
1
+ #!/bin/bash
2
+ bundle exec exe/gnarails new rails-test-app
3
+
4
+ mkdir rails-test-app/app/views/job_postings
5
+ mkdir rails-test-app/db/migrate
6
+ mkdir rails-test-app/spec/factories
7
+ mkdir rails-test-app/spec/models
8
+ mkdir rails-test-app/spec/system
9
+ mkdir rails-test-app/spec/requests
10
+
11
+ cp test-app/app/controllers/job_postings_controller.rb rails-test-app/app/controllers/job_postings_controller.rb
12
+ cp test-app/app/models/job_posting.rb rails-test-app/app/models/job_posting.rb
13
+ cp test-app/app/models/comment.rb rails-test-app/app/models/comment.rb
14
+ cp test-app/app/views/job_postings/index.html.erb rails-test-app/app/views/job_postings/index.html.erb
15
+ yes | cp test-app/app/views/layouts/application.html.erb rails-test-app/app/views/layouts/application.html.erb
16
+ yes | cp test-app/config/routes.rb rails-test-app/config/routes.rb
17
+ cp test-app/db/migrate/20170918002433_create_job_postings.rb rails-test-app/db/migrate/20170918002433_create_job_postings.rb
18
+ cp test-app/db/migrate/20170918002455_create_comments.rb rails-test-app/db/migrate/20170918002455_create_comments.rb
19
+ cp test-app/spec/factories/job_postings.rb rails-test-app/spec/factories/job_postings.rb
20
+ cp test-app/spec/models/job_posting_spec.rb rails-test-app/spec/models/job_posting_spec.rb
21
+ cp test-app/spec/system/viewing_all_job_postings_spec.rb rails-test-app/spec/system/viewing_all_job_postings_spec.rb
22
+ cp test-app/spec/requests/status_spec.rb rails-test-app/spec/requests/status_spec.rb
data/bin/setup ADDED
@@ -0,0 +1,8 @@
1
+ #!/usr/bin/env bash
2
+ set -euo pipefail
3
+ IFS=$'\n\t'
4
+ set -vx
5
+
6
+ bundle install
7
+
8
+ # Do any other automated setup that you need to do here
data/bin/test-setup.sh ADDED
@@ -0,0 +1,8 @@
1
+ sh ./bin/generate-test-app.sh
2
+
3
+ cd rails-test-app
4
+ bundle
5
+ bundle exec rake db:drop
6
+ bundle exec rake db:setup
7
+ bundle exec rails db:migrate
8
+ cd ..
data/exe/gnarails ADDED
@@ -0,0 +1,4 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require "gnarails"
4
+ Gnarails::Cli::Application.start(ARGV)
data/gnarails.gemspec ADDED
@@ -0,0 +1,34 @@
1
+ lib = File.expand_path("../lib", __FILE__)
2
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
3
+ require "gnarails/version"
4
+
5
+ Gem::Specification.new do |spec|
6
+ spec.name = "gnarails"
7
+ spec.version = Gnarails::VERSION
8
+ spec.authors = ["The Gnar Company"]
9
+ spec.email = ["hi@thegnar.co"]
10
+
11
+ spec.summary = "Easily create a gnarly rails app."
12
+ spec.homepage = "https://github.com/TheGnarCo/gnarails"
13
+ spec.license = "MIT"
14
+
15
+ spec.files = `git ls-files -z`.split("\x0").reject do |f|
16
+ f.match(%r{^(test|spec|features)/})
17
+ end
18
+ spec.bindir = "exe"
19
+ spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
20
+ spec.require_paths = ["lib"]
21
+
22
+ spec.required_ruby_version = ">= 2.5.0"
23
+
24
+ spec.add_dependency "rails"
25
+ spec.add_dependency "rspec-rails"
26
+ spec.add_dependency "thor"
27
+
28
+ spec.add_development_dependency "bundler", "~> 1.16"
29
+ spec.add_development_dependency "gnar-style"
30
+ spec.add_development_dependency "pronto"
31
+ spec.add_development_dependency "pronto-rubocop"
32
+ spec.add_development_dependency "rake", "~> 10.0"
33
+ spec.add_development_dependency "rspec", "~> 3.0"
34
+ end
data/gnarly.rb ADDED
@@ -0,0 +1,395 @@
1
+ # Add the current directory to the path Thor uses
2
+ # to look up files
3
+ def source_paths
4
+ Array(super) +
5
+ [File.expand_path(File.dirname(__FILE__))]
6
+ end
7
+
8
+ RUBY_VERSION = "2.5.0".freeze
9
+
10
+ JS_DEPENDENCIES = [
11
+ "babel-preset-es2015".freeze,
12
+ "babel-preset-stage-0".freeze,
13
+ "classnames".freeze,
14
+ "es6-object-assign".freeze,
15
+ "es6-promise".freeze,
16
+ "history".freeze,
17
+ "lodash".freeze,
18
+ "react-entity-getter".freeze,
19
+ "react-redux".freeze,
20
+ "react-router".freeze,
21
+ "react-router-dom".freeze,
22
+ "react-router-redux@next".freeze,
23
+ "redux".freeze,
24
+ "redux-form".freeze,
25
+ "redux-thunk".freeze,
26
+ "schlepp".freeze,
27
+ ].freeze
28
+
29
+ JS_DEV_DEPENDENCIES = [
30
+ "babel-eslint".freeze,
31
+ "enzyme".freeze,
32
+ "enzyme-adapter-react-16".freeze,
33
+ "eslint".freeze,
34
+ "eslint-config-airbnb".freeze,
35
+ "eslint-plugin-import".freeze,
36
+ "eslint-plugin-jsx-a11y@^5.1.1".freeze,
37
+ "eslint-plugin-react".freeze,
38
+ "expect".freeze,
39
+ "jsdom".freeze,
40
+ "mocha".freeze,
41
+ "nock".freeze,
42
+ "react-dom".freeze,
43
+ "react-test-renderer".freeze,
44
+ "redux-mock-store".freeze,
45
+ ].freeze
46
+
47
+ def create_gnarly_rails_app
48
+ add_gems
49
+ setup_database
50
+ add_ruby_version
51
+ setup_scss
52
+ setup_gitignore
53
+ setup_testing
54
+ setup_analysis
55
+ setup_environments
56
+ setup_readme
57
+ post_bundle
58
+ end
59
+
60
+ def add_gems
61
+ gem_group :development, :test do
62
+ gem 'axe-matchers'
63
+ gem 'bullet'
64
+ gem 'bundler-audit'
65
+ gem 'capybara'
66
+ gem 'dotenv-rails'
67
+ gem 'factory_bot_rails'
68
+ gem 'gnar-style', require: false
69
+ gem 'lol_dba'
70
+ gem 'okcomputer'
71
+ gem 'pronto'
72
+ gem 'pronto-brakeman', require: false
73
+ gem 'pronto-rubocop', require: false
74
+ gem 'pronto-scss', require: false
75
+ gem 'pry-rails'
76
+ gem 'rspec-its'
77
+ gem 'rspec-rails'
78
+ gem 'scss_lint', require: false
79
+ gem 'selenium-webdriver'
80
+ gem 'shoulda-matchers'
81
+ gem 'simplecov', require: false
82
+ end
83
+ end
84
+
85
+ def setup_database
86
+ remove_file "config/database.yml"
87
+ copy_file "templates/database.yml", "config/database.yml"
88
+ gsub_file "config/database.yml", "__application_name__", app_name
89
+
90
+ gsub_file "Gemfile", /.*sqlite.*\n/, ""
91
+ end
92
+
93
+ def add_ruby_version
94
+ insert_into_file "Gemfile", after: "source 'https://rubygems.org'" do
95
+ "\nruby \"#{RUBY_VERSION}\""
96
+ end
97
+
98
+ copy_file "templates/.ruby-version", ".ruby-version"
99
+ gsub_file ".ruby-version", "__ruby_version__", RUBY_VERSION
100
+ end
101
+
102
+ def setup_scss
103
+ run "mv app/assets/stylesheets/application.css app/assets/stylesheets/application.scss"
104
+ end
105
+
106
+ def setup_gitignore
107
+ remove_file ".gitignore"
108
+ copy_file "templates/.gitignore", ".gitignore"
109
+ end
110
+
111
+ def setup_testing
112
+ setup_rspec
113
+ setup_factory_bot
114
+ setup_system_tests
115
+ setup_shoulda
116
+ setup_bullet
117
+ limit_test_logging
118
+ end
119
+
120
+ def setup_rspec
121
+ generate "rspec:install"
122
+ remove_file ".rspec"
123
+ copy_file "templates/.rspec", ".rspec"
124
+ gsub_file "spec/rails_helper.rb",
125
+ "# Dir[Rails.root.join('spec/support/**/*.rb')].each { |f| require f }",
126
+ "Dir[Rails.root.join(\"spec/support/**/*.rb\")].each { |f| require f }"
127
+ end
128
+
129
+ def setup_factory_bot
130
+ copy_file "templates/spec/support/factory_bot.rb", "spec/support/factory_bot.rb"
131
+ end
132
+
133
+ def setup_system_tests
134
+ copy_file "templates/spec/support/system_test_configuration.rb",
135
+ "spec/support/system_test_configuration.rb"
136
+
137
+ insert_into_file "spec/rails_helper.rb", after: "Rails is not loaded until this point!\n" do
138
+ system_tests_rails_helper_text
139
+ end
140
+
141
+ append_to_file "spec/rails_helper.rb" do
142
+ "\nCapybara.default_max_wait_time = 3\n"
143
+ end
144
+ end
145
+
146
+ def system_tests_rails_helper_text
147
+ <<~SYSTEM_TESTS
148
+ require "capybara/rails"
149
+ require "axe/rspec"
150
+ require "selenium/webdriver"
151
+ SYSTEM_TESTS
152
+ end
153
+
154
+ def setup_shoulda
155
+ append_to_file "spec/rails_helper.rb" do
156
+ shoulda_rails_helper_text
157
+ end
158
+ end
159
+
160
+ def shoulda_rails_helper_text
161
+ <<~SHOULDA
162
+
163
+ Shoulda::Matchers.configure do |config|
164
+ config.integrate do |with|
165
+ with.test_framework :rspec
166
+ with.library :rails
167
+ end
168
+ end
169
+ SHOULDA
170
+ end
171
+
172
+ def setup_bullet
173
+ insert_into_file "config/environments/test.rb", after: "Rails.application.configure do" do
174
+ bullet_test_env_text
175
+ end
176
+
177
+ insert_into_file "spec/rails_helper.rb", after: "RSpec.configure do |config|" do
178
+ bullet_rails_helper_text
179
+ end
180
+ end
181
+
182
+ def bullet_test_env_text
183
+ <<-BULLET_TEST
184
+
185
+ # Bullet gem initialization
186
+ config.after_initialize do
187
+ Bullet.enable = true
188
+ Bullet.bullet_logger = true
189
+ Bullet.raise = true
190
+ end
191
+ BULLET_TEST
192
+ end
193
+
194
+ def bullet_rails_helper_text
195
+ <<-BULLET_RAILS
196
+
197
+ if Bullet.enable?
198
+ config.before(:each) do
199
+ Bullet.start_request
200
+ end
201
+
202
+ config.after(:each) do
203
+ Bullet.perform_out_of_channel_notifications if Bullet.notification?
204
+ Bullet.end_request
205
+ end
206
+ end
207
+ BULLET_RAILS
208
+ end
209
+
210
+ def limit_test_logging
211
+ insert_into_file "config/environments/test.rb", after: "Rails.application.configure do" do
212
+ <<-TEST_LOGGING
213
+
214
+ unless ENV[\"RAILS_ENABLE_TEST_LOG\"]
215
+ config.logger = Logger.new(nil)
216
+ config.log_level = :fatal
217
+ end
218
+ TEST_LOGGING
219
+ end
220
+ end
221
+
222
+ def setup_analysis
223
+ setup_linting
224
+ setup_pronto
225
+ setup_brakeman
226
+ setup_simplecov
227
+ end
228
+
229
+ def setup_linting
230
+ copy_file "templates/.rubocop.yml", ".rubocop.yml"
231
+ copy_file "templates/.scss-lint.yml", ".scss-lint.yml"
232
+ end
233
+
234
+ def setup_pronto
235
+ copy_file "templates/.pronto.yml", ".pronto.yml"
236
+ copy_file "templates/script/ci_pronto", "script/ci_pronto"
237
+ run "chmod +x script/ci_pronto"
238
+ end
239
+
240
+ def setup_brakeman
241
+ copy_file "templates/script/brakeman", "script/brakeman"
242
+ run "chmod +x script/brakeman"
243
+ end
244
+
245
+ def setup_simplecov
246
+ prepend_to_file "spec/spec_helper.rb" do
247
+ <<~SIMPLECOV
248
+ require "simplecov"
249
+
250
+ # Save to CircleCI's artifacts directory if we're on CircleCI
251
+ if ENV["CIRCLE_ARTIFACTS"]
252
+ dir = File.join(ENV["CIRCLE_ARTIFACTS"], "coverage")
253
+ SimpleCov.coverage_dir(dir)
254
+ end
255
+
256
+ SimpleCov.start "rails" if (ENV["CI"] || ENV["COVERAGE"])
257
+
258
+ SIMPLECOV
259
+ end
260
+ end
261
+
262
+ def setup_environments
263
+ setup_dotenv
264
+ setup_ci
265
+ setup_docker
266
+ end
267
+
268
+ def setup_dotenv
269
+ copy_file "templates/.env.development", ".env.development"
270
+ copy_file "templates/.env.test", ".env.test"
271
+ gsub_file ".env.development", "__application_name__", app_name
272
+ gsub_file ".env.test", "__application_name__", app_name
273
+ end
274
+
275
+ def setup_ci
276
+ copy_file "templates/.circleci/config.yml", ".circleci/config.yml"
277
+ gsub_file ".circleci/config.yml", "__ruby_version__", RUBY_VERSION
278
+ gsub_file ".circleci/config.yml", "__application_name__", app_name
279
+ end
280
+
281
+ def setup_docker
282
+ copy_file "templates/Dockerfile", "Dockerfile"
283
+ gsub_file "Dockerfile", "__ruby_version__", RUBY_VERSION
284
+
285
+ if react?
286
+ setup_docker_react
287
+ else
288
+ setup_docker_standard
289
+ end
290
+ end
291
+
292
+ def setup_docker_standard
293
+ copy_file "templates/.env.docker/.env.docker-standard", ".env.docker"
294
+ copy_file "templates/docker-compose.yml/docker-compose-standard.yml", "docker-compose.yml"
295
+ end
296
+
297
+ def setup_docker_react
298
+ copy_file "templates/Dockerfile-assets", "Dockerfile-assets"
299
+ gsub_file "Dockerfile-assets", "__ruby_version__", RUBY_VERSION
300
+ copy_file "templates/.env.docker/.env.docker-webpack", ".env.docker"
301
+ copy_file "templates/.env.docker-assets", ".env.docker-assets"
302
+ copy_file "templates/docker-compose.yml/docker-compose-webpack.yml", "docker-compose.yml"
303
+ end
304
+
305
+ def setup_readme
306
+ remove_file "README.md"
307
+ copy_file "templates/README.md", "README.md"
308
+ gsub_file "README.md", "__application_name__", app_name
309
+ end
310
+
311
+ def react?
312
+ options[:webpack] == "react"
313
+ end
314
+
315
+ def post_bundle
316
+ after_bundle do
317
+ setup_react if react?
318
+ remove_dir "test"
319
+ git :init
320
+
321
+ puts ""
322
+ ascii_art
323
+ post_install_instructions
324
+ end
325
+ end
326
+
327
+ def ascii_art
328
+ puts " _____ __ _ ____ ____ "
329
+ puts " / / \\ \\ | \\ | | / \\ | \\ "
330
+ puts "| | | | | \\ | | | /\\ | | |\\ \\ "
331
+ puts "| | - | \\ | | | | | | | | | | "
332
+ puts "| | | |\\ \\ | | | |__| | | |/ / "
333
+ puts "| | / -- | | \\ \\ | | | | | | | / "
334
+ puts "| | \\ \\ | | \\ \\ | | | | | | | |\\ \\ "
335
+ puts " \\ \\ | | | | \\ \\| | | | | | | | \\ \\ "
336
+ puts " \\ --/ / | | \\ | | | | | | | \\ \\ "
337
+ puts " -----/ |__| \\__| |_| |_| |_| \\_\\ "
338
+ end
339
+
340
+ def post_install_instructions
341
+ puts "\n\nNEXT STEPS"
342
+ puts "=========="
343
+ puts "* Install Google Chrome for acceptance tests"
344
+ puts "* Install ChromeDriver for default headless acceptance tests: brew install chromedriver"
345
+ puts "* Follow the post-install instructions to set up circle to allow gnarbot to comment on PRs."
346
+ puts " * https://github.com/TheGnarCo/gnarails#post-install"
347
+ end
348
+
349
+ def setup_react
350
+ install_js_deps
351
+ add_js_files
352
+ modify_js_files
353
+ modify_npm_scripts
354
+ end
355
+
356
+ def install_js_deps
357
+ puts "Installing Gnar react packages"
358
+ run "yarn add #{JS_DEPENDENCIES.join(' ')}"
359
+ run "yarn add --dev #{JS_DEV_DEPENDENCIES.join(' ')}"
360
+ end
361
+
362
+ def add_js_files
363
+ directory "templates/react/js", "app/javascript"
364
+ directory "templates/react/views", "app/views"
365
+ copy_file "templates/react/layout.html.erb", "app/views/layouts/application.html.erb", force: true
366
+ copy_file "templates/react/rails_routes.rb", "config/routes.rb", force: true
367
+ copy_file "templates/react/controllers/home_controller.rb", "app/controllers/home_controller.rb"
368
+ copy_file "templates/react/.babelrc", ".babelrc", force: true
369
+ copy_file "templates/react/.eslintrc.js", ".eslintrc.js", force: true
370
+ end
371
+
372
+ def modify_js_files
373
+ gsub_file "app/views/layouts/application.html.erb",
374
+ "placeholder_application_title",
375
+ app_name.tr("-", "_").titleize
376
+ gsub_file "app/javascript/app_constants/index.js",
377
+ " APP_NAME: 'CHANGE_ME',",
378
+ " APP_NAME: '#{app_name}',"
379
+ remove_file "app/javascript/packs/application.js"
380
+ end
381
+
382
+ def modify_npm_scripts
383
+ insert_into_file "package.json", before: " \"dependencies\": {\n" do
384
+ <<-NPM_SCRIPTS
385
+ "scripts": {
386
+ "start": "./bin/webpack-dev-server",
387
+ "mocha": "NODE_PATH=./app/javascript mocha --compilers js:babel-register --require babel-polyfill --require app/javascript/test/.setup.js --recursive './app/javascript/**/*.tests.js*'",
388
+ "lint": "eslint app/javascript",
389
+ "test": "npm run lint && npm run mocha"
390
+ },
391
+ NPM_SCRIPTS
392
+ end
393
+ end
394
+
395
+ create_gnarly_rails_app