hoboken 0.9.0 → 0.10.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (98) hide show
  1. checksums.yaml +4 -4
  2. data/.github/ISSUE_TEMPLATE/bug_report.md +33 -0
  3. data/.github/ISSUE_TEMPLATE/code_change.md +11 -0
  4. data/.github/PULL_REQUEST_TEMPLATE.md +25 -0
  5. data/.gitignore +3 -0
  6. data/.rubocop.yml +13 -5
  7. data/.tool-versions +1 -0
  8. data/CHANGELOG.md +131 -0
  9. data/CODE_OF_CONDUCT.md +8 -0
  10. data/CONTRIBUTING.md +16 -0
  11. data/README.md +10 -14
  12. data/Rakefile +7 -16
  13. data/hoboken.gemspec +18 -8
  14. data/lib/hoboken/add_ons/active_record.rb +142 -0
  15. data/lib/hoboken/add_ons/airbrake.rb +64 -0
  16. data/lib/hoboken/add_ons/heroku.rb +5 -1
  17. data/lib/hoboken/add_ons/internationalization.rb +2 -2
  18. data/lib/hoboken/add_ons/metrics.rb +3 -2
  19. data/lib/hoboken/add_ons/omniauth.rb +9 -8
  20. data/lib/hoboken/add_ons/rubocop.rb +10 -4
  21. data/lib/hoboken/add_ons/sequel.rb +55 -29
  22. data/lib/hoboken/add_ons/sidekiq.rb +137 -0
  23. data/lib/hoboken/add_ons/turnip.rb +109 -0
  24. data/lib/hoboken/add_ons/twbs.rb +5 -35
  25. data/lib/hoboken/add_ons/vcr.rb +54 -0
  26. data/lib/hoboken/generate.rb +18 -10
  27. data/lib/hoboken/templates/Gemfile.erb.tt +13 -3
  28. data/lib/hoboken/templates/README.md.tt +18 -6
  29. data/lib/hoboken/templates/Rakefile.tt +11 -0
  30. data/lib/hoboken/templates/active_record.rake +11 -0
  31. data/lib/hoboken/templates/airbrake.rb.tt +13 -0
  32. data/lib/hoboken/templates/classic.rb.tt +6 -20
  33. data/lib/hoboken/templates/classic_environment.rb.tt +51 -0
  34. data/lib/hoboken/templates/config.ru.tt +2 -4
  35. data/lib/hoboken/templates/console +19 -0
  36. data/lib/hoboken/templates/example_worker.rb.tt +14 -0
  37. data/lib/hoboken/templates/metrics.rake.tt +3 -1
  38. data/lib/hoboken/templates/modular.rb.tt +8 -25
  39. data/lib/hoboken/templates/modular_environment.rb.tt +62 -0
  40. data/lib/hoboken/templates/rspec.rake.tt +7 -3
  41. data/lib/hoboken/templates/rubocop.yml.tt +23 -3
  42. data/lib/hoboken/templates/seeds.rb +12 -0
  43. data/lib/hoboken/templates/server +15 -0
  44. data/lib/hoboken/templates/setup +28 -0
  45. data/lib/hoboken/templates/sidekiq.rb.tt +21 -0
  46. data/lib/hoboken/templates/spec/app_spec.rb.tt +0 -2
  47. data/lib/hoboken/templates/spec/example_worker_spec.rb.tt +16 -0
  48. data/lib/hoboken/templates/spec/rack_matchers.rb.tt +8 -6
  49. data/lib/hoboken/templates/spec/spec_helper.rb.tt +2 -6
  50. data/lib/hoboken/templates/spec/turnip_helper.rb.tt +10 -0
  51. data/lib/hoboken/templates/styles.css.tt +1 -1
  52. data/lib/hoboken/templates/support/rack_test_assertions.rb.tt +5 -3
  53. data/lib/hoboken/templates/test/test_helper.rb.tt +2 -5
  54. data/lib/hoboken/templates/test/unit/example_worker_test.rb.tt +20 -0
  55. data/lib/hoboken/templates/vcr_setup.rb.tt +15 -0
  56. data/lib/hoboken/templates/views/index.erb.tt +1 -1
  57. data/lib/hoboken/templates/views/layout.erb.tt +3 -3
  58. data/lib/hoboken/version.rb +1 -1
  59. data/lib/hoboken.rb +54 -10
  60. data/test/integration/active_record_test.rb +66 -0
  61. data/test/integration/airbrake_test.rb +31 -0
  62. data/test/integration/generate_classic_test.rb +75 -0
  63. data/test/integration/generate_modular_test.rb +83 -0
  64. data/test/integration/github_action_test.rb +13 -0
  65. data/test/integration/heroku_test.rb +14 -0
  66. data/test/integration/internationalization_test.rb +26 -0
  67. data/test/integration/metrics_test.rb +54 -0
  68. data/test/integration/omniauth_test.rb +143 -0
  69. data/test/integration/rubocop_test.rb +39 -0
  70. data/test/integration/sequel_test.rb +64 -0
  71. data/test/integration/sidekiq_test.rb +105 -0
  72. data/test/integration/travis_test.rb +13 -0
  73. data/test/integration/turnip_test.rb +51 -0
  74. data/test/integration/twitter_bootstrap_test.rb +39 -0
  75. data/test/integration/vcr_test.rb +54 -0
  76. data/test/test_helper.rb +21 -10
  77. data/www/Gemfile +4 -0
  78. data/www/README.md +2 -0
  79. data/www/config.rb +11 -0
  80. data/www/source/documentation.html.erb +274 -0
  81. data/www/source/images/hoboken-running.png +0 -0
  82. data/www/source/images/hoboken.png +0 -0
  83. data/www/source/images/sinatra.png +0 -0
  84. data/www/source/index.html.erb +44 -0
  85. data/www/source/javascripts/all.js +1 -0
  86. data/www/source/layouts/layout.erb +38 -0
  87. data/www/source/stylesheets/all.css.scss +116 -0
  88. data/www/source/stylesheets/normalize.css +375 -0
  89. metadata +230 -44
  90. data/lib/hoboken/add_ons/sprockets.rb +0 -99
  91. data/lib/hoboken/templates/console.sh +0 -5
  92. data/lib/hoboken/templates/server.sh +0 -12
  93. data/lib/hoboken/templates/setup.sh +0 -7
  94. data/lib/hoboken/templates/sprockets.rake +0 -39
  95. data/lib/hoboken/templates/sprockets_chain.rb +0 -30
  96. data/lib/hoboken/templates/sprockets_helper.rb +0 -17
  97. data/test/integration/add_on_test.rb +0 -505
  98. data/test/integration/generate_test.rb +0 -203
@@ -9,7 +9,7 @@ module Hoboken
9
9
  class Generate < Thor::Group
10
10
  include Thor::Actions
11
11
 
12
- NULL = RbConfig::CONFIG['host_os'] =~ /mingw|mswin/ ? 'NUL' : '/dev/null'
12
+ NULL = RbConfig::CONFIG['host_os'].match?(/mingw|mswin/) ? 'NUL' : '/dev/null'
13
13
 
14
14
  argument :name
15
15
 
@@ -64,7 +64,7 @@ module Hoboken
64
64
  empty_directory("#{snake_name}/bin")
65
65
  %w[console server setup].each do |f|
66
66
  target = "#{snake_name}/bin/#{f}"
67
- copy_file("templates/#{f}.sh", target)
67
+ copy_file("templates/#{f}", target)
68
68
  chmod(target, 0o755)
69
69
  end
70
70
  end
@@ -72,6 +72,7 @@ module Hoboken
72
72
  def config_folder
73
73
  empty_directory("#{snake_name}/config")
74
74
  apply_template('puma.rb.tt', 'config/puma.rb')
75
+ apply_template('classic_environment.rb.tt', 'config/environment.rb')
75
76
  end
76
77
 
77
78
  def view_folder
@@ -82,19 +83,20 @@ module Hoboken
82
83
  apply_template('views/index.erb.tt', 'views/index.erb')
83
84
  end
84
85
 
85
- def public_folder
86
- return if options[:tiny] || options[:api_only]
86
+ def asset_pipeline
87
+ return if options[:api_only]
87
88
 
88
89
  inside snake_name do
90
+ empty_directory('assets')
89
91
  empty_directory('public')
90
- %w[css img js].each { |f| empty_directory("public/#{f}") }
92
+ %w[stylesheets images javascripts].each { |f| empty_directory("assets/#{f}") }
91
93
  end
92
94
 
93
- apply_template('styles.css.tt', 'public/css/styles.css')
94
- create_file("#{snake_name}/public/js/app.js", '')
95
+ apply_template('styles.css.tt', 'assets/stylesheets/styles.scss')
96
+ create_file("#{snake_name}/assets/javascripts/app.js", '')
95
97
 
96
98
  %w[favicon hoboken sinatra].each do |f|
97
- copy_file("templates/#{f}.png", "#{snake_name}/public/img/#{f}.png")
99
+ copy_file("templates/#{f}.png", "#{snake_name}/assets/images/#{f}.png")
98
100
  end
99
101
  end
100
102
 
@@ -128,7 +130,7 @@ module Hoboken
128
130
  def env_file
129
131
  inside snake_name do
130
132
  create_file('.env') do
131
- "RACK_ENV=development\nPORT=9292"
133
+ "RACK_ENV=development\nPORT=9292\nSESSION_SECRET=secret"
132
134
  end
133
135
  end
134
136
  end
@@ -139,7 +141,9 @@ module Hoboken
139
141
 
140
142
  empty_directory("#{snake_name}/helpers")
141
143
  remove_file("#{snake_name}/app.rb")
144
+ remove_file("#{snake_name}/config/environment.rb")
142
145
  apply_template('modular.rb.tt', 'app.rb')
146
+ apply_template('modular_environment.rb.tt', 'config/environment.rb')
143
147
 
144
148
  files = [].tap do |f|
145
149
  f << 'config.ru'
@@ -178,7 +182,7 @@ module Hoboken
178
182
  end
179
183
  else
180
184
  say "\nYou asked that a Git repository be created for the " \
181
- 'project, but no Git executable could be found.'
185
+ 'project, but no Git executable could be found.'
182
186
  end
183
187
  end
184
188
 
@@ -220,6 +224,10 @@ module Hoboken
220
224
  def apply_template(src, dest)
221
225
  template("templates/#{src}", "#{snake_name}/#{dest}")
222
226
  end
227
+
228
+ def ruby_three_one_or_greater?
229
+ Gem::Version.new(RUBY_VERSION).release >= Gem::Version.new('3.1')
230
+ end
223
231
  end
224
232
  # rubocop:enable Metrics/ClassLength
225
233
  end
@@ -7,12 +7,25 @@ ruby '<%= options[:ruby_version] %>'
7
7
  gem 'erubi', '~> 1.10'
8
8
  <% end -%>
9
9
  gem 'puma', '~> 5.2'
10
+ <% unless options[:api_only] -%>
10
11
  gem 'rack_csrf', '~> 2.6'
12
+ <% end -%>
13
+ gem 'rake', '~> 12.3'
11
14
  gem 'sinatra', '~> 2.1'
15
+ <% unless options[:api_only] -%>
16
+ gem 'sinatra-asset-pipeline', '~> 2.2'
17
+ <% end -%>
12
18
  gem 'sinatra-contrib', '~> 2.1'
13
19
  <% unless options[:api_only] -%>
14
20
  gem 'sinatra-flash', '~> 0.3'
15
21
  <% end -%>
22
+ <% unless options[:api_only] -%>
23
+
24
+ group :assets do
25
+ gem 'sassc', '~> 2.4'
26
+ gem 'uglifier', '~> 4.2'
27
+ end
28
+ <% end -%>
16
29
 
17
30
  group :development do
18
31
  gem 'better_errors', '~> 2.9'
@@ -20,9 +33,6 @@ group :development do
20
33
  gem 'dotenv', '~> 2.7'
21
34
  gem 'pry-byebug', '~> 3.9'
22
35
  gem 'racksh', '~> 1.0'
23
- gem 'rake', '~> 13.0'
24
- gem 'rerun', '~> 0.13'
25
- gem 'rb-fsevent', '~> 0.10'
26
36
  end
27
37
 
28
38
  group :test do
@@ -4,9 +4,12 @@
4
4
 
5
5
  TODO: Project description.
6
6
 
7
- * TODO: a list of
8
- * high level features
9
- * ...
7
+ ### Features
8
+ #### Feature A
9
+ TODO: Describe feature.
10
+
11
+ #### Feature B
12
+ TODO: Describe feature.
10
13
 
11
14
  ### Links
12
15
  * [Production](TODO)
@@ -33,17 +36,18 @@ TODO: Project description.
33
36
 
34
37
  The following pre-requisites are needed to build this project:
35
38
  * Ruby <%= RUBY_VERSION %>
36
- * [Bundler](https://bundler.io/)
37
39
 
38
40
  After cloning this repository, the project can be setup by running the `./bin/setup` script. This script will install dependencies and perform any other required setup tasks.
39
41
 
40
42
  Once setup is complete, you can start a local development server by running the `./bin/server` script. Additionally, you can start a development console using the `./bin/console` script. The console uses the [racksh](https://github.com/sickill/racksh) gem which exposes a `$rack` variable that can be used to make simulated HTTP requests.
41
43
 
42
44
  ## Configuration
43
- Environment variables are used for project configuration. For local development, the `.env` file is used. Below is a sample `.env` file that contains the minimum required configuration.
45
+ Environment variables are used for project configuration. For local development, the `.env` file is used. A sample file is shown below.
44
46
 
45
47
  ```
48
+ PORT=9292
46
49
  RACK_ENV=development
50
+ SESSION_SECRET=secret
47
51
  ```
48
52
 
49
53
  Here is a table containing all available environment variable configuration options and their descriptions.
@@ -76,6 +80,12 @@ Here is a table containing all available environment variable configuration opti
76
80
  <td>production</td>
77
81
  <td>Web server environment (i.e. development, test, production, etc.)</td>
78
82
  </tr>
83
+ <tr>
84
+ <td>SESSION_SECRET</td>
85
+ <td>Yes</td>
86
+ <td>None</td>
87
+ <td>Key used for signing and/or encrypting cookies set by the application to maintain session state</td>
88
+ </tr>
79
89
  <tr>
80
90
  <td>WEB_CONCURRENCY</td>
81
91
  <td>No</td>
@@ -90,10 +100,12 @@ This project has the following default behavior:
90
100
 
91
101
  * helpers scripts for common project actions; refer to the `bin` folder
92
102
  * uses [Puma](https://github.com/puma/puma) as the default web server
103
+ <% unless options[:api_only] -%>
93
104
  * [erubi](https://github.com/jeremyevans/erubi) for templating; escaping is done by default
94
105
  * [Rack::Csrf](http://rubygems.org/gems/rack_csrf") is turned on by default
106
+ <% end -%>
95
107
  * environment variable support via the [dotenv](http://rubygems.org/gems/dotenv) gem
96
- * Procfile for [foreman](https://github.com/ddollar/foreman) support; if foreman is not installed uses rackup instead
108
+ * Procfile for [foreman](https://github.com/ddollar/foreman) support
97
109
  * code reloading via the [rerun](https://github.com/alexch/rerun) gem is enabled for the development environment
98
110
  * [pry-byebug](https://github.com/deivid-rodriguez/pry-byebug") is installed for debugging
99
111
 
@@ -1,4 +1,15 @@
1
1
  # frozen_string_literal: true
2
+ <% unless options[:api_only] -%>
3
+
4
+ require 'sinatra/asset_pipeline/task'
5
+ require_relative 'config/environment'
6
+
7
+ <% if 'modular' == options[:type] -%>
8
+ Sinatra::AssetPipeline::Task.define! <%= camel_name %>::App
9
+ <% else -%>
10
+ Sinatra::AssetPipeline::Task.define! Sinatra::Application
11
+ <% end -%>
12
+ <% end -%>
2
13
 
3
14
  # Import any external rake tasks
4
15
  Dir.glob('tasks/*.rake').each { |r| import r }
@@ -0,0 +1,11 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'sinatra/activerecord/rake'
4
+
5
+ namespace :db do
6
+ # rubocop:disable Rake/Desc
7
+ task :load_config do
8
+ require_relative '../config/environment'
9
+ end
10
+ # rubocop:enable Rake/Desc
11
+ end
@@ -0,0 +1,13 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'airbrake'
4
+
5
+ Airbrake.configure do |c|
6
+ c.environment = ENV['RACK_ENV']
7
+ c.ignore_environments = %w[development test]
8
+ c.project_id = ENV['AIRBRAKE_PROJECT_ID']
9
+ c.project_key = ENV['AIRBRAKE_PROJECT_KEY']
10
+
11
+ # Set your application's version, or use a Git SHA
12
+ # c.app_version = '1.0.0' or `git rev-parse --short HEAD`
13
+ end
@@ -1,36 +1,22 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require 'bundler/setup'
4
-
5
3
  <% unless options[:api_only] -%>
6
4
  require 'erubi'
7
- <% end -%>
8
5
  require 'rack/csrf'
6
+ <% end -%>
9
7
  require 'sinatra'
8
+ <% unless options[:api_only] -%>
9
+ require 'sinatra/asset_pipeline'
10
+ <% end -%>
10
11
  <% if options[:api_only] -%>
11
12
  require 'sinatra/json'
12
13
  <% else -%>
13
14
  require 'sinatra/flash'
14
15
  <% end -%>
15
-
16
- Dir.glob(File.join('helpers', '**', '*.rb')).each do |helper|
17
- require_relative helper
18
- end
19
-
20
- configure do
21
- use Rack::Session::Cookie, secret: 'TODO: CHANGE ME'
22
- use Rack::Csrf, raise: true
23
16
  <% unless options[:api_only] -%>
24
-
25
- set :erb, { escape_html: true }
17
+ require 'sinatra/sprockets-helpers'
18
+ require 'uglifier'
26
19
  <% end -%>
27
- end
28
-
29
- configure :development do
30
- require 'better_errors'
31
- use BetterErrors::Middleware
32
- BetterErrors.application_root = __dir__
33
- end
34
20
 
35
21
  <% if options[:api_only] -%>
36
22
  get '/' do
@@ -0,0 +1,51 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'bundler/setup'
4
+
5
+ unless 'production' == ENV['RACK_ENV']
6
+ require 'dotenv'
7
+ Dotenv.load
8
+ end
9
+
10
+ require_relative '../app'
11
+
12
+ configure do
13
+ <% if options[:api_only] -%>
14
+ # Configuration common to all environments goes here...
15
+ <% else -%>
16
+ use Rack::Session::Cookie, secret: ENV['SESSION_SECRET']
17
+ use Rack::Csrf, raise: true, skip_if: proc {
18
+ 'test' == ENV.fetch('RACK_ENV', 'production')
19
+ }
20
+
21
+ set :erb, { escape_html: true }
22
+
23
+ set :assets_precompile, %w[
24
+ javascripts/app.js
25
+ stylesheets/styles.scss
26
+ *.png *.jpg *.svg *.eot *.ttf *.woff *.woff2
27
+ ]
28
+ set :assets_paths, %w[assets vendor] + Sprockets.paths
29
+ set :assets_css_compressor, :scss
30
+ set :assets_js_compressor, Uglifier.new(harmony: true)
31
+ register Sinatra::AssetPipeline
32
+ <% end -%>
33
+ end
34
+
35
+ configure :development do
36
+ require 'better_errors'
37
+ use BetterErrors::Middleware
38
+ BetterErrors.application_root = File.expand_path('..', __dir__)
39
+ end
40
+
41
+ configure :test do
42
+ set :raise_errors, true
43
+ set :dump_errors, false
44
+ set :show_exceptions, false
45
+ end
46
+
47
+ configure :production do
48
+ before do
49
+ redirect request.url.sub('http', 'https') unless request.secure?
50
+ end
51
+ end
@@ -1,7 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require 'bundler/setup'
4
- require 'dotenv'
5
- Dotenv.load
6
- require File.expand_path('app', __dir__)
3
+ require_relative 'config/environment'
4
+
7
5
  run Sinatra::Application
@@ -0,0 +1,19 @@
1
+ #!/usr/bin/env ruby
2
+ # frozen_string_literal: true
3
+
4
+ require 'fileutils'
5
+
6
+ APP_ROOT = File.expand_path('..', __dir__)
7
+
8
+ def system!(*args)
9
+ system(*args) || abort("\n== Command #{args} failed ==")
10
+ end
11
+
12
+ FileUtils.chdir APP_ROOT do
13
+ puts '== Starting application console =='
14
+ puts 'Console supports racksh. A `$rack` global variable is provided for'
15
+ puts "making simulated requests (i.e. `$rack.get '/'`)."
16
+ puts "\nSee the racksh gem for more details."
17
+ puts "https://github.com/sickill/racksh\n\n"
18
+ system! 'bundle exec racksh'
19
+ end
@@ -0,0 +1,14 @@
1
+ # frozen_string_literal: true
2
+
3
+ # Example Sidekiq worker. Refer to Sidekiq's documentation[1] for
4
+ # more information.
5
+ #
6
+ # [1]: https://github.com/mperham/sidekiq/wiki/Best-Practices
7
+ #
8
+ class ExampleWorker
9
+ include Sidekiq::Worker
10
+
11
+ def perform
12
+ logger.info 'Doing some work!'
13
+ end
14
+ end
@@ -1,7 +1,9 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  unless 'production' == ENV['RACK_ENV']
4
+ require 'bundler/setup'
4
5
  require 'flay'
6
+
5
7
  desc 'Analyze code for structural similarities'
6
8
  task :flay do
7
9
  flay = Flay.new
@@ -27,7 +29,7 @@ unless 'production' == ENV['RACK_ENV']
27
29
  score > threshold
28
30
  end
29
31
 
30
- bad_methods.sort { |a, b| a[1] <=> b[1] }.each do |name, score|
32
+ bad_methods.sort_by { |a| a[1] }.each do |name, score|
31
33
  puts format('%<score>8.1f: %<name>s', score: score, name: name)
32
34
  end
33
35
 
@@ -1,17 +1,22 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require 'bundler/setup'
4
-
5
3
  <% unless options[:api_only] -%>
6
4
  require 'erubi'
7
- <% end -%>
8
5
  require 'rack/csrf'
6
+ <% end -%>
9
7
  require 'sinatra/base'
8
+ <% unless options[:api_only] -%>
9
+ require 'sinatra/asset_pipeline'
10
+ <% end -%>
10
11
  <% if options[:api_only] -%>
11
12
  require 'sinatra/json'
12
13
  <% else -%>
13
14
  require 'sinatra/flash'
14
15
  <% end -%>
16
+ <% unless options[:api_only] -%>
17
+ require 'sinatra/sprockets-helpers'
18
+ require 'uglifier'
19
+ <% end -%>
15
20
 
16
21
  Dir.glob(File.join('helpers', '**', '*.rb')).each do |helper|
17
22
  require_relative helper
@@ -21,28 +26,6 @@ module <%= camel_name %>
21
26
  # Sinatra web application
22
27
  #
23
28
  class App < Sinatra::Base
24
- configure do
25
- set :root, File.dirname(__FILE__)
26
- <% unless options[:api_only] -%>
27
- set :erb, { escape_html: true }
28
- <% end -%>
29
-
30
- enable :logging
31
-
32
- use Rack::Session::Cookie, secret: 'TODO: CHANGE ME'
33
- use Rack::Csrf, raise: true
34
- <% unless options[:api_only] -%>
35
-
36
- register Sinatra::Flash
37
- <% end -%>
38
- end
39
-
40
- configure :development do
41
- require 'better_errors'
42
- use BetterErrors::Middleware
43
- BetterErrors.application_root = __dir__
44
- end
45
-
46
29
  <% if options[:api_only] -%>
47
30
  get '/' do
48
31
  json message: 'Smoke test successful!'
@@ -0,0 +1,62 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'bundler/setup'
4
+
5
+ unless 'production' == ENV['RACK_ENV']
6
+ require 'dotenv'
7
+ Dotenv.load
8
+ end
9
+
10
+ require_relative '../app'
11
+
12
+ module <%= camel_name %>
13
+ # Re-opening application to apply configuration.
14
+ #
15
+ class App < Sinatra::Base
16
+ configure do
17
+ set :root, File.expand_path('..', __dir__)
18
+ <% unless options[:api_only] -%>
19
+ set :erb, { escape_html: true }
20
+ <% end -%>
21
+
22
+ enable :logging
23
+ <% unless options[:api_only] -%>
24
+
25
+ use Rack::Session::Cookie, secret: ENV['SESSION_SECRET']
26
+ use Rack::Csrf, raise: true, skip_if: proc {
27
+ 'test' == ENV.fetch('RACK_ENV', 'production')
28
+ }
29
+
30
+ register Sinatra::Flash
31
+
32
+ set :assets_precompile, %w[
33
+ javascripts/app.js
34
+ stylesheets/styles.scss
35
+ *.png *.jpg *.svg *.eot *.ttf *.woff *.woff2
36
+ ]
37
+ set :assets_paths, %w[assets vendor] + Sprockets.paths
38
+ set :assets_css_compressor, :scss
39
+ set :assets_js_compressor, Uglifier.new(harmony: true)
40
+ register Sinatra::AssetPipeline
41
+ <% end -%>
42
+ end
43
+
44
+ configure :development do
45
+ require 'better_errors'
46
+ use BetterErrors::Middleware
47
+ BetterErrors.application_root = File.expand_path('..', __dir__)
48
+ end
49
+
50
+ configure :test do
51
+ set :raise_errors, true
52
+ set :dump_errors, false
53
+ set :show_exceptions, false
54
+ end
55
+
56
+ configure :production do
57
+ before do
58
+ redirect request.url.sub('http', 'https') unless request.secure?
59
+ end
60
+ end
61
+ end
62
+ end
@@ -1,5 +1,9 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require 'rspec/core/rake_task'
4
-
5
- RSpec::Core::RakeTask.new(:spec)
3
+ begin
4
+ require 'rspec/core/rake_task'
5
+ RSpec::Core::RakeTask.new(:spec)
6
+ # rubocop:disable Lint/SuppressedException
7
+ rescue LoadError
8
+ end
9
+ # rubocop:enable Lint/SuppressedException
@@ -1,28 +1,48 @@
1
1
  require:
2
+ - rubocop-performance
2
3
  - rubocop-rake
3
4
  <% if rspec? -%>
4
5
  - rubocop-rspec
5
6
  <% end -%>
7
+ <% if sequel? -%>
8
+ - rubocop-sequel
9
+ <% end -%>
6
10
 
7
11
  AllCops:
8
12
  Exclude:
9
- - 'bin/*'
10
13
  - 'tmp/*'
11
14
  - 'vendor/bundle/**/*'
12
15
  NewCops: enable
13
16
  TargetRubyVersion: <%= RUBY_VERSION %>
14
17
 
18
+ Layout/LineLength:
19
+ Max: 90
20
+
15
21
  Layout/SpaceAroundEqualsInParameterDefault:
16
22
  EnforcedStyle: no_space
23
+ <% if rspec? -%>
24
+
25
+ Metrics/BlockLength:
26
+ IgnoredMethods:
27
+ - describe
28
+ - context
29
+ - it
30
+ - RSpec.configure
31
+ <% end -%>
17
32
 
18
33
  Metrics/ClassLength:
19
34
  Max: 150
20
35
 
21
36
  Metrics/MethodLength:
22
37
  Max: 15
38
+ <% if rspec? -%>
23
39
 
24
- Layout/LineLength:
25
- Max: 90
40
+ RSpec/DescribeClass:
41
+ Enabled: false
42
+
43
+ RSpec/MultipleDescribes:
44
+ Enabled: false
45
+ <% end -%>
26
46
 
27
47
  Style/BlockDelimiters:
28
48
  EnforcedStyle: braces_for_chaining
@@ -0,0 +1,12 @@
1
+ # frozen_string_literal: true
2
+
3
+ # This file should contain all the record creation needed to seed the database
4
+ # with its default values.
5
+ #
6
+ # The data can then be loaded with the bin/rails db:seed command (or created
7
+ # alongside the database with db:setup).
8
+ #
9
+ # Examples:
10
+ #
11
+ # movies = Movie.create([{ name: 'Star Wars' }, { name: 'Lord of the Rings' }])
12
+ # Character.create(name: 'Luke', movie: movies.first)
@@ -0,0 +1,15 @@
1
+ #!/usr/bin/env ruby
2
+ # frozen_string_literal: true
3
+
4
+ require 'fileutils'
5
+
6
+ APP_ROOT = File.expand_path('..', __dir__)
7
+
8
+ def system!(*args)
9
+ system(*args) || abort("\n== Command #{args} failed ==")
10
+ end
11
+
12
+ FileUtils.chdir APP_ROOT do
13
+ puts '== Starting development server =='
14
+ system! 'rerun --background foreman start'
15
+ end
@@ -0,0 +1,28 @@
1
+ #!/usr/bin/env ruby
2
+ # frozen_string_literal: true
3
+
4
+ require 'fileutils'
5
+
6
+ APP_ROOT = File.expand_path('..', __dir__)
7
+
8
+ def system!(*args)
9
+ system(*args) || abort("\n== Command #{args} failed ==")
10
+ end
11
+
12
+ FileUtils.chdir APP_ROOT do
13
+ # This script is a way to set up or update your development environment
14
+ # automatically. This script is idempotent, so that you can run it at
15
+ # anytime and get an expectable outcome. Add necessary setup steps to
16
+ # this file.
17
+
18
+ puts '== Installing dependencies =='
19
+ system! 'gem install bundler --conservative'
20
+ system! 'bundle config --local cache_all true'
21
+ system! 'bundle config --local cache_all_platforms true'
22
+ system! 'bundle config --local ignore_messages.rpush true'
23
+ system('bundle check') || system!('bundle install')
24
+
25
+ system! 'gem list "^foreman$" -v 0.87.2 -i --silent || gem install foreman'
26
+ system! 'gem list "^rerun$" -v 0.13.1 -i --silent || gem install rerun'
27
+ system! 'gem list "^rb-fsevent$" -v 0.11.0 -i --silent || gem install rb-fsevent'
28
+ end
@@ -0,0 +1,21 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'sidekiq'
4
+
5
+ Sidekiq.configure_client do |config|
6
+ config.redis = { size: 1 }
7
+ end
8
+
9
+ Sidekiq.configure_server do |config|
10
+ # TODO: Setup an error handling service (i.e. Airbrake, Sentry, etc.)
11
+ # https://github.com/mperham/sidekiq/wiki/Error-Handling#best-practices
12
+ # config.error_handlers << ->(ex, ctx_hash) { MyErrorService.notify(ex, ctx_hash) }
13
+
14
+ config.death_handlers << lambda do |job, ex|
15
+ puts "#{job['class']} job #{job['jid']} just died (#{ex.message})"
16
+ end
17
+ end
18
+
19
+ Dir.glob(File.join('workers', '**', '*.rb')).each do |worker|
20
+ require_relative "../#{worker}"
21
+ end
@@ -1,6 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- # rubocop:disable RSpec/DescribeClass
4
3
  RSpec.describe 'GET /', rack: true do
5
4
  before { get '/' }
6
5
 
@@ -12,4 +11,3 @@ RSpec.describe 'GET /', rack: true do
12
11
  <% end -%>
13
12
  it { expect(last_response.body).to include('Smoke test successful!') }
14
13
  end
15
- # rubocop:enable RSpec/DescribeClass