hoboken 0.0.1.beta2 → 0.10.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (115) hide show
  1. checksums.yaml +5 -5
  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/.github/dependabot.yml +7 -0
  6. data/.github/workflows/ruby.yml +28 -0
  7. data/.gitignore +3 -0
  8. data/.rubocop.yml +41 -0
  9. data/.ruby-version +1 -0
  10. data/.tool-versions +1 -0
  11. data/CHANGELOG.md +131 -0
  12. data/CODE_OF_CONDUCT.md +8 -0
  13. data/CONTRIBUTING.md +16 -0
  14. data/Gemfile +2 -0
  15. data/IDEAS.md +57 -0
  16. data/LICENSE.txt +1 -1
  17. data/README.md +28 -17
  18. data/Rakefile +14 -8
  19. data/bin/hoboken +2 -1
  20. data/hoboken.gemspec +63 -16
  21. data/lib/hoboken/actions.rb +11 -6
  22. data/lib/hoboken/add_ons/active_record.rb +142 -0
  23. data/lib/hoboken/add_ons/airbrake.rb +64 -0
  24. data/lib/hoboken/add_ons/github_action.rb +14 -0
  25. data/lib/hoboken/add_ons/heroku.rb +29 -0
  26. data/lib/hoboken/add_ons/internationalization.rb +28 -0
  27. data/lib/hoboken/add_ons/metrics.rb +60 -0
  28. data/lib/hoboken/add_ons/omniauth.rb +174 -0
  29. data/lib/hoboken/add_ons/rubocop.rb +46 -0
  30. data/lib/hoboken/add_ons/sequel.rb +135 -0
  31. data/lib/hoboken/add_ons/sidekiq.rb +137 -0
  32. data/lib/hoboken/add_ons/travis.rb +15 -0
  33. data/lib/hoboken/add_ons/turnip.rb +109 -0
  34. data/lib/hoboken/add_ons/twbs.rb +50 -0
  35. data/lib/hoboken/add_ons/vcr.rb +54 -0
  36. data/lib/hoboken/generate.rb +146 -46
  37. data/lib/hoboken/templates/Gemfile.erb.tt +43 -8
  38. data/lib/hoboken/templates/README.md.tt +117 -35
  39. data/lib/hoboken/templates/Rakefile.tt +20 -16
  40. data/lib/hoboken/templates/active_record.rake +11 -0
  41. data/lib/hoboken/templates/airbrake.rb.tt +13 -0
  42. data/lib/hoboken/templates/classic.rb.tt +25 -11
  43. data/lib/hoboken/templates/classic_environment.rb.tt +51 -0
  44. data/lib/hoboken/templates/config.ru.tt +4 -2
  45. data/lib/hoboken/templates/console +19 -0
  46. data/lib/hoboken/templates/db.rb.tt +24 -0
  47. data/lib/hoboken/templates/example_worker.rb.tt +14 -0
  48. data/lib/hoboken/templates/github_action.tt +28 -0
  49. data/lib/hoboken/templates/gitignore +8 -0
  50. data/lib/hoboken/templates/metrics.rake.tt +12 -9
  51. data/lib/hoboken/templates/modular.rb.tt +28 -15
  52. data/lib/hoboken/templates/modular_environment.rb.tt +62 -0
  53. data/lib/hoboken/templates/puma.rb.tt +21 -0
  54. data/lib/hoboken/templates/rspec.rake.tt +9 -0
  55. data/lib/hoboken/templates/rubocop.yml.tt +51 -0
  56. data/lib/hoboken/templates/seeds.rb +12 -0
  57. data/lib/hoboken/templates/sequel.rake +21 -0
  58. data/lib/hoboken/templates/server +15 -0
  59. data/lib/hoboken/templates/setup +28 -0
  60. data/lib/hoboken/templates/sidekiq.rb.tt +21 -0
  61. data/lib/hoboken/templates/spec/app_spec.rb.tt +13 -0
  62. data/lib/hoboken/templates/spec/example_worker_spec.rb.tt +16 -0
  63. data/lib/hoboken/templates/spec/rack_matchers.rb.tt +58 -0
  64. data/lib/hoboken/templates/spec/spec_helper.rb.tt +37 -0
  65. data/lib/hoboken/templates/spec/turnip_helper.rb.tt +10 -0
  66. data/lib/hoboken/templates/styles.css.tt +1 -1
  67. data/lib/hoboken/templates/support/rack_helpers.rb.tt +55 -0
  68. data/lib/hoboken/templates/support/rack_test_assertions.rb.tt +113 -0
  69. data/lib/hoboken/templates/test/test_helper.rb.tt +47 -0
  70. data/lib/hoboken/templates/test/unit/app_test.rb.tt +11 -3
  71. data/lib/hoboken/templates/test/unit/example_worker_test.rb.tt +20 -0
  72. data/lib/hoboken/templates/test_unit.rake.tt +18 -0
  73. data/lib/hoboken/templates/vcr_setup.rb.tt +15 -0
  74. data/lib/hoboken/templates/views/index.erb.tt +11 -4
  75. data/lib/hoboken/templates/views/layout.erb.tt +7 -4
  76. data/lib/hoboken/version.rb +3 -1
  77. data/lib/hoboken.rb +147 -325
  78. data/test/fixtures/Gemfile +3 -3
  79. data/test/fixtures/Gemfile.pristine +3 -2
  80. data/test/integration/active_record_test.rb +66 -0
  81. data/test/integration/airbrake_test.rb +31 -0
  82. data/test/integration/generate_classic_test.rb +75 -0
  83. data/test/integration/generate_modular_test.rb +83 -0
  84. data/test/integration/github_action_test.rb +13 -0
  85. data/test/integration/heroku_test.rb +14 -0
  86. data/test/integration/internationalization_test.rb +26 -0
  87. data/test/integration/metrics_test.rb +54 -0
  88. data/test/integration/omniauth_test.rb +143 -0
  89. data/test/integration/rubocop_test.rb +39 -0
  90. data/test/integration/sequel_test.rb +64 -0
  91. data/test/integration/sidekiq_test.rb +105 -0
  92. data/test/integration/travis_test.rb +13 -0
  93. data/test/integration/turnip_test.rb +51 -0
  94. data/test/integration/twitter_bootstrap_test.rb +39 -0
  95. data/test/integration/vcr_test.rb +54 -0
  96. data/test/test_helper.rb +109 -0
  97. data/test/unit/hoboken_actions_test.rb +82 -53
  98. data/www/Gemfile +4 -0
  99. data/www/README.md +2 -0
  100. data/www/config.rb +11 -0
  101. data/www/source/documentation.html.erb +274 -0
  102. data/www/source/images/hoboken-running.png +0 -0
  103. data/www/source/images/hoboken.png +0 -0
  104. data/www/source/images/sinatra.png +0 -0
  105. data/www/source/index.html.erb +44 -0
  106. data/www/source/javascripts/all.js +1 -0
  107. data/www/source/layouts/layout.erb +38 -0
  108. data/www/source/stylesheets/all.css.scss +116 -0
  109. data/www/source/stylesheets/normalize.css +375 -0
  110. metadata +655 -29
  111. data/lib/hoboken/templates/sprockets.rake +0 -33
  112. data/lib/hoboken/templates/sprockets_chain.rb +0 -26
  113. data/lib/hoboken/templates/sprockets_helper.rb +0 -13
  114. data/lib/hoboken/templates/test/support/rack_test_assertions.rb.tt +0 -79
  115. data/lib/hoboken/templates/test/unit/test_helper.rb.tt +0 -36
@@ -0,0 +1,142 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Hoboken
4
+ module AddOns
5
+ # ActiveRecord database access via sinatra-activerecord gem.
6
+ #
7
+ class ActiveRecord < Hoboken::Group
8
+ def add_gems
9
+ gem 'sinatra-activerecord', version: '2.0'
10
+ gem 'sqlite3', version: '1.4', group: %i[development test]
11
+ end
12
+
13
+ def setup_directories
14
+ empty_directory('db/migrate')
15
+ empty_directory('tasks')
16
+ end
17
+
18
+ def copy_example_seeds_file
19
+ copy_file('hoboken/templates/seeds.rb', 'db/seeds.rb')
20
+ end
21
+
22
+ def copy_rake_task
23
+ copy_file('hoboken/templates/active_record.rake', 'tasks/active_record.rake')
24
+ end
25
+
26
+ def require_sinatra_activerecord
27
+ location = %r{require_relative '\.\./app'}
28
+ insert_into_file('config/environment.rb', before: location) do
29
+ "require 'sinatra/activerecord'\n\n"
30
+ end
31
+ end
32
+
33
+ def set_database_variable
34
+ snippet = "set :database, ENV['DATABASE_URL']"
35
+ snippet = "register Sinatra::ActiveRecordExtension\n#{snippet}" if modular?
36
+ indentation = classic? ? 2 : 6
37
+ location = /set :erb.+\n/
38
+ insert_into_file('config/environment.rb', after: location) do
39
+ "\n#{indent(snippet, indentation)}\n"
40
+ end
41
+ end
42
+
43
+ def setup_puma_config
44
+ insert_into_file('config/puma.rb', after: 'on_worker_boot do') do
45
+ "\n ActiveRecord::Base.establish_connection"
46
+ end
47
+ end
48
+
49
+ # rubocop:disable Metrics/MethodLength
50
+ def add_database_test_helper_class
51
+ return if rspec?
52
+
53
+ insert_into_file('test/test_helper.rb', before: /ENV\['RACK_ENV'\] = 'test'/) do
54
+ "ENV['DATABASE_URL'] = 'sqlite3:db/test.db'\n"
55
+ end
56
+
57
+ snippet = <<~CODE
58
+ def run(*args, &block)
59
+ result = nil
60
+ ActiveRecord::Base.connection.transaction do
61
+ result = super
62
+ raise ActiveRecord::Rollback
63
+ end
64
+ result
65
+ end
66
+ CODE
67
+
68
+ insert_into_file('test/test_helper.rb', after: /include RackHelpers\n/) do
69
+ "\n#{indent(snippet, 6)}"
70
+ end
71
+ end
72
+ # rubocop:enable Metrics/MethodLength
73
+
74
+ # rubocop:disable Metrics/MethodLength
75
+ def add_database_spec_helper
76
+ return unless rspec?
77
+
78
+ insert_into_file('spec/spec_helper.rb', before: /ENV\['RACK_ENV'\] = 'test'/) do
79
+ "ENV['DATABASE_URL'] = 'sqlite3:db/test.db'\n"
80
+ end
81
+
82
+ snippet = <<~CODE
83
+ config.around do |example|
84
+ ActiveRecord::Base.transaction do
85
+ example.run
86
+ ActiveRecord::Rollback
87
+ end
88
+ end
89
+ CODE
90
+
91
+ location = /RSpec\.configure do \|config\|\n/
92
+ insert_into_file('spec/spec_helper.rb', after: location) do
93
+ "#{indent(snippet, 2)}\n"
94
+ end
95
+ end
96
+ # rubocop:enable Metrics/MethodLength
97
+
98
+ # rubocop:disable Metrics/MethodLength
99
+ def update_readme
100
+ snippet = <<~CODE
101
+ <tr>
102
+ <td>DATABASE_URL</td>
103
+ <td>Yes</td>
104
+ <td>
105
+ `sqlite3:db/test.db` (for the test environment <em>only</em>)
106
+ </td>
107
+ <td>
108
+ Connection URL to the database. The format varies according
109
+ database adapter. Refer to the documentation for the adapter
110
+ you're using for more information. Some examples:
111
+ <dl>
112
+ <dt>Sqlite3</dt>
113
+ <dd>`sqlite3:db/development.db`</dd>
114
+ <dt>PostgreSQL</dt>
115
+ <dd>`postgresql://localhost/myapp_development?pool=5`</dd>
116
+ </dl>
117
+ </td>
118
+ </tr>
119
+ CODE
120
+
121
+ insert_into_file('README.md', after: /<tbody>\n/) do
122
+ indent(snippet, 8)
123
+ end
124
+ end
125
+ # rubocop:enable Metrics/MethodLength
126
+
127
+ def reminders
128
+ say "\nGemfile updated... don't forget to 'bundle install'"
129
+ say <<~TEXT
130
+
131
+ Notes:
132
+ * The sqlite3 gem has been installed for dev and test environments
133
+ only. You will need to specify a gem to use for production.
134
+
135
+ * You will need to specify an environment variable 'DATABASE_URL'
136
+ (either add it to .env or export it). For example, in your .env
137
+ file add: `DATABASE_URL=sqlite3:db/development.db`.
138
+ TEXT
139
+ end
140
+ end
141
+ end
142
+ end
@@ -0,0 +1,64 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Hoboken
4
+ module AddOns
5
+ # Support for official Airbrake library for Ruby applications.
6
+ #
7
+ class Airbrake < ::Hoboken::Group
8
+ def add_gem
9
+ gem 'airbrake', version: '11.0'
10
+ end
11
+
12
+ def setup_config
13
+ template('hoboken/templates/airbrake.rb.tt', 'config/airbrake.rb')
14
+ end
15
+
16
+ def add_middleware
17
+ indentation = classic? ? 2 : 6
18
+ require_snippet = indent("require_relative 'airbrake'\n", indentation)
19
+ middleware_snippet = indent("use Airbrake::Rack::Middleware\n", indentation)
20
+ location = /configure :production do\n/
21
+
22
+ insert_into_file('config/environment.rb', after: location) do
23
+ "#{require_snippet}#{middleware_snippet}\n"
24
+ end
25
+ end
26
+
27
+ # rubocop:disable Metrics/MethodLength
28
+ def update_readme
29
+ snippet = <<~CODE
30
+ <tr>
31
+ <td>AIRBRAKE_PROJECT_ID</td>
32
+ <td>Production Only</td>
33
+ <td>None</td>
34
+ <td>Airbrake project ID. Refer to the project's settings page in Airbrake</td>
35
+ </tr>
36
+ <tr>
37
+ <td>AIRBRAKE_PROJECT_KEY</td>
38
+ <td>Production Only</td>
39
+ <td>None</td>
40
+ <td>Airbrake project key. Refer to the project's settings page in Airbrake</td>
41
+ </tr>
42
+ CODE
43
+
44
+ insert_into_file('README.md', after: /<tbody>\n/) do
45
+ indent(snippet, 8)
46
+ end
47
+ end
48
+ # rubocop:enable Metrics/MethodLength
49
+
50
+ def reminders
51
+ text = <<~TEXT
52
+
53
+ Gemfile updated... don't forget to 'bundle install'
54
+
55
+ You can configure a Airbrake settings in `config/airbrake.rb`. By
56
+ default Airbrake is set to only be used in production environments.
57
+ Don't forget to set your `AIRBRAKE_PROJECT_ID` and `AIRBRAKE_PROJECT_KEY`.
58
+ TEXT
59
+
60
+ say text, :green
61
+ end
62
+ end
63
+ end
64
+ end
@@ -0,0 +1,14 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Hoboken
4
+ module AddOns
5
+ # Github action that runs CI task.
6
+ #
7
+ class GithubAction < ::Hoboken::Group
8
+ def add_action_yml_file
9
+ empty_directory('.github/workflows')
10
+ template('hoboken/templates/github_action.tt', '.github/workflows/ruby.yml')
11
+ end
12
+ end
13
+ end
14
+ end
@@ -0,0 +1,29 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Hoboken
4
+ module AddOns
5
+ # Heroku deployment support.
6
+ #
7
+ class Heroku < ::Hoboken::Group
8
+ def slugignore
9
+ create_file('.slugignore') do
10
+ "spec\ntags\n/test\n/tmp"
11
+ end
12
+ end
13
+
14
+ def fix_stdout_for_logging
15
+ insert_into_file('config.ru', after: /# frozen_string_literal: true/) do
16
+ "\n\n$stdout.sync = true"
17
+ end
18
+ end
19
+
20
+ def reminders
21
+ say <<~TEXT
22
+ Ready to deploy to Heroku. See the Heroku docs[1] for details.
23
+
24
+ [1]: https://devcenter.heroku.com/articles/rack
25
+ TEXT
26
+ end
27
+ end
28
+ end
29
+ end
@@ -0,0 +1,28 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Hoboken
4
+ module AddOns
5
+ # Internationalization support using sinatra-r18n.
6
+ #
7
+ class Internationalization < ::Hoboken::Group
8
+ def add_gem
9
+ gem 'sinatra-r18n', version: '5.0'
10
+ insert_into_file('app.rb', after: %r{require 'sinatra('|/base')}) do
11
+ "\nrequire 'sinatra/r18n'"
12
+ end
13
+ insert_into_file('config/environment.rb', after: /register Sinatra::Flash/) do
14
+ "\n register Sinatra::R18n"
15
+ end
16
+ end
17
+
18
+ def translations
19
+ empty_directory('i18n')
20
+ template('hoboken/templates/en.yml.tt', 'i18n/en.yml')
21
+ end
22
+
23
+ def reminders
24
+ say "\nGemfile updated... don't forget to 'bundle install'"
25
+ end
26
+ end
27
+ end
28
+ end
@@ -0,0 +1,60 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Hoboken
4
+ module AddOns
5
+ # Add metrics (flog, flay, simplecov).
6
+ #
7
+ class Metrics < ::Hoboken::Group
8
+ def add_gems
9
+ gem 'flog', version: '4.6', group: :test
10
+ gem 'flay', version: '2.12', group: :test
11
+ gem 'simplecov', version: '0.21', require: false, group: :test
12
+ end
13
+
14
+ def copy_task_templates
15
+ empty_directory('tasks')
16
+ template('hoboken/templates/metrics.rake.tt', 'tasks/metrics.rake')
17
+ end
18
+
19
+ def simplecov_test_unit
20
+ return if rspec?
21
+
22
+ insert_into_file 'test/test_helper.rb', before: snippet_location do
23
+ snippet('test')
24
+ end
25
+ end
26
+
27
+ def simplecov_rspec
28
+ return unless rspec?
29
+
30
+ insert_into_file 'spec/spec_helper.rb', before: snippet_location do
31
+ snippet('spec')
32
+ end
33
+ end
34
+
35
+ def reminders
36
+ say "\nGemfile updated... don't forget to 'bundle install'"
37
+ end
38
+
39
+ private
40
+
41
+ def snippet(framework_folder)
42
+ <<~CODE
43
+ require 'simplecov'
44
+ SimpleCov.start do
45
+ add_filter '/bin/'
46
+ add_filter '/config/'
47
+ add_filter '/db/migrate/'
48
+ add_filter '/#{framework_folder}/'
49
+ coverage_dir 'tmp/coverage'
50
+ end
51
+
52
+ CODE
53
+ end
54
+
55
+ def snippet_location
56
+ %r{require_relative '\.\./config/environment'}
57
+ end
58
+ end
59
+ end
60
+ end
@@ -0,0 +1,174 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Hoboken
4
+ module AddOns
5
+ # OmniAuth authentication (allows you to select a provider).
6
+ #
7
+ class OmniAuth < ::Hoboken::Group
8
+ attr_reader :provider
9
+
10
+ def add_gem
11
+ @provider = ask('Specify a provider (i.e. twitter, facebook. etc.): ').downcase
12
+ provider_version = ask('Specify provider version: ')
13
+ gem gem_name, version: provider_version
14
+ end
15
+
16
+ def setup_middleware
17
+ insert_into_file('app.rb', after: %r{require 'sinatra('|/base')}) do
18
+ "\nrequire '#{gem_name}'\nrequire 'sinatra/json'\n"
19
+ end
20
+
21
+ snippet = <<~CODE
22
+ use OmniAuth::Builder do
23
+ provider :#{provider}, ENV['#{provider.upcase}_KEY'], ENV['#{provider.upcase}_SECRET']
24
+ end
25
+ CODE
26
+
27
+ indentation = classic? ? 2 : 6
28
+ location = /use Rack::Session::Cookie.+\n/
29
+ insert_into_file('config/environment.rb', after: location) do
30
+ "\n#{indent(snippet, indentation)}\n"
31
+ end
32
+ end
33
+
34
+ # rubocop:disable Metrics/MethodLength
35
+ def add_routes
36
+ routes = <<~CODE
37
+
38
+ get '/login' do
39
+ '<a href="/auth/#{provider}">Login</a>'
40
+ end
41
+
42
+ get '/auth/:provider/callback' do
43
+ # TODO: Insert real authentication logic...
44
+ json request.env['omniauth.auth']
45
+ end
46
+
47
+ get '/auth/failure' do
48
+ # TODO: Insert real error handling logic...
49
+ halt 401, params[:message]
50
+ end
51
+ CODE
52
+
53
+ if classic?
54
+ append_file('app.rb', routes)
55
+ else
56
+ inject_into_class('app.rb', 'App') { indent(routes, 4) }
57
+ end
58
+ end
59
+ # rubocop:enable Metrics/MethodLength
60
+
61
+ # rubocop:disable Metrics/MethodLength
62
+ def add_tests
63
+ return if rspec?
64
+
65
+ inject_into_class('test/unit/app_test.rb', 'AppTest') do
66
+ <<-CODE
67
+ setup do
68
+ OmniAuth.config.test_mode = true
69
+ end
70
+
71
+ test 'GET /login' do
72
+ get '/login'
73
+ assert_equal('<a href="/auth/#{provider}">Login</a>', last_response.body)
74
+ end
75
+
76
+ test 'GET /auth/#{provider}/callback' do
77
+ auth_hash = {
78
+ provider: '#{provider}',
79
+ uid: '123545',
80
+ info: {
81
+ name: 'John Doe'
82
+ }
83
+ }
84
+
85
+ OmniAuth.config.mock_auth[:#{provider}] = auth_hash
86
+ get '/auth/#{provider}/callback'
87
+ assert_equal(MultiJson.encode(auth_hash), last_response.body)
88
+ end
89
+
90
+ test 'GET /auth/failure' do
91
+ OmniAuth.config.mock_auth[:#{provider}] = :invalid_credentials
92
+ get '/auth/failure'
93
+ assert_response :not_authorized
94
+ end
95
+
96
+ CODE
97
+ end
98
+ end
99
+ # rubocop:enable Metrics/MethodLength
100
+
101
+ # rubocop:disable Metrics/MethodLength
102
+ def add_specs
103
+ return unless rspec?
104
+
105
+ append_file('spec/app_spec.rb') do
106
+ <<~CODE
107
+
108
+ # rubocop:disable Metrics/BlockLength
109
+ RSpec.describe 'omniauth', rack: true do
110
+ before { OmniAuth.config.test_mode = true }
111
+
112
+ describe 'GET /login' do
113
+ before { get '/login' }
114
+
115
+ it { expect(last_response).to have_http_status(:ok) }
116
+ it { expect(last_response).to have_content_type(:html) }
117
+
118
+ it 'renders a template with a login link' do
119
+ #{provider}_link = '<a href="/auth/#{provider}">Login</a>'
120
+ expect(last_response.body).to include(#{provider}_link)
121
+ end
122
+ end
123
+
124
+ describe 'GET /auth/#{provider}/callback' do
125
+ let(:auth_hash) do
126
+ {
127
+ provider: '#{provider}',
128
+ uid: '123545',
129
+ info: {
130
+ name: 'John Doe'
131
+ }
132
+ }
133
+ end
134
+
135
+ before do
136
+ OmniAuth.config.mock_auth[:#{provider}] = auth_hash
137
+ get '/auth/#{provider}/callback'
138
+ end
139
+
140
+ it { expect(last_response).to have_http_status(:ok) }
141
+ it { expect(last_response).to have_content_type(:json) }
142
+
143
+ it 'renders the auth hash result' do
144
+ expect(last_response.body).to eq(JSON.generate(auth_hash))
145
+ end
146
+ end
147
+
148
+ describe 'GET /auth/failure' do
149
+ before do
150
+ OmniAuth.config.mock_auth[:#{provider}] = :invalid_credentials
151
+ get '/auth/failure'
152
+ end
153
+
154
+ it { expect(last_response).to have_http_status(:not_authorized) }
155
+ end
156
+ end
157
+ # rubocop:enable Metrics/BlockLength
158
+ CODE
159
+ end
160
+ end
161
+ # rubocop:enable Metrics/MethodLength
162
+
163
+ def reminders
164
+ say "\nGemfile updated... don't forget to 'bundle install'"
165
+ end
166
+
167
+ private
168
+
169
+ def gem_name
170
+ "omniauth-#{provider}"
171
+ end
172
+ end
173
+ end
174
+ end
@@ -0,0 +1,46 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Hoboken
4
+ module AddOns
5
+ # Basic Rubocop YAML config.
6
+ #
7
+ class Rubocop < ::Hoboken::Group
8
+ def add_gems
9
+ gem 'rubocop', version: '1.12', group: %i[development test]
10
+ gem 'rubocop-performance', version: '1.13', group: %i[development test]
11
+ gem 'rubocop-rake', version: '0.5', group: %i[development test]
12
+ gem 'rubocop-rspec', version: '2.2', group: %i[development test] if rspec?
13
+ gem 'rubocop-sequel', version: '0.2', group: %i[development test] if sequel?
14
+ end
15
+
16
+ def rubocop_yml
17
+ template('hoboken/templates/rubocop.yml.tt', '.rubocop.yml')
18
+ end
19
+
20
+ def rake_task
21
+ create_file('tasks/rubocop.rake') do
22
+ <<~TEXT
23
+ # frozen_string_literal: true
24
+
25
+ begin
26
+ require 'rubocop/rake_task'
27
+ RuboCop::RakeTask.new
28
+ # rubocop:disable Lint/SuppressedException
29
+ rescue LoadError
30
+ end
31
+ # rubocop:enable Lint/SuppressedException
32
+ TEXT
33
+ end
34
+ end
35
+
36
+ def ci_task
37
+ task_list = if rspec?
38
+ '%w[spec rubocop]'
39
+ else
40
+ "['test:all', 'rubocop']"
41
+ end
42
+ gsub_file('Rakefile', /task ci:.*/, "task ci: #{task_list}")
43
+ end
44
+ end
45
+ end
46
+ end
@@ -0,0 +1,135 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Hoboken
4
+ module AddOns
5
+ # Database access via Sequel gem.
6
+ #
7
+ class Sequel < ::Hoboken::Group
8
+ def add_gems
9
+ gem 'sequel', version: '5.43'
10
+ gem 'sqlite3', version: '1.4', group: %i[development test]
11
+ gem 'rubocop-sequel', version: '0.2', group: %i[development test] if rubocop?
12
+ end
13
+
14
+ def setup_directories
15
+ empty_directory('db/migrate')
16
+ empty_directory('tasks')
17
+ empty_directory('tmp')
18
+ end
19
+
20
+ def copy_rake_task
21
+ copy_file('hoboken/templates/sequel.rake', 'tasks/sequel.rake')
22
+ end
23
+
24
+ def setup_db_config
25
+ template('hoboken/templates/db.rb.tt', 'config/db.rb')
26
+ end
27
+
28
+ def require_db_config
29
+ location = %r{require_relative '\.\./app'}
30
+ insert_into_file('config/environment.rb', before: location) do
31
+ "require_relative 'db'\n\n"
32
+ end
33
+ end
34
+
35
+ def setup_puma_config
36
+ insert_into_file('config/puma.rb', after: 'before_fork do') do
37
+ "\n DB.disconnect if defined?(DB)"
38
+ end
39
+ end
40
+
41
+ # rubocop:disable Metrics/MethodLength
42
+ def add_database_test_helper_class
43
+ return if rspec?
44
+
45
+ insert_into_file('test/test_helper.rb', before: /ENV\['RACK_ENV'\] = 'test'/) do
46
+ "ENV['DATABASE_URL'] = 'sqlite://db/test.db'\n"
47
+ end
48
+
49
+ insert_into_file('test/test_helper.rb', after: %r{require 'test/unit'}) do
50
+ "\nrequire 'sequel'"
51
+ end
52
+
53
+ snippet = <<~CODE
54
+ def run(*args, &block)
55
+ result = nil
56
+ DB.transaction(rollback: :always) { result = super }
57
+ result
58
+ end
59
+ CODE
60
+
61
+ insert_into_file('test/test_helper.rb', after: /include RackHelpers\n/) do
62
+ "\n#{indent(snippet, 6)}"
63
+ end
64
+ end
65
+ # rubocop:enable Metrics/MethodLength
66
+
67
+ def add_database_spec_helper
68
+ return unless rspec?
69
+
70
+ insert_into_file('spec/spec_helper.rb', before: /ENV\['RACK_ENV'\] = 'test'/) do
71
+ "ENV['DATABASE_URL'] = 'sqlite://db/test.db'\n"
72
+ end
73
+
74
+ snippet = <<~CODE
75
+ config.around do |example|
76
+ DB.transaction(rollback: :always) { example.run }
77
+ end
78
+ CODE
79
+
80
+ location = /RSpec\.configure do \|config\|\n/
81
+ insert_into_file('spec/spec_helper.rb', after: location) do
82
+ "#{indent(snippet, 2)}\n"
83
+ end
84
+ end
85
+
86
+ def update_rubocop_config
87
+ return unless rubocop?
88
+
89
+ insert_into_file('.rubocop.yml', after: /require:\n/) do
90
+ " - rubocop-sequel\n"
91
+ end
92
+ end
93
+
94
+ # rubocop:disable Metrics/MethodLength
95
+ def update_readme
96
+ snippet = <<~CODE
97
+ <tr>
98
+ <td>DATABASE_URL</td>
99
+ <td>Yes</td>
100
+ <td>
101
+ `sqlite://db/test.db` (for the test environment <em>only</em>)
102
+ </td>
103
+ <td>
104
+ Connection URL to the database. The format varies according
105
+ database adapter. Refer to the
106
+ <a href="https://sequel.jeremyevans.net/rdoc/files/doc/opening_databases_rdoc.html">
107
+ Sequel gem documentation</a> for more information. Some examples:
108
+ <dl>
109
+ <dt>Sqlite3</dt>
110
+ <dd>`sqlite://db/development.db`</dd>
111
+ <dt>PostgreSQL</dt>
112
+ <dd>`postgresql://localhost/myapp_development?pool=5`</dd>
113
+ </dl>
114
+ </td>
115
+ </tr>
116
+ CODE
117
+
118
+ insert_into_file('README.md', after: /<tbody>\n/) do
119
+ indent(snippet, 8)
120
+ end
121
+ end
122
+ # rubocop:enable Metrics/MethodLength
123
+
124
+ def reminders
125
+ say "\nGemfile updated... don't forget to 'bundle install'"
126
+ say <<~TEXT
127
+
128
+ Notes:
129
+ * The sqlite3 gem has been installed for dev and test environments only. You will need to specify a gem to use for production.
130
+ * You will need to specify an environment variable 'DATABASE_URL' (either add it to .env or export it)
131
+ TEXT
132
+ end
133
+ end
134
+ end
135
+ end